Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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()
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
 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()')
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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)