def spatial_coordinate(self, expr): try: return self._makeTmp(self.predefined[expr], True) except KeyError: self.using.add(Using(cplusplus.coordinate)) var = Variable('const auto', 'y') self.code.append(Declaration(var, 'entity().geometry().global( coordinate( x ) )')) return var
def atan_2(self, expr, x, y): self.using.add(Using(cplusplus.atan2)) return self._makeTmp(cplusplus.atan2(x, y))
def atan(self, expr, x): self.using.add(Using(cplusplus.atan)) return self._makeTmp(cplusplus.atan(x))
def AndCondition(self, expr, left, right): self.using.add(Using(cplusplus.and_)) return self._makeTmp(cplusplus.and_(left, right))
def abs(self, expr, x): self.using.add(Using(cplusplus.abs_)) return self._makeTmp(cplusplus.abs_(x))
def code(self, name=None, targs=None): # self.name = "Integrands" # self.targs = ['class GridPart'] # self.gridPartType = TypeAlias("GridPartType", "GridPart") # self.ctor_args = [] # self.ctor_init = [] # self.skeleton (None is no intersecton terms are needed) # self.init (code to be added to init(Entity) method # self.vars (further class variables) # self.methods(code) if name is not None: self.name = name if targs is not None: self.targs = targs code = Struct(self.className, targs=(self.targs + ['class ' + n for n in self.coefficientTypes]), bases=self.bases) code.append(self.gridPartType) code.append(TypeAlias("GridView", "typename GridPartType::GridViewType")) if self.bindable: code.append(TypeAlias("FunctionSpaceType", "Dune::Fem::GridFunctionSpace<GridPartType,Dune::Dim<"+str(self.dimRange)+">>")) code.append(TypeAlias("EntityType", "typename GridPartType::template Codim< 0 >::EntityType")) code.append(TypeAlias("IntersectionType", "typename GridPartType::IntersectionType")) code.append(TypeAlias("GlobalCoordinateType", "typename EntityType::Geometry::GlobalCoordinate")) code.append(TypeAlias("Side","Dune::Fem::IntersectionSide")) for type, alias in zip(self._constants, self.constantTypes): code.append(TypeAlias(alias, type)) constants = ["std::shared_ptr< " + c + " >" for c in self.constantTypes] if constants: code.append(TypeAlias("ConstantTupleType", "std::tuple< " + ", ".join(constants) + " >")) code.append(TypeAlias("ConstantsRangeType", "typename std::tuple_element_t< i, ConstantTupleType >::element_type", targs=["std::size_t i"])) else: code.append(TypeAlias("ConstantTupleType", "std::tuple<>")) if self._coefficients: coefficientSpaces = [('Dune::Fem::GridFunctionSpace< GridPartType, ' + c + ' >') for c in self._coefficients] code.append(TypeAlias("CoefficientFunctionSpaceTupleType", "std::tuple< " +", ".join(coefficientSpaces) + " >")) code.append(TypeAlias('CoefficientTupleType', 'std::tuple< ' + ', '.join(self.coefficientTypes) + ' >')) code.append(TypeAlias("CoefficientFunctionSpaceType", "std::tuple_element_t< i, CoefficientFunctionSpaceTupleType >", targs=["std::size_t i"])) for s in ["RangeType", "JacobianRangeType"]: code.append(TypeAlias("Coefficient" + s, "typename CoefficientFunctionSpaceType< i >::" + s, targs=["std::size_t i"])) code.append(Declaration(Variable("bool", "gridPartValid"), initializer=UnformattedExpression("bool"," && ".join(["Dune::Fem::checkGridPartValid<GridPartType,"+ "Dune::Fem::ConstLocalFunction<"+c+">>()" for c in self.coefficientTypes])), static=True, constexpr=True)) else: code.append(TypeAlias("CoefficientTupleType", "std::tuple<>")) code.append(Declaration(Variable("bool", "gridPartValid"), initializer="true", static=True, constexpr=True)) code.append(TypeAlias('CoefficientType', 'std::tuple_element_t< i, CoefficientTupleType >', targs=['std::size_t i'])) code.append(TypeAlias('ConstantType', 'typename std::tuple_element_t< i, ConstantTupleType >::element_type', targs=['std::size_t i'])) # if self.skeleton is not None: # code.append(EnumClass('Side', ['in = 0u', 'out = 1u'], 'std::size_t')) # inside = '[ static_cast< std::size_t >( Side::in ) ]' # else: # inside = '' if not self.bindable: if self.skeleton is None: entity_ = Variable('EntityType', 'entity_') insideEntity = entity_ else: entity_ = Variable('std::array< EntityType, 2 >', 'entity_') insideEntity = entity_[UnformattedExpression('std::size_t', 'static_cast< std::size_t >( Side::in )')] outsideEntity = entity_[UnformattedExpression('std::size_t', 'static_cast< std::size_t >( Side::out )')] intersection_ = Variable('IntersectionType', 'intersection_') else: code.append(Using(self.bindableBase+'::entity')) constants_ = Variable("ConstantTupleType", "constants_") coefficientsTupleType = 'std::tuple< ' + ', '.join('Dune::Fem::ConstLocalFunction< ' + n + ' >' for n in self.coefficientTypes) + ' >' if self.skeleton is None: coefficients_ = Variable(coefficientsTupleType, 'coefficients_') else: coefficients_ = Variable('std::array< ' + coefficientsTupleType + ', 2 >', 'coefficients_') # generate code for constructor arg_param = Variable('const Dune::Fem::ParameterReader &', 'parameter') if self.bindable: args = [ Variable('const GridPartType &','gridPart'), Variable('const std::string &','name'), Variable('int','order') ] else: args = [] args += self.ctor_args + [Variable('const ' + t + ' &', n) for t, n in zip(self.coefficientTypes, self.coefficientNames)] if self.bindable: init = [self.bindableBase+'(gridPart,name,order)'] else: init = [] if self._coefficients: coeffInit = ['Dune::Fem::ConstLocalFunction< ' + n + ' >( ' + p + ' )' for n, p in zip(self.coefficientTypes, self.coefficientNames)] if self.skeleton is None: init += ["coefficients_( " + ", ".join(coeffInit) + " )"] else: init += ['coefficients_{{ ' + coefficientsTupleType + '( ' + ', '.join(coeffInit) + ' ), ' + coefficientsTupleType + '( ' + ', '.join(coeffInit) + ' ) }}'] init = self.ctor_init + init args.append(Declaration(arg_param, initializer=UnformattedExpression('const ParameterReader &', 'Dune::Fem::Parameter::container()'))) constructor = Constructor(args=args, init=init) for idx, (cppType, value) in enumerate(zip(self.constantTypes, self.constantValues)): constructor.append(assign(get(idx)(constants_), make_shared(cppType)(cppType+"(0)"))) for idx, (name, cppType) in enumerate(zip(self._parameterNames, self.constantTypes)): if name is not None: constructor.append(assign(dereference(get(idx)(constants_)), UnformattedExpression('auto', arg_param.name + '.getValue< ' + cppType + ' >( "' + name + '" )', uses=[arg_param]))) code.append(constructor) entity = Variable('const EntityType &', 'entity') intersection = Variable('const IntersectionType &', 'intersection') if self.bindable: initEntity = Method('void', 'bind', args=[entity]) initEntity.append(self.bindableBase+'::bind(entity);') uninitEntity = Method('void', 'unbind') uninitEntity.append(self.bindableBase+'::unbind();') initIntersection = Method('void', 'bind', args=[intersection, Variable('Side', 'side')]) initIntersection.append(self.bindableBase+'::bind(intersection,side);') code.append(initIntersection) else: initEntity = Method('bool', 'init', args=[entity]) initEntity.append(assign(insideEntity, entity)) uninitEntity = Method('void', 'unbind') if self.skeleton is None: for i, c in enumerate(self._coefficients): initEntity.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + ' ).bind( entity )', uses=[entity, coefficients_])) uninitEntity.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + ').unbind( )', uses=[coefficients_])) else: for i, c in enumerate(self._coefficients): initEntity.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::in ) ] ).bind( entity )', uses=[entity, coefficients_])) initEntity.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::out ) ] ).bind( entity )', uses=[entity, coefficients_])) uninitEntity.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::in ) ] ).unbind( )', uses=[coefficients_])) uninitEntity.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::out ) ] ).unbind( )', uses=[coefficients_])) initEntity.append(self.init) if not self.bindable: initEntity.append(return_(True)) code.append(initEntity) code.append(uninitEntity) if not self.bindable: initIntersection = Method('bool', 'init', args=[intersection]) initIntersection.append(assign(intersection_, intersection)) if self.skeleton is None: initIntersection.append(return_('(intersection.boundary() && init( intersection.inside() ))')) else: initIntersection.append(assign(insideEntity, UnformattedExpression('EntityType', 'intersection.inside()'))) for i, c in enumerate(self._coefficients): # initIntersection.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::in ) ] ).bind( entity_[ static_cast< std::size_t >( Side::in ) ] )', uses=[coefficients_])) initIntersection.append(UnformattedExpression('void', 'std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::in ) ] ).bind( intersection_, Side::in )', uses=[coefficients_])) initIntersection.append('if( intersection.neighbor() )') initIntersection.append('{') initIntersection.append(' entity_[ static_cast< std::size_t >( Side::out ) ] = intersection.outside();') for i, c in enumerate(self._coefficients): # initIntersection.append(UnformattedExpression('void', ' std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::out ) ] ).bind( entity_[ static_cast< std::size_t >( Side::out ) ] )', uses=[coefficients_])) initIntersection.append(UnformattedExpression('void', ' std::get< ' + str(i) + ' >( ' + coefficients_.name + '[ static_cast< std::size_t >( Side::out ) ] ).bind( intersection_, Side::out )', uses=[coefficients_])) initIntersection.append('}') initIntersection.append(return_(True)) code.append(initIntersection) ################################ self.methods(code) ################################ code.append(Method('const ConstantType< i > &', 'constant', targs=['std::size_t i'], code=return_(dereference(get('i')(constants_))), const=True)) code.append(Method('ConstantType< i > &', 'constant', targs=['std::size_t i'], code=return_(dereference(get('i')(constants_))))) for i, (t, n) in enumerate(zip(self.constantTypes, self.constantNames)): code.append(Method('const ' + t + ' &', n, code=return_(dereference(get(i)(constants_))), const=True)) code.append(Method(t + ' &', n, code=return_(dereference(get(i)(constants_))))) if not self.bindable: code.append(Method('const EntityType &', 'entity', const=True, code=return_(insideEntity))) code.append(AccessModifier('private')) if self._coefficients: for cppType, name in self._derivatives: var = Variable('typename CoefficientFunctionSpaceType< i >::' + cppType, 'result') if self.skeleton is None: method = Method(var.cppType, name + 'Coefficient', targs=['std::size_t i', 'class Point'], args=['const Point &x'], const=True) method.append(Declaration(var)) method.append(UnformattedExpression('void', 'std::get< i >( coefficients_ ).' + name + '( x, ' + var.name + ' );')) method.append(return_(var)) code.append(method) else: method = Method(var.cppType, name + 'Coefficient', targs=['std::size_t i', 'Side side', 'class Point'], args=['const Point &x'], const=True) method.append(Declaration(var)) method.append(UnformattedExpression('void', 'std::get< i >( coefficients_[ static_cast< std::size_t >( side ) ] ).' + name + '( x, ' + var.name + ' )')) method.append(return_(var)) code.append(method) method = Method(var.cppType, name + 'Coefficient', targs=['std::size_t i', 'class Point'], args=['const Point &x'], const=True) method.append(return_(UnformattedExpression(var.cppType, name + 'Coefficient< i, Side::in >( x )'))) code.append(method) if not self.bindable: code.append(Declaration(entity_), Declaration(intersection_)) code.append(Declaration(constants_), Declaration(coefficients_)) if self.vars is not None: code += self.vars return code
def tanh(self, expr, x): self.using.add(Using(cplusplus.tanh)) return self._makeTmp(cplusplus.tanh(x))
def power(self, expr, x, y): self.using.add(Using(cplusplus.pow_)) return self._makeTmp(cplusplus.pow_(x, y))
def sqrt(self, expr, x): self.using.add(Using(cplusplus.sqrt)) return self._makeTmp(cplusplus.sqrt(x))
def min_value(self, expr, left, right): self.using.add(Using(cplusplus.min_)) return self._makeTmp(cplusplus.min_(left, right))
def MaxValue(self, expr, left, right): self.using.add(Using(cplusplus.max_)) return self._makeTmp(cplusplus.max_(left, right))
def ln(self, expr, x): self.using.add(Using(cplusplus.log)) return self._makeTmp(cplusplus.log(x))
def exp(self, expr, x): self.using.add(Using(cplusplus.exp)) return self._makeTmp(cplusplus.exp(x))
def cosh(self, expr, x): self.using.add(Using(cplusplus.cosh)) return self._makeTmp(cplusplus.cosh(x))