Source code for oasismove.problems.NSfracStep.MovingTaylorGreen3D

import pickle
from os import getcwd

from oasismove.problems.NSfracStep import *
from oasismove.problems.NSfracStep.MovingCommon import get_visualization_writers

comm = MPI.comm_world


[docs]def problem_parameters( commandline_kwargs, NS_parameters, NS_expressions, **NS_namespace ): """ Problem file for running CFD simulation for the moving Taylor-Green problem in 3D as described by Fehn et al.[1]. The problem solves the N-S equations in the absence of body forces, and is commonly used to study transitional and turbulent flows. The problem initializes the solution at the two previous time steps, and applies periodic boundary condition on the domain walls in all coordinate directions. The domain boundaries are moving for the given mesh motion, while the fluid velocity is defined periodically in order to ensure consistency with the periodic boundary conditions. The main simulation parameters are the ampliture A, and period time duration T_G. [1] Fehn, N., Heinz, J., Wall, W. A., & Kronbichler, M. (2021). High-order arbitrary Lagrangian–Eulerian discontinuous Galerkin methods for the incompressible Navier–Stokes equations. Journal of Computational Physics, 430, 110040. """ if "restart_folder" in commandline_kwargs.keys(): restart_folder = commandline_kwargs["restart_folder"] restart_folder = path.join(getcwd(), restart_folder) f = open( path.join( path.dirname(path.abspath(__file__)), restart_folder, "params.dat" ), "rb", ) NS_parameters.update(pickle.load(f)) NS_parameters["restart_folder"] = restart_folder globals().update(NS_parameters) else: # Override some problem specific parameters NS_parameters.update( # Problem specific parameters L=2 * np.pi, # Mesh size A0=np.pi / 6, # Amplitude T_G=20, # Period time # Fluid parameters Re=1600, # Simulation parameters T=1, # End time dt=0.005, # Time step Nx=32, # Resolution in the x-direction Ny=32, # Resolution in the y-direction Nz=32, # Resolution in the z-direction folder="results_moving_taylor_green_3d", # Oasis parameters max_iter=2, dynamic_mesh=True, save_solution_frequency=5e10, save_step=5, checkpoint=500, print_intermediate_info=100, velocity_degree=1, pressure_degree=1, use_krylov_solvers=True, ) NS_expressions.update( dict( constrained_domain=PeriodicDomain(), kin=np.zeros(1), initial_fields_w=dict( w0="2 * pi * A / T_G * cos(2 * pi * t / T_G)" + "* sin(2 * pi * (x[1] + L/2)/L) * sin(2*pi* (x[2] + L/2)/L)", w1="2*pi*A/T_G*cos(2*pi*t/T_G) * sin(2*pi * (x[0] + L/2)/L) * sin(2*pi* (x[2] + L/2)/L)", w2="2*pi*A/T_G*cos(2*pi*t/T_G) * sin(2*pi * (x[0] + L/2)/L) * sin(2*pi* (x[1] + L/2)/L)", ), initial_fields=dict( u0="sin(x[0])*cos(x[1])*cos(x[2])", u1="-cos(x[0])*sin(x[1])*cos(x[2])", u2="0", p="1./16.*(cos(2*x[0])+cos(2*x[1]))*(cos(2*x[2])+2)", ), ) )
[docs]def mesh(Nx, Ny, Nz, L, dt, **params): mesh = BoxMesh( Point(-L / 2, -L / 2, -L / 2), Point(L / 2, L / 2, L / 2), Nx, Ny, Nz ) print_mesh_information(mesh, dt, u_mean=1) return mesh
[docs]def near(x, y, tol=1e-12): return bool(abs(x - y) < tol)
[docs]def pre_boundary_condition(mesh, Re, **NS_namespace): # Mark geometry boundary = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundary.set_all(0) inlet = AutoSubDomain(lambda x, b: b) inlet.mark(boundary, 1) # Update viscosity nu = 1 / Re return dict(boundary=boundary, nu=nu)
[docs]class PeriodicDomain(SubDomain):
[docs] def inside(self, x, on_boundary): return bool( (near(x[0], -pi) or near(x[1], -pi) or near(x[2], -pi)) and (not (near(x[0], pi) or near(x[1], pi) or near(x[2], pi))) and on_boundary )
[docs] def map(self, x, y): if near(x[0], pi) and near(x[1], pi) and near(x[2], pi): y[0] = x[0] - 2.0 * pi y[1] = x[1] - 2.0 * pi y[2] = x[2] - 2.0 * pi elif near(x[0], pi) and near(x[1], pi): y[0] = x[0] - 2.0 * pi y[1] = x[1] - 2.0 * pi y[2] = x[2] elif near(x[1], pi) and near(x[2], pi): y[0] = x[0] y[1] = x[1] - 2.0 * pi y[2] = x[2] - 2.0 * pi elif near(x[1], pi): y[0] = x[0] y[1] = x[1] - 2.0 * pi y[2] = x[2] elif near(x[0], pi) and near(x[2], pi): y[0] = x[0] - 2.0 * pi y[1] = x[1] y[2] = x[2] - 2.0 * pi elif near(x[0], pi): y[0] = x[0] - 2.0 * pi y[1] = x[1] y[2] = x[2] else: # near(x[2], pi): y[0] = x[0] y[1] = x[1] y[2] = x[2] - 2.0 * pi
[docs]def pre_solve_hook( V, mesh, A0, T_G, L, t, newfolder, initial_fields_w, velocity_degree, u_components, boundary, NS_expressions, **NS_namespace, ): # Visualization files viz_p, viz_u = get_visualization_writers(newfolder, ["pressure", "velocity"]) # Extract dof map and coordinates VV = VectorFunctionSpace(mesh, "CG", velocity_degree) u_vec = Function(VV, name="Velocity") coordinates = mesh.coordinates() if velocity_degree == 1: dof_map = vertex_to_dof_map(V) else: dof_map = V.dofmap().entity_dofs(mesh, 0) # Mesh velocity conditions bc_mesh = dict((ui, []) for ui in u_components) for u, w in zip(["u0", "u1", "u2"], ["w0", "w1", "w2"]): wall_motion = Expression( (initial_fields_w[w]), element=V.ufl_element(), t=t, A=A0, T_G=T_G, L=L ) NS_expressions[f"bc_{w}"] = wall_motion bc = DirichletBC(V, wall_motion, boundary, 1) bc_mesh[u] = [bc] return dict( viz_p=viz_p, viz_u=viz_u, u_vec=u_vec, dof_map=dof_map, bc_mesh=bc_mesh, coordinates=coordinates, )
[docs]def initialize(q_, q_1, q_2, VV, initial_fields, OasisFunction, **NS_namespace): for ui in q_: vv = OasisFunction( Expression((initial_fields[ui]), element=VV[ui].ufl_element()), VV[ui] ) vv() q_[ui].vector()[:] = vv.vector()[:] if not ui == "p": q_1[ui].vector()[:] = q_[ui].vector()[:] q_2[ui].vector()[:] = q_[ui].vector()[:]
[docs]def update_boundary_conditions(t, NS_expressions, **NS_namespace): for key, value in NS_expressions.items(): if "bc" in key: value.t = t
[docs]def temporal_hook( nu, L, dt, mesh, u_, save_solution_frequency, u_vec, viz_u, tstep, t, **NS_namespace ): # Save velocity and pressure if tstep % save_solution_frequency == 0: for i in range(3): assign(u_vec.sub(i), u_[i]) viz_u.write(u_vec, t) # Compute mean velocity and Reynolds number at inlet if tstep % 10 == 0: h = mesh.hmin() compute_flow_quantities( u_, L, nu, mesh, t, tstep, dt, h, outlet_area=1, boundary=None, outlet_ids=[], inlet_ids=[], id_wall=0, period=1.0, newfolder=None, dynamic_mesh=False, write_to_file=False, )