def flat_end_sin(x): from hedge.optemplate.primitives import CFunction from pymbolic.primitives import IfPositive from math import pi return IfPositive(-pi / 2 - x, -1, IfPositive(x - pi / 2, 1, CFunction("sin")(x)))
def ic_expr(t, x, fields): from hedge.optemplate import CFunction from pymbolic.primitives import IfPositive from pytools.obj_array import make_obj_array tanh = CFunction("tanh") sin = CFunction("sin") rho = 1 u0 = 0.05 w = 0.05 delta = 0.05 from hedge.optemplate.primitives import make_common_subexpression as cse u = cse( make_obj_array([ IfPositive(x[1] - 1 / 2, u0 * tanh(4 * (3 / 4 - x[1]) / w), u0 * tanh(4 * (x[1] - 1 / 4) / w)), u0 * delta * sin(2 * np.pi * (x[0] + 1 / 4)) ]), "u") return make_obj_array([ op.method.f_equilibrium(rho, alpha, u) for alpha in range(len(op.method)) ])
def op_template_struct(self, u=None): from hedge.optemplate import Field if u is None: u = Field("u") result = DecayFitDiscontinuitySensorBase\ .op_template_struct(self, u) from pymbolic.primitives import IfPositive from hedge.optemplate.primitives import ( CFunction, ScalarParameter) from math import pi from hedge.optemplate.primitives import make_common_subexpression as cse if self.correct_for_fit_error: decay_expt = cse(result.decay_expt_corrected, "decay_expt") else: decay_expt = cse(result.decay_expt, "decay_expt") def flat_end_sin(x): return IfPositive(-pi/2-x, -1, IfPositive(x-pi/2, 1, sin(x))) sin = CFunction("sin") isnan = CFunction("isnan") c_abs = CFunction("abs") visc_scale = Field("viscosity_scaling") result.sensor = IfPositive(c_abs(isnan(visc_scale)), ScalarParameter("max_viscosity_scaling"), 0.5*visc_scale * (1+flat_end_sin((decay_expt+2)*pi/2))) return result
def flux(self): from hedge.flux import (make_normal, FluxVectorPlaceholder, flux_max) from pymbolic.primitives import IfPositive d = self.dimensions w = FluxVectorPlaceholder((1 + d) + 1) u = w[0] v = w[1:d + 1] c = w[1 + d] normal = make_normal(self.dimensions) if self.flux_type == "central": return (u.int * numpy.dot(v.int, normal) + u.ext * numpy.dot(v.ext, normal)) * 0.5 elif self.flux_type == "lf": n_vint = numpy.dot(normal, v.int) n_vext = numpy.dot(normal, v.ext) return 0.5 * (n_vint * u.int + n_vext * u.ext) \ - 0.5 * (u.ext - u.int) \ * flux_max(c.int, c.ext) elif self.flux_type == "upwind": return (IfPositive( numpy.dot(normal, v.avg), numpy.dot(normal, v.int) * u.int, # outflow numpy.dot(normal, v.ext) * u.ext, # inflow )) else: raise ValueError, "invalid flux type"
def op_template(self, u=None): from pymbolic.primitives import IfPositive, Variable from hedge.optemplate.primitives import Field, ScalarParameter from hedge.optemplate.primitives import make_common_subexpression as cse from math import pi if u is None: u = Field("u") from hedge.optemplate.operators import ( MassOperator, FilterOperator, OnesOperator) mode_truncator = FilterOperator( persson_peraire_filter_response_function) truncated_u = mode_truncator(u) diff = u - truncated_u el_norm_squared_mass_diff_u = OnesOperator()(MassOperator()(diff)*diff) el_norm_squared_mass_u = OnesOperator()(MassOperator()(u)*u) capital_s_e = cse(el_norm_squared_mass_diff_u / el_norm_squared_mass_u, "S_e") sin = Variable("sin") log10 = Variable("log10") s_e = cse(log10(capital_s_e), "s_e") kappa = ScalarParameter("kappa") eps0 = ScalarParameter("eps0") s_0 = ScalarParameter("s_0") return IfPositive(s_0-self.kappa-s_e, 0, IfPositive(s_e-self.kappa-s_0, eps0, eps0/2*(1+sin(pi*(s_e-s_0)/self.kappa))))
def get_advection_flux(self, velocity): from grudge.flux import make_normal, FluxScalarPlaceholder from pymbolic.primitives import IfPositive u = FluxScalarPlaceholder(0) normal = make_normal(self.method.dimensions) if self.flux_type == "central": return u.avg * np.dot(normal, velocity) elif self.flux_type == "lf": return u.avg*np.dot(normal, velocity) \ + 0.5*la.norm(v)*(u.int - u.ext) elif self.flux_type == "upwind": return (np.dot(normal, velocity) * IfPositive( np.dot(normal, velocity), u.int, # outflow u.ext, # inflow )) else: raise ValueError("invalid flux type")
def weak_flux(self): from hedge.flux import make_normal, FluxScalarPlaceholder from pymbolic.primitives import IfPositive u = FluxScalarPlaceholder(0) normal = make_normal(self.dimensions) if self.flux_type == "central": return u.avg * numpy.dot(normal, self.v) elif self.flux_type == "lf": return u.avg*numpy.dot(normal, self.v) \ + 0.5*la.norm(self.v)*(u.int - u.ext) elif self.flux_type == "upwind": return (numpy.dot(normal, self.v) * IfPositive( numpy.dot(normal, self.v), u.int, # outflow u.ext, # inflow )) else: raise ValueError, "invalid flux type"
def flat_end_sin(x): return IfPositive(-pi/2-x, -1, IfPositive(x-pi/2, 1, sin(x)))