diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index b0d5d7f7d3f32843b3981c157aee52e5bff13fd5..0f00654e037cfb1ab253fa4276a57fc1f0f25126 100755 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,3 +1,5 @@ add_subdirectory( heat-equation ) add_subdirectory( navier-stokes ) +add_subdirectory( advection ) +add_subdirectory( inviscid-flow ) #add_subdirectory( mean-curvature-flow ) diff --git a/examples/advection/CMakeLists.txt b/examples/advection/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a7dfa1398d30ff61a3f5540e9b591c589d25b0ea --- /dev/null +++ b/examples/advection/CMakeLists.txt @@ -0,0 +1,20 @@ +set( tnl_heat_equation_SOURCES + advection.cpp + advection.cu ) + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE( tnl-advection{debugExt} advection.cu) + target_link_libraries( tnl-advection${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} ) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE( tnl-advection${debugExt} advection.cpp) + target_link_libraries( tnl-advection${debugExt} tnl${debugExt}-${tnlVersion} ) +ENDIF( BUILD_CUDA ) + + +INSTALL( TARGETS tnl-advection${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +INSTALL( FILES tnl-run-advection + ${tnl_heat_equation_SOURCES} + DESTINATION share/tnl-${tnlVersion}/examples/advection ) diff --git a/examples/advection/LaxFridrichs.h b/examples/advection/LaxFridrichs.h new file mode 100644 index 0000000000000000000000000000000000000000..85e445704e63a21eb79a35e21f2103a7e6873bfd --- /dev/null +++ b/examples/advection/LaxFridrichs.h @@ -0,0 +1,218 @@ +#ifndef LaxFridrichs_H +#define LaxFridrichs_H + +#include <core/vectors/tnlVector.h> +#include <mesh/tnlGrid.h> + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichs +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + Real tau; + double artificalViscosity; + double advectionSpeedX; + double advectionSpeedY; + + void setAdvectionSpeedY(const double advectionSpeed) + { + this->advectionSpeedY = advectionSpeed; + } + + + void setAdvectionSpeedX(const double advectionSpeed) + { + this->advectionSpeedX = advectionSpeed; + } + + void setViscosity(const double artificalViscosity) + { + this->artificalViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + Real tau; + double artificalViscosity; + double advectionSpeedX; + double advectionSpeedY; + + void setAdvectionSpeedY(const double advectionSpeed) + { + this->advectionSpeedY = advectionSpeed; + } + + + void setAdvectionSpeedX(const double advectionSpeed) + { + this->advectionSpeedX = advectionSpeed; + } + + void setViscosity(const double artificalViscosity) + { + this->artificalViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + Real tau; + double artificalViscosity; + double advectionSpeedX; + double advectionSpeedY; + + void setAdvectionSpeedY(const double advectionSpeed) + { + this->advectionSpeedY = advectionSpeed; + } + + + void setAdvectionSpeedX(const double advectionSpeed) + { + this->advectionSpeedX = advectionSpeed; + } + + void setViscosity(const double artificalViscosity) + { + this->artificalViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + + +#include "LaxFridrichs_impl.h" + +#endif /* LaxFridrichs_H */ diff --git a/examples/advection/LaxFridrichs_impl.h b/examples/advection/LaxFridrichs_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..a82fca1d3613ec5d95b5ba8fca64cfaf9a3cb0d8 --- /dev/null +++ b/examples/advection/LaxFridrichs_impl.h @@ -0,0 +1,369 @@ +#ifndef LaxFridrichs_IMPL_H +#define LaxFridrichs_IMPL_H + +/**** + * 1D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + double a; + a = this->advectionSpeedX; + return (0.5 / this->tau ) * this->artificalViscosity * + ( u[ west ] + - 2.0 * u[ center ] + + u[ east ] ) + - (a * ( u[ east ] + - u[west] ) ) + * hxInverse * 0.5; + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + matrixRow.setElement( 0, west, - lambdaX ); + matrixRow.setElement( 1, center, 2.0 * lambdaX ); + matrixRow.setElement( 2, east, - lambdaX ); +} + +/**** + * 2D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + double a; + double b; + a = this->advectionSpeedX; + b = this->advectionSpeedY; + return ( 0.25 / this->tau ) * this->artificalViscosity * ( + u[ west ] + + u[ east ] + + u[ south ] + + u[ north ] + - 4 * u[ center ] ) + - (a * ( u[ east ] + - u[west] ) ) + * hxInverse * 0.5 + - (b * ( u[ south ] + - u[ south ] ) ) + * hyInverse * 0.5; + + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + matrixRow.setElement( 0, south, -lambdaY ); + matrixRow.setElement( 1, west, -lambdaX ); + matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) ); + matrixRow.setElement( 3, east, -lambdaX ); + matrixRow.setElement( 4, north, -lambdaY ); +} + +/**** + * 3D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighbourEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighbourEntities.template getEntityIndex< 0, 0, -1 >(); + return ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) * hxSquareInverse + + ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse + + ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& lambdaZ = tau * entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighbourEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighbourEntities.template getEntityIndex< 0, 0, -1 >(); + matrixRow.setElement( 0, down, -lambdaZ ); + matrixRow.setElement( 1, south, -lambdaY ); + matrixRow.setElement( 2, west, -lambdaX ); + matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) ); + matrixRow.setElement( 4, east, -lambdaX ); + matrixRow.setElement( 5, north, -lambdaY ); + matrixRow.setElement( 6, up, -lambdaZ ); +} + +#endif /* LaxFridrichsIMPL_H */ + diff --git a/examples/advection/advection.cpp b/examples/advection/advection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..374d4714086168f7ebf1ed2a62664c4aaae0c4b7 --- /dev/null +++ b/examples/advection/advection.cpp @@ -0,0 +1 @@ +#include "advection.h" diff --git a/examples/advection/advection.cu b/examples/advection/advection.cu new file mode 100644 index 0000000000000000000000000000000000000000..374d4714086168f7ebf1ed2a62664c4aaae0c4b7 --- /dev/null +++ b/examples/advection/advection.cu @@ -0,0 +1 @@ +#include "advection.h" diff --git a/examples/advection/advection.h b/examples/advection/advection.h new file mode 100644 index 0000000000000000000000000000000000000000..7c722df204506bd0977dd5eec1b231e84fd1f8e2 --- /dev/null +++ b/examples/advection/advection.h @@ -0,0 +1,116 @@ +#include <tnlConfig.h> +#include <solvers/tnlSolver.h> +#include <solvers/tnlBuildConfigTags.h> +#include <operators/tnlDirichletBoundaryConditions.h> +#include <operators/tnlNeumannBoundaryConditions.h> +#include <functions/tnlConstantFunction.h> +#include "advectionProblem.h" +#include "LaxFridrichs.h" +#include "advectionRhs.h" +#include "advectionBuildConfigTag.h" + +typedef advectionBuildConfigTag BuildConfig; + +/**** + * Uncoment the following (and comment the previous line) for the complete build. + * This will include support for all floating point precisions, all indexing types + * and more solvers. You may then choose between them from the command line. + * The compile time may, however, take tens of minutes or even several hours, + * esppecially if CUDA is enabled. Use this, if you want, only for the final build, + * not in the development phase. + */ +//typedef tnlDefaultConfigTag BuildConfig; + +template< typename ConfigTag >class advectionConfig +{ + public: + static void configSetup( tnlConfigDescription & config ) + { + config.addDelimiter( "advection settings:" ); + config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); + config.addEntryEnum< tnlString >( "dirichlet" ); + config.addEntryEnum< tnlString >( "neumann" ); + config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." ); + config.addEntry< double >( "artifical-viscosity", "This sets value of artifical viscosity (default 1)", 1.0); + config.addEntry< tnlString >( "begin", "choose begin type", "sin"); + config.addEntryEnum< tnlString >( "sin"); + config.addEntryEnum< tnlString >( "sin_square"); + config.addEntry< double >( "advection-speedX", "This sets value of advection speed in X direction (default 1)" , 1.0); + config.addEntry< double >( "advection-speedY", "This sets value of advection speed in Y direction (default 1)" , 1.0); + config.addEntry< tnlString >( "move", "choose movement type", "advection"); + config.addEntryEnum< tnlString >( "advection"); + config.addEntryEnum< tnlString >( "rotation"); + + /**** + * Add definition of your solver command line arguments. + */ + + } +}; + +template< typename Real, + typename Device, + typename Index, + typename MeshType, + typename ConfigTag, + typename SolverStarter > +class advectionSetter +{ + public: + + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + static bool run( const tnlParameterContainer & parameters ) + { + enum { Dimensions = MeshType::getMeshDimensions() }; + typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator; + typedef advectionRhs< MeshType, Real > RightHandSide; + typedef tnlStaticVector < MeshType::getMeshDimensions(), Real > Vertex; + + /**** + * Resolve the template arguments of your solver here. + * The following code is for the Dirichlet and the Neumann boundary conditions. + * Both can be constant or defined as descrete values of tnlVector. + */ + tnlString boundaryConditionsType = parameters.getParameter< tnlString >( "boundary-conditions-type" ); + if( parameters.checkParameter( "boundary-conditions-constant" ) ) + { + typedef tnlConstantFunction< Dimensions, Real > ConstantFunction; + if( boundaryConditionsType == "dirichlet" ) + { + typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions; + typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlMeshFunction< MeshType > MeshFunction; + if( boundaryConditionsType == "dirichlet" ) + { + typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions; + typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + +}; + +int main( int argc, char* argv[] ) +{ + tnlSolver< advectionSetter, advectionConfig, BuildConfig > solver; + if( ! solver. run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + diff --git a/examples/advection/advectionBuildConfigTag.h b/examples/advection/advectionBuildConfigTag.h new file mode 100644 index 0000000000000000000000000000000000000000..a8ea6ddef4eba8fa8802a3ae41f7ceefe1628273 --- /dev/null +++ b/examples/advection/advectionBuildConfigTag.h @@ -0,0 +1,43 @@ +#ifndef advectionBUILDCONFIGTAG_H_ +#define advectionBUILDCONFIGTAG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class advectionBuildConfigTag{}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< advectionBuildConfigTag, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< advectionBuildConfigTag, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< advectionBuildConfigTag, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< advectionBuildConfigTag, long int >{ enum { enabled = false }; }; + +/**** + * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types. + */ + +template< int Dimensions, typename Real, typename Device, typename Index > + struct tnlConfigTagMesh< advectionBuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< advectionBuildConfigTag, Dimensions >::enabled && + tnlConfigTagReal< advectionBuildConfigTag, Real >::enabled && + tnlConfigTagDevice< advectionBuildConfigTag, Device >::enabled && + tnlConfigTagIndex< advectionBuildConfigTag, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< advectionBuildConfigTag, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< advectionBuildConfigTag, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< advectionBuildConfigTag, tnlImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< advectionBuildConfigTag, tnlExplicitEulerSolverTag >{ enum { enabled = true }; }; + +#endif /* advectionBUILDCONFIGTAG_H_ */ diff --git a/examples/advection/advectionProblem.h b/examples/advection/advectionProblem.h new file mode 100644 index 0000000000000000000000000000000000000000..64ae07480c584cacf3647d09c5bf075ad0f67ce8 --- /dev/null +++ b/examples/advection/advectionProblem.h @@ -0,0 +1,83 @@ +#ifndef advectionPROBLEM_H_ +#define advectionPROBLEM_H_ + +#include <problems/tnlPDEProblem.h> +#include <functions/tnlMeshFunction.h> + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +class advectionProblem: + public tnlPDEProblem< Mesh, + typename DifferentialOperator::RealType, + typename Mesh::DeviceType, + typename DifferentialOperator::IndexType > +{ + public: + + typedef typename DifferentialOperator::RealType RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef typename DifferentialOperator::IndexType IndexType; + typedef tnlMeshFunction< Mesh > MeshFunctionType; + typedef tnlPDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; + + using typename BaseType::MeshType; + using typename BaseType::DofVectorType; + using typename BaseType::MeshDependentDataType; + tnlString velocityType; + static tnlString getTypeStatic(); + + tnlString getPrologHeader() const; + + void writeProlog( tnlLogger& logger, + const tnlParameterContainer& parameters ) const; + + bool setup( const tnlParameterContainer& parameters ); + + bool setInitialCondition( const tnlParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ); + + template< typename Matrix > + bool setupLinearSystem( const MeshType& mesh, + Matrix& matrix ); + + bool makeSnapshot( const RealType& time, + const IndexType& step, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ); + + IndexType getDofs( const MeshType& mesh ) const; + + void bindDofs( const MeshType& mesh, + DofVectorType& dofs ); + + void getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + DofVectorType& _fu, + MeshDependentDataType& meshDependentData ); + + template< typename Matrix > + void assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& dofs, + Matrix& matrix, + DofVectorType& rightHandSide, + MeshDependentDataType& meshDependentData ); + + protected: + + DifferentialOperator differentialOperator; + BoundaryCondition boundaryCondition; + RightHandSide rightHandSide; +}; + +#include "advectionProblem_impl.h" + +#endif /* advectionPROBLEM_H_ */ diff --git a/examples/advection/advectionProblem_impl.h b/examples/advection/advectionProblem_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..7d7c324d5ae1d6d2b90ee73827101743461bba2a --- /dev/null +++ b/examples/advection/advectionProblem_impl.h @@ -0,0 +1,317 @@ +#ifndef advectionPROBLEM_IMPL_H_ +#define advectionPROBLEM_IMPL_H_ + +#include <core/mfilename.h> +#include <matrices/tnlMatrixSetter.h> +#include <solvers/pde/tnlExplicitUpdater.h> +#include <solvers/pde/tnlLinearSystemAssembler.h> +#include <solvers/pde/tnlBackwardTimeDiscretisation.h> + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +tnlString +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getTypeStatic() +{ + return tnlString( "advectionProblem< " ) + Mesh :: getTypeStatic() + " >"; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +tnlString +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getPrologHeader() const +{ + return tnlString( "advection" ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const +{ + /**** + * Add data you want to have in the computation report (log) as follows: + * logger.writeParameter< double >( "Parameter description", parameter ); + */ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setup( const tnlParameterContainer& parameters ) +{ + if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) || + ! this->rightHandSide.setup( parameters, "right-hand-side-" ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +typename advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getDofs( const MeshType& mesh ) const +{ + /**** + * Return number of DOFs (degrees of freedom) i.e. number + * of unknowns to be resolved by the main solver. + */ + return mesh.template getEntitiesCount< typename MeshType::Cell >(); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +bindDofs( const MeshType& mesh, + DofVectorType& dofVector ) +{ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setInitialCondition( const tnlParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + typedef typename MeshType::Cell Cell; + int count = mesh.template getEntitiesCount< Cell >(); + const RealType& size = 1;//mesh.template getSpaceStepsProducts< -1, 0 >(); + const tnlString& beginChoice = parameters.getParameter< tnlString >( "begin" ); + int dimensions = 2; //vyresit!!!! + if (beginChoice == "sin_square") + { + double constantFunction; + if (dimensions == 1) + { + dofs[0] = 0; + double expValue; + for (long int i = 1; i < count; i++) + { + expValue = exp(-pow(size*i-2,2)); + if ((i>0.4*count) && (i<0.5*count)) constantFunction=1; else constantFunction=0; + if (expValue>constantFunction) dofs[i] = expValue; else dofs[i] = constantFunction; + }; + dofs[count] = 0; + }; + if (dimensions == 2) + { + double expValue; + for (long int i = 1; i < count; i++) + for (long int j = 1; j < count; j++) + { + expValue = exp(-pow(size*i-2,2)-pow(size*j-2,2)); + if ((i>0.4*count) && (i<0.5*count)&&((j>0.4*count) && (j<0.5*count))) constantFunction=1; else constantFunction=0; + if (expValue>constantFunction) dofs[(i-1) * count -1+ j] = expValue; else dofs[(i-1) * count -1+ j] = constantFunction; + }; + }; + } + else if (beginChoice == "sin") + { + if (dimensions == 1) + { + dofs[0] = 0; + for (long int i = 1; i < count; i++) + { + dofs[i] = exp(-pow(size*i-2,2)); + }; + dofs[count] = 0; + }; + if (dimensions == 2) + { + for (long int i = 1; i < count; i++) + for (long int j = 1; j < count; j++) + { + dofs[(i-1) * count -1+ j] = exp(-pow(size*i-2,2)-pow(size*j-2,2)); + }; + }; + }; +//setting velocity field + + + /*const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" ); + if( ! dofs.load( initialConditionFile ) ) + { + cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << endl; + return false; + } + return true;*/ + dofs.save( "dofs.tnl" ); + this->velocityType = parameters.getParameter< tnlString >( "move" ); + const double artificalViscosity = parameters.getParameter< double >( "artifical-viscosity" ); + differentialOperator.setViscosity(artificalViscosity); + const double advectionSpeedX = parameters.getParameter< double >( "advection-speedX" ); + differentialOperator.setAdvectionSpeedX(advectionSpeedX); + const double advectionSpeedY = parameters.getParameter< double >( "advection-speedY" ); + differentialOperator.setAdvectionSpeedY(advectionSpeedY); + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > + template< typename Matrix > +bool +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setupLinearSystem( const MeshType& mesh, + Matrix& matrix ) +{ + const IndexType dofs = this->getDofs( mesh ); + typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVectorType; + CompressedRowsLengthsVectorType rowLengths; + if( ! rowLengths.setSize( dofs ) ) + return false; + tnlMatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter; + matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh, + differentialOperator, + boundaryCondition, + rowLengths ); + matrix.setDimensions( dofs, dofs ); + if( ! matrix.setCompressedRowsLengths( rowLengths ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +makeSnapshot( const RealType& time, + const IndexType& step, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + cout << endl << "Writing output at time " << time << " step " << step << "." << endl; + this->bindDofs( mesh, dofs ); + tnlString fileName; + FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName ); + if( ! dofs.save( fileName ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + DofVectorType& _fu, + MeshDependentDataType& meshDependentData ) +{ + /**** + * If you use an explicit solver like tnlEulerSolver or tnlMersonSolver, you + * need to implement this method. Compute the right-hand side of + * + * d/dt u(x) = fu( x, u ) + * + * You may use supporting mesh dependent data if you need. + */ + typedef typename MeshType::Cell Cell; + int count = mesh.template getEntitiesCount< Cell >(); + const RealType& size = 1;//mesh.template getSpaceStepsProducts< -1, 0 >(); + if (this->velocityType == "rotation") + { + double radius; + for (int i =1; i < count; i++) + for (int j =1; j < count; j++) + { + radius = sqrt(pow(i-1-(count/2.0),2) + pow(j-1-(count/2.0),2)); + if (radius != 0.0) + _fu[(i-1)*count+j-1] =(0.25*tau)*differentialOperator.artificalViscosity* //smoothening part + (_u[(i-1)*count-2+j]+_u[(i-1)*count+j]+ + _u[i*count+j-1]+_u[(i-2)*count+j-1]- + 4.0*_u[(i-1)*count+j-1]) + -((1.0/(2.0*count))*differentialOperator.advectionSpeedX //X addition + *radius*(-1)*((j-1-(count/2.0))/radius) + *(_u[(i-1)*count+j]-_u[(i-1)*count+j-2])) + -((1.0/(2.0*count))*differentialOperator.advectionSpeedY //Y addition + *radius*((i-1-(count/2.0))/radius) + *(_u[i*count+j-1]-_u[(i-2)*count+j-1])) + ;} + } + else if (this->velocityType == "advection") + { + this->bindDofs( mesh, _u ); + tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater; + MeshFunctionType u( mesh, _u ); + MeshFunctionType fu( mesh, _fu ); + explicitUpdater.template update< typename Mesh::Cell >( time, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + fu ); + tnlBoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter; + boundaryConditionsSetter.template apply< typename Mesh::Cell >( + this->boundaryCondition, + time + tau, + u ); + } +} +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > + template< typename Matrix > +void +advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + Matrix& matrix, + DofVectorType& b, + MeshDependentDataType& meshDependentData ) +{ + tnlLinearSystemAssembler< Mesh, + MeshFunctionType, + DifferentialOperator, + BoundaryCondition, + RightHandSide, + tnlBackwardTimeDiscretisation, + Matrix, + DofVectorType > systemAssembler; + + tnlMeshFunction< Mesh > u( mesh, _u ); + systemAssembler.template assembly< typename Mesh::Cell >( time, + tau, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + matrix, + b ); +} + +#endif /* advectionPROBLEM_IMPL_H_ */ diff --git a/examples/advection/advectionRhs.h b/examples/advection/advectionRhs.h new file mode 100644 index 0000000000000000000000000000000000000000..3bd2c294e142cac0779f66bdc99da51dc572222b --- /dev/null +++ b/examples/advection/advectionRhs.h @@ -0,0 +1,29 @@ +#ifndef advectionRHS_H_ +#define advectionRHS_H_ +#include<functions/tnlDomain.h> +template< typename Mesh, typename Real >class advectionRhs + : public tnlDomain< Mesh::meshDimensions, MeshDomain > + { + public: + + typedef Mesh MeshType; + typedef Real RealType; + + bool setup( const tnlParameterContainer& parameters, + const tnlString& prefix = "" ) + { + return true; + } + + template< typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshEntity& entity, + const Real& time = 0.0 ) const + { + typedef typename MeshEntity::MeshType::VertexType VertexType; + VertexType v = entity.getCenter(); + return 0.0; + }; +}; + +#endif /* advectionRHS_H_ */ diff --git a/examples/advection/tnl-run-advection b/examples/advection/tnl-run-advection new file mode 100644 index 0000000000000000000000000000000000000000..97122dd9ca95ecc0da694bd54a9b97ab8c383310 --- /dev/null +++ b/examples/advection/tnl-run-advection @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 1 \ + --origin-x 0.0 \ + --proportions-x 10.0 \ + --size-x 500 \ + +#tnl-init --test-function sin-wave \ +# --output-file init.tnl +./advection --time-discretisation explicit \ + --time-step 1.0e-3 \ + --boundary-conditions-constant 0 \ + --discrete-solver euler \ + --snapshot-period 0.1 \ + --final-time 1.0 \ + --artifical-viscosity 1.0 \ + --begin sin \ + --advection-speedX 2.0 \ + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/advection/tnl-run-advection1 b/examples/advection/tnl-run-advection1 new file mode 100644 index 0000000000000000000000000000000000000000..fb5e81faf2e19ab8e6b19c02c0c441dd96a9c807 --- /dev/null +++ b/examples/advection/tnl-run-advection1 @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-y 0.0 \ + --proportions-x 10.0 \ + --proportions-y 10.0 \ + --size-x 500 \ + --size-y 500 \ + +#tnl-init --test-function sin-wave \ +# --output-file init.tnl +./advection --time-discretisation explicit \ + --time-step 1.0e-3 \ + --boundary-conditions-constant 0 \ + --discrete-solver euler \ + --snapshot-period 0.1 \ + --final-time 1.0 \ + --artifical-viscosity 0.2 \ + --begin sin_square \ + --advection-speedX 2.0 \ + --advection-speedY 2.0 \ + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/advection/tnl-run-advectionrot1 b/examples/advection/tnl-run-advectionrot1 new file mode 100644 index 0000000000000000000000000000000000000000..5d3e3990a98ef64233a6b629b4002cc50b26a923 --- /dev/null +++ b/examples/advection/tnl-run-advectionrot1 @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-y 0.0 \ + --proportions-x 10.0 \ + --proportions-y 10.0 \ + --size-x 100 \ + --size-y 100 \ + +#tnl-init --test-function sin-wave \ +# --output-file init.tnl +./advection --time-discretisation explicit \ + --time-step 1.0e-2 \ + --boundary-conditions-constant 0 \ + --discrete-solver euler \ + --snapshot-period 0.1 \ + --final-time 1.0 \ + --artifical-viscosity 5.0 \ + --begin sin_square \ + --advection-speedX 2.0 \ + --advection-speedY 2.0 \ + --move rotation \ + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/inviscid-flow/1d/CMakeLists.txt b/examples/inviscid-flow/1d/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6fe0766eec90a76d7888c56f615122804abf4bcc --- /dev/null +++ b/examples/inviscid-flow/1d/CMakeLists.txt @@ -0,0 +1,20 @@ +set( tnl_heat_equation_SOURCES + euler.cpp + euler.cu ) + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(tnl-euler-1d${debugExt} euler.cu) + target_link_libraries (tnl-euler-1d${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} ) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(tnl-euler-1d${debugExt} euler.cpp) + target_link_libraries (tnl-euler-1d${debugExt} tnl${debugExt}-${tnlVersion} ) +ENDIF( BUILD_CUDA ) + + +INSTALL( TARGETS tnl-euler-1d${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +INSTALL( FILES tnl-run-euler-1d + ${tnl_heat_equation_SOURCES} + DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow-1d ) diff --git a/examples/inviscid-flow/1d/LaxFridrichs.h b/examples/inviscid-flow/1d/LaxFridrichs.h new file mode 100644 index 0000000000000000000000000000000000000000..db63defd3f6585702840e7bb575e225c6667c917 --- /dev/null +++ b/examples/inviscid-flow/1d/LaxFridrichs.h @@ -0,0 +1,143 @@ +#ifndef LaxFridrichs_H +#define LaxFridrichs_H + +#include <core/vectors/tnlVector.h> +#include <mesh/tnlGrid.h> + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichs +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + + +#include "LaxFridrichs_impl.h" + +#endif /* LaxFridrichs_H */ diff --git a/examples/inviscid-flow/1d/LaxFridrichs_impl.h b/examples/inviscid-flow/1d/LaxFridrichs_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..c1fa87b34c637da6edfb77e0fafda1a4c47c8399 --- /dev/null +++ b/examples/inviscid-flow/1d/LaxFridrichs_impl.h @@ -0,0 +1,344 @@ +#ifndef LaxFridrichs_IMPL_H +#define LaxFridrichs_IMPL_H + +/**** + * 1D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + return ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) * hxSquareInverse; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + matrixRow.setElement( 0, west, - lambdaX ); + matrixRow.setElement( 1, center, 2.0 * lambdaX ); + matrixRow.setElement( 2, east, - lambdaX ); +} + +/**** + * 2D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + return ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) * hxSquareInverse + + ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + matrixRow.setElement( 0, south, -lambdaY ); + matrixRow.setElement( 1, west, -lambdaX ); + matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) ); + matrixRow.setElement( 3, east, -lambdaX ); + matrixRow.setElement( 4, north, -lambdaY ); +} + +/**** + * 3D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighbourEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighbourEntities.template getEntityIndex< 0, 0, -1 >(); + return ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) * hxSquareInverse + + ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse + + ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& lambdaZ = tau * entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighbourEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighbourEntities.template getEntityIndex< 0, 0, -1 >(); + matrixRow.setElement( 0, down, -lambdaZ ); + matrixRow.setElement( 1, south, -lambdaY ); + matrixRow.setElement( 2, west, -lambdaX ); + matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) ); + matrixRow.setElement( 4, east, -lambdaX ); + matrixRow.setElement( 5, north, -lambdaY ); + matrixRow.setElement( 6, up, -lambdaZ ); +} + +#endif /* LaxFridrichsIMPL_H */ + diff --git a/examples/inviscid-flow/1d/euler.cpp b/examples/inviscid-flow/1d/euler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f --- /dev/null +++ b/examples/inviscid-flow/1d/euler.cpp @@ -0,0 +1 @@ +#include "euler.h" diff --git a/examples/inviscid-flow/1d/euler.cu b/examples/inviscid-flow/1d/euler.cu new file mode 100644 index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f --- /dev/null +++ b/examples/inviscid-flow/1d/euler.cu @@ -0,0 +1 @@ +#include "euler.h" diff --git a/examples/inviscid-flow/1d/euler.h b/examples/inviscid-flow/1d/euler.h new file mode 100644 index 0000000000000000000000000000000000000000..cba3c12b65fa683360aa5076e861b7e69d6ec16a --- /dev/null +++ b/examples/inviscid-flow/1d/euler.h @@ -0,0 +1,115 @@ +#include <tnlConfig.h> +#include <solvers/tnlSolver.h> +#include <solvers/tnlBuildConfigTags.h> +#include <operators/tnlDirichletBoundaryConditions.h> +#include <operators/tnlNeumannBoundaryConditions.h> +#include <functions/tnlConstantFunction.h> +#include "eulerProblem.h" +#include "LaxFridrichs.h" +#include "eulerRhs.h" +#include "eulerBuildConfigTag.h" + +typedef eulerBuildConfigTag BuildConfig; + +/**** + * Uncoment the following (and comment the previous line) for the complete build. + * This will include support for all floating point precisions, all indexing types + * and more solvers. You may then choose between them from the command line. + * The compile time may, however, take tens of minutes or even several hours, + * esppecially if CUDA is enabled. Use this, if you want, only for the final build, + * not in the development phase. + */ +//typedef tnlDefaultConfigTag BuildConfig; + +template< typename ConfigTag >class eulerConfig +{ + public: + static void configSetup( tnlConfigDescription & config ) + { + config.addDelimiter( "euler settings:" ); + config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); + config.addEntryEnum< tnlString >( "dirichlet" ); + config.addEntryEnum< tnlString >( "neumann" ); + config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." ); + config.addEntry< double >( "left-density", "This sets a value of left density." ); + config.addEntry< double >( "left-velocity", "This sets a value of left velocity." ); + config.addEntry< double >( "left-pressure", "This sets a value of left pressure." ); + config.addEntry< double >( "riemann-border", "This sets a position of discontinuity." ); + config.addEntry< double >( "right-density", "This sets a value of right density." ); + config.addEntry< double >( "right-velocity", "This sets a value of right velocity." ); + config.addEntry< double >( "right-pressure", "This sets a value of right pressure." ); + config.addEntry< double >( "gamma", "This sets a value of gamma constant." ); + + /**** + * Add definition of your solver command line arguments. + */ + + } +}; + +template< typename Real, + typename Device, + typename Index, + typename MeshType, + typename ConfigTag, + typename SolverStarter > +class eulerSetter +{ + public: + + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + static bool run( const tnlParameterContainer & parameters ) + { + enum { Dimensions = MeshType::getMeshDimensions() }; + typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator; + typedef eulerRhs< MeshType, Real > RightHandSide; + typedef tnlStaticVector < MeshType::getMeshDimensions(), Real > Vertex; + + /**** + * Resolve the template arguments of your solver here. + * The following code is for the Dirichlet and the Neumann boundary conditions. + * Both can be constant or defined as descrete values of tnlVector. + */ + tnlString boundaryConditionsType = parameters.getParameter< tnlString >( "boundary-conditions-type" ); + if( parameters.checkParameter( "boundary-conditions-constant" ) ) + { + typedef tnlConstantFunction< Dimensions, Real > ConstantFunction; + if( boundaryConditionsType == "dirichlet" ) + { + typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlMeshFunction< MeshType > MeshFunction; + if( boundaryConditionsType == "dirichlet" ) + { + typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + +}; + +int main( int argc, char* argv[] ) +{ + tnlSolver< eulerSetter, eulerConfig, BuildConfig > solver; + if( ! solver. run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + diff --git a/examples/inviscid-flow/1d/eulerBuildConfigTag.h b/examples/inviscid-flow/1d/eulerBuildConfigTag.h new file mode 100644 index 0000000000000000000000000000000000000000..dea2c8445e7bf7dfbd537e1b98ca40b669b674b6 --- /dev/null +++ b/examples/inviscid-flow/1d/eulerBuildConfigTag.h @@ -0,0 +1,43 @@ +#ifndef eulerBUILDCONFIGTAG_H_ +#define eulerBUILDCONFIGTAG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class eulerBuildConfigTag{}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< eulerBuildConfigTag, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< eulerBuildConfigTag, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; }; + +/**** + * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types. + */ + +template< int Dimensions, typename Real, typename Device, typename Index > + struct tnlConfigTagMesh< eulerBuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< eulerBuildConfigTag, Dimensions >::enabled && + tnlConfigTagReal< eulerBuildConfigTag, Real >::enabled && + tnlConfigTagDevice< eulerBuildConfigTag, Device >::enabled && + tnlConfigTagIndex< eulerBuildConfigTag, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< eulerBuildConfigTag, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* eulerBUILDCONFIGTAG_H_ */ diff --git a/examples/inviscid-flow/1d/eulerProblem.h b/examples/inviscid-flow/1d/eulerProblem.h new file mode 100644 index 0000000000000000000000000000000000000000..8c2e5020fc2417de5038ffbf73ba1f8f5b62c09a --- /dev/null +++ b/examples/inviscid-flow/1d/eulerProblem.h @@ -0,0 +1,90 @@ +#ifndef eulerPROBLEM_H_ +#define eulerPROBLEM_H_ + +#include <problems/tnlPDEProblem.h> +#include <functions/tnlMeshFunction.h> + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +class eulerProblem: + public tnlPDEProblem< Mesh, + typename DifferentialOperator::RealType, + typename Mesh::DeviceType, + typename DifferentialOperator::IndexType > +{ + public: + + typedef typename DifferentialOperator::RealType RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef typename DifferentialOperator::IndexType IndexType; + typedef tnlMeshFunction< Mesh > MeshFunctionType; + typedef tnlPDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; + + using typename BaseType::MeshType; + using typename BaseType::DofVectorType; + using typename BaseType::MeshDependentDataType; + + static tnlString getTypeStatic(); + tnlSharedVector< RealType, DeviceType, IndexType > rho; + tnlSharedVector< RealType, DeviceType, IndexType > rhoVel; + tnlSharedVector< RealType, DeviceType, IndexType > energy; + tnlVector< RealType, DeviceType, IndexType > data; + tnlSharedVector< RealType, DeviceType, IndexType > pressure; + tnlSharedVector< RealType, DeviceType, IndexType > velocity; + double gamma; + + tnlString getPrologHeader() const; + + void writeProlog( tnlLogger& logger, + const tnlParameterContainer& parameters ) const; + + bool setup( const tnlParameterContainer& parameters ); + + bool setInitialCondition( const tnlParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ); + + template< typename Matrix > + bool setupLinearSystem( const MeshType& mesh, + Matrix& matrix ); + + bool makeSnapshot( const RealType& time, + const IndexType& step, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ); + + IndexType getDofs( const MeshType& mesh ) const; + + void bindDofs( const MeshType& mesh, + DofVectorType& dofs ); + + void getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + DofVectorType& _fu, + MeshDependentDataType& meshDependentData ); + + template< typename Matrix > + void assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& dofs, + Matrix& matrix, + DofVectorType& rightHandSide, + MeshDependentDataType& meshDependentData ); + + protected: + + DifferentialOperator differentialOperator; + BoundaryCondition boundaryCondition; + RightHandSide rightHandSide; +}; + +#include "eulerProblem_impl.h" + +#endif /* eulerPROBLEM_H_ */ diff --git a/examples/inviscid-flow/1d/eulerProblem_impl.h b/examples/inviscid-flow/1d/eulerProblem_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..06c647f9594586c9181c37b955ffe8d360456504 --- /dev/null +++ b/examples/inviscid-flow/1d/eulerProblem_impl.h @@ -0,0 +1,338 @@ +#ifndef eulerPROBLEM_IMPL_H_ +#define eulerPROBLEM_IMPL_H_ + +#include <core/mfilename.h> +#include <matrices/tnlMatrixSetter.h> +#include <solvers/pde/tnlExplicitUpdater.h> +#include <solvers/pde/tnlLinearSystemAssembler.h> +#include <solvers/pde/tnlBackwardTimeDiscretisation.h> + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +tnlString +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getTypeStatic() +{ + return tnlString( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >"; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +tnlString +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getPrologHeader() const +{ + return tnlString( "euler" ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const +{ + /**** + * Add data you want to have in the computation report (log) as follows: + * logger.writeParameter< double >( "Parameter description", parameter ); + */ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setup( const tnlParameterContainer& parameters ) +{ + if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) || + ! this->rightHandSide.setup( parameters, "right-hand-side-" ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getDofs( const MeshType& mesh ) const +{ + /**** + * Return number of DOFs (degrees of freedom) i.e. number + * of unknowns to be resolved by the main solver. + */ + return 3*mesh.template getEntitiesCount< typename MeshType::Cell >(); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +bindDofs( const MeshType& mesh, + DofVectorType& dofVector ) +{ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setInitialCondition( const tnlParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + typedef typename MeshType::Cell Cell; + double gamma = parameters.getParameter< double >( "gamma" ); + double rhoL = parameters.getParameter< double >( "left-density" ); + double velL = parameters.getParameter< double >( "left-velocity" ); + double preL = parameters.getParameter< double >( "left-pressure" ); + double eL = ( preL / (gamma - 1) ) + 0.5 * rhoL * velL * velL; + double rhoR = parameters.getParameter< double >( "right-density" ); + double velR = parameters.getParameter< double >( "right-velocity" ); + double preR = parameters.getParameter< double >( "right-pressure" ); + double eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * velR * velR; + double x0 = parameters.getParameter< double >( "riemann-border" ); + cout << gamma << " " << rhoL << " " << velL << " " << preL << " " << eL << " " << rhoR << " " << velR << " " << preR << " " << eR << " " << x0 << " " << gamma << endl; + int count = mesh.template getEntitiesCount< Cell >(); + this->rho.bind(dofs,0,count); + this->rhoVel.bind(dofs,count,count); + this->energy.bind(dofs,2 * count,count); + this->data.setSize(2*count); + this->pressure.bind(this->data,0,count); + this->velocity.bind(this->data,count,count); + for(long int i = 0; i < count; i++) + if (i < x0 * count ) + { + this->rho[i] = rhoL; + this->rhoVel[i] = rhoL * velL; + this->energy[i] = eL; + this->velocity[i] = velL; + this->pressure[i] = preL; + } + else + { + this->rho[i] = rhoR; + this->rhoVel[i] = rhoR * velR; + this->energy[i] = eR; + this->velocity[i] = velR; + this->pressure[i] = preR; + }; + this->gamma = gamma; + cout << "dofs = " << dofs << endl; + getchar(); + + + /* + const tnlString& initialConditionFile = parameters.getParameter< tnlString >( "initial-condition" ); + if( ! dofs.load( initialConditionFile ) ) + { + cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << endl; + return false; + } + */ + return true; +} +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > + template< typename Matrix > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setupLinearSystem( const MeshType& mesh, + Matrix& matrix ) +{ + const IndexType dofs = this->getDofs( mesh ); + typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVectorType; + CompressedRowsLengthsVectorType rowLengths; + if( ! rowLengths.setSize( dofs ) ) + return false; + tnlMatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter; + matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh, + differentialOperator, + boundaryCondition, + rowLengths ); + matrix.setDimensions( dofs, dofs ); + if( ! matrix.setCompressedRowsLengths( rowLengths ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +makeSnapshot( const RealType& time, + const IndexType& step, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + cout << endl << "Writing output at time " << time << " step " << step << "." << endl; + this->bindDofs( mesh, dofs ); + tnlString fileName; + ofstream vysledek; + cout << "pressure:" << endl; + for (int i = 0; i<100; i++) cout << this->pressure[i] << " " ; + vysledek.open("pressure" + to_string(step) + ".txt"); + for (int i = 0; i<101; i++) + vysledek << 0.01*i << " " << pressure[i] << endl; + vysledek.close(); + cout << " " << endl; + cout << "velocity:" << endl; + for (int i = 0; i<100; i++) cout << this->velocity[i] << " " ; + vysledek.open("velocity" + to_string(step) + ".txt"); + for (int i = 0; i<101; i++) + vysledek << 0.01*i << " " << pressure[i] << endl; + vysledek.close(); + cout << "energy:" << endl; + for (int i = 0; i<100; i++) cout << this->energy[i] << " " ; + vysledek.open("energy" + to_string(step) + ".txt"); + for (int i = 0; i<101; i++) + vysledek << 0.01*i << " " << energy[i] << endl; + vysledek.close(); + cout << " " << endl; + cout << "density:" << endl; + for (int i = 0; i<100; i++) cout << this->rho[i] << " " ; + vysledek.open("density" + to_string(step) + ".txt"); + for (int i = 0; i<101; i++) + vysledek << 0.01*i << " " << rho[i] << endl; + vysledek.close(); + getchar(); + + FileNameBaseNumberEnding( "rho-", step, 5, ".tnl", fileName ); + if( ! rho.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "rhoVel-", step, 5, ".tnl", fileName ); + if( ! rhoVel.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "energy-", step, 5, ".tnl", fileName ); + if( ! energy.save( fileName ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + DofVectorType& _fu, + MeshDependentDataType& meshDependentData ) +{ + /* + W[1] [0 ... count-1 ] + W[2] [count ... 2*count-1 ] + W[3] [2*count ... 3*count-1 ] + V this->velocity[] + p this->pressure[] + */ + typedef typename MeshType::Cell Cell; + int count = mesh.template getEntitiesCount< Cell >(); + const RealType& size = 1;//mesh.template getSpaceStepsProducts< -1, 0 >(); + for (long int i = 1; i < count - 1; i++) + _fu[i] = 1.0 / (2.0*tau) * (this->rho[i-1]+this->rho[i+1]-2.0*this->rho[i])-(1.0/(2.0 * size)) * (this->rho[i+1] + * this->velocity[i+1] - this->rho[i-1] * this->velocity[i-1]); + _fu[count-1] = _fu[count-2]; + for (long int i = 1; i < count - 1; i++) + _fu[count + i] = + 1.0 / (2.0 * tau) * (this->rhoVel[i+1] + this->rhoVel[i+1] - + 2.0 * this->rhoVel[i])-(1.0 / (2.0 * size)) * ((this->rhoVel[i+1] + * this->velocity[i + 1] + this->pressure[i + 1]) - (this->rhoVel[i-1] * this->velocity[i - 1] + + this->pressure[i - 1])); + _fu[2*count-1] = _fu[2*count-2]; + for (long int i = 1; i < count - 1; i++) + _fu[i + 2 * count] = 1.0 / (2.0*tau) * (this->energy[i-1] + + this->energy[i+1]-2.0*this->energy[i]) + - (1.0/(2.0 * size)) * ((this->energy[i+1] + + this->pressure[i + 1]) * this->velocity[i + 1] - (this->energy[i-1] + this->pressure[i -1]) * this->velocity[i - 1]); + _fu[3 * count-1] = _fu[3 * count-2]; + for (long int i = 0; i <= count; i++) //pressure + this->pressure[i] = (this->gamma - 1 ) * ( this->energy[i] - 0.5 * this->rhoVel[i] * this->velocity[i]); + for (long int i = 0; i <= count ; i++) //velocity + this->velocity[i] = this->rhoVel[i]/this->rho[i]; + + /**** + * If you use an explicit solver like tnlEulerSolver or tnlMersonSolver, you + * need to implement this method. Compute the right-hand side of + * + * d/dt u(x) = fu( x, u ) + * + * You may use supporting mesh dependent data if you need. + + + this->bindDofs( mesh, _u ); + tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater; + MeshFunctionType u( mesh, _u ); + MeshFunctionType fu( mesh, _fu ); + explicitUpdater.template update< typename Mesh::Cell >( time, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + fu ); + tnlBoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter; + boundaryConditionsSetter.template apply< typename Mesh::Cell >( + this->boundaryCondition, + time + tau, + u ); */ + } + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > + template< typename Matrix > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + Matrix& matrix, + DofVectorType& b, + MeshDependentDataType& meshDependentData ) +{ + tnlLinearSystemAssembler< Mesh, + MeshFunctionType, + DifferentialOperator, + BoundaryCondition, + RightHandSide, + tnlBackwardTimeDiscretisation, + Matrix, + DofVectorType > systemAssembler; + + tnlMeshFunction< Mesh > u( mesh, _u ); + systemAssembler.template assembly< typename Mesh::Cell >( time, + tau, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + matrix, + b ); +} + +#endif /* eulerPROBLEM_IMPL_H_ */ diff --git a/examples/inviscid-flow/1d/eulerRhs.h b/examples/inviscid-flow/1d/eulerRhs.h new file mode 100644 index 0000000000000000000000000000000000000000..582dc36413ae36d78aa06a03be2ad745325263d6 --- /dev/null +++ b/examples/inviscid-flow/1d/eulerRhs.h @@ -0,0 +1,29 @@ +#ifndef eulerRHS_H_ +#define eulerRHS_H_ +#include<functions/tnlDomain.h> +template< typename Mesh, typename Real >class eulerRhs + : public tnlDomain< Mesh::meshDimensions, MeshDomain > + { + public: + + typedef Mesh MeshType; + typedef Real RealType; + + bool setup( const tnlParameterContainer& parameters, + const tnlString& prefix = "" ) + { + return true; + } + + template< typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshEntity& entity, + const Real& time = 0.0 ) const + { + typedef typename MeshEntity::MeshType::VertexType VertexType; + VertexType v = entity.getCenter(); + return 0.0; + }; +}; + +#endif /* eulerRHS_H_ */ diff --git a/examples/inviscid-flow/1d/tnl-run-euler-1d b/examples/inviscid-flow/1d/tnl-run-euler-1d new file mode 100644 index 0000000000000000000000000000000000000000..f68b98a8406dea2f2142526283ec60248551c56d --- /dev/null +++ b/examples/inviscid-flow/1d/tnl-run-euler-1d @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-y 0.0 \ + --proportions-x 1.0 \ + --proportions-y 1.0 \ + --size-x 100 \ + --size-y 100 + +tnl-init --test-function sin-wave \ + --output-file init.tnl +./euler --time-discretisation explicit \ + --boundary-conditions-constant 0 \ + --discrete-solver merson \ + --snapshot-period 0.01 \ + --final-time 1.0 + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/inviscid-flow/2d/CMakeLists.txt b/examples/inviscid-flow/2d/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..315b26d110246c4512d87f13bb178c9d5a07f539 --- /dev/null +++ b/examples/inviscid-flow/2d/CMakeLists.txt @@ -0,0 +1,21 @@ +set( tnl_heat_equation_SOURCES + euler.cpp + euler.cu ) + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(tnl-euler-2d${debugExt} euler.cu) + target_link_libraries (tnl-euler-2d${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} ) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(tnl-euler-2d${debugExt} euler.cpp) + target_link_libraries (tnl-euler-2d${debugExt} tnl${debugExt}-${tnlVersion} ) +ENDIF( BUILD_CUDA ) + + +INSTALL( TARGETS tnl-euler-2d${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +INSTALL( FILES tnl-run-euler-2d + ${tnl_heat_equation_SOURCES} + DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow-2d ) + diff --git a/examples/inviscid-flow/2d/LaxFridrichs.h b/examples/inviscid-flow/2d/LaxFridrichs.h new file mode 100644 index 0000000000000000000000000000000000000000..db63defd3f6585702840e7bb575e225c6667c917 --- /dev/null +++ b/examples/inviscid-flow/2d/LaxFridrichs.h @@ -0,0 +1,143 @@ +#ifndef LaxFridrichs_H +#define LaxFridrichs_H + +#include <core/vectors/tnlVector.h> +#include <mesh/tnlGrid.h> + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichs +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichs< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + enum { Dimensions = MeshType::getMeshDimensions() }; + + static tnlString getType(); + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + __cuda_callable__ + template< typename MeshEntity > + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const; +}; + + +#include "LaxFridrichs_impl.h" + +#endif /* LaxFridrichs_H */ diff --git a/examples/inviscid-flow/2d/LaxFridrichs_impl.h b/examples/inviscid-flow/2d/LaxFridrichs_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..7f9c73731154d797334ccb86a26e7640743a7ae7 --- /dev/null +++ b/examples/inviscid-flow/2d/LaxFridrichs_impl.h @@ -0,0 +1,495 @@ +#ifndef LaxFridrichs_IMPL_H +#define LaxFridrichs_IMPL_H + +/**** + * 1D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + /* + //rho + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/5; + return (0.5 * this->tau)( u[ west ] - 2.0 * u[ center ] + u[ east ] ) + - 0.5 * hxInverse * ( u[ west ] * u[ west + 3*size ] - u[ east ] * u[ east + 3*size ] ); + */ + /* + //rhoVel + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/5; + return (0.5 * this->tau)( u[ west ] - 2.0 * u[ center ] + u[ east ] ) + - 0.5 * hxInverse * + (( u[ west ] * u[ west + 2*size ] + u[ west + 3*size ] ) + - (u[ east ] * u[ east + 2*size ] + u[ east + 3*size ] )); + */ + /* + //energy + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/5; + return (0.5 * this->tau)( u[ west ] - 2.0 * u[ center ] + u[ east ] ) + - 0.5 * hxInverse * + (( u[ west ] + u[ west + 2*size ] ) * u[ west + size ] + - (u[ east ] + u[ east + 2*size ] ) * u[ east + size ] ); + */ + /* + //vel + const IndexType& center = entity.getIndex(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/5; + return ( fu[ center - 2*size] - fu[ center - 3*size]); + */ + /* + //pressure + const IndexType& center = entity.getIndex(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/5; + return ( this->gamma - 1 ) * ( fu[ center - 2*size ] - 0.5 * fu[ center - 3* size ] * fu[ center - 4*size]); + */ + + + + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + return ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) * hxSquareInverse; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1 >(); + matrixRow.setElement( 0, west, - lambdaX ); + matrixRow.setElement( 1, center, 2.0 * lambdaX ); + matrixRow.setElement( 2, east, - lambdaX ); +} + +/**** + * 2D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + + /* + //rho + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/8; + return (0.5 * this->tau)( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) + - 0.5 * hxInverse * ( u[ west ] * u[ west + 4*size ] - u[ east ] * u[ east + 4*size ] ) + - 0.5 * hyInverse * ( u[ north ] * u[ north + 5*size ] - u[ south ] * u[ south + 5*size ] ); + */ + /* + //rhoVelX + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/8; + return (0.5 * this->tau)( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) + - 0.5 * hxInverse * (( u[ west ] * u[ west + 3*size ] + u[ west + 6*size ] ) + -( u[ east ] * u[ east + 3*size ] + u[ east + 6*size ] )) + - 0.5 * hyInverse * (( u[ north ] * u[ north + 4*size ] + u[ north + 6*size ] ) + -( u[ south ] * u[ south + 4*size ] + u[ south + 6*size ] )); + */ + /* + //rhoVelY + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/8; + return (0.5 * this->tau)( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) + - 0.5 * hxInverse * (( u[ west ] * u[ west + 3*size ] + u[ west + 5*size ] ) + -( u[ east ] * u[ east + 3*size ] + u[ east + 5*size ] )) + - 0.5 * hyInverse * (( u[ north ] * u[ north + 2*size ] + u[ north + 5*size ] ) + -( u[ south ] * u[ south + 2*size ] + u[ south + 5*size ] )); + */ + /* + //energy + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/8; + return (0.5 * this->tau)( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) + - 0.5 * hxInverse * (( u[ west ] + u[ west + 4*size ] ) * u[ west + size ] ) + -( u[ east ] + u[ east + 4*size ] ) * u[ east + size ] )) + - 0.5 * hyInverse * (( u[ north ] + u[ north + 4*size ] ) * u[ north + 2*size ] ) + -( u[ south ] + u[ south + 4*size ] ) * u[ south + 2*size ] )); + */ + /* + //velX + const IndexType& center = entity.getIndex(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/8; + return ( fu[ center - 3*size] - fu[ center - 5*size]); + */ + /* + //velY + const IndexType& center = entity.getIndex(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/8; + return ( fu[ center - 3*size] - fu[ center - 5*size]); + */ + /* + //vel + const IndexType& center = entity.getIndex(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/8; + return sqrt(pow( fu[ center - 2*size],2)+pow( fu[ center - size],2)); + */ + /* + //pressure + const IndexType& center = entity.getIndex(); + typedef typename MeshType::Cell Cell; + const int size = mesh.template getEntitiesCount< Cell >()/5; + return ( this->gamma - 1 ) * ( fu[ center - 4*size ] - 0.5 * fu[ center - 7 * size ] * pow( fu[ center - size],2 )); + */ + + + + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + return ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) * hxSquareInverse + + ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1 >(); + matrixRow.setElement( 0, south, -lambdaY ); + matrixRow.setElement( 1, west, -lambdaX ); + matrixRow.setElement( 2, center, 2.0 * ( lambdaX + lambdaY ) ); + matrixRow.setElement( 3, east, -lambdaX ); + matrixRow.setElement( 4, north, -lambdaY ); +} + +/**** + * 3D problem + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +getType() +{ + return tnlString( "LaxFridrichs< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshFunction, typename MeshEntity > +__cuda_callable__ +Real +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +operator()( const MeshFunction& u, + const MeshEntity& entity, + const Real& time ) const +{ + /**** + * Implement your explicit form of the differential operator here. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + static_assert( MeshEntity::entityDimensions == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimensions() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighbourEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighbourEntities.template getEntityIndex< 0, 0, -1 >(); + return ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) * hxSquareInverse + + ( u[ south ] - 2.0 * u[ center ] + u[ north ] ) * hySquareInverse + + ( u[ up ] - 2.0 * u[ center ] + u[ down ] ) * hzSquareInverse; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename MeshEntity > +__cuda_callable__ +Index +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const +{ + /**** + * Return a number of non-zero elements in a line (associated with given grid element) of + * the linear system. + * The following example is the Laplace operator approximated + * by the Finite difference method. + */ + + return 2*Dimensions + 1; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename MeshEntity, typename Vector, typename MatrixRow > +__cuda_callable__ +void +LaxFridrichs< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const +{ + /**** + * Setup the non-zero elements of the linear system here. + * The following example is the Laplace operator appriximated + * by the Finite difference method. + */ + + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& lambdaX = tau * entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& lambdaY = tau * entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& lambdaZ = tau * entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighbourEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighbourEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighbourEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighbourEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighbourEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighbourEntities.template getEntityIndex< 0, 0, -1 >(); + matrixRow.setElement( 0, down, -lambdaZ ); + matrixRow.setElement( 1, south, -lambdaY ); + matrixRow.setElement( 2, west, -lambdaX ); + matrixRow.setElement( 3, center, 2.0 * ( lambdaX + lambdaY + lambdaZ ) ); + matrixRow.setElement( 4, east, -lambdaX ); + matrixRow.setElement( 5, north, -lambdaY ); + matrixRow.setElement( 6, up, -lambdaZ ); +} + +#endif /* LaxFridrichsIMPL_H */ + diff --git a/examples/inviscid-flow/2d/euler-cuda.cu b/examples/inviscid-flow/2d/euler-cuda.cu new file mode 100644 index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f --- /dev/null +++ b/examples/inviscid-flow/2d/euler-cuda.cu @@ -0,0 +1 @@ +#include "euler.h" diff --git a/examples/inviscid-flow/2d/euler.cpp b/examples/inviscid-flow/2d/euler.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4d76005cb1f70724be978ff0fa6fec63c4a8a76f --- /dev/null +++ b/examples/inviscid-flow/2d/euler.cpp @@ -0,0 +1 @@ +#include "euler.h" diff --git a/examples/inviscid-flow/2d/euler.h b/examples/inviscid-flow/2d/euler.h new file mode 100644 index 0000000000000000000000000000000000000000..ce35381216dbaaa170a3934247cb7e4d49a216d6 --- /dev/null +++ b/examples/inviscid-flow/2d/euler.h @@ -0,0 +1,117 @@ +#include <tnlConfig.h> +#include <solvers/tnlSolver.h> +#include <solvers/tnlBuildConfigTags.h> +#include <operators/tnlDirichletBoundaryConditions.h> +#include <operators/tnlNeumannBoundaryConditions.h> +#include <functions/tnlConstantFunction.h> +#include "eulerProblem.h" +#include "LaxFridrichs.h" +#include "eulerRhs.h" +#include "eulerBuildConfigTag.h" + +typedef eulerBuildConfigTag BuildConfig; + +/**** + * Uncoment the following (and comment the previous line) for the complete build. + * This will include support for all floating point precisions, all indexing types + * and more solvers. You may then choose between them from the command line. + * The compile time may, however, take tens of minutes or even several hours, + * esppecially if CUDA is enabled. Use this, if you want, only for the final build, + * not in the development phase. + */ +//typedef tnlDefaultConfigTag BuildConfig; + +template< typename ConfigTag >class eulerConfig +{ + public: + static void configSetup( tnlConfigDescription & config ) + { + config.addDelimiter( "euler2D settings:" ); + config.addEntry< tnlString >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); + config.addEntryEnum< tnlString >( "dirichlet" ); + config.addEntryEnum< tnlString >( "neumann" ); + config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." ); + config.addEntry< double >( "left-density", "This sets a value of left density." ); + config.addEntry< double >( "left-velocityX", "This sets a value of left_x velocity." ); + config.addEntry< double >( "left-velocityY", "This sets a value of left_y velocity." ); + config.addEntry< double >( "left-pressure", "This sets a value of left pressure." ); + config.addEntry< double >( "riemann-border", "This sets a position of discontinuity." ); + config.addEntry< double >( "right-density", "This sets a value of right density." ); + config.addEntry< double >( "right-velocityX", "This sets a value of right_x velocity." ); + config.addEntry< double >( "right-velocityY", "This sets a value of right_y velocity." ); + config.addEntry< double >( "right-pressure", "This sets a value of right pressure." ); + config.addEntry< double >( "gamma", "This sets a value of gamma constant." ); + + /**** + * Add definition of your solver command line arguments. + */ + + } +}; + +template< typename Real, + typename Device, + typename Index, + typename MeshType, + typename ConfigTag, + typename SolverStarter > +class eulerSetter +{ + public: + + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + static bool run( const tnlParameterContainer & parameters ) + { + enum { Dimensions = MeshType::getMeshDimensions() }; + typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator; + typedef eulerRhs< MeshType, Real > RightHandSide; + typedef tnlStaticVector < MeshType::getMeshDimensions(), Real > Vertex; + + /**** + * Resolve the template arguments of your solver here. + * The following code is for the Dirichlet and the Neumann boundary conditions. + * Both can be constant or defined as descrete values of tnlVector. + */ + tnlString boundaryConditionsType = parameters.getParameter< tnlString >( "boundary-conditions-type" ); + if( parameters.checkParameter( "boundary-conditions-constant" ) ) + { + typedef tnlConstantFunction< Dimensions, Real > ConstantFunction; + if( boundaryConditionsType == "dirichlet" ) + { + typedef tnlDirichletBoundaryConditions< MeshType, ConstantFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunction, Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlMeshFunction< MeshType > MeshFunction; + if( boundaryConditionsType == "dirichlet" ) + { + typedef tnlDirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + typedef tnlNeumannBoundaryConditions< MeshType, MeshFunction, Real, Index > BoundaryConditions; + typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + +}; + +int main( int argc, char* argv[] ) +{ + tnlSolver< eulerSetter, eulerConfig, BuildConfig > solver; + if( ! solver. run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + diff --git a/examples/inviscid-flow/2d/eulerBuildConfigTag.h b/examples/inviscid-flow/2d/eulerBuildConfigTag.h new file mode 100644 index 0000000000000000000000000000000000000000..d242a88650f98f2cac9e0ea68473a10e7c29469f --- /dev/null +++ b/examples/inviscid-flow/2d/eulerBuildConfigTag.h @@ -0,0 +1,43 @@ +#ifndef eulerBUILDCONFIGTAG_H_ +#define eulerBUILDCONFIGTAG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class eulerBuildConfigTag{}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< eulerBuildConfigTag, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< eulerBuildConfigTag, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; }; + +/**** + * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types. + */ + +template< int Dimensions, typename Real, typename Device, typename Index > + struct tnlConfigTagMesh< eulerBuildConfigTag, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< eulerBuildConfigTag, Dimensions >::enabled && + tnlConfigTagReal< eulerBuildConfigTag, Real >::enabled && + tnlConfigTagDevice< eulerBuildConfigTag, Device >::enabled && + tnlConfigTagIndex< eulerBuildConfigTag, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< eulerBuildConfigTag, tnlImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< eulerBuildConfigTag, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* eulerBUILDCONFIGTAG_H_ */ diff --git a/examples/inviscid-flow/2d/eulerProblem.h b/examples/inviscid-flow/2d/eulerProblem.h new file mode 100644 index 0000000000000000000000000000000000000000..6a514c1da74cf0149feea852fdc227b08b1355cc --- /dev/null +++ b/examples/inviscid-flow/2d/eulerProblem.h @@ -0,0 +1,93 @@ +#ifndef eulerPROBLEM_H_ +#define eulerPROBLEM_H_ + +#include <problems/tnlPDEProblem.h> +#include <functions/tnlMeshFunction.h> + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +class eulerProblem: + public tnlPDEProblem< Mesh, + typename DifferentialOperator::RealType, + typename Mesh::DeviceType, + typename DifferentialOperator::IndexType > +{ + public: + + typedef typename DifferentialOperator::RealType RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef typename DifferentialOperator::IndexType IndexType; + typedef tnlMeshFunction< Mesh > MeshFunctionType; + typedef tnlPDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; + + using typename BaseType::MeshType; + using typename BaseType::DofVectorType; + using typename BaseType::MeshDependentDataType; + tnlSharedVector< RealType, DeviceType, IndexType > rho; + tnlSharedVector< RealType, DeviceType, IndexType > rhoVelX; + tnlSharedVector< RealType, DeviceType, IndexType > rhoVelY; + tnlSharedVector< RealType, DeviceType, IndexType > energy; + tnlVector< RealType, DeviceType, IndexType > data; + tnlSharedVector< RealType, DeviceType, IndexType > pressure; + tnlSharedVector< RealType, DeviceType, IndexType > velocity; + tnlSharedVector< RealType, DeviceType, IndexType > velocityX; + tnlSharedVector< RealType, DeviceType, IndexType > velocityY; + double gamma; + + static tnlString getTypeStatic(); + + tnlString getPrologHeader() const; + + void writeProlog( tnlLogger& logger, + const tnlParameterContainer& parameters ) const; + + bool setup( const tnlParameterContainer& parameters ); + + bool setInitialCondition( const tnlParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ); + + template< typename Matrix > + bool setupLinearSystem( const MeshType& mesh, + Matrix& matrix ); + + bool makeSnapshot( const RealType& time, + const IndexType& step, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ); + + IndexType getDofs( const MeshType& mesh ) const; + + void bindDofs( const MeshType& mesh, + DofVectorType& dofs ); + + void getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + DofVectorType& _fu, + MeshDependentDataType& meshDependentData ); + + template< typename Matrix > + void assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& dofs, + Matrix& matrix, + DofVectorType& rightHandSide, + MeshDependentDataType& meshDependentData ); + + protected: + + DifferentialOperator differentialOperator; + BoundaryCondition boundaryCondition; + RightHandSide rightHandSide; +}; + +#include "eulerProblem_impl.h" + +#endif /* eulerPROBLEM_H_ */ diff --git a/examples/inviscid-flow/2d/eulerProblem_impl.h b/examples/inviscid-flow/2d/eulerProblem_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..aedadddb10efa559e2ec138974cd36f2b9368833 --- /dev/null +++ b/examples/inviscid-flow/2d/eulerProblem_impl.h @@ -0,0 +1,355 @@ +#ifndef eulerPROBLEM_IMPL_H_ +#define eulerPROBLEM_IMPL_H_ + +#include <core/mfilename.h> +#include <matrices/tnlMatrixSetter.h> +#include <solvers/pde/tnlExplicitUpdater.h> +#include <solvers/pde/tnlLinearSystemAssembler.h> +#include <solvers/pde/tnlBackwardTimeDiscretisation.h> + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +tnlString +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getTypeStatic() +{ + return tnlString( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >"; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +tnlString +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getPrologHeader() const +{ + return tnlString( "euler2D" ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +writeProlog( tnlLogger& logger, const tnlParameterContainer& parameters ) const +{ + /**** + * Add data you want to have in the computation report (log) as follows: + * logger.writeParameter< double >( "Parameter description", parameter ); + */ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setup( const tnlParameterContainer& parameters ) +{ + if( ! this->boundaryCondition.setup( parameters, "boundary-conditions-" ) || + ! this->rightHandSide.setup( parameters, "right-hand-side-" ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getDofs( const MeshType& mesh ) const +{ + /**** + * Return number of DOFs (degrees of freedom) i.e. number + * of unknowns to be resolved by the main solver. + */ + return 4*mesh.template getEntitiesCount< typename MeshType::Cell >(); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +bindDofs( const MeshType& mesh, + DofVectorType& dofVector ) +{ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setInitialCondition( const tnlParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + typedef typename MeshType::Cell Cell; + double gamma = parameters.getParameter< double >( "gamma" ); + double rhoL = parameters.getParameter< double >( "left-density" ); + double velLX = parameters.getParameter< double >( "left-velocityX" ); + double velLY = parameters.getParameter< double >( "left-velocityY" ); + double preL = parameters.getParameter< double >( "left-pressure" ); + double eL = ( preL / (gamma - 1) ) + 0.5 * rhoL * pow(velLX,2)+pow(velLY,2); + double rhoR = parameters.getParameter< double >( "right-density" ); + double velRX = parameters.getParameter< double >( "right-velocityX" ); + double velRY = parameters.getParameter< double >( "right-velocityY" ); + double preR = parameters.getParameter< double >( "right-pressure" ); + double eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * pow(velRX,2)+pow(velRY,2); + double x0 = parameters.getParameter< double >( "riemann-border" ); + int size = mesh.template getEntitiesCount< Cell >(); + int size2 = pow(size,2); + this->rho.bind(dofs,0,size2); + this->rhoVelX.bind(dofs,size2,size2); + this->rhoVelY.bind(dofs,2*size2,size2); + this->energy.bind(dofs,3*size2,size2); + this->data.setSize(4*size2); + this->pressure.bind(this->data,0,size2); + this->velocity.bind(this->data,size2,size2); + this->velocityX.bind(this->data,2*size2,size2); + this->velocityY.bind(this->data,3*size2,size2); + for(long int j = 0; j < size; j++) + for(long int i = 0; i < size; i++) + if ((i < x0 * size)&&(j < x0 * size) ) + { + this->rho[j*size+i] = rhoL; + this->rhoVelX[j*size+i] = rhoL * velLX; + this->rhoVelY[j*size+i] = rhoL * velLY; + this->energy[j*size+i] = eL; + this->velocity[j*size+i] = sqrt(pow(velLX,2)+pow(velLY,2)); + this->velocityX[j*size+i] = velLX; + this->velocityY[j*size+i] = velLY; + this->pressure[j*size+i] = preL; + } + else + { + this->rho[j*size+i] = rhoR; + this->rhoVelX[j*size+i] = rhoR * velRX; + this->rhoVelY[j*size+i] = rhoR * velRY; + this->energy[j*size+i] = eR; + this->velocity[j*size+i] = sqrt(pow(velRX,2)+pow(velRY,2)); + this->velocityX[j*size+i] = velRX; + this->velocityY[j*size+i] = velRY; + this->pressure[j*size+i] = preR; + }; + this->gamma = gamma; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > + template< typename Matrix > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setupLinearSystem( const MeshType& mesh, + Matrix& matrix ) +{ + const IndexType dofs = this->getDofs( mesh ); + typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVectorType; + CompressedRowsLengthsVectorType rowLengths; + if( ! rowLengths.setSize( dofs ) ) + return false; + tnlMatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter; + matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh, + differentialOperator, + boundaryCondition, + rowLengths ); + matrix.setDimensions( dofs, dofs ); + if( ! matrix.setCompressedRowsLengths( rowLengths ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +makeSnapshot( const RealType& time, + const IndexType& step, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + cout << endl << "Writing output at time " << time << " step " << step << "." << endl; + this->bindDofs( mesh, dofs ); + tnlString fileName; + FileNameBaseNumberEnding( "rho-", step, 5, ".tnl", fileName ); + if( ! this->rho.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "rhoVelX-", step, 5, ".tnl", fileName ); + if( ! this->rhoVelX.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "rhoVelY-", step, 5, ".tnl", fileName ); + if( ! this->rhoVelY.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "energy-", step, 5, ".tnl", fileName ); + if( ! this->energy.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "velocityX-", step, 5, ".tnl", fileName ); + if( ! this->velocityX.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "velocityY-", step, 5, ".tnl", fileName ); + if( ! this->velocityY.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "velocity-", step, 5, ".tnl", fileName ); + if( ! this->velocity.save( fileName ) ) + return false; + FileNameBaseNumberEnding( "pressure-", step, 5, ".tnl", fileName ); + if( ! this->pressure.save( fileName ) ) + return false; + + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + DofVectorType& _fu, + MeshDependentDataType& meshDependentData ) +{ + typedef typename MeshType::Cell Cell; + const RealType& cellSize = 1;// mesh.template getSpaceStepsProducts< -1, 0 >(); + int size = mesh.template getEntitiesCount< Cell >()/4; +// prepsat na SWEN + + for (long int j = 1; j < size - 1; j++) + { + for (long int i = 1; i < size - 1; i++) + { + _fu[j*size+i] = 1.0 / (4.0*tau) * + (this->rho[j*size+i-1]+this->rho[j*size+i+1]+this->rho[(j-1)*size+i]+this->rho[(j+1)*size+i]-4.0*this->rho[j*size+i]) + -(1.0/(2.0*cellSize))*(this->rho[j*size+i+1]*this->velocityX[j*size+i+1]-this->rho[j*size+i-1]*this->velocityX[j*size+i-1]) + -(1.0/(2.0*cellSize))*(this->rho[(j+1)*size+i]*this->velocityY[(j+1)*size+i]-this->rho[(j-1)*size+i]*this->velocityY[(j-1)*size+i]); + _fu[pow(size,2)-size+i]=_fu[pow(size,2)-2*size+i]; + }; + _fu[j*size-1] = _fu[j*size-1]; + }; + for (long int j = 1; j < size - 1; j++) + { + for (long int i = 1; i < size - 1; i++) + { + _fu[pow(size,2) + j*size+i] = 1.0 / (4.0 * tau) * + (this->rhoVelX[j*size+i+1]+this->rhoVelX[j*size+i-1]+this->rhoVelX[(j-1)*size+i]+this->rhoVelX[(j+1)*size+i]-4.0*this->rhoVelX[j*size+i]) + -(1.0/(2.0*cellSize))*((this->rhoVelX[j*size+i+1]*this->velocityX[j*size+i+1]+this->pressure[j*size+i+1])-(this->rhoVelX[j*size+i-1]*this->velocityX[j*size+i-1]+this->pressure[j*size+i-1])) + -(1.0/(2.0*cellSize))*((this->rhoVelX[(j+1)*size+i]*this->velocityY[(j+1)*size+i])-(this->rhoVelX[(j-1)*size+i]*this->velocityY[(j-1)*size+i])); + _fu[2*pow(size,2)-size+i]=_fu[2*pow(size,2)-2*size+i]; + }; + _fu[pow(size,2)+j*size] = _fu[pow(size,2)+j*size-1]; + }; + for (long int j = 1; j < size - 1; j++) + { + for (long int i = 1; i < size - 1; i++) + { + _fu[2*pow(size,2) + j*size+i] = 1.0 / (4.0 * tau) * + (this->rhoVelY[j*size+i+1]+this->rhoVelY[j*size+i-1]+this->rhoVelY[(j-1)*size+i]+this->rhoVelY[(j+1)*size+i]-4.0*this->rhoVelY[j*size+i]) + -(1.0/(2.0*cellSize))*((this->rhoVelY[(j+1)*size+i]*this->velocityY[(j+1)*size+i]+this->pressure[(j+1)*size+i])-(this->rhoVelY[(j-1)*size+i]*this->velocityY[(j-1)*size+i]+this->pressure[(j-1)*size+i])) + -(1.0/(2.0*cellSize))*((this->rhoVelY[j*size+i+1]*this->velocityX[j*size+i+1])-(this->rhoVelY[j*size+i-1]*this->velocityX[j*size+i-1])); + _fu[3*pow(size,2)-size+i]=_fu[3*pow(size,2)-2*size+i]; + }; + _fu[2*pow(size,2)+j*size] = _fu[2*pow(size,2)+j*size-1]; + }; + for (long int j = 1; j < size - 1; j++) + { + for (long int i = 1; i < size - 1; i++) + { + _fu[3*pow(size,2) + j*size+i] = 1.0 / (4.0 * tau) * + (this->energy[j*size+i+1]+this->energy[j*size+i-1]+this->energy[(j-1)*size+i]+this->energy[(j+1)*size+i]-4.0*this->energy[j*size+i]) + -(1.0/(2.0*cellSize))*((this->energy[j*size+i+1]+this->pressure[j*size+i+1])*this->velocityX[j*size+i+1]-(this->energy[j*size+i-1]+this->pressure[j*size+i-1])*this->velocityX[j*size+i-1]) + -(1.0/(2.0*cellSize))*((this->energy[(j+1)*size+i]+this->pressure[(j+1)*size+i])*this->velocityY[(j+1)*size+i]-(this->energy[(j-1)*size+i]+this->pressure[(j-1)*size+i])*this->velocityY[(j-1)*size+i]); + _fu[4*pow(size,2)-size+i] = _fu[4*pow(size,2)-2*size+i]; + }; + _fu[3*pow(size,2)+j*size] = _fu[3*pow(size,2)+j*size-1]; + }; + + for (long int j = 1; j < size; j++) //pressure + for (long int i = 1; i < size; i++) + this->pressure[j*size+i] = (this->gamma - 1 ) * ( this->energy[j*size+i] - 0.5 * this->rho[j*size+i] * (pow(this->velocityX[j*size+i],2) + pow(this->velocityY[j*size+i],2))); + for (long int j = 1; j < size; j++) //velocityX + for (long int i = 1; i < size; i++) + this->velocityX[j*size+i] = this->rhoVelX[j*size+i]/this->rho[j*size+i]; + for (long int j = 1; j < size; j++) //velocityY + for (long int i = 1; i < size; i++) + this->velocityY[j*size+i] = this->rhoVelY[j*size+i]/this->rho[j*size+i]; + for (long int j = 1; j < size; j++) //velocity + for (long int i = 1; i < size; i++) + this->velocity[j*size+i] =sqrt(pow(velocityX[j*size+i],2)+pow(velocityY[j*size+i],2)); + +/* + + this->bindDofs( mesh, _u ); + tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater; + MeshFunctionType u( mesh, _u ); + MeshFunctionType fu( mesh, _fu ); + explicitUpdater.template update< typename Mesh::Cell >( time, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + fu ); + tnlBoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter; + boundaryConditionsSetter.template apply< typename Mesh::Cell >( + this->boundaryCondition, + time + tau, + u ); +*/ + } + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > + template< typename Matrix > +void +eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + Matrix& matrix, + DofVectorType& b, + MeshDependentDataType& meshDependentData ) +{ + tnlLinearSystemAssembler< Mesh, + MeshFunctionType, + DifferentialOperator, + BoundaryCondition, + RightHandSide, + tnlBackwardTimeDiscretisation, + Matrix, + DofVectorType > systemAssembler; + + tnlMeshFunction< Mesh > u( mesh, _u ); + systemAssembler.template assembly< typename Mesh::Cell >( time, + tau, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + matrix, + b ); +} + +#endif /* eulerPROBLEM_IMPL_H_ */ diff --git a/examples/inviscid-flow/2d/eulerRhs.h b/examples/inviscid-flow/2d/eulerRhs.h new file mode 100644 index 0000000000000000000000000000000000000000..582dc36413ae36d78aa06a03be2ad745325263d6 --- /dev/null +++ b/examples/inviscid-flow/2d/eulerRhs.h @@ -0,0 +1,29 @@ +#ifndef eulerRHS_H_ +#define eulerRHS_H_ +#include<functions/tnlDomain.h> +template< typename Mesh, typename Real >class eulerRhs + : public tnlDomain< Mesh::meshDimensions, MeshDomain > + { + public: + + typedef Mesh MeshType; + typedef Real RealType; + + bool setup( const tnlParameterContainer& parameters, + const tnlString& prefix = "" ) + { + return true; + } + + template< typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshEntity& entity, + const Real& time = 0.0 ) const + { + typedef typename MeshEntity::MeshType::VertexType VertexType; + VertexType v = entity.getCenter(); + return 0.0; + }; +}; + +#endif /* eulerRHS_H_ */ diff --git a/examples/inviscid-flow/2d/run-euler b/examples/inviscid-flow/2d/run-euler new file mode 100644 index 0000000000000000000000000000000000000000..f68b98a8406dea2f2142526283ec60248551c56d --- /dev/null +++ b/examples/inviscid-flow/2d/run-euler @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-y 0.0 \ + --proportions-x 1.0 \ + --proportions-y 1.0 \ + --size-x 100 \ + --size-y 100 + +tnl-init --test-function sin-wave \ + --output-file init.tnl +./euler --time-discretisation explicit \ + --boundary-conditions-constant 0 \ + --discrete-solver merson \ + --snapshot-period 0.01 \ + --final-time 1.0 + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/inviscid-flow/CMakeLists.txt b/examples/inviscid-flow/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..10af3c9c773bc36bca44191359b4a4e244d1faa4 --- /dev/null +++ b/examples/inviscid-flow/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory( 1d ) +add_subdirectory( 2d )