| |
| |
|
|
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
| from onescience.utils.pdenneval.integral_operators import * |
|
|
| |
| |
| |
| class UNO1d(nn.Module): |
| def __init__(self, num_channels, width, pad = 9, factor = 1, initial_step = 10): |
| super(UNO1d, self).__init__() |
|
|
| self.in_width = num_channels * initial_step + 1 |
| self.width = width |
| |
| self.padding = pad |
|
|
| self.fc_n1 = nn.Linear(self.in_width, self.width//2) |
|
|
| self.fc0 = nn.Linear(self.width//2, self.width) |
|
|
| self.conv0 = OperatorBlock_1D(self.width, 2*factor*self.width,24, 11) |
|
|
| self.conv1 = OperatorBlock_1D(2*factor*self.width, 4*factor*self.width, 12, 5, Normalize = True) |
|
|
| self.conv2 = OperatorBlock_1D(4*factor*self.width, 4*factor*self.width, 12, 5) |
|
|
| self.conv4 = OperatorBlock_1D(4*factor*self.width, 2*factor*self.width, 24, 5, Normalize = True) |
|
|
| self.conv5 = OperatorBlock_1D(4*factor*self.width, self.width, 57, 11) |
|
|
| self.fc1 = nn.Linear(2*self.width, 1*self.width) |
| self.fc2 = nn.Linear(1*self.width, num_channels) |
|
|
| def forward(self, x, grid): |
| x = torch.cat((x, grid), dim=-1) |
|
|
| x_fc_1 = self.fc_n1(x) |
| x_fc_1 = F.gelu(x_fc_1) |
|
|
| x_fc0 = self.fc0(x_fc_1) |
| x_fc0 = F.gelu(x_fc0) |
| |
| x_fc0 = x_fc0.permute(0, 2, 1) |
| |
| x_fc0 = F.pad(x_fc0, [0,self.padding]) |
| |
| D1 = x_fc0.shape[-1] |
| x_c0 = self.conv0(x_fc0,D1//2) |
|
|
| x_c1 = self.conv1(x_c0,D1//4) |
|
|
| x_c2 = self.conv2(x_c1,D1//4) |
| |
| x_c4 = self.conv4(x_c2 ,D1//2) |
| x_c4 = torch.cat([x_c4, x_c0], dim=1) |
|
|
| x_c5 = self.conv5(x_c4,D1) |
| x_c5 = torch.cat([x_c5, x_fc0], dim=1) |
|
|
|
|
| if self.padding!=0: |
| x_c5 = x_c5[..., :-self.padding] |
|
|
|
|
| x_c5 = x_c5.permute(0, 2, 1) |
|
|
| x_fc1 = self.fc1(x_c5) |
| x_fc1 = F.gelu(x_fc1) |
|
|
| x_out = self.fc2(x_fc1) |
| return x_out.unsqueeze(-2) |
|
|
| class UNO2d(nn.Module): |
| def __init__(self, num_channels, width, pad = 6, factor = 1, initial_step = 10): |
| super(UNO2d, self).__init__() |
|
|
| self.in_width = num_channels * initial_step + 2 |
| self.width = width |
| |
| self.padding = pad |
|
|
| self.fc_n1 = nn.Linear(self.in_width, self.width//2) |
|
|
| self.fc0 = nn.Linear(self.width//2, self.width) |
|
|
| self.conv0 = OperatorBlock_2D(self.width, 2*factor*self.width,36, 36, 17, 17) |
|
|
| self.conv1 = OperatorBlock_2D(2*factor*self.width, 4*factor*self.width, 18, 18, 7, 7, Normalize = True) |
|
|
| self.conv2 = OperatorBlock_2D(4*factor*self.width, 4*factor*self.width, 18, 18, 7, 7) |
|
|
| self.conv4 = OperatorBlock_2D(4*factor*self.width, 2*factor*self.width, 36, 36, 7, 7, Normalize = True) |
|
|
| self.conv5 = OperatorBlock_2D(4*factor*self.width, self.width, 81, 81, 17, 17) |
|
|
| self.fc1 = nn.Linear(2*self.width, 1*self.width) |
| self.fc2 = nn.Linear(1*self.width, num_channels) |
|
|
| def forward(self, x, grid): |
| x = torch.cat((x, grid), dim=-1) |
|
|
| x_fc_1 = self.fc_n1(x) |
| x_fc_1 = F.gelu(x_fc_1) |
|
|
| x_fc0 = self.fc0(x_fc_1) |
| x_fc0 = F.gelu(x_fc0) |
| |
| x_fc0 = x_fc0.permute(0, 3, 1, 2) |
| |
| |
| x_fc0 = F.pad(x_fc0, [0,self.padding, 0,self.padding]) |
| |
| D1,D2 = x_fc0.shape[-2],x_fc0.shape[-1] |
|
|
| x_c0 = self.conv0(x_fc0,D1//2,D2//2) |
|
|
| x_c1 = self.conv1(x_c0,D1//4,D2//4) |
|
|
| x_c2 = self.conv2(x_c1,D1//4,D2//4) |
| |
| x_c4 = self.conv4(x_c2 ,D1//2,D2//2) |
| x_c4 = torch.cat([x_c4, x_c0], dim=1) |
|
|
| x_c5 = self.conv5(x_c4,D1,D2) |
| x_c5 = torch.cat([x_c5, x_fc0], dim=1) |
|
|
|
|
| if self.padding!=0: |
| x_c5 = x_c5[..., :-self.padding, :-self.padding] |
|
|
|
|
| x_c5 = x_c5.permute(0, 2, 3, 1) |
|
|
| x_fc1 = self.fc1(x_c5) |
| x_fc1 = F.gelu(x_fc1) |
|
|
| x_out = self.fc2(x_fc1) |
| |
| return x_out.unsqueeze(-2) |
|
|
| class UNO3d(nn.Module): |
| def __init__(self, num_channels, width, pad = 5, factor = 1, initial_step = 10): |
| super(UNO3d, self).__init__() |
|
|
| self.in_width = num_channels * initial_step + 3 |
| self.width = width |
| |
| self.padding = pad |
|
|
| self.fc_n1 = nn.Linear(self.in_width, self.width//2) |
|
|
| self.fc0 = nn.Linear(self.width//2, self.width) |
|
|
| self.conv0 = OperatorBlock_3D(self.width, 2*factor*self.width,36, 36, 36, 17, 17, 17) |
|
|
| self.conv1 = OperatorBlock_3D(2*factor*self.width, 4*factor*self.width, 18, 18, 18, 7, 7, 7, Normalize = True) |
|
|
| self.conv2 = OperatorBlock_3D(4*factor*self.width, 4*factor*self.width, 18, 18, 18, 7, 7, 7) |
|
|
| self.conv4 = OperatorBlock_3D(4*factor*self.width, 2*factor*self.width, 36, 36, 36, 7, 7, 7, Normalize = True) |
|
|
| self.conv5 = OperatorBlock_3D(4*factor*self.width, self.width, 81, 81, 81, 17, 17, 17) |
|
|
| self.fc1 = nn.Linear(2*self.width, 1*self.width) |
| self.fc2 = nn.Linear(1*self.width, num_channels) |
|
|
| def forward(self, x, grid): |
| x = torch.cat((x, grid), dim=-1) |
|
|
| x_fc_1 = self.fc_n1(x) |
| x_fc_1 = F.gelu(x_fc_1) |
|
|
| x_fc0 = self.fc0(x_fc_1) |
| x_fc0 = F.gelu(x_fc0) |
| |
| x_fc0 = x_fc0.permute(0, 4, 1, 2, 3) |
| |
| |
| x_fc0 = F.pad(x_fc0, [0,self.padding, 0,self.padding, 0,self.padding]) |
| |
| D1,D2,D3 = x_fc0.shape[-3],x_fc0.shape[-2],x_fc0.shape[-1] |
|
|
| x_c0 = self.conv0(x_fc0,D1//2,D2//2,D3//2) |
|
|
| x_c1 = self.conv1(x_c0,D1//4,D2//4,D3//4) |
|
|
| x_c2 = self.conv2(x_c1,D1//4,D2//4,D3//4) |
| |
| x_c4 = self.conv4(x_c2 ,D1//2,D2//2,D3//2) |
| x_c4 = torch.cat([x_c4, x_c0], dim=1) |
|
|
| x_c5 = self.conv5(x_c4,D1,D2,D3) |
| x_c5 = torch.cat([x_c5, x_fc0], dim=1) |
|
|
|
|
| if self.padding!=0: |
| x_c5 = x_c5[..., :-self.padding, :-self.padding, :-self.padding] |
|
|
|
|
| x_c5 = x_c5.permute(0, 2, 3, 4, 1) |
|
|
| x_fc1 = self.fc1(x_c5) |
| x_fc1 = F.gelu(x_fc1) |
|
|
| x_out = self.fc2(x_fc1) |
| |
| return x_out.unsqueeze(-2) |
|
|
| class UNO_maxwell(nn.Module): |
| def __init__(self, num_channels, width, pad = 5, factor = 1, initial_step = 10): |
| super(UNO_maxwell, self).__init__() |
|
|
| self.in_width = num_channels * initial_step |
| self.width = width |
| |
| self.padding = pad |
|
|
| self.fc_n1 = nn.Linear(self.in_width, self.width//2) |
|
|
| self.fc0 = nn.Linear(self.width//2, self.width) |
|
|
| self.conv0 = OperatorBlock_3D(self.width, 2*factor*self.width,24, 24, 24, 10, 10, 10) |
|
|
| self.conv1 = OperatorBlock_3D(2*factor*self.width, 4*factor*self.width, 12, 12, 12, 5, 5, 5, Normalize = True) |
|
|
| self.conv2 = OperatorBlock_3D(4*factor*self.width, 4*factor*self.width, 12, 12, 12, 5, 5, 5) |
|
|
| self.conv4 = OperatorBlock_3D(4*factor*self.width, 2*factor*self.width, 12, 12, 12, 5, 5, 5, Normalize = True) |
|
|
| self.conv5 = OperatorBlock_3D(4*factor*self.width, self.width, 53, 53, 53, 10, 10, 10) |
|
|
| self.fc1 = nn.Linear(2*self.width, 1*self.width) |
| self.fc2 = nn.Linear(1*self.width, num_channels) |
|
|
| def forward(self, x, grid): |
| x_fc_1 = self.fc_n1(x) |
| x_fc_1 = F.gelu(x_fc_1) |
|
|
| x_fc0 = self.fc0(x_fc_1) |
| x_fc0 = F.gelu(x_fc0) |
| |
| x_fc0 = x_fc0.permute(0, 4, 1, 2, 3) |
| |
| |
| x_fc0 = F.pad(x_fc0, [0,self.padding, 0,self.padding, 0,self.padding]) |
| |
| D1,D2,D3 = x_fc0.shape[-3],x_fc0.shape[-2],x_fc0.shape[-1] |
|
|
| x_c0 = self.conv0(x_fc0,D1//2,D2//2,D3//2) |
|
|
| x_c1 = self.conv1(x_c0,D1//4,D2//4,D3//4) |
|
|
| x_c2 = self.conv2(x_c1,D1//4,D2//4,D3//4) |
| |
| x_c4 = self.conv4(x_c2 ,D1//2,D2//2,D3//2) |
| x_c4 = torch.cat([x_c4, x_c0], dim=1) |
|
|
| x_c5 = self.conv5(x_c4,D1,D2,D3) |
| x_c5 = torch.cat([x_c5, x_fc0], dim=1) |
|
|
|
|
| if self.padding!=0: |
| x_c5 = x_c5[..., :-self.padding, :-self.padding, :-self.padding] |
|
|
|
|
| x_c5 = x_c5.permute(0, 2, 3, 4, 1) |
|
|
| x_fc1 = self.fc1(x_c5) |
| x_fc1 = F.gelu(x_fc1) |
|
|
| x_out = self.fc2(x_fc1) |
| |
| return x_out.unsqueeze(-2) |
| |