def make_func(self, discr, boundary_tag=None): from pymbolic import var def make_vec(basename): from hedge.tools import make_obj_array return make_obj_array( [var("%s%d" % (basename, i)) for i in range(self.dimensions)]) from hedge.optemplate.primitives import ScalarParameter from hedge.optemplate.tools import make_sym_vector x = make_sym_vector("x", discr.dimensions) fields = make_sym_vector("fields", self.arg_count) exprs = self.expressions_getter( t=ScalarParameter("t"), x=x, fields=fields) from hedge.optemplate.mappers.type_inference import ( type_info, NodalRepresentation) type_hints = {} if boundary_tag is not None: my_vec_type = type_info.BoundaryVector( boundary_tag, NodalRepresentation()) else: my_vec_type = type_info.VolumeVector( NodalRepresentation()) for x_i in x: type_hints[x_i] = my_vec_type for f_i in fields: type_hints[f_i] = my_vec_type return discr.compile(exprs, type_hints=type_hints)
def make_func(self, discr, boundary_tag=None): from pymbolic import var def make_vec(basename): from hedge.tools import make_obj_array return make_obj_array( [var("%s%d" % (basename, i)) for i in range(self.dimensions)]) from hedge.optemplate.primitives import ScalarParameter from hedge.optemplate.tools import make_sym_vector x = make_sym_vector("x", discr.dimensions) fields = make_sym_vector("fields", self.arg_count) exprs = self.expressions_getter(t=ScalarParameter("t"), x=x, fields=fields) from hedge.optemplate.mappers.type_inference import ( type_info, NodalRepresentation) type_hints = {} if boundary_tag is not None: my_vec_type = type_info.BoundaryVector(boundary_tag, NodalRepresentation()) else: my_vec_type = type_info.VolumeVector(NodalRepresentation()) for x_i in x: type_hints[x_i] = my_vec_type for f_i in fields: type_hints[f_i] = my_vec_type return discr.compile(exprs, type_hints=type_hints)
def make_bc_info(self, bc_name, tag, state, state0=None): """ :param state0: The boundary 'free-stream' state around which the BC is linearized. """ if state0 is None: state0 = make_sym_vector(bc_name, self.dimensions+2) state0 = cse(to_bdry_quad(state0)) rho0 = self.rho(state0) p0 = self.cse_p(state0) u0 = self.cse_u(state0) c0 = (self.equation_of_state.gamma * p0 / rho0)**0.5 from hedge.optemplate import BoundarizeOperator bdrize_op = BoundarizeOperator(tag) class SingleBCInfo(Record): pass return SingleBCInfo( rho0=rho0, p0=p0, u0=u0, c0=c0, # notation: suffix "m" for "minus", i.e. "interior" drhom=cse(self.rho(cse(to_bdry_quad(bdrize_op(state)))) - rho0, "drhom"), dumvec=cse(self.cse_u(cse(to_bdry_quad(bdrize_op(state)))) - u0, "dumvec"), dpm=cse(self.cse_p(cse(to_bdry_quad(bdrize_op(state)))) - p0, "dpm"))
def noslip_state(self, state): from hedge.optemplate import make_normal state0 = join_fields(make_sym_vector("bc_q_noslip", 2), [0] * self.dimensions) normal = make_normal(self.noslip_tag, self.dimensions) bc = self.make_bc_info("bc_q_noslip", self.noslip_tag, state, state0) return self.inflow_state_inner(normal, bc, "noslip")
def noslip_state(self, state): from hedge.optemplate import make_normal state0 = join_fields( make_sym_vector("bc_q_noslip", 2), [0]*self.dimensions) normal = make_normal(self.noslip_tag, self.dimensions) bc = self.make_bc_info("bc_q_noslip", self.noslip_tag, state, state0) return self.inflow_state_inner(normal, bc, "noslip")
def bind_characteristic_velocity(self, discr): state = make_sym_vector("q", self.dimensions+2) compiled = discr.compile( self.characteristic_velocity_optemplate(state)) def do(q): return compiled(q=q) return do
def bind_characteristic_velocity(self, discr): state = make_sym_vector("q", self.dimensions + 2) compiled = discr.compile( self.characteristic_velocity_optemplate(state)) def do(q): return compiled(q=q) return do
def get_conservative_boundary_conditions(self): state = self.state() from hedge.optemplate import BoundarizeOperator return { self.supersonic_inflow_tag: make_sym_vector("bc_q_supersonic_in", self.dimensions+2), self.supersonic_outflow_tag: BoundarizeOperator(self.supersonic_outflow_tag)( (state)), self.wall_tag: self.wall_state(state), }
def get_conservative_boundary_conditions(self): state = self.state() from hedge.optemplate import BoundarizeOperator return { self.supersonic_inflow_tag: make_sym_vector("bc_q_supersonic_in", self.dimensions + 2), self.supersonic_outflow_tag: BoundarizeOperator(self.supersonic_outflow_tag)((state)), self.wall_tag: self.wall_state(state), }
def make_bc_info(self, bc_name, tag, state, state0=None): """ :param state0: The boundary 'free-stream' state around which the BC is linearized. """ if state0 is None: state0 = make_sym_vector(bc_name, self.dimensions + 2) state0 = cse(to_bdry_quad(state0)) rho0 = self.rho(state0) p0 = self.cse_p(state0) u0 = self.cse_u(state0) c0 = (self.equation_of_state.gamma * p0 / rho0)**0.5 from hedge.optemplate import BoundarizeOperator bdrize_op = BoundarizeOperator(tag) class SingleBCInfo(Record): pass return SingleBCInfo( rho0=rho0, p0=p0, u0=u0, c0=c0, # notation: suffix "m" for "minus", i.e. "interior" drhom=cse( self.rho(cse(to_bdry_quad(bdrize_op(state)))) - rho0, "drhom"), dumvec=cse( self.cse_u(cse(to_bdry_quad(bdrize_op(state)))) - u0, "dumvec"), dpm=cse( self.cse_p(cse(to_bdry_quad(bdrize_op(state)))) - p0, "dpm"))
def op_template(self, sensor_scaling=None, viscosity_only=False): u = self.cse_u rho = self.cse_rho rho_u = self.rho_u p = self.p e = self.e # {{{ artificial diffusion def make_artificial_diffusion(): if self.artificial_viscosity_mode not in ["diffusion"]: return 0 dq = self.grad_of_state() return make_obj_array([ self.div( to_vol_quad(self.sensor())*to_vol_quad(dq[i]), to_int_face_quad(self.sensor())*to_int_face_quad(dq[i])) for i in range(dq.shape[0])]) # }}} # {{{ state setup volq_flux = self.flux(self.volq_state()) faceq_flux = self.flux(self.faceq_state()) from hedge.optemplate.primitives import CFunction sqrt = CFunction("sqrt") speed = self.characteristic_velocity_optemplate(self.state()) has_viscosity = not is_zero(self.get_mu(self.state(), to_quad_op=None)) # }}} # {{{ operator assembly ----------------------------------------------- from hedge.flux.tools import make_lax_friedrichs_flux from hedge.optemplate.operators import InverseMassOperator from hedge.optemplate.tools import make_stiffness_t primitive_bcs_as_quad_conservative = dict( (tag, self.primitive_to_conservative(to_bdry_quad(bc))) for tag, bc in self.get_primitive_boundary_conditions().iteritems()) def get_bc_tuple(tag): state = self.state() bc = make_obj_array([ self.get_boundary_condition_for(tag, s_i) for s_i in state]) return tag, bc, self.flux(bc) first_order_part = InverseMassOperator()( numpy.dot(make_stiffness_t(self.dimensions), volq_flux) - make_lax_friedrichs_flux( wave_speed=cse(to_int_face_quad(speed), "emax_c"), state=self.faceq_state(), fluxes=faceq_flux, bdry_tags_states_and_fluxes=[ get_bc_tuple(tag) for tag in self.get_boundary_tags()], strong=False)) if viscosity_only: first_order_part = 0*first_order_part result = join_fields( first_order_part + self.make_second_order_part() + make_artificial_diffusion() + self.make_extra_terms(), speed) if self.source is not None: result = result + join_fields( make_sym_vector("source_vect", len(self.state())), # extra field for speed 0) return result
def state(self): return make_sym_vector("q", self.dimensions+2)
def op_template(self, sensor_scaling=None, viscosity_only=False): u = self.cse_u rho = self.cse_rho rho_u = self.rho_u p = self.p e = self.e # {{{ artificial diffusion def make_artificial_diffusion(): if self.artificial_viscosity_mode not in ["diffusion"]: return 0 dq = self.grad_of_state() return make_obj_array([ self.div( to_vol_quad(self.sensor()) * to_vol_quad(dq[i]), to_int_face_quad(self.sensor()) * to_int_face_quad(dq[i])) for i in range(dq.shape[0]) ]) # }}} # {{{ state setup volq_flux = self.flux(self.volq_state()) faceq_flux = self.flux(self.faceq_state()) from hedge.optemplate.primitives import CFunction sqrt = CFunction("sqrt") speed = self.characteristic_velocity_optemplate(self.state()) has_viscosity = not is_zero(self.get_mu(self.state(), to_quad_op=None)) # }}} # {{{ operator assembly ----------------------------------------------- from hedge.flux.tools import make_lax_friedrichs_flux from hedge.optemplate.operators import InverseMassOperator from hedge.optemplate.tools import make_stiffness_t primitive_bcs_as_quad_conservative = dict( (tag, self.primitive_to_conservative(to_bdry_quad(bc))) for tag, bc in self.get_primitive_boundary_conditions().iteritems()) def get_bc_tuple(tag): state = self.state() bc = make_obj_array( [self.get_boundary_condition_for(tag, s_i) for s_i in state]) return tag, bc, self.flux(bc) first_order_part = InverseMassOperator()( numpy.dot(make_stiffness_t(self.dimensions), volq_flux) - make_lax_friedrichs_flux( wave_speed=cse(to_int_face_quad(speed), "emax_c"), state=self.faceq_state(), fluxes=faceq_flux, bdry_tags_states_and_fluxes=[ get_bc_tuple(tag) for tag in self.get_boundary_tags() ], strong=False)) if viscosity_only: first_order_part = 0 * first_order_part result = join_fields( first_order_part + self.make_second_order_part() + make_artificial_diffusion() + self.make_extra_terms(), speed) if self.source is not None: result = result + join_fields( make_sym_vector("source_vect", len(self.state())), # extra field for speed 0) return result
def state(self): return make_sym_vector("q", self.dimensions + 2)