Commit 01725bae authored by Tomáš Oberhuber's avatar Tomáš Oberhuber
Browse files

Implementing operator composition.

parent dc1f0eab
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
/***************************************************************************
                          tnlFunction.h  -  description
                          tnlDomain.h  -  description
                             -------------------
    begin                : Nov 8, 2015
    copyright            : (C) 2015 by oberhuber
+4 −4
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ class tnlOperatorFunction : public tnlDomain< Operator::getDimensions(), Operato
      tnlOperatorFunction(
         const OperatorType& operator_,
         const FunctionType& function )
      :  operator_( &operator_ ), function( &function ){};
      :  operator_( operator_ ), function( function ){};
      
      template< typename MeshEntity >
      __cuda_callable__
@@ -57,14 +57,14 @@ class tnlOperatorFunction : public tnlDomain< Operator::getDimensions(), Operato
         const MeshEntity& meshEntity,
         const RealType& time = 0 ) const
      {
         return operator_->operator()( *function, meshEntity, time );
         return operator_( function, meshEntity, time );
      }
      
   protected:
      
      const Operator* operator_;
      const Operator& operator_;
      
      const FunctionType* function;
      const FunctionType& function;
      
      template< typename, typename > friend class tnlMeshFunctionEvaluator;
};
+7 −3
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@ class tnlCoFVMGradientNorm< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Inde
   typedef Device DeviceType;
   typedef Index IndexType;
   
   constexpr static int getImageMeshEntitiesDimensions() { return MeshType::getDimensionsCount() - 1; };
   
   tnlCoFVMGradientNorm()
   : epsSquare( 0.0 ){}

@@ -99,6 +101,8 @@ class tnlCoFVMGradientNorm< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Ind
   typedef Device DeviceType;
   typedef Index IndexType;
   
   constexpr static int getImageMeshEntitiesDimensions() { return MeshType::getDimensionsCount() - 1; };
   
   tnlCoFVMGradientNorm()
   : epsSquare( 0.0 ){}

@@ -213,6 +217,8 @@ class tnlCoFVMGradientNorm< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Ind
   typedef Device DeviceType;
   typedef Index IndexType;
   
   constexpr static int getImageMeshEntitiesDimensions() { return MeshType::getDimensionsCount() - 1; };
   
   tnlCoFVMGradientNorm()
   : epsSquare( 0.0 ){}   

@@ -440,7 +446,5 @@ class tnlCoFVMGradientNorm< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Ind
   RealType epsSquare;
};



#endif	/* TNLCOFVMGRADIENTNORM_H */
+284 −5
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
                          tnlMeshEntitiesInterpolants.h  -  description
                             -------------------
    begin                : Jan 25, 2016
    copyright            : (C) 2015 by Tomas Oberhuber
    copyright            : (C) 2016 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

@@ -18,13 +18,292 @@
#ifndef TNLMESHENTITIESINTERPOLANTS_H
#define	TNLMESHENTITIESINTERPOLANTS_H

template< typename InEntity,
          typename OutEntity,
          int InEntityDimensions = InEntity::getDimensions(),
          int OutEntityDimenions = OutEntity::getDimensions() >
#include <type_traits>
#include<functions/tnlDomain.h>

template< typename Mesh,
          int InEntityDimensions,
          int OutEntityDimenions >
class tnlMeshEntitiesInterpolants
{   
};

/***
 * 1D grid mesh entity interpolation: 1 -> 0 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 1, Real, Device, Index >, 1, 0 >
   : public tnlDomain< 1, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 1, Real, Device, Index > MeshType;

      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 1,
            "Mesh function must be defined on cells." );

         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );
         
         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();      
         
         return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1 >() ] + 
                        u[ neighbourEntities.template getEntityIndex<  1 >() ] );
      }
};

/***
 * 1D grid mesh entity interpolation: 0 -> 1 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 1, Real, Device, Index >, 0, 1 >
   : public tnlDomain< 1, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 1, Real, Device, Index > MeshType;

      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 0,
            "Mesh function must be defined on vertices (or faces in case on 1D grid)." );
         
         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );         
         
         const typename MeshEntity::template NeighbourEntities< 0 >& neighbourEntities = entity.getNeighbourEntities();      
         
         return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1 >() ] + 
                        u[ neighbourEntities.template getEntityIndex<  1 >() ] );
      }
};

/***
 * 2D grid mesh entity interpolation: 2 -> 1 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 2, 1 >
   : public tnlDomain< 2, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 2, Real, Device, Index > MeshType;
      
      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 2,
            "Mesh function must be defined on cells." );
         
         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );         
         
         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
         
         if( entity.getOrientation().x() == 1.0 )
            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1, 0 >() ] + 
                           u[ neighbourEntities.template getEntityIndex<  1, 0 >() ] );
         else
            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< 0, -1 >() ] + 
                           u[ neighbourEntities.template getEntityIndex< 0,  1 >() ] );
      }
};

/***
 * 2D grid mesh entity interpolation: 2 -> 0 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 2, 0 >
   : public tnlDomain< 2, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 2, Real, Device, Index > MeshType;

      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 2,
            "Mesh function must be defined on cells." );
         
         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );         
         
         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
                  
         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] + 
                         u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
                         u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] + 
                         u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] );
      }
};

/***
 * 2D grid mesh entity interpolation: 1 -> 2 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 1, 2 >
   : public tnlDomain< 2, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 2, Real, Device, Index > MeshType;

      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 1,
            "Mesh function must be defined on faces." );
         
         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );         
         
         const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities();      
                  
         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  0 >() ] + 
                         u[ neighbourEntities.template getEntityIndex<  1,  0 >() ] +
                         u[ neighbourEntities.template getEntityIndex<  0,  1 >() ] + 
                         u[ neighbourEntities.template getEntityIndex<  0, -1 >() ] );
      }
};

/***
 * 2D grid mesh entity interpolation: 0 -> 2 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 2, Real, Device, Index >, 0, 2 >
   : public tnlDomain< 2, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 2, Real, Device, Index > MeshType;

      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 1,
            "Mesh function must be defined on vertices." );

         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );         
         
         const typename MeshEntity::template NeighbourEntities< 0 >& neighbourEntities = entity.getNeighbourEntities();      
                  
         return 0.25 * ( u[ neighbourEntities.template getEntityIndex< -1,  1 >() ] + 
                         u[ neighbourEntities.template getEntityIndex<  1,  1 >() ] +
                         u[ neighbourEntities.template getEntityIndex< -1, -1 >() ] + 
                         u[ neighbourEntities.template getEntityIndex<  1, -1 >() ] );
      }
};

/***
 * 3D grid mesh entity interpolation: 3 -> 2 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 3, Real, Device, Index >, 3, 2 >
   : public tnlDomain< 3, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 3, Real, Device, Index > MeshType;

      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 3,
            "Mesh function must be defined on cells." );

         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );         
         
         const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities();      
                  
         if( entity.getOrientation().x() == 1.0 )
            return 0.5 * ( u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] + 
                           u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] );
         if( entity.getOrientation().y() == 1.0 )
            return 0.5 * ( u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] + 
                           u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] );
         else
            return 0.5 * ( u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] + 
                           u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] );            
      }
};

/***
 * 3D grid mesh entity interpolation: 2 -> 3 
 */
template< typename Real,
          typename Device,
          typename Index >
class tnlMeshEntitiesInterpolants< tnlGrid< 3, Real, Device, Index >, 2, 3 >
   : public tnlDomain< 3, MeshInteriorDomain >
{
   public:
      
      typedef tnlGrid< 3, Real, Device, Index > MeshType;

      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      Real operator()( const MeshFunction& u,
                       const MeshEntity& entity,
                       const Real& time = 0.0 ) const
      {
         static_assert( MeshFunction::getEntityDimensions() == 3,
            "Mesh function must be defined on faces." );

         static_assert( std::is_same< typename MeshEntity::MeshType, MeshType >::value,
            "The mesh entity belongs to other mesh type then the interpolants." );         
         
         const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities();      
                  
         return 1.0 / 6.0 * ( u[ neighbourEntities.template getEntityIndex< -1,  0,  0 >() ] + 
                              u[ neighbourEntities.template getEntityIndex<  1,  0,  0 >() ] +
                              u[ neighbourEntities.template getEntityIndex<  0, -1,  0 >() ] + 
                              u[ neighbourEntities.template getEntityIndex<  0,  1,  0 >() ] +
                              u[ neighbourEntities.template getEntityIndex<  0,  0, -1 >() ] + 
                              u[ neighbourEntities.template getEntityIndex<  0,  0,  1 >() ] );            
      }
};

#endif	/* TNLMESHENTITIESINTERPOLANTS_H */
+65 −0
Original line number Diff line number Diff line
/***************************************************************************
                          tnlOperatorComposition.h  -  description
                             -------------------
    begin                : Jan 30, 2016
    copyright            : (C) 2016 by Tomas Oberhuber
    email                : tomas.oberhuber@fjfi.cvut.cz
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef TNLOPERATORCOMPOSITION_H
#define	TNLOPERATORCOMPOSITION_H

#include<functions/tnlOperatorFunction.h>
#include<functions/tnlMeshFunction.h>

template< typename OuterOperator,
          typename InnerOperator >
class tnlOperatorComposition
   : public tnlDomain< InnerOperator::getDimensions(), InnerOperator::getDomainType() >
{
      static_assert( is_same< typename OuterOperator::MeshType, typename InnerOperator::MeshType >::value,
         "Both operators have different mesh types." );
   public:
      
      typedef typename InnerOperator::MeshType MeshType;
      typedef tnlOperatorFunction< InnerOperator, tnlMeshFunction< MeshType, InnerOperator::getImageMeshEntitiesDimensions() > > InnerOperatorFunction;
      typedef typename InnerOperator::RealType RealType;
      typedef typename InnerOperator::IndexType IndexType;
      
      tnlOperatorComposition( const OuterOperator& outerOperator,
                              const InnerOperator& innerOperator )
      : outerOperator( &outerOperator ), innerOperator( &innerOperator ) {};
      
      template< typename MeshFunction, typename MeshEntity >
      __cuda_callable__
      RealType operator()(
         const MeshFunction& function,
         const MeshEntity& meshEntity,
         const RealType& time = 0 ) const
      {
         static_assert( MeshFunction::getDimensions() == InnerOperator::getDimensions(),
            "Mesh function and operator have both different number of dimensions." );
         InnerOperatorFunction innerOperatorFunction( innerOperator, function );
         return outerOperator( innerOperatorFunction, meshEntity, time );
      }
      
   
   protected:
      
      const OuterOperator& outerOperator;
      
      const InnerOperator& innerOperator;
      
};

#endif	/* TNLOPERATORCOMPOSITION_H */
Loading