def apply_analytical_solution(self): """ Read initial conditions for up0, up1 and p to update the fields """ sim = self.simulation funcs = { 'up0': sim.data['u0'] if 'u0' in sim.data else None, 'up1': sim.data['u1'] if 'u1' in sim.data else None, 'up2': sim.data['u2'] if 'u2' in sim.data else None, 'p': sim.data['p'], } ic = sim.input.get_value('initial_conditions', {}, 'dict(string:dict)') for name, info in ic.items(): name = str(name) if name not in funcs: continue func = funcs[name] if 'cpp_code' in info: # Initial condition given as a C++ code string cpp_code = str(info['cpp_code']) V = func.function_space() description = 'initial conditions for %r' % name # Update the function by running the C++ code ocellaris_interpolate(sim, cpp_code, description, V, func) else: # Initial condition given as a known field function field_name, func_name = info['function'].strip().split('/') field = self.simulation.fields[field_name] func.interpolate(field.get_variable(func_name))
def update(self, timestep_number, t, dt): """ Update the density field by advecting it for a time dt using the given divergence free velocity field """ timer = dolfin.Timer('Ocellaris update rho') sim = self.simulation if timestep_number != 1: # Update the previous values self.rho_pp.assign(self.rho_p) self.rho_p.assign(self.rho) # Check for steady solution every timestep, this can change over time force_static = sim.input.get_value('multiphase_solver/force_static', FORCE_STATIC, 'bool') if force_static: # Keep the existing solution self.rho.assign(self.rho_p) elif self.use_analytical_solution: # Use an analytical density field for testing other parts of Ocellaris cpp_code = sim.input.get_value('initial_conditions/rho_p/cpp_code', required_type='string') description = 'initial condition for rho_p' V = sim.data['Vrho'] ocellaris_interpolate(sim, cpp_code, description, V, self.rho) elif self.use_rk_method: # Strong-Stability-Preserving Runge-Kutta DG time integration self.rho.assign(self.rho_p) self.rho_explicit.assign(self.rho_p) self.rk.step(dt) else: # Compute global bounds if self.is_first_timestep: lo, hi = self.slope_limiter.set_global_bounds(self.rho) if self.slope_limiter.has_global_bounds: sim.log.info( 'Setting global bounds [%r, %r] in VariableDensity' % (lo, hi)) # Solve the implicit advection equation A = self.eq.assemble_lhs() b = self.eq.assemble_rhs() self.solver.solve(A, self.rho.vector(), b) self.slope_limiter.run() self.time_coeffs.assign(Constant([3 / 2, -2, 1 / 2])) sim.reporting.report_timestep_value('min(rho)', self.rho.vector().min()) sim.reporting.report_timestep_value('max(rho)', self.rho.vector().max()) timer.stop() # Stop timer before hook self.simulation.hooks.run_custom_hook('MultiPhaseModelUpdated') self.is_first_timestep = False
def update_prescribed_mesh_velocity(self): """ Move the mesh according to prescribed velocities """ sim = self.simulation Vmesh = sim.data['Vmesh'] for d, cpp_code in enumerate(self.cpp_codes): description = 'initial conditions for mesh vel %d' % d func = sim.data['u_mesh%d' % d] # Update the mesh velocity functions ocellaris_interpolate(sim, cpp_code, description, Vmesh, func) self.morph_mesh()
def get_height_func(): height = ocellaris_interpolate( simulation, height_function_cpp, 'Height function', Vmesh ) height.vector()[:] += height_function_mean return height
def setup_initial_conditions(simulation): """ Setup the initial values for the fields NOTE: this is never run on simulation restarts! """ simulation.log.info('Creating initial conditions') ic = simulation.input.get_value('initial_conditions', {}, 'Input') has_file = False for name in ic: name = str(name) if name == 'file': has_file = True continue elif 'p' not in name: ocellaris_error( 'Invalid initial condition', 'You have given initial conditions for %r but this does ' 'not seem to be a previous or pressure field.\n\n' 'Valid names: up0, up1, ... , p, cp, rho_p, ...' % name, ) elif name not in simulation.data: ocellaris_error( 'Invalid initial condition', 'You have given initial conditions for %r but this does ' 'not seem to be an existing field.' % name, ) func = simulation.data[name] V = func.function_space() description = 'initial conditions for %r' % name if 'cpp_code' in ic[name]: cpp_code = ic.get_value('%s/cpp_code' % name, required_type='string!') simulation.log.info(' C++ %s' % description) ocellaris_interpolate(simulation, cpp_code, description, V, func) elif 'function' in ic[name]: vardef = ic.get_value('%s/function' % name, required_type='string!') simulation.log.info(' Field function %s' % description) f = verify_field_variable_definition(simulation, vardef, description) dolfin.project(f, V, function=func) else: ocellaris_error( 'Invalid initial condition', 'You have not given "cpp_code" or "function" for %r' % name, ) # Some fields start out as copies, we do that here so that the input file # does not have to contain superfluous initial conditions comp_name_pairs = [('up_conv%d', 'up%d'), ('upp_conv%d', 'upp%d')] for cname_pattern, cname_main_pattern in comp_name_pairs: for d in range(simulation.ndim): cname = cname_pattern % d cname_main = cname_main_pattern % d if cname in ic: simulation.log.info( ' Leaving %s as set by initial condition' % cname) continue if cname not in simulation.data or cname_main not in ic: continue simulation.data[cname].assign(simulation.data[cname_main]) simulation.log.info(' Assigning initial value %s = %s' % (cname, cname_main)) if has_file: setup_initial_conditions_from_restart_file(simulation)