def __init__(self, simulation, var_name, inp_dict, subdomains, subdomain_id): """ Wall slip length (Navier) boundary condition where the slip length is multiplied by a slip factor ∈ [0, 1] that varies along the domain boundary depending on the distance to an interface (typically a free surface between two fluids). """ self.simulation = simulation vn = var_name[:-1] if var_name[-1].isdigit() else var_name self.func_space = simulation.data['V%s' % vn] dim = self.func_space.num_sub_spaces() default_base = 0.0 if dim == 0 else [0.0] * dim length = inp_dict.get_value('slip_length', required_type='any') base = inp_dict.get_value('value', default_base, 'float') vardef = inp_dict.get_value('slip_factor_function', required_type='string') # Use a subdomain as the slip factor (1.0 inside the domain and # 0.0 outside with a smooth transition) fac = verify_field_variable_definition(simulation, vardef, 'InterfaceSlipLength') fac_name = 'subdomain %s' % vardef.split('/')[0] self.register_slip_length_condition(var_name, length, fac, fac_name, base, subdomains, subdomain_id)
def read_input(self, field_inp): self.name = field_inp.get_value('name', required_type='string') field_name0 = field_inp.get_value('field0', required_type='string') field_name1 = field_inp.get_value('field1', required_type='string') blend_def = field_inp.get_value('blending_function', required_type='string') verify_key( 'blending field0', field_name0, self.simulation.fields, 'BlendedField %s' % self.name, ) verify_key( 'blending field1', field_name1, self.simulation.fields, 'BlendedField %s' % self.name, ) blend = verify_field_variable_definition(self.simulation, blend_def, 'BlendedField %s' % self.name) self.field0 = self.simulation.fields[field_name0] self.field1 = self.simulation.fields[field_name1] self.blending_function = blend
def __init__(self, simulation, var_name, inp_dict, subdomains, subdomain_id): """ Dirichlet boundary condition with value from a field function """ self.simulation = simulation # A var_name like "u0" should be given. Look up "Vu" self.func_space = simulation.data['V%s' % var_name[:-1]] # Get the field function expression object vardef = inp_dict.get_value('function', required_type='any') description = 'boundary condititon for %s' % var_name self.velocity = verify_field_variable_definition( simulation, vardef, description) field = simulation.fields[vardef.split('/')[0]] # The expression value is updated as the field is changed inp_dict.get_value('function', required_type='any') field.register_dependent_field(self) self.flux = dolfin.Constant(1.0) # Create the bc = OcellarisDirichletBC(self.simulation, self.func_space, self.flux, subdomains, subdomain_id) bcs = self.simulation.data['dirichlet_bcs'] bcs.setdefault(var_name, []).append(bc) self.simulation.log.info(' Field velocity valve for %s' % var_name) # Compute the region area, then update the flux mesh = simulation.data['mesh'] self.area = dolfin.assemble(self.flux * bc.ds()(domain=mesh)) self.region_names = inp_dict.get_value('regions', required_type='list(string)') self.update()
def __init__(self, simulation, var_name, inp_dict, subdomains, subdomain_id): """ Dirichlet boundary condition with value from a field function """ self.simulation = simulation if var_name[-1].isdigit(): # A var_name like "u0" was given. Look up "Vu" self.func_space = simulation.data['V%s' % var_name[:-1]] else: # A var_name like "u" was given. Look up "Vu" self.func_space = simulation.data['V%s' % var_name] # Get the field function expression object vardef = inp_dict.get_value('function', required_type='any') description = 'boundary condititon for %s' % var_name if isinstance(vardef, list): assert len(vardef) == simulation.ndim exprs = [ verify_field_variable_definition(simulation, vd, description) for vd in vardef ] else: expr = verify_field_variable_definition(simulation, vardef, description) if expr.ufl_shape != (): assert expr.ufl_shape == ( simulation.ndim, ), 'Expected shape %r got %r' % ( (simulation.ndim, ), expr.ufl_shape) exprs = [expr[d] for d in range(simulation.ndim)] else: exprs = [expr] # Register BCs if len(exprs) > 1: for d in range(simulation.ndim): name = '%s%d' % (var_name, d) self.register_dirichlet_condition(name, exprs[d], subdomains, subdomain_id) else: self.register_dirichlet_condition(var_name, exprs[0], subdomains, subdomain_id)
def get_data(self, name): """ Return a solver variable if one exists with the given name (p, u0, mesh, ...) or a known field function if no solver variable with the given name exists. Known field functions must be specified (as always) with forward slash separated field name and function name, e.g., "waves/c" """ if name in self.data: return self.data[name] else: return verify_field_variable_definition(self, name, 'Simulation.get_data()')
def add_forcing_zone(simulation, fzones, inp): """ Add a penalty forcing zone to the simulation """ name = inp.get_value('name', required_type='string') ztype = inp.get_value('type', required_type='string') penalty = inp.get_value('penalty', required_type='float') zone_vardef = inp.get_value('zone', required_type='string') target_vardef = inp.get_value('target', required_type='string') plot = inp.get_value('plot', False, required_type='bool') zone = verify_field_variable_definition( simulation, zone_vardef, 'forcing zone %r zone definition' % name) target = verify_field_variable_definition(simulation, target_vardef, 'forcing zone %r target' % name) verify_key( 'forcing zone type', ztype, ('MomentumForcing', 'ScalarForcing'), 'penalty forcing zone %s' % name, ) if ztype == 'MomentumForcing': varname = inp.get_value('variable', 'u', required_type='string') else: varname = inp.get_value('variable', required_type='string') fzones.setdefault(varname, []).append(ForcingZone(name, zone, target, penalty)) if plot: # Save zone blending function to a plot file for easy verification prefix = simulation.input.get_value('output/prefix', '', 'string') pfile = prefix + '_blending_zone_%s.pvd' % name zone.rename('beta', 'beta') dolfin.File(pfile) << zone
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)