Commit 887a580c authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Implementing operator function with values precomputing.

Implementing operator function test.
parent b8f20bba
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ class heatEquationSetter
      typedef tnlTestFunction< MeshType::meshDimensions, Real, Device > TestFunction;
      typedef tnlHeatEquationEocRhs< ExactOperator, TestFunction > RightHandSide;
      typedef tnlStaticVector < MeshType::meshDimensions, Real > Vertex;
      typedef tnlDirichletBoundaryConditions< MeshType, TestFunction, Real, Index > BoundaryConditions;
      typedef tnlDirichletBoundaryConditions< MeshType, TestFunction, Dimensions, Real, Index > BoundaryConditions;
      typedef tnlHeatEquationEocProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
      SolverStarter solverStarter;
      return solverStarter.template run< Solver >( parameters );
+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ class meanCurvatureFlowEocSetter
      typedef tnlTestFunction< MeshType::meshDimensions, Real, Device > TestFunction;
      typedef tnlMeanCurvatureFlowEocRhs< ExactOperator, TestFunction, Dimensions > RightHandSide;
      typedef tnlStaticVector < MeshType::meshDimensions, Real > Vertex;
      typedef tnlDirichletBoundaryConditions< MeshType, TestFunction, Real, Index > BoundaryConditions;
      typedef tnlDirichletBoundaryConditions< MeshType, TestFunction, Dimensions, Real, Index > BoundaryConditions;
      typedef tnlMeanCurvatureFlowEocProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
      SolverStarter solverStarter;
      return solverStarter.template run< Solver >( parameters );
+2 −2
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ class meanCurvatureFlowSetter
         typedef tnlConstantFunction< Dimensions, Real > ConstantFunction;
         if( boundaryConditionsType == "dirichlet" )
         {
            typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions;
            typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunction, Dimensions, Real, Index > BoundaryConditions;
            typedef tnlMeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
            SolverStarter solverStarter;
            return solverStarter.template run< Solver >( parameters );
@@ -125,7 +125,7 @@ class meanCurvatureFlowSetter
      typedef tnlMeshFunction< MeshType > MeshFunction;
      if( boundaryConditionsType == "dirichlet" )
      {
         typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions;
         typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, Dimensions, Real, Index > BoundaryConditions;
         typedef tnlMeanCurvatureFlowProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Solver;
         SolverStarter solverStarter;
         return solverStarter.template run< Solver >( parameters );
+3 −3
Original line number Diff line number Diff line
@@ -35,13 +35,13 @@ evaluate( OutMeshFunction& meshFunction,
   {
      case SpaceDomain:
      case MeshDomain:   
         return evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, all );
         evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, all );
         break;
      case MeshInteriorDomain:
         return evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, interior );
         evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, interior );
         break;
      case MeshBoundaryDomain:
         return evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, boundary );
         evaluateEntities( meshFunction, function, time, outFunctionMultiplicator, inFunctionMultiplicator, boundary );
         break;
   }         
}
+220 −7
Original line number Diff line number Diff line
@@ -20,22 +20,93 @@

#include <type_traits>
#include <core/tnlCuda.h>
#include <functions/tnlMeshFunction.h>

/***
 * This class evaluates given operator on given function.
 * The main role of this type is that the mesh function evaluator
 * evaluates this function only on the INTERIOR mesh entities.
 * This class evaluates given operator on given function. If the flag 
 * EvaluateOnFly is set on true, the values on particular mesh entities
 * are computed just  when operator() is called. If the EvaluateOnFly flag
 * is 'false', values on all mesh entities are evaluated by calling a method
 * refresh() they are stores in internal mesh function and the operator()
 * just returns precomputed values. If BoundaryConditions are void then the
 * values on the boundary mesh entities are undefined. In this case, the mesh
 * function evaluator evaluates this function only on the INTERIOR mesh entities.
 */

/*template< typename Operator,
template< typename Operator,
          typename MeshFunction,
          typename BoundaryConditions = void,
          bool StorageFlag = true >
class tnlOperatorFunction{};*/
          bool EvaluateOnFly = false >
class tnlOperatorFunction{};

