Beispiel #1
0
 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
Beispiel #2
0
 def atan_2(self, expr, x, y):
     self.using.add(Using(cplusplus.atan2))
     return self._makeTmp(cplusplus.atan2(x, y))
Beispiel #3
0
 def atan(self, expr, x):
     self.using.add(Using(cplusplus.atan))
     return self._makeTmp(cplusplus.atan(x))
Beispiel #4
0
 def AndCondition(self, expr, left, right):
     self.using.add(Using(cplusplus.and_))
     return self._makeTmp(cplusplus.and_(left, right))
Beispiel #5
0
 def abs(self, expr, x):
     self.using.add(Using(cplusplus.abs_))
     return self._makeTmp(cplusplus.abs_(x))
Beispiel #6
0
    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
Beispiel #7
0
 def tanh(self, expr, x):
     self.using.add(Using(cplusplus.tanh))
     return self._makeTmp(cplusplus.tanh(x))
Beispiel #8
0
 def power(self, expr, x, y):
     self.using.add(Using(cplusplus.pow_))
     return self._makeTmp(cplusplus.pow_(x, y))
Beispiel #9
0
 def sqrt(self, expr, x):
     self.using.add(Using(cplusplus.sqrt))
     return self._makeTmp(cplusplus.sqrt(x))
Beispiel #10
0
 def min_value(self, expr, left, right):
     self.using.add(Using(cplusplus.min_))
     return self._makeTmp(cplusplus.min_(left, right))
Beispiel #11
0
 def MaxValue(self, expr, left, right):
     self.using.add(Using(cplusplus.max_))
     return self._makeTmp(cplusplus.max_(left, right))
Beispiel #12
0
 def ln(self, expr, x):
     self.using.add(Using(cplusplus.log))
     return self._makeTmp(cplusplus.log(x))
Beispiel #13
0
 def exp(self, expr, x):
     self.using.add(Using(cplusplus.exp))
     return self._makeTmp(cplusplus.exp(x))
Beispiel #14
0
 def cosh(self, expr, x):
     self.using.add(Using(cplusplus.cosh))
     return self._makeTmp(cplusplus.cosh(x))