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 grudge.symbolic import RestrictToBoundary bdrize_op = RestrictToBoundary(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 grudge.symbolic 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 get_conservative_boundary_conditions(self): state = self.state() from grudge.symbolic import RestrictToBoundary return { self.supersonic_inflow_tag: make_sym_vector("bc_q_supersonic_in", self.dimensions+2), self.supersonic_outflow_tag: RestrictToBoundary(self.supersonic_outflow_tag)( state), self.wall_tag: self.wall_state(state), }
def sym_operator(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 grudge.symbolic.primitives import FunctionSymbol sqrt = FunctionSymbol("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 grudge.flux.tools import make_lax_friedrichs_flux from grudge.symbolic.operators import InverseMassOperator from grudge.symbolic.tools import make_stiffness_t primitive_bcs_as_quad_conservative = { tag: self.primitive_to_conservative(to_bdry_quad(bc)) for tag, bc in self.get_primitive_boundary_conditions().items()} 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)