/****
 * Specialization for 'On the fly' evaluation.
 */
template< typename Operator,
          typename MeshFunction,
          typename BoundaryConditions >
class tnlOperatorFunction< Operator, MeshFunction, BoundaryConditions, true>
 : public tnlDomain< Operator::getDimensions(), MeshDomain >
{   
   public:
      
      static_assert( MeshFunction::getDomainType() == MeshDomain ||
                     MeshFunction::getDomainType() == MeshInteriorDomain ||
                     MeshFunction::getDomainType() == MeshBoundaryDomain,
         "Only mesh functions may be used in the operator function. Use tnlExactOperatorFunction instead of tnlOperatorFunction." );
      static_assert( std::is_same< typename Operator::MeshType, typename MeshFunction::MeshType >::value,
          "Both, operator and mesh function must be defined on the same mesh." );
      static_assert( is_same< typename BoundaryConditions::MeshType, typename Operator::MeshType >::value,
         "The operator and the boundary conditions are defined on different mesh types." );
      
      typedef Operator OperatorType;
      typedef MeshFunction FunctionType;
      typedef typename OperatorType::MeshType MeshType;
      typedef typename OperatorType::RealType RealType;
      typedef typename OperatorType::DeviceType DeviceType;
      typedef typename OperatorType::IndexType IndexType;
      typedef BoundaryConditions BoundaryConditionsType;
      
      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
      
      tnlOperatorFunction(
         const OperatorType& operator_,
         const BoundaryConditionsType& boundaryConditions,
         const FunctionType& function )
      :  operator_( operator_ ), boundaryConditions( boundaryConditions ), function( function ){};
      
      void refresh() {};
      
      template< typename MeshEntity >
      __cuda_callable__
      RealType operator()(
         const MeshEntity& meshEntity,
         const RealType& time = 0 ) const
      {
         if( ! meshEntity.isBoundaryEntity() )
            return operator_( function, meshEntity, time );
         else
            return boundaryConditions( function, meshEntity, time );
      }
      
   protected:
      
      const Operator& operator_;
      
      const FunctionType& function;
      
      const BoundaryConditionsType& boundaryConditions;
      
      template< typename, typename > friend class tnlMeshFunctionEvaluator;
};

/****
 * Specialization for 'On the fly' evaluation and no boundary conditions.
 */
template< typename Operator,
          typename MeshFunction >
class tnlOperatorFunction : public tnlDomain< Operator::getDimensions(), Operator::getDomainType() >
class tnlOperatorFunction< Operator, MeshFunction, void, true >
 : public tnlDomain< Operator::getDimensions(), Operator::getDomainType() >
{   
   public:
      
@@ -60,6 +131,8 @@ class tnlOperatorFunction : public tnlDomain< Operator::getDimensions(), Operato
         const FunctionType& function )
      :  operator_( operator_ ), function( function ){};
      
      void refresh() {};
      
      template< typename MeshEntity >
      __cuda_callable__
      RealType operator()(
@@ -78,5 +151,145 @@ class tnlOperatorFunction : public tnlDomain< Operator::getDimensions(), Operato
      template< typename, typename > friend class tnlMeshFunctionEvaluator;
};

/****
 * Specialization for precomputed evaluation and no boundary conditions.
 */
template< typename Operator,
          typename MeshFunction >
