Commit 087a703b authored by Valentin Vallaeys's avatar Valentin Vallaeys Committed by Jonathan Lambrechts
Browse files

new mode splitting

parent 4d2a6feb
import slim3d import slim3d
from slimPre import make_directory
output_directory = 'output' output_directory = 'output'
make_directory(output_directory)
domain = slim3d.Domain('data/mesh3d.msh') domain = slim3d.Domain('data/mesh3d.msh')
......
...@@ -4,7 +4,7 @@ from dgpy.scripts import slim_private ...@@ -4,7 +4,7 @@ from dgpy.scripts import slim_private
class Domain : class Domain :
"""Create the slim3d Domain""" """Create the slim3d Domain"""
def __init__(self, mesh_file_name, periodic_map_file='') : def __init__(self, mesh_file_name, periodic_map_file='', reference_density=1027, gravity=9.81) :
"""keyword arguments: """keyword arguments:
* mesh_file_name * mesh_file_name
...@@ -14,6 +14,8 @@ class Domain : ...@@ -14,6 +14,8 @@ class Domain :
self._topTags = topTags self._topTags = topTags
self._bottomTags = bottomTags self._bottomTags = bottomTags
self._slimSolver = dgpy.slim3dSolver(mesh_file_name, bottomTags, topTags, periodic_map_file) self._slimSolver = dgpy.slim3dSolver(mesh_file_name, bottomTags, topTags, periodic_map_file)
self._density = reference_density
self._g = gravity
class Slim3d_equations : class Slim3d_equations :
"""Create the slim3d Equation""" """Create the slim3d Equation"""
...@@ -40,7 +42,8 @@ class Slim3d_equations : ...@@ -40,7 +42,8 @@ class Slim3d_equations :
self._coriolis = None self._coriolis = None
self._atmPress = None self._atmPress = None
self._linear_density = None self._linear_density = None
self._reference_density = 1027 self._reference_density = self._domain._density
self._gravity = self._domain._g
self._initial_elevation = None self._initial_elevation = None
self._initial_salinity = None self._initial_salinity = None
self._initial_temperature = None self._initial_temperature = None
...@@ -49,6 +52,8 @@ class Slim3d_equations : ...@@ -49,6 +52,8 @@ class Slim3d_equations :
self._boundary_open = [] self._boundary_open = []
self._gotm_option_file = None self._gotm_option_file = None
self._z0 = [0.005, 0.02] self._z0 = [0.005, 0.02]
self._linear2d = False
self._linear_solver_2D = True
def set_implicit_vertical_diffusion(self, flag): def set_implicit_vertical_diffusion(self, flag):
slimSolver = self._slimSolver slimSolver = self._slimSolver
...@@ -61,6 +66,12 @@ class Slim3d_equations : ...@@ -61,6 +66,12 @@ class Slim3d_equations :
if slimSolver.getSolveT() and self._vertical_diffusivity: if slimSolver.getSolveT() and self._vertical_diffusivity:
slimSolver.setSolveTImplicitVerticalDiffusion(True) slimSolver.setSolveTImplicitVerticalDiffusion(True)
def set_linear_2d_equations(self, flag):
self._linear2d = flag
def set_linear_solver_2d(self, flag):
self._linear_solver_2D = flag
def set_limiter(self, flag): def set_limiter(self, flag):
slimSolver = self._slimSolver slimSolver = self._slimSolver
slimSolver.setFlagUVLimiter(flag) slimSolver.setFlagUVLimiter(flag)
...@@ -125,7 +136,7 @@ class Slim3d_equations : ...@@ -125,7 +136,7 @@ class Slim3d_equations :
if z0S: if z0S:
self._z0[1] = z0S self._z0[1] = z0S
def set_linear_density(self, salinity=False, temperature=False, constant_coefficient=0, linear_coefficient=0): def set_linear_density(self, mode, constant_coefficient=0, linear_coefficient=0):
"""Set the density as a linear function of either salinity, temperature or z coordinate. If this function is not set, density follows Jackett-McDougall """Set the density as a linear function of either salinity, temperature or z coordinate. If this function is not set, density follows Jackett-McDougall
keyword arguments: keyword arguments:
...@@ -142,9 +153,6 @@ class Slim3d_equations : ...@@ -142,9 +153,6 @@ class Slim3d_equations :
dgpy.Msg.Fatal('density is a linear function of either salinity, temperature or z coordinate') dgpy.Msg.Fatal('density is a linear function of either salinity, temperature or z coordinate')
self._linear_density = (mode, constant_coefficient, linear_coefficient) self._linear_density = (mode, constant_coefficient, linear_coefficient)
def set_reference_density(self, density):
self._reference_density = density
def set_initial_elevation(self, elevation): def set_initial_elevation(self, elevation):
self._initial_elevation = elevation self._initial_elevation = elevation
...@@ -202,11 +210,10 @@ class Slim3d_equations : ...@@ -202,11 +210,10 @@ class Slim3d_equations :
class Loop: class Loop:
"""Temporal solver""" """Temporal solver"""
def __init__(self, equations, maximum_2d_time_step=3600, ratio_3dvs2d_time_step=1, export_time_step=3600, ratio_full_export=-1, initial_time='1970-01-01 00:00:00', final_time=0, output_directory="./output"): def __init__(self, equations, time_step=3600, export_time_step=3600, ratio_full_export=-1, initial_time='1970-01-01 00:00:00', final_time=0, output_directory="./output"):
self._slimSolver = equations._slimSolver self._slimSolver = equations._slimSolver
self._equations = equations self._equations = equations
self._max_2d_dt = maximum_2d_time_step self._dt = time_step
self._dt2d3d_ratio = ratio_3dvs2d_time_step
self._export_dt = export_time_step self._export_dt = export_time_step
self._ratio_full_export = ratio_full_export self._ratio_full_export = ratio_full_export
fmt = '%Y-%m-%d %H:%M:%S' fmt = '%Y-%m-%d %H:%M:%S'
...@@ -237,6 +244,7 @@ class Loop: ...@@ -237,6 +244,7 @@ class Loop:
self._ncExport = [] self._ncExport = []
self._restart_dir = None self._restart_dir = None
self._restart_ind = -1 self._restart_ind = -1
self._timer = False
def export_uv(self, vect=True): def export_uv(self, vect=True):
self._export_uv = True self._export_uv = True
...@@ -259,6 +267,9 @@ class Loop: ...@@ -259,6 +267,9 @@ class Loop:
def restart(self, directory, index): def restart(self, directory, index):
self._restart_dir = directory self._restart_dir = directory
self._restart_ind = index self._restart_ind = index
def set_timer(self):
self._timer = True
def setup(self): def setup(self):
slim3d_private.slim3d_setup(self) slim3d_private.slim3d_setup(self)
...@@ -352,6 +363,7 @@ class Loop: ...@@ -352,6 +363,7 @@ class Loop:
d = self._slimSolver.getDofs() d = self._slimSolver.getDofs()
uvNorm = d.uvDof.norm() uvNorm = d.uvDof.norm()
if dgpy.Msg.GetCommRank() == 0 : dgpy.Msg.Info("%5i [ %s ] normuv %6.12e clock %.1fs" % (self._timeIntegrator.getIter(),slim_private.time.strftime("%d %b %Y %H:%M:%S", slim_private.time.gmtime(self._timeIntegrator.getTime())), uvNorm, slim_private.time.time() - self._tic)) if dgpy.Msg.GetCommRank() == 0 : dgpy.Msg.Info("%5i [ %s ] normuv %6.12e clock %.1fs" % (self._timeIntegrator.getIter(),slim_private.time.strftime("%d %b %Y %H:%M:%S", slim_private.time.gmtime(self._timeIntegrator.getTime())), uvNorm, slim_private.time.time() - self._tic))
return uvNorm
def terminate(self): def terminate(self):
self._timeIntegrator.terminate() self._timeIntegrator.terminate()
...@@ -360,6 +372,9 @@ class Loop: ...@@ -360,6 +372,9 @@ class Loop:
def loop(self): def loop(self):
if not self._timeIntegrator: if not self._timeIntegrator:
self.setup() self.setup()
if self._timer:
timer = dgpy.dgTimer.root()
timer.start()
while self.get_time() < self.final_time: while self.get_time() < self.final_time:
self.advance_one_time_step() self.advance_one_time_step()
self.check_sanity() self.check_sanity()
...@@ -369,6 +384,8 @@ class Loop: ...@@ -369,6 +384,8 @@ class Loop:
self.export_full() self.export_full()
self.check_tracer_consistency() self.check_tracer_consistency()
self.print_iter_info() self.print_iter_info()
if self._timer:
timer.printFull()
self.terminate() self.terminate()
......
...@@ -15,15 +15,13 @@ def slim3d_setup(loop): ...@@ -15,15 +15,13 @@ def slim3d_setup(loop):
slimSolver.setSolveTurbulence(True) slimSolver.setSolveTurbulence(True)
slimSolver.setAdvectTurbulentEnergy(True) slimSolver.setAdvectTurbulentEnergy(True)
if eq._gotm_option_file: if eq._gotm_option_file:
slimSolver.turbulenceSetupFile = 'eq._gotm_option_file' slimSolver.turbulenceSetupFile = eq._gotm_option_file
else: else:
gotmFileStr = gotmOptionFile gotmFileStr = gotmOptionFile
f = open('gotmturb.nml', 'w') f = open('gotmturb.nml', 'w')
f.write(gotmFileStr) f.write(gotmFileStr)
f.close() f.close()
slimSolver.turbulenceSetupFile = 'gotmturb.nml'
# TODO download automatically or in SLIM
slimSolver.turbulenceSetupFile = 'gotmturb.nml'
if (slimSolver.getSolveUVImplicitVerticalDiffusion() or slimSolver.getSolveTurbulence()) and not slimSolver.getComputeBottomFriction(): if (slimSolver.getSolveUVImplicitVerticalDiffusion() or slimSolver.getSolveTurbulence()) and not slimSolver.getComputeBottomFriction():
dgpy.Msg.Fatal('If Vertical implicit diffusion or using gotm, bottom friction must be true') dgpy.Msg.Fatal('If Vertical implicit diffusion or using gotm, bottom friction must be true')
if eq._horizontal_viscosity == 'smagorinsky' : if eq._horizontal_viscosity == 'smagorinsky' :
...@@ -62,9 +60,9 @@ def slim3d_setup(loop): ...@@ -62,9 +60,9 @@ def slim3d_setup(loop):
val[:] = eq._initial_salinity[2] + xyz[:,2] * eq._initial_salinity[3] val[:] = eq._initial_salinity[2] + xyz[:,2] * eq._initial_salinity[3]
f.SInitFunc = dgpy.functionNumpy(1, zFunc, [d.xyzOrigDof.getFunction()]) f.SInitFunc = dgpy.functionNumpy(1, zFunc, [d.xyzOrigDof.getFunction()])
else: else:
dgpy.Msg.Fatal('this mode does not exist') dgpy.Msg.Fatal('Unknown mode for initial salinity:' + eq._initial_salinity[0])
elif (not eq._linear_density) or (eq._linear_density[0]): elif (not eq._linear_density) or (eq._linear_density[0] == 'salinity'):
dgpy.Msg.Fatal('Initial salinity must be set if rhoFunc is not set') dgpy.Msg.Fatal('Initial salinity must be set for rhoFunc')
if eq._initial_temperature: if eq._initial_temperature:
if eq._initial_temperature[0] == 'netcdf': if eq._initial_temperature[0] == 'netcdf':
...@@ -74,33 +72,38 @@ def slim3d_setup(loop): ...@@ -74,33 +72,38 @@ def slim3d_setup(loop):
val[:] = eq._initial_temperature[2] + xyz[:,2] * eq._initial_temperature[3] val[:] = eq._initial_temperature[2] + xyz[:,2] * eq._initial_temperature[3]
f.TInitFunc = dgpy.functionNumpy(1, zFunc, [d.xyzOrigDof.getFunction()]) f.TInitFunc = dgpy.functionNumpy(1, zFunc, [d.xyzOrigDof.getFunction()])
else: else:
dgpy.Msg.Fatal('this mode does not exist') dgpy.Msg.Fatal('Unknown mode for initial temperature:' + eq._initial_temperature[0])
elif (not eq._linear_density) or (not eq._linear_density[0]): elif (not eq._linear_density) or (eq._linear_density[0] == 'temperature'):
dgpy.Msg.Fatal('Initial temperature must be set if rhoFunc is not set') dgpy.Msg.Fatal('Initial temperature must be set for rhoFunc')
if eq._linear_density : if eq._linear_density :
if eq._linear_density[0] == 'salinity': if eq._linear_density[0] == 'salinity':
f.rhoFunc = dgpy.linearStateEquation(d.SDof.getFunction(), eq._linear_density[2], eq._linear_density[1]) if slimSolver.getSolveS():
f.rhoFunc = dgpy.linearStateEquation(d.SDof.getFunction(), eq._linear_density[2], eq._linear_density[1])
else:
f.rhoFunc = dgpy.linearStateEquation(f.SInitFunc, eq._linear_density[2], eq._linear_density[1])
elif eq._linear_density[0] == 'temperature' : elif eq._linear_density[0] == 'temperature' :
f.rhoFunc = dgpy.linearStateEquation(d.TDof.getFunction(), eq._linear_density[2], eq._linear_density[1]) if slimSolver.getSolveT():
f.rhoFunc = dgpy.linearStateEquation(d.TDof.getFunction(), eq._linear_density[2], eq._linear_density[1])
else:
f.rhoFunc = dgpy.linearStateEquation(f.TInitFunc, eq._linear_density[2], eq._linear_density[1])
else: else:
f.rhoFunc = dgpy.linearStateEquation(d.zDof.getFunction(), eq._linear_density[2], eq._linear_density[1]) f.rhoFunc = dgpy.linearStateEquation(d.zDof.getFunction(), eq._linear_density[2], eq._linear_density[1])
if eq._vertical_diffusivity == 'gotm': if eq._vertical_diffusivity == 'gotm':
dgpy.Msg.Fatal('GOTM does not work with linear density. S and T must be set, and the automatic Jackett-McDougall state equation will be computed') dgpy.Msg.Fatal('GOTM does not work with linear density. S and T must be set, and the automatic Jackett-McDougall state equation will be computed')
dgpy.slim3dParameters.setRho0(eq._reference_density) dgpy.slim3dParameters.setRho0(eq._reference_density)
dgpy.slim3dParameters.setG(eq._gravity)
eq._gravityFunc = dgpy.functionConstant(eq._gravity)
eq._areaFunc = None eq._areaFunc = None
if eq._horizontal_viscosity == 'constant': if eq._horizontal_viscosity == 'constant':
f.nuh = dgpy.functionConstant(eq._hor_visc_const) f.nuh = dgpy.functionConstant(eq._hor_visc_const)
f.nuh2d = dgpy.functionConstant(eq._hor_visc_const)
elif eq._horizontal_viscosity == 'smagorinsky': elif eq._horizontal_viscosity == 'smagorinsky':
area2d = dgpy.dgDofContainer(slimSolver.groups2d, 1) area2d = dgpy.dgDofContainer(slimSolver.groups2d, 1)
slimSolver.copy2d3d.computeArea2d( area2d) slimSolver.copy2d3d.computeArea2d( area2d)
area2d.scatter() area2d.scatter()
eq._areaFunc = dgpy.functionPrecomputedExtrusion(slimSolver.extrusion(), 3, area2d.getFunction()) eq._areaFunc = dgpy.functionPrecomputedExtrusion(slimSolver.extrusion(), 3, area2d.getFunction())
f.nuh = dgpy.domeSmagorinsky(eq._hor_visc_fact, eq._hor_visc_max, d.uvGradDof.getFunction(), eq._areaFunc) f.nuh = dgpy.domeSmagorinsky(eq._hor_visc_fact, eq._hor_visc_max, d.uvGradDof.getFunction(), eq._areaFunc)
f.nuh2d = dgpy.domeSmagorinsky(eq._hor_visc_fact, eq._hor_visc_max, d.uvGradDof2d.getFunction(), eq._areaFunc)
if eq._horizontal_diffusivity == 'constant': if eq._horizontal_diffusivity == 'constant':
f.kappahTotal = dgpy.functionConstant(eq._hor_diff_const) f.kappahTotal = dgpy.functionConstant(eq._hor_diff_const)
...@@ -147,7 +150,7 @@ def slim3d_setup(loop): ...@@ -147,7 +150,7 @@ def slim3d_setup(loop):
bottomTags = eq._domain._bottomTags bottomTags = eq._domain._bottomTags
topTags = eq._domain._topTags topTags = eq._domain._topTags
g = dgpy.slim3dParameters.getG() g = eq._gravity
# Open Boundaries # Open Boundaries
def uvOpenGivenEtaNumpy(cmap, val, uv, normals) : def uvOpenGivenEtaNumpy(cmap, val, uv, normals) :
un = uv[:,0] * normals[:,0] + uv[:,1] * normals[:,1] un = uv[:,0] * normals[:,0] + uv[:,1] * normals[:,1]
...@@ -161,64 +164,64 @@ def slim3d_setup(loop): ...@@ -161,64 +164,64 @@ def slim3d_setup(loop):
val[:] = numpy.sqrt( (bath[:]+eta[:]) / g) * un val[:] = numpy.sqrt( (bath[:]+eta[:]) / g) * un
def transport2UVNumpy(cmap, val, uv, bath, eta) : def transport2UVNumpy(cmap, val, uv, bath, eta) :
val[:,0] = uv[:,0] / ( bath[:] + eta[:] ) val[:,0] = uv[:,0] / ( bath[:] + eta[:] )
val[:,1] = uv[:,1] / ( bath[:] + eta[:] ) val[:,1] = uv[:,1] / ( bath[:] + eta[:] )
def mergeEtaUV(cmap, val, eta, uv):
val[:,0] = eta[:]
val[:,1] = uv[:,0]
val[:,2] = uv[:,1]
eta = f.eta2dFunc eta = f.eta2dFunc
uv = d.uvDof.getFunction() uv = d.uvDof.getFunction()
uvAv2d = f.uvAv2dFunc uvAv2d = f.uvAv2dFunc
uvInt2d = f.uvInt2dFunc
eq._uv_open = {} eq._uv_open = {}
eq._uvInt2d_open = {} eq._uvDev_open = {}
eq._uvAv2d_open = {} eq._uvAv2d_open = {}
eq._uvTransport_open = {} eq._uvTransport_open = {}
eq._uvAv2dTransport_open = {} eq._uvAv2dTransport_open = {}
eq._u_open = {} eq._u_open = {}
eq._uAv2d_open = {}
eq._v_open = {} eq._v_open = {}
eq._uAv2d_open = {}
eq._vAv2d_open = {} eq._vAv2d_open = {}
eq._flux_section = {} eq._flux_section = {}
eq._flux = {} eq._flux = {}
eq._flux2d = {} eq._flux2d = {}
eq._eta_open = {} eq._eta_open = {}
eq._S_open = {} eq._S_open = {}
eq._T_open = {} eq._T_open = {}
eq._sw2D_open = {}
for openBnd in eq._boundary_open: for openBnd in eq._boundary_open:
eq._uvDev_open[openBnd] = dgpy.functionConstant([0.,0.])
if openBnd.u and openBnd.eta: if openBnd.u and openBnd.eta:
eq._u_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups3d) eq._u_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups3d)
eq._v_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups3d) eq._v_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups3d)
eq._uAv2d_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups2d) eq._uAv2d_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups2d)
eq._vAv2d_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups2d) eq._vAv2d_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups2d)
if openBnd.transport: if openBnd.transport:
eq._uvTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]]) eq._uvTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]])
eq._uv_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvTransport_open[openBnd], f.bathFunc2d, eta]) eq._uv_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvTransport_open[openBnd], f.bathFunc2d, eta])
eq._uvAv2dTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]]) eq._uvAv2dTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]])
eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvAv2dTransport_open[openBnd], f.bathFunc2d, eta]) eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvAv2dTransport_open[openBnd], f.bathFunc2d, eta])
eq._uvInt2d_open[openBnd] = eq._uvAv2d_open[openBnd]
else: else:
eq._uv_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]]) eq._uv_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]])
eq._uvInt2d_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]]) eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]])
eq._uvAv2d_open[openBnd] = eq._uvAv2d_open[openBnd]
eq._eta_open[openBnd] = slim_private._load_function(openBnd.eta, slimSolver.groups2d) eq._eta_open[openBnd] = slim_private._load_function(openBnd.eta, slimSolver.groups2d)
elif openBnd.u: elif openBnd.u:
eq._u_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups3d) eq._u_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups3d)
eq._v_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups3d) eq._v_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups3d)
eq._uAv2d_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups2d) eq._uAv2d_open[openBnd] = slim_private._load_function(openBnd.u, slimSolver.groups2d)
eq._vAv2d_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups2d) eq._vAv2d_open[openBnd] = slim_private._load_function(openBnd.v, slimSolver.groups2d)
if openBnd.transport: if openBnd.transport:
eq._uvTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]]) eq._uvTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]])
eq._uv_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvTransport_open[openBnd], f.bathFunc2d, eta]) eq._uv_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvTransport_open[openBnd], f.bathFunc2d, eta])
eq._uvAv2dTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]]) eq._uvAv2dTransport_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]])
eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvAv2dTransport_open[openBnd], f.bathFunc2d, eta]) eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, transport2UVNumpy, [eq._uvAv2dTransport_open[openBnd], f.bathFunc2d, eta])
eq._uvInt2d_open[openBnd] = eq._uvAv2d_open[openBnd]
else: else:
eq._uv_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]]) eq._uv_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._u_open[openBnd], eq._v_open[openBnd]])
eq._uvInt2d_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]]) eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, mergeUVNumpy, [eq._uAv2d_open[openBnd], eq._vAv2d_open[openBnd]])
eq._uvAv2d_open[openBnd] = eq._uvAv2d_open[openBnd]
eq._eta_open[openBnd] = dgpy.functionNumpy(1, etaOpenGivenUVNumpy, [uvAv2d, f.bathFunc2d, eta, dgpy.function.getNormals()]) eq._eta_open[openBnd] = dgpy.functionNumpy(1, etaOpenGivenUVNumpy, [uvAv2d, f.bathFunc2d, eta, dgpy.function.getNormals()])
elif openBnd.eta: elif openBnd.eta:
eq._uv_open[openBnd] = dgpy.functionNumpy(2, uvOpenGivenEtaNumpy, [uv, dgpy.function.getNormals()]) eq._uv_open[openBnd] = dgpy.functionNumpy(2, uvOpenGivenEtaNumpy, [uv, dgpy.function.getNormals()])
eq._uvInt2d_open[openBnd] = dgpy.functionNumpy(2, uvOpenGivenEtaNumpy, [uvInt2d, dgpy.function.getNormals()])
eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, uvOpenGivenEtaNumpy, [uvAv2d, dgpy.function.getNormals()]) eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, uvOpenGivenEtaNumpy, [uvAv2d, dgpy.function.getNormals()])
eq._eta_open[openBnd] = slim_private._load_function(openBnd.eta, slimSolver.groups2d) eq._eta_open[openBnd] = slim_private._load_function(openBnd.eta, slimSolver.groups2d)
elif openBnd.flux: elif openBnd.flux:
...@@ -228,13 +231,11 @@ def slim3d_setup(loop): ...@@ -228,13 +231,11 @@ def slim3d_setup(loop):
eq._flux_section[openBnd] = sectionFM(0,0) eq._flux_section[openBnd] = sectionFM(0,0)
eq._flux[openBnd] = slim_private._load_function(openBnd.flux, slimSolver.groups3d) eq._flux[openBnd] = slim_private._load_function(openBnd.flux, slimSolver.groups3d)
eq._flux2d[openBnd] = slim_private._load_function(openBnd.flux, slimSolver.groups2d) eq._flux2d[openBnd] = slim_private._load_function(openBnd.flux, slimSolver.groups2d)
eq._uv_open[openBnd] = dgpy.slimFlowRateToVelocity(slimSolver.groups3d, eq._flux_section[openBnd], eq._flux[openBnd], f.bathFunc2d, eta) eq._uv_open[openBnd] = dgpy.slimFlowRateToVelocity(slimSolver.groups3d, eq._flux_section[openBnd], eq._flux[openBnd], f.bathFunc2d, eta)
eq._uvInt2d_open[openBnd] = dgpy.slimFlowRateToVelocity(slimSolver.groups2d, eq._flux_section[openBnd], eq._flux2d[openBnd], f.bathFunc2d, eta)
eq._uvAv2d_open[openBnd] = dgpy.slimFlowRateToVelocity(slimSolver.groups2d, eq._flux_section[openBnd], eq._flux2d[openBnd], f.bathFunc2d, eta) eq._uvAv2d_open[openBnd] = dgpy.slimFlowRateToVelocity(slimSolver.groups2d, eq._flux_section[openBnd], eq._flux2d[openBnd], f.bathFunc2d, eta)
eq._eta_open[openBnd] = eta eq._eta_open[openBnd] = eta
else: else:
eq._uv_open[openBnd] = dgpy.functionNumpy(2, uvOpenFreeNumpy, [f.bathFunc2d, eta, dgpy.function.getNormals()]) eq._uv_open[openBnd] = dgpy.functionNumpy(2, uvOpenFreeNumpy, [f.bathFunc2d, eta, dgpy.function.getNormals()])
eq._uvInt2d_open[openBnd] = dgpy.functionNumpy(2, uvOpenFreeNumpy, [f.bathFunc2d, eta, dgpy.function.getNormals()])
eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, uvOpenFreeNumpy, [f.bathFunc2d, eta, dgpy.function.getNormals()]) eq._uvAv2d_open[openBnd] = dgpy.functionNumpy(2, uvOpenFreeNumpy, [f.bathFunc2d, eta, dgpy.function.getNormals()])
eq._eta_open[openBnd] = eta eq._eta_open[openBnd] = eta
if openBnd.salinity: if openBnd.salinity:
...@@ -247,7 +248,18 @@ def slim3d_setup(loop): ...@@ -247,7 +248,18 @@ def slim3d_setup(loop):
eq._T_open[openBnd] = f.TInitFunc eq._T_open[openBnd] = f.TInitFunc
else: else:
eq._T_open[openBnd] = slim_private._load_function(openBnd.temperature, slimSolver.groups3d) eq._T_open[openBnd] = slim_private._load_function(openBnd.temperature, slimSolver.groups3d)
eq._sw2D_open[openBnd] = dgpy.functionNumpy(3, mergeEtaUV, [eq._eta_open[openBnd], eq._uvAv2d_open[openBnd]])
sw2DEq = e.sw2DEq
sw2DEq.setFrom3D(True)
sw2DEq.setIsLinear(eq._linear2d)
sw2DEq.setLinearSolverFrom3D(eq._linear_solver_2D)
sw2DEq.setGravity(eq._gravityFunc)
sw2DEq.setDensity(eq._reference_density)
sw2DBndWall = sw2DEq.newBoundaryWall(True)
sw2DEq.addBoundaryCondition(eq._boundary_coast, sw2DBndWall)
for openBnd in eq._boundary_open:
sw2DEq.addBoundaryCondition(openBnd.tag, sw2DEq.newOutsideValueBoundary(eq._sw2D_open[openBnd]))
horMomEq = e.horMomEq horMomEq = e.horMomEq
horMomEq.setLaxFriedrichsFactor(0.0) horMomEq.setLaxFriedrichsFactor(0.0)
...@@ -257,8 +269,8 @@ def slim3d_setup(loop): ...@@ -257,8 +269,8 @@ def slim3d_setup(loop):
else : else :
horMomEq.addBoundaryCondition(topTags, horMomEq.newBoundarySurface(f.windStressFunc)) # zero for nonconst tracers! horMomEq.addBoundaryCondition(topTags, horMomEq.newBoundarySurface(f.windStressFunc)) # zero for nonconst tracers!
for openBnd in eq._boundary_open: for openBnd in eq._boundary_open:
toReplaceHorMomOpen = dgpy.VectorFunctorConst([uv, uvInt2d, eta]) toReplaceHorMomOpen = dgpy.VectorFunctorConst([dgpy.function.getSolution(), uvAv2d, eta])
replaceByHorMomOpen = dgpy.VectorFunctorConst([eq._uv_open[openBnd], eq._uvInt2d_open[openBnd], eq._eta_open[openBnd]]) replaceByHorMomOpen = dgpy.VectorFunctorConst([eq._uvDev_open[openBnd], eq._uvAv2d_open[openBnd], eq._eta_open[openBnd]])
horMomBndOpen = horMomEq.newOutsideValueBoundaryGeneric("", toReplaceHorMomOpen, replaceByHorMomOpen) horMomBndOpen = horMomEq.newOutsideValueBoundaryGeneric("", toReplaceHorMomOpen, replaceByHorMomOpen)
horMomEq.addBoundaryCondition(openBnd.tag, horMomBndOpen) horMomEq.addBoundaryCondition(openBnd.tag, horMomBndOpen)
horMomBndWall = horMomEq.newBoundaryWall() horMomBndWall = horMomEq.newBoundaryWall()
...@@ -330,42 +342,25 @@ def slim3d_setup(loop): ...@@ -330,42 +342,25 @@ def slim3d_setup(loop):
turbEq.setBoundary0Flux('vertical_bottom') turbEq.setBoundary0Flux('vertical_bottom')
for openBnd in eq._boundary_open: for openBnd in eq._boundary_open:
turbEq.addBoundaryCondition(openBnd.tag, turbEq.newInFluxBoundary(f.tinyFunc)) turbEq.addBoundaryCondition(openBnd.tag, turbEq.newInFluxBoundary(f.tinyFunc))
eta2dEq = e.eta2dEq
eta2dEq.setBoundary0Flux(eq._boundary_coast)
for openBnd in eq._boundary_open:
toReplaceEtaOpen = dgpy.VectorFunctorConst([uvAv2d, dgpy.function.getSolution()])
replaceByEtaOpen = dgpy.VectorFunctorConst([eq._uvAv2d_open[openBnd], eq._eta_open[openBnd]])
etaBndOpen = eta2dEq.newOutsideValueBoundaryGeneric("", toReplaceEtaOpen, replaceByEtaOpen)
eta2dEq.addBoundaryCondition(openBnd.tag, etaBndOpen)
uv2dEq = e.uv2dEq
uv2dBndWall = uv2dEq.newBoundaryWall()
uv2dEq.addBoundaryCondition(eq._boundary_coast,uv2dBndWall)
for openBnd in eq._boundary_open:
toReplaceUV2dOpen = dgpy.VectorFunctorConst([dgpy.function.getSolution(), eta])
replaceByUV2dOpen = dgpy.VectorFunctorConst([eq._uvAv2d_open[openBnd], eq._eta_open[openBnd]])
uv2dBndOpen = uv2dEq.newOutsideValueBoundaryGeneric("", toReplaceUV2dOpen, replaceByUV2dOpen)
uv2dEq.addBoundaryCondition(openBnd.tag, uv2dBndOpen)
# .-------------------------------. # .-------------------------------.
# | setup time integrator | # | setup time integrator |
# '-------------------------------' # '-------------------------------'
timeIntegrator = dgpy.slim3dTimeIntegratorPC(slimSolver) timeIntegrator = dgpy.slim3dTimeIntegratorPC(slimSolver)
rk = dgpy.dgERK(e.eta2dEq, None, dgpy.DG_ERK_EULER) # rk = dgpy.dgERK(e.eta2dEq, None, dgpy.DG_ERK_EULER)
dtRK = rk.computeInvSpectralRadius(d.etaDof2d) # dtRK = rk.computeInvSpectralRadius(d.etaDof2d)
CFL = 0.7236 # CFL = 0.7236
dt = CFL*dtRK # dt = CFL*dtRK
maxUV = 1.5 # max advective velocity # maxUV = 1.5 # max advective velocity
c2d = slim_private.math.sqrt(9.81*20.) # c2d = slim_private.math.sqrt(9.81*20.)
dt1 = c2d/(c2d+maxUV) * dt # dt1 = c2d/(c2d+maxUV) * dt
dt2 = min(dt1, loop._max_2d_dt) # dt2 = min(dt1, loop._max_2d_dt)
n_iter_per_export = numpy.ceil(loop._export_dt/(dt2*loop._dt2d3d_ratio)) # n_iter_per_export = numpy.ceil(loop._export_dt/(dt2*loop._dt2d3d_ratio))
dt = loop._export_dt/(n_iter_per_export*loop._dt2d3d_ratio) # dt = loop._export_dt/(n_iter_per_export*loop._dt2d3d_ratio)
n_iter_per_export = numpy.ceil(loop._export_dt/loop._dt)
dt = loop._export_dt/n_iter_per_export
if dgpy.Msg.GetCommRank() == 0 : if dgpy.Msg.GetCommRank() == 0 :
dgpy.Msg.Info('Runge-Kutta dt :' + str(dtRK) + ' CFL:' + str(CFL) + ' dt:' + str(dt)) dgpy.Msg.Info('dt_user :' + str(loop._dt) + ' dt:' + str(dt))
# .-------------------------------. # .-------------------------------.
# | setup export options | # | setup export options |
...@@ -375,7 +370,6 @@ def slim3d_setup(loop): ...@@ -375,7 +370,6 @@ def slim3d_setup(loop):
#timeIntegrator.setFullExportAtEveryTimeStep(False)