PDENNEval / model /uno.py
OneScience's picture
Upload folder using huggingface_hub
e2703dc verified
Raw
History Blame Contribute Delete
8.74 kB
# coding=utf-8
# Codes for section: Results on Darcy Flow Equation
import torch
import torch.nn as nn
import torch.nn.functional as F
from onescience.utils.pdenneval.integral_operators import *
###############
# UNO^dagger achitechtures
###############
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 # input channel
self.width = width
self.padding = pad # pad the domain if input is non-periodic
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) # will be reshaped
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)
# scale = math.ceil(x_fc0.shape[-1]/43)
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 # input channel
self.width = width
self.padding = pad # pad the domain if input is non-periodic
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) # will be reshaped
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)
# scale = math.ceil(x_fc0.shape[-1]/85)
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 # input channel
self.width = width
self.padding = pad # pad the domain if input is non-periodic
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) # will be reshaped
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)
# scale = math.ceil(x_fc0.shape[-1]/85)
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 # input channel
self.width = width
self.padding = pad # pad the domain if input is non-periodic
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) # will be reshaped
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)
# scale = math.ceil(x_fc0.shape[-1]/85)
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)