class tnlOperatorFunction< Operator, MeshFunction, void, false >
 : public tnlDomain< Operator::getDimensions(), Operator::getDomainType() >
{   
   public:
      
      static_assert( MeshFunction::getDomainType() == MeshDomain ||
                     MeshFunction::getDomainType() == MeshInteriorDomain ||
                     MeshFunction::getDomainType() == MeshBoundaryDomain,
         "Only mesh functions may be used in the operator function. Use tnlExactOperatorFunction instead of tnlOperatorFunction." );
      static_assert( std::is_same< typename Operator::MeshType, typename MeshFunction::MeshType >::value,
          "Both, operator and mesh function must be defined on the same mesh." );
      
      typedef Operator OperatorType;
      typedef MeshFunction FunctionType;
      typedef typename OperatorType::MeshType MeshType;
      typedef typename OperatorType::RealType RealType;
      typedef typename OperatorType::DeviceType DeviceType;
      typedef typename OperatorType::IndexType IndexType;
      typedef tnlMeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType;
      typedef tnlOperatorFunction< Operator, MeshFunction, void, true > OperatorFunction;
      
      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
      
      tnlOperatorFunction(
         const OperatorType& operator_,
         const FunctionType& function )
      :  operator_( operator_ ), function( function ), imageFunction( function.getMesh() )
      {};
      
      ImageFunctionType& getImageFunction() { return this->imageFunction; };
      
      const ImageFunctionType& getImageFunction() const { return this->imageFunction; };
      
      void refresh()
      {
         this->function.refresh();
         OperatorFunction operatorFunction( this->operator_, this->function );
         this->imageFunction = operatorFunction;
      };
      
      template< typename MeshEntity >
      __cuda_callable__
      RealType operator()(
         const MeshEntity& meshEntity,
         const RealType& time = 0 ) const
      {
         return imageFunction[ meshEntity.getIndex() ];
      }
      
   protected:
      
      const Operator& operator_;
      
      const FunctionType& function;
      
      ImageFunctionType imageFunction;
      
      template< typename, typename > friend class tnlMeshFunctionEvaluator;
};

/****
 * Specialization for precomputed evaluation and with boundary conditions.
 */
template< typename Operator,
          typename MeshFunction,
          typename BoundaryConditions >
class tnlOperatorFunction< Operator, MeshFunction, BoundaryConditions, false >
  : public tnlDomain< Operator::getDimensions(), MeshDomain >
{   
   public:
      
      static_assert( MeshFunction::getDomainType() == MeshDomain ||
                     MeshFunction::getDomainType() == MeshInteriorDomain ||
                     MeshFunction::getDomainType() == MeshBoundaryDomain,
         "Only mesh functions may be used in the operator function. Use tnlExactOperatorFunction instead of tnlOperatorFunction." );
      static_assert( std::is_same< typename Operator::MeshType, typename MeshFunction::MeshType >::value,
          "Both, operator and mesh function must be defined on the same mesh." );
      static_assert( std::is_same< typename BoundaryConditions::MeshType, typename Operator::MeshType >::value,
         "The operator and the boundary conditions are defined on different mesh types." );      
      
      typedef Operator OperatorType;
      typedef MeshFunction FunctionType;
      typedef typename OperatorType::MeshType MeshType;
      typedef typename OperatorType::RealType RealType;
      typedef typename OperatorType::DeviceType DeviceType;
      typedef typename OperatorType::IndexType IndexType;
      typedef tnlMeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType;
      typedef BoundaryConditions BoundaryConditionsType;
      typedef tnlOperatorFunction< Operator, MeshFunction, BoundaryConditions, true > OperatorFunction;
      
      static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); };     
      
      tnlOperatorFunction(
         const OperatorType& operator_,
         const BoundaryConditionsType& boundaryConditions,
         const FunctionType& function )
      :  operator_( operator_ ), boundaryConditions( boundaryConditions ), function( function ), imageFunction( function.getMesh() )
      {};
      
      ImageFunctionType& getImageFunction() { return this->imageFunction; };
      
      const ImageFunctionType& getImageFunction() const { return this->imageFunction; };
      
      void refresh()
      {
         // TODO: Try to split it into evaluation first of interior and then of the boundary entities.
         this->function.refresh();
         OperatorFunction operatorFunction( this->operator_, this->boundaryConditions, this->function );
         this->imageFunction = operatorFunction;
      };
      
      template< typename MeshEntity >
      __cuda_callable__
      RealType operator()(
         const MeshEntity& meshEntity,
         const RealType& time = 0 ) const
      {
         return imageFunction[ meshEntity.getIndex() ];
      }
      
   protected:
      
      const Operator& operator_;
      
      const FunctionType& function;
      
      ImageFunctionType imageFunction;
      
      const BoundaryConditionsType& boundaryConditions;
      
      template< typename, typename > friend class tnlMeshFunctionEvaluator;
};



#endif	/* TNLOPERATORFUNCTION_H */
Loading