Пример #1
0
    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))
Пример #2
0
    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
Пример #3
0
    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()
Пример #4
0
 def get_height_func():
     height = ocellaris_interpolate(
         simulation, height_function_cpp, 'Height function', Vmesh
     )
     height.vector()[:] += height_function_mean
     return height
Пример #5
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)