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_vector_field x = make_vector_field("x", discr.dimensions) fields = make_vector_field("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 op_template(self): dim = self.dimensions q = make_vector_field('q', self.len_q) f2 = make_vector_field('f2', self.len_f2) w = join_fields(q, f2) dim_subset = (True,) * dim + (False,) * (3-dim) def pad_vec(v, subset): result = numpy.zeros((3,), dtype=object) result[numpy.array(subset, dtype=bool)] = v return result sigma = pad_vec(make_vector_field('sigma', dim),dim_subset) alpha = pad_vec(make_vector_field('alpha', dim),dim_subset) kappa = pad_vec(make_vector_field('kappa', dim),dim_subset) fluxes = self.flux(w, kappa) # Boundary conditions q_bc_stressfree = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(q) q_bc_stressfree_null = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(0) q_bc_fixed = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(q) q_bc_fixed_null = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(0) all_tags_and_bcs = [ (self.boundaryconditions_tag['stressfree'], q_bc_stressfree, q_bc_stressfree_null), (self.boundaryconditions_tag['fixed'], q_bc_fixed, q_bc_fixed_null) ] bdry_tag_state_flux = [(tag, bc, self.bdry_flux(bc, bc_null, tag)) for tag, bc, bc_null in all_tags_and_bcs] # Entire operator nabla = make_nabla(dim) res_q = (numpy.dot(nabla, fluxes) + InverseMassOperator() * (self.flux_num(q, fluxes, bdry_tag_state_flux))) res_q = self.add_sources(res_q) F2 = self.F2(w) P = self.P(q) v = self.v(q) if dim == 1: F = [P[0],v[0]] elif dim == 2: F = [P[0],P[2],v[0],v[1], P[2],P[1],v[1],v[0]] elif dim == 3: F = [P[0],P[5],P[4],v[0],v[2],v[1], P[5],P[1],P[3],v[1],v[2],v[0], P[4],P[3],P[2],v[2],v[1],v[0]] else: raise ValueError("Invalid dimension") res_f2 = numpy.zeros(self.len_f2, dtype=object) for i in range(dim): for j in range(dim*2): res_f2[i*dim*2+j] = (-1)*F2[i*dim*2+j]*alpha[i]-sigma[i]/kappa[i]*(F2[i*dim*2+j]+F[i*dim*2+j]) return join_fields(res_q, res_f2)
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_vector_field(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): q = make_vector_field('q', self.len_q) fluxes = self.flux(q) # Boundary conditions q_bc_stressfree = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(q) q_bc_stressfree_null = BoundarizeOperator(self.boundaryconditions_tag['stressfree'])(0) q_bc_fixed = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(q) q_bc_fixed_null = BoundarizeOperator(self.boundaryconditions_tag['fixed'])(0) all_tags_and_bcs = [ (self.boundaryconditions_tag['stressfree'], q_bc_stressfree, q_bc_stressfree_null), (self.boundaryconditions_tag['fixed'], q_bc_fixed, q_bc_fixed_null) ] bdry_tag_state_flux = [(tag, bc, self.bdry_flux(bc, bc_null, tag)) for tag, bc, bc_null in all_tags_and_bcs] # Entire operator nabla = make_nabla(self.dimensions) result = (numpy.dot(nabla, fluxes) + InverseMassOperator() * (self.flux_num(q, fluxes, bdry_tag_state_flux))) result = self.add_sources(result) return result
def noslip_state(self, state): from hedge.optemplate import make_normal state0 = join_fields( make_vector_field("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_vector_field("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_vector_field("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 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_vector_field("source_vect", len(self.state())), # extra field for speed 0) return result
def state(self): return make_vector_field("q", self.dimensions+2)