diff --git a/CMakeLists.txt b/CMakeLists.txt index b215cce5d76251005d880a2d9a5e25531ac689c8..61a85bf4637f99157c7762b69e9d884edf90b874 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,6 +171,7 @@ if( WITH_CUDA STREQUAL "yes" ) endif( CUDA_FOUND ) endif( WITH_CUDA STREQUAL "yes" ) + #### # Check for OpenMP # diff --git a/Copyright b/Copyright index 1acdabf71aab5f9fa39db4324b5df03c2d4628f8..5582a49998d29ad3d7552e697c4eeb26a09ea461 100644 --- a/Copyright +++ b/Copyright @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2004-2016 Tomáš Oberhuber et al. +Copyright (c) 2004-2017 Tomáš Oberhuber et al. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/TODO b/TODO index e83b80a67e00b0c6fa1911f2d37919b410aa03ba..089a312dd155e7817f8fc5ab5b3a0c823f832be8 100644 --- a/TODO +++ b/TODO @@ -16,9 +16,6 @@ TODO: TODO: - - zrejme bude potreba udrzovat ke kazdemu objektu jeho obraz na GPU/MIC - - to by zarizovala metoda syncToDevice() napr. kazdy objekt by mel promennou modified, ktera by rikala, jestli se zmenil a zda je nutne ho - prekopirovavat TODO: - zavest namespaces @@ -31,6 +28,11 @@ TODO: CUDA unified memory se s nimi pracovat postaru - bylo by dobre to obalit unique poinetry, aby se nemusela delat dealokace rucne +TODO: shared pointery + - mohli bysme pomoci nich odstranit Shared objekty + - asi by bylo lepsi datcounter z shared pointeru primo do array a tento counter by se alokoval az po porvnim sdileni dat + - diky tomu by se array mohlo vytvaret i na gpu bez nutnosti dynamicke alokace, jen by nebylo mozne delat bind (nebo nejaky zjednoduseny) + TODO: Mesh * vsechny traits zkusit presunout do jednotneho MeshTraits, tj. temer MeshConfigTraits ale pojmenovat jako MeshTraits * omezit tnlDimesnionsTag - asi to ale nepujde diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 0f00654e037cfb1ab253fa4276a57fc1f0f25126..dca68ee58a2075836a177be031be115907577cc8 100755 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,15 @@ add_subdirectory( heat-equation ) +add_subdirectory( transport-equation ) add_subdirectory( navier-stokes ) -add_subdirectory( advection ) + +#add_subdirectory( mean-curvature-flow ) +#add_subdirectory( hamilton-jacobi ) +#add_subdirectory( hamilton-jacobi-parallel ) +#add_subdirectory( fast-sweeping ) +#add_subdirectory( hamilton-jacobi-parallel-map ) +#add_subdirectory( fast-sweeping-map ) +#add_subdirectory( narrow-band ) + add_subdirectory( inviscid-flow ) #add_subdirectory( mean-curvature-flow ) + diff --git a/examples/advection/CMakeLists.txt b/examples/advection/CMakeLists.txt deleted file mode 100644 index a09abadcdf99acf50e41f0909dfe02f4dfc31ea9..0000000000000000000000000000000000000000 --- a/examples/advection/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -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 deleted file mode 100644 index 46e63b77a2fa7661b8f7dd83cae964eab0c61272..0000000000000000000000000000000000000000 --- a/examples/advection/LaxFridrichs.h +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef LaxFridrichs_H -#define LaxFridrichs_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -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< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - Real tau; - Real artificalViscosity; - Real advectionSpeedX; - Real advectionSpeedY; - - void setAdvectionSpeedY(const Real& advectionSpeed) - { - this->advectionSpeedY = advectionSpeed; - } - - - void setAdvectionSpeedX(const Real& advectionSpeed) - { - this->advectionSpeedX = advectionSpeed; - } - - void setViscosity(const Real& artificalViscosity) - { - this->artificalViscosity = artificalViscosity; - } - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - static String getType(); - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - Real tau; - Real artificalViscosity; - Real advectionSpeedX; - Real advectionSpeedY; - - void setAdvectionSpeedY(const Real& advectionSpeed) - { - this->advectionSpeedY = advectionSpeed; - } - - - void setAdvectionSpeedX(const Real& advectionSpeed) - { - this->advectionSpeedX = advectionSpeed; - } - - void setViscosity(const Real& artificalViscosity) - { - this->artificalViscosity = artificalViscosity; - } - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - static String getType(); - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - Real tau; - Real artificalViscosity; - Real advectionSpeedX; - Real advectionSpeedY; - - void setAdvectionSpeedY(const Real& advectionSpeed) - { - this->advectionSpeedY = advectionSpeed; - } - - - void setAdvectionSpeedX(const Real& advectionSpeed) - { - this->advectionSpeedX = advectionSpeed; - } - - void setViscosity(const Real& artificalViscosity) - { - this->artificalViscosity = artificalViscosity; - } - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - static String getType(); - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} // namespace TNL - - -#include "LaxFridrichs_impl.h" - -#endif /* LaxFridrichs_H */ diff --git a/examples/advection/LaxFridrichs_impl.h b/examples/advection/LaxFridrichs_impl.h deleted file mode 100644 index dc65664b3b5b8ef599d61988924b3a705b6f94ca..0000000000000000000000000000000000000000 --- a/examples/advection/LaxFridrichs_impl.h +++ /dev/null @@ -1,361 +0,0 @@ -#ifndef LaxFridrichs_IMPL_H -#define LaxFridrichs_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichs< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichs< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichs< Meshes::Grid< 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 = this->advectionSpeedX * ( 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< Meshes::Grid< 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< Meshes::Grid< 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 > -String -LaxFridrichs< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichs< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichs< Meshes::Grid< 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[ north ] - u[ south ] ) ) * hyInverse * 0.5; - - -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichs< Meshes::Grid< 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< Meshes::Grid< 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 > -String -LaxFridrichs< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichs< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichs< Meshes::Grid< 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< Meshes::Grid< 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< Meshes::Grid< 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 );*/ -} - -} // namespace TNL - -#endif /* LaxFridrichsIMPL_H */ - diff --git a/examples/advection/advection.cpp b/examples/advection/advection.cpp deleted file mode 100644 index 374d4714086168f7ebf1ed2a62664c4aaae0c4b7..0000000000000000000000000000000000000000 --- a/examples/advection/advection.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "advection.h" diff --git a/examples/advection/advection.cu b/examples/advection/advection.cu deleted file mode 100644 index 374d4714086168f7ebf1ed2a62664c4aaae0c4b7..0000000000000000000000000000000000000000 --- a/examples/advection/advection.cu +++ /dev/null @@ -1 +0,0 @@ -#include "advection.h" diff --git a/examples/advection/advection.h b/examples/advection/advection.h deleted file mode 100644 index dc8d52ae085b277225634637969e72e2d3ff6a40..0000000000000000000000000000000000000000 --- a/examples/advection/advection.h +++ /dev/null @@ -1,122 +0,0 @@ -#include <TNL/tnlConfig.h> -#include <TNL/Solvers/Solver.h> -#include <TNL/Solvers/BuildConfigTags.h> -#include <TNL/Operators/DirichletBoundaryConditions.h> -#include <TNL/Operators/NeumannBoundaryConditions.h> -#include <TNL/Functions/Analytic/Constant.h> -#include "advectionProblem.h" -#include "LaxFridrichs.h" -#include "advectionRhs.h" -#include "advectionBuildConfigTag.h" - -using namespace TNL; - -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( Config::ConfigDescription & config ) - { - config.addDelimiter( "advection settings:" ); - config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); - config.addEntryEnum< String >( "dirichlet" ); - config.addEntryEnum< String >( "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< String >( "begin", "choose begin type", "sin"); - config.addEntryEnum< String >( "sin"); - config.addEntryEnum< String >( "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< String >( "move", "choose movement type", "advection"); - config.addEntryEnum< String >( "advection"); - config.addEntryEnum< String >( "rotation"); - config.addEntry< int >( "dimension", "choose movement typeproblem dimension", 1); - config.addEntryEnum< int >( 1 ); - config.addEntryEnum< int >( 2 ); - config.addEntry< double >( "realSize", "Real size of scheme", 1.0); - - /**** - * 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 Config::ParameterContainer & parameters ) - { - enum { Dimensions = MeshType::getMeshDimensions() }; - typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator; - typedef advectionRhs< MeshType, Real > RightHandSide; - typedef Containers::StaticVector < 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 Vector. - */ - String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" ); - if( parameters.checkParameter( "boundary-conditions-constant" ) ) - { - typedef Functions::Analytic::Constant< Dimensions, Real > Constant; - if( boundaryConditionsType == "dirichlet" ) - { - typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; - typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; - SolverStarter solverStarter; - return solverStarter.template run< Problem >( parameters ); - } - typedef Operators::NeumannBoundaryConditions< MeshType, Constant, Real, Index > BoundaryConditions; - typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; - SolverStarter solverStarter; - return solverStarter.template run< Problem >( parameters ); - } - typedef Functions::MeshFunction< MeshType > MeshFunction; - if( boundaryConditionsType == "dirichlet" ) - { - typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; - typedef advectionProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; - SolverStarter solverStarter; - return solverStarter.template run< Problem >( parameters ); - } - typedef Operators::NeumannBoundaryConditions< 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[] ) -{ - Solvers::Solver< 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 deleted file mode 100644 index 98371b43a3fce8743b7945bbec10ef04ce0d219c..0000000000000000000000000000000000000000 --- a/examples/advection/advectionBuildConfigTag.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef advectionBUILDCONFIGTAG_H_ -#define advectionBUILDCONFIGTAG_H_ - -#include <TNL/Solvers/BuildConfigTags.h> - -namespace TNL { - -class advectionBuildConfigTag{}; - -namespace Solvers { - -/**** - * Turn off support for float and long double. - */ -template<> struct ConfigTagReal< advectionBuildConfigTag, float > { enum { enabled = false }; }; -template<> struct ConfigTagReal< advectionBuildConfigTag, long double > { enum { enabled = false }; }; - -/**** - * Turn off support for short int and long int indexing. - */ -template<> struct ConfigTagIndex< advectionBuildConfigTag, short int >{ enum { enabled = false }; }; -template<> struct ConfigTagIndex< advectionBuildConfigTag, long int >{ enum { enabled = false }; }; - -/**** - * Use of Grid is enabled for allowed dimensions and Real, Device and Index types. - */ - -template< int Dimensions, typename Real, typename Device, typename Index > - struct ConfigTagMesh< advectionBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > > - { enum { enabled = ConfigTagDimensions< advectionBuildConfigTag, Dimensions >::enabled && - ConfigTagReal< advectionBuildConfigTag, Real >::enabled && - ConfigTagDevice< advectionBuildConfigTag, Device >::enabled && - ConfigTagIndex< advectionBuildConfigTag, Index >::enabled }; }; - -/**** - * Please, chose your preferred time discretisation here. - */ -template<> struct ConfigTagTimeDiscretisation< advectionBuildConfigTag, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; -template<> struct ConfigTagTimeDiscretisation< advectionBuildConfigTag, SemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; -template<> struct ConfigTagTimeDiscretisation< advectionBuildConfigTag, ImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; - -/**** - * Only the Runge-Kutta-Merson solver is enabled by default. - */ -template<> struct ConfigTagExplicitSolver< advectionBuildConfigTag, Solvers::ExplicitEulerSolverTag >{ enum { enabled = true }; }; - -} // namespace Solvers -} // namespace TNL - -#endif /* advectionBUILDCONFIGTAG_H_ */ diff --git a/examples/advection/advectionProblem_impl.h b/examples/advection/advectionProblem_impl.h deleted file mode 100644 index cd37f52eff7454b863d14eb245b2b9d7236a5a37..0000000000000000000000000000000000000000 --- a/examples/advection/advectionProblem_impl.h +++ /dev/null @@ -1,342 +0,0 @@ -#ifndef advectionPROBLEM_IMPL_H_ -#define advectionPROBLEM_IMPL_H_ - -#include <TNL/FileName.h> -#include <TNL/Matrices/MatrixSetter.h> -#include <TNL/Solvers/PDE/ExplicitUpdater.h> -#include <TNL/Solvers/PDE/LinearSystemAssembler.h> -#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h> - -namespace TNL { - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -String -advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -getTypeStatic() -{ - return String( "advectionProblem< " ) + Mesh :: getTypeStatic() + " >"; -} - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -String -advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -getPrologHeader() const -{ - return String( "advection" ); -} - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -void -advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -writeProlog( Logger& logger, const Config::ParameterContainer& 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 MeshPointer& meshPointer, - const Config::ParameterContainer& parameters, - const String& prefix ) -{ - if( ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) || - ! this->rightHandSidePointer->setup( parameters, prefix + "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 MeshPointer& 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 MeshPointer& mesh, - DofVectorPointer& dofVector ) -{ -} - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -bool -advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -setInitialCondition( const Config::ParameterContainer& parameters, - const MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ) -{ - std::cout << "vaules adding"; - typedef typename MeshType::Cell Cell; - int dimensions = parameters.getParameter< int >( "dimension" ); - int count = mesh->template getEntitiesCount< Cell >(); - const RealType& size = parameters.getParameter< double >( "realSize" ) / ::pow(count, 1.0/dimensions); - const String& beginChoice = parameters.getParameter< String >( "begin" ); - std::cout << beginChoice << " " << dimensions << " " << size << " " << count << " "<< 1/dimensions << std::endl; - getchar(); - if (beginChoice == "sin_square") - { - double constantFunction; - if (dimensions == 1) - { - std::cout << "adding DOFS" << std::endl; - ( *dofs )[0] = 0; - double expValue; - for (IndexType i = 1; i < count-2; i++) - { - expValue = std::exp(-std::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-1] = 0; - } - else if (dimensions == 2) - { - count = std::sqrt(count); - double expValue; - for (IndexType i = 0; i < count-1; i++) - for (IndexType j = 0; j < count-1; j++) - { - expValue = std::exp(-std::pow(size*i-2,2)-std::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 * count + j] = expValue; - else ( *dofs )[i * count + j] = constantFunction; - }; - }; - } - else if (beginChoice == "sin") - { - if (dimensions == 1) - { - ( *dofs )[0] = 0; - for (IndexType i = 1; i < count-2; i++) - { - ( *dofs )[i] = std::exp(-std::pow(size*i-2,2)); - }; - ( *dofs )[count-1] = 0; - } - else if (dimensions == 2) - { - count = ::sqrt(count); - for (IndexType i = 1; i < count-1; i++) - for (IndexType j = 1; j < count-1; j++) - { - ( *dofs )[i * count + j] = std::exp(-std::pow(size*i-2,2)-std::pow(size*j-2,2)); - }; - }; - }; - //setting velocity field - std::cout << *dofs << std::endl; - getchar(); - /*const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" ); - if( ! dofs.load( initialConditionFile ) ) - { - std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl; - return false; - } - return true;*/ - dofs->save( "dofs.tnl" ); - this->velocityType = parameters.getParameter< String >( "move" ); - const double artificalViscosity = parameters.getParameter< double >( "artifical-viscosity" ); - differentialOperatorPointer->setViscosity(artificalViscosity); - const double advectionSpeedX = parameters.getParameter< double >( "advection-speedX" ); - differentialOperatorPointer->setAdvectionSpeedX(advectionSpeedX); - const double advectionSpeedY = parameters.getParameter< double >( "advection-speedY" ); - differentialOperatorPointer->setAdvectionSpeedY(advectionSpeedY); - std::cout << "vaules added"; - return true; -} - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > - template< typename Matrix > -bool -advectionProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -setupLinearSystem( const MeshPointer& mesh, - Matrix& matrix ) -{ - const IndexType dofs = this->getDofs( mesh ); - typedef typename Matrix::ObjectType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType; - SharedPointer< CompressedRowsLengthsVectorType > rowLengths; - if( ! rowLengths->setSize( dofs ) ) - return false; - Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter; - matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh, - differentialOperatorPointer, - boundaryConditionPointer, - 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 MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ) -{ - std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl; - this->bindDofs( mesh, dofs ); - FileName fileName; - fileName.setFileNameBase( "u-" ); - fileName.setExtension( "tnl" ); - fileName.setIndex( step ); - if( ! dofs->save( fileName.getFileName() ) ) - 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 MeshPointer& mesh, - DofVectorPointer& _u, - DofVectorPointer& _fu, - MeshDependentDataPointer& meshDependentData ) -{ - /**** - * If you use an explicit solver like Euler or Merson, 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 = ::sqrt(mesh->template getEntitiesCount< Cell >()); -// const RealType& size = parameters.getParameter< double >( "realSize" ) / ::pow(count, 0.5); -/* 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 ); - Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater; - SharedPointer< MeshFunctionType > u( mesh, _u ); - SharedPointer< MeshFunctionType > fu( mesh, _fu ); - differentialOperatorPointer->setTau(tau); - explicitUpdater.template update< typename Mesh::Cell >( time, - mesh, - this->differentialOperatorPointer, - this->boundaryConditionPointer, - this->rightHandSidePointer, - u, - fu ); -/* BoundaryConditionsSetter< 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 MeshPointer& mesh, - DofVectorPointer& _u, - Matrix& matrix, - DofVectorPointer& b, - MeshDependentDataPointer& meshDependentData ) -{ - /*LinearSystemAssembler< Mesh, - MeshFunctionType, - DifferentialOperator, - BoundaryCondition, - RightHandSide, - BackwardTimeDiscretisation, - Matrix, - DofVectorType > systemAssembler; - - MeshFunction< Mesh > u( mesh, _u ); - systemAssembler.template assembly< typename Mesh::Cell >( time, - tau, - mesh, - this->differentialOperator, - this->boundaryCondition, - this->rightHandSide, - u, - matrix, - b );*/ -} - -} // namespace TNL - -#endif /* advectionPROBLEM_IMPL_H_ */ diff --git a/examples/advection/advectionRhs.h b/examples/advection/advectionRhs.h deleted file mode 100644 index 1ddb255a09906deece99fbf31df54659f3740a92..0000000000000000000000000000000000000000 --- a/examples/advection/advectionRhs.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include <TNL/Functions/Domain.h> - -namespace TNL { - -template< typename Mesh, typename Real >class advectionRhs - : public Functions::Domain< Mesh::meshDimensions, Functions::MeshDomain > -{ - public: - - typedef Mesh MeshType; - typedef Real RealType; - - bool setup( const Config::ParameterContainer& parameters, - const String& 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; - } -}; - -} // namespace TNL - diff --git a/examples/advection/tnl-run-advection b/examples/advection/tnl-run-advection deleted file mode 100644 index 4ce2c6be3f3aea3c49e3619155cc489335bb2e25..0000000000000000000000000000000000000000 --- a/examples/advection/tnl-run-advection +++ /dev/null @@ -1,20 +0,0 @@ -#!/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 -tnl-advection-dbg --time-discretisation explicit \ - --time-step 1.0e-3 \ - --boundary-conditions-constant 0 \ - --discrete-solver merson \ - --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 deleted file mode 100644 index fb5e81faf2e19ab8e6b19c02c0c441dd96a9c807..0000000000000000000000000000000000000000 --- a/examples/advection/tnl-run-advection1 +++ /dev/null @@ -1,24 +0,0 @@ -#!/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 deleted file mode 100644 index 5d3e3990a98ef64233a6b629b4002cc50b26a923..0000000000000000000000000000000000000000 --- a/examples/advection/tnl-run-advectionrot1 +++ /dev/null @@ -1,25 +0,0 @@ -#!/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/heat-equation/tnl-heat-equation.h b/examples/heat-equation/tnl-heat-equation.h index bb9de072e09465d93ba8bacdda947cfc474c1438..382ecdb3ba247c4aa4746b78b4752555f91c6100 100644 --- a/examples/heat-equation/tnl-heat-equation.h +++ b/examples/heat-equation/tnl-heat-equation.h @@ -46,7 +46,7 @@ class heatEquationConfig config.addEntry< String >( "boundary-conditions-file", "File with the values of the boundary conditions.", "boundary.tnl" ); config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." ); config.addEntry< double >( "right-hand-side-constant", "This sets a constant value for the right-hand side.", 0.0 ); - //config.addEntry< String >( "initial-condition", "File with the initial condition.", "initial.tnl"); + config.addEntry< String >( "initial-condition", "File with the initial condition.", "initial.tnl"); }; }; diff --git a/examples/inviscid-flow/1d/CMakeLists.txt b/examples/inviscid-flow/1d/CMakeLists.txt deleted file mode 100644 index 6fe0766eec90a76d7888c56f615122804abf4bcc..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -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/EulerPressureGetter.h b/examples/inviscid-flow/1d/EulerPressureGetter.h deleted file mode 100644 index fc98847a276c165b9352a42767e70e43ec5bcd98..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/EulerPressureGetter.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef EulerPressureGetter_H -#define EulerPressureGetter_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> -#include <TNL/Functions/Domain.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class EulerPressureGetter -: public Functions::Domain< Mesh::getMeshDimensions(), Functions::MeshDomain > -{ - public: - - typedef Mesh MeshType; - typedef typename MeshType::DeviceType DeviceType; - typedef Real RealType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - - EulerPressureGetter( const MeshFunctionType& velocity, - const MeshFunctionType& rhoVel, - const MeshFunctionType& energy, - const RealType& gamma ) - : rho( rho ), rhoVel( rhoVel ), energy( energy ), gamma( gamma ) - {} - - template< typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshEntity& entity, - const RealType& time = 0.0 ) const - { - return this->operator[]( entity.getIndex() ); - } - - __cuda_callable__ - Real operator[]( const IndexType& idx ) const - { - return ( this->gamma - 1.0 ) * ( this->energy[ idx ] - 0.5 * this->rhoVel[ idx ] * this->rhoVel[ idx ] / this->rho[ idx ]); - } - - - protected: - - Real gamma; - - const MeshFunctionType& rho; - - const MeshFunctionType& rhoVel; - - const MeshFunctionType& energy; - -}; - -} //namespace TNL - -#endif /* EulerPressureGetter_H */ diff --git a/examples/inviscid-flow/1d/EulerVelGetter.h b/examples/inviscid-flow/1d/EulerVelGetter.h deleted file mode 100644 index 7e58ae77d6058d27c6e21169603ed09efe68f089..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/EulerVelGetter.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef EulerVelGetter_H -#define EulerVelGetter_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class EulerVelGetter -: public Functions::Domain< Mesh::getMeshDimensions(), Functions::MeshDomain > -{ - public: - - typedef Mesh MeshType; - typedef typename MeshType::DeviceType DeviceType; - typedef Real RealType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - - EulerVelGetter( const MeshFunctionType& rho, - const MeshFunctionType& rhoVel) - : rho( rho ), rhoVel( rhoVel ) - {} - - template< typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshEntity& entity, - const RealType& time = 0.0 ) const - { - return this->operator[]( entity.getIndex() ); - } - - __cuda_callable__ - Real operator[]( const IndexType& idx ) const - { - return this->rho[ idx ] / this->rhoVel[ idx ]; - } - - - protected: - - const MeshFunctionType& rho; - - const MeshFunctionType& rhoVel; - -}; - -} // namespace TNL - -#endif /* EulerVelGetter_H */ diff --git a/examples/inviscid-flow/1d/LaxFridrichs.h b/examples/inviscid-flow/1d/LaxFridrichs.h deleted file mode 100644 index a5cb7eea5c6183e07facebb0750d02b8fc04d694..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/LaxFridrichs.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef LaxFridrichs_H -#define LaxFridrichs_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -#include "LaxFridrichsContinuity.h" -#include "LaxFridrichsMomentum.h" -#include "LaxFridrichsEnergy.h" -#include "EulerVelGetter.h" -#include "EulerPressureGetter.h" - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichs -{ - public: - typedef Real RealType; - typedef typename Mesh::DeviceType DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< Mesh > MeshFunctionType; - - typedef LaxFridrichsContinuity< Mesh, Real, Index > Continuity; - typedef LaxFridrichsMomentum< Mesh, Real, Index > Momentum; - typedef LaxFridrichsEnergy< Mesh, Real, Index > Energy; - typedef EulerVelGetter< Mesh, Real, Index > Velocity; - typedef EulerPressureGetter< Mesh, Real, Index > Pressure; - -}; - -} // namespace TNL - -#endif /* LaxFridrichs_H */ diff --git a/examples/inviscid-flow/1d/LaxFridrichsContinuity.h b/examples/inviscid-flow/1d/LaxFridrichsContinuity.h deleted file mode 100644 index 8053895eda0787a52d12335ad4d9a1acc87e114a..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/LaxFridrichsContinuity.h +++ /dev/null @@ -1,184 +0,0 @@ -#ifndef LaxFridrichsContinuity_H -#define LaxFridrichsContinuity_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichsContinuity -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class LaxFridrichsContinuity< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType velocity) - { - //this->velocity = velocity; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsContinuity< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsContinuity< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} // namespace TNL - -#include "LaxFridrichsContinuity_impl.h" - -#endif /* LaxFridrichsContinuity_H */ diff --git a/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h b/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h deleted file mode 100644 index 3be1a5b6e4cbcdafcab3cf81c55ac51304123a8e..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/LaxFridrichsContinuity_impl.h +++ /dev/null @@ -1,345 +0,0 @@ -#ifndef LaxFridrichsContinuity_IMPL_H -#define LaxFridrichsContinuity_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichsContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsContinuity< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -operator()( const MeshFunction& u, - const MeshEntity& entity, - const Real& time ) const -{ - 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 >(); - return (0.5 * this->tau) * ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) - - 0.5 * hxInverse * ( u[ west ] * this->velocity[ west ] - u[ east ] * this->velocity[ east ] ); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 > -String -LaxFridrichsContinuity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsContinuity< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 > -String -LaxFridrichsContinuity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsContinuity< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 ); -} - -} // namespace TNL - -#endif /* LaxFridrichsContinuityIMPL_H */ - diff --git a/examples/inviscid-flow/1d/LaxFridrichsEnergy.h b/examples/inviscid-flow/1d/LaxFridrichsEnergy.h deleted file mode 100644 index fa0012eb8d006aa452b702c4d0d38eed6b04ccdd..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/LaxFridrichsEnergy.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef LaxFridrichsEnergy_H -#define LaxFridrichsEnergy_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichsEnergy -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class LaxFridrichsEnergy< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsEnergy< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsEnergy< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} // namespace TNL - -#include "LaxFridrichsEnergy_impl.h" - -#endif /* LaxFridrichsEnergy_H */ diff --git a/examples/inviscid-flow/1d/LaxFridrichsEnergy_impl.h b/examples/inviscid-flow/1d/LaxFridrichsEnergy_impl.h deleted file mode 100644 index ba8092e807211da1470873252ad269c98d69a990..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/LaxFridrichsEnergy_impl.h +++ /dev/null @@ -1,352 +0,0 @@ -#ifndef LaxFridrichsEnergy_IMPL_H -#define LaxFridrichsEnergy_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichsEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsEnergy< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsEnergy< Meshes::Grid< 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(); - - //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 >(); - return (0.5 * this->tau) * ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) - - 0.5 * hxInverse * - (( u[ west ] + this->pressure[ west ] ) * velocity[ west ] - - (u[ east ] + this->pressure[ east ] ) * velocity[ east ] ); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 > -String -LaxFridrichsEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsEnergy< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 > -String -LaxFridrichsEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsEnergy< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 ); -} - -} //namespace TNL - -#endif /* LaxFridrichsEnergyIMPL_H */ - diff --git a/examples/inviscid-flow/1d/LaxFridrichsMomentum.h b/examples/inviscid-flow/1d/LaxFridrichsMomentum.h deleted file mode 100644 index 5bb8818833b32f14415c4d2c107dfe0025d44a7e..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/LaxFridrichsMomentum.h +++ /dev/null @@ -1,201 +0,0 @@ -#ifndef LaxFridrichsMomentum_H -#define LaxFridrichsMomentum_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichsMomentum -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class LaxFridrichsMomentum< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsMomentum< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsMomentum< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocity; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} // namespace TNL - - -#include "LaxFridrichsMomentum_impl.h" - -#endif /* LaxFridrichsMomentum_H */ diff --git a/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h b/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h deleted file mode 100644 index 75c7a7fea080bc13201c19dd843f017b8052e4bc..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/LaxFridrichsMomentum_impl.h +++ /dev/null @@ -1,347 +0,0 @@ -#ifndef LaxFridrichsMomentum_IMPL_H -#define LaxFridrichsMomentum_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichsMomentum< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentum< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentum< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -operator()( const MeshFunction& u, - const MeshEntity& entity, - const Real& time ) const -{ - 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(); - - //rhoVelocity - 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 (0.5 * this->tau) * ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) - - 0.5 * hxInverse * - (( u[ west ] * this -> velocity[ west ] + this -> pressure [ west ] ) - - (u[ east ] * this -> velocity[ east ] + this -> pressure [ east ] )); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichsMomentum< Meshes::Grid< 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 -LaxFridrichsMomentum< Meshes::Grid< 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 > -String -LaxFridrichsMomentum< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentum< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentum< Meshes::Grid< 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 -LaxFridrichsMomentum< Meshes::Grid< 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 -LaxFridrichsMomentum< Meshes::Grid< 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 > -String -LaxFridrichsMomentum< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentum< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentum< Meshes::Grid< 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 -LaxFridrichsMomentum< Meshes::Grid< 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 -LaxFridrichsMomentum< Meshes::Grid< 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 ); -} - -} // namespace TNL - -#endif /* LaxFridrichsMomentumIMPL_H */ - diff --git a/examples/inviscid-flow/1d/eulerProblem_impl.h b/examples/inviscid-flow/1d/eulerProblem_impl.h deleted file mode 100644 index 0ed9d4f1a5da37c32faa7fc0e41ef4bc92e84521..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/eulerProblem_impl.h +++ /dev/null @@ -1,383 +0,0 @@ -#ifndef eulerPROBLEM_IMPL_H_ -#define eulerPROBLEM_IMPL_H_ - -#include <TNL/FileName.h> -#include <TNL/Matrices/MatrixSetter.h> -#include <TNL/Solvers/PDE/ExplicitUpdater.h> -#include <TNL/Solvers/PDE/LinearSystemAssembler.h> -#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h> -#include "LaxFridrichsContinuity.h" -#include "LaxFridrichsMomentum.h" -#include "LaxFridrichsEnergy.h" -#include "EulerVelGetter.h" -#include "EulerPressureGetter.h" - -namespace TNL { - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -String -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -getTypeStatic() -{ - return String( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >"; -} - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -String -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -getPrologHeader() const -{ - return String( "euler" ); -} - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -void -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -writeProlog( Logger& logger, const Config::ParameterContainer& 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 MeshPointer& meshPointer, - const Config::ParameterContainer& parameters, - const String& prefix ) -{ - if( ! this->boundaryConditionsPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) || - ! this->rightHandSidePointer->setup( parameters, prefix + "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 MeshPointer& 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 MeshPointer& mesh, - DofVectorPointer& dofVector ) -{ -} - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -bool -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -setInitialCondition( const Config::ParameterContainer& parameters, - const MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ) -{ - std::cout << std::endl << "get conditions from CML"; - typedef typename MeshType::Cell Cell; - this->gamma = parameters.getParameter< RealType >( "gamma" ); - RealType rhoL = parameters.getParameter< RealType >( "left-density" ); - RealType velL = parameters.getParameter< RealType >( "left-velocity" ); - RealType preL = parameters.getParameter< RealType >( "left-pressure" ); - RealType eL = ( preL / (gamma - 1) ) + 0.5 * rhoL * velL * velL; - RealType rhoR = parameters.getParameter< RealType >( "right-density" ); - RealType velR = parameters.getParameter< RealType >( "right-velocity" ); - RealType preR = parameters.getParameter< RealType >( "right-pressure" ); - RealType eR = ( preR / (gamma - 1) ) + 0.5 * rhoR * velR * velR; - RealType x0 = parameters.getParameter< RealType >( "riemann-border" ); - std::cout << std::endl << gamma << " " << rhoL << " " << velL << " " << preL << " " << eL << " " << rhoR << " " << velR << " " << preR << " " << eR << " " << x0 << " " << gamma << std::endl; - int count = mesh->template getEntitiesCount< Cell >(); - std::cout << count << std::endl; - uRho->bind( mesh, *dofs, 0); - uRhoVelocity->bind( mesh, *dofs, count); - uEnergy->bind( mesh, *dofs, 2 * count); - Containers::Vector < RealType, DeviceType, IndexType > data; - data.setSize(2*count); - velocity->bind( mesh, data, 0); - pressure->bind( mesh, data, count ); - std::cout << std::endl << "set conditions from CML"<< std::endl; - for(IndexType i = 0; i < count; i++) - if (i < x0 * count ) - { - ( *uRho )[i] = rhoL; - ( *uRhoVelocity )[i] = rhoL * velL; - ( *uEnergy )[i] = eL; - ( *velocity )[i] = velL; - ( *pressure )[i] = preL; - } - else - { - ( *uRho )[i] = rhoR; - ( *uRhoVelocity )[i] = rhoR * velR; - ( *uEnergy )[i] = eR; - ( *velocity )[i] = velR; - ( *pressure )[i] = preR; - }; - std::cout << "dofs = " << *dofs << std::endl; - getchar(); - - - /* - const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" ); - if( ! dofs.load( initialConditionFile ) ) - { - std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::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 MeshPointer& mesh, - Matrix& matrix ) -{ -/* const IndexType dofs = this->getDofs( mesh ); - typedef typename Matrix::CompressedRowsLengthsVector CompressedRowsLengthsVectorType; - CompressedRowsLengthsVectorType rowLengths; - if( ! rowLengths.setSize( dofs ) ) - return false; - MatrixSetter< 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 MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ) -{ - std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl; - this->bindDofs( mesh, dofs ); - typedef typename MeshType::Cell Cell; - int count = mesh->template getEntitiesCount< Cell >(); - std::ofstream vysledek; -/* std::cout << "pressure:" << std::endl; - for (IndexType i = 0; i<count; i++)std::cout << this->pressure[i] << " " << i ; - vysledek.open("pressure" + to_string(step) + ".txt"); - for (IndexType i = 0; i<count; i++) - vysledek << 0.01*i << " " << pressure[i] << std::endl; - vysledek.close(); - std::cout << " " << std::endl; - std::cout << "velocity:" << std::endl; - for (IndexType i = 0; i<count; i++)std::cout << this->velocity[i] << " " ; - vysledek.open("velocity" + to_string(step) + ".txt"); - for (IndexType i = 0; i<count; i++) - vysledek << 0.01*i << " " << pressure[i] << std::endl; - vysledek.close(); - std::cout << "energy:" << std::endl; - for (IndexType i = 0; i<count; i++)std::cout << this->uEnergy[i] << " " ; - vysledek.open("energy" + to_string(step) + ".txt"); - for (IndexType i = 0; i<count; i++) - vysledek << 0.01*i << " " << uEnergy[i] << std::endl; - vysledek.close(); - std::cout << " " << std::endl; - std::cout << "density:" << std::endl; - for (IndexType i = 0; i<count; i++)std::cout << this->uRho[i] << " " ; - vysledek.open("density" + to_string(step) + ".txt"); - for (IndexType i = 0; i<count; i++) - vysledek << 0.01*i << " " << uRho[i] << std::endl; - vysledek.close(); -*/ getchar(); - - FileName fileName; - fileName.setExtension( "tnl" ); - fileName.setIndex( step ); - fileName.setFileNameBase( "rho-" ); - - if( ! uRho->save( fileName.getFileName() ) ) - return false; - fileName.setFileNameBase( "rhoVel-" ); - if( ! uRhoVelocity->save( fileName.getFileName() ) ) - return false; - fileName.setFileNameBase( "energy-" ); - if( ! uEnergy->save( fileName.getFileName() ) ) - 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 MeshPointer& mesh, - DofVectorPointer& _u, - DofVectorPointer& _fu, - MeshDependentDataPointer& meshDependentData ) -{ - std::cout << "explicitRHS" << std::endl; - typedef typename MeshType::Cell Cell; - int count = mesh->template getEntitiesCount< Cell >(); - //bind _u - this->uRho->bind(mesh, _u, 0); - this->uRhoVelocity->bind(mesh, _u ,count); - this->uEnergy->bind(mesh, _u, 2 * count); - - //bind _fu - this->fuRho->bind(mesh, _u, 0); - this->fuRhoVelocity->bind(mesh, _u, count); - this->fuEnergy->bind(mesh, _u, 2 * count); - - //generating Differential operator object - SharedPointer< Continuity > lF1DContinuity; - SharedPointer< Momentum > lF1DMomentum; - SharedPointer< Energy > lF1DEnergy; - - - - std::cout << "explicitRHSrho" << std::endl; - //rho - this->bindDofs( mesh, _u ); - lF1DContinuity->setTau(tau); - lF1DContinuity->setVelocity( *velocity); - /*ExplicitUpdater< Mesh, MeshFunctionType, Continuity, BoundaryCondition, RightHandSide > explicitUpdaterContinuity; - explicitUpdaterContinuity.template update< typename Mesh::Cell >( time, - mesh, - lF1DContinuity, - this->boundaryCondition, - this->rightHandSide, - uRho, - fuRho );*/ - - std::cout << "explicitRHSrhovel" << std::endl; - //rhoVelocity - lF1DMomentum->setTau(tau); - lF1DMomentum->setVelocity( *velocity); - lF1DMomentum->setPressure( *pressure); - Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Momentum, BoundaryCondition, RightHandSide > explicitUpdaterMomentum; - explicitUpdaterMomentum.template update< typename Mesh::Cell >( time, - mesh, - lF1DMomentum, - this->boundaryConditionsPointer, - this->rightHandSidePointer, - uRhoVelocity, - fuRhoVelocity ); - - std::cout << "explicitRHSenergy" << std::endl; - //energy - lF1DEnergy->setTau(tau); - lF1DEnergy->setPressure( *pressure); - lF1DEnergy->setVelocity( *velocity); - Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Energy, BoundaryCondition, RightHandSide > explicitUpdaterEnergy; - explicitUpdaterEnergy.template update< typename Mesh::Cell >( time, - mesh, - lF1DEnergy, - this->boundaryConditionsPointer, - this->rightHandSidePointer, - uEnergy, - fuEnergy ); - - } - -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 MeshPointer& mesh, - DofVectorPointer& _u, - Matrix& matrix, - DofVectorPointer& b, - MeshDependentDataPointer& meshDependentData ) -{ -/* LinearSystemAssembler< Mesh, - MeshFunctionType, - DifferentialOperator, - BoundaryCondition, - RightHandSide, - BackwardTimeDiscretisation, - Matrix, - DofVectorType > systemAssembler; - - MeshFunction< Mesh > u( mesh, _u ); - systemAssembler.template assembly< typename Mesh::Cell >( time, - tau, - mesh, - this->differentialOperator, - this->boundaryCondition, - this->rightHandSide, - u, - matrix, - b );*/ -} -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -bool -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: -postIterate( const RealType& time, - const RealType& tau, - const MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ) -{ - //velocity - this->velocity->setMesh( mesh ); - Velocity velocityGetter( *uRho, *uRhoVelocity ); - *this->velocity = velocityGetter; - //pressure - this->pressure->setMesh( mesh ); - Pressure pressureGetter( *uRho, *uRhoVelocity, *uEnergy, gamma ); - *this->pressure = pressureGetter; -} - -} // namespace TNL - -#endif /* eulerPROBLEM_IMPL_H_ */ diff --git a/examples/inviscid-flow/1d/tnl-run-euler-1d b/examples/inviscid-flow/1d/tnl-run-euler-1d deleted file mode 100644 index a45f664042d2f4dab646319e506dd130b6238cfc..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/1d/tnl-run-euler-1d +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env bash - -tnl-grid-setup --dimensions 1 \ - --origin-x 0.0 \ - --proportions-x 1.0 \ - --size-x 100 - -#tnl-init --test-function sin-wave \ -# --output-file init.tnl -tnl-euler-1d-dbg --time-discretisation explicit \ - --time-step 1.0e-3 \ - --boundary-conditions-constant 0 \ - --discrete-solver euler \ - --snapshot-period 0.1 \ - --final-time 1.0 \ - --left-density 1.0 \ - --left-velocity 0.75 \ - --left-pressure 1.0 \ - --right-density 0.125 \ - --right-velocity 0 \ - --right-pressure 0.1 \ - --gamma 1.4 \ - --riemann-border 0.3 \ - -tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/inviscid-flow/2d/CMakeLists.txt b/examples/inviscid-flow/2d/CMakeLists.txt deleted file mode 100644 index d753d50afcc11a2fccbe04e30410c77e8a5c1f81..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -set( tnl_heat_equation_SOURCES - euler.cpp - euler-cuda.cu ) - -IF( BUILD_CUDA ) - CUDA_ADD_EXECUTABLE(tnl-euler-2d${debugExt} euler-cuda.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 run-euler - ${tnl_heat_equation_SOURCES} - DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow-2d ) - diff --git a/examples/inviscid-flow/2d/EulerPressureGetter.h b/examples/inviscid-flow/2d/EulerPressureGetter.h deleted file mode 100644 index 49e50d72576c270dc1f94f661aae70444ca00677..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerPressureGetter.h +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef EulerPressureGetter_H -#define EulerPressureGetter_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class EulerPressureGetter -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class EulerPressureGetter< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real gamma; - MeshFunctionType velocity; - MeshFunctionType rho; - MeshFunctionType energy; - - void setGamma(const Real& gamma) - { - this->gamma = gamma; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - void setEnergy(const MeshFunctionType& energy) - { - this->energy = energy; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerPressureGetter< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real gamma; - MeshFunctionType velocity; - MeshFunctionType rho; - MeshFunctionType energy; - - void setGamma(const Real& gamma) - { - this->gamma = gamma; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - void setEnergy(const MeshFunctionType& energy) - { - this->energy = energy; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerPressureGetter< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real gamma; - MeshFunctionType velocity; - MeshFunctionType rho; - MeshFunctionType energy; - - void setGamma(const Real& gamma) - { - this->gamma = gamma; - }; - - void setVelocity(const MeshFunctionType& velocity) - { - this->velocity = velocity; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - void setEnergy(const MeshFunctionType& energy) - { - this->energy = energy; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - - -} //namespace TNL - -#include "EulerPressureGetter_impl.h" - -#endif /* EulerPressureGetter_H */ diff --git a/examples/inviscid-flow/2d/EulerPressureGetter_impl.h b/examples/inviscid-flow/2d/EulerPressureGetter_impl.h deleted file mode 100644 index 7d6b9310df3ddd19fbb261d7eb8dca00b72c82b9..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerPressureGetter_impl.h +++ /dev/null @@ -1,338 +0,0 @@ -#ifndef EulerPressureGetter_IMPL_H -#define EulerPressureGetter_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -EulerPressureGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerPressureGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerPressureGetter< Meshes::Grid< 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< -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 -EulerPressureGetter< Meshes::Grid< 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 -EulerPressureGetter< Meshes::Grid< 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 > -String -EulerPressureGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerPressureGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerPressureGetter< Meshes::Grid< 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. - */ - //pressure - const IndexType& center = entity.getIndex(); - - return ( this->gamma - 1 ) * ( energy[ center ] - 0.5 * rho[ center ] * ::pow( velocity[ center ],2 )); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -EulerPressureGetter< Meshes::Grid< 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 -EulerPressureGetter< Meshes::Grid< 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 > -String -EulerPressureGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerPressureGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerPressureGetter< Meshes::Grid< 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 -EulerPressureGetter< Meshes::Grid< 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 -EulerPressureGetter< Meshes::Grid< 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 ); -} - -} // namespace TNL - -#endif /* EulerPressureGetterIMPL_H */ - diff --git a/examples/inviscid-flow/2d/EulerVelGetter.h b/examples/inviscid-flow/2d/EulerVelGetter.h deleted file mode 100644 index 2da0052b87492d6dd27a2b6def5fa3ead42318fa..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerVelGetter.h +++ /dev/null @@ -1,186 +0,0 @@ -#ifndef EulerVelGetter_H -#define EulerVelGetter_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> -#include <TNL/Functions/Domain.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class EulerVelGetter -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class EulerVelGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > - : public TNL::Functions::Domain< 1, TNL::Functions::MeshDomain > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType velX; - MeshFunctionType velY; - - void setVelX(const MeshFunctionType& velX) - { - this->velX = velX; - }; - - void setVelY(const MeshFunctionType& velY) - { - this->velY = velY; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerVelGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > - : public TNL::Functions::Domain< 2, TNL::Functions::MeshDomain > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType velX; - MeshFunctionType velY; - - void setVelX(const MeshFunctionType& velX) - { - this->velX = velX; - }; - - void setVelY(const MeshFunctionType& velY) - { - this->velY = velY; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerVelGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > - : public TNL::Functions::Domain< 3, TNL::Functions::MeshDomain > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType velX; - MeshFunctionType velY; - - void setVelX(const MeshFunctionType& velX) - { - this->velX = velX; - }; - - void setVelY(const MeshFunctionType& velY) - { - this->velY = velY; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} //namespace TNL - -#include "EulerVelGetter_impl.h" - -#endif /* EulerVelGetter_H */ diff --git a/examples/inviscid-flow/2d/EulerVelGetter_impl.h b/examples/inviscid-flow/2d/EulerVelGetter_impl.h deleted file mode 100644 index eeac07e57011bac7bd9769de63687f2f9bbc0852..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerVelGetter_impl.h +++ /dev/null @@ -1,340 +0,0 @@ -#ifndef EulerVelGetter_IMPL_H -#define EulerVelGetter_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -EulerVelGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelGetter< Meshes::Grid< 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< -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 -EulerVelGetter< Meshes::Grid< 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 -EulerVelGetter< Meshes::Grid< 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 > -String -EulerVelGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelGetter< Meshes::Grid< 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(); - //vel - const IndexType& center = entity.getIndex(); - return ::sqrt(pow( velX[ center ],2)+pow( velY[ center ],2)); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -EulerVelGetter< Meshes::Grid< 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 -EulerVelGetter< Meshes::Grid< 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 > -String -EulerVelGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelGetter< Meshes::Grid< 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 -EulerVelGetter< Meshes::Grid< 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 -EulerVelGetter< Meshes::Grid< 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 ); -} - -} //namespace TNL - -#endif /* EulerVelGetterIMPL_H */ - diff --git a/examples/inviscid-flow/2d/EulerVelXGetter.h b/examples/inviscid-flow/2d/EulerVelXGetter.h deleted file mode 100644 index 93e3363bfab2f2d7eca6b375d9013c661bd47427..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerVelXGetter.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef EulerVelXGetter_H -#define EulerVelXGetter_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class EulerVelXGetter -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class EulerVelXGetter< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType rhoVelX; - MeshFunctionType rho; - - void setRhoVelX(const MeshFunctionType& rhoVelX) - { - this->rhoVelX = rhoVelX; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerVelXGetter< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType rhoVelX; - MeshFunctionType rho; - - void setRhoVelX(const MeshFunctionType& rhoVelX) - { - this->rhoVelX = rhoVelX; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerVelXGetter< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType rhoVelX; - MeshFunctionType rho; - - void setRhoVelX(const MeshFunctionType& rhoVelX) - { - this->rhoVelX = rhoVelX; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} // namespace TNL - -#include "EulerVelXGetter_impl.h" - -#endif /* EulerVelXGetter_H */ diff --git a/examples/inviscid-flow/2d/EulerVelXGetter_impl.h b/examples/inviscid-flow/2d/EulerVelXGetter_impl.h deleted file mode 100644 index 6008509056afbadfbd99dddc3c0a57bad4185b28..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerVelXGetter_impl.h +++ /dev/null @@ -1,339 +0,0 @@ -#pragma once - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -EulerVelXGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelXGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelXGetter< Meshes::Grid< 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< -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 -EulerVelXGetter< Meshes::Grid< 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 -EulerVelXGetter< Meshes::Grid< 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 > -String -EulerVelXGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelXGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelXGetter< Meshes::Grid< 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(); - //velX - const IndexType& center = entity.getIndex(); - return ( rhoVelX[ center ] / rho[ center ]); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -EulerVelXGetter< Meshes::Grid< 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 -EulerVelXGetter< Meshes::Grid< 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 > -String -EulerVelXGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelXGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelXGetter< Meshes::Grid< 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 -EulerVelXGetter< Meshes::Grid< 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 -EulerVelXGetter< Meshes::Grid< 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 ); -} - -}// namespace TNL - - - diff --git a/examples/inviscid-flow/2d/EulerVelYGetter.h b/examples/inviscid-flow/2d/EulerVelYGetter.h deleted file mode 100644 index 49474808d38d60baa3a0625ca690b953f714c5c7..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerVelYGetter.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef EulerVelYGetter_H -#define EulerVelYGetter_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class EulerVelYGetter -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class EulerVelYGetter< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType rhoVelY; - MeshFunctionType rho; - - void setRhoVelY(const MeshFunctionType& rhoVelY) - { - this->rhoVelY = rhoVelY; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerVelYGetter< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType rhoVelY; - MeshFunctionType rho; - - void setRhoVelY(const MeshFunctionType& rhoVelY) - { - this->rhoVelY = rhoVelY; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 EulerVelYGetter< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - MeshFunctionType rhoVelY; - MeshFunctionType rho; - - void setRhoVelY(const MeshFunctionType& rhoVelY) - { - this->rhoVelY = rhoVelY; - }; - - void setRho(const MeshFunctionType& rho) - { - this->rho = rho; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} //namespace TNL - - -#include "EulerVelYGetter_impl.h" - -#endif /* EulerVelYGetter_H */ diff --git a/examples/inviscid-flow/2d/EulerVelYGetter_impl.h b/examples/inviscid-flow/2d/EulerVelYGetter_impl.h deleted file mode 100644 index 337f4208c3ee6c0feef0e77e4d136b7704113671..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/EulerVelYGetter_impl.h +++ /dev/null @@ -1,332 +0,0 @@ -#ifndef EulerVelYGetter_IMPL_H -#define EulerVelYGetter_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -EulerVelYGetter< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelYGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelYGetter< Meshes::Grid< 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< -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 -EulerVelYGetter< Meshes::Grid< 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 -EulerVelYGetter< Meshes::Grid< 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 > -String -EulerVelYGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelYGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelYGetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -operator()( const MeshFunction& u, - const MeshEntity& entity, - const Real& time ) const -{ - //velY - const IndexType& center = entity.getIndex(); - return ( rhoVelY[ center ] / rho[ center ]); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -EulerVelYGetter< Meshes::Grid< 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 -EulerVelYGetter< Meshes::Grid< 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 > -String -EulerVelYGetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "EulerVelYGetter< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -EulerVelYGetter< Meshes::Grid< 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 -EulerVelYGetter< Meshes::Grid< 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 -EulerVelYGetter< Meshes::Grid< 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 ); -} - -} // namespace TNL - -#endif /* EulerVelYGetterIMPL_H */ - diff --git a/examples/inviscid-flow/2d/LaxFridrichs.h b/examples/inviscid-flow/2d/LaxFridrichs.h deleted file mode 100644 index b689e002122e0c885a53585ebe982f281cfbf43e..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichs.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef LaxFridrichs_H -#define LaxFridrichs_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -#include "LaxFridrichsContinuity.h" -#include "LaxFridrichsEnergy.h" -#include "LaxFridrichsMomentumX.h" -#include "LaxFridrichsMomentumY.h" -#include "EulerPressureGetter.h" -#include "EulerVelXGetter.h" -#include "EulerVelYGetter.h" -#include "EulerVelGetter.h" - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichs -{ - public: - typedef Real RealType; - typedef typename Mesh::DeviceType DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< Mesh > MeshFunctionType; - - typedef LaxFridrichsContinuity< Mesh, Real, Index > Continuity; - typedef LaxFridrichsMomentumX< Mesh, Real, Index > MomentumX; - typedef LaxFridrichsMomentumY< Mesh, Real, Index > MomentumY; - typedef LaxFridrichsEnergy< Mesh, Real, Index > Energy; - typedef EulerVelXGetter< Mesh, Real, Index > VelocityX; - typedef EulerVelYGetter< Mesh, Real, Index > VelocityY; - typedef EulerVelGetter< Mesh, Real, Index > Velocity; - typedef EulerPressureGetter< Mesh, Real, Index > Pressure; - -}; - -} //namespace TNL - -#endif /* LaxFridrichs_H */ diff --git a/examples/inviscid-flow/2d/LaxFridrichsContinuity.h b/examples/inviscid-flow/2d/LaxFridrichsContinuity.h deleted file mode 100644 index 433d6a3512cbd8493ac16d0181d2255bb7692974..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsContinuity.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef LaxFridrichsContinuity_H -#define LaxFridrichsContinuity_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichsContinuity -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class LaxFridrichsContinuity< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsContinuity< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsContinuity< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - - -} //namespace TNL - -#include "LaxFridrichsContinuity_impl .h" - -#endif /* LaxFridrichsContinuity_H */ diff --git a/examples/inviscid-flow/2d/LaxFridrichsContinuity_impl .h b/examples/inviscid-flow/2d/LaxFridrichsContinuity_impl .h deleted file mode 100644 index 237b1a5845614a16ec708cf495ad057b297830b2..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsContinuity_impl .h +++ /dev/null @@ -1,349 +0,0 @@ -#ifndef LaxFridrichsContinuity_IMPL_H -#define LaxFridrichsContinuity_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichsContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsContinuity< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsContinuity< Meshes::Grid< 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< -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 -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 > -String -LaxFridrichsContinuity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsContinuity< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsContinuity< Meshes::Grid< 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 >(); - return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) - - 0.5 * hxInverse * ( u[ west ] * this->velocityX[ west ] - u[ east ] * this->velocityX[ east ] ) - - 0.5 * hyInverse * ( u[ north ] * this->velocityY[ north ] - u[ south ] * this->velocityY[ east ] ); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 > -String -LaxFridrichsContinuity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsContinuity< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 -LaxFridrichsContinuity< Meshes::Grid< 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 ); -} - -} //namespace TNL - -#endif /* LaxFridrichsContinuityIMPL_H */ - diff --git a/examples/inviscid-flow/2d/LaxFridrichsEnergy.h b/examples/inviscid-flow/2d/LaxFridrichsEnergy.h deleted file mode 100644 index 8685697295d485d03c57e3748d2b6320e84f3ac5..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsEnergy.h +++ /dev/null @@ -1,219 +0,0 @@ -#ifndef LaxFridrichsEnergy_H -#define LaxFridrichsEnergy_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichsEnergy -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class LaxFridrichsEnergy< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsEnergy< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsEnergy< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} //namespace TNL - - -#include "LaxFridrichsEnergy_impl.h" - -#endif /* LaxFridrichsEnergy_H */ diff --git a/examples/inviscid-flow/2d/LaxFridrichsEnergy_impl.h b/examples/inviscid-flow/2d/LaxFridrichsEnergy_impl.h deleted file mode 100644 index e4f9b2e176d9acdb50157c6cf5f77a6c86801dd8..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsEnergy_impl.h +++ /dev/null @@ -1,350 +0,0 @@ -#ifndef LaxFridrichsEnergy_IMPL_H -#define LaxFridrichsEnergy_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichsEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsEnergy< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsEnergy< Meshes::Grid< 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< -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 -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 > -String -LaxFridrichsEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsEnergy< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsEnergy< Meshes::Grid< 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(); - //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 >(); - return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) - - 0.5 * hxInverse * ((( u[ west ] + this->pressure[ west ] ) * this->velocityX[ west ] ) - -(( u[ east ] + this->pressure[ east ] ) * this->velocityX[ east ] )) - - 0.5 * hyInverse * ((( u[ north ] + this->pressure[ north ] ) * this->velocityY[ north ] ) - -(( u[ south ] + this->pressure[ south ] ) * this->velocityY[ south ] )); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 > -String -LaxFridrichsEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsEnergy< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 -LaxFridrichsEnergy< Meshes::Grid< 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 ); -} - -} //namespace TNL - -#endif /* LaxFridrichsEnergyIMPL_H */ - diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h deleted file mode 100644 index b82758fc7c24cebfcc08580d73c0fd142a82dedc..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsMomentumX.h +++ /dev/null @@ -1,220 +0,0 @@ -#ifndef LaxFridrichsMomentumX_H -#define LaxFridrichsMomentumX_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichsMomentumX -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class LaxFridrichsMomentumX< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsMomentumX< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsMomentumX< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - - -} // namespace TNL - -#include "LaxFridrichsMomentumX_impl.h" - -#endif /* LaxFridrichsMomentumX_H */ diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumX_impl.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumX_impl.h deleted file mode 100644 index bffb1fe02b4bdc505cb2214954a159f4b8f141bc..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsMomentumX_impl.h +++ /dev/null @@ -1,351 +0,0 @@ -#ifndef LaxFridrichsMomentumX_IMPL_H -#define LaxFridrichsMomentumX_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichsMomentumX< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentumX< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentumX< Meshes::Grid< 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< -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 -LaxFridrichsMomentumX< Meshes::Grid< 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 -LaxFridrichsMomentumX< Meshes::Grid< 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 > -String -LaxFridrichsMomentumX< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentumX< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentumX< Meshes::Grid< 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(); - - //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 >(); - return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) - - 0.5 * hxInverse * (( u[ west ] * this->velocityX[ west ] + this->pressure[ west ] ) - -( u[ east ] * this->velocityX[ east ] + this->pressure[ east ] )) - - 0.5 * hyInverse * (( u[ north ] * this->velocityY[ north ] ) - -( u[ south ] * this->velocityY[ south ] )); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichsMomentumX< Meshes::Grid< 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 -LaxFridrichsMomentumX< Meshes::Grid< 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 > -String -LaxFridrichsMomentumX< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentumX< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentumX< Meshes::Grid< 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 -LaxFridrichsMomentumX< Meshes::Grid< 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 -LaxFridrichsMomentumX< Meshes::Grid< 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 ); -} - -} //namespace TNL - -#endif /* LaxFridrichsMomentumXIMPL_H */ - diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h deleted file mode 100644 index 309051829f7b973ed3009ae12eef2c8ec425f647..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsMomentumY.h +++ /dev/null @@ -1,218 +0,0 @@ -#ifndef LaxFridrichsMomentumY_H -#define LaxFridrichsMomentumY_H - -#include <TNL/Containers/Vector.h> -#include <TNL/Meshes/Grid.h> - -namespace TNL { - -template< typename Mesh, - typename Real = typename Mesh::RealType, - typename Index = typename Mesh::IndexType > -class LaxFridrichsMomentumY -{ -}; - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -class LaxFridrichsMomentumY< Meshes::Grid< 1,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsMomentumY< Meshes::Grid< 2,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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 LaxFridrichsMomentumY< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > -{ - public: - typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; - typedef typename MeshType::CoordinatesType CoordinatesType; - typedef Real RealType; - typedef Device DeviceType; - typedef Index IndexType; - typedef Functions::MeshFunction< MeshType > MeshFunctionType; - enum { Dimensions = MeshType::getMeshDimensions() }; - - static String getType(); - Real tau; - MeshFunctionType velocityX; - MeshFunctionType velocityY; - MeshFunctionType pressure; - - void setTau(const Real& tau) - { - this->tau = tau; - }; - - void setVelocityX(const MeshFunctionType& velocityX) - { - this->velocityX = velocityX; - }; - - void setVelocityY(const MeshFunctionType& velocityY) - { - this->velocityY = velocityY; - }; - - void setPressure(const MeshFunctionType& pressure) - { - this->pressure = pressure; - }; - - template< typename MeshFunction, typename MeshEntity > - __cuda_callable__ - Real operator()( const MeshFunction& u, - const MeshEntity& entity, - const RealType& time = 0.0 ) const; - - template< typename MeshEntity > - __cuda_callable__ - 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; -}; - -} // namespace TNL - -#include "LaxFridrichsMomentumY_impl.h" - -#endif /* LaxFridrichsMomentumY_H */ diff --git a/examples/inviscid-flow/2d/LaxFridrichsMomentumY_impl.h b/examples/inviscid-flow/2d/LaxFridrichsMomentumY_impl.h deleted file mode 100644 index 0624e19aa88750ceb7c78f940b287e515e34ee45..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/LaxFridrichsMomentumY_impl.h +++ /dev/null @@ -1,351 +0,0 @@ -#ifndef LaxFridrichsMomentumY_IMPL_H -#define LaxFridrichsMomentumY_IMPL_H - -namespace TNL { - -/**** - * 1D problem - */ -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -String -LaxFridrichsMomentumY< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentumY< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentumY< Meshes::Grid< 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< -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 -LaxFridrichsMomentumY< Meshes::Grid< 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 -LaxFridrichsMomentumY< Meshes::Grid< 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 > -String -LaxFridrichsMomentumY< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentumY< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentumY< Meshes::Grid< 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(); - - //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 >(); - return (0.5 * this->tau) * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) - - 0.5 * hyInverse * (( u[ west ] * this->velocityX[ west ] ) - -( u[ east ] * this->velocityX[ east ] )) - - 0.5 * hxInverse * (( u[ north ] * this->velocityY[ north ] + this->pressure[ north ] ) - -( u[ south ] * this->velocityY[ south ] + this->pressure[ south ])); -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshEntity > -__cuda_callable__ -Index -LaxFridrichsMomentumY< Meshes::Grid< 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 -LaxFridrichsMomentumY< Meshes::Grid< 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 > -String -LaxFridrichsMomentumY< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: -getType() -{ - return String( "LaxFridrichsMomentumY< " ) + - MeshType::getType() + ", " + - TNL::getType< Real >() + ", " + - TNL::getType< Index >() + " >"; -} - -template< typename MeshReal, - typename Device, - typename MeshIndex, - typename Real, - typename Index > -template< typename MeshFunction, typename MeshEntity > -__cuda_callable__ -Real -LaxFridrichsMomentumY< Meshes::Grid< 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 -LaxFridrichsMomentumY< Meshes::Grid< 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 -LaxFridrichsMomentumY< Meshes::Grid< 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 ); -} - -} //namespace TNL - -#endif /* LaxFridrichsMomentumYIMPL_H */ - diff --git a/examples/inviscid-flow/2d/euler-cuda.cu b/examples/inviscid-flow/2d/euler-cuda.cu deleted file mode 100644 index 4d76005cb1f70724be978ff0fa6fec63c4a8a76f..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/euler-cuda.cu +++ /dev/null @@ -1 +0,0 @@ -#include "euler.h" diff --git a/examples/inviscid-flow/2d/euler.cpp b/examples/inviscid-flow/2d/euler.cpp deleted file mode 100644 index 4d76005cb1f70724be978ff0fa6fec63c4a8a76f..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/euler.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "euler.h" diff --git a/examples/inviscid-flow/2d/euler.h b/examples/inviscid-flow/2d/euler.h deleted file mode 100644 index a888f928e86227dd3126c32408ba69fe46c89b7d..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/euler.h +++ /dev/null @@ -1,118 +0,0 @@ -#include <TNL/tnlConfig.h> -#include <TNL/Solvers/Solver.h> -#include <TNL/Solvers/BuildConfigTags.h> -#include <TNL/Operators/DirichletBoundaryConditions.h> -#include <TNL/Operators/NeumannBoundaryConditions.h> -#include <TNL/Functions/Analytic/Constant.h> -#include "eulerProblem.h" -#include "LaxFridrichs.h" -#include "eulerRhs.h" -#include "eulerBuildConfigTag.h" - -using namespace TNL; - -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( Config::ConfigDescription & config ) - { - config.addDelimiter( "euler2D settings:" ); - config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); - config.addEntryEnum< String >( "dirichlet" ); - config.addEntryEnum< String >( "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 Config::ParameterContainer & parameters ) - { - enum { Dimensions = MeshType::getMeshDimensions() }; - typedef LaxFridrichs< MeshType, Real, Index > ApproximateOperator; - typedef eulerRhs< MeshType, Real > RightHandSide; - typedef Containers::StaticVector < 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 Vector. - */ - String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" ); - if( parameters.checkParameter( "boundary-conditions-constant" ) ) - { - typedef Functions::Analytic::Constant< Dimensions, Real > Constant; - if( boundaryConditionsType == "dirichlet" ) - { - typedef Operators::DirichletBoundaryConditions< MeshType, Constant, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; - typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; - SolverStarter solverStarter; - return solverStarter.template run< Problem >( parameters ); - } - typedef Operators::NeumannBoundaryConditions< MeshType, Constant, Real, Index > BoundaryConditions; - typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; - SolverStarter solverStarter; - return solverStarter.template run< Problem >( parameters ); - } - typedef Functions::MeshFunction< MeshType > MeshFunction; - if( boundaryConditionsType == "dirichlet" ) - { - typedef Operators::DirichletBoundaryConditions< MeshType, MeshFunction, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; - typedef eulerProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; - SolverStarter solverStarter; - return solverStarter.template run< Problem >( parameters ); - } - typedef Operators::NeumannBoundaryConditions< 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[] ) -{ - Solvers::Solver< 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 deleted file mode 100644 index fef4dfffce5400b1ef97786bc92b8a57ac246c1d..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/eulerBuildConfigTag.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef eulerBUILDCONFIGTAG_H_ -#define eulerBUILDCONFIGTAG_H_ - -#include <TNL/Solvers/BuildConfigTags.h> - -namespace TNL { - -class eulerBuildConfigTag{}; - -namespace Solvers { - -/**** - * Turn off support for float and long double. - */ -template<> struct ConfigTagReal< eulerBuildConfigTag, float > { enum { enabled = false }; }; -template<> struct ConfigTagReal< eulerBuildConfigTag, long double > { enum { enabled = false }; }; - -/**** - * Turn off support for short int and long int indexing. - */ -template<> struct ConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; }; -template<> struct ConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; }; - -template< int Dimensions > struct ConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = ( Dimensions == 2 ) }; }; - -/**** - * Use of Grid is enabled for allowed dimensions and Real, Device and Index types. - */ -template< int Dimensions, typename Real, typename Device, typename Index > - struct ConfigTagMesh< eulerBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > > - { enum { enabled = ConfigTagDimensions< eulerBuildConfigTag, Dimensions >::enabled && - ConfigTagReal< eulerBuildConfigTag, Real >::enabled && - ConfigTagDevice< eulerBuildConfigTag, Device >::enabled && - ConfigTagIndex< eulerBuildConfigTag, Index >::enabled }; }; - -/**** - * Please, chose your preferred time discretisation here. - */ -template<> struct ConfigTagTimeDiscretisation< eulerBuildConfigTag, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; -template<> struct ConfigTagTimeDiscretisation< eulerBuildConfigTag, SemiImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; -template<> struct ConfigTagTimeDiscretisation< eulerBuildConfigTag, ImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; - -/**** - * Only the Runge-Kutta-Merson solver is enabled by default. - */ -template<> struct ConfigTagExplicitSolver< eulerBuildConfigTag, ExplicitEulerSolverTag >{ enum { enabled = false }; }; - -} // namespace Solvers -} // namespace TNL - -#endif /* eulerBUILDCONFIGTAG_H_ */ diff --git a/examples/inviscid-flow/2d/eulerProblem.h b/examples/inviscid-flow/2d/eulerProblem.h deleted file mode 100644 index 71a9a7a7c1b71f96afd3c289258f27225337f854..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/eulerProblem.h +++ /dev/null @@ -1,135 +0,0 @@ -#pragma once - -#include <TNL/Problems/PDEProblem.h> -#include <TNL/Functions/MeshFunction.h> - -using namespace TNL::Problems; - -namespace TNL { - -template< typename Mesh, - typename BoundaryCondition, - typename RightHandSide, - typename DifferentialOperator > -class eulerProblem: - public PDEProblem< 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 Functions::MeshFunction< Mesh > MeshFunctionType; - typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; - typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer; - typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer; - typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer; - typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; - - using typename BaseType::MeshType; - using typename BaseType::MeshPointer; - using typename BaseType::DofVectorType; - using typename BaseType::DofVectorPointer; - using typename BaseType::MeshDependentDataType; - using typename BaseType::MeshDependentDataPointer; - - typedef typename DifferentialOperator::Continuity Continuity; - typedef typename DifferentialOperator::MomentumX MomentumX; - typedef typename DifferentialOperator::MomentumY MomentumY; - typedef typename DifferentialOperator::Energy Energy; - typedef typename DifferentialOperator::Velocity Velocity; - typedef typename DifferentialOperator::VelocityX VelocityX; - typedef typename DifferentialOperator::VelocityY VelocityY; - typedef typename DifferentialOperator::Pressure Pressure; - - static String getTypeStatic(); - - String getPrologHeader() const; - - void writeProlog( Logger& logger, - const Config::ParameterContainer& parameters ) const; - - bool setup( const MeshPointer& meshPointer, - const Config::ParameterContainer& parameters, - const String& prefix = "" ); - - bool setInitialCondition( const Config::ParameterContainer& parameters, - const MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ); - - template< typename Matrix > - bool setupLinearSystem( const MeshPointer& mesh, - Matrix& matrix ); - - bool makeSnapshot( const RealType& time, - const IndexType& step, - const MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ); - - IndexType getDofs( const MeshPointer& mesh ) const; - - void bindDofs( const MeshPointer& mesh, - DofVectorPointer& dofs ); - - void getExplicitRHS( const RealType& time, - const RealType& tau, - const MeshPointer& mesh, - DofVectorPointer& _u, - DofVectorPointer& _fu, - MeshDependentDataPointer& meshDependentData ); - - template< typename Matrix > - void assemblyLinearSystem( const RealType& time, - const RealType& tau, - const MeshPointer& mesh, - DofVectorPointer& dofs, - Matrix& matrix, - DofVectorPointer& rightHandSide, - MeshDependentDataPointer& meshDependentData ); - - bool postIterate( const RealType& time, - const RealType& tau, - const MeshPointer& mesh, - DofVectorPointer& dofs, - MeshDependentDataPointer& meshDependentData ); - - protected: - - DifferentialOperatorPointer differentialOperatorPointer; - BoundaryConditionPointer boundaryConditionPointer; - RightHandSidePointer rightHandSidePointer; - - //definition - Containers::Vector< RealType, DeviceType, IndexType > _uRho; - Containers::Vector< RealType, DeviceType, IndexType > _uRhoVelocityX; - Containers::Vector< RealType, DeviceType, IndexType > _uRhoVelocityY; - Containers::Vector< RealType, DeviceType, IndexType > _uEnergy; - - Containers::Vector< RealType, DeviceType, IndexType > _fuRho; - Containers::Vector< RealType, DeviceType, IndexType > _fuRhoVelocityX; - Containers::Vector< RealType, DeviceType, IndexType > _fuRhoVelocityY; - Containers::Vector< RealType, DeviceType, IndexType > _fuEnergy; - - Containers::Vector< RealType, DeviceType, IndexType > rho; - Containers::Vector< RealType, DeviceType, IndexType > rhoVelX; - Containers::Vector< RealType, DeviceType, IndexType > rhoVelY; - Containers::Vector< RealType, DeviceType, IndexType > energy; - Containers::Vector< RealType, DeviceType, IndexType > data; - Containers::Vector< RealType, DeviceType, IndexType > pressure; - Containers::Vector< RealType, DeviceType, IndexType > velocity; - Containers::Vector< RealType, DeviceType, IndexType > velocityX; - Containers::Vector< RealType, DeviceType, IndexType > velocityY; - double gamma; - - -}; - -} // namespace TNL - -#include "eulerProblem_impl.h" - diff --git a/examples/inviscid-flow/2d/eulerRhs.h b/examples/inviscid-flow/2d/eulerRhs.h deleted file mode 100644 index 1b46dc831fe9daa6133ff32ee4bea5faf4eb8d1c..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/eulerRhs.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef eulerRHS_H_ -#define eulerRHS_H_ - -#include <TNL/Functions/Domain.h> - -namespace TNL { - -template< typename Mesh, typename Real >class eulerRhs - : public Functions::Domain< Mesh::meshDimensions, Functions::MeshDomain > - { - public: - - typedef Mesh MeshType; - typedef Real RealType; - - bool setup( const Config::ParameterContainer& parameters, - const String& 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; - } -}; - -} //namespace TNL - -#endif /* eulerRHS_H_ */ diff --git a/examples/inviscid-flow/2d/run-euler b/examples/inviscid-flow/2d/run-euler deleted file mode 100644 index f68b98a8406dea2f2142526283ec60248551c56d..0000000000000000000000000000000000000000 --- a/examples/inviscid-flow/2d/run-euler +++ /dev/null @@ -1,19 +0,0 @@ -#!/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 index 10af3c9c773bc36bca44191359b4a4e244d1faa4..634cce16141410c692254c2b7385b2cac5acd5a7 100644 --- a/examples/inviscid-flow/CMakeLists.txt +++ b/examples/inviscid-flow/CMakeLists.txt @@ -1,2 +1,24 @@ -add_subdirectory( 1d ) -add_subdirectory( 2d ) +set( tnl_inviscid_flow_HEADERS + CompressibleConservativeVariables.h ) + +set( tnl_inviscid_flow_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 run-euler + ${tnl_inviscid_flow_SOURCES} + DESTINATION share/tnl-${tnlVersion}/examples/inviscid-flow-2d ) + diff --git a/examples/inviscid-flow/CompressibleConservativeVariables.h b/examples/inviscid-flow/CompressibleConservativeVariables.h new file mode 100644 index 0000000000000000000000000000000000000000..04f1214999de5e6154131461098a061c2cfca311 --- /dev/null +++ b/examples/inviscid-flow/CompressibleConservativeVariables.h @@ -0,0 +1,147 @@ +/*************************************************************************** + CompressibleConservativeVariables.h - description + ------------------- + begin : Feb 12, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/MeshFunction.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/SharedPointer.h> + +namespace TNL { + +template< typename Mesh > +class CompressibleConservativeVariables +{ + public: + typedef Mesh MeshType; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshType > MeshPointer; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > MomentumFieldPointer; + + CompressibleConservativeVariables(){}; + + CompressibleConservativeVariables( const MeshPointer& meshPointer ) + : density( meshPointer ), + momentum( meshPointer ), + //pressure( meshPointer ), + energy( meshPointer ){}; + + void setMesh( const MeshPointer& meshPointer ) + { + this->density->setMesh( meshPointer ); + this->momentum->setMesh( meshPointer ); + //this->pressure.setMesh( meshPointer ); + this->energy->setMesh( meshPointer ); + } + + template< typename Vector > + void bind( const MeshPointer& meshPointer, + const Vector& data, + IndexType offset = 0 ) + { + IndexType currentOffset( offset ); + this->density->bind( meshPointer, data, currentOffset ); + currentOffset += this->density->getDofs( meshPointer ); + for( IndexType i = 0; i < Dimensions; i++ ) + { + ( *this->momentum )[ i ]->bind( meshPointer, data, currentOffset ); + currentOffset += ( *this->momentum )[ i ]->getDofs( meshPointer ); + } + this->energy->bind( meshPointer, data, currentOffset ); + } + + IndexType getDofs( const MeshPointer& meshPointer ) const + { + return this->density->getDofs( meshPointer ) + + this->momentum->getDofs( meshPointer ) + + this->energy->getDofs( meshPointer ); + } + + MeshFunctionPointer& getDensity() + { + return this->density; + } + + const MeshFunctionPointer& getDensity() const + { + return this->density; + } + + void setDensity( MeshFunctionPointer& density ) + { + this->density = density; + } + + MomentumFieldPointer& getMomentum() + { + return this->momentum; + } + + const MomentumFieldPointer& getMomentum() const + { + return this->momentum; + } + + void setMomentum( MomentumFieldPointer& momentum ) + { + this->momentum = momentum; + } + + /*MeshFunctionPointer& getPressure() + { + return this->pressure; + } + + const MeshFunctionPointer& getPressure() const + { + return this->pressure; + } + + void setPressure( MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }*/ + + MeshFunctionPointer& getEnergy() + { + return this->energy; + } + + const MeshFunctionPointer& getEnergy() const + { + return this->energy; + } + + void setEnergy( MeshFunctionPointer& energy ) + { + this->energy = energy; + } + + void getVelocityField( VelocityFieldType& velocityField ) + { + + } + + protected: + + MeshFunctionPointer density; + MomentumFieldPointer momentum; + MeshFunctionPointer energy; + +}; + +} // namespace TN \ No newline at end of file diff --git a/examples/inviscid-flow/LaxFridrichs.h b/examples/inviscid-flow/LaxFridrichs.h new file mode 100644 index 0000000000000000000000000000000000000000..42ea19c145fd164d020af76b974c58020e8184e5 --- /dev/null +++ b/examples/inviscid-flow/LaxFridrichs.h @@ -0,0 +1,141 @@ +/*************************************************************************** + LaxFridrichs.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> + +#include "LaxFridrichsContinuity.h" +#include "LaxFridrichsEnergy.h" +#include "LaxFridrichsMomentumX.h" +#include "LaxFridrichsMomentumY.h" +#include "LaxFridrichsMomentumZ.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichs +{ + public: + typedef Mesh MeshType; + typedef Real RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + static const int Dimensions = Mesh::getMeshDimensions(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VectorFieldType; + + typedef LaxFridrichsContinuity< Mesh, Real, Index > ContinuityOperatorType; + typedef LaxFridrichsMomentumX< Mesh, Real, Index > MomentumXOperatorType; + typedef LaxFridrichsMomentumY< Mesh, Real, Index > MomentumYOperatorType; + typedef LaxFridrichsMomentumZ< Mesh, Real, Index > MomentumZOperatorType; + typedef LaxFridrichsEnergy< Mesh, Real, Index > EnergyOperatorType; + + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VectorFieldType > VectorFieldPointer; + typedef SharedPointer< MeshType > MeshPointer; + + typedef SharedPointer< ContinuityOperatorType > ContinuityOperatorPointer; + typedef SharedPointer< MomentumXOperatorType > MomentumXOperatorPointer; + typedef SharedPointer< MomentumYOperatorType > MomentumYOperatorPointer; + typedef SharedPointer< MomentumZOperatorType > MomentumZOperatorPointer; + typedef SharedPointer< EnergyOperatorType > EnergyOperatorPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + LaxFridrichs() + : artificialViscosity( 1.0 ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + this->continuityOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->momentumXOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->momentumYOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->momentumZOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->energyOperatorPointer->setArtificialViscosity( artificialViscosity ); + + return true; + } + + void setTau( const RealType& tau ) + { + this->continuityOperatorPointer->setTau( tau ); + this->momentumXOperatorPointer->setTau( tau ); + this->momentumYOperatorPointer->setTau( tau ); + this->momentumZOperatorPointer->setTau( tau ); + this->energyOperatorPointer->setTau( tau ); + } + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->momentumXOperatorPointer->setPressure( pressure ); + this->momentumYOperatorPointer->setPressure( pressure ); + this->momentumZOperatorPointer->setPressure( pressure ); + this->energyOperatorPointer->setPressure( pressure ); + } + + void setVelocity( const VectorFieldPointer& velocity ) + { + this->continuityOperatorPointer->setVelocity( velocity ); + this->momentumXOperatorPointer->setVelocity( velocity ); + this->momentumYOperatorPointer->setVelocity( velocity ); + this->momentumZOperatorPointer->setVelocity( velocity ); + this->energyOperatorPointer->setVelocity( velocity ); + } + + const ContinuityOperatorPointer& getContinuityOperator() const + { + return this->continuityOperatorPointer; + } + + const MomentumXOperatorPointer& getMomentumXOperator() const + { + return this->momentumXOperatorPointer; + } + + const MomentumYOperatorPointer& getMomentumYOperator() const + { + return this->momentumYOperatorPointer; + } + + const MomentumZOperatorPointer& getMomentumZOperator() const + { + return this->momentumZOperatorPointer; + } + + const EnergyOperatorPointer& getEnergyOperator() const + { + return this->energyOperatorPointer; + } + + protected: + + ContinuityOperatorPointer continuityOperatorPointer; + MomentumXOperatorPointer momentumXOperatorPointer; + MomentumYOperatorPointer momentumYOperatorPointer; + MomentumZOperatorPointer momentumZOperatorPointer; + EnergyOperatorPointer energyOperatorPointer; + + RealType artificialViscosity; +}; + +} //namespace TNL diff --git a/examples/inviscid-flow/LaxFridrichsContinuity.h b/examples/inviscid-flow/LaxFridrichsContinuity.h new file mode 100644 index 0000000000000000000000000000000000000000..9cc5ddc7f0ec7ec3aca8452eaecea7187d632963 --- /dev/null +++ b/examples/inviscid-flow/LaxFridrichsContinuity.h @@ -0,0 +1,288 @@ +/*************************************************************************** + LaxFridrichsContinuity.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/SharedPointer.h> + +namespace TNL { + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsContinuityBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + LaxFridrichsContinuityBase() + : artificialViscosity( 1.0 ){}; + + static String getType() + { + return String( "LaxFridrichsContinuity< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setArtificialViscosity( const RealType& artificialViscosity ) + { + this->artificialViscosity = artificialViscosity; + } + + + protected: + + RealType tau; + + VelocityFieldPointer velocity; + + RealType artificialViscosity; +}; + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsContinuity +{ +}; + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsContinuityBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + return 1.0 / 2.0 * this->tau * this->artificialViscosity * ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) + - 0.5 * ( u[ west ] * velocity_x_west - u[ east ] * velocity_x_east ) * hxInverse; + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsContinuity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsContinuityBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) + - 0.5 * ( ( u[ west ] * velocity_x_west - u[ east ] * velocity_x_east ) * hxInverse + + ( u[ north ] * velocity_y_north - u[ south ] * velocity_y_south ) * hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsContinuity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsContinuityBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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(); + + //rho + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + 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 >(); + + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + + return 1.0 / 6.0 * this->tau * this->artificialViscosity * + ( u[ west ] + u[ east ] + u[ south ] + u[ north ] + u[ up ] + u[ down ]- 6.0 * u[ center ] ) + - 0.5 * ( ( u[ west ] * velocity_x_west - u[ east ] * velocity_x_east ) * hxInverse + + ( u[ north ] * velocity_y_north - u[ south ] * velocity_y_south ) * hyInverse + + ( u[ up ] * velocity_z_up - u[ down ] * velocity_z_down ) * hzInverse ); + + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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;*/ +}; + + +} //namespace TNL diff --git a/examples/inviscid-flow/LaxFridrichsEnergy.h b/examples/inviscid-flow/LaxFridrichsEnergy.h new file mode 100644 index 0000000000000000000000000000000000000000..df1570f19ca13f32bcb408c83a658a5e8f0cad81 --- /dev/null +++ b/examples/inviscid-flow/LaxFridrichsEnergy.h @@ -0,0 +1,309 @@ +/*************************************************************************** + LaxFridrichsEnergy.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsEnergyBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + LaxFridrichsEnergyBase() + : artificialViscosity( 1.0 ){}; + + static String getType() + { + return String( "LaxFridrichsEnergy< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }; + + void setArtificialViscosity( const RealType& artificialViscosity ) + { + this->artificialViscosity = artificialViscosity; + } + + protected: + + RealType tau; + + VelocityFieldPointer velocity; + + MeshFunctionPointer pressure; + + RealType artificialViscosity; +}; + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsEnergy +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsEnergyBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& e, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + return 1.0 / 2.0 * this->tau * this->artificialViscosity * ( e[ west ] - 2.0 * e[ center ] + e[ east ] ) + - 0.5 * ( ( e[ west ] + pressure_west ) * velocity_x_west + - ( e[ east ] + pressure_east ) * velocity_x_east ) * hxInverse; + + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsEnergyBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& e, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( e[ west ] + e[ east ] + e[ south ] + e[ north ] - 4.0 * e[ center ] ) + - 0.5 * ( ( ( ( e[ west ] + pressure_west ) * velocity_x_west ) + -( ( e[ east ] + pressure_east ) * velocity_x_east ) ) * hxInverse + + ( ( ( e[ north ] + pressure_north ) * velocity_y_north ) + -( ( e[ south ] + pressure_south ) * velocity_y_south ) ) * hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsEnergyBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& e, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + 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 >(); + + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + + return 1.0 / 6.0 * this->tau * this->artificialViscosity * + ( e[ west ] + e[ east ] + e[ south ] + e[ north ] + e[ up ] + e[ down ] - 6.0 * e[ center ] ) + - 0.5 * ( ( ( ( e[ west ] + pressure_west ) * velocity_x_west ) + -( ( e[ east ] + pressure_east ) * velocity_x_east ) ) * hxInverse + + ( ( ( e[ north ] + pressure_north ) * velocity_y_north ) + -( ( e[ south ] + pressure_south ) * velocity_y_south ) ) * hyInverse + + ( ( ( e[ up ] + pressure_up ) * velocity_z_up ) + -( ( e[ down ] + pressure_down ) * velocity_z_down ) ) * hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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;*/ +}; + +} //namespace TNL diff --git a/examples/inviscid-flow/LaxFridrichsMomentumBase.h b/examples/inviscid-flow/LaxFridrichsMomentumBase.h new file mode 100644 index 0000000000000000000000000000000000000000..b3eb777b890cca2eb22b7a988edfa4d0dde5c956 --- /dev/null +++ b/examples/inviscid-flow/LaxFridrichsMomentumBase.h @@ -0,0 +1,68 @@ +/*************************************************************************** + LaxFridrichsMomentumBase.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + LaxFridrichsMomentumBase() + : artificialViscosity( 1.0 ){}; + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }; + + void setArtificialViscosity( const RealType& artificialViscosity ) + { + this->artificialViscosity = artificialViscosity; + } + + protected: + + RealType tau; + + VelocityFieldPointer velocity; + + MeshFunctionPointer pressure; + + RealType artificialViscosity; +}; + +} //namespace TNL diff --git a/examples/inviscid-flow/LaxFridrichsMomentumX.h b/examples/inviscid-flow/LaxFridrichsMomentumX.h new file mode 100644 index 0000000000000000000000000000000000000000..c4f004fa4eb447f06bc5e0b95e65be50f6347f8b --- /dev/null +++ b/examples/inviscid-flow/LaxFridrichsMomentumX.h @@ -0,0 +1,276 @@ +/*************************************************************************** + LaxFridrichsMomentumX.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "LaxFridrichsMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumX +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumX< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + + return 1.0 / 2.0 * this->tau * this->artificialViscosity * ( rho_u[ west ] + rho_u[ east ] - 2.0 * rho_u[ center ] ) + - 0.5 * ( ( rho_u[ west ] * velocity_x_west + pressure_west ) + -( rho_u[ east ] * velocity_x_east + pressure_east ) ) * hxInverse; + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsMomentumX< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( rho_u[ west ] + rho_u[ east ] + rho_u[ south ] + rho_u[ north ] - 4.0 * rho_u[ center ] ) + - 0.5 * ( ( ( rho_u[ west ] * velocity_x_west + pressure_west ) + - ( rho_u[ east ] * velocity_x_east + pressure_east ) ) * hxInverse + + ( ( rho_u[ north ] * velocity_y_north ) + - ( rho_u[ south ] * velocity_y_south ) ) * hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsMomentumX< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + 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 >(); + + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + //const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + //const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + //const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + //const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + return 1.0 / 6.0 * this->tau * this->artificialViscosity * + ( rho_u[ west ] + rho_u[ east ] + rho_u[ south ] + rho_u[ north ] + rho_u[ up ] + rho_u[ down ] - 6.0 * rho_u[ center ] ) + - 0.5 * ( ( ( rho_u[ west ] * velocity_x_west + pressure_west ) + - ( rho_u[ east ] * velocity_x_east + pressure_east ) )* hxInverse + + ( ( rho_u[ north ] * velocity_y_north ) + - ( rho_u[ south ] * velocity_y_south ) )* hyInverse + + ( ( rho_u[ up ] * velocity_z_up ) + - ( rho_u[ down ] * velocity_z_down ) )* hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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;*/ +}; + + +} // namespace TNL + diff --git a/examples/inviscid-flow/LaxFridrichsMomentumY.h b/examples/inviscid-flow/LaxFridrichsMomentumY.h new file mode 100644 index 0000000000000000000000000000000000000000..2b931be883e81dbb066c404d22d292482e85ff14 --- /dev/null +++ b/examples/inviscid-flow/LaxFridrichsMomentumY.h @@ -0,0 +1,260 @@ +/*************************************************************************** + LaxFridrichsMomentumY.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "LaxFridrichsMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumY +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumY< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_v, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsMomentumY< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_v, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / 4.0 * this->tau * this->artificialViscosity * ( rho_v[ west ] + rho_v[ east ] + rho_v[ south ] + rho_v[ north ] - 4.0 * rho_v[ center ] ) + - 0.5 * ( ( ( rho_v[ west ] * velocity_x_west ) + - ( rho_v[ east ] * velocity_x_east ) )* hxInverse + + ( ( rho_v[ north ] * velocity_y_north + pressure_north ) + - ( rho_v[ south ] * velocity_y_south + pressure_south ) )* hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsMomentumY< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_v, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + 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 >(); + + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + return 1.0 / 6.0 * this->tau * this->artificialViscosity * + ( rho_v[ west ] + rho_v[ east ] + rho_v[ south ] + rho_v[ north ] + rho_v[ up ] + rho_v[ down ] - 6.0 * rho_v[ center ] ) + - 0.5 * ( ( ( rho_v[ west ] * velocity_x_west ) + - ( rho_v[ east ] * velocity_x_east ) ) * hxInverse + + ( ( rho_v[ north ] * velocity_y_north + pressure_north ) + - ( rho_v[ south ] * velocity_y_south + pressure_south ) ) * hyInverse + + ( ( rho_v[ up ] * velocity_z_up ) + - ( rho_v[ down ] * velocity_z_down ) ) * hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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;*/ +}; + + +} // namespace TNL + diff --git a/examples/inviscid-flow/LaxFridrichsMomentumZ.h b/examples/inviscid-flow/LaxFridrichsMomentumZ.h new file mode 100644 index 0000000000000000000000000000000000000000..0ab7da1234570de3e5ab0edabafdca17ce8e719d --- /dev/null +++ b/examples/inviscid-flow/LaxFridrichsMomentumZ.h @@ -0,0 +1,240 @@ +/*************************************************************************** + LaxFridrichsMomentumZ.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "LaxFridrichsMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumZ +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumZ< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsMomentumZ< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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 LaxFridrichsMomentumZ< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + 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 >(); + + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + return 1.0 / 6.0 * this->tau * this->artificialViscosity * + ( rho_w[ west ] + rho_w[ east ] + rho_w[ south ] + rho_w[ north ] + rho_w[ up ] + rho_w[ down ] - 6.0 * rho_w[ center ] ) + -0.5 * ( ( ( rho_w[ west ] * velocity_x_west ) + - ( rho_w[ east ] * velocity_x_east ) )* hxInverse + + ( ( rho_w[ north ] * velocity_y_north ) + - ( rho_w[ south ] * velocity_y_south ) )* hyInverse + + ( ( rho_w[ up ] * velocity_z_up + pressure_up ) + - ( rho_w[ down ] * velocity_z_down + pressure_down ) )* hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + 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;*/ +}; + + +} // namespace TNL + diff --git a/examples/inviscid-flow/PhysicalVariablesGetter.h b/examples/inviscid-flow/PhysicalVariablesGetter.h new file mode 100644 index 0000000000000000000000000000000000000000..25108da0791e266f48f32e0ae0c7296d4e2ef18b --- /dev/null +++ b/examples/inviscid-flow/PhysicalVariablesGetter.h @@ -0,0 +1,116 @@ +/*************************************************************************** + CompressibleConservativeVariables.h - description + ------------------- + begin : Feb 12, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/SharedPointer.h> +#include <TNL/Functions/MeshFunction.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/Functions/MeshFunctionEvaluator.h> +#include "CompressibleConservativeVariables.h" + +namespace TNL { + +template< typename Mesh > +class PhysicalVariablesGetter +{ + public: + + typedef Mesh MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + static const int Dimensions = MeshType::getMeshDimensions(); + + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef CompressibleConservativeVariables< MeshType > ConservativeVariablesType; + typedef SharedPointer< ConservativeVariablesType > ConservativeVariablesPointer; + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + class VelocityGetter : public Functions::Domain< Dimensions, Functions::MeshDomain > + { + public: + typedef typename MeshType::RealType RealType; + + VelocityGetter( MeshFunctionPointer density, + MeshFunctionPointer momentum ) + : density( density ), momentum( momentum ) {} + + template< typename EntityType > + __cuda_callable__ + RealType operator()( const EntityType& meshEntity, + const RealType& time = 0.0 ) const + { + return momentum.template getData< DeviceType >()( meshEntity ) / + density.template getData< DeviceType >()( meshEntity ); + } + + protected: + const MeshFunctionPointer density, momentum; + }; + + class PressureGetter : public Functions::Domain< Dimensions, Functions::MeshDomain > + { + public: + typedef typename MeshType::RealType RealType; + + PressureGetter( MeshFunctionPointer density, + MeshFunctionPointer energy, + VelocityFieldPointer momentum, + const RealType& gamma ) + : density( density ), energy( energy ), momentum( momentum ), gamma( gamma ) {} + + template< typename EntityType > + __cuda_callable__ + RealType operator()( const EntityType& meshEntity, + const RealType& time = 0.0 ) const + { + const RealType e = energy.template getData< DeviceType >()( meshEntity ); + const RealType rho = density.template getData< DeviceType >()( meshEntity ); + const RealType momentumNorm = momentum.template getData< DeviceType >().getVector( meshEntity ).lpNorm( 2.0 ); + return ( gamma - 1.0 ) * ( e - 0.5 * momentumNorm * momentumNorm / rho ); + } + + protected: + const MeshFunctionPointer density, energy; + const VelocityFieldPointer momentum; + const RealType gamma; + }; + + + void getVelocity( const ConservativeVariablesPointer& conservativeVariables, + VelocityFieldPointer& velocity ) + { + Functions::MeshFunctionEvaluator< MeshFunctionType, VelocityGetter > evaluator; + for( int i = 0; i < Dimensions; i++ ) + { + SharedPointer< VelocityGetter, DeviceType > velocityGetter( conservativeVariables->getDensity(), + ( *conservativeVariables->getMomentum() )[ i ] ); + evaluator.evaluate( ( *velocity )[ i ], velocityGetter ); + } + } + + void getPressure( const ConservativeVariablesPointer& conservativeVariables, + const RealType& gamma, + MeshFunctionPointer& pressure ) + { + Functions::MeshFunctionEvaluator< MeshFunctionType, PressureGetter > evaluator; + SharedPointer< PressureGetter, DeviceType > pressureGetter( conservativeVariables->getDensity(), + conservativeVariables->getEnergy(), + conservativeVariables->getMomentum(), + gamma ); + evaluator.evaluate( pressure, pressureGetter ); + } + +}; + +} //namespace TNL diff --git a/examples/inviscid-flow/RiemannProblemInitialCondition.h b/examples/inviscid-flow/RiemannProblemInitialCondition.h new file mode 100644 index 0000000000000000000000000000000000000000..0de73687f12ef63d54026b9366687f794dc4d373 --- /dev/null +++ b/examples/inviscid-flow/RiemannProblemInitialCondition.h @@ -0,0 +1,209 @@ +/*************************************************************************** + RiemannProblemInitialCondition.h - description + ------------------- + begin : Feb 13, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Containers/StaticVector.h> +#include <TNL/Operators/Analytic/Sign.h> +#include <TNL/Functions/MeshFunctionEvaluator.h> +#include <TNL/Operators/Analytic/Sign.h> +#include "CompressibleConservativeVariables.h" + +namespace TNL { + +template< typename Mesh > +class RiemannProblemInitialCondition +{ + public: + + typedef Mesh MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef Containers::StaticVector< Dimensions, RealType > VertexType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef Functions::VectorField< Dimensions, MeshType > VectorFieldType; + + RiemannProblemInitialCondition() + : discontinuityPlacement( 0.5 ), + leftDensity( 1.0 ), rightDensity( 1.0 ), + leftVelocity( -2.0 ), rightVelocity( 2.0 ), + leftPressure( 0.4 ), rightPressure( 0.4 ), + gamma( 1.67 ){} + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "discontinuity-placement-0", "x-coordinate of the discontinuity placement.", 0.5 ); + config.addEntry< double >( prefix + "discontinuity-placement-1", "y-coordinate of the discontinuity placement.", 0.5 ); + config.addEntry< double >( prefix + "discontinuity-placement-2", "z-coordinate of the discontinuity placement.", 0.5 ); + config.addEntry< double >( prefix + "left-density", "Density on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "right-density", "Density on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "left-velocity-0", "x-coordinate of the velocity on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "left-velocity-1", "y-coordinate of the velocity on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "left-velocity-2", "z-coordinate of the velocity on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "right-velocity-0", "x-coordinate of the velocity on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "right-velocity-1", "y-coordinate of the velocity on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "right-velocity-2", "z-coordinate of the velocity on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "left-pressure", "Pressure on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "right-pressure", "Pressure on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "gamma", "Gamma in the ideal gas state equation.", 1.67 ); + } + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->discontinuityPlacement.setup( parameters, prefix + "discontinuity-placement-" ); + this->leftVelocity.setup( parameters, prefix + "left-velocity-" ); + this->rightVelocity.setup( parameters, prefix + "right-velocity-" ); + this->leftDensity = parameters.getParameter< double >( prefix + "left-density" ); + this->rightDensity = parameters.getParameter< double >( prefix + "right-density" ); + this->leftPressure = parameters.getParameter< double >( prefix + "left-pressure" ); + this->rightPressure = parameters.getParameter< double >( prefix + "right-pressure" ); + this->gamma = parameters.getParameter< double >( prefix + "gamma" ); + return true; + }; + + void setDiscontinuityPlacement( const VertexType& v ) + { + this->discontinuityPlacement = v; + } + + const VertexType& getDiscontinuityPlasement() const + { + return this->discontinuityPlacement; + } + + void setLeftDensity( const RealType& leftDensity ) + { + this->leftDensity = leftDensity; + } + + const RealType& getLeftDensity() const + { + return this->leftDensity; + } + + void setRightDensity( const RealType& rightDensity ) + { + this->rightDensity = rightDensity; + } + + const RealType& getRightDensity() const + { + return this->rightDensity; + } + + void setLeftVelocity( const VertexType& leftVelocity ) + { + this->leftVelocity = leftVelocity; + } + + const VertexType& getLeftVelocity() const + { + return this->leftVelocity; + } + + void setRightVelocity( const RealType& rightVelocity ) + { + this->rightVelocity = rightVelocity; + } + + const VertexType& getRightVelocity() const + { + return this->rightVelocity; + } + + void setLeftPressure( const RealType& leftPressure ) + { + this->leftPressure = leftPressure; + } + + const RealType& getLeftPressure() const + { + return this->leftPressure; + } + + void setRightPressure( const RealType& rightPressure ) + { + this->rightPressure = rightPressure; + } + + const RealType& getRightPressure() const + { + return this->rightPressure; + } + + void setInitialCondition( CompressibleConservativeVariables< MeshType >& conservativeVariables, + const VertexType& center = VertexType( 0.0 ) ) + { + typedef Functions::Analytic::VectorNorm< Dimensions, RealType > VectorNormType; + typedef Operators::Analytic::Sign< Dimensions, RealType > SignType; + typedef Functions::OperatorFunction< SignType, VectorNormType > InitialConditionType; + typedef SharedPointer< InitialConditionType, DeviceType > InitialConditionPointer; + + InitialConditionPointer initialCondition; + initialCondition->getFunction().setCenter( center ); + initialCondition->getFunction().setMaxNorm( true ); + initialCondition->getFunction().setRadius( discontinuityPlacement[ 0 ] ); + discontinuityPlacement *= 1.0 / discontinuityPlacement[ 0 ]; + for( int i = 1; i < Dimensions; i++ ) + discontinuityPlacement[ i ] = 1.0 / discontinuityPlacement[ i ]; + initialCondition->getFunction().setAnisotropy( discontinuityPlacement ); + initialCondition->getFunction().setMultiplicator( -1.0 ); + + Functions::MeshFunctionEvaluator< MeshFunctionType, InitialConditionType > evaluator; + + /**** + * Density + */ + initialCondition->getOperator().setPositiveValue( leftDensity ); + initialCondition->getOperator().setNegativeValue( rightDensity ); + evaluator.evaluate( conservativeVariables.getDensity(), initialCondition ); + conservativeVariables.getDensity()->write( "density.gplt", "gnuplot" ); + + /**** + * Momentum + */ + for( int i = 0; i < Dimensions; i++ ) + { + initialCondition->getOperator().setPositiveValue( leftDensity * leftVelocity[ i ] ); + initialCondition->getOperator().setNegativeValue( rightDensity * rightVelocity[ i ] ); + evaluator.evaluate( ( *conservativeVariables.getMomentum() )[ i ], initialCondition ); + } + + /**** + * Energy + */ + const RealType leftKineticEnergy = leftVelocity.lpNorm( 2.0 ); + const RealType rightKineticEnergy = rightVelocity.lpNorm( 2.0 ); + const RealType leftEnergy = leftPressure / ( gamma - 1.0 ) + 0.5 * leftDensity * leftKineticEnergy * leftKineticEnergy; + const RealType rightEnergy = rightPressure / ( gamma - 1.0 ) + 0.5 * rightDensity * rightKineticEnergy * rightKineticEnergy; + initialCondition->getOperator().setPositiveValue( leftEnergy ); + initialCondition->getOperator().setNegativeValue( rightEnergy ); + evaluator.evaluate( conservativeVariables.getEnergy(), initialCondition ); + conservativeVariables.getEnergy()->write( "energy-init", "gnuplot" ); + } + + + protected: + + VertexType discontinuityPlacement; + + RealType leftDensity, rightDensity; + VertexType leftVelocity, rightVelocity; + RealType leftPressure, rightPressure; + + RealType gamma; // gamma in the ideal gas state equation +}; + +} //namespace TNL \ No newline at end of file diff --git a/examples/inviscid-flow/1d/euler.cpp b/examples/inviscid-flow/euler.cpp similarity index 100% rename from examples/inviscid-flow/1d/euler.cpp rename to examples/inviscid-flow/euler.cpp diff --git a/examples/inviscid-flow/1d/euler.cu b/examples/inviscid-flow/euler.cu similarity index 100% rename from examples/inviscid-flow/1d/euler.cu rename to examples/inviscid-flow/euler.cu diff --git a/examples/inviscid-flow/1d/euler.h b/examples/inviscid-flow/euler.h similarity index 82% rename from examples/inviscid-flow/1d/euler.h rename to examples/inviscid-flow/euler.h index 65bf55820659f8ce67d3a1cfd5622e1f558dab72..baa8941346311cd651c3f7443c11c56f2c690651 100644 --- a/examples/inviscid-flow/1d/euler.h +++ b/examples/inviscid-flow/euler.h @@ -6,20 +6,21 @@ #include <TNL/Functions/Analytic/Constant.h> #include "eulerProblem.h" #include "LaxFridrichs.h" - #include "eulerRhs.h" #include "eulerBuildConfigTag.h" +#include "RiemannProblemInitialCondition.h" + using namespace TNL; typedef eulerBuildConfigTag BuildConfig; /**** - * Uncoment the following (and comment the previous line) for the complete build. + * Uncomment 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, + * especially if CUDA is enabled. Use this, if you want, only for the final build, * not in the development phase. */ //typedef tnlDefaultConfigTag BuildConfig; @@ -29,19 +30,14 @@ template< typename ConfigTag >class eulerConfig public: static void configSetup( Config::ConfigDescription & config ) { - config.addDelimiter( "euler settings:" ); + config.addDelimiter( "Inviscid flow settings:" ); config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); config.addEntryEnum< String >( "dirichlet" ); config.addEntryEnum< String >( "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." ); + typedef Meshes::Grid< 3 > Mesh; + LaxFridrichs< Mesh >::configSetup( config, "inviscid-operators-" ); + RiemannProblemInitialCondition< Mesh >::configSetup( config ); /**** * Add definition of your solver command line arguments. @@ -115,5 +111,3 @@ int main( int argc, char* argv[] ) return EXIT_FAILURE; return EXIT_SUCCESS; } - - diff --git a/examples/inviscid-flow/1d/eulerBuildConfigTag.h b/examples/inviscid-flow/eulerBuildConfigTag.h similarity index 96% rename from examples/inviscid-flow/1d/eulerBuildConfigTag.h rename to examples/inviscid-flow/eulerBuildConfigTag.h index abede16343a81cde5e75386f8b2e15117fd6672d..2bb81e8cb3cd81772c4c5722ca9c5a518ffea25a 100644 --- a/examples/inviscid-flow/1d/eulerBuildConfigTag.h +++ b/examples/inviscid-flow/eulerBuildConfigTag.h @@ -21,7 +21,7 @@ template<> struct ConfigTagReal< eulerBuildConfigTag, long double > { enum { ena template<> struct ConfigTagIndex< eulerBuildConfigTag, short int >{ enum { enabled = false }; }; template<> struct ConfigTagIndex< eulerBuildConfigTag, long int >{ enum { enabled = false }; }; -template< int Dimensions > struct ConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = ( Dimensions == 1 ) }; }; +template< int Dimensions > struct ConfigTagDimensions< eulerBuildConfigTag, Dimensions >{ enum { enabled = true }; }; /**** * Use of Grid is enabled for allowed dimensions and Real, Device and Index types. diff --git a/examples/inviscid-flow/1d/eulerProblem.h b/examples/inviscid-flow/eulerProblem.h similarity index 64% rename from examples/inviscid-flow/1d/eulerProblem.h rename to examples/inviscid-flow/eulerProblem.h index f687ee5460accc7a593bb8f6e034872f8d8e6eda..79cff960a4e6801900cf43990f3cae0d23178ee2 100644 --- a/examples/inviscid-flow/1d/eulerProblem.h +++ b/examples/inviscid-flow/eulerProblem.h @@ -1,33 +1,40 @@ -#ifndef eulerPROBLEM_H_ -#define eulerPROBLEM_H_ +/*************************************************************************** + eulerProblem.h - description + ------------------- + begin : Feb 13, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once #include <TNL/Problems/PDEProblem.h> #include <TNL/Functions/MeshFunction.h> +#include "CompressibleConservativeVariables.h" + using namespace TNL::Problems; + namespace TNL { template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > class eulerProblem: public PDEProblem< Mesh, - typename DifferentialOperator::RealType, - typename Mesh::DeviceType, - typename DifferentialOperator::IndexType > + typename InviscidOperators::RealType, + typename Mesh::DeviceType, + typename InviscidOperators::IndexType > { public: - - typedef typename DifferentialOperator::RealType RealType; + + typedef typename InviscidOperators::RealType RealType; typedef typename Mesh::DeviceType DeviceType; - typedef typename DifferentialOperator::IndexType IndexType; - typedef Functions::MeshFunction< Mesh > MeshFunctionType; - typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; - typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer; - typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer; - typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer; - typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; + typedef typename InviscidOperators::IndexType IndexType; + typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; using typename BaseType::MeshType; using typename BaseType::MeshPointer; @@ -36,13 +43,17 @@ class eulerProblem: using typename BaseType::MeshDependentDataType; using typename BaseType::MeshDependentDataPointer; - typedef typename DifferentialOperator::Continuity Continuity; - typedef typename DifferentialOperator::Momentum Momentum; - typedef typename DifferentialOperator::Energy Energy; - typedef typename DifferentialOperator::Velocity Velocity; - typedef typename DifferentialOperator::Pressure Pressure; - + static const int Dimensions = Mesh::getMeshDimensions(); + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + typedef CompressibleConservativeVariables< MeshType > ConservativeVariablesType; + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + typedef SharedPointer< ConservativeVariablesType > ConservativeVariablesPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + typedef SharedPointer< InviscidOperators > InviscidOperatorsPointer; + typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer; + typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer; static String getTypeStatic(); @@ -51,9 +62,9 @@ class eulerProblem: void writeProlog( Logger& logger, const Config::ParameterContainer& parameters ) const; - bool setup( const MeshPointer& meshPointer, + bool setup( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters, - const String& prefix ); + const String& prefix = "" ); bool setInitialCondition( const Config::ParameterContainer& parameters, const MeshPointer& mesh, @@ -90,7 +101,7 @@ class eulerProblem: Matrix& matrix, DofVectorPointer& rightHandSide, MeshDependentDataPointer& meshDependentData ); - + bool postIterate( const RealType& time, const RealType& tau, const MeshPointer& mesh, @@ -99,22 +110,21 @@ class eulerProblem: protected: - DifferentialOperatorPointer differentialOperatorPointer; - BoundaryConditionPointer boundaryConditionsPointer; + InviscidOperatorsPointer inviscidOperatorsPointer; + + BoundaryConditionPointer boundaryConditionPointer; RightHandSidePointer rightHandSidePointer; - MeshFunctionPointer uRho, uRhoVelocity, uEnergy; - MeshFunctionPointer fuRho, fuRhoVelocity, fuEnergy; + ConservativeVariablesPointer conservativeVariables, + conservativeVariablesRHS; - MeshFunctionPointer pressure, velocity, rho, rhoVel, energy; + VelocityFieldPointer velocity; + MeshFunctionPointer pressure; - RealType gamma; - - + RealType gamma; }; -} // namepsace TNL +} // namespace TNL #include "eulerProblem_impl.h" -#endif /* eulerPROBLEM_H_ */ diff --git a/examples/inviscid-flow/2d/eulerProblem_impl.h b/examples/inviscid-flow/eulerProblem_impl.h similarity index 51% rename from examples/inviscid-flow/2d/eulerProblem_impl.h rename to examples/inviscid-flow/eulerProblem_impl.h index 27d4aa4ae67b7cacf7fdfb13214349a8a996a874..08b12e344e7551f2c0f3b8dead00f8dbe8c2c891 100644 --- a/examples/inviscid-flow/2d/eulerProblem_impl.h +++ b/examples/inviscid-flow/eulerProblem_impl.h @@ -1,3 +1,13 @@ +/*************************************************************************** + eulerProblem_impl.h - description + ------------------- + begin : Feb 13, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + #pragma once #include <TNL/FileName.h> @@ -5,24 +15,27 @@ #include <TNL/Solvers/PDE/ExplicitUpdater.h> #include <TNL/Solvers/PDE/LinearSystemAssembler.h> #include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h> +#include <TNL/Functions/Analytic/VectorNorm.h> + +#include "RiemannProblemInitialCondition.h" +#include "CompressibleConservativeVariables.h" +#include "PhysicalVariablesGetter.h" +#include "eulerProblem.h" #include "LaxFridrichsContinuity.h" #include "LaxFridrichsEnergy.h" #include "LaxFridrichsMomentumX.h" #include "LaxFridrichsMomentumY.h" -#include "EulerPressureGetter.h" -#include "EulerVelXGetter.h" -#include "EulerVelYGetter.h" -#include "EulerVelGetter.h" +#include "LaxFridrichsMomentumZ.h" namespace TNL { template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > String -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: getTypeStatic() { return String( "eulerProblem< " ) + Mesh :: getTypeStatic() + " >"; @@ -31,20 +44,20 @@ getTypeStatic() template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > String -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: getPrologHeader() const { - return String( "euler2D" ); + return String( "Inviscid flow solver" ); } template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > void -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: writeProlog( Logger& logger, const Config::ParameterContainer& parameters ) const { /**** @@ -56,115 +69,83 @@ writeProlog( Logger& logger, const Config::ParameterContainer& parameters ) cons template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > bool -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: setup( const MeshPointer& meshPointer, const Config::ParameterContainer& parameters, const String& prefix ) { - if( ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) || + if( ! this->inviscidOperatorsPointer->setup( meshPointer, parameters, prefix + "inviscid-operators-" ) || + ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) || ! this->rightHandSidePointer->setup( parameters, prefix + "right-hand-side-" ) ) return false; + this->gamma = parameters.getParameter< double >( "gamma" ); + velocity->setMesh( meshPointer ); + pressure->setMesh( meshPointer ); return true; } template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > -typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: + typename InviscidOperators > +typename eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::IndexType +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: getDofs( const MeshPointer& 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 >(); + return this->conservativeVariables->getDofs( mesh ); } template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > void -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: bindDofs( const MeshPointer& mesh, DofVectorPointer& dofVector ) { + this->conservativeVariables->bind( mesh, dofVector ); } template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > bool -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: setInitialCondition( const Config::ParameterContainer& parameters, const MeshPointer& mesh, DofVectorPointer& dofs, MeshDependentDataPointer& 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 = size * size; - 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; + CompressibleConservativeVariables< MeshType > conservativeVariables; + conservativeVariables.bind( mesh, dofs ); + const String& initialConditionType = parameters.getParameter< String >( "initial-condition" ); + if( initialConditionType == "riemann-problem" ) + { + RiemannProblemInitialCondition< MeshType > initialCondition; + if( ! initialCondition.setup( parameters ) ) + return false; + initialCondition.setInitialCondition( conservativeVariables ); + return true; + } + std::cerr << "Unknown initial condition " << initialConditionType << std::endl; + return false; } template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > template< typename Matrix > bool -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: setupLinearSystem( const MeshPointer& mesh, Matrix& matrix ) { @@ -173,7 +154,7 @@ setupLinearSystem( const MeshPointer& mesh, CompressedRowsLengthsVectorType rowLengths; if( ! rowLengths.setSize( dofs ) ) return false; - MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter; + MatrixSetter< MeshType, InviscidOperators, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter; matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh, differentialOperator, boundaryCondition, @@ -187,9 +168,9 @@ setupLinearSystem( const MeshPointer& mesh, template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > bool -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: makeSnapshot( const RealType& time, const IndexType& step, const MeshPointer& mesh, @@ -197,44 +178,40 @@ makeSnapshot( const RealType& time, MeshDependentDataPointer& meshDependentData ) { std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl; - this->bindDofs( mesh, dofs ); + + this->bindDofs( mesh, dofs ); + PhysicalVariablesGetter< MeshType > physicalVariablesGetter; + physicalVariablesGetter.getVelocity( this->conservativeVariables, this->velocity ); + physicalVariablesGetter.getPressure( this->conservativeVariables, this->gamma, this->pressure ); + FileName fileName; fileName.setExtension( "tnl" ); fileName.setIndex( step ); - fileName.setFileNameBase( "rho-" ); - if( ! this->rho.save( fileName.getFileName() ) ) - return false; - fileName.setFileNameBase( "rhoVelX-" ); - if( ! this->rhoVelX.save( fileName.getFileName() ) ) - return false; - fileName.setFileNameBase( "rhoVelY-" ); - if( ! this->rhoVelY.save( fileName.getFileName() ) ) - return false; - fileName.setFileNameBase( "energy-" ); - if( ! this->energy.save( fileName.getFileName() ) ) - return false; - fileName.setFileNameBase( "velocityX-" ); - if( ! this->velocityX.save( fileName.getFileName() ) ) - return false; - fileName.setFileNameBase( "velocityY-" ); - if( ! this->velocityY.save( fileName.getFileName() ) ) + fileName.setFileNameBase( "density-" ); + if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) ) return false; + fileName.setFileNameBase( "velocity-" ); - if( ! this->velocity.save( fileName.getFileName() ) ) + if( ! this->velocity->save( fileName.getFileName() ) ) return false; - fileName.setFileNameBase( "pressue-" ); - if( ! this->pressure.save( fileName.getFileName() ) ) + + fileName.setFileNameBase( "pressure-" ); + if( ! this->pressure->save( fileName.getFileName() ) ) return false; + fileName.setFileNameBase( "energy-" ); + if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) ) + return false; + return true; } template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > void -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: getExplicitRHS( const RealType& time, const RealType& tau, const MeshPointer& mesh, @@ -243,92 +220,100 @@ getExplicitRHS( const RealType& time, MeshDependentDataPointer& meshDependentData ) { typedef typename MeshType::Cell Cell; - int count = mesh->template getEntitiesCount< Cell >()/4; - //bind _u - this->_uRho.bind( *_u,0,count); - this->_uRhoVelocityX.bind( *_u,count,count); - this->_uRhoVelocityY.bind( *_u,2 * count,count); - this->_uEnergy.bind( *_u,3 * count,count); - - //bind _fu - this->_fuRho.bind( *_u,0,count); - this->_fuRhoVelocityX.bind( *_u,count,count); - this->_fuRhoVelocityY.bind( *_u,2 * count,count); - this->_fuEnergy.bind( *_u,3 * count,count); - //bind MeshFunctionType - MeshFunctionPointer velocity( mesh, this->velocity ); - MeshFunctionPointer velocityX( mesh, this->velocityX ); - MeshFunctionPointer velocityY( mesh, this->velocityY ); - MeshFunctionPointer pressure( mesh, this->pressure ); - MeshFunctionPointer uRho( mesh, _uRho ); - MeshFunctionPointer fuRho( mesh, _fuRho ); - MeshFunctionPointer uRhoVelocityX( mesh, _uRhoVelocityX ); - MeshFunctionPointer fuRhoVelocityX( mesh, _fuRhoVelocityX ); - MeshFunctionPointer uRhoVelocityY( mesh, _uRhoVelocityY ); - MeshFunctionPointer fuRhoVelocityY( mesh, _fuRhoVelocityY ); - MeshFunctionPointer uEnergy( mesh, _uEnergy ); - MeshFunctionPointer fuEnergy( mesh, _fuEnergy ); - //generate Operators - SharedPointer< Continuity > lF2DContinuity; - SharedPointer< MomentumX > lF2DMomentumX; - SharedPointer< MomentumY > lF2DMomentumY; - SharedPointer< Energy > lF2DEnergy; - - this->bindDofs( mesh, _u ); - //rho - lF2DContinuity->setTau(tau); - lF2DContinuity->setVelocityX( *velocityX ); - lF2DContinuity->setVelocityY( *velocityY ); - Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Continuity, BoundaryCondition, RightHandSide > explicitUpdaterContinuity; + + /**** + * Bind DOFs + */ + this->conservativeVariables->bind( mesh, _u ); + this->conservativeVariablesRHS->bind( mesh, _fu ); + this->velocity->setMesh( mesh ); + this->pressure->setMesh( mesh ); + + /**** + * Resolve the physical variables + */ + PhysicalVariablesGetter< typename MeshPointer::ObjectType > physicalVariables; + physicalVariables.getVelocity( this->conservativeVariables, this->velocity ); + physicalVariables.getPressure( this->conservativeVariables, this->gamma, this->pressure ); + + /**** + * Set-up operators + */ + typedef typename InviscidOperators::ContinuityOperatorType ContinuityOperatorType; + typedef typename InviscidOperators::MomentumXOperatorType MomentumXOperatorType; + typedef typename InviscidOperators::MomentumYOperatorType MomentumYOperatorType; + typedef typename InviscidOperators::MomentumZOperatorType MomentumZOperatorType; + typedef typename InviscidOperators::EnergyOperatorType EnergyOperatorType; + + this->inviscidOperatorsPointer->setTau( tau ); + this->inviscidOperatorsPointer->setVelocity( this->velocity ); + this->inviscidOperatorsPointer->setPressure( this->pressure ); + + /**** + * Continuity equation + */ + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, ContinuityOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterContinuity; explicitUpdaterContinuity.template update< typename Mesh::Cell >( time, mesh, - lF2DContinuity, + this->inviscidOperatorsPointer->getContinuityOperator(), this->boundaryConditionPointer, this->rightHandSidePointer, - uRho, - fuRho ); - - //rhoVelocityX - lF2DMomentumX->setTau(tau); - lF2DMomentumX->setVelocityX( *velocityX ); - lF2DMomentumX->setVelocityY( *velocityY ); - lF2DMomentumX->setPressure( *pressure ); - Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumX, BoundaryCondition, RightHandSide > explicitUpdaterMomentumX; + this->conservativeVariables->getDensity(), + this->conservativeVariablesRHS->getDensity() ); + + /**** + * Momentum equations + */ + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumXOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumX; explicitUpdaterMomentumX.template update< typename Mesh::Cell >( time, mesh, - lF2DMomentumX, - this->boundaryConditionPointer, - this->rightHandSidePointer, - uRhoVelocityX, - fuRhoVelocityX ); - - //rhoVelocityY - lF2DMomentumY->setTau(tau); - lF2DMomentumY->setVelocityX( *velocityX ); - lF2DMomentumY->setVelocityY( *velocityY ); - lF2DMomentumY->setPressure( *pressure ); - Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumY, BoundaryCondition, RightHandSide > explicitUpdaterMomentumY; - explicitUpdaterMomentumY.template update< typename Mesh::Cell >( time, - mesh, - lF2DMomentumY, + this->inviscidOperatorsPointer->getMomentumXOperator(), this->boundaryConditionPointer, this->rightHandSidePointer, - uRhoVelocityY, - fuRhoVelocityY ); + ( *this->conservativeVariables->getMomentum() )[ 0 ], // uRhoVelocityX, + ( *this->conservativeVariablesRHS->getMomentum() )[ 0 ] ); //, fuRhoVelocityX ); + + if( Dimensions > 1 ) + { + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumYOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumY; + explicitUpdaterMomentumY.template update< typename Mesh::Cell >( time, + mesh, + this->inviscidOperatorsPointer->getMomentumYOperator(), + this->boundaryConditionPointer, + this->rightHandSidePointer, + ( *this->conservativeVariables->getMomentum() )[ 1 ], // uRhoVelocityX, + ( *this->conservativeVariablesRHS->getMomentum() )[ 1 ] ); //, fuRhoVelocityX ); + } + + if( Dimensions > 2 ) + { + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumZOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterMomentumZ; + explicitUpdaterMomentumZ.template update< typename Mesh::Cell >( time, + mesh, + this->inviscidOperatorsPointer->getMomentumZOperator(), + this->boundaryConditionPointer, + this->rightHandSidePointer, + ( *this->conservativeVariables->getMomentum() )[ 2 ], // uRhoVelocityX, + ( *this->conservativeVariablesRHS->getMomentum() )[ 2 ] ); //, fuRhoVelocityX ); + } + - //energy - lF2DEnergy->setTau(tau); - lF2DEnergy->setVelocityX( *velocityX ); - lF2DEnergy->setVelocityY( *velocityY ); - lF2DEnergy->setPressure( *pressure ); - Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, Energy, BoundaryCondition, RightHandSide > explicitUpdaterEnergy; + /**** + * Energy equation + */ + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, EnergyOperatorType, BoundaryCondition, RightHandSide > explicitUpdaterEnergy; explicitUpdaterEnergy.template update< typename Mesh::Cell >( time, mesh, - lF2DEnergy, + this->inviscidOperatorsPointer->getEnergyOperator(), this->boundaryConditionPointer, this->rightHandSidePointer, - uEnergy, - fuEnergy ); + this->conservativeVariables->getEnergy(), // uRhoVelocityX, + this->conservativeVariablesRHS->getEnergy() ); //, fuRhoVelocityX ); + + /*this->conservativeVariablesRHS->getDensity()->write( "density", "gnuplot" ); + this->conservativeVariablesRHS->getEnergy()->write( "energy", "gnuplot" ); + this->conservativeVariablesRHS->getMomentum()->write( "momentum", "gnuplot", 0.05 ); + getchar();*/ /* BoundaryConditionsSetter< MeshFunctionType, BoundaryCondition > boundaryConditionsSetter; @@ -341,10 +326,10 @@ getExplicitRHS( const RealType& time, template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > template< typename Matrix > void -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: assemblyLinearSystem( const RealType& time, const RealType& tau, const MeshPointer& mesh, @@ -355,7 +340,7 @@ assemblyLinearSystem( const RealType& time, { /* LinearSystemAssembler< Mesh, MeshFunctionType, - DifferentialOperator, + InviscidOperators, BoundaryCondition, RightHandSide, BackwardTimeDiscretisation, @@ -377,15 +362,16 @@ assemblyLinearSystem( const RealType& time, template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > + typename InviscidOperators > bool -eulerProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +eulerProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: postIterate( const RealType& time, const RealType& tau, const MeshPointer& mesh, DofVectorPointer& dofs, MeshDependentDataPointer& meshDependentData ) { + /* typedef typename MeshType::Cell Cell; int count = mesh->template getEntitiesCount< Cell >()/4; //bind _u @@ -433,7 +419,8 @@ postIterate( const RealType& time, euler2DPressure.setRho(uRho); // OperatorFunction< euler2DPressure, MeshFunction, void, time > OFPressure; // pressure = OFPressure; - + */ + return true; } } // namespace TNL diff --git a/examples/inviscid-flow/1d/eulerRhs.h b/examples/inviscid-flow/eulerRhs.h similarity index 100% rename from examples/inviscid-flow/1d/eulerRhs.h rename to examples/inviscid-flow/eulerRhs.h diff --git a/examples/inviscid-flow/run-euler b/examples/inviscid-flow/run-euler new file mode 100644 index 0000000000000000000000000000000000000000..7af3493805c96e19c65a3f475e2ed63aaf59db92 --- /dev/null +++ b/examples/inviscid-flow/run-euler @@ -0,0 +1,35 @@ +#!/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 +tnl-euler-2d --initial-condition riemann-problem \ + --discontinuity-placement-0 0.3 \ + --discontinuity-placement-1 0.3 \ + --discontinuity-placement-2 0.3 \ + --left-density 1.0 \ + --right-density 1.0 \ + --left-velocity-0 -0.2 \ + --left-velocity-1 -0.2 \ + --left-velocity-2 -0.2 \ + --right-velocity-0 0.2 \ + --right-velocity-1 0.2 \ + --right-velocity-2 0.2 \ + --left-pressure 0.4 \ + --right-pressure 0.4 \ + --time-discretisation explicit \ + --boundary-conditions-type neumann \ + --boundary-conditions-constant 0 \ + --discrete-solver euler \ + --time-step 0.0001 \ + --snapshot-period 0.01 \ + --final-time 1.0 + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/narrow-band/CMakeLists.txt b/examples/narrow-band/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..748343b58e4c5bcca2fe5de2160d3e4a2eeb2e76 --- /dev/null +++ b/examples/narrow-band/CMakeLists.txt @@ -0,0 +1,22 @@ +set( tnl_narrow_band_SOURCES +# MainBuildConfig.h +# tnlNarrowBand2D_impl.h +# tnlNarrowBand.h +# narrowBandConfig.h + main.cpp) + + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(narrow-band${debugExt} main.cu) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(narrow-band${debugExt} main.cpp) +ENDIF( BUILD_CUDA ) +target_link_libraries (narrow-band${debugExt} tnl${debugExt}-${tnlVersion} ) + + +INSTALL( TARGETS narrow-band${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +#INSTALL( FILES ${tnl_narrow_band_SOURCES} +# DESTINATION share/tnl-${tnlVersion}/examples/narrow-band ) diff --git a/examples/narrow-band/MainBuildConfig.h b/examples/narrow-band/MainBuildConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4 --- /dev/null +++ b/examples/narrow-band/MainBuildConfig.h @@ -0,0 +1,64 @@ +/*************************************************************************** + MainBuildConfig.h - description + ------------------- + begin : Jul 7, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MAINBUILDCONFIG_H_ +#define MAINBUILDCONFIG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class MainBuildConfig +{ + public: + + static void print() { cerr << "MainBuildConfig" << endl; } +}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && + tnlConfigTagReal< MainBuildConfig, Real >::enabled && + tnlConfigTagDevice< MainBuildConfig, Device >::enabled && + tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* MAINBUILDCONFIG_H_ */ diff --git a/examples/narrow-band/main.cpp b/examples/narrow-band/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9 --- /dev/null +++ b/examples/narrow-band/main.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/examples/narrow-band/main.cu b/examples/narrow-band/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9 --- /dev/null +++ b/examples/narrow-band/main.cu @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/examples/narrow-band/main.h b/examples/narrow-band/main.h new file mode 100644 index 0000000000000000000000000000000000000000..47d8648bbf7646cd9580134f55be6002359cf21e --- /dev/null +++ b/examples/narrow-band/main.h @@ -0,0 +1,88 @@ +/*************************************************************************** + main.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "MainBuildConfig.h" + //for HOST versions: +//#include "tnlNarrowBand.h" + //for DEVICE versions: +#include "tnlNarrowBand_CUDA.h" +#include "narrowBandConfig.h" +#include <solvers/tnlBuildConfigTags.h> + +#include <mesh/tnlGrid.h> +#include <core/tnlDevice.h> +#include <time.h> +#include <ctime> + +typedef MainBuildConfig BuildConfig; + +int main( int argc, char* argv[] ) +{ + time_t start; + time_t stop; + time(&start); + std::clock_t start2= std::clock(); + Config::ParameterContainer parameters; + tnlConfigDescription configDescription; + narrowBandConfig< BuildConfig >::configSetup( configDescription ); + + if( ! parseCommandLine( argc, argv, configDescription, parameters ) ) + return false; + + const int& dim = parameters.getParameter< int >( "dim" ); + + if(dim == 2) + { + tnlNarrowBand<tnlGrid<2,double,tnlHost, int>, double, int> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + checkCudaDevice; + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver..." << endl; + solver.run(); + } +// else if(dim == 3) +// { +// tnlNarrowBand<tnlGrid<3,double,tnlHost, int>, double, int> solver; +// if(!solver.init(parameters)) +// { +// cerr << "Solver failed to initialize." << endl; +// return EXIT_FAILURE; +// } +// checkCudaDevice; +// cout << "-------------------------------------------------------------" << endl; +// cout << "Starting solver..." << endl; +// solver.run(); +// } + else + { + cerr << "Unsupported number of dimensions: " << dim << "!" << endl; + return EXIT_FAILURE; + } + + + time(&stop); + cout << "Solver stopped..." << endl; + cout << endl; + cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl; + return EXIT_SUCCESS; +} + + diff --git a/examples/narrow-band/narrowBandConfig.h b/examples/narrow-band/narrowBandConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..bab58ceac46bf9c766b697ed79c2c676111323a2 --- /dev/null +++ b/examples/narrow-band/narrowBandConfig.h @@ -0,0 +1,40 @@ +/*************************************************************************** + narrowBandConfig.h - description + ------------------- + begin : Oct 15, 2015 + copyright : (C) 2015 by Tomas Sobotik + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef NARROWBANDCONFIG_H_ +#define NARROWBANDCONFIG_H_ + +#include <config/tnlConfigDescription.h> + +template< typename ConfigTag > +class narrowBandConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Narrow Band Solver solver settings:" ); + config.addEntry < String > ( "problem-name", "This defines particular problem.", "fast-sweeping" ); + config.addRequiredEntry < String > ( "initial-condition", "Initial condition for solver"); + config.addRequiredEntry < int > ( "dim", "Dimension of problem."); + config.addRequiredEntry < double > ( "tau", "Time step."); + config.addRequiredEntry < double > ( "final-time", "Final time."); + config.addEntry < String > ( "mesh", "Name of mesh.", "mesh.tnl" ); + config.addEntry < String > ( "exact-input", "Are the function values near the curve equal to the SDF? (yes/no)", "no" ); + } +}; + +#endif /* NARROWBANDCONFIG_H_ */ diff --git a/examples/narrow-band/tnlNarrowBand.h b/examples/narrow-band/tnlNarrowBand.h new file mode 100644 index 0000000000000000000000000000000000000000..e2817424a1feb0f24bcbf8a759d37e8c9697977d --- /dev/null +++ b/examples/narrow-band/tnlNarrowBand.h @@ -0,0 +1,186 @@ +/*************************************************************************** + tnlNarrowBand.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLNARROWBAND_H_ +#define TNLNARROWBAND_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <functions/tnlMeshFunction.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> +#include <limits.h> +#include <core/tnlDevice.h> +#include <ctime> +#ifdef HAVE_OPENMP +#include <omp.h> +#endif + + + + +template< typename Mesh, + typename Real, + typename Index > +class tnlNarrowBand +{}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + tnlNarrowBand(); + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + + bool initGrid(); + bool run(); + + //for single core version use this implementation: + void updateValue(const Index i, const Index j); + //for parallel version use this one instead: +// void updateValue(const Index i, const Index j, DofVectorType* grid); + + + void setupSquare1000(Index i, Index j); + void setupSquare1100(Index i, Index j); + void setupSquare1010(Index i, Index j); + void setupSquare1001(Index i, Index j); + void setupSquare1110(Index i, Index j); + void setupSquare1101(Index i, Index j); + void setupSquare1011(Index i, Index j); + void setupSquare1111(Index i, Index j); + void setupSquare0000(Index i, Index j); + void setupSquare0100(Index i, Index j); + void setupSquare0010(Index i, Index j); + void setupSquare0001(Index i, Index j); + void setupSquare0110(Index i, Index j); + void setupSquare0101(Index i, Index j); + void setupSquare0011(Index i, Index j); + void setupSquare0111(Index i, Index j); + + Real fabsMin(const Real x, const Real y); + + +protected: + + MeshType Mesh; + + bool exactInput; + + tnlMeshFunction<MeshType> dofVector, dofVector2; + DofVectorType data; + + RealType h; + + tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity; + + +#ifdef HAVE_OPENMP +// omp_lock_t* gridLock; +#endif + + +}; + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + tnlNarrowBand(); + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + + bool initGrid(); + bool run(); + + //for single core version use this implementation: + void updateValue(const Index i, const Index j, const Index k); + //for parallel version use this one instead: +// void updateValue(const Index i, const Index j, DofVectorType* grid); + + Real fabsMin(const Real x, const Real y); + + +protected: + + MeshType Mesh; + + bool exactInput; + + + tnlMeshFunction<MeshType> dofVector, dofVector2; + DofVectorType data; + + RealType h; + + tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage > Entity; + +#ifdef HAVE_OPENMP +// omp_lock_t* gridLock; +#endif + + +}; + + + //for single core version use this implementation: +#include "tnlNarrowBand2D_impl.h" + //for parallel version use this one instead: +// #include "tnlNarrowBand2D_openMP_impl.h" + +#include "tnlNarrowBand3D_impl.h" + +#endif /* TNLNARROWBAND_H_ */ diff --git a/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h b/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..e532bca7774c9c42648bf43f648a07ebbf20eb78 --- /dev/null +++ b/examples/narrow-band/tnlNarrowBand2D_CUDA_v4_impl.h @@ -0,0 +1,1317 @@ +/*************************************************************************** + tnlNarrowBand2D_CUDA_v4_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLNARROWBAND2D_IMPL_H_ +#define TNLNARROWBAND2D_IMPL_H_ + +#define NARROWBAND_SUBGRID_SIZE 32 + +#include "tnlNarrowBand.h" + +#ifdef HAVE_CUDA +__device__ +double fabsMin( double x, double y) +{ + double fx = abs(x); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; +} + +__device__ +double atomicFabsMin(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) )); + } while (assumed != old); + return __longlong_as_double(old); +} +#endif + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return -arg; + return 0.0; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlNarrowBand< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand() +:dofVector(Mesh) +{ +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.template getSpaceStepsProducts< 1, 0 >(); + //Entity.refresh(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + tau = parameters.getParameter< double >( "tau" ); + + finalTime = parameters.getParameter< double >( "final-time" ); + + statusGridSize = ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE); +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaStatusVector), statusGridSize*statusGridSize*sizeof(int)); +// cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), statusGridSize*statusGridSize* sizeof(int)), cudaMemcpyHostToDevice); + + cudaMalloc(&reinitialize, sizeof(int)); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + + + cudaDeviceSynchronize(); + checkCudaDevice; +#endif + + int n = Mesh.getDimensions().x(); + + dim3 threadsPerBlock2(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE); + dim3 numBlocks2(statusGridSize ,statusGridSize); + initSetupGridCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + initSetupGrid2CUDA<<<numBlocks2,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + + /*dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1);*/ + initCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + + cout << "Solver initialized." << endl; + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlockFS(1, 512); + dim3 numBlocksFS(4,1); + dim3 threadsPerBlockNB(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE); + dim3 numBlocksNB(n/NARROWBAND_SUBGRID_SIZE + 1,n/NARROWBAND_SUBGRID_SIZE + 1); + + double time = 0.0; + int reinit = 0; + + cout << "Hi!" << endl; + runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0); + cudaDeviceSynchronize(); + checkCudaDevice; + cout << "Hi2!" << endl; + while(time < finalTime) + { + if(tau+time > finalTime) + tau=finalTime-time; + + runNarrowBandCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver,tau); + cudaDeviceSynchronize(); + checkCudaDevice; + + time += tau; + + + cudaMemcpy(&reinit, this->reinitialize, sizeof(int), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + checkCudaDevice; + if(reinit != 0 /*&& time != finalTime */) + { + cout << time << endl; + + initSetupGridCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + initSetupGrid2CUDA<<<numBlocksNB,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + initCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0); + cudaDeviceSynchronize(); + checkCudaDevice; + } + } + + //data.setLike(dofVector.getData()); + //cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + //data.save("u-00001.tnl"); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + // 1 - with curve, 2 - to the north of curve, 4 - to the south of curve, + // 8 - to the east of curve, 16 - to the west of curve. + int subgridID = i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * statusGridSize; + if(cudaStatusVector[subgridID] != 0 && i<Mesh.getDimensions().x() && j < Mesh.getDimensions().y()) + { + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real value = cudaDofVector2[Entity.getIndex()]; + Real a,b, tmp; + + if( i == 0 /*|| (i/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 9))*/ ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 /*|| (i/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 17))*/ ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + { + a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] ); + } + + if( j == 0 /*|| (j/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 3))*/ ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( j == Mesh.getDimensions().y() - 1 /* || (j/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 5)) */) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + { + b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + // cudaDofVector2[Entity.getIndex()] = fabsMin(value, tmp); + atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp); + } + +} + + +__global__ void initCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + + + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + int gid = Entity.getIndex(); + + if(abs(cudaDofVector2[gid]) > 1.5*h) + cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector2[gid]); + +// if (i >0 && j > 0 && i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y()) +// { +// if(cudaDofVector2[gid]*cudaDofVector2[gid+1] <= 0 ) +// { +// cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; +// cudaDofVector2[gid+1] = sign(cudaDofVector2[gid+1])*0.5*h; +// } +// if( cudaDofVector2[gid]*cudaDofVector2[gid+Mesh.getDimensions().x()] <= 0 ) +// { +// cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; +// cudaDofVector2[gid+Mesh.getDimensions().x()] = sign(cudaDofVector2[gid+Mesh.getDimensions().x()])*0.5*h; +// } +// +// if(cudaDofVector2[gid]*cudaDofVector2[gid-1] <= 0 ) +// { +// cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; +// cudaDofVector2[gid-1] = sign(cudaDofVector2[gid-1])*0.5*h; +// } +// if( cudaDofVector2[gid]*cudaDofVector2[gid-Mesh.getDimensions().x()] <= 0 ) +// { +// cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; +// cudaDofVector2[gid-Mesh.getDimensions().x()] = sign(cudaDofVector2[gid-Mesh.getDimensions().x()])*0.5*h; +// } +// } + + +// + + + + + + +// if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() ) +// { +// if(cudaDofVector[Entity.getIndex()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1111(i,j); +// else +// setupSquare1110(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1101(i,j); +// else +// setupSquare1100(i,j); +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1011(i,j); +// else +// setupSquare1010(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1001(i,j); +// else +// setupSquare1000(i,j); +// } +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0111(i,j); +// else +// setupSquare0110(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0101(i,j); +// else +// setupSquare0100(i,j); +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0011(i,j); +// else +// setupSquare0010(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0001(i,j); +// else +// setupSquare0000(i,j); +// } +// } +// } +// +// } + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + //Real fy = abs(y); + + //Real tmpMin = Min(fx,abs(y)); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i) +{ + + + int gx = 0; + int gy = threadIdx.y; + //if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy) + // return; + int n = solver->Mesh.getDimensions().x(); + int blockCount = n/blockDim.y +1; + //int gid = solver->Mesh.getDimensions().x() * gy + gx; + //int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x(); + + //int id1 = gx+gy; + //int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy; + + if(blockIdx.x==0) + { + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==1) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==2) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==3) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + +} + + + + +__global__ void initSetupGridCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + __shared__ double u0; + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + +// printf("Hello from block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y); + if(threadIdx.x+threadIdx.y == 0) + { +// printf("Hello from block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y); + + if(blockIdx.x+blockIdx.y == 0) + *(solver->reinitialize) = 0; + + solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] = 0; + + u0 = solver->cudaDofVector2[(blockDim.y*blockIdx.y + 0)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + 0]; + } + __syncthreads(); + + double u = solver->cudaDofVector2[(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x]; + + if(u*u0 <=0.0) + atomicMax(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y]),1); + } +// if(threadIdx.x+threadIdx.y == 0) + +// printf("Bye from block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y); + + +} + + + +// run this with one thread per block +__global__ void initSetupGrid2CUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ +// printf("Hello\n"); + if(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] == 1) + { +// 1 - with curve, 2 - to the north of curve, 4 - to the south of curve, +// 8 - to the east of curve, 16 - to the west of curve. + if(blockIdx.x > 0) + { + atomicAdd(&(solver->cudaStatusVector[blockIdx.x - 1 + gridDim.x*blockIdx.y]), 16); + } + + if(blockIdx.x < gridDim.x - 1) + atomicAdd(&(solver->cudaStatusVector[blockIdx.x + 1 + gridDim.x*blockIdx.y]), 8); + + if(blockIdx.y > 0 ) + atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y - 1)]), 4); + + if(blockIdx.y < gridDim.y - 1) + atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y + 1)]), 2); + } + + +} + + + + + +__global__ void runNarrowBandCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, double tau) +{ + int gid = (blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x()+ threadIdx.x; + int i = threadIdx.x + blockIdx.x*blockDim.x; + int j = threadIdx.y + blockIdx.y*blockDim.y; + +// if(i+j == 0) +// printf("Hello\n"); + + int blockID = blockIdx.x + blockIdx.y*gridDim.x; /*i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE);*/ + + int status = solver->cudaStatusVector[blockID]; + + if(solver->Mesh.getDimensions().x() > i && solver->Mesh.getDimensions().y() > j) + { + + if(status != 0) + { + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(solver->Mesh); + Entity.setCoordinates(Containers::StaticVector<2,double>(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + double value = solver->cudaDofVector2[Entity.getIndex()]; + double xf,xb,yf,yb, grad, fu, a,b; + a = b = 0.0; + + if( i == 0 || (threadIdx.x == 0 && !(status & 9)) ) + { + xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] - value; + } + else if( i == solver->Mesh.getDimensions().x() - 1 || (threadIdx.x == blockDim.x - 1 && !(status & 17)) ) + { + xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()] - value; + } + else + { + xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + xf = solver-> cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] - value; + } + + if( j == 0 || (threadIdx.y == 0 && !(status & 3)) ) + { + yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ; + yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] - value; + } + else if( j == solver->Mesh.getDimensions().y() - 1 || (threadIdx.y == blockDim.y - 1 && !(status & 5)) ) + { + yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()] - value; + } + else + { + yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + yf = solver-> cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] - value; + } + __syncthreads(); + + + + + + if(sign(value) >= 0.0) + { + xf = solver->negativePart(xf); + + xb = solver->positivePart(xb); + + yf = solver->negativePart(yf); + + yb = solver->positivePart(yb); + + } + else + { + + xb = solver->negativePart(xb); + + xf = solver->positivePart(xf); + + yb = solver->negativePart(yb); + + yf = solver->positivePart(yf); + } + + + if(xb > xf) + a = xb*solver->Mesh.template getSpaceStepsProducts< -1, 0 >(); + else + a = xf*solver->Mesh.template getSpaceStepsProducts< -1, 0 >(); + + if(yb > yf) + b = yb*solver->Mesh.template getSpaceStepsProducts< 0, -1 >(); + else + b = yf*solver->Mesh.template getSpaceStepsProducts< 0, -1 >(); + + + +// grad = sqrt(0.5 * (xf*xf + xb*xb + yf*yf + yb*yb ) )*solver->Mesh.template getSpaceStepsProducts< -1, 0 >(); + + grad = sqrt(/*0.5 **/ (a*a + b*b ) ); + + fu = -1.0 * grad; + + if((tau*fu+value)*value <=0 ) + { + // 1 - with curve, 2 - to the north of curve, 4 - to the south of curve, + // 8 - to the east of curve, 16 - to the west of curve. + + if((threadIdx.x == 6 && !(status & 9)) && (blockIdx.x > 0) ) + atomicMax(solver->reinitialize,1); + else if((threadIdx.x == blockDim.x - 7 && !(status & 17)) && (blockIdx.x < gridDim.x - 1) ) + atomicMax(solver->reinitialize,1); + else if((threadIdx.y == 6 && !(status & 3)) && (blockIdx.y > 0) ) + atomicMax(solver->reinitialize,1); + else if((threadIdx.y == blockDim.y - 7 && !(status & 5)) && (blockIdx.y < gridDim.y - 1) ) + atomicMax(solver->reinitialize,1); + } + + solver->cudaDofVector2[Entity.getIndex()] += tau*fu; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); +} +#endif + + + + +#endif /* TNLNARROWBAND_IMPL_H_ */ diff --git a/examples/narrow-band/tnlNarrowBand2D_CUDA_v5_impl.h b/examples/narrow-band/tnlNarrowBand2D_CUDA_v5_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..2d1296058391a0685d9385047469acb41a40b765 --- /dev/null +++ b/examples/narrow-band/tnlNarrowBand2D_CUDA_v5_impl.h @@ -0,0 +1,1313 @@ +/*************************************************************************** + tnlNarrowBand2D_CUDA_v4_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLNARROWBAND2D_IMPL_H_ +#define TNLNARROWBAND2D_IMPL_H_ + +#define NARROWBAND_SUBGRID_SIZE 32 + +#include "tnlNarrowBand.h" + +__device__ +double fabsMin( double x, double y) +{ + double fx = abs(x); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; +} + +__device__ +double atomicFabsMin(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) )); + } while (assumed != old); + return __longlong_as_double(old); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return -arg; + return 0.0; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlNarrowBand< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand() +:dofVector(Mesh) +{ +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.template getSpaceStepsProducts< 1, 0 >(); + //Entity.refresh(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + tau = parameters.getParameter< double >( "tau" ); + + finalTime = parameters.getParameter< double >( "final-time" ); + + statusGridSize = ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE); +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaStatusVector), statusGridSize*statusGridSize*sizeof(int)); +// cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), statusGridSize*statusGridSize* sizeof(int)), cudaMemcpyHostToDevice); + + cudaMalloc(&reinitialize, sizeof(int)); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + + + cudaDeviceSynchronize(); + checkCudaDevice; +#endif + + int n = Mesh.getDimensions().x(); + + dim3 threadsPerBlock2(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE); + dim3 numBlocks2(statusGridSize ,statusGridSize); + initSetupGridCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + initSetupGrid2CUDA<<<numBlocks2,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + + /*dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1);*/ + initCUDA<<<numBlocks2,threadsPerBlock2>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + + cout << "Solver initialized." << endl; + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlockFS(1, 512); + dim3 numBlocksFS(4,1); + dim3 threadsPerBlockNB(NARROWBAND_SUBGRID_SIZE, NARROWBAND_SUBGRID_SIZE); + dim3 numBlocksNB(n/NARROWBAND_SUBGRID_SIZE + 1,n/NARROWBAND_SUBGRID_SIZE + 1); + + double time = 0.0; + int reinit = 0; + + cout << "Hi!" << endl; + runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0); + cudaDeviceSynchronize(); + checkCudaDevice; + cout << "Hi2!" << endl; + while(time < finalTime) + { + if(tau+time > finalTime) + tau=finalTime-time; + + runNarrowBandCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver,tau); + cudaDeviceSynchronize(); + checkCudaDevice; + + time += tau; + + + cudaMemcpy(&reinit, this->reinitialize, sizeof(int), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + checkCudaDevice; + if(reinit != 0 /*&& time != finalTime */) + { + cout << time << endl; + + initSetupGridCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + initSetupGrid2CUDA<<<numBlocksNB,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + initCUDA<<<numBlocksNB,threadsPerBlockNB>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + runCUDA<<<numBlocksFS,threadsPerBlockFS>>>(this->cudaSolver,0,0); + cudaDeviceSynchronize(); + checkCudaDevice; + } + } + + //data.setLike(dofVector.getData()); + //cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + //data.save("u-00001.tnl"); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + // 1 - with curve, 2 - to the north of curve, 4 - to the south of curve, + // 8 - to the east of curve, 16 - to the west of curve. + int subgridID = i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE); + if(/*cudaStatusVector[subgridID] != 0 &&*/ i<Mesh.getDimensions().x() && Mesh.getDimensions().y()) + { + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real value = cudaDofVector2[Entity.getIndex()]; + Real a,b, tmp; + + if( i == 0 /*|| (i/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 9)) */) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 /*|| (i/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 17)) */) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + { + a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] ); + } + + if( j == 0/* || (j/NARROWBAND_SUBGRID_SIZE == 0 && !(cudaStatusVector[subgridID] & 3)) */) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( j == Mesh.getDimensions().y() - 1 /* || (j/NARROWBAND_SUBGRID_SIZE == NARROWBAND_SUBGRID_SIZE - 1 && !(cudaStatusVector[subgridID] & 5))*/ ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + { + b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + // cudaDofVector2[Entity.getIndex()] = fabsMin(value, tmp); + atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp); + } + +} + + +__global__ void initCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + + + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + int gid = Entity.getIndex(); + + cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector2[gid]); + + if (i >0 && j > 0 && i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y()) + { + if(cudaDofVector2[gid]*cudaDofVector2[gid+1] <= 0 ) + { + cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; + cudaDofVector2[gid+1] = sign(cudaDofVector2[gid+1])*0.5*h; + } + if( cudaDofVector2[gid]*cudaDofVector2[gid+Mesh.getDimensions().x()] <= 0 ) + { + cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; + cudaDofVector2[gid+Mesh.getDimensions().x()] = sign(cudaDofVector2[gid+Mesh.getDimensions().x()])*0.5*h; + } + + if(cudaDofVector2[gid]*cudaDofVector2[gid-1] <= 0 ) + { + cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; + cudaDofVector2[gid-1] = sign(cudaDofVector2[gid-1])*0.5*h; + } + if( cudaDofVector2[gid]*cudaDofVector2[gid-Mesh.getDimensions().x()] <= 0 ) + { + cudaDofVector2[gid] = sign(cudaDofVector2[gid])*0.5*h; + cudaDofVector2[gid-Mesh.getDimensions().x()] = sign(cudaDofVector2[gid-Mesh.getDimensions().x()])*0.5*h; + } + } + + +// + + + + + + +// if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() ) +// { +// if(cudaDofVector[Entity.getIndex()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1111(i,j); +// else +// setupSquare1110(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1101(i,j); +// else +// setupSquare1100(i,j); +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1011(i,j); +// else +// setupSquare1010(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1001(i,j); +// else +// setupSquare1000(i,j); +// } +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0111(i,j); +// else +// setupSquare0110(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0101(i,j); +// else +// setupSquare0100(i,j); +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0011(i,j); +// else +// setupSquare0010(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0001(i,j); +// else +// setupSquare0000(i,j); +// } +// } +// } +// +// } + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + //Real fy = abs(y); + + //Real tmpMin = Min(fx,abs(y)); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i) +{ + + + int gx = 0; + int gy = threadIdx.y; + //if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy) + // return; + int n = solver->Mesh.getDimensions().x(); + int blockCount = n/blockDim.y +1; + //int gid = solver->Mesh.getDimensions().x() * gy + gx; + //int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x(); + + //int id1 = gx+gy; + //int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy; + + if(blockIdx.x==0) + { + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==1) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==2) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==3) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + +} + + + + +__global__ void initSetupGridCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + __shared__ double u0; + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + +// printf("Hello from block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y); + if(threadIdx.x+threadIdx.y == 0) + { +// printf("Hello from block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y); + + if(blockIdx.x+blockIdx.y == 0) + *(solver->reinitialize) = 0; + + solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] = 0; + + u0 = solver->cudaDofVector2[(blockDim.y*blockIdx.y + 0)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + 0]; + } + __syncthreads(); + + double u = solver->cudaDofVector2[(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x]; + + if(u*u0 <=0.0) + atomicMax(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y]),1); + } +// if(threadIdx.x+threadIdx.y == 0) + +// printf("Bye from block = %d, thread = %d, x = %d, y = %d\n", blockIdx.x + gridDim.x*blockIdx.y,(blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x() + blockDim.x*blockIdx.x + threadIdx.x, threadIdx.x, threadIdx.y); + + +} + + + +// run this with one thread per block +__global__ void initSetupGrid2CUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ +// printf("Hello\n"); + if(solver->cudaStatusVector[blockIdx.x + gridDim.x*blockIdx.y] == 1) + { +// 1 - with curve, 2 - to the north of curve, 4 - to the south of curve, +// 8 - to the east of curve, 16 - to the west of curve. + if(blockIdx.x > 0) + atomicAdd(&(solver->cudaStatusVector[blockIdx.x - 1 + gridDim.x*blockIdx.y]), 16); + + if(blockIdx.x < gridDim.x - 1) + atomicAdd(&(solver->cudaStatusVector[blockIdx.x + 1 + gridDim.x*blockIdx.y]), 8); + + if(blockIdx.y > 0 ) + atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y - 1)]), 4); + + if(blockIdx.y < gridDim.y - 1) + atomicAdd(&(solver->cudaStatusVector[blockIdx.x + gridDim.x*(blockIdx.y + 1)]), 2); + } + + +} + + + + + +__global__ void runNarrowBandCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, double tau) +{ + int gid = (blockDim.y*blockIdx.y + threadIdx.y)*solver->Mesh.getDimensions().x()+ threadIdx.x; + int i = threadIdx.x + blockIdx.x*blockDim.x; + int j = threadIdx.y + blockIdx.y*blockDim.y; + +// if(i+j == 0) +// printf("Hello\n"); + + int blockID = blockIdx.x + blockIdx.y*gridDim.x; /*i/NARROWBAND_SUBGRID_SIZE + (j/NARROWBAND_SUBGRID_SIZE) * ((Mesh.getDimensions().x() + NARROWBAND_SUBGRID_SIZE-1 ) / NARROWBAND_SUBGRID_SIZE);*/ + + int status = solver->cudaStatusVector[blockID]; + + if(solver->Mesh.getDimensions().x() > i && solver->Mesh.getDimensions().y() > j) + { + +// if(status != 0) + { + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(solver->Mesh); + Entity.setCoordinates(Containers::StaticVector<2,double>(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + double value = solver->cudaDofVector2[Entity.getIndex()]; + double xf,xb,yf,yb, grad, fu, a,b; + a = b = 0.0; + + if( i == 0 /*|| (threadIdx.x == 0 && !(status & 9)) */) + { + xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] - value; + } + else if( i == solver->Mesh.getDimensions().x() - 1 /*|| (threadIdx.x == blockDim.x - 1 && !(status & 17)) */) + { + xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + xf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()] - value; + } + else + { + xb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + xf = solver-> cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] - value; + } + + if( j == 0/* || (threadIdx.y == 0 && !(status & 3))*/ ) + { + yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ; + yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] - value; + } + else if( j == solver->Mesh.getDimensions().y() - 1 /*|| (threadIdx.y == blockDim.y - 1 && !(status & 5)) */) + { + yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + yf = solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()] - value; + } + else + { + yb = value - solver->cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + yf = solver-> cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] - value; + } + __syncthreads(); + + + + + + if(sign(value) > 0.0) + { + xf = solver->negativePart(xf); + + xb = solver->positivePart(xb); + + yf = solver->negativePart(yf); + + yb = solver->positivePart(yb); + + } + else + { + + xb = solver->negativePart(xb); + + xf = solver->positivePart(xf); + + yb = solver->negativePart(yb); + + yf = solver->positivePart(yf); + } + + + if(xb > xf) + a = xb*solver->Mesh.template getSpaceStepsProducts< -1, 0 >(); + else + a = xf*solver->Mesh.template getSpaceStepsProducts< -1, 0 >(); + + if(yb > yf) + b = yb*solver->Mesh.template getSpaceStepsProducts< 0, -1 >(); + else + b = yf*solver->Mesh.template getSpaceStepsProducts< 0, -1 >(); + + + +// grad = sqrt(0.5 * (xf*xf + xb*xb + yf*yf + yb*yb ) )*solver->Mesh.template getSpaceStepsProducts< -1, 0 >(); + + grad = sqrt(/*0.5 **/ (a*a + b*b ) ); + + fu = -1.0 * grad; + +// if((tau*fu+value)*value <=0 ) +// { +// // 1 - with curve, 2 - to the north of curve, 4 - to the south of curve, +// // 8 - to the east of curve, 16 - to the west of curve. +// +// if((threadIdx.x == 1 && !(status & 9)) && (blockIdx.x > 0) ) +// atomicMax(solver->reinitialize,1); +// else if((threadIdx.x == blockDim.x - 2 && !(status & 17)) && (blockIdx.x < gridDim.x - 1) ) +// atomicMax(solver->reinitialize,1); +// else if((threadIdx.y == 1 && !(status & 3)) && (blockIdx.y > 0) ) +// atomicMax(solver->reinitialize,1); +// else if((threadIdx.y == blockDim.y - 2 && !(status & 5)) && (blockIdx.y < gridDim.y - 1) ) +// atomicMax(solver->reinitialize,1); +// } + + solver->cudaDofVector2[Entity.getIndex()] += tau*fu; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); +} +#endif + + + + +#endif /* TNLNARROWBAND_IMPL_H_ */ diff --git a/examples/narrow-band/tnlNarrowBand2D_impl.h b/examples/narrow-band/tnlNarrowBand2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..8248baa0949862de6ebcee797e6916c9634de72e --- /dev/null +++ b/examples/narrow-band/tnlNarrowBand2D_impl.h @@ -0,0 +1,927 @@ +/*************************************************************************** + tnlNarrowBand2D_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLNARROWBAND2D_IMPL_H_ +#define TNLNARROWBAND2D_IMPL_H_ + +#include "tnlNarrowBand.h" + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlNarrowBand< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand() +:Entity(Mesh), + dofVector(Mesh), + dofVector2(Mesh) +{ +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + dofVector2.load(initialCondition); + + h = Mesh.template getSpaceStepsProducts< 1, 0 >(); + Entity.refresh(); + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + cout << "a" << endl; + return initGrid(); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().x();i++) + { + dofVector2[i]=INT_MAX*sign(dofVector[i]); + } + + for(int i = 0 ; i < Mesh.getDimensions().x()-1; i++) + { + for(int j = 0 ; j < Mesh.getDimensions().x()-1; j++) + { + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + neighbourEntities.refresh(Mesh,Entity.getIndex()); + + if(dofVector[this->Entity.getIndex()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1111(i,j); + else + setupSquare1110(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1101(i,j); + else + setupSquare1100(i,j); + } + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1011(i,j); + else + setupSquare1010(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1001(i,j); + else + setupSquare1000(i,j); + } + } + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0111(i,j); + else + setupSquare0110(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0101(i,j); + else + setupSquare0100(i,j); + } + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0011(i,j); + else + setupSquare0010(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0001(i,j); + else + setupSquare0000(i,j); + } + } + } + + } + } + cout << "a" << endl; + +// Real tmp = 0.0; +// Real ax=0.5/sqrt(2.0); +// +// if(!exactInput) +// { +// for(Index i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++) +// dofVector[i]=0.5*h*sign(dofVector[i]); +// } +// +// +// for(Index i = 1; i < Mesh.getDimensions().x()-1; i++) +// { +// for(Index j = 1; j < Mesh.getDimensions().y()-1; j++) +// { +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// } +// +// +// +// for(int i = 1; i < Mesh.getDimensions().x()-1; i++) +// { +// Index j = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// for(int i = 1; i < Mesh.getDimensions().x()-1; i++) +// { +// Index j = Mesh.getDimensions().y() - 1; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// for(int j = 1; j < Mesh.getDimensions().y()-1; j++) +// { +// Index i = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// for(int j = 1; j < Mesh.getDimensions().y()-1; j++) +// { +// Index i = Mesh.getDimensions().x() - 1; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// +// Index i = Mesh.getDimensions().x() - 1; +// Index j = Mesh.getDimensions().y() - 1; +// +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// +// +// +// j = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// +// +// +// i = 0; +// j = Mesh.getDimensions().y() -1; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// +// +// +// j = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + + //data.setLike(dofVector2.getData()); + //data=dofVector2.getData(); + //cout << data.getType() << endl; + dofVector2.save("u-00000.tnl"); + //dofVector2.getData().save("u-00000.tnl"); + + return true; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + +// data.setLike(dofVector2.getData()); +// data = dofVector2.getData(); +// cout << data.getType() << endl; + dofVector2.save("u-00001.tnl"); + //dofVector2.getData().save("u-00001.tnl"); + + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + Real value = dofVector2[Entity.getIndex()]; + Real a,b, tmp; + + if( i == 0 ) + a = dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = dofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + { + a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()], + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] ); + } + + if( j == 0 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + { + b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()], + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ); + } + + + if(fabs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + + dofVector2[Entity.getIndex()] = fabsMin(value, tmp); + +// if(dofVector2[Entity.getIndex()] > 1.0) +// cout << value << " " << tmp << " " << dofVector2[Entity.getIndex()] << endl; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = fabs(x); + Real fy = fabs(y); + + Real tmpMin = Min(fx,fy); + + if(tmpMin == fx) + return x; + else + return y; + +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +{ +// this->Entity.setCoordinates(CoordinatesType(i,j)); +// this->Entity.refresh(); +// auto neighbourEntities = Entity.getNeighbourEntities(); +// dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]); +// dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +{ +// this->Entity.setCoordinates(CoordinatesType(i,j)); +// this->Entity.refresh(); +// auto neighbourEntities = Entity.getNeighbourEntities(); +// dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]); +// dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); +} + + + + +#endif /* TNLNARROWBAND_IMPL_H_ */ diff --git a/examples/narrow-band/tnlNarrowBand3D_CUDA_impl.h b/examples/narrow-band/tnlNarrowBand3D_CUDA_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..ac8a023d7d93060f63858892c0541f5eda0ee706 --- /dev/null +++ b/examples/narrow-band/tnlNarrowBand3D_CUDA_impl.h @@ -0,0 +1,961 @@ +/*************************************************************************** + tnlNarrowBand2D_CUDA_v4_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLNARROWBAND3D_IMPL_H_ +#define TNLNARROWBAND3D_IMPL_H_ + +#include "tnlNarrowBand.h" + +//__device__ +//double fabsMin( double x, double y) +//{ +// double fx = abs(x); +// +// if(Min(fx,abs(y)) == fx) +// return x; +// else +// return y; +//} +// +//__device__ +//double atomicFabsMin(double* address, double val) +//{ +// unsigned long long int* address_as_ull = +// (unsigned long long int*)address; +// unsigned long long int old = *address_as_ull, assumed; +// do { +// assumed = old; +// old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(assumed,val) )); +// } while (assumed != old); +// return __longlong_as_double(old); +//} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlNarrowBand< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + this->h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(8, 8,8); + dim3 numBlocks(n/8 + 1, n/8 +1, n/8 +1); + + cudaDeviceSynchronize(); + checkCudaDevice; + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(1, 512); + dim3 numBlocks(8,1); + + + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0); + + cudaDeviceSynchronize(); + checkCudaDevice; + + cudaMemcpy(this->dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k) +{ + tnlGridEntity< tnlGrid< 3,double, tnlHost, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j,k)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity); + Real value = cudaDofVector2[Entity.getIndex()]; + Real a,b,c, tmp; + + if( i == 0 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + else + { + a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0 >()] ); + } + + if( j == 0 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0 >()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0 >()]; + else + { + b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0 >()] ); + } + + if( k == 0 ) + c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1 >()]; + else if( k == Mesh.getDimensions().z() - 1 ) + c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1 >()]; + else + { + c = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1 >()] ); + } + + Real hD = 3.0*h*h - 2.0*(a*a + b*b + c*c - a*b - a*c - b*c); + + if(hD < 0.0) + tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h; + else + tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) ); + + atomicFabsMin(&cudaDofVector2[Entity.getIndex()],tmp); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid(int i, int j, int k) +{ + tnlGridEntity< tnlGrid< 3,double, tnlHost, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j,k)); + Entity.refresh(); + int gid = Entity.getIndex(); + + if(abs(cudaDofVector[gid]) < 1.8*h) + cudaDofVector2[gid] = cudaDofVector[gid]; + else + cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]); + + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + if(Min(fx,abs(y)) == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlNarrowBand< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i) +{ + + int gx = 0; + int gy = threadIdx.y; + + int n = solver->Mesh.getDimensions().x(); + int blockCount = n/blockDim.y +1; + + if(blockIdx.x==0) + { + for(int gz = 0; gz < n;gz++) + { + gx = 0; + gy = threadIdx.y; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + __syncthreads(); + } + } + else if(blockIdx.x==1) + { + for(int gz = 0; gz < n;gz++) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==2) + { + + for(int gz = 0; gz < n;gz++) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==3) + { + for(int gz = 0; gz < n;gz++) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + + + + + else if(blockIdx.x==4) + { + for(int gz = n-1; gz > -1;gz--) + { + gx = 0; + gy = threadIdx.y; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==5) + { + for(int gz = n-1; gz > -1;gz--) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==6) + { + + for(int gz = n-1; gz > -1;gz--) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==7) + { + for(int gz = n-1; gz > -1;gz--) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + + + + +} + + +__global__ void initCUDA(tnlNarrowBand< tnlGrid< 3,double, tnlHost, int >, double, int >* solver) +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + int gz = blockDim.z*blockIdx.z + threadIdx.z; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && solver->Mesh.getDimensions().z() > gz) + { + solver->initGrid(gx,gy,gz); + } + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(INT_MAX,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(-INT_MAX,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +// +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = al-be; +// b=1.0; +// c=-al; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = al-be; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +// +// +// +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = al-be; +// b=1.0; +// c=-al; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = al-be; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +//} +#endif + + + + +#endif /* TNLNARROWBAND_IMPL_H_ */ diff --git a/examples/narrow-band/tnlNarrowBand3D_impl.h b/examples/narrow-band/tnlNarrowBand3D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..eb446d9d2831967e9016b3eaaf326baf6751ab7c --- /dev/null +++ b/examples/narrow-band/tnlNarrowBand3D_impl.h @@ -0,0 +1,307 @@ +/*************************************************************************** + tnlNarrowBand2D_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLNARROWBAND3D_IMPL_H_ +#define TNLNARROWBAND3D_IMPL_H_ + +#include "tnlNarrowBand.h" + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlNarrowBand< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: tnlNarrowBand() +:Entity(Mesh), + dofVector(Mesh), + dofVector2(Mesh) +{ +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + dofVector2.load(initialCondition); + + h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >(); + Entity.refresh(); + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; +// cout << "bla "<<endl; + return initGrid(); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().y()*Mesh.getDimensions().z();i++) + { + + if (abs(dofVector[i]) < 1.8*h) + dofVector2[i]=dofVector[i]; + else + dofVector2[i]=INT_MAX*sign(dofVector[i]); + } + + return true; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + + + + + + + + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + + dofVector2.save("u-00001.tnl"); + + cout << "bla 3"<<endl; + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k) +{ + this->Entity.setCoordinates(CoordinatesType(i,j,k)); + this->Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity); + Real value = dofVector2[Entity.getIndex()]; + Real a,b,c, tmp; + + if( i == 0 ) + a = dofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0>()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = dofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + else + { + a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0>()], + dofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0>()] ); + } + + if( j == 0 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0>()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0>()]; + else + { + b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0>()], + dofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0>()] ); + } + + if( k == 0 ) + c = dofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1>()]; + else if( k == Mesh.getDimensions().z() - 1 ) + c = dofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1>()]; + else + { + c = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1>()], + dofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1>()] ); + } + + Real hD = 3.0*h*h - 2.0*(a*a+b*b+c*c-a*b-a*c-b*c); + + if(hD < 0.0) + tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h; + else + tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) ); + + + dofVector2[Entity.getIndex()] = fabsMin(value, tmp); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = fabs(x); + Real fy = fabs(y); + + Real tmpMin = Min(fx,fy); + + if(tmpMin == fx) + return x; + else + return y; + +} + + + +#endif /* TNLNARROWBAND_IMPL_H_ */ diff --git a/examples/narrow-band/tnlNarrowBand_CUDA.h b/examples/narrow-band/tnlNarrowBand_CUDA.h new file mode 100644 index 0000000000000000000000000000000000000000..8da92f5fc570275c85ebba69113f0e59a4be7988 --- /dev/null +++ b/examples/narrow-band/tnlNarrowBand_CUDA.h @@ -0,0 +1,203 @@ +/*************************************************************************** + tnlNarrowBand_CUDA.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLNARROWBAND_H_ +#define TNLNARROWBAND_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> + +#include <functions/tnlMeshFunction.h> +#include <limits.h> +#include <core/tnlDevice.h> +#include <ctime> + + + + + +template< typename Mesh, + typename Real, + typename Index > +class tnlNarrowBand +{}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + tnlNarrowBand(); + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + bool run(); +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType positivePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType negativePart(const RealType arg) const; + +#ifdef HAVE_CUDA + __device__ bool initGrid(); + __device__ void updateValue(const Index i, const Index j); + __device__ void updateValue(const Index i, const Index j, double** sharedMem, const int k3); + __device__ Real fabsMin(const Real x, const Real y); + + tnlNarrowBand< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver; + double* cudaDofVector; + double* cudaDofVector2; + int* cudaStatusVector; + int counter; + int* reinitialize; + __device__ void setupSquare1000(Index i, Index j); + __device__ void setupSquare1100(Index i, Index j); + __device__ void setupSquare1010(Index i, Index j); + __device__ void setupSquare1001(Index i, Index j); + __device__ void setupSquare1110(Index i, Index j); + __device__ void setupSquare1101(Index i, Index j); + __device__ void setupSquare1011(Index i, Index j); + __device__ void setupSquare1111(Index i, Index j); + __device__ void setupSquare0000(Index i, Index j); + __device__ void setupSquare0100(Index i, Index j); + __device__ void setupSquare0010(Index i, Index j); + __device__ void setupSquare0001(Index i, Index j); + __device__ void setupSquare0110(Index i, Index j); + __device__ void setupSquare0101(Index i, Index j); + __device__ void setupSquare0011(Index i, Index j); + __device__ void setupSquare0111(Index i, Index j); +#endif + + MeshType Mesh; + +protected: + + int statusGridSize; + bool exactInput; + + tnlMeshFunction<MeshType> dofVector; + DofVectorType data; + + + RealType h, tau, finalTime; + + +}; + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + bool run(); + +#ifdef HAVE_CUDA + __device__ bool initGrid(int i, int j, int k); + __device__ void updateValue(const Index i, const Index j, const Index k); + __device__ void updateValue(const Index i, const Index j, const Index k, double** sharedMem, const int k3); + __device__ Real fabsMin(const Real x, const Real y); + + tnlNarrowBand< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver; + double* cudaDofVector; + double* cudaDofVector2; + int counter; +#endif + + MeshType Mesh; + +protected: + + + + bool exactInput; + + tnlMeshFunction<MeshType> dofVector; + DofVectorType data; + + RealType h; + + +}; + + + + + + + +#ifdef HAVE_CUDA +//template<int sweep_t> +__global__ void runCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i); +//__global__ void runCUDA(tnlNarrowBand< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i); + +__global__ void initCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver); + +__global__ void initSetupGridCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver); +__global__ void initSetupGrid2CUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver); +__global__ void initSetupGrid1_2CUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver); +__global__ void runNarrowBandCUDA(tnlNarrowBand< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, double tau); +//__global__ void initCUDA(tnlNarrowBand< tnlGrid< 3,double, tnlHost, int >, double, int >* solver); +#endif + + + +#include "tnlNarrowBand2D_CUDA_v4_impl.h" +// #include "tnlNarrowBand3D_CUDA_impl.h" + +#endif /* TNLNARROWBAND_H_ */ diff --git a/examples/navier-stokes/navierStokesBoundaryConditions_impl.h b/examples/navier-stokes/navierStokesBoundaryConditions_impl.h index c6674391bc24cd313f78b6c703c6d786d91a181f..3eb66e8555419614e134d0dc6370461336dc3301 100644 --- a/examples/navier-stokes/navierStokesBoundaryConditions_impl.h +++ b/examples/navier-stokes/navierStokesBoundaryConditions_impl.h @@ -31,11 +31,19 @@ navierStokesBoundaryConditions< Mesh >::navierStokesBoundaryConditions() template< typename Mesh > bool navierStokesBoundaryConditions< Mesh >::setup( const Config::ParameterContainer& parameters ) { +<<<<<<< HEAD + this -> maxInflowVelocity = parameters. getParameter< double >( "max-inflow-velocity" ); + //this -> maxOutflowVelocity = parameters. getParameter< double >( "max-outflow-velocity" ); + this -> startUp = parameters. getParameter< double >( "start-up" ); + this -> T = parameters. getParameter< double >( "T" ); + this -> R = parameters. getParameter< double >( "R" ); +======= this->maxInflowVelocity = parameters. getParameter< double >( "max-inflow-velocity" ); //this->maxOutflowVelocity = parameters. getParameter< double >( "max-outflow-velocity" ); this->startUp = parameters. getParameter< double >( "start-up" ); this->T = parameters. getParameter< double >( "T" ); this->R = parameters. getParameter< double >( "R" ); +>>>>>>> develop this->p0 = parameters. getParameter< double >( "p0" ); this->gamma = parameters. getParameter< double >( "gamma" ); return true; diff --git a/examples/navier-stokes/navierStokesSolverMonitor_impl.h b/examples/navier-stokes/navierStokesSolverMonitor_impl.h index 47e82e3bba940c430b5d16e377a6c1751a96b808..462d31257aabda14745385f13bb70a412b90c6ce 100644 --- a/examples/navier-stokes/navierStokesSolverMonitor_impl.h +++ b/examples/navier-stokes/navierStokesSolverMonitor_impl.h @@ -30,7 +30,11 @@ navierStokesSolverMonitor< Real, Index > :: navierStokesSolverMonitor() template< typename Real, typename Index > void navierStokesSolverMonitor< Real, Index > :: refresh() { +<<<<<<< HEAD + if( this -> verbose > 0 && this -> refresRate % this -> refreshRate == 0 ) +======= if( this->verbose > 0 && this->refresRate % this->refreshRate == 0 ) +>>>>>>> develop { std::cout << "V=( " << uMax << " , " << uAvg diff --git a/examples/transport-equation/CMakeLists.txt b/examples/transport-equation/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..9c4b587d180a06142149459094b3ca2e8c3e9150 --- /dev/null +++ b/examples/transport-equation/CMakeLists.txt @@ -0,0 +1,34 @@ +set( tnl_transport_equation_SOURCES + tnl-transport-equation.cpp + tnl-transport-equation.cu ) + +set( tnl_transport_equation_HEADERS + tnl-transport-equation.h + transportEquationBuildConfigTag.h + transportEquationProblem.h + transportEquationProblem_impl.h ) + + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE( tnl-transport-equation${debugExt} tnl-transport-equation.cu) + target_link_libraries( tnl-transport-equation${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} ) + CUDA_ADD_EXECUTABLE( tnl-transport-equation-eoc${debugExt} tnl-transport-equation-eoc.cu) + target_link_libraries( tnl-transport-equation-eoc${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} ) + +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE( tnl-transport-equation${debugExt} tnl-transport-equation.cpp) + target_link_libraries( tnl-transport-equation${debugExt} tnl${debugExt}-${tnlVersion} ) + ADD_EXECUTABLE( tnl-transport-equation-eoc${debugExt} tnl-transport-equation-eoc.cpp) + target_link_libraries( tnl-transport-equation-eoc${debugExt} tnl${debugExt}-${tnlVersion} ) +ENDIF( BUILD_CUDA ) + + +INSTALL( TARGETS tnl-transport-equation${debugExt} + tnl-transport-equation-eoc${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +INSTALL( FILES tnl-run-transport-equation + ${tnl_transport_equation_SOURCES} + ${tnl_transport_equation_HEADERS} + DESTINATION share/tnl-${tnlVersion}/examples/transport-equation ) diff --git a/examples/transport-equation/tnl-run-transport-equation b/examples/transport-equation/tnl-run-transport-equation new file mode 100644 index 0000000000000000000000000000000000000000..aa33723a4336b7c947c448e6486a2e324ef4edc7 --- /dev/null +++ b/examples/transport-equation/tnl-run-transport-equation @@ -0,0 +1,34 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-x 0.0 \ + --proportions-x 1.0 \ + --proportions-y 1.0 \ + --size-x 100 \ + --size-y 100 + +tnl-init --test-function heaviside-of-vector-norm \ + --output-file init.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.5 \ + --vector-norm-center-1 0.5 \ + --vector-norm-center-2 0.5 \ + --vector-norm-radius 0.2 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm false + +tnl-transport-equation --device host \ + --initial-condition init.tnl \ + --time-discretisation explicit \ + --time-step 1.0e-5 \ + --boundary-conditions-constant 0.0 \ + --discrete-solver euler \ + --snapshot-period 0.005 \ + --final-time 0.1 \ + --numerical-viscosity 1.0 \ + --velocity-field-0-constant 1.0 \ + --velocity-field-1-constant 1.0 \ + --velocity-field-2-constant 1.0 + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/transport-equation/tnl-run-transport-equation-eoc b/examples/transport-equation/tnl-run-transport-equation-eoc new file mode 100755 index 0000000000000000000000000000000000000000..ec08d44172fdb38be9d9349013871fce7e6a6abf --- /dev/null +++ b/examples/transport-equation/tnl-run-transport-equation-eoc @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-x 0.0 \ + --proportions-x 1.0 \ + --proportions-y 1.0 \ + --size-x 100 \ + --size-y 100 + +tnl-transport-equation-eoc --device host \ + --initial-condition heaviside-vector-norm \ + --heaviside-multiplicator 1.0 \ + --vector-norm-multiplicator -1.0 \ + --vector-norm-center-0 0.5 \ + --vector-norm-center-1 0.5 \ + --vector-norm-center-2 0.5 \ + --vector-norm-radius 0.2 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm false \ + --time-discretisation explicit \ + --time-step 1.0e-5 \ + --boundary-conditions-constant 0.0 \ + --discrete-solver euler \ + --snapshot-period 0.005 \ + --final-time 0.1 \ + --numerical-viscosity 1.0 \ + --velocity-field-0-constant 1.0 \ + --velocity-field-1-constant 1.0 \ + --velocity-field-2-constant 1.0 + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/transport-equation/tnl-transport-equation-eoc.cpp b/examples/transport-equation/tnl-transport-equation-eoc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..00e2e867a1c34e3a71073144e0209f15cba9c150 --- /dev/null +++ b/examples/transport-equation/tnl-transport-equation-eoc.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + tnl-transport-equation-eoc.cpp - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include "tnl-transport-equation-eoc.h" diff --git a/examples/transport-equation/tnl-transport-equation-eoc.cu b/examples/transport-equation/tnl-transport-equation-eoc.cu new file mode 100644 index 0000000000000000000000000000000000000000..9a17dc4e1f6297eb2c1ec04dca8dc67535c8a762 --- /dev/null +++ b/examples/transport-equation/tnl-transport-equation-eoc.cu @@ -0,0 +1,12 @@ +/*************************************************************************** + tnl-transport-equation-eoc.cu - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#include "tnl-transport-equation-eoc.h" diff --git a/examples/transport-equation/tnl-transport-equation-eoc.h b/examples/transport-equation/tnl-transport-equation-eoc.h new file mode 100644 index 0000000000000000000000000000000000000000..08f0a6fbeb66a74177d52584344af718a911a074 --- /dev/null +++ b/examples/transport-equation/tnl-transport-equation-eoc.h @@ -0,0 +1,145 @@ +/*************************************************************************** + tnl-transport-equation-eoc.h - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#include <TNL/tnlConfig.h> +#include <TNL/Solvers/Solver.h> +#include <TNL/Solvers/BuildConfigTags.h> +#include <TNL/Operators/DirichletBoundaryConditions.h> +#include <TNL/Operators/NeumannBoundaryConditions.h> +#include <TNL/Operators/Advection/LaxFridrichs.h> +#include <TNL/Functions/Analytic/Constant.h> +#include <TNL/Functions/Analytic/VectorNorm.h> +#include <TNL/Operators/Analytic/Heaviside.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/Meshes/Grid.h> +#include "transportEquationProblemEoc.h" +#include "transportEquationBuildConfigTag.h" + +using namespace TNL; + +typedef transportEquationBuildConfigTag BuildConfig; + +/**** + * Uncomment 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, + * especially 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( Config::ConfigDescription& config ) + { + config.addDelimiter( "Transport equation settings:" ); + config.addDelimiter( "Initial condition" ); + config.addEntry< String >( "initial-condition", "Set type of initial condition.", "heaviside-vector-norm" ); + config.addEntryEnum< String >( "heaviside-vector-norm" ); + Functions::Analytic::VectorNorm< 3, double >::configSetup( config, "vector-norm-" ); + Operators::Analytic::Heaviside< 3, double >::configSetup( config, "heaviside-" ); + Operators::Analytic::Shift< 3, double >::configSetup( config, "heaviside-" ); + + config.addDelimiter( "Velocity field" ); + config.addEntry< String >( "velocity-field", "Type of velocity field.", "constant" ); + config.addEntryEnum< String >( "constant" ); + Functions::VectorField< 3, Functions::Analytic::Constant< 3 > >::configSetup( config, "velocity-field-" ); + + config.addDelimiter( "Numerical scheme" ); + typedef Meshes::Grid< 3 > MeshType; + Operators::Advection::LaxFridrichs< MeshType >::configSetup( config ); + + config.addDelimiter( "Boundary conditions" ); + config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); + config.addEntryEnum< String >( "dirichlet" ); + config.addEntryEnum< String >( "neumann" ); + config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions.", 0.0 ); + } +}; + +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 const int Dimensions = MeshType::getMeshDimensions(); + + template< typename Problem > + static bool callSolverStarter( const Config::ParameterContainer& parameters ) + { + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + + template< typename DifferentialOperatorType > + static bool setBoundaryConditionsType( const Config::ParameterContainer& parameters ) + { + typedef Functions::Analytic::Constant< Dimensions, Real > ConstantFunctionType; + String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" ); + if( boundaryConditionsType == "dirichlet" ) + { + typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef transportEquationProblemEoc< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem; + return callSolverStarter< Problem >( parameters ); + } + if( boundaryConditionsType == "neumann" ) + { + typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef transportEquationProblemEoc< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem; + return callSolverStarter< Problem >( parameters ); + } + std::cerr << "Unknown boundary conditions type: " << boundaryConditionsType << "." << std::endl; + return false; + } + + template< typename VelocityFieldType > + static bool setDifferentialOperatorType( const Config::ParameterContainer& parameters ) + { + typedef Operators::Advection::LaxFridrichs< MeshType, Real, Index, VelocityFieldType > DifferentialOperatorType; + return setBoundaryConditionsType< DifferentialOperatorType >( parameters ); + } + + static bool setVelocityFieldType( const Config::ParameterContainer& parameters ) + { + String velocityFieldType = parameters.getParameter< String >( "velocity-field" ); + if( velocityFieldType == "constant" ) + { + typedef Functions::Analytic::Constant< Dimensions, RealType > VelocityFieldType; + return setDifferentialOperatorType< VelocityFieldType >( parameters ); + } + return false; + } + + static bool run( const Config::ParameterContainer& parameters ) + { + return setVelocityFieldType( parameters ); + } +}; + +int main( int argc, char* argv[] ) +{ + Solvers::Solver< advectionSetter, advectionConfig, BuildConfig > solver; + if( ! solver. run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + diff --git a/examples/transport-equation/tnl-transport-equation.cpp b/examples/transport-equation/tnl-transport-equation.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8cc396d31d0592dc8626c370015886f1d3b2dc4 --- /dev/null +++ b/examples/transport-equation/tnl-transport-equation.cpp @@ -0,0 +1,11 @@ +/*************************************************************************** + tnl-transport-equation.cpp - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include "tnl-transport-equation.h" diff --git a/examples/transport-equation/tnl-transport-equation.cu b/examples/transport-equation/tnl-transport-equation.cu new file mode 100644 index 0000000000000000000000000000000000000000..068984a891fdc9df2c58ad24ae7a5c9b87ef015d --- /dev/null +++ b/examples/transport-equation/tnl-transport-equation.cu @@ -0,0 +1,11 @@ +/*************************************************************************** + tnl-transport-equation.cu - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include "tnl-transport-equation.h" diff --git a/examples/transport-equation/tnl-transport-equation.h b/examples/transport-equation/tnl-transport-equation.h new file mode 100644 index 0000000000000000000000000000000000000000..ad9cc970a3000384cd4a49e5d369f1326c59453d --- /dev/null +++ b/examples/transport-equation/tnl-transport-equation.h @@ -0,0 +1,132 @@ +/*************************************************************************** + tnl-transport-equation.h - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#include <TNL/tnlConfig.h> +#include <TNL/Solvers/Solver.h> +#include <TNL/Solvers/BuildConfigTags.h> +#include <TNL/Operators/DirichletBoundaryConditions.h> +#include <TNL/Operators/NeumannBoundaryConditions.h> +#include <TNL/Operators/Advection/LaxFridrichs.h> +#include <TNL/Functions/Analytic/Constant.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/Meshes/Grid.h> +#include "transportEquationProblem.h" +#include "transportEquationBuildConfigTag.h" + +using namespace TNL; + +typedef transportEquationBuildConfigTag BuildConfig; + +/**** + * Uncomment 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, + * especially 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( Config::ConfigDescription& config ) + { + config.addDelimiter( "Transport equation settings:" ); + config.addEntry< String >( "velocity-field", "Type of velocity field.", "constant" ); + config.addEntryEnum< String >( "constant" ); + Functions::VectorField< 3, Functions::Analytic::Constant< 3 > >::configSetup( config, "velocity-field-" ); + + typedef Meshes::Grid< 3 > MeshType; + Operators::Advection::LaxFridrichs< MeshType >::configSetup( config ); + + config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "dirichlet"); + config.addEntryEnum< String >( "dirichlet" ); + config.addEntryEnum< String >( "neumann" ); + config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." ); + } +}; + +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 const int Dimensions = MeshType::getMeshDimensions(); + + template< typename Problem > + static bool callSolverStarter( const Config::ParameterContainer& parameters ) + { + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + + template< typename DifferentialOperatorType > + static bool setBoundaryConditionsType( const Config::ParameterContainer& parameters ) + { + typedef Functions::Analytic::Constant< Dimensions, Real > ConstantFunctionType; + String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" ); + if( boundaryConditionsType == "dirichlet" ) + { + typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef transportEquationProblem< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem; + return callSolverStarter< Problem >( parameters ); + } + if( boundaryConditionsType == "neumann" ) + { + typedef Operators::DirichletBoundaryConditions< MeshType, ConstantFunctionType, MeshType::getMeshDimensions(), Real, Index > BoundaryConditions; + typedef transportEquationProblem< MeshType, BoundaryConditions, ConstantFunctionType, DifferentialOperatorType > Problem; + return callSolverStarter< Problem >( parameters ); + } + std::cerr << "Unknown boundary conditions type: " << boundaryConditionsType << "." << std::endl; + return false; + } + + template< typename VelocityFieldType > + static bool setDifferentialOperatorType( const Config::ParameterContainer& parameters ) + { + typedef Operators::Advection::LaxFridrichs< MeshType, Real, Index, VelocityFieldType > DifferentialOperatorType; + return setBoundaryConditionsType< DifferentialOperatorType >( parameters ); + } + + static bool setVelocityFieldType( const Config::ParameterContainer& parameters ) + { + String velocityFieldType = parameters.getParameter< String >( "velocity-field" ); + if( velocityFieldType == "constant" ) + { + typedef Functions::Analytic::Constant< Dimensions, RealType > VelocityFieldType; + return setDifferentialOperatorType< VelocityFieldType >( parameters ); + } + return false; + } + + static bool run( const Config::ParameterContainer& parameters ) + { + return setVelocityFieldType( parameters ); + } +}; + +int main( int argc, char* argv[] ) +{ + Solvers::Solver< advectionSetter, advectionConfig, BuildConfig > solver; + if( ! solver. run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + diff --git a/examples/transport-equation/transportEquationBuildConfigTag.h b/examples/transport-equation/transportEquationBuildConfigTag.h new file mode 100644 index 0000000000000000000000000000000000000000..df87a06b2b818ec466449ccab911cbcccd8bfb4a --- /dev/null +++ b/examples/transport-equation/transportEquationBuildConfigTag.h @@ -0,0 +1,58 @@ +/*************************************************************************** + transportEquationBuildConfigTag.cpp - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Solvers/BuildConfigTags.h> + +namespace TNL { + +class transportEquationBuildConfigTag{}; + +namespace Solvers { + +/**** + * Turn off support for float and long double. + */ +template<> struct ConfigTagReal< transportEquationBuildConfigTag, float > { enum { enabled = false }; }; +template<> struct ConfigTagReal< transportEquationBuildConfigTag, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct ConfigTagIndex< transportEquationBuildConfigTag, short int >{ enum { enabled = false }; }; +template<> struct ConfigTagIndex< transportEquationBuildConfigTag, long int >{ enum { enabled = false }; }; + +/**** + * Use of Grid is enabled for allowed dimensions and Real, Device and Index types. + */ + +template< int Dimensions, typename Real, typename Device, typename Index > + struct ConfigTagMesh< transportEquationBuildConfigTag, Meshes::Grid< Dimensions, Real, Device, Index > > + { enum { enabled = ConfigTagDimensions< transportEquationBuildConfigTag, Dimensions >::enabled && + ConfigTagReal< transportEquationBuildConfigTag, Real >::enabled && + ConfigTagDevice< transportEquationBuildConfigTag, Device >::enabled && + ConfigTagIndex< transportEquationBuildConfigTag, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct ConfigTagTimeDiscretisation< transportEquationBuildConfigTag, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct ConfigTagTimeDiscretisation< transportEquationBuildConfigTag, SemiImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct ConfigTagTimeDiscretisation< transportEquationBuildConfigTag, ImplicitTimeDiscretisationTag >{ enum { enabled = true }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct ConfigTagExplicitSolver< transportEquationBuildConfigTag, Solvers::ExplicitEulerSolverTag >{ enum { enabled = true }; }; + +} // namespace Solvers +} // namespace TNL diff --git a/examples/advection/advectionProblem.h b/examples/transport-equation/transportEquationProblem.h similarity index 76% rename from examples/advection/advectionProblem.h rename to examples/transport-equation/transportEquationProblem.h index a44048c08c7899a47a8ee27a6f91a5d758eff1f4..8e7e164ab2688e600ad8a1578985a1f90d834138 100644 --- a/examples/advection/advectionProblem.h +++ b/examples/transport-equation/transportEquationProblem.h @@ -1,5 +1,14 @@ -#ifndef advectionPROBLEM_H_ -#define advectionPROBLEM_H_ +/*************************************************************************** + transportEquationProblem.h - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once #include <TNL/Problems/PDEProblem.h> #include <TNL/Functions/MeshFunction.h> @@ -12,12 +21,12 @@ namespace TNL { template< typename Mesh, typename BoundaryCondition, typename RightHandSide, - typename DifferentialOperator > -class advectionProblem: - public PDEProblem< Mesh, - typename DifferentialOperator::RealType, - typename Mesh::DeviceType, - typename DifferentialOperator::IndexType > + typename DifferentialOperator > +class transportEquationProblem: +public PDEProblem< Mesh, + typename DifferentialOperator::RealType, + typename Mesh::DeviceType, + typename DifferentialOperator::IndexType > { public: @@ -30,7 +39,9 @@ class advectionProblem: typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer; typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer; typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer; - + typedef typename DifferentialOperator::VelocityFieldType VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + using typename BaseType::MeshType; using typename BaseType::MeshPointer; using typename BaseType::DofVectorType; @@ -93,13 +104,11 @@ class advectionProblem: BoundaryConditionPointer boundaryConditionPointer; - RightHandSidePointer rightHandSidePointer; + RightHandSidePointer rightHandSidePointer; - String velocityType; + VelocityFieldPointer velocityField; }; } // namespace TNL -#include "advectionProblem_impl.h" - -#endif /* advectionPROBLEM_H_ */ +#include "transportEquationProblem_impl.h" diff --git a/examples/transport-equation/transportEquationProblemEoc.h b/examples/transport-equation/transportEquationProblemEoc.h new file mode 100644 index 0000000000000000000000000000000000000000..0f2c8ea3ae6749b2f5c3b9896c2f4a8b5ad35500 --- /dev/null +++ b/examples/transport-equation/transportEquationProblemEoc.h @@ -0,0 +1,95 @@ +/*************************************************************************** + transportEquationProblemEoc.h - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Problems/PDEProblem.h> +#include <TNL/Functions/MeshFunction.h> +#include <TNL/SharedPointer.h> +#include "transportEquationProblem.h" + +using namespace TNL::Problems; + +namespace TNL { + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +class transportEquationProblemEoc: +public transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator > +{ + public: + + typedef typename DifferentialOperator::RealType RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef typename DifferentialOperator::IndexType IndexType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + typedef transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator > BaseType; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + typedef SharedPointer< DifferentialOperator > DifferentialOperatorPointer; + typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer; + typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer; + typedef typename DifferentialOperator::VelocityFieldType VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + + + using typename BaseType::MeshType; + using typename BaseType::MeshPointer; + using typename BaseType::DofVectorType; + using typename BaseType::DofVectorPointer; + using typename BaseType::MeshDependentDataType; + using typename BaseType::MeshDependentDataPointer; + + //using BaseType::getExplicitRHS; + + static String getTypeStatic(); + + String getPrologHeader() const; + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + bool setInitialCondition( const Config::ParameterContainer& parameters, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ); + + /*template< typename Matrix > + bool setupLinearSystem( const MeshPointer& mesh, + Matrix& matrix ); + + bool makeSnapshot( const RealType& time, + const IndexType& step, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ); + + IndexType getDofs( const MeshPointer& mesh ) const; + + void bindDofs( const MeshPointer& mesh, + DofVectorPointer& dofs ); + + void getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& _u, + DofVectorPointer& _fu, + MeshDependentDataPointer& meshDependentData );*/ + + + protected: +}; + +} // namespace TNL + +#include "transportEquationProblemEoc_impl.h" + diff --git a/examples/transport-equation/transportEquationProblemEoc_impl.h b/examples/transport-equation/transportEquationProblemEoc_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..c238bc311b5ea0e25745eef64e58ad9d1e3caa57 --- /dev/null +++ b/examples/transport-equation/transportEquationProblemEoc_impl.h @@ -0,0 +1,151 @@ +/*************************************************************************** + transportEquationProblemEoc_impl.h - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/FileName.h> +#include <TNL/Matrices/MatrixSetter.h> +#include <TNL/Solvers/PDE/ExplicitUpdater.h> +#include <TNL/Solvers/PDE/LinearSystemAssembler.h> +#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h> +#include <TNL/Functions/Analytic/Paraboloid.h> +#include <TNL/Operators/Analytic/Heaviside.h> +#include <TNL/Operators/Analytic/Shift.h> + +#include "transportEquationProblem.h" + +namespace TNL { + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +String +transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getTypeStatic() +{ + return String( "transportEquationProblemEoc< " ) + Mesh :: getTypeStatic() + " >"; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +String +transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getPrologHeader() const +{ + return String( "Transport Equation EOC" ); +} + + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix ) +{ + if( ! this->velocityField->setup( meshPointer, parameters, prefix + "velocity-field-" ) || + ! this->differentialOperatorPointer->setup( meshPointer, parameters, prefix ) || + ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) ) + return false; + + /**** + * Render the exact solution + */ + const String& initialCondition = parameters.getParameter< String >( "initial-condition" ); + const double& finalTime = parameters.getParameter< double >( "final-time" ); + const double& snapshotPeriod = parameters.getParameter< double >( "snapshot-period" ); + static const int Dimensions = Mesh::getMeshDimensions(); + typedef typename MeshPointer::ObjectType MeshType; + typedef Functions::MeshFunction< MeshType > MeshFunction; + SharedPointer< MeshFunction > u( meshPointer ); + if( initialCondition == "heaviside-vector-norm" ) + { + typedef Functions::Analytic::VectorNorm< Dimensions, RealType > VectorNormType; + typedef Operators::Analytic::Heaviside< Dimensions, RealType > HeavisideType; + typedef Functions::OperatorFunction< HeavisideType, VectorNormType > InitialConditionType; + String velocityFieldType = parameters.getParameter< String >( "velocity-field" ); + if( velocityFieldType == "constant" ) + { + typedef Operators::Analytic::Shift< Dimensions, RealType > ShiftOperatorType; + typedef Functions::OperatorFunction< ShiftOperatorType, InitialConditionType > ExactSolutionType; + SharedPointer< ExactSolutionType, Devices::Host > exactSolution; + if( ! exactSolution->getFunction().setup( parameters, prefix + "vector-norm-" ) || + ! exactSolution->getOperator().setup( parameters, prefix + "heaviside-" ) ) + return false; + Containers::StaticVector< Dimensions, RealType > velocity; + for( int i = 0; i < Dimensions; i++ ) + velocity[ i ] = parameters.getParameter< double >( "velocity-field-" + String( i ) + "-constant" ); + + Functions::MeshFunctionEvaluator< MeshFunction, ExactSolutionType > evaluator; + RealType time( 0.0 ); + int step( 0 ); + exactSolution->getOperator().setShift( 0.0 * velocity ); + evaluator.evaluate( u, exactSolution, time ); + FileName fileName; + fileName.setFileNameBase( "exact-u-" ); + fileName.setExtension( "tnl" ); + fileName.setIndex( step ); + if( ! u->save( fileName.getFileName() ) ) + return false; + while( time < finalTime ) + { + time += snapshotPeriod; + if( time > finalTime ) + time = finalTime; + exactSolution->getOperator().setShift( time * velocity ); + std::cerr << time * velocity << std::endl; + std::cerr << exactSolution->getOperator().getShift() << std::endl; + evaluator.evaluate( u, exactSolution, time ); + fileName.setIndex( ++step ); + if( ! u->save( fileName.getFileName() ) ) + return false; + } + } + if( velocityFieldType == "rotation" ) + { + // TODO: implement this using RotationXY operator + } + } + + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +transportEquationProblemEoc< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setInitialCondition( const Config::ParameterContainer& parameters, + const MeshPointer& meshPointer, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ) +{ + this->bindDofs( meshPointer, dofs ); + //const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" ); + FileName fileName; + fileName.setFileNameBase( "exact-u-" ); + fileName.setExtension( "tnl" ); + fileName.setIndex( 0 ); + if( ! this->uPointer->boundLoad( fileName.getFileName() ) ) + { + std::cerr << "I am not able to load the initial condition from the file " << fileName.getFileName() << "." << std::endl; + return false; + } + return true; +} + +} // namespace TNL diff --git a/examples/transport-equation/transportEquationProblem_impl.h b/examples/transport-equation/transportEquationProblem_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..7e2023ad2fb39a2381b71ecca0705fa0d09ff56f --- /dev/null +++ b/examples/transport-equation/transportEquationProblem_impl.h @@ -0,0 +1,233 @@ +/*************************************************************************** + transportEquationProblem_impl.h - description + ------------------- + begin : Feb 10, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/FileName.h> +#include <TNL/Matrices/MatrixSetter.h> +#include <TNL/Solvers/PDE/ExplicitUpdater.h> +#include <TNL/Solvers/PDE/LinearSystemAssembler.h> +#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h> + +#include "transportEquationProblem.h" + +namespace TNL { + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +String +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getTypeStatic() +{ + return String( "transportEquationProblem< " ) + Mesh :: getTypeStatic() + " >"; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +String +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getPrologHeader() const +{ + return String( "Transport Equation" ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +writeProlog( Logger& logger, const Config::ParameterContainer& 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 +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix ) +{ + if( ! this->velocityField->setup( meshPointer, parameters, prefix + "velocity-field-" ) || + ! this->differentialOperatorPointer->setup( meshPointer, parameters, prefix ) || + ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +typename transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >::IndexType +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getDofs( const MeshPointer& 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 +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +bindDofs( const MeshPointer& meshPointer, + DofVectorPointer& dofVector ) +{ + const IndexType dofs = meshPointer->template getEntitiesCount< typename MeshType::Cell >(); + this->uPointer->bind( meshPointer, dofVector ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setInitialCondition( const Config::ParameterContainer& parameters, + const MeshPointer& meshPointer, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ) +{ + this->bindDofs( meshPointer, dofs ); + const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" ); + if( ! this->uPointer->boundLoad( initialConditionFile ) ) + { + std::cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << std::endl; + return false; + } + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > + template< typename Matrix > +bool +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +setupLinearSystem( const MeshPointer& mesh, + Matrix& matrix ) +{ + /*const IndexType dofs = this->getDofs( mesh ); + typedef typename Matrix::ObjectType::CompressedRowsLengthsVector CompressedRowsLengthsVectorType; + SharedPointer< CompressedRowsLengthsVectorType > rowLengths; + if( ! rowLengths->setSize( dofs ) ) + return false; + Matrices::MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowsLengthsVectorType > matrixSetter; + matrixSetter.template getCompressedRowsLengths< typename Mesh::Cell >( mesh, + differentialOperatorPointer, + boundaryConditionPointer, + rowLengths ); + matrix->setDimensions( dofs, dofs ); + if( ! matrix->setCompressedRowsLengths( *rowLengths ) ) + return false;*/ + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +bool +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +makeSnapshot( const RealType& time, + const IndexType& step, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ) +{ + std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl; + this->bindDofs( mesh, dofs ); + FileName fileName; + fileName.setFileNameBase( "u-" ); + fileName.setExtension( "tnl" ); + fileName.setIndex( step ); + if( ! dofs->save( fileName.getFileName() ) ) + return false; + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename DifferentialOperator > +void +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& _u, + DofVectorPointer& _fu, + MeshDependentDataPointer& meshDependentData ) +{ + /**** + * If you use an explicit solver like Euler or Merson, 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 = ::sqrt(mesh->template getEntitiesCount< Cell >()); + this->bindDofs( mesh, _u ); + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater; + SharedPointer< MeshFunctionType > u( mesh, _u ); + SharedPointer< MeshFunctionType > fu( mesh, _fu ); + differentialOperatorPointer->setTau(tau); + differentialOperatorPointer->setVelocityField( this->velocityField ); + explicitUpdater.template update< typename Mesh::Cell >( time, + mesh, + this->differentialOperatorPointer, + this->boundaryConditionPointer, + this->rightHandSidePointer, + u, + fu ); + /*BoundaryConditionsSetter< 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 +transportEquationProblem< Mesh, BoundaryCondition, RightHandSide, DifferentialOperator >:: +assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& _u, + Matrix& matrix, + DofVectorPointer& b, + MeshDependentDataPointer& meshDependentData ) +{ +} + +} // namespace TNL diff --git a/src/TNL/Config/ConfigEntryBase.h b/src/TNL/Config/ConfigEntryBase.h index 44b6d4e8f5b6a9abb848be88fd69b8ba7e81e4ff..f69729ef5aaaa0d8120307eecfc8608d12742dfc 100644 --- a/src/TNL/Config/ConfigEntryBase.h +++ b/src/TNL/Config/ConfigEntryBase.h @@ -43,8 +43,7 @@ struct ConfigEntryBase virtual void printEnumValues() const {}; - // TODO: Fix this -- uncommenting leads to SIGSEGV (for example in tnl-init) - //virtual ~ConfigEntryBase() {}; + virtual ~ConfigEntryBase() {}; }; } // namespace Config diff --git a/src/TNL/Config/ParameterContainer.h b/src/TNL/Config/ParameterContainer.h index 5f6df343000fe3a28eb1afe5edc1f54156ba451d..5ac93da80dfda6eac8333d6f08540ea6683f4d71 100644 --- a/src/TNL/Config/ParameterContainer.h +++ b/src/TNL/Config/ParameterContainer.h @@ -14,6 +14,7 @@ #include <TNL/Config/ConfigDescription.h> #include <TNL/mpi-supp.h> #include <TNL/param-types.h> +//#include <TNL/Debugging/StackBacktrace.h> namespace TNL { namespace Config { @@ -62,7 +63,7 @@ class ParameterContainer template< class T > bool getParameter( const String& name, T& value, - bool verbose = false ) const + bool verbose = true ) const { int i; const int size = parameters. getSize(); @@ -73,7 +74,10 @@ class ParameterContainer return true; } if( verbose ) + { std::cerr << "Missing parameter '" << name << "'." << std::endl; + throw(0); //PrintStackBacktrace; + } return false; } diff --git a/src/TNL/Containers/Algorithms/CudaReductionKernel.h b/src/TNL/Containers/Algorithms/CudaReductionKernel.h index e2ab7e2cebc348e0797cf11a88775a3e7b5c388d..98a8841a36917cbb420dd54ef25c619a699853fb 100644 --- a/src/TNL/Containers/Algorithms/CudaReductionKernel.h +++ b/src/TNL/Containers/Algorithms/CudaReductionKernel.h @@ -123,7 +123,7 @@ CudaReductionKernel( Operation operation, /*** * This runs in one warp so it is synchronized implicitly. - */ + */ if( tid < 32 ) { volatile ResultType* vsdata = sdata; @@ -132,6 +132,8 @@ CudaReductionKernel( Operation operation, operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 32 ] ); //printf( "4: tid %d data %f \n", tid, sdata[ tid ] ); } + // TODO: If blocksize == 32, the following does not work + // We do not check if tid < 16. Fix it!!! if( blockSize >= 32 ) { operation.commonReductionOnDevice( vsdata[ tid ], vsdata[ tid + 16 ] ); diff --git a/src/TNL/Containers/Array_impl.h b/src/TNL/Containers/Array_impl.h index 65c2bc58f487460137b3bc4996264552345ab062..e9d34f860fa6c0dcff23e9847c311a3fe4d85e45 100644 --- a/src/TNL/Containers/Array_impl.h +++ b/src/TNL/Containers/Array_impl.h @@ -22,6 +22,8 @@ namespace TNL { namespace Containers { +using namespace std; + template< typename Element, typename Device, typename Index > @@ -177,9 +179,9 @@ setSize( const Index size ) this->size = size; if( size > 0 && ! this->allocationPointer ) { - std::cerr << "I am not able to allocate new array with size " - << ( double ) this->size * sizeof( ElementType ) / 1.0e9 << " GB." << std::endl; - this->size = 0; + cerr << "I am not able to allocate new array with size " + << ( double ) this->size * sizeof( ElementType ) / 1.0e9 << " GB." << endl; + this -> size = 0; return false; } return true; @@ -299,7 +301,7 @@ Index Array< Element, Device, Index >:: getSize() const { - return this->size; + return this -> size; } template< typename Element, @@ -411,7 +413,7 @@ bool Array< Element, Device, Index >:: operator == ( const ArrayT& array ) const { - if( array. getSize() != this->getSize() ) + if( array. getSize() != this -> getSize() ) return false; if( this->getSize() == 0 ) return true; @@ -449,7 +451,7 @@ template< typename Element, __cuda_callable__ const Element* Array< Element, Device, Index > :: getData() const { - return this->data; + return this -> data; } template< typename Element, @@ -458,7 +460,7 @@ template< typename Element, __cuda_callable__ Element* Array< Element, Device, Index > :: getData() { - return this->data; + return this -> data; } template< typename Element, @@ -495,8 +497,8 @@ bool Array< Element, Device, Index > :: save( File& file ) const #endif if( this->size != 0 && ! ArrayIO< Element, Device, Index >::save( file, this->data, this->size ) ) { - std::cerr << "I was not able to save " << this->getType() - << " with size " << this->getSize() << std::endl; + cerr << "I was not able to save " << this->getType() + << " with size " << this -> getSize() << endl; return false; } return true; @@ -521,7 +523,7 @@ load( File& file ) #endif if( _size < 0 ) { - std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl; + cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << endl; return false; } setSize( _size ); @@ -529,8 +531,8 @@ load( File& file ) { if( ! ArrayIO< Element, Device, Index >::load( file, this->data, this->size ) ) { - std::cerr << "I was not able to load " << this->getType() - << " with size " << this->getSize() << std::endl; + cerr << "I was not able to load " << this->getType() + << " with size " << this -> getSize() << endl; return false; } } @@ -556,7 +558,7 @@ boundLoad( File& file ) #endif if( _size < 0 ) { - std::cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << std::endl; + cerr << "Error: The size " << _size << " of the file is not a positive number or zero." << endl; return false; } if( this->getSize() != 0 ) @@ -573,8 +575,8 @@ boundLoad( File& file ) { if( ! ArrayIO< Element, Device, Index >::load( file, this->data, this->size ) ) { - std::cerr << "I was not able to load " << this->getType() - << " with size " << this->getSize() << std::endl; + cerr << "I was not able to load " << this->getType() + << " with size " << this -> getSize() << endl; return false; } } @@ -591,14 +593,14 @@ boundLoad( const String& fileName ) File file; if( ! file. open( fileName, tnlReadMode ) ) { - std::cerr << "I am not bale to open the file " << fileName << " for reading." << std::endl; + cerr << "I am not bale to open the file " << fileName << " for reading." << endl; return false; } if( ! this->boundLoad( file ) ) return false; if( ! file. close() ) { - std::cerr << "An error occurred when I was closing the file " << fileName << "." << std::endl; + cerr << "An error occurred when I was closing the file " << fileName << "." << endl; return false; } return true; diff --git a/src/TNL/Containers/StaticVector.h b/src/TNL/Containers/StaticVector.h index 2b0e7c7fdeb013e47d578a4ff33053a05aecde2e..a75f34d3b88f0390caec5ea0e10bd60c810bb8f0 100644 --- a/src/TNL/Containers/StaticVector.h +++ b/src/TNL/Containers/StaticVector.h @@ -23,6 +23,8 @@ class StaticVector : public Containers::StaticArray< Size, Real > typedef StaticVector< Size, Real > ThisType; enum { size = Size }; + using Containers::StaticArray< Size, Real >::operator=; + __cuda_callable__ StaticVector(); @@ -36,6 +38,9 @@ class StaticVector : public Containers::StaticArray< Size, Real > //! Copy constructor __cuda_callable__ StaticVector( const StaticVector< Size, Real >& v ); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); static String getType(); @@ -85,6 +90,9 @@ class StaticVector : public Containers::StaticArray< Size, Real > __cuda_callable__ ThisType abs() const; + + __cuda_callable__ + Real lpNorm( const Real& p ) const; }; template< typename Real > @@ -94,7 +102,7 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real > typedef Real RealType; typedef StaticVector< 1, Real > ThisType; enum { size = 1 }; - + __cuda_callable__ StaticVector(); @@ -105,6 +113,9 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real > //! Copy constructor __cuda_callable__ StaticVector( const StaticVector< 1, Real >& v ); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); static String getType(); @@ -154,6 +165,9 @@ class StaticVector< 1, Real > : public Containers::StaticArray< 1, Real > __cuda_callable__ ThisType abs() const; + + __cuda_callable__ + Real lpNorm( const Real& p ) const; }; template< typename Real > @@ -163,7 +177,7 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real > typedef Real RealType; typedef StaticVector< 2, Real > ThisType; enum { size = 2 }; - + __cuda_callable__ StaticVector(); @@ -180,6 +194,9 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real > //! Copy constructor __cuda_callable__ StaticVector( const StaticVector< 2, Real >& v ); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); static String getType(); @@ -229,6 +246,9 @@ class StaticVector< 2, Real > : public Containers::StaticArray< 2, Real > __cuda_callable__ ThisType abs() const; + + __cuda_callable__ + Real lpNorm( const Real& p ) const; }; template< typename Real > @@ -238,7 +258,7 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real > typedef Real RealType; typedef StaticVector< 3, Real > ThisType; enum { size = 3 }; - + __cuda_callable__ StaticVector(); @@ -255,6 +275,9 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real > //! Copy constructor __cuda_callable__ StaticVector( const StaticVector< 3, Real >& v ); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); static String getType(); @@ -304,6 +327,9 @@ class StaticVector< 3, Real > : public Containers::StaticArray< 3, Real > __cuda_callable__ ThisType abs() const; + + __cuda_callable__ + Real lpNorm( const Real& p ) const; }; template< int Size, typename Real, typename Scalar > diff --git a/src/TNL/Containers/StaticVector1D_impl.h b/src/TNL/Containers/StaticVector1D_impl.h index a8e4151a352a71b455f7404977d3e347874a46d2..ab2391eddacb43a5667d7c82d9c120a940bb1e6e 100644 --- a/src/TNL/Containers/StaticVector1D_impl.h +++ b/src/TNL/Containers/StaticVector1D_impl.h @@ -33,6 +33,15 @@ StaticVector< 1, Real >::StaticVector( const StaticVector< 1, Real >& v ) { } +template< typename Real > +bool +StaticVector< 1, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + this->data[ 0 ] = parameters.getParameter< double >( prefix + "0" ); + return true; +} + template< typename Real > String StaticVector< 1, Real >::getType() { @@ -148,6 +157,14 @@ StaticVector< 1, Real >::abs() const return StaticVector< 1, Real >( TNL::abs( this->data[ 0 ] ) ); } +template< typename Real > +__cuda_callable__ +Real +StaticVector< 1, Real >::lpNorm( const Real& p ) const +{ + return TNL::abs( this->data[ 0 ] ); +} + #ifdef UNDEF //TEMPLATE_EXPLICIT_INSTANTIATION #ifndef HAVE_CUDA diff --git a/src/TNL/Containers/StaticVector2D_impl.h b/src/TNL/Containers/StaticVector2D_impl.h index 60b0ffa452d7c3eb8028b4f504d11b39645de5ef..d5f63f283129ae11e50fcdd4352cff91eda26ea3 100644 --- a/src/TNL/Containers/StaticVector2D_impl.h +++ b/src/TNL/Containers/StaticVector2D_impl.h @@ -49,6 +49,16 @@ StaticVector< 2, Real >::StaticVector( const StaticVector< 2, Real >& v ) { } +template< typename Real > +bool +StaticVector< 2, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + this->data[ 0 ] = parameters.getParameter< double >( prefix + "0" ); + this->data[ 1 ] = parameters.getParameter< double >( prefix + "1" ); + return true; +} + template< typename Real > String StaticVector< 2, Real >::getType() { @@ -177,6 +187,19 @@ StaticVector< 2, Real >::abs() const ::abs( this->data[ 1 ] ) ); } +template< typename Real > +__cuda_callable__ +Real +StaticVector< 2, Real >::lpNorm( const Real& p ) const +{ + if( p == 1.0 ) + return TNL::abs( this->data[ 0 ] ) + TNL::abs( this->data[ 1 ] ); + if( p == 2.0 ) + return std::sqrt( this->data[ 0 ] * this->data[ 0 ] + + this->data[ 1 ] * this->data[ 1 ] ); + return std::pow( std::pow( TNL::abs( this->data[ 0 ] ), p ) + + std::pow( TNL::abs( this->data[ 1 ] ), p ), 1.0 / p ); +} #ifdef UNDEF //TEMPLATE_EXPLICIT_INSTANTIATION @@ -195,3 +218,4 @@ extern template class StaticVector< 2, long double >; } // namespace Containers } // namespace TNL + diff --git a/src/TNL/Containers/StaticVector3D_impl.h b/src/TNL/Containers/StaticVector3D_impl.h index 91de4c92266453c7b5660b64644c6e5a89f3e049..68f5802e2772884305e3a6e6e50db913e1b8319d 100644 --- a/src/TNL/Containers/StaticVector3D_impl.h +++ b/src/TNL/Containers/StaticVector3D_impl.h @@ -47,6 +47,17 @@ StaticVector< 3, Real >::StaticVector( const StaticVector< 3, Real >& v ) { } +template< typename Real > +bool +StaticVector< 3, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + this->data[ 0 ] = parameters.getParameter< double >( prefix + "0" ); + this->data[ 1 ] = parameters.getParameter< double >( prefix + "1" ); + this->data[ 2 ] = parameters.getParameter< double >( prefix + "2" ); + return true; +} + template< typename Real > String StaticVector< 3, Real >::getType() { @@ -187,6 +198,25 @@ StaticVector< 3, Real >::abs() const ::abs( this->data[ 2 ] ) ); } +template< typename Real > +__cuda_callable__ +Real +StaticVector< 3, Real >::lpNorm( const Real& p ) const +{ + if( p == 1.0 ) + return TNL::abs( this->data[ 0 ] ) + + TNL::abs( this->data[ 1 ] ) + + TNL::abs( this->data[ 2 ] ); + if( p == 2.0 ) + return std::sqrt( this->data[ 0 ] * this->data[ 0 ] + + this->data[ 1 ] * this->data[ 1 ] + + this->data[ 2 ] * this->data[ 2 ] ); + return std::pow( std::pow( TNL::abs( this->data[ 0 ] ), p ) + + std::pow( TNL::abs( this->data[ 1 ] ), p ) + + std::pow( TNL::abs( this->data[ 2 ] ), p ), 1.0 / p ); +} + + #ifdef UNDEF //TEMPLATE_EXPLICIT_INSTANTIATION diff --git a/src/TNL/Containers/StaticVector_impl.h b/src/TNL/Containers/StaticVector_impl.h index 32b8f4b95ece7bdc9c6e0a435c072e17e58e8979..8c8d37b9c0c0e5b3f58a5f182f75f2837eddf156 100644 --- a/src/TNL/Containers/StaticVector_impl.h +++ b/src/TNL/Containers/StaticVector_impl.h @@ -10,6 +10,8 @@ #pragma once +#include <TNL/Config/ParameterContainer.h> + namespace TNL { namespace Containers { @@ -40,6 +42,17 @@ StaticVector< Size, Real >::StaticVector( const StaticVector< Size, Real >& v ) { } +template< int Size, typename Real > +bool +StaticVector< Size, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + for( int i = 0; i < Size; i++ ) + if( ! parameters.template getParameter< double >( prefix + String( i ), this->data[ i ] ) ) + return false; + return true; +} + template< int Size, typename Real > String StaticVector< Size, Real >::getType() { @@ -180,6 +193,30 @@ StaticVector< Size, Real >::abs() const return v; } +template< int Size, typename Real > +__cuda_callable__ +Real +StaticVector< Size, Real >::lpNorm( const Real& p ) const +{ + if( p == 1.0 ) + { + Real aux = TNL::abs( this->data[ 0 ] ); + for( int i = 1; i < Size; i++ ) + aux += TNL::abs( this->data[ i ] ); + return aux; + } + if( p == 2.0 ) + { + Real aux = this->data[ 0 ] * this->data[ 0 ]; + for( int i = 1; i < Size; i++ ) + aux += this->data[ i ] * this->data[ i ]; + return std::sqrt( aux ); + } + Real aux = std::pow( TNL::abs( this->data[ 0 ] ), p ); + for( int i = 1; i < Size; i++ ) + aux += std::pow( TNL::abs( this->data[ i ] ), p ); + return std::pow( aux, 1.0 / p ); +} template< int Size, typename Real, typename Scalar > __cuda_callable__ diff --git a/src/TNL/Debugging/StackBacktrace.h b/src/TNL/Debugging/StackBacktrace.h index 17e576fd7219e6da8b4b7e3bfc5beab4510d42cc..ee419922637899c7187e25d187abc6a427ebff68 100644 --- a/src/TNL/Debugging/StackBacktrace.h +++ b/src/TNL/Debugging/StackBacktrace.h @@ -18,6 +18,7 @@ namespace TNL { namespace Debugging { +#ifndef NDEBUG /* * Print a demangled stack backtrace of the caller function to FILE* out. * @@ -99,6 +100,13 @@ printStackBacktrace( FILE *out = stderr, unsigned int max_frames = 63 ) free(funcname); free(symbollist); } +#endif } // namespace Debugging } // namespace TNL + +#ifdef NDEBUG +#define PrintStackBacktrace +#else +#define PrintStackBacktrace TNL::Debugging::printStackBacktrace(); +#endif diff --git a/src/TNL/Experimental/CMakeLists.txt b/src/TNL/Experimental/CMakeLists.txt index acb1a43c37120ab468bea9a3e1126c319d2dca92..47fc9efa44f92699b64e247af1778ad83e6cebfa 100755 --- a/src/TNL/Experimental/CMakeLists.txt +++ b/src/TNL/Experimental/CMakeLists.txt @@ -1,2 +1,3 @@ ADD_SUBDIRECTORY( Arithmetics ) ADD_SUBDIRECTORY( Multimaps ) +ADD_SUBDIRECTORY( Hamilton-Jacobi ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..538e5d99ccaacd6892be2a378da2f19349ec3fa4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/CMakeLists.txt @@ -0,0 +1,3 @@ +ADD_SUBDIRECTORY( Operators ) +#ADD_SUBDIRECTORY( Solvers ) + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..8ee63a0ac16a88e13ecb964013435160464e38b1 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/CMakeLists.txt @@ -0,0 +1 @@ +ADD_SUBDIRECTORY( Hamilton-Jacobi ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..bce61025f2bae120464881216c62091e40604836 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY( Godunov ) +ADD_SUBDIRECTORY( Godunov-Eikonal ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..202550179b61cbf4a47bca43f96f751d0e2510eb --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/CMakeLists.txt @@ -0,0 +1,18 @@ +set( headers godunov.h + godunov1D_impl.h + godunov2D_impl.h + godunov3D_impl.h) + +SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/operators/godunov ) + +if( BUILD_CUDA) + set( tnl_implementation_operators_godunov_CUDA__SOURCES + ${common_SOURCES} + PARENT_SCOPE ) +endif() + +set( tnl_implementation_operators_godunov_SOURCES + ${common_SOURCES} + PARENT_SCOPE ) + +INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/implementation/operators/godunov ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/godunovEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/godunovEikonal.h new file mode 100644 index 0000000000000000000000000000000000000000..a90c7258438a52c0afebf2d0e9838e1491f16a13 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Eikonal/godunovEikonal.h @@ -0,0 +1,264 @@ +/*************************************************************************** + godunov.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <mesh/tnlGrid.h> + +template< typename Mesh, + typename Real, + typename Index > +class godunovEikonalScheme +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + static String getType(); + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& f ) const + { + const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& u_c = u[ entity.getIndex() ]; + const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1 >() ]; + const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1 >() ]; + + if( f > 0.0 ) + { + RealType xf = negativePart( ( u_e - u_c ) * hx_inv ); + RealType xb = positivePart( ( u_c - u_w ) * hx_inv ); + + if( xb + xf > 0.0 ) + xf = 0.0; + else + xb = 0.0; + + return sqrt( xf * xf + xb * xb ); + } + else if( f < 0.0 ) + { + RealType xf = positivePart( ( u_e - u_c ) * hx_inv ); + RealType xb = negativePart( ( u_c - u_w ) * hx_inv ); + + if( xb + xf > 0.0 ) + xb = 0.0; + else + xf = 0.0; + + return sqrt( xf * xf + xb * xb ); + + } + else + { + return 0.0; + } + } +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + static String getType(); + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& f ) const + { + const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& u_c = u[ entity.getIndex() ]; + const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1, 0 >() ]; + const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1, 0 >() ]; + const RealType& u_n = u[ neighbourEntities.template getEntityIndex< 0, 1 >() ]; + const RealType& u_s = u[ neighbourEntities.template getEntityIndex< 0, -1 >() ]; + + if( f > 0.0 ) + { + RealType xf = negativePart( ( u_e - u_c ) * hx_inv ); + RealType xb = positivePart( ( u_c - u_w ) * hx_inv ); + RealType yf = negativePart( ( u_n - u_c ) * hy_inv ); + RealType yb = positivePart( ( u_c - u_s ) * hy_inv ); + + if( xb + xf > 0.0 ) + xf = 0.0; + else + xb = 0.0; + + if( yb + yf > 0.0 ) + yf = 0.0; + else + yb = 0.0; + + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb ); + } + else if( f < 0.0 ) + { + RealType xf = positivePart( ( u_e - u_c ) * hx_inv ); + RealType xb = negativePart( ( u_c - u_w ) * hx_inv ); + RealType yf = positivePart( ( u_n - u_c ) * hy_inv ); + RealType yb = negativePart( ( u_c - u_s ) * hy_inv ); + + if( xb + xf > 0.0 ) + xb = 0.0; + else + xf = 0.0; + + if( yb + yf > 0.0 ) + yb = 0.0; + else + yf = 0.0; + + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb ); + + } + else + { + return 0.0; + } + } +}; + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + static String getType(); + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& f ) const + { + const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hz_inv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& u_c = u[ entity.getIndex() ]; + const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ]; + const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ]; + const RealType& u_n = u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ]; + const RealType& u_s = u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ]; + const RealType& u_t = u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ]; + const RealType& u_b = u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ]; + + if( f > 0.0 ) + { + RealType xf = negativePart( ( u_e - u_c ) * hx_inv ); + RealType xb = positivePart( ( u_c - u_w ) * hx_inv ); + RealType yf = negativePart( ( u_n - u_c ) * hy_inv ); + RealType yb = positivePart( ( u_c - u_s ) * hy_inv ); + RealType zf = negativePart( ( u_t - u_c ) * hz_inv ); + RealType zb = positivePart( ( u_c - u_b ) * hz_inv ); + + if( xb + xf > 0.0 ) + xf = 0.0; + else + xb = 0.0; + + if( yb + yf > 0.0 ) + yf = 0.0; + else + yb = 0.0; + + if( zb + zf > 0.0 ) + zf = 0.0; + else + zb = 0.0; + + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb ); + } + else if( f < 0.0 ) + { + RealType xf = positivePart( ( u_e - u_c ) * hx_inv ); + RealType xb = negativePart( ( u_c - u_w ) * hx_inv ); + RealType yf = positivePart( ( u_n - u_c ) * hy_inv ); + RealType yb = negativePart( ( u_c - u_s ) * hy_inv ); + RealType zf = positivePart( ( u_t - u_c ) * hz_inv ); + RealType zb = negativePart( ( u_c - u_b ) * hz_inv ); + + if( xb + xf > 0.0 ) + xb = 0.0; + else + xf = 0.0; + + if( yb + yf > 0.0 ) + yb = 0.0; + else + yf = 0.0; + + if( zb + zf > 0.0 ) + zb = 0.0; + else + zf = 0.0; + + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb ); + } + else + { + return 0.0; + } + } +}; diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..8b74f755ed0a74e7001f1c155c60f61c650679d2 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/CMakeLists.txt @@ -0,0 +1,24 @@ +set( headers godunovEikonal.h + parallelGodunovEikonal.h + parallelGodunovMap.h + godunovEikonal1D_impl.h + godunovEikonal2D_impl.h + godunovEikonal3D_impl.h + parallelGodunovEikonal1D_impl.h + parallelGodunovEikonal2D_impl.h + parallelGodunovEikonal3D_impl.h + parallelGodunovMap2D_impl.h) + +SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/operators/godunov-eikonal ) + +if( BUILD_CUDA) + set( tnl_implementation_operators_godunov-eikonal_CUDA__SOURCES + ${common_SOURCES} + PARENT_SCOPE ) +endif() + +set( tnl_implementation_operators_godunov-eikonal_SOURCES + ${common_SOURCES} + PARENT_SCOPE ) + +INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/implementation/operators/godunov-eikonal ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal.h new file mode 100644 index 0000000000000000000000000000000000000000..d4941ba38a992fd76047a7ead2f538b79af2f079 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal.h @@ -0,0 +1,186 @@ +/*************************************************************************** + godunov.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <matrices/tnlCSRMatrix.h> +#include <solvers/preconditioners/tnlDummyPreconditioner.h> +#include <solvers/tnlSolverMonitor.h> +#include <core/tnlLogger.h> +#include <core/vectors/tnlVector.h> +#include <core/vectors/tnlSharedVector.h> +#include <core/mfilename.h> +#include <mesh/tnlGrid.h> + + +template< typename Mesh, + typename Real, + typename Index > +class godunovEikonalScheme +{ +}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + + static String getType(); + + RealType positivePart(const RealType arg) const; + + RealType negativePart(const RealType arg) const; + + RealType sign(const RealType x, const RealType eps) const; + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + bool init( const Config::ParameterContainer& parameters ); + + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType h; + + RealType epsilon; + + +}; + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + static String getType(); + + RealType positivePart(const RealType arg) const; + + RealType negativePart(const RealType arg) const; + + RealType sign(const RealType x, const Real eps) const; + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + bool init( const Config::ParameterContainer& parameters ); + + protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx; + RealType hy; + + RealType epsilon; +}; + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + static String getType(); + + RealType positivePart(const RealType arg) const; + + RealType negativePart(const RealType arg) const; + + RealType sign(const RealType x, const Real eps) const; + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const; + + + bool init( const Config::ParameterContainer& parameters ); + + + protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx; + RealType hy; + RealType hz; + + RealType epsilon; + +}; + +#include <operators/hamilton-jacobi/godunov-eikonal/godunovEikonal1D_impl.h> +#include <operators/hamilton-jacobi/godunov-eikonal/godunovEikonal2D_impl.h> +#include <operators/hamilton-jacobi/godunov-eikonal/godunovEikonal3D_impl.h> + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal1D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..308cfe93e7292e3660d305e9bd91e7e7b72716c5 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal1D_impl.h @@ -0,0 +1,165 @@ +/*************************************************************************** + godunov1D_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if(eps == 0.0) + return 0.0; + + return sin( ( M_PI * x ) / (2 * eps) ); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool godunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + + + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + h = originalMesh.template getSpaceSteps().x(); + cout << "h = " << h << endl; + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=h; + + /*dofVector. setSize( this->mesh.getDofs() );*/ + + return true; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String godunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "godunovEikonalScheme< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real godunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time ) const +{ +/* + RealType nabla, xb, xf, signui; + + signui = sign(u[cellIndex],epsilon); + + if(signui > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return signui*(1.0 - nabla); + } + else if (signui < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return signui*(1.0 - nabla); + } + else +*/ { + return 0.0; + } + +} + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..2b4dfdcef01ac7adec0be39f0b8f088bfbed758a --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal2D_impl.h @@ -0,0 +1,186 @@ +/*************************************************************************** + godunov2D_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOVEIKONAL2D_IMPL_H_ +#define GODUNOVEIKONAL2D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if ( eps == 0.0) + return 0.0; + + return sin((M_PI*x)/(2.0*eps)); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool godunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + + + hx = originalMesh.template getSpaceStepsProducts< 1, 0 >(); + hy = originalMesh.template getSpaceStepsProducts< 0, 1 >(); + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=sqrt( hx*hx + hy*hy ); + +// dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String godunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlLinearDiffusion< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real godunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time ) const +{ +/* + RealType nabla, xb, xf, yb, yf, signui; + + signui = sign(u[cellIndex],epsilon); + + if(signui > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + if(yb + yf > 0.0) + yf = 0.0; + else + yb = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); + + return signui*(1.0 - nabla); + } + else if (signui < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + if(yb + yf > 0.0) + yb = 0.0; + else + yf = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); + + return signui*(1.0 - nabla); + } + else +*/ { + return 0.0; + } + +} + + +#endif /* GODUNOVEIKONAL2D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal3D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..2d5bd0442a0ecd9c920df520cb41ccd8f83b7932 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/godunovEikonal3D_impl.h @@ -0,0 +1,196 @@ +/*************************************************************************** + godunov3D_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOVEIKONAL3D_IMPL_H_ +#define GODUNOVEIKONAL3D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if ( eps == 0.0) + return 0.0; + + return sin((M_PI*x)/(2.0*eps)); +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool godunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + hx = originalMesh.getSpaceSteps().x(); + hy = originalMesh.getSpaceSteps().y(); + hz = originalMesh.getSpaceSteps().z(); + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=sqrt( hx*hx + hy*hy +hz*hz ); + + // dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String godunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlLinearDiffusion< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real godunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time ) const +{ +/* + RealType nabla, xb, xf, yb, yf, zb, zf, signui; + + signui = sign(u[cellIndex],epsilon); + + if(signui > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + zf = negativePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz); + zb = positivePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + if(yb + yf > 0.0) + yf = 0.0; + else + yb = 0.0; + + if(zb + zf > 0.0) + zf = 0.0; + else + zb = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb ); + + return signui*(1.0 - nabla); + } + else if (signui < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + zf = positivePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz); + zb = negativePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + if(yb + yf > 0.0) + yb = 0.0; + else + yf = 0.0; + + if(zb + zf > 0.0) + zb = 0.0; + else + zf = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb ); + + return signui*(1.0 - nabla); + } + else +*/ { + return 0.0; + } + +} + + +#endif /* GODUNOVEIKONAL3D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal.h new file mode 100644 index 0000000000000000000000000000000000000000..e2f1859231a8096ae38e0dcaff664f490efa5cfc --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal.h @@ -0,0 +1,269 @@ +/*************************************************************************** + parallelGodunovEikonal.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PARALLELGODUNOVEIKONAL_H_ +#define PARALLELGODUNOVEIKONAL_H_ + +#include <matrices/tnlCSRMatrix.h> +#include <solvers/preconditioners/tnlDummyPreconditioner.h> +#include <solvers/tnlSolverMonitor.h> +#include <core/tnlLogger.h> +#include <core/vectors/tnlVector.h> +#include <core/vectors/tnlSharedVector.h> +#include <core/mfilename.h> +#include <mesh/tnlGrid.h> +#include <core/tnlCuda.h> +#include <mesh/grids/tnlGridEntity.h> + + +template< typename Mesh, + typename Real, + typename Index > +class parallelGodunovEikonalScheme +{ +}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + +#ifdef HAVE_CUDA + __device__ __host__ +#endif + static String getType(); +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType positivePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType negativePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType sign(const RealType x, const RealType eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + bool init( const Config::ParameterContainer& parameters ); + + RealType epsilon; + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType h; + + + + +}; + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + static String getType(); +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType positivePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType negativePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType sign(const RealType x, const Real eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities) const; + + #ifdef HAVE_CUDA + __device__ + #endif + Real getValueDev( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const RealType* u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + bool init( const Config::ParameterContainer& parameters ); + + RealType epsilon; + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx, ihx; + RealType hy, ihy; + + + + +}; + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + +#ifdef HAVE_CUDA + __device__ __host__ +#endif + static String getType(); +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType positivePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType negativePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType sign(const RealType x, const Real eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities ) const; + +#ifdef HAVE_CUDA + __device__ +#endif + Real getValueDev( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const RealType* u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities ) const; + +#ifdef HAVE_CUDA + __device__ __host__ +#endif + bool init( const Config::ParameterContainer& parameters ); + + RealType epsilon; + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx, ihx; + RealType hy, ihy; + RealType hz, ihz; + +}; + + + +//#include <operators/godunov-eikonal/parallelGodunovEikonal1D_impl.h> +#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovEikonal2D_impl.h> +#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovEikonal3D_impl.h> + + +#endif /* PARALLELGODUNOVEIKONAL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal1D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..b2e5c549fdf97c68ef3f4c4adf82e261dd85f576 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal1D_impl.h @@ -0,0 +1,170 @@ +/*************************************************************************** + parallelGodunovEikonal1D_impl.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PARALLELGODUNOVEIKONAL1D_IMPL_H_ +#define PARALLELGODUNOVEIKONAL1D_IMPL_H_ + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if(eps == 0.0) + return 0.0; + + return sin( ( M_PI * x ) / (2 * eps) ); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + + + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + h = originalMesh.template getSpaceStepsProducts< 1, 0 >(); + cout << "h = " << h << endl; + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=h; + + /*dofVector. setSize( this->mesh.getDofs() );*/ + + return true; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String parallelGodunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "parallelGodunovEikonalScheme< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time, + const IndexType boundaryCondition ) const +{ +/* + RealType nabla, xb, xf, signui; + + signui = sign(u[cellIndex],epsilon); + + if(signui > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return signui*(1.0 - nabla); + } + else if (signui < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return signui*(1.0 - nabla); + } + else +*/ { + return 0.0; + } + +} + + +#endif /* PARALLELGODUNOVEIKONAL1D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..29738ab330e3b951d6b8a9bd6be89b5606c0f5b0 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal2D_impl.h @@ -0,0 +1,484 @@ +/*************************************************************************** + parallelGodunovEikonal2D_impl.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PARALLELGODUNOVEIKONAL2D_IMPL_H_ +#define PARALLELGODUNOVEIKONAL2D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return -arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + if (x < -eps) + return (-1.0); + + if ( x == 0.0) + return 0.0; + + return sin(/*(M_PI*x)/(2.0*eps) */(M_PI/2.0)*(x/eps)); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +bool parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + + const String& meshFile = parameters.getParameter< String >( "mesh" ); + //MeshType originalMesh; + if( ! originalMesh.load( meshFile ) ) + { + //cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + + + hx = originalMesh.template getSpaceStepsProducts< 1, 0 >(); + ihx = 1.0/hx; + hy = originalMesh.template getSpaceStepsProducts< 0, 1 >(); + ihy = 1.0/hy; + + this->epsilon = parameters. getParameter< double >( "epsilon" ); + + this->epsilon *=sqrt( hx*hx + hy*hy ); + +// dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +String parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "parallelGodunovEikonalScheme< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities ) const +{ + + + if ( ((coordinates.x() == 0 && (boundaryCondition & 4)) or + (coordinates.x() == mesh.getDimensions().x() - 1 && (boundaryCondition & 2)) or + (coordinates.y() == 0 && (boundaryCondition & 8)) or + (coordinates.y() == mesh.getDimensions().y() - 1 && (boundaryCondition & 1))) + /*and + !( (coordinates.y() == 0 or coordinates.y() == mesh.getDimensions().y() - 1) + and + ( coordinates.x() == 0 or coordinates.x() == mesh.getDimensions().x() - 1) + )*/ + ) + { + return 0.0; + } + + + //----------------------------------- + + RealType signui; + signui = sign(u[cellIndex],this->epsilon); + + +#ifdef HAVE_CUDA + //printf("%d : %d ;;;; %d : %d , %f \n",threadIdx.x, mesh.getDimensions().x() , threadIdx.y,mesh.getDimensions().y(), epsilon ); +#endif + + RealType xb = u[cellIndex]; + RealType xf = -u[cellIndex]; + RealType yb = u[cellIndex]; + RealType yf = -u[cellIndex]; + RealType a,b,c; + + + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf += u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + xf += u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + + if(coordinates.x() == 0) + xb -= u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else + xb -= u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf += u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + yf += u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + + if(coordinates.y() == 0) + yb -= u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else + yb -= u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + + + //xb *= ihx; + //xf *= ihx; + // yb *= ihy; + //yf *= ihy; + + if(signui > 0.0) + { + xf = negativePart(xf); + + xb = positivePart(xb); + + yf = negativePart(yf); + + yb = positivePart(yb); + + } + else if(signui < 0.0) + { + + xb = negativePart(xb); + + xf = positivePart(xf); + + yb = negativePart(yb); + + yf = positivePart(yf); + } + + + if(xb - xf > 0.0) + a = xb; + else + a = xf; + + if(yb - yf > 0.0) + b = yb; + else + b = yf; + + c =(1.0 - sqrt(a*a+b*b)*ihx ); + + if(sign(c) > 0.0 ) + return sign(u[cellIndex])*c; + else + return signui*c; + + //-------------------------------------------------- + +// +// +// +// RealType acc = hx*hy*hx*hy; +// +// RealType nabla, xb, xf, yb, yf, signui; +// +// signui = sign(u[cellIndex],this->epsilon); +// +// +// //if(fabs(u[cellIndex]) < acc) return 0.0; +// +// if(signui > 0.0) +// { +// /**/ /* if(boundaryCondition & 2) +// xf = (u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx; +// else *//*if(boundaryCondition & 4) +// xf = 0.0; +// else /**/if(coordinates.x() == mesh.getDimensions().x() - 1) +// xf = negativePart((u[neighbourEntities.template getEntityIndex< -1, 0 >()] - u[cellIndex])*ihx); +// else +// xf = negativePart((u[neighbourEntities.template getEntityIndex< 1, 0 >()] - u[cellIndex])*ihx); +// +// /**/ /* if(boundaryCondition & 4) +// xb = (u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])*ihx; +// else *//*if(boundaryCondition & 2) +// xb = 0.0; +// else /**/if(coordinates.x() == 0) +// xb = positivePart((u[cellIndex] - u[mesh.template getCellNextToCell<+1,0>( cellIndex )])*ihx); +// else +// xb = positivePart((u[cellIndex] - u[neighbourEntities.template getEntityIndex< -1, 0 >()])*ihx); +// +// /**/ /* if(boundaryCondition & 1) +// yf = (u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])*ihy; +// else *//*if(boundaryCondition & 8) +// yf = 0.0; +// else /**/if(coordinates.y() == mesh.getDimensions().y() - 1) +// yf = negativePart((u[neighbourEntities.template getEntityIndex< 0, -1 >()] - u[cellIndex])*ihy); +// else +// yf = negativePart((u[neighbourEntities.template getEntityIndex< 0, 1 >()] - u[cellIndex])*ihy); +// +// /**/ /* if(boundaryCondition & 8) +// yb = (u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])*ihy; +// else *//*if(boundaryCondition & 1) +// yb = 0.0; +// else /**/if(coordinates.y() == 0) +// yb = positivePart((u[cellIndex] - u[neighbourEntities.template getEntityIndex< 0, 1 >()])*ihy); +// else +// yb = positivePart((u[cellIndex] - u[neighbourEntities.template getEntityIndex< 0, -1 >()])*ihy); +// +// if(xb - xf > 0.0) +// xf = 0.0; +// else +// xb = 0.0; +// +// if(yb - yf > 0.0) +// yf = 0.0; +// else +// yb = 0.0; +// +// nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); +// if(fabs(1.0-nabla) < acc) +// return 0.0; +// return signui*(1.0 - nabla); +// } +// else if (signui < 0.0) +// { +// +// /**/ /* if(boundaryCondition & 2) +// xf = (u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])*ihx; +// else*//* if(boundaryCondition & 4) +// xf = 0.0; +// else /**/if(coordinates.x() == mesh.getDimensions().x() - 1) +// xf = positivePart((u[neighbourEntities.template getEntityIndex< -1, 0 >()] - u[cellIndex])*ihx); +// else +// xf = positivePart((u[neighbourEntities.template getEntityIndex< 1, 0 >()] - u[cellIndex])*ihx); +// +// /**/ /* if(boundaryCondition & 4) +// xb = (u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])*ihx; +// else*//* if(boundaryCondition & 2) +// xb = 0.0; +// else /**/if(coordinates.x() == 0) +// xb = negativePart((u[cellIndex] - u[neighbourEntities.template getEntityIndex< 1, 0 >()])*ihx); +// else +// xb = negativePart((u[cellIndex] - u[neighbourEntities.template getEntityIndex< -1, 0 >()])*ihx); +// +// /**/ /* if(boundaryCondition & 1) +// yf = (u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])*ihy; +// else *//*if(boundaryCondition & 8) +// yf = 0.0; +// else /**/if(coordinates.y() == mesh.getDimensions().y() - 1) +// yf = positivePart((u[neighbourEntities.template getEntityIndex< 0, -1 >()] - u[cellIndex])*ihy); +// else +// yf = positivePart((u[neighbourEntities.template getEntityIndex< 0, 1 >()] - u[cellIndex])*ihy); +// +// /**/ /* if(boundaryCondition & 8) +// yb = (u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])*ihy; +// else*//* if(boundaryCondition & 1) +// yb = 0.0; +// else /**/if(coordinates.y() == 0) +// yb = negativePart((u[cellIndex] - u[neighbourEntities.template getEntityIndex< 0, 1 >()])*ihy); +// else +// yb = negativePart((u[cellIndex] - u[neighbourEntities.template getEntityIndex< 0, -1 >()])*ihy); +// +// +// if(xb - xf > 0.0) +// xf = 0.0; +// else +// xb = 0.0; +// +// if(yb - yf > 0.0) +// yf = 0.0; +// else +// yb = 0.0; +// +// nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); +// +// if(fabs(1.0-nabla) < acc) +// return 0.0; +// return signui*(1.0 - nabla); +// } +// else +// { +// return 0.0; +// } + +} + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + +#ifdef HAVE_CUDA +__device__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValueDev( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Real* u, + const Real& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities) const +{ + + RealType signui; + if(boundaryCondition == 0) + signui = sign(u[cellIndex],/*(boundaryCondition != 0) * */this->epsilon); + else + signui = sign(u[cellIndex]); + + RealType xb = u[cellIndex]; + RealType xf = -u[cellIndex]; + RealType yb = u[cellIndex]; + RealType yf = -u[cellIndex]; + RealType a,b/*,c*/; + + + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf += u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + xf += u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + + if(coordinates.x() == 0) + xb -= u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else + xb -= u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf += u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + yf += u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + + if(coordinates.y() == 0) + yb -= u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else + yb -= u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + + + if(signui > 0.0) + { + xf = negativePart(xf); + + xb = positivePart(xb); + + yf = negativePart(yf); + + yb = positivePart(yb); + + } + else if(signui < 0.0) + { + + xb = negativePart(xb); + + xf = positivePart(xf); + + yb = negativePart(yb); + + yf = positivePart(yf); + } + + + if(xb > xf) + a = xb; + else + a = xf; + + if(yb > yf) + b = yb; + else + b = yf; + +// c =(1.0 - sqrt(a*a+b*b)*ihx ); + +// if(c > 0.0 ) +// return sign(u[cellIndex])*c; +// else + return signui*(1.0 - sqrt(a*a+b*b)*ihx ); +} + + +#endif /* PARALLELGODUNOVEIKONAL2D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal3D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..3aa8aeed5357e7a4f0b0f176e9002c89a4295a84 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovEikonal3D_impl.h @@ -0,0 +1,370 @@ +/*************************************************************************** + parallelGodunovEikonal3D_impl.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PARALLELGODUNOVEIKONAL3D_IMPL_H_ +#define PARALLELGODUNOVEIKONAL3D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return -arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + if (x < -eps) + return (-1.0); + + if ( x == 0.0) + return 0.0; + + return sin((M_PI/2.0)*(x/eps)); +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + hx = originalMesh.template getSpaceStepsProducts< 1, 0, 0 >(); + hy = originalMesh.template getSpaceStepsProducts< 0, 1, 0 >(); + hz = originalMesh.template getSpaceStepsProducts< 0, 0, 1 >(); + ihx = 1.0/hx; + ihy = 1.0/hy; + ihz = 1.0/hz; + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=sqrt( hx*hx + hy*hy + hz*hz ); + + // dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlLinearDiffusion< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities ) const +{ + if ( ((coordinates.x() == 0 && (boundaryCondition & 4)) or + (coordinates.x() == mesh.getDimensions().x() - 1 && (boundaryCondition & 2)) or + (coordinates.y() == 0 && (boundaryCondition & 8)) or + (coordinates.y() == mesh.getDimensions().y() - 1 && (boundaryCondition & 1)) or + (coordinates.z() == 0 && (boundaryCondition & 32)) or + (coordinates.z() == mesh.getDimensions().y() - 1 && (boundaryCondition & 16))) + + ) + { + return 0.0; + } + + + //----------------------------------- + + RealType signui; + signui = sign(u[cellIndex], this->epsilon); + + + RealType xb = u[cellIndex]; + RealType xf = -u[cellIndex]; + RealType yb = u[cellIndex]; + RealType yf = -u[cellIndex]; + RealType zb = u[cellIndex]; + RealType zf = -u[cellIndex]; + RealType a,b,c,d; + + + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf += u[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + else + xf += u[neighbourEntities.template getEntityIndex< 1, 0, 0 >()]; + + if(coordinates.x() == 0) + xb -= u[neighbourEntities.template getEntityIndex< 1, 0, 0 >()]; + else + xb -= u[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf += u[neighbourEntities.template getEntityIndex< 0, -1, 0 >()]; + else + yf += u[neighbourEntities.template getEntityIndex< 0, 1, 0 >()]; + + if(coordinates.y() == 0) + yb -= u[neighbourEntities.template getEntityIndex< 0, 1, 0 >()]; + else + yb -= u[neighbourEntities.template getEntityIndex< 0, -1, 0 >()]; + + + if(coordinates.z() == mesh.getDimensions().z() - 1) + zf += u[neighbourEntities.template getEntityIndex< 0, 0, -1 >()]; + else + zf += u[neighbourEntities.template getEntityIndex< 0, 0, 1 >()]; + + if(coordinates.z() == 0) + zb -= u[neighbourEntities.template getEntityIndex< 0, 0, 1 >()]; + else + zb -= u[neighbourEntities.template getEntityIndex< 0, 0, -1 >()]; + + if(signui > 0.0) + { + xf = negativePart(xf); + + xb = positivePart(xb); + + yf = negativePart(yf); + + yb = positivePart(yb); + + zf = negativePart(zf); + + zb = positivePart(zb); + + } + else if(signui < 0.0) + { + + xb = negativePart(xb); + + xf = positivePart(xf); + + yb = negativePart(yb); + + yf = positivePart(yf); + + zb = negativePart(zb); + + zf = positivePart(zf); + } + + + if(xb - xf > 0.0) + a = xb; + else + a = xf; + + if(yb - yf > 0.0) + b = yb; + else + b = yf; + + if(zb - zf > 0.0) + c = zb; + else + c = zf; + + d = ( 1.0 - sqrt(a*a + b*b + c*c)*ihx ); + +// d = 1.0 - sqrt(xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb)*ihx; /*upwind*/ + + if(sign(d) > 0.0 ) + return sign(u[cellIndex])*d; + else + return signui*d; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + +#ifdef HAVE_CUDA +__device__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: getValueDev( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Real* u, + const Real& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities + ) const +{ + RealType signui; + signui = sign(u[cellIndex], this->epsilon); + + + RealType xb = u[cellIndex]; + RealType xf = -u[cellIndex]; + RealType yb = u[cellIndex]; + RealType yf = -u[cellIndex]; + RealType zb = u[cellIndex]; + RealType zf = -u[cellIndex]; + RealType a,b,c,d; + + + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf += u[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + else + xf += u[neighbourEntities.template getEntityIndex< 1, 0, 0 >()]; + + if(coordinates.x() == 0) + xb -= u[neighbourEntities.template getEntityIndex< 1, 0, 0 >()]; + else + xb -= u[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf += u[neighbourEntities.template getEntityIndex< 0, -1, 0 >()]; + else + yf += u[neighbourEntities.template getEntityIndex< 0, 1, 0 >()]; + + if(coordinates.y() == 0) + yb -= u[neighbourEntities.template getEntityIndex< 0, 1, 0 >()]; + else + yb -= u[neighbourEntities.template getEntityIndex< 0, -1, 0 >()]; + + + if(coordinates.z() == mesh.getDimensions().z() - 1) + zf += u[neighbourEntities.template getEntityIndex< 0, 0, -1 >()]; + else + zf += u[neighbourEntities.template getEntityIndex< 0, 0, 1 >()]; + + if(coordinates.z() == 0) + zb -= u[neighbourEntities.template getEntityIndex< 0, 0, 1 >()]; + else + zb -= u[neighbourEntities.template getEntityIndex< 0, 0, -1 >()]; + + if(signui > 0.0) + { + xf = negativePart(xf); + + xb = positivePart(xb); + + yf = negativePart(yf); + + yb = positivePart(yb); + + zf = negativePart(zf); + + zb = positivePart(zb); + + } + else if(signui < 0.0) + { + + xb = negativePart(xb); + + xf = positivePart(xf); + + yb = negativePart(yb); + + yf = positivePart(yf); + + zb = negativePart(zb); + + zf = positivePart(zf); + } + + + if(xb - xf > 0.0) + a = xb; + else + a = xf; + + if(yb - yf > 0.0) + b = yb; + else + b = yf; + + if(zb - zf > 0.0) + c = zb; + else + c = zf; + + d = ( 1.0 - sqrt(a*a + b*b + c*c)*ihx ); + + // d = 1.0 - sqrt(xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb)*ihx; /*upwind*/ + + if(sign(d) > 0.0 ) + return sign(u[cellIndex])*d; + else + return signui*d; +} + + +#endif /* PARALLELGODUNOVEIKONAL3D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap.h new file mode 100644 index 0000000000000000000000000000000000000000..db7a087224b933150fcda1ed47119d2e23448000 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap.h @@ -0,0 +1,271 @@ +/*************************************************************************** + parallelGodunovMap.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PARALLELGODUNOVMAP_H_ +#define PARALLELGODUNOVMAP_H_ + +#include <matrices/tnlCSRMatrix.h> +#include <solvers/preconditioners/tnlDummyPreconditioner.h> +#include <solvers/tnlSolverMonitor.h> +#include <core/tnlLogger.h> +#include <core/vectors/tnlVector.h> +#include <core/vectors/tnlSharedVector.h> +#include <core/mfilename.h> +#include <mesh/tnlGrid.h> +#include <core/tnlCuda.h> +#include <mesh/grids/tnlGridEntity.h> + + +template< typename Mesh, + typename Real, + typename Index > +class parallelGodunovMapScheme +{ +}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovMapScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + +#ifdef HAVE_CUDA + __device__ __host__ +#endif + static String getType(); +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType positivePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType negativePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType sign(const RealType x, const RealType eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + bool init( const Config::ParameterContainer& parameters ); + + RealType epsilon; + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType h; + + + + +}; + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + static String getType(); +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType positivePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType negativePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType sign(const RealType x, const Real eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities, + const Vector& map) const; + + #ifdef HAVE_CUDA + __device__ + #endif + Real getValueDev( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const RealType* u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities, + const RealType* map) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + bool init( const Config::ParameterContainer& parameters ); + + RealType epsilon; + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx, ihx; + RealType hy, ihy; + + + + +}; + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovMapScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + +#ifdef HAVE_CUDA + __device__ __host__ +#endif + static String getType(); +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType positivePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType negativePart(const RealType arg) const; +#ifdef HAVE_CUDA + __device__ __host__ +#endif + RealType sign(const RealType x, const Real eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities ) const; + +#ifdef HAVE_CUDA + __device__ +#endif + Real getValueDev( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const RealType* u, + const RealType& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities) const; + +#ifdef HAVE_CUDA + __device__ __host__ +#endif + bool init( const Config::ParameterContainer& parameters ); + + RealType epsilon; + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx, ihx; + RealType hy, ihy; + RealType hz, ihz; + +}; + + + +//#include <operators/godunov-eikonal/parallelGodunovMap1D_impl.h> +#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovMap2D_impl.h> +//#include <operators/godunov-eikonal/parallelGodunovMap3D_impl.h> + + +#endif /* PARALLELGODUNOVMAP_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..c5f7d613497e7f61b449a2e16190c18988a12c3f --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov-Eikonal/parallelGodunovMap2D_impl.h @@ -0,0 +1,391 @@ +/*************************************************************************** + parallelGodunovMap2D_impl.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef PARALLELGODUNOVMAP2D_IMPL_H_ +#define PARALLELGODUNOVMAP2D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return -arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +Real parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + if (x < -eps) + return (-1.0); + + if ( x == 0.0) + return 0.0; + + return sin(/*(M_PI*x)/(2.0*eps) */(M_PI/2.0)*(x/eps)); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +bool parallelGodunovMapScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + + const String& meshFile = parameters.getParameter< String >( "mesh" ); + //MeshType originalMesh; + if( ! originalMesh.load( meshFile ) ) + { + //cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + + + hx = originalMesh.template getSpaceStepsProducts< 1, 0 >(); + ihx = 1.0/hx; + hy = originalMesh.template getSpaceStepsProducts< 0, 1 >(); + ihy = 1.0/hy; + + this->epsilon = parameters. getParameter< double >( "epsilon" ); + + this->epsilon *=sqrt( hx*hx + hy*hy ); + +// dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +#ifdef HAVE_CUDA + __device__ __host__ +#endif +String parallelGodunovMapScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "parallelGodunovMapScheme< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real parallelGodunovMapScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities, + const Vector& map) const +{ + + + if ( ((coordinates.x() == 0 && (boundaryCondition & 4)) or + (coordinates.x() == mesh.getDimensions().x() - 1 && (boundaryCondition & 2)) or + (coordinates.y() == 0 && (boundaryCondition & 8)) or + (coordinates.y() == mesh.getDimensions().y() - 1 && (boundaryCondition & 1))) + /*and + !( (coordinates.y() == 0 or coordinates.y() == mesh.getDimensions().y() - 1) + and + ( coordinates.x() == 0 or coordinates.x() == mesh.getDimensions().x() - 1) + )*/ + ) + { + return 0.0; + } + + + RealType signui; +// if(boundaryCondition == 0) + signui = sign(u[cellIndex],/*(boundaryCondition != 0) * */this->epsilon); +// else +// signui = sign(u[cellIndex]); + + RealType value; +// if(map[cellIndex] == 0.0) +// { +//// value = INT_MAX; +// u[cellIndex] = sign(u[cellIndex])*INT_MAX; +// return 0.0; +// } +// else + value = 1.0/ map[cellIndex]; + + + RealType xb = u[cellIndex]; + RealType xf = -u[cellIndex]; + RealType yb = u[cellIndex]; + RealType yf = -u[cellIndex]; + RealType a,b,c; + + + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf += u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + xf += u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + + if(coordinates.x() == 0) + xb -= u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else + xb -= u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf += u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + yf += u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + + if(coordinates.y() == 0) + yb -= u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else + yb -= u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + + + if(signui > 0.0) + { + xf = negativePart(xf); + + xb = positivePart(xb); + + yf = negativePart(yf); + + yb = positivePart(yb); + + } + else if(signui < 0.0) + { + + xb = negativePart(xb); + + xf = positivePart(xf); + + yb = negativePart(yb); + + yf = positivePart(yf); + } + + /*if(boundaryCondition &1) + yb = 0.0; + else + yf = 0.0; + + if(boundaryCondition & 2) + xb = 0.0; + else + xf = 0.0;*/ + + if(xb - xf > 0.0) + a = xb; + else + a = xf; + + if(yb - yf > 0.0) + b = yb; + else + b = yf; + + c =(value - sqrt(a*a+b*b)*ihx ); + + if(c > 0.0 ) + return sign(u[cellIndex])*c; + else + + return signui*c; + +} + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + +#ifdef HAVE_CUDA +__device__ +#endif +Real parallelGodunovMapScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValueDev( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Real* u, + const Real& time, + const IndexType boundaryCondition, + const tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities, + const Real* map) const +{ +// int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x; + + RealType signui; + if(boundaryCondition == 0) + signui = sign(u[cellIndex],/*(boundaryCondition != 0) * */this->epsilon); + else + signui = sign(u[cellIndex]); + +// RealType value; +// if(map[cellIndex] == 0.0) +// { +//// value = INT_MAX; +// u[cellIndex] = sign(u[cellIndex])*INT_MAX; +// return 0.0; +// } +// else + RealType value = /*1.0/*/ map[cellIndex]; + + + RealType xb = u[cellIndex]; + RealType xf = -u[cellIndex]; + RealType yb = u[cellIndex]; + RealType yf = -u[cellIndex]; + RealType a,b,c; + + + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf += u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + xf += u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + + if(coordinates.x() == 0) + xb -= u[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else + xb -= u[neighbourEntities.template getEntityIndex< -1, 0 >()]; + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf += u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + yf += u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + + if(coordinates.y() == 0) + yb -= u[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else + yb -= u[neighbourEntities.template getEntityIndex< 0, -1 >()]; + + + if(signui > 0.0) + { + xf = negativePart(xf); + + xb = positivePart(xb); + + yf = negativePart(yf); + + yb = positivePart(yb); + + } + else if(signui < 0.0) + { + + xb = negativePart(xb); + + xf = positivePart(xf); + + yb = negativePart(yb); + + yf = positivePart(yf); + } + +// if(boundaryCondition &1) +// yb = 0.0; +// else +// yf = 0.0; +// +// if(boundaryCondition & 2) +// xb = 0.0; +// else +// xf = 0.0; + + if(xb > xf) + a = xb; + else + a = xf; + + if(yb > yf) + b = yb; + else + b = yf; + + c = (value - sqrt(a*a+b*b)*ihx ); + +// if(c > 0.0 ) +// return sign(u[cellIndex])*c; +// else + return signui*c; +} + + +#endif /* PARALLELGODUNOVMAP2D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..74f7510d72329f60305bb366604e72b7201a3ea0 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/CMakeLists.txt @@ -0,0 +1,17 @@ +set( headers godunov1D_impl.h + godunov2D_impl.h + godunov3D_impl.h) + +SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/operators/godunov ) + +if( BUILD_CUDA) + set( tnl_implementation_operators_godunov_CUDA__SOURCES + ${common_SOURCES} + PARENT_SCOPE ) +endif() + +set( tnl_implementation_operators_godunov_SOURCES + ${common_SOURCES} + PARENT_SCOPE ) + +INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/implementation/operators/godunov ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov1D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..2f902ad7d8dc81273a7e0067f29c459a4bbd1dfc --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov1D_impl.h @@ -0,0 +1,174 @@ +/*************************************************************************** + godunov1D_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOV1D_IMPL_H_ +#define GODUNOV1D_IMPL_H_ + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if(eps == 0.0) + return 0.0; + + return sin( ( M_PI * x ) / (2 * eps) ); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +bool godunovScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index, Function > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + h = originalMesh.getSpaceSteps().x(); + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=h; + + f.setup( parameters ); + + /*dofVector. setSize( this->mesh.getDofs() );*/ + + return true; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +String godunovScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, Function > :: getType() +{ + return String( "godunovScheme< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real godunovScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index, Function >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time ) const +{ + + RealType nabla, xb, xf, fi; + + fi = f.getValue(mesh.getCellCenter( coordinates ),time); + + if(fi > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return -fi*( nabla); + } + else if (fi < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return -fi*( nabla); + } + else + { + return 0.0; + } + +} + + +#endif /* GODUNOV1D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..fdd7e671630ec4c2eb40230f80b779c1f5058f89 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov2D_impl.h @@ -0,0 +1,192 @@ +/*************************************************************************** + godunov2D_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOV2D_IMPL_H_ +#define GODUNOV2D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function >:: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if ( eps == 0.0) + return 0.0; + + return sin((M_PI*x)/(2.0*eps)); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +bool godunovScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index, Function > :: init( const Config::ParameterContainer& parameters ) +{ + + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + hx = originalMesh.getSpaceSteps().x(); + hy = originalMesh.getSpaceSteps().y(); + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=sqrt( hx*hx + hy*hy ); + + f.setup( parameters ); + +// dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +String godunovScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, Function > :: getType() +{ + return String( "tnlLinearDiffusion< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real godunovScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index, Function >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time ) const +{ + + + RealType nabla, xb, xf, yb, yf, fi; + + fi = f.getValue(mesh.getCellCenter( coordinates ),time); + + if(fi > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + if(yb + yf > 0.0) + yf = 0.0; + else + yb = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); + + return -1.0*fi*( nabla); + } + else if (fi < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + if(yb + yf > 0.0) + yb = 0.0; + else + yf = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); + + return -1.0*fi*( nabla); + } + else + { + return 0.0; + } + +} + + +#endif /* GODUNOV2D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov3D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..d25f354bc0a4cc448166ad44d3400f16132682f9 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/Godunov/godunov3D_impl.h @@ -0,0 +1,204 @@ +/*************************************************************************** + godunov3D_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOV3D_IMPL_H_ +#define GODUNOV3D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +Real godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if ( eps == 0.0) + return 0.0; + + return sin((M_PI*x)/(2.0*eps)); +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +bool godunovScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index, Function > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + hx = originalMesh.getSpaceSteps().x(); + hy = originalMesh.getSpaceSteps().y(); + hz = originalMesh.getSpaceSteps().z(); + + epsilon = parameters. getParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=sqrt( hx*hx + hy*hy +hz*hz ); + + f.setup( parameters ); + + // dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +String godunovScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, Function > :: getType() +{ + return String( "tnlLinearDiffusion< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename Function > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real godunovScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index, Function >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time ) const +{ + + RealType nabla, xb, xf, yb, yf, zb, zf, fi; + + fi = f.getValue(mesh.getCellCenter( coordinates ),time); + + if(fi > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + zf = negativePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz); + zb = positivePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + if(yb + yf > 0.0) + yf = 0.0; + else + yb = 0.0; + + if(zb + zf > 0.0) + zf = 0.0; + else + zb = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb ); + + return -fi*( nabla); + } + else if (fi < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + zf = positivePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz); + zb = negativePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + if(yb + yf > 0.0) + yb = 0.0; + else + yf = 0.0; + + if(zb + zf > 0.0) + zb = 0.0; + else + zf = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb ); + + return -fi*( nabla); + } + else + { + return 0.0; + } + +} + + +#endif /* GODUNOV3D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/tnlEikonalOperator.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/tnlEikonalOperator.h new file mode 100644 index 0000000000000000000000000000000000000000..3beb7e997e0f7aa6759df7c571b3a398445630b9 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/tnlEikonalOperator.h @@ -0,0 +1,66 @@ +/* + * File: tnlEikonalOperator.h + * Author: oberhuber + * + * Created on July 11, 2016, 6:33 PM + */ + +#pragma once + +#include <functions/tnlConstantFunction.h> +#include <functions/tnlFunctionAdapter.h> + +template< typename GradientNormOperator, + typename Anisotropy = + tnlConstantFunction< GradientNormOperator::MeshType::getMeshDimensions(), + typename GradientNormOperator::MeshType::RealType > > +class tnlEikonalOperator + : public tnlOperator< typename GradientNormOperator::MeshType, MeshDomain > +{ + public: + + typedef typename GradientNormOperator::MeshType MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + typedef GradientNormOperator GradientNormOperatorType; + typedef Anisotropy AnisotropyType; + //typedef tnlExactLinearDiffusion< 1 > ExactOperatorType; + + static const int Dimensions = MeshType::meshDimensions; + + static constexpr int getMeshDimensions() { return Dimensions; } + + static String getType(); + + AnisotropyType& getAnisotropy() { return this->anisotropy; }; + + const AnisotropyType& getAnisotropy() const { return this->anisotropy; }; + + const RealType getSmoothing() const { return this->smoothing; }; + + void setSmoothing( const RealType& smoothing ) { this->smoothing = smoothing; }; + + template< typename PreimageFunction, + typename MeshEntity > + __cuda_callable__ + RealType operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + const RealType signU = sign( u( entity ), smoothing * entity.getMesh().getSmallestSpaceStep() ); + const RealType f = tnlFunctionAdapter< MeshType, AnisotropyType >::getValue( anisotropy, entity, 0.0 ); + return signU * ( f - gradientNorm( u, entity, signU ) ); + }; + + protected: + + GradientNormOperatorType gradientNorm; + + AnisotropyType anisotropy; + + RealType smoothing; + +}; + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/upwindEikonal.h b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/upwindEikonal.h new file mode 100644 index 0000000000000000000000000000000000000000..e8f793260999eba3f7e2082a5237ee3daba6e86a --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Operators/Hamilton-Jacobi/upwindEikonal.h @@ -0,0 +1,202 @@ +/*************************************************************************** + upwindEikonal.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <mesh/tnlGrid.h> +#include <functions/tnlFunctions.h> + +template< typename Mesh, + typename Real, + typename Index > +class upwindEikonalScheme +{ +}; + +/**** + * 1D scheme + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class upwindEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + static String getType(); + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& f ) const + { + const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const typename MeshEntity::template NeighbourEntities< 1 >& neighbourEntities = entity.getNeighbourEntities(); + + const RealType& u_c = u[ entity.getIndex() ]; + const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1 >() ]; + const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1 >() ]; + + if( f > 0.0 ) + { + const RealType& xf = negativePart( ( u_e - u_c ) * hx_inv ); + const RealType& xb = positivePart( ( u_c - u_w ) * hx_inv ); + return sqrt( xf * xf + xb * xb ); + } + else if( f < 0.0 ) + { + const RealType& xf = negativePart( ( u_c - u_w ) * hx_inv ); + const RealType& xb = positivePart( ( u_e - u_c ) * hx_inv ); + return sqrt( xf * xf + xb * xb ); + } + else + { + return 0.0; + } + }; +}; + +/**** + * 2D scheme + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class upwindEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + static String getType(); + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& f ) const + { + const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + + const typename MeshEntity::template NeighbourEntities< 2 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& u_c = u[ entity.getIndex() ]; + const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1, 0 >() ]; + const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1, 0 >() ]; + const RealType& u_n = u[ neighbourEntities.template getEntityIndex< 0, 1 >() ]; + const RealType& u_s = u[ neighbourEntities.template getEntityIndex< 0, -1 >() ]; + if( f > 0.0 ) + { + const RealType xf = negativePart( ( u_e - u_c ) * hx_inv ); + const RealType xb = positivePart( ( u_c - u_w ) * hx_inv ); + const RealType yf = negativePart( ( u_n - u_c ) * hy_inv ); + const RealType yb = positivePart( ( u_c - u_s ) * hy_inv ); + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb ); + } + else if( f < 0.0 ) + { + const RealType xf = positivePart( ( u_e - u_c ) * hx_inv ); + const RealType xb = negativePart( ( u_c - u_w ) * hx_inv ); + const RealType yf = positivePart( ( u_n - u_c ) * hy_inv ); + const RealType yb = negativePart( ( u_c - u_s ) * hy_inv ); + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb ); + } + else + return 0.0; + } +}; + +/**** + * 3D scheme + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class upwindEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + + public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + static String getType(); + + template< typename PreimageFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& f ) const + { + const RealType& hx_inv = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hy_inv = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hz_inv = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + + const typename MeshEntity::template NeighbourEntities< 3 >& neighbourEntities = entity.getNeighbourEntities(); + const RealType& u_c = u[ entity.getIndex() ]; + const RealType& u_e = u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ]; + const RealType& u_w = u[ neighbourEntities.template getEntityIndex< -1, 0, 0 >() ]; + const RealType& u_n = u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ]; + const RealType& u_s = u[ neighbourEntities.template getEntityIndex< 0, -1, 0 >() ]; + const RealType& u_t = u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ]; + const RealType& u_b = u[ neighbourEntities.template getEntityIndex< 0, 0, -1 >() ]; + + if( f > 0.0 ) + { + const RealType xf = negativePart( ( u_e - u_c ) * hx_inv ); + const RealType xb = positivePart( ( u_c - u_w ) * hx_inv ); + const RealType yf = negativePart( ( u_n - u_c ) * hy_inv ); + const RealType yb = positivePart( ( u_c - u_s ) * hy_inv ); + const RealType zf = negativePart( ( u_t - u_c ) * hz_inv ); + const RealType zb = positivePart( ( u_c - u_b ) * hz_inv ); + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb ); + } + else if( f < 0.0 ) + { + const RealType xf = positivePart( ( u_e - u_c ) * hx_inv ); + const RealType xb = negativePart( ( u_c - u_w ) * hx_inv ); + const RealType yf = positivePart( ( u_n - u_c ) * hy_inv ); + const RealType yb = negativePart( ( u_c - u_s ) * hy_inv ); + const RealType zf = positivePart( ( u_t - u_c ) * hz_inv ); + const RealType zb = negativePart( ( u_c - u_b ) * hz_inv ); + return sqrt( xf * xf + xb * xb + yf * yf + yb * yb + zf * zf + zb * zb ); + } + else + return 0.0; + }; +}; \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..b4ec5170b50f7b9bfdf6b81f261f396c0c59d624 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/CMakeLists.txt @@ -0,0 +1,3 @@ +ADD_SUBDIRECTORY( hamilton-jacobi ) + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..73cc05e2646fd6f5ad77227a73722d981580f7c6 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/CMakeLists.txt @@ -0,0 +1,22 @@ +set( tnl_fast_sweeping_map_SOURCES +# MainBuildConfig.h +# tnlFastSweepingMap2D_impl.h +# tnlFastSweepingMap.h +# fastSweepingMapConfig.h + main.cpp) + + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(fast-sweeping-map${debugExt} main.cu) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(fast-sweeping-map${debugExt} main.cpp) +ENDIF( BUILD_CUDA ) +target_link_libraries (fast-sweeping-map${debugExt} tnl${debugExt}-${tnlVersion} ) + + +INSTALL( TARGETS fast-sweeping-map${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +#INSTALL( FILES ${tnl_fast_sweeping_map_SOURCES} +# DESTINATION share/tnl-${tnlVersion}/examples/fast-sweeping-map ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/MainBuildConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/MainBuildConfig.h @@ -0,0 +1,64 @@ +/*************************************************************************** + MainBuildConfig.h - description + ------------------- + begin : Jul 7, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MAINBUILDCONFIG_H_ +#define MAINBUILDCONFIG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class MainBuildConfig +{ + public: + + static void print() { cerr << "MainBuildConfig" << endl; } +}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && + tnlConfigTagReal< MainBuildConfig, Real >::enabled && + tnlConfigTagDevice< MainBuildConfig, Device >::enabled && + tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* MAINBUILDCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/fastSweepingMapConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/fastSweepingMapConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..9251deca876e821dace59682ca1a151555095c69 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/fastSweepingMapConfig.h @@ -0,0 +1,39 @@ +/*************************************************************************** + fastSweepingConfig.h - description + ------------------- + begin : Oct 15, 2015 + copyright : (C) 2015 by Tomas Sobotik + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FASTSWEEPINGCONFIG_H_ +#define FASTSWEEPINGCONFIG_H_ + +#include <config/tnlConfigDescription.h> + +template< typename ConfigTag > +class fastSweepingMapConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Parallel Eikonal solver settings:" ); + config.addEntry < String > ( "problem-name", "This defines particular problem.", "fast-sweeping" ); + config.addRequiredEntry < String > ( "initial-condition", "Initial condition for solver"); + config.addRequiredEntry < int > ( "dim", "Dimension of problem."); + config.addEntry < String > ( "mesh", "Name of mesh.", "mesh.tnl" ); + config.addEntry < String > ( "exact-input", "Are the function values near the curve equal to the SDF? (yes/no)", "no" ); + config.addRequiredEntry < String > ( "map", "Gradient map for solver"); + } +}; + +#endif /* FASTSWEEPINGCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.cu @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.h new file mode 100644 index 0000000000000000000000000000000000000000..d17b47ac5125bebf9ac9619a9496b5dc4b46b394 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/main.h @@ -0,0 +1,88 @@ +/*************************************************************************** + main.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "MainBuildConfig.h" + //for HOST versions: +#include "tnlFastSweepingMap.h" + //for DEVICE versions: +//#include "tnlFastSweepingMap_CUDA.h" +#include "fastSweepingMapConfig.h" +#include <solvers/tnlBuildConfigTags.h> + +#include <mesh/tnlGrid.h> +#include <core/tnlDevice.h> +#include <time.h> +#include <ctime> + +typedef MainBuildConfig BuildConfig; + +int main( int argc, char* argv[] ) +{ + time_t start; + time_t stop; + time(&start); + std::clock_t start2= std::clock(); + Config::ParameterContainer parameters; + tnlConfigDescription configDescription; + fastSweepingMapConfig< BuildConfig >::configSetup( configDescription ); + + if( ! parseCommandLine( argc, argv, configDescription, parameters ) ) + return false; + + const int& dim = parameters.getParameter< int >( "dim" ); + + if(dim == 2) + { + tnlFastSweepingMap<tnlGrid<2,double,tnlHost, int>, double, int> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + checkCudaDevice; + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver..." << endl; + solver.run(); + } +// else if(dim == 3) +// { +// tnlFastSweepingMap<tnlGrid<3,double,tnlHost, int>, double, int> solver; +// if(!solver.init(parameters)) +// { +// cerr << "Solver failed to initialize." << endl; +// return EXIT_FAILURE; +// } +// checkCudaDevice; +// cout << "-------------------------------------------------------------" << endl; +// cout << "Starting solver..." << endl; +// solver.run(); +// } + else + { + cerr << "Unsupported number of dimensions: " << dim << "!" << endl; + return EXIT_FAILURE; + } + + + time(&stop); + cout << "Solver stopped..." << endl; + cout << endl; + cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl; + return EXIT_SUCCESS; +} + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap.h new file mode 100644 index 0000000000000000000000000000000000000000..f6f2150a4df3ae6f0fe85efeeb6ea9abac0007d3 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap.h @@ -0,0 +1,188 @@ +/*************************************************************************** + tnlFastSweepingMap.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING_H_ +#define TNLFASTSWEEPING_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <functions/tnlMeshFunction.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> +#include <limits.h> +#include <core/tnlDevice.h> +#include <ctime> +#ifdef HAVE_OPENMP +#include <omp.h> +#endif + + + + +template< typename Mesh, + typename Real, + typename Index > +class tnlFastSweepingMap +{}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + tnlFastSweepingMap(); + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + + bool initGrid(); + bool run(); + + //for single core version use this implementation: + void updateValue(const Index i, const Index j); + //for parallel version use this one instead: +// void updateValue(const Index i, const Index j, DofVectorType* grid); + + + void setupSquare1000(Index i, Index j); + void setupSquare1100(Index i, Index j); + void setupSquare1010(Index i, Index j); + void setupSquare1001(Index i, Index j); + void setupSquare1110(Index i, Index j); + void setupSquare1101(Index i, Index j); + void setupSquare1011(Index i, Index j); + void setupSquare1111(Index i, Index j); + void setupSquare0000(Index i, Index j); + void setupSquare0100(Index i, Index j); + void setupSquare0010(Index i, Index j); + void setupSquare0001(Index i, Index j); + void setupSquare0110(Index i, Index j); + void setupSquare0101(Index i, Index j); + void setupSquare0011(Index i, Index j); + void setupSquare0111(Index i, Index j); + + Real fabsMin(const Real x, const Real y); + + +protected: + + MeshType Mesh; + + bool exactInput; + + int something_changed; + + tnlMeshFunction<MeshType> dofVector, dofVector2; + DofVectorType data,map; + + RealType h; + + tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity; + + +#ifdef HAVE_OPENMP +// omp_lock_t* gridLock; +#endif + + +}; + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweepingMap< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + tnlFastSweepingMap(); + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + + bool initGrid(); + bool run(); + + //for single core version use this implementation: + void updateValue(const Index i, const Index j, const Index k); + //for parallel version use this one instead: +// void updateValue(const Index i, const Index j, DofVectorType* grid); + + Real fabsMin(const Real x, const Real y); + + +protected: + + MeshType Mesh; + + bool exactInput; + + + tnlMeshFunction<MeshType> dofVector, dofVector2; + DofVectorType data; + + RealType h; + + tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage > Entity; + +#ifdef HAVE_OPENMP +// omp_lock_t* gridLock; +#endif + + +}; + + + //for single core version use this implementation: +#include "tnlFastSweepingMap2D_impl.h" + //for parallel version use this one instead: +// #include "tnlFastSweepingMap2D_openMP_impl.h" + +// #include "tnlFastSweepingMap3D_impl.h" + +#endif /* TNLFASTSWEEPING_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_CUDA_v4_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_CUDA_v4_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..5e9d11b5264e301d8eb9a30b625861bf6a79ad2b --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_CUDA_v4_impl.h @@ -0,0 +1,1051 @@ +/*************************************************************************** + tnlFastSweepingMap2D_CUDA_v4_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweepingMap.h" + +#define MAP_SOLVER_MAX_VALUE 3 + +__device__ +double fabsMin( double x, double y) +{ + double fx = abs(x); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; +} + +__device__ +double atomicFabsMin(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) )); + } while (assumed != old); + return __longlong_as_double(old); +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweepingMap< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweepingMap() +:dofVector(Mesh) +{ +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + const String& mapFile = parameters.getParameter <String>("map"); + if(! this->map.load( mapFile )) + cout << "Failed to load map file : " << mapFile << endl; + + h = Mesh.template getSpaceStepsProducts< 1, 0 >(); + //Entity.refresh(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(map_cuda), this->map.getSize()*sizeof(double)); + cudaMemcpy(map_cuda, this->map.getData(), this->map.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(changed), sizeof(int)); + //counter == 0 --> setting changed to 0 + cudaMemcpy(changed, &counter, sizeof(int), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1); + + + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(1, 1024); + dim3 numBlocks(4,1); + + int run = 1; + int zero = 0; + int cntr = 0; + + while(run != 0) + { + cudaMemcpy(this->changed, &zero, sizeof(int), cudaMemcpyHostToDevice); + cudaDeviceSynchronize(); + checkCudaDevice; + + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0, this->changed); + cudaDeviceSynchronize(); + checkCudaDevice; + + cudaMemcpy(&run, this->changed,sizeof(int), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + checkCudaDevice; + cntr++; + cout << "Finished set of sweeps #" << cntr << " " << run << endl; + } + + cudaDeviceSynchronize(); + checkCudaDevice; + + //data.setLike(dofVector.getData()); + //cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + //data.save("u-00001.tnl"); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index* something_changed) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + + if(map_cuda[Entity.getIndex()] != 0.0) + { + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real value = cudaDofVector2[Entity.getIndex()]; + Real im = abs(1.0/map_cuda[Entity.getIndex()]); + Real a,b, tmp; + + if( i == 0 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + { + a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] ); + } + + if( j == 0 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + { + b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ); + } + + + if(abs(a-b) >= im*h) + tmp = fabsMin(a,b) + sign(value)*im*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * im * h * im * h - (a - b) * (a - b) ) ); + + // cudaDofVector2[Entity.getIndex()] = fabsMin(value, tmp); + atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp); + + if(abs(value)-abs(tmp) > 0.0) + atomicMax(something_changed,1); + } + else + { + atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), MAP_SOLVER_MAX_VALUE); + } + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + int gid = Entity.getIndex(); + + cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]); + + if(abs(cudaDofVector[gid]) < 1.01*h) + { + cudaDofVector2[gid] = cudaDofVector[gid]; + if(map_cuda[gid] != 0.0) + cudaDofVector2[gid] /=map_cuda[gid]; + } + + + + + +// if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() ) +// { +// if(cudaDofVector[Entity.getIndex()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1111(i,j); +// else +// setupSquare1110(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1101(i,j); +// else +// setupSquare1100(i,j); +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1011(i,j); +// else +// setupSquare1010(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1001(i,j); +// else +// setupSquare1000(i,j); +// } +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0111(i,j); +// else +// setupSquare0110(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0101(i,j); +// else +// setupSquare0100(i,j); +// } +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0011(i,j); +// else +// setupSquare0010(i,j); +// } +// else +// { +// if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0001(i,j); +// else +// setupSquare0000(i,j); +// } +// } +// } +// +// } + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + //Real fy = abs(y); + + //Real tmpMin = Min(fx,abs(y)); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlFastSweepingMap< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i, int* changed) +{ + + __shared__ int something_changed; + if(threadIdx.x+threadIdx.y == 0) + something_changed = 0; + + int gx = 0; + int gy = threadIdx.y; + //if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy) + // return; + int n = solver->Mesh.getDimensions().x(); + int blockCount = n/blockDim.y +1; + //int gid = solver->Mesh.getDimensions().x() * gy + gx; + //int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x(); + + //int id1 = gx+gy; + //int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy; + + __syncthreads(); + if(blockIdx.x==0) + { + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,&something_changed); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==1) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,&something_changed); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==2) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,&something_changed); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==3) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,&something_changed); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + + + if(threadIdx.x+threadIdx.y == 0) + atomicMax(changed, something_changed); + + + + +} + + +__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + + + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); +} +#endif + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..adff615fd43cd012ba5e45095140d7c2e0e5fbf0 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap2D_impl.h @@ -0,0 +1,823 @@ +/*************************************************************************** + tnlFastSweepingMap2D_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + + +#define MAP_SOLVER_MAX_VALUE 3 + + +#include "tnlFastSweepingMap.h" + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweepingMap< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweepingMap() +:Entity(Mesh), + dofVector(Mesh), + dofVector2(Mesh) +{ +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + dofVector2.load(initialCondition); + + const String& mapFile = parameters.getParameter <String>("map"); + if(! this->map.load( mapFile )) + cout << "Failed to load map file : " << mapFile << endl; + + h = Mesh.template getSpaceStepsProducts< 1, 0 >(); + Entity.refresh(); + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + cout << "a" << endl; + + something_changed = 1; + return initGrid(); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().x();i++) + { + dofVector2[i]=INT_MAX*sign(dofVector[i]); + + if(abs(dofVector[i]) < 1.01*h) + { + dofVector2[i] = dofVector[i]; + if(map[i] != 0.0) + dofVector2[i] /= map[i]; + } + } + +// for(int i = 0 ; i < Mesh.getDimensions().x()-1; i++) +// { +// for(int j = 0 ; j < Mesh.getDimensions().x()-1; j++) +// { +// this->Entity.setCoordinates(CoordinatesType(i,j)); +// this->Entity.refresh(); +// neighbourEntities.refresh(Mesh,Entity.getIndex()); +// +// if(dofVector[this->Entity.getIndex()] > 0) +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1111(i,j); +// else +// setupSquare1110(i,j); +// } +// else +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1101(i,j); +// else +// setupSquare1100(i,j); +// } +// } +// else +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1011(i,j); +// else +// setupSquare1010(i,j); +// } +// else +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare1001(i,j); +// else +// setupSquare1000(i,j); +// } +// } +// } +// else +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0111(i,j); +// else +// setupSquare0110(i,j); +// } +// else +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0101(i,j); +// else +// setupSquare0100(i,j); +// } +// } +// else +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0011(i,j); +// else +// setupSquare0010(i,j); +// } +// else +// { +// if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) +// setupSquare0001(i,j); +// else +// setupSquare0000(i,j); +// } +// } +// } +// +// } +// } + cout << "a" << endl; + + //data.setLike(dofVector2.getData()); + //data=dofVector2.getData(); + //cout << data.getType() << endl; + dofVector2.save("u-00000.tnl"); + //dofVector2.getData().save("u-00000.tnl"); + + return true; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + int cntr = 0; + while(something_changed != 0) + { + something_changed = 0; + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j); + } + } + + /*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j); + } + } + + /*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j); + } + } + + /*---------------------------------------------------------------------------------------------------------------------------*/ + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j); + } + } + + /*---------------------------------------------------------------------------------------------------------------------------*/ + cntr++; + cout << "Finished set of sweeps #" << cntr << " " << something_changed << endl; + } + + + + dofVector2.save("u-00001.tnl"); + + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + if(map[Entity.getIndex()] != 0.0) + { + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + Real value = dofVector2[Entity.getIndex()]; + Real im = abs(1.0/map[Entity.getIndex()]); + Real a,b, tmp; + + if( i == 0 ) + a = dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = dofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + { + a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()], + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] ); + } + + if( j == 0 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + { + b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()], + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ); + } + + + if(fabs(a-b) >= im*h) + tmp = fabsMin(a,b) + sign(value)*im*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * im * h * im * h - (a - b) * (a - b) ) ); + + if(abs(value)-abs(tmp) > 0.0) + something_changed = 1; + + dofVector2[Entity.getIndex()] = fabsMin(value, tmp); + + } + else + { + dofVector2[Entity.getIndex()] = MAP_SOLVER_MAX_VALUE; + } +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = fabs(x); + Real fy = fabs(y); + + Real tmpMin = Min(fx,fy); + + if(tmpMin == fx) + return x; + else + return y; + +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +{ +// this->Entity.setCoordinates(CoordinatesType(i,j)); +// this->Entity.refresh(); +// auto neighbourEntities = Entity.getNeighbourEntities(); +// dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]); +// dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +{ +// this->Entity.setCoordinates(CoordinatesType(i,j)); +// this->Entity.refresh(); +// auto neighbourEntities = Entity.getNeighbourEntities(); +// dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]); +// dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); +} + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap_CUDA.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap_CUDA.h new file mode 100644 index 0000000000000000000000000000000000000000..aa606ea47999ce739fb23d7ad6c38f937cf23f26 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping-map/tnlFastSweepingMap_CUDA.h @@ -0,0 +1,196 @@ +/*************************************************************************** + tnlFastSweepingMap_CUDA.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING_H_ +#define TNLFASTSWEEPING_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> + +#include <functions/tnlMeshFunction.h> +#include <limits.h> +#include <core/tnlDevice.h> +#include <ctime> + + + + + +template< typename Mesh, + typename Real, + typename Index > +class tnlFastSweepingMap +{}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + tnlFastSweepingMap(); + + __host__ static String getType(); + __host__ bool init( const Config::ParameterContainer& parameters ); + __host__ bool run(); + +#ifdef HAVE_CUDA + __device__ bool initGrid(); + __device__ void updateValue(const Index i, const Index j, Index* something_changed); + __device__ void updateValue(const Index i, const Index j, double** sharedMem, const int k3); + __device__ Real fabsMin(const Real x, const Real y); + + tnlFastSweepingMap< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver; + double* cudaDofVector; + double* cudaDofVector2; + double* map_cuda; + int counter; + int* changed; + __device__ void setupSquare1000(Index i, Index j); + __device__ void setupSquare1100(Index i, Index j); + __device__ void setupSquare1010(Index i, Index j); + __device__ void setupSquare1001(Index i, Index j); + __device__ void setupSquare1110(Index i, Index j); + __device__ void setupSquare1101(Index i, Index j); + __device__ void setupSquare1011(Index i, Index j); + __device__ void setupSquare1111(Index i, Index j); + __device__ void setupSquare0000(Index i, Index j); + __device__ void setupSquare0100(Index i, Index j); + __device__ void setupSquare0010(Index i, Index j); + __device__ void setupSquare0001(Index i, Index j); + __device__ void setupSquare0110(Index i, Index j); + __device__ void setupSquare0101(Index i, Index j); + __device__ void setupSquare0011(Index i, Index j); + __device__ void setupSquare0111(Index i, Index j); +#endif + + MeshType Mesh; + +protected: + + + + bool exactInput; + + tnlMeshFunction<MeshType> dofVector; + DofVectorType data, map; + + + RealType h; + + +}; + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweepingMap< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + + __host__ static String getType(); + __host__ bool init( const Config::ParameterContainer& parameters ); + __host__ bool run(); + +#ifdef HAVE_CUDA + __device__ bool initGrid(int i, int j, int k); + __device__ void updateValue(const Index i, const Index j, const Index k); + __device__ void updateValue(const Index i, const Index j, const Index k, double** sharedMem, const int k3); + __device__ Real fabsMin(const Real x, const Real y); + + tnlFastSweepingMap< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver; + double* cudaDofVector; + double* cudaDofVector2; + int counter; +#endif + + MeshType Mesh; + +protected: + + + + bool exactInput; + + tnlMeshFunction<MeshType> dofVector; + DofVectorType data; + + RealType h; + + +}; + + + + + + + +#ifdef HAVE_CUDA +//template<int sweep_t> +__global__ void runCUDA(tnlFastSweepingMap< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i, int* changed); +//__global__ void runCUDA(tnlFastSweepingMap< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i); + +__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 2,double, tnlHost, int >, double, int >* solver); +//__global__ void initCUDA(tnlFastSweepingMap< tnlGrid< 3,double, tnlHost, int >, double, int >* solver); +#endif + +/*various implementtions.... choose one*/ +//#include "tnlFastSweepingMap2D_CUDA_impl.h" +//#include "tnlFastSweepingMap2D_CUDA_v2_impl.h" +//#include "tnlFastSweepingMap2D_CUDA_v3_impl.h" +#include "tnlFastSweepingMap2D_CUDA_v4_impl.h" +//#include "tnlFastSweepingMap2D_CUDA_v5_impl.h" + + +// #include "tnlFastSweepingMap3D_CUDA_impl.h" + +#endif /* TNLFASTSWEEPING_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..7a2963cc680e3a5c83f9116c19c715b3d44d7a42 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/CMakeLists.txt @@ -0,0 +1,22 @@ +set( tnl_fast_sweeping_SOURCES +# MainBuildConfig.h +# tnlFastSweeping2D_impl.h +# tnlFastSweeping.h +# fastSweepingConfig.h + main.cpp) + + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(fast-sweeping${debugExt} main.cu) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(fast-sweeping${debugExt} main.cpp) +ENDIF( BUILD_CUDA ) +target_link_libraries (fast-sweeping${debugExt} tnl${debugExt}-${tnlVersion} ) + + +INSTALL( TARGETS fast-sweeping${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +#INSTALL( FILES ${tnl_fast_sweeping_SOURCES} +# DESTINATION share/tnl-${tnlVersion}/examples/fast-sweeping ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/MainBuildConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/MainBuildConfig.h @@ -0,0 +1,64 @@ +/*************************************************************************** + MainBuildConfig.h - description + ------------------- + begin : Jul 7, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MAINBUILDCONFIG_H_ +#define MAINBUILDCONFIG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class MainBuildConfig +{ + public: + + static void print() { cerr << "MainBuildConfig" << endl; } +}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && + tnlConfigTagReal< MainBuildConfig, Real >::enabled && + tnlConfigTagDevice< MainBuildConfig, Device >::enabled && + tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* MAINBUILDCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/fastSweepingConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/fastSweepingConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..3df2c1e889050448fc07baf7dcd0e32feab3f778 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/fastSweepingConfig.h @@ -0,0 +1,38 @@ +/*************************************************************************** + fastSweepingConfig.h - description + ------------------- + begin : Oct 15, 2015 + copyright : (C) 2015 by Tomas Sobotik + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FASTSWEEPINGCONFIG_H_ +#define FASTSWEEPINGCONFIG_H_ + +#include <config/tnlConfigDescription.h> + +template< typename ConfigTag > +class fastSweepingConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Parallel Eikonal solver settings:" ); + config.addEntry < String > ( "problem-name", "This defines particular problem.", "fast-sweeping" ); + config.addRequiredEntry < String > ( "initial-condition", "Initial condition for solver"); + config.addRequiredEntry < int > ( "dim", "Dimension of problem."); + config.addEntry < String > ( "mesh", "Name of mesh.", "mesh.tnl" ); + config.addEntry < String > ( "exact-input", "Are the function values near the curve equal to the SDF? (yes/no)", "no" ); + } +}; + +#endif /* FASTSWEEPINGCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..8849008ff630db0400a6d7d98e789099e5fbb5d9 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.cu @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.h new file mode 100644 index 0000000000000000000000000000000000000000..217377f3b77645f2ad2ede8db68bdada5f0885fb --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/main.h @@ -0,0 +1,88 @@ +/*************************************************************************** + main.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include "MainBuildConfig.h" + //for HOST versions: +#include "tnlFastSweeping.h" + //for DEVICE versions: +//#include "tnlFastSweeping_CUDA.h" +#include "fastSweepingConfig.h" +#include <solvers/tnlBuildConfigTags.h> + +#include <mesh/tnlGrid.h> +#include <core/tnlDevice.h> +#include <time.h> +#include <ctime> + +typedef MainBuildConfig BuildConfig; + +int main( int argc, char* argv[] ) +{ + time_t start; + time_t stop; + time(&start); + std::clock_t start2= std::clock(); + Config::ParameterContainer parameters; + tnlConfigDescription configDescription; + fastSweepingConfig< BuildConfig >::configSetup( configDescription ); + + if( ! parseCommandLine( argc, argv, configDescription, parameters ) ) + return false; + + const int& dim = parameters.getParameter< int >( "dim" ); + + if(dim == 2) + { + tnlFastSweeping<tnlGrid<2,double,tnlHost, int>, double, int> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + checkCudaDevice; + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver..." << endl; + solver.run(); + } + else if(dim == 3) + { + tnlFastSweeping<tnlGrid<3,double,tnlHost, int>, double, int> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + checkCudaDevice; + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver..." << endl; + solver.run(); + } + else + { + cerr << "Unsupported number of dimensions: " << dim << "!" << endl; + return EXIT_FAILURE; + } + + + time(&stop); + cout << "Solver stopped..." << endl; + cout << endl; + cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl; + return EXIT_SUCCESS; +} + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping.h new file mode 100644 index 0000000000000000000000000000000000000000..55f145af95deba9752fb5c4f564bbbfa331bf153 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping.h @@ -0,0 +1,186 @@ +/*************************************************************************** + tnlFastSweeping.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING_H_ +#define TNLFASTSWEEPING_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <functions/tnlMeshFunction.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> +#include <limits.h> +#include <core/tnlDevice.h> +#include <ctime> +#ifdef HAVE_OPENMP +#include <omp.h> +#endif + + + + +template< typename Mesh, + typename Real, + typename Index > +class tnlFastSweeping +{}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + tnlFastSweeping(); + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + + bool initGrid(); + bool run(); + + //for single core version use this implementation: + void updateValue(const Index i, const Index j); + //for parallel version use this one instead: +// void updateValue(const Index i, const Index j, DofVectorType* grid); + + + void setupSquare1000(Index i, Index j); + void setupSquare1100(Index i, Index j); + void setupSquare1010(Index i, Index j); + void setupSquare1001(Index i, Index j); + void setupSquare1110(Index i, Index j); + void setupSquare1101(Index i, Index j); + void setupSquare1011(Index i, Index j); + void setupSquare1111(Index i, Index j); + void setupSquare0000(Index i, Index j); + void setupSquare0100(Index i, Index j); + void setupSquare0010(Index i, Index j); + void setupSquare0001(Index i, Index j); + void setupSquare0110(Index i, Index j); + void setupSquare0101(Index i, Index j); + void setupSquare0011(Index i, Index j); + void setupSquare0111(Index i, Index j); + + Real fabsMin(const Real x, const Real y); + + +protected: + + MeshType Mesh; + + bool exactInput; + + tnlMeshFunction<MeshType> dofVector, dofVector2; + DofVectorType data; + + RealType h; + + tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity; + + +#ifdef HAVE_OPENMP +// omp_lock_t* gridLock; +#endif + + +}; + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + tnlFastSweeping(); + + static String getType(); + bool init( const Config::ParameterContainer& parameters ); + + bool initGrid(); + bool run(); + + //for single core version use this implementation: + void updateValue(const Index i, const Index j, const Index k); + //for parallel version use this one instead: +// void updateValue(const Index i, const Index j, DofVectorType* grid); + + Real fabsMin(const Real x, const Real y); + + +protected: + + MeshType Mesh; + + bool exactInput; + + + tnlMeshFunction<MeshType> dofVector, dofVector2; + DofVectorType data; + + RealType h; + + tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage > Entity; + +#ifdef HAVE_OPENMP +// omp_lock_t* gridLock; +#endif + + +}; + + + //for single core version use this implementation: +#include "tnlFastSweeping2D_impl.h" + //for parallel version use this one instead: +// #include "tnlFastSweeping2D_openMP_impl.h" + +#include "tnlFastSweeping3D_impl.h" + +#endif /* TNLFASTSWEEPING_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..48cbba5cb2e247296d41d3b7c2f935c8f75ce960 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_impl.h @@ -0,0 +1,522 @@ +/*************************************************************************** + tnlFastSweeping2D_CUDA_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweeping.h" + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.getSpaceSteps().x(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1); + + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ +// +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// +// dofVector.save("u-00001.tnl"); + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(32, 32); + dim3 numBlocks(n/32 + 1 ,n/32 +1); + + for(int i = 2*n - 1; i > -1; i--) + { + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,i); + cudaDeviceSynchronize(); + } + cudaDeviceSynchronize(); + checkCudaDevice; + for(int i = 0; i < 2*n ; i++) + { + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,i); + cudaDeviceSynchronize(); + } + cudaDeviceSynchronize(); + checkCudaDevice; + for(int i = 0; i < 2*n ; i++) + { + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i); + cudaDeviceSynchronize(); + } + cudaDeviceSynchronize(); + checkCudaDevice; + for(int i = 2*n - 1; i > -1; i--) + { + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,3,i); + cudaDeviceSynchronize(); + } + + cudaDeviceSynchronize(); + checkCudaDevice; + + cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + Index index = Mesh.getCellIndex(CoordinatesType(i,j)); + Real value = cudaDofVector[index]; + Real a,b, tmp; + + if( i == 0 ) + a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)]; + else + { + a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)], + cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] ); + } + + if( j == 0 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)]; + else + { + b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)], + cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + cudaDofVector[index] = fabsMin(value, tmp); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + int gid = Mesh.getCellIndex(CoordinatesType(gx,gy)); + + int total = blockDim.x*gridDim.x; + + + + Real tmp = 0.0; + int flag = 0; + counter = 0; + tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + + + if(!exactInput) + { + cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]); + } + __threadfence(); +// printf("-----------------------------------------------------------------------------------\n"); + + __threadfence(); + + if(gx > 0 && gx < Mesh.getDimensions().x()-1) + { + if(gy > 0 && gy < Mesh.getDimensions().y()-1) + { + + Index j = gy; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + } + +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); +// printf("****************************************************************\n"); +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0) + { +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + Index j = 0; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1) + { + Index i = gx; + Index j = Mesh.getDimensions().y() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0) + { + Index j = gy; + Index i = 0; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } +// printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == Mesh.getDimensions().x() - 1) + { + Index j = gy; + Index i = Mesh.getDimensions().x() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("##################################################################################################\n"); + if(gx == Mesh.getDimensions().x() - 1 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == Mesh.getDimensions().x() - 1 && + gy == 0) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } +// printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); + if(gx == 0 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == 0 && + gy == 0) + { +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + + __threadfence(); + + if(flag==1) + cudaDofVector[gid] = tmp*3; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + Real fy = abs(y); + + Real tmpMin = Min(fx,fy); + + if(tmpMin == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i) +{ + + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy) + return; + int total = solver->Mesh.getDimensions().x(); + //int gid = solver->Mesh.getDimensions().x() * gy + gx; + int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x(); + + int id1 = gx+gy; + int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy; + + /*---------------------------------------------------------------------------------------------------------------------------*/ + if(sweep == 1) +// for(int i = 0; i < 2*total - 1; i++) + { + if(id1 == i) + { + solver->updateValue(gx,gy); + return; + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + else if(sweep == 2) +// for(int i = 0; i < 2*total - 1; i++) + { + if(id2 == i) + { + solver->updateValue(gx,gy); + return; + } + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + else if(sweep == 3) +// for(int i = 2*total - 2; i > -1; i--) + { + if(id1 == i) + { + solver->updateValue(gx,gy); + return; + } + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + else if(sweep == 4) +// for(int i = 2*total - 2; i > -1; i--) + { + if(id2 == i) + { + solver->updateValue(gx,gy); + return; + } + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + + + +} + + +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} +#endif + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v2_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v2_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..e6b20eb4153b04248a3bf72b2198d923aa21d748 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v2_impl.h @@ -0,0 +1,588 @@ +/*************************************************************************** + tnlFastSweeping2D_CUDA_v2_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweeping.h" + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.getSpaceSteps().x(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1); + + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ +// +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// +// dofVector.save("u-00001.tnl"); + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(27, 27); + dim3 numBlocks(1 ,1); + +// for(int i = 2*n - 1; i > -1; i--) + { + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,0); + cudaDeviceSynchronize(); + } + cudaDeviceSynchronize(); + checkCudaDevice; +//// for(int i = 0; i < 2*n ; i++) +// { +// runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,0); +// cudaDeviceSynchronize(); +// } +// cudaDeviceSynchronize(); +// checkCudaDevice; +//// for(int i = 0; i < 2*n ; i++) +// { +// runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,0); +// cudaDeviceSynchronize(); +// } +// cudaDeviceSynchronize(); +// checkCudaDevice; +//// for(int i = 2*n - 1; i > -1; i--) +// { +// runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,3,0); +// cudaDeviceSynchronize(); +// } +// +// cudaDeviceSynchronize(); +// checkCudaDevice; + + cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + Index index = Mesh.getCellIndex(CoordinatesType(i,j)); + Real value = cudaDofVector[index]; + Real a,b, tmp; + + if( i == 0 ) + a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)]; + else + { + a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)], + cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] ); + } + + if( j == 0 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)]; + else + { + b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)], + cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + cudaDofVector[index] = fabsMin(value, tmp); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + int gid = Mesh.getCellIndex(CoordinatesType(gx,gy)); + + int total = blockDim.x*gridDim.x; + + + + Real tmp = 0.0; + int flag = 0; + counter = 0; + tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + + + if(!exactInput) + { + cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]); + } + __threadfence(); +// printf("-----------------------------------------------------------------------------------\n"); + + __threadfence(); + + if(gx > 0 && gx < Mesh.getDimensions().x()-1) + { + if(gy > 0 && gy < Mesh.getDimensions().y()-1) + { + + Index j = gy; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + } + +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); +// printf("****************************************************************\n"); +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0) + { +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + Index j = 0; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1) + { + Index i = gx; + Index j = Mesh.getDimensions().y() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0) + { + Index j = gy; + Index i = 0; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } +// printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == Mesh.getDimensions().x() - 1) + { + Index j = gy; + Index i = Mesh.getDimensions().x() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("##################################################################################################\n"); + if(gx == Mesh.getDimensions().x() - 1 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == Mesh.getDimensions().x() - 1 && + gy == 0) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } +// printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); + if(gx == 0 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == 0 && + gy == 0) + { +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + + __threadfence(); + + if(flag==1) + cudaDofVector[gid] = tmp*3; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + + Real tmpMin = Min(fx,abs(y)); + + if(tmpMin == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) +{ + + //int gx = threadIdx.x; + //int gy = threadIdx.y; + int id1,id2; + int nx = solver->Mesh.getDimensions().x()+ threadIdx.x; + int ny = solver->Mesh.getDimensions().y()+ threadIdx.y; + + int blockCount = solver->Mesh.getDimensions().x()/blockDim.x + 1; + + for(int gy = threadIdx.y; gy < ny;gy+=blockDim.y) + { + for(int gx = threadIdx.x; gx < nx;gx+=blockDim.x) + { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1) + { + id1 = threadIdx.x+threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + } + __syncthreads(); + } + + } + //gx+=blockDim.x; + //__syncthreads(); + } + //gx = threadIdx.x; + //gy+=blockDim.y; + //__syncthreads(); + } + /*---------------------------------------------------------------------------------------------------------------------------*/ +// gx = blockDim.x*(blockCount-1) + threadIdx.x; +// gy = threadIdx.y; + for(int gy = threadIdx.y; gy < ny;gy+=blockDim.y) + { + for(int gx = blockDim.x*(blockCount-1) + threadIdx.x; gx >- 1;gx-=blockDim.x) + { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1) + { + id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + } + __syncthreads(); + } + } + //gx-=blockDim.x; + //__syncthreads(); + } + //gx = blockDim.x*(blockCount-1) + threadIdx.x; + //gy+=blockDim.y; + //__syncthreads(); + } + /*---------------------------------------------------------------------------------------------------------------------------*/ +// gx = blockDim.x*(blockCount-1) + threadIdx.x; +// gy = blockDim.x*(blockCount-1) + threadIdx.y; + for(int gy = blockDim.x*(blockCount-1) +threadIdx.y; gy >- 1;gy-=blockDim.y) + { + for(int gx = blockDim.x*(blockCount-1) + threadIdx.x; gx >- 1;gx-=blockDim.x) + { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1) + { + id1 = threadIdx.x+threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + } + __syncthreads(); + } + } + //gx-=blockDim.x; + //__syncthreads(); + } + //gx = blockDim.x*(blockCount-1) + threadIdx.x; + //gy-=blockDim.y; + //__syncthreads(); + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + //gx = threadIdx.x; + //gy = blockDim.x*(blockCount-1) +threadIdx.y; + for(int gy = blockDim.x*(blockCount-1) +threadIdx.y; gy >- 1;gy-=blockDim.y) + { + for(int gx = threadIdx.x; gx < nx;gx+=blockDim.x) + { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && gy > -1&& gx > -1) + { + id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + } + __syncthreads(); + } + } + //gx+=blockDim.x; + //__syncthreads(); + } + //gx = threadIdx.x; + //gy-=blockDim.y; + ///__syncthreads(); + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + + + + +} + + +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} +#endif + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v3_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v3_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..d05b649f29d222bc96649d3d6ed92a7fa11cf14e --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v3_impl.h @@ -0,0 +1,920 @@ +/*************************************************************************** + tnlFastSweeping2D_CUDA_v3_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweeping.h" + + + + +__device__ double atomicSet(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong(val )); + } while (assumed != old); + return __longlong_as_double(old); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.getSpaceSteps().x(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1); + + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ +// +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// +// dofVector.save("u-00001.tnl"); + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 +1 ,n/16 +1); + int m =n/16 +1; + + for(int i = 0; i < 2*m -1; i++) + { + runCUDA<15><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,i); + //cudaDeviceSynchronize(); + } +// cudaDeviceSynchronize(); +// checkCudaDevice; +// for(int i = 0; i < 2*m -1; i++) +// { +// runCUDA<2><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i); +// cudaDeviceSynchronize(); +// } +// cudaDeviceSynchronize(); +// checkCudaDevice; +// for(int i = 0; i < 2*m -1; i++) +// { +// runCUDA<4><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,i); +// cudaDeviceSynchronize(); +// } +// cudaDeviceSynchronize(); +// checkCudaDevice; +// for(int i = 0; i < 2*m -1; i++) +// { +// runCUDA<8><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,8,i); +// cudaDeviceSynchronize(); +// } + + + + +// for(int i = 0; i < (2*m -1)/4 -1; i++) +// { +// runCUDA<15><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,15,i);//all +// cudaDeviceSynchronize(); +// } +// for(int i = (2*m -1)/4 -1; i < (2*m -1)/2 -1; i++) +// { +// runCUDA<5><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,5,i); //two +// cudaDeviceSynchronize(); +// runCUDA<10><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,10,i); //two +// cudaDeviceSynchronize(); +// } +// for(int i = (2*m -1)/2 -1; i < (2*m -1)/2 +1; i++) +// { +// runCUDA<1><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,1,i); //separate +// cudaDeviceSynchronize(); +// runCUDA<2><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,2,i); //separate +// cudaDeviceSynchronize(); +// runCUDA<4><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,4,i); //separate +// cudaDeviceSynchronize(); +// runCUDA<8><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,8,i); //separate +// cudaDeviceSynchronize(); +// } +// for(int i = (2*m -1)/2 +1; i < (2*m -1/4)*3 +1; i++) +// { +// runCUDA<5><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,5,i); //two +// cudaDeviceSynchronize(); +// runCUDA<10><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,10,i); //two +// cudaDeviceSynchronize(); +// } +// for(int i = (2*m -1/4)*3 +1; i < 2*m -1; i++) +// { +// runCUDA<15><<<numBlocks,threadsPerBlock>>>(this->cudaSolver,15,i);//all +// cudaDeviceSynchronize(); +// } +cudaDeviceSynchronize(); + checkCudaDevice; + + cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + Index index = Mesh.getCellIndex(CoordinatesType(i,j)); + Real value = cudaDofVector[index]; + Real a,b, tmp; + + if( i == 0 ) + a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)]; + else + { + a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)], + cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] ); + } + + if( j == 0 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)]; + else + { + b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)], + cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + atomicSet(&cudaDofVector[index],fabsMin(value, tmp)); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + int gid = Mesh.getCellIndex(CoordinatesType(gx,gy)); + + int total = blockDim.x*gridDim.x; + + + + Real tmp = 0.0; + int flag = 0; + counter = 0; + tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + + + if(!exactInput) + { + cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]); + } + __threadfence(); +// printf("-----------------------------------------------------------------------------------\n"); + + __threadfence(); + + if(gx > 0 && gx < Mesh.getDimensions().x()-1) + { + if(gy > 0 && gy < Mesh.getDimensions().y()-1) + { + + Index j = gy; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + } + +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); +// printf("****************************************************************\n"); +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0) + { +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + Index j = 0; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1) + { + Index i = gx; + Index j = Mesh.getDimensions().y() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0) + { + Index j = gy; + Index i = 0; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } +// printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == Mesh.getDimensions().x() - 1) + { + Index j = gy; + Index i = Mesh.getDimensions().x() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("##################################################################################################\n"); + if(gx == Mesh.getDimensions().x() - 1 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == Mesh.getDimensions().x() - 1 && + gy == 0) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } +// printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); + if(gx == 0 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == 0 && + gy == 0) + { +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + + __threadfence(); + + if(flag==1) + cudaDofVector[gid] = tmp*3; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ +// Real fx = abs(x); +// +// Real tmpMin = Min(fx,abs(y)); + + if(abs(y) > abs(x)) + return x; + else + return y; + + +} + + +template<> +__global__ void runCUDA<1>(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) +{ + + if(blockIdx.x+blockIdx.y == k) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id1 = threadIdx.x+threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + } + __syncthreads(); + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ +} + template<> + __global__ void runCUDA<2>(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) + { + if((gridDim.x - blockIdx.x - 1)+blockIdx.y == k) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + } + __syncthreads(); + } + + } + } /*---------------------------------------------------------------------------------------------------------------------------*/ + template<> + __global__ void runCUDA<4>(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) + { + if(blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id1 = threadIdx.x+threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + } + + template<> + __global__ void runCUDA<8>(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) + { + if((gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + + + + +} + + + template<> + __global__ void runCUDA<5>(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) + { + + if(blockIdx.x+blockIdx.y == k) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id1 = threadIdx.x+threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + else if(blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id1 = threadIdx.x+threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + } + + + template<> + __global__ void runCUDA<10>(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) + { + if((gridDim.x - blockIdx.x - 1)+blockIdx.y == k) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + + else if((gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + + } + + + + template<> + __global__ void runCUDA<15>(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) + { + + if(blockIdx.x+blockIdx.y == k) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id1 = threadIdx.x+threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + if((gridDim.x - blockIdx.x - 1)+blockIdx.y == k) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 0; l < 2*blockDim.x - 1; l++) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + if(blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id1 = threadIdx.x+threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id1 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + if((gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2) + { + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = threadIdx.y + blockDim.y*blockIdx.y; + + int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; + + for(int l = 2*blockDim.x - 2; l > -1; l--) + { + if(id2 == l) + { + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) + solver->updateValue(gx,gy); + return; + } + __syncthreads(); + } + + } + /*---------------------------------------------------------------------------------------------------------------------------*/ + + + + + + } + + + + + + + + + + + + + + + + + + + + + + + + + + + +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} +#endif + + + + + + +//__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int k) +//{ +// +// if(sweep==1 && blockIdx.x+blockIdx.y == k) +// { +// int gx = threadIdx.x + blockDim.x*blockIdx.x; +// int gy = threadIdx.y + blockDim.y*blockIdx.y; +// +// int id1 = threadIdx.x+threadIdx.y; +// +// for(int l = 0; l < 2*blockDim.x - 1; l++) +// { +// if(id1 == l) +// { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) +// solver->updateValue(gx,gy); +// } +// __syncthreads(); +// } +// +// } +// /*---------------------------------------------------------------------------------------------------------------------------*/ +// +// else if(sweep==2 && (gridDim.x - blockIdx.x - 1)+blockIdx.y == k) +// { +// int gx = threadIdx.x + blockDim.x*blockIdx.x; +// int gy = threadIdx.y + blockDim.y*blockIdx.y; +// +// int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; +// +// for(int l = 0; l < 2*blockDim.x - 1; l++) +// { +// if(id2 == l) +// { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) +// solver->updateValue(gx,gy); +// } +// __syncthreads(); +// } +// +// } +// /*---------------------------------------------------------------------------------------------------------------------------*/ +// +// else if(sweep==4 && blockIdx.x+blockIdx.y == gridDim.x+gridDim.y-k-2) +// { +// int gx = threadIdx.x + blockDim.x*blockIdx.x; +// int gy = threadIdx.y + blockDim.y*blockIdx.y; +// +// int id1 = threadIdx.x+threadIdx.y; +// +// for(int l = 2*blockDim.x - 2; l > -1; l--) +// { +// if(id1 == l) +// { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) +// solver->updateValue(gx,gy); +// return; +// } +// __syncthreads(); +// } +// +// } +// /*---------------------------------------------------------------------------------------------------------------------------*/ +// +// else if(sweep==8 && (gridDim.x - blockIdx.x - 1)+blockIdx.y == gridDim.x+gridDim.y-k-2) +// { +// int gx = threadIdx.x + blockDim.x*blockIdx.x; +// int gy = threadIdx.y + blockDim.y*blockIdx.y; +// +// int id2 = (blockDim.x - threadIdx.x - 1) + threadIdx.y; +// +// for(int l = 2*blockDim.x - 2; l > -1; l--) +// { +// if(id2 == l) +// { +// if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy /*&& gy > -1&& gx > -1*/) +// solver->updateValue(gx,gy); +// return; +// } +// __syncthreads(); +// } +// +// } +// /*---------------------------------------------------------------------------------------------------------------------------*/ +// +// +// +// +// +//} + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v4_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v4_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..230b6ce436bb53c40172eb43cf8b7e668f4bf891 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v4_impl.h @@ -0,0 +1,1003 @@ +/*************************************************************************** + tnlFastSweeping2D_CUDA_v4_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweeping.h" + +__device__ +double fabsMin( double x, double y) +{ + double fx = abs(x); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; +} + +__device__ +double atomicFabsMin(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) )); + } while (assumed != old); + return __longlong_as_double(old); +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweeping() +:dofVector(Mesh) +{ +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.template getSpaceStepsProducts< 1, 0 >(); + //Entity.refresh(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1); + + + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(1, 1024); + dim3 numBlocks(4,1); + + + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0); + + cudaDeviceSynchronize(); + checkCudaDevice; + + //data.setLike(dofVector.getData()); + //cudaMemcpy(data.getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaMemcpy(dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + //data.save("u-00001.tnl"); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + Real value = cudaDofVector2[Entity.getIndex()]; + Real a,b, tmp; + + if( i == 0 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + { + a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] ); + } + + if( j == 0 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + { + b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + +// cudaDofVector2[Entity.getIndex()] = fabsMin(value, tmp); + atomicFabsMin(&(cudaDofVector2[Entity.getIndex()]), tmp); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int i = threadIdx.x + blockDim.x*blockIdx.x; + int j = blockDim.y*blockIdx.y + threadIdx.y; + + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + int gid = Entity.getIndex(); + + cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]); +// +// if(abs(cudaDofVector[gid]) < 1.01*h) +// cudaDofVector2[gid] = cudaDofVector[gid]; + + + + + + if(i+1 < Mesh.getDimensions().x() && j+1 < Mesh.getDimensions().y() && !exactInput) + { + if(cudaDofVector[Entity.getIndex()] > 0) + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1111(i,j); + else + setupSquare1110(i,j); + } + else + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1101(i,j); + else + setupSquare1100(i,j); + } + } + else + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1011(i,j); + else + setupSquare1010(i,j); + } + else + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1001(i,j); + else + setupSquare1000(i,j); + } + } + } + else + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0111(i,j); + else + setupSquare0110(i,j); + } + else + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0101(i,j); + else + setupSquare0100(i,j); + } + } + else + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0011(i,j); + else + setupSquare0010(i,j); + } + else + { + if(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0001(i,j); + else + setupSquare0000(i,j); + } + } + } + + } + if(exactInput) + { + if(abs(cudaDofVector[gid]) < 1.5*h) + cudaDofVector2[gid] = cudaDofVector[gid]; + } + + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + //Real fy = abs(y); + + //Real tmpMin = Min(fx,abs(y)); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i) +{ + + int gx = 0; + int gy = threadIdx.y; + //if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy) + // return; + int n = solver->Mesh.getDimensions().x(); + int blockCount = n/blockDim.y +1; + //int gid = solver->Mesh.getDimensions().x() * gy + gx; + //int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x(); + + //int id1 = gx+gy; + //int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy; + + if(blockIdx.x==0) + { + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==1) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==2) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + else if(blockIdx.x==3) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + + + + + +} + + +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + + + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +{ +// tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); +// Entity.setCoordinates(CoordinatesType(i,j)); +// Entity.refresh(); +// tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); +// cudaDofVector2[Entity.getIndex()]=fabsMin(INT_MAX,cudaDofVector2[Entity.getIndex()]); +// cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +{ +// tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); +// Entity.setCoordinates(CoordinatesType(i,j)); +// Entity.refresh(); +// tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); +// cudaDofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,cudaDofVector2[Entity.getIndex()]); +// cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-INT_MAX,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=INT_MAX; //fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=-0.5*h; //fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=0.5*h; //fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=0.5*h; //fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=0.5*h; //fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=INT_MAX; //fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=0.5*h; //fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=INT_MAX; //fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=-0.5*h; //fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=-0.5*h; //fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=INT_MAX; //fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=0.5*h; //fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=-INT_MAX; //fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=-0.5*h; //fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=0.5*h; //fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=-0.5*h; //fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=-0.5*h; //fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=-0.5*h; //fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=-INT_MAX; //fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[Entity.getIndex()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=-0.5*h; //fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=INT_MAX; //fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=-0.5*h; //fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=0.5*h; //fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=0.5*h; //fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=-0.5*h; //fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=-INT_MAX; //fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=-0.5*h; //fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=0.5*h; //fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=-0.5*h; //fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=-0.5*h; //fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=0.5*h; //fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=0.5*h; //fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=-0.5*h; //fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=-0.5*h; //fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=0.5*h; //fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=-0.5*h; //fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=0.5*h; //fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=-0.5*h; //fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=-0.5*h; //fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=0.5*h; //fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=-0.5*h; //fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Real al,be, a,b,c,s; + al=abs(cudaDofVector[Entity.getIndex()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + cudaDofVector[Entity.getIndex()])); + + be=abs(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b = 1.0; + c = -be; + s = h/sqrt(a*a+b*b); + + + cudaDofVector2[Entity.getIndex()]=-0.5*h; //fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=-0.5*h; //fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=0.5*h; //fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=0.5*h; //fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +{ + tnlGridEntity< tnlGrid< 2,double, tnlHost, int >, 2, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + cudaDofVector2[Entity.getIndex()]=-0.5*h; //fabsMin(cudaDofVector[Entity.getIndex()],cudaDofVector2[Entity.getIndex()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=0.5*h; //fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=-0.5*h; //fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=0.5*h; //fabsMin(cudaDofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); +} +#endif + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v5_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v5_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..f9f3e28f63fc7a3ad88b98980a4454035fd299b4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_CUDA_v5_impl.h @@ -0,0 +1,697 @@ +/*************************************************************************** + tnlFastSweeping2D_CUDA_v5_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweeping.h" + +__device__ +double fabsMin( double x, double y) +{ + double fx = abs(x); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; +} + +__device__ +double atomicFabsMin(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(assumed,val) )); + } while (assumed != old); + return __longlong_as_double(old); +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.getSpaceSteps().x(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData(), this->dofVector.getSize()*sizeof(double), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(16, 16); + dim3 numBlocks(n/16 + 1 ,n/16 +1); + + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ +// +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = 0; j < Mesh.getDimensions().y(); j++) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// for(Index i = 0; i < Mesh.getDimensions().x(); i++) +// { +// for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) +// { +// updateValue(i,j); +// } +// } +// +///*---------------------------------------------------------------------------------------------------------------------------*/ +// +// +// dofVector.save("u-00001.tnl"); + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(1, 512); + dim3 numBlocks(4,1); + + + runCUDA<<<numBlocks,threadsPerBlock,3*(512+1)*sizeof(double)>>>(this->cudaSolver,0,0); + + cudaDeviceSynchronize(); + checkCudaDevice; + + cudaMemcpy(this->dofVector.getData(), cudaDofVector, this->dofVector.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + Index index = Mesh.getCellIndex(CoordinatesType(i,j)); + Real value = cudaDofVector[index]; + Real a,b, tmp; + + if( i == 0 ) + a = cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)]; + else + { + a = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<-1,0>(index)], + cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)] ); + } + + if( j == 0 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)]; + else + { + b = fabsMin( cudaDofVector[Mesh.template getCellNextToCell<0,-1>(index)], + cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + cudaDofVector[index] = fabsMin(value, tmp); + +} + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, double** sharedMem, int k3) +{ + Index index = Mesh.getCellIndex(CoordinatesType(i,j)); + Real value = sharedMem[k3+1][threadIdx.y]; + Real a,b, tmp; + + if( i == 0 ) + a = sharedMem[k3][threadIdx.y]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = sharedMem[k3+2][threadIdx.y]; + else + { + a = fabsMin( sharedMem[k3][threadIdx.y], + sharedMem[k3+2][threadIdx.y] ); + } + + if( j == 0 ) + b = sharedMem[k3][threadIdx.y+1]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = sharedMem[k3+2][threadIdx.y-1]; + else + { + b = fabsMin( sharedMem[k3][threadIdx.y+1], + sharedMem[k3+2][threadIdx.y-1] ); + } + + + if(abs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + +// sharedMem[k3+1][threadIdx.y] = this->fabsMin(value, tmp); +// atomicFabsMin(&(cudaDofVector[index]), tmp); + cudaDofVector[index] = tmp; + this->fabsMin(value, tmp); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + int gid = Mesh.getCellIndex(CoordinatesType(gx,gy)); + + int total = blockDim.x*gridDim.x; + + + + Real tmp = 0.0; + int flag = 0; + counter = 0; + tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + + + if(!exactInput) + { + cudaDofVector[gid]=cudaDofVector[gid]=0.5*h*sign(cudaDofVector[gid]); + } + __threadfence(); +// printf("-----------------------------------------------------------------------------------\n"); + + __threadfence(); + + if(gx > 0 && gx < Mesh.getDimensions().x()-1) + { + if(gy > 0 && gy < Mesh.getDimensions().y()-1) + { + + Index j = gy; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag=1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + } + +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); +// printf("****************************************************************\n"); +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == 0) + { +// printf("gx: %d, gy: %d, gid: %d \n", gx, gy,gid); + Index j = 0; + Index i = gx; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"); + if(gx > 0 && gx < Mesh.getDimensions().x()-1 && gy == Mesh.getDimensions().y() - 1) + { + Index i = gx; + Index j = Mesh.getDimensions().y() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == 0) + { + Index j = gy; + Index i = 0; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } +// printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); + if(gy > 0 && gy < Mesh.getDimensions().y()-1 && gx == Mesh.getDimensions().x() - 1) + { + Index j = gy; + Index i = Mesh.getDimensions().x() - 1; +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + +// printf("##################################################################################################\n"); + if(gx == Mesh.getDimensions().x() - 1 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == Mesh.getDimensions().x() - 1 && + gy == 0) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx-1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } +// printf("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n"); + if(gx == 0 && + gy == Mesh.getDimensions().y() - 1) + { + +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy-1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + if(gx == 0 && + gy == 0) + { +// tmp = sign(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))]); + if(cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx+1,gy))]*tmp > 0.0 && + cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy+1))]*tmp > 0.0) + + flag = 1;//cudaDofVector[Mesh.getCellIndex(CoordinatesType(gx,gy))] = tmp*INT_MAX; + } + + __threadfence(); + + if(flag==1) + cudaDofVector[gid] = tmp*3; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + //Real fy = abs(y); + + //Real tmpMin = Min(fx,abs(y)); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i) +{ + + extern __shared__ double u[]; + double* sharedMem[5]; + sharedMem[0] = u; + sharedMem[1] = &(u[blockDim.y+1]); + sharedMem[2] = &(sharedMem[1][blockDim.y+1]); + sharedMem[3] = sharedMem[1]; + sharedMem[4] = sharedMem[2]; + + int gx = 0; + int gy = threadIdx.y; + //if(solver->Mesh.getDimensions().x() <= gx || solver->Mesh.getDimensions().y() <= gy) + // return; + int n = solver->Mesh.getDimensions().x(); + int blockCount = n/blockDim.y +1; + //int gid = solver->Mesh.getDimensions().x() * gy + gx; + //int max = solver->Mesh.getDimensions().x()*solver->Mesh.getDimensions().x(); + + //int id1 = gx+gy; + //int id2 = (solver->Mesh.getDimensions().x() - gx - 1) + gy; + + + if(blockIdx.x==0) + { + if(threadIdx.y==0) + sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,0))]; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + int k3=k%3; + + if(threadIdx.y==0) + { + if(gx==n-1) + sharedMem[k3][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,gy+blockDim.y))]; + else + sharedMem[k3][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx+1,gy))]; + } +// else +// solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3+2][threadIdx.y-1]; + + if(gy<n-1) + sharedMem[k3][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))]; + + solver->updateValue(gx,gy,sharedMem,k3); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } +// else if(blockIdx.x==1) +// { +// gx=n-1; +// gy=threadIdx.y; +// +// if(threadIdx.y==0) +// sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,0))]; +// +// for(int k = 0; k < n*blockCount + blockDim.y; k++) +// { +// if(threadIdx.y < k+1 && gy < n) +// { +// int k3=k%3; +// +// if(threadIdx.y==0) +// if(gx==0) +// sharedMem[k3+2][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,gy+blockDim.y))]; +// else +// sharedMem[k3+2][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx-1,gy))]; +// else +// solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3][threadIdx.y-1]; +// +// if(gy<n-1) +// sharedMem[k3+2][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))]; +// +// +// solver->updateValue(gx,gy,sharedMem,k3); +// gx--; +// if(gx==-1) +// { +// gx=n-1; +// gy+=blockDim.y; +// } +// } +// +// +// __syncthreads(); +// } +// } +// else if(blockIdx.x==2) +// { +// gx=0; +// gy=n-blockDim.y-1+threadIdx.y; +// +// if(threadIdx.y==0) +// sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,n-1))]; +// +// for(int k = 0; k < n*blockCount + blockDim.y; k++) +// { +// if(blockDim.y-threadIdx.y < k+1 && gy > -1) +// { +// int k3=k%3; +// +// if(threadIdx.y==blockDim.y-1) +// if(gx==n-1) +// sharedMem[k3][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(0,gy-blockDim.y))]; +// else +// sharedMem[k3][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx+1,gy))]; +// else +// solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3+2][threadIdx.y-1]; +// +// if(gy<n-1) +// sharedMem[k3][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))]; +// +// +// solver->updateValue(gx,gy,sharedMem,k3); +// gx++; +// if(gx==n) +// { +// gx=0; +// gy-=blockDim.y; +// } +// } +// +// +// __syncthreads(); +// } +// } +// else if(blockIdx.x==3) +// { +// gx=n-1; +// gy=n-blockDim.y-1+threadIdx.y; +// +// if(threadIdx.y==0) +// sharedMem[1][0]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,n-1))]; +// +// +// for(int k = 0; k < n*blockCount + blockDim.y; k++) +// { +// if(blockDim.y-threadIdx.y < k+1 && gy > -1) +// { +// int k3=k%3; +// +// if(threadIdx.y==blockDim.y-1) +// if(gx==n-1) +// sharedMem[k3+2][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(n-1,gy-blockDim.y))]; +// else +// sharedMem[k3+2][n-1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx+1,gy))]; +// else +// solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy-1))]=sharedMem[k3][threadIdx.y-1]; +// +// if(gy<n-1) +// sharedMem[k3+2][threadIdx.y+1]=solver->cudaDofVector[solver->Mesh.getCellIndex(Containers::StaticVector<2,int>(gx,gy+1))]; +// +// +// solver->updateValue(gx,gy,sharedMem,k3); +// gx--; +// if(gx==-1) +// { +// gx=n-1; +// gy-=blockDim.y; +// } +// } +// +// +// __syncthreads(); +// } +// } + + + + +} + + +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver) +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy) + { + solver->initGrid(); + } + + +} +#endif + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..920806c211483d1c8cc3dabd2e194704dbb560bd --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_impl.h @@ -0,0 +1,927 @@ +/*************************************************************************** + tnlFastSweeping2D_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweeping.h" + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweeping() +:Entity(Mesh), + dofVector(Mesh), + dofVector2(Mesh) +{ +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + dofVector2.load(initialCondition); + + h = Mesh.template getSpaceStepsProducts< 1, 0 >(); + Entity.refresh(); + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + cout << "a" << endl; + return initGrid(); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().x();i++) + { + dofVector2[i]=INT_MAX*sign(dofVector[i]); + } + + for(int i = 0 ; i < Mesh.getDimensions().x()-1; i++) + { + for(int j = 0 ; j < Mesh.getDimensions().x()-1; j++) + { + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + neighbourEntities.refresh(Mesh,Entity.getIndex()); + + if(dofVector[this->Entity.getIndex()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1111(i,j); + else + setupSquare1110(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1101(i,j); + else + setupSquare1100(i,j); + } + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1011(i,j); + else + setupSquare1010(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare1001(i,j); + else + setupSquare1000(i,j); + } + } + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0111(i,j); + else + setupSquare0110(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0101(i,j); + else + setupSquare0100(i,j); + } + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()] > 0) + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0011(i,j); + else + setupSquare0010(i,j); + } + else + { + if(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()] > 0) + setupSquare0001(i,j); + else + setupSquare0000(i,j); + } + } + } + + } + } + cout << "a" << endl; + +// Real tmp = 0.0; +// Real ax=0.5/sqrt(2.0); +// +// if(!exactInput) +// { +// for(Index i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++) +// dofVector[i]=0.5*h*sign(dofVector[i]); +// } +// +// +// for(Index i = 1; i < Mesh.getDimensions().x()-1; i++) +// { +// for(Index j = 1; j < Mesh.getDimensions().y()-1; j++) +// { +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// } +// +// +// +// for(int i = 1; i < Mesh.getDimensions().x()-1; i++) +// { +// Index j = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// for(int i = 1; i < Mesh.getDimensions().x()-1; i++) +// { +// Index j = Mesh.getDimensions().y() - 1; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// for(int j = 1; j < Mesh.getDimensions().y()-1; j++) +// { +// Index i = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// for(int j = 1; j < Mesh.getDimensions().y()-1; j++) +// { +// Index i = Mesh.getDimensions().x() - 1; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// +// +// if(tmp == 0.0) +// {} +// else if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) +// {} +// else +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// } +// +// +// Index i = Mesh.getDimensions().x() - 1; +// Index j = Mesh.getDimensions().y() - 1; +// +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// +// +// +// j = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// +// +// +// i = 0; +// j = Mesh.getDimensions().y() -1; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; +// +// +// +// j = 0; +// tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); +// if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 && +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0) +// +// dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + + //data.setLike(dofVector2.getData()); + //data=dofVector2.getData(); + //cout << data.getType() << endl; + dofVector2.save("u-00000.tnl"); + //dofVector2.getData().save("u-00000.tnl"); + + return true; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + +// data.setLike(dofVector2.getData()); +// data = dofVector2.getData(); +// cout << data.getType() << endl; + dofVector2.save("u-00001.tnl"); + //dofVector2.getData().save("u-00001.tnl"); + + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j) +{ + + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + Real value = dofVector2[Entity.getIndex()]; + Real a,b, tmp; + + if( i == 0 ) + a = dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = dofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()]; + else + { + a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1, 0 >()], + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()] ); + } + + if( j == 0 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()]; + else + { + b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0, -1 >()], + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()] ); + } + + + if(fabs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + + + dofVector2[Entity.getIndex()] = fabsMin(value, tmp); + +// if(dofVector2[Entity.getIndex()] > 1.0) +// cout << value << " " << tmp << " " << dofVector2[Entity.getIndex()] << endl; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = fabs(x); + Real fy = fabs(y); + + Real tmpMin = Min(fx,fy); + + if(tmpMin == fx) + return x; + else + return y; + +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +{ +// this->Entity.setCoordinates(CoordinatesType(i,j)); +// this->Entity.refresh(); +// auto neighbourEntities = Entity.getNeighbourEntities(); +// dofVector2[Entity.getIndex()]=fabsMin(INT_MAX,dofVector2[Entity.getIndex()]); +// dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +{ +// this->Entity.setCoordinates(CoordinatesType(i,j)); +// this->Entity.refresh(); +// auto neighbourEntities = Entity.getNeighbourEntities(); +// dofVector2[Entity.getIndex()]=fabsMin(-INT_MAX,dofVector2[(Entity.getIndex())]); +// dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); +// dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-INT_MAX,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[Entity.getIndex()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + a = be/al; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(-abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()])); + + a = al-be; + b=1.0; + c=-al; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + Real al,be, a,b,c,s; + al=abs(dofVector[Entity.getIndex()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()]- + dofVector[Entity.getIndex()])); + + be=abs(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()]/ + (dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()]- + dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()])); + + a = al-be; + b=1.0; + c=-be; + s= h/sqrt(a*a+b*b); + + + dofVector2[Entity.getIndex()]=fabsMin(-abs(a*0+b*0+c)*s,dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(-abs(a*1+b*0+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(abs(a*1+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(abs(a*0+b*1+c)*s,dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); + +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +{ + this->Entity.setCoordinates(CoordinatesType(i,j)); + this->Entity.refresh(); + auto neighbourEntities = Entity.getNeighbourEntities(); + dofVector2[Entity.getIndex()]=fabsMin(dofVector[Entity.getIndex()],dofVector2[(Entity.getIndex())]); + dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 0, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 0, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 1 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 1 >()]); + dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]=fabsMin(dofVector[neighbourEntities.template getEntityIndex< 1, 0 >()],dofVector2[neighbourEntities.template getEntityIndex< 1, 0 >()]); +} + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_openMP_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_openMP_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..d766c62c528b76b61312c5c485692d6655ff8f90 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping2D_openMP_impl.h @@ -0,0 +1,399 @@ +/*************************************************************************** + tnlFastSweeping_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING2D_IMPL_H_ +#define TNLFASTSWEEPING2D_IMPL_H_ + +#include "tnlFastSweeping.h" + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + h = Mesh.getSpaceSteps().x(); + + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + +#ifdef HAVE_OPENMP +// gridLock = (omp_lock_t*) malloc(sizeof(omp_lock_t)*Mesh.getDimensions().x()*Mesh.getDimensions().y()); +// +// for(int i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++) +// omp_init_lock(&gridLock[i]); +#endif + + return initGrid(); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + + Real tmp = 0.0; + + if(!exactInput) + { + for(Index i = 0; i < Mesh.getDimensions().x()*Mesh.getDimensions().y(); i++) + dofVector[i]=0.5*h*sign(dofVector[i]); + } + + + for(Index i = 1; i < Mesh.getDimensions().x()-1; i++) + { + for(Index j = 1; j < Mesh.getDimensions().y()-1; j++) + { + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + } + + + + for(int i = 1; i < Mesh.getDimensions().x()-1; i++) + { + Index j = 0; + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 ) + {} + else + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + + for(int i = 1; i < Mesh.getDimensions().x()-1; i++) + { + Index j = Mesh.getDimensions().y() - 1; + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + + for(int j = 1; j < Mesh.getDimensions().y()-1; j++) + { + Index i = 0; + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + + for(int j = 1; j < Mesh.getDimensions().y()-1; j++) + { + Index i = Mesh.getDimensions().x() - 1; + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + + + if(tmp == 0.0) + {} + else if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp < 0.0 || + dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp < 0.0 ) + {} + else + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + } + + + Index i = Mesh.getDimensions().x() - 1; + Index j = Mesh.getDimensions().y() - 1; + + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 && + dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0) + + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + + + + j = 0; + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + if(dofVector[Mesh.getCellIndex(CoordinatesType(i-1,j))]*tmp > 0.0 && + dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0) + + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + + + + i = 0; + j = Mesh.getDimensions().y() -1; + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 && + dofVector[Mesh.getCellIndex(CoordinatesType(i,j-1))]*tmp > 0.0) + + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + + + + j = 0; + tmp = sign(dofVector[Mesh.getCellIndex(CoordinatesType(i,j))]); + if(dofVector[Mesh.getCellIndex(CoordinatesType(i+1,j))]*tmp > 0.0 && + dofVector[Mesh.getCellIndex(CoordinatesType(i,j+1))]*tmp > 0.0) + + dofVector[Mesh.getCellIndex(CoordinatesType(i,j))] = tmp*INT_MAX; + + + dofVector.save("u-00000.tnl"); + + return true; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + DofVectorType d2,d3,d4; + d2.setLike(dofVector); + d2=dofVector; + d3.setLike(dofVector); + d3=dofVector; + d4.setLike(dofVector); + d4=dofVector; + + +#ifdef HAVE_OPENMP +#pragma omp parallel sections num_threads(4) + { + { +#endif + + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,&dofVector); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ +#ifdef HAVE_OPENMP + } +#pragma omp section + { +#endif + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,&d2); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ +#ifdef HAVE_OPENMP + } +#pragma omp section + { +#endif + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j, &d3); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ +#ifdef HAVE_OPENMP + } +#pragma omp section + { +#endif + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j, &d4); + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ +#ifdef HAVE_OPENMP + } + } +#endif + + +#ifdef HAVE_OPENMP +#pragma omp parallel for num_threads(4) schedule(dynamic) +#endif + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + int index = Mesh.getCellIndex(CoordinatesType(i,j)); + dofVector[index] = fabsMin(dofVector[index], d2[index]); + dofVector[index] = fabsMin(dofVector[index], d3[index]); + dofVector[index] = fabsMin(dofVector[index], d4[index]); + } + } + + dofVector.save("u-00001.tnl"); + + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, DofVectorType* grid) +{ + Index index = Mesh.getCellIndex(CoordinatesType(i,j)); + Real value = (*grid)[index]; + Real a,b, tmp; + + if( i == 0 ) + a = (*grid)[Mesh.template getCellNextToCell<1,0>(index)]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = (*grid)[Mesh.template getCellNextToCell<-1,0>(index)]; + else + { + a = fabsMin( (*grid)[Mesh.template getCellNextToCell<-1,0>(index)], + (*grid)[Mesh.template getCellNextToCell<1,0>(index)] ); + } + + if( j == 0 ) + b = (*grid)[Mesh.template getCellNextToCell<0,1>(index)]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = (*grid)[Mesh.template getCellNextToCell<0,-1>(index)]; + else + { + b = fabsMin( (*grid)[Mesh.template getCellNextToCell<0,-1>(index)], + (*grid)[Mesh.template getCellNextToCell<0,1>(index)] ); + } + + + if(fabs(a-b) >= h) + tmp = fabsMin(a,b) + sign(value)*h; + else + tmp = 0.5 * (a + b + sign(value)*sqrt(2.0 * h * h - (a - b) * (a - b) ) ); + +#ifdef HAVE_OPENMP +// omp_set_lock(&gridLock[index]); +#endif + (*grid)[index] = fabsMin(value, tmp); +#ifdef HAVE_OPENMP +// omp_unset_lock(&gridLock[index]); +#endif +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = fabs(x); + Real fy = fabs(y); + + Real tmpMin = Min(fx,fy); + + if(tmpMin == fx) + return x; + else + return y; + + +} + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_CUDA_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_CUDA_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..da045676ae1f119e73cc4539732b31d5d632ca23 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_CUDA_impl.h @@ -0,0 +1,961 @@ +/*************************************************************************** + tnlFastSweeping2D_CUDA_v4_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING3D_IMPL_H_ +#define TNLFASTSWEEPING3D_IMPL_H_ + +#include "tnlFastSweeping.h" + +//__device__ +//double fabsMin( double x, double y) +//{ +// double fx = abs(x); +// +// if(Min(fx,abs(y)) == fx) +// return x; +// else +// return y; +//} +// +//__device__ +//double atomicFabsMin(double* address, double val) +//{ +// unsigned long long int* address_as_ull = +// (unsigned long long int*)address; +// unsigned long long int old = *address_as_ull, assumed; +// do { +// assumed = old; +// old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(assumed,val) )); +// } while (assumed != old); +// return __longlong_as_double(old); +//} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + + this->h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >(); + counter = 0; + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; + + +#ifdef HAVE_CUDA + + cudaMalloc(&(cudaDofVector), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + cudaMalloc(&(cudaDofVector2), this->dofVector.getData().getSize()*sizeof(double)); + cudaMemcpy(cudaDofVector2, this->dofVector.getData().getData(), this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyHostToDevice); + + + cudaMalloc(&(this->cudaSolver), sizeof(tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >), cudaMemcpyHostToDevice); + +#endif + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(8, 8,8); + dim3 numBlocks(n/8 + 1, n/8 +1, n/8 +1); + + cudaDeviceSynchronize(); + checkCudaDevice; + initCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + return true; +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + int n = Mesh.getDimensions().x(); + dim3 threadsPerBlock(1, 1024); + dim3 numBlocks(8,1); + + + runCUDA<<<numBlocks,threadsPerBlock>>>(this->cudaSolver,0,0); + + cudaDeviceSynchronize(); + checkCudaDevice; + + cudaMemcpy(this->dofVector.getData().getData(), cudaDofVector2, this->dofVector.getData().getSize()*sizeof(double), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + cudaFree(cudaDofVector); + cudaFree(cudaDofVector2); + cudaFree(cudaSolver); + dofVector.save("u-00001.tnl"); + cudaDeviceSynchronize(); + return true; +} + + + + +#ifdef HAVE_CUDA + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k) +{ + tnlGridEntity< tnlGrid< 3,double, tnlHost, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j,k)); + Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity); + Real value = cudaDofVector2[Entity.getIndex()]; + Real a,b,c, tmp; + + if( i == 0 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0 >()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + else + { + a = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0 >()] ); + } + + if( j == 0 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0 >()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0 >()]; + else + { + b = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0 >()] ); + } + + if( k == 0 ) + c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1 >()]; + else if( k == Mesh.getDimensions().z() - 1 ) + c = cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1 >()]; + else + { + c = fabsMin( cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1 >()], + cudaDofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1 >()] ); + } + + Real hD = 3.0*h*h - 2.0*(a*a + b*b + c*c - a*b - a*c - b*c); + + if(hD < 0.0) + tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h; + else + tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) ); + + atomicFabsMin(&cudaDofVector2[Entity.getIndex()],tmp); + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid(int i, int j, int k) +{ + tnlGridEntity< tnlGrid< 3,double, tnlHost, int >, 3, tnlGridEntityNoStencilStorage > Entity(Mesh); + Entity.setCoordinates(CoordinatesType(i,j,k)); + Entity.refresh(); + int gid = Entity.getIndex(); + + if(abs(cudaDofVector[gid]) < 1.0*h) + cudaDofVector2[gid] = 0.5*h;//cudaDofVector[gid]; + else + cudaDofVector2[gid] = INT_MAX*sign(cudaDofVector[gid]); + + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +__device__ +Real tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = abs(x); + if(Min(fx,abs(y)) == fx) + return x; + else + return y; + + +} + + + +__global__ void runCUDA(tnlFastSweeping< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i) +{ + + int gx = 0; + int gy = threadIdx.y; + + int n = solver->Mesh.getDimensions().x(); + int blockCount = n/blockDim.y +1; + + if(blockIdx.x==0) + { + for(int gz = 0; gz < n;gz++) + { + gx = 0; + gy = threadIdx.y; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + __syncthreads(); + } + } + else if(blockIdx.x==1) + { + for(int gz = 0; gz < n;gz++) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==2) + { + + for(int gz = 0; gz < n;gz++) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==3) + { + for(int gz = 0; gz < n;gz++) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + + + + + else if(blockIdx.x==4) + { + for(int gz = n-1; gz > -1;gz--) + { + gx = 0; + gy = threadIdx.y; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==5) + { + for(int gz = n-1; gz > -1;gz--) + { + gx=n-1; + gy=threadIdx.y; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy < n) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy+=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==6) + { + + for(int gz = n-1; gz > -1;gz--) + { + gx=0; + gy=n-threadIdx.y-1; + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx++; + if(gx==n) + { + gx=0; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + else if(blockIdx.x==7) + { + for(int gz = n-1; gz > -1;gz--) + { + gx=n-1; + gy=n-threadIdx.y-1; + + for(int k = 0; k < n*blockCount + blockDim.y; k++) + { + if(threadIdx.y < k+1 && gy > -1) + { + solver->updateValue(gx,gy,gz); + gx--; + if(gx==-1) + { + gx=n-1; + gy-=blockDim.y; + } + } + + + __syncthreads(); + } + } + } + + + + +} + + +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 3,double, tnlHost, int >, double, int >* solver) +{ + int gx = threadIdx.x + blockDim.x*blockIdx.x; + int gy = blockDim.y*blockIdx.y + threadIdx.y; + int gz = blockDim.z*blockIdx.z + threadIdx.z; + + if(solver->Mesh.getDimensions().x() > gx && solver->Mesh.getDimensions().y() > gy && solver->Mesh.getDimensions().z() > gz) + { + solver->initGrid(gx,gy,gz); + } + + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1111( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(INT_MAX,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0000( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(-INT_MAX,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-INT_MAX,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1110( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1101( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1011( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0111( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0001( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0010( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0100( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1000( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// a = be/al; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +// +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1100( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = al-be; +// b=1.0; +// c=-al; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1010( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = al-be; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(-abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare1001( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +// +// +// +// +// +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0011( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)])); +// +// a = al-be; +// b=1.0; +// c=-al; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0101( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// Real al,be, a,b,c,s; +// al=abs(cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,0>(index)])); +// +// be=abs(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)]/ +// (cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)]- +// cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)])); +// +// a = al-be; +// b=1.0; +// c=-be; +// s= h/sqrt(a*a+b*b); +// +// +// cudaDofVector2[index]=fabsMin(-abs(a*0+b*0+c)*s,cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(-abs(a*1+b*0+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(abs(a*1+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(abs(a*0+b*1+c)*s,cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +// +//} +// +//template< typename MeshReal, +// typename Device, +// typename MeshIndex, +// typename Real, +// typename Index > +//void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: setupSquare0110( Index i, Index j) +//{ +// Index index = Mesh.getCellIndex(CoordinatesType(i,j)); +// cudaDofVector2[index]=fabsMin(cudaDofVector[index],cudaDofVector2[(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<0,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<0,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,1>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,1>(index)]); +// cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]=fabsMin(cudaDofVector[Mesh.template getCellNextToCell<1,0>(index)],cudaDofVector2[Mesh.template getCellNextToCell<1,0>(index)]); +//} +#endif + + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..dd5681e6d88b3fa666f210d0fe24f2423ac78b68 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping3D_impl.h @@ -0,0 +1,307 @@ +/*************************************************************************** + tnlFastSweeping2D_impl.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING3D_IMPL_H_ +#define TNLFASTSWEEPING3D_IMPL_H_ + +#include "tnlFastSweeping.h" + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +String tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return String( "tnlFastSweeping< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: tnlFastSweeping() +:Entity(Mesh), + dofVector(Mesh), + dofVector2(Mesh) +{ +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const Config::ParameterContainer& parameters ) +{ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + + if( ! Mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + if( ! dofVector.load( initialCondition ) ) + { + cerr << "I am not able to load the initial condition from the file " << meshFile << "." << endl; + return false; + } + dofVector2.load(initialCondition); + + h = Mesh.template getSpaceStepsProducts< 1, 0, 0 >(); + Entity.refresh(); + + const String& exact_input = parameters.getParameter< String >( "exact-input" ); + + if(exact_input == "no") + exactInput=false; + else + exactInput=true; +// cout << "bla "<<endl; + return initGrid(); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: initGrid() +{ + for(int i=0; i< Mesh.getDimensions().x()*Mesh.getDimensions().y()*Mesh.getDimensions().z();i++) + { + + if (abs(dofVector[i]) < 1.8*h) + dofVector2[i]=dofVector[i]; + else + dofVector2[i]=INT_MAX*sign(dofVector[i]); + } + + return true; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: run() +{ + + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + for(Index k = 0; k < Mesh.getDimensions().z(); k++) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + + + + + + + + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = 0; j < Mesh.getDimensions().y(); j++) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = Mesh.getDimensions().x() - 1; i > -1; i--) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + for(Index k = Mesh.getDimensions().z() -1; k > -1; k--) + { + for(Index i = 0; i < Mesh.getDimensions().x(); i++) + { + for(Index j = Mesh.getDimensions().y() - 1; j > -1; j--) + { + updateValue(i,j,k); + } + } + } + +/*---------------------------------------------------------------------------------------------------------------------------*/ + + + dofVector2.save("u-00001.tnl"); + + cout << "bla 3"<<endl; + return true; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +void tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: updateValue( Index i, Index j, Index k) +{ + this->Entity.setCoordinates(CoordinatesType(i,j,k)); + this->Entity.refresh(); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity); + Real value = dofVector2[Entity.getIndex()]; + Real a,b,c, tmp; + + if( i == 0 ) + a = dofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0>()]; + else if( i == Mesh.getDimensions().x() - 1 ) + a = dofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0 >()]; + else + { + a = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< -1, 0, 0>()], + dofVector2[neighbourEntities.template getEntityIndex< 1, 0, 0>()] ); + } + + if( j == 0 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0>()]; + else if( j == Mesh.getDimensions().y() - 1 ) + b = dofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0>()]; + else + { + b = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0, -1, 0>()], + dofVector2[neighbourEntities.template getEntityIndex< 0, 1, 0>()] ); + } + + if( k == 0 ) + c = dofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1>()]; + else if( k == Mesh.getDimensions().z() - 1 ) + c = dofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1>()]; + else + { + c = fabsMin( dofVector2[neighbourEntities.template getEntityIndex< 0, 0, -1>()], + dofVector2[neighbourEntities.template getEntityIndex< 0, 0, 1>()] ); + } + + Real hD = 3.0*h*h - 2.0*(a*a+b*b+c*c-a*b-a*c-b*c); + + if(hD < 0.0) + tmp = fabsMin(a,fabsMin(b,c)) + sign(value)*h; + else + tmp = (1.0/3.0) * ( a + b + c + sign(value)*sqrt(hD) ); + + + dofVector2[Entity.getIndex()] = fabsMin(value, tmp); +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: fabsMin( Real x, Real y) +{ + Real fx = fabs(x); + Real fy = fabs(y); + + Real tmpMin = Min(fx,fy); + + if(tmpMin == fx) + return x; + else + return y; + +} + + + +#endif /* TNLFASTSWEEPING_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweepingSolver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweepingSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..e5e2e1d7dfecceceb47f34bc46480daaff9975ab --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweepingSolver.h @@ -0,0 +1,34 @@ +/* + * File: tnlFastSweepingSolver.h + * Author: oberhuber + * + * Created on July 12, 2016, 6:04 PM + */ + +#pragma once + +#include <functions/tnlConstantFunction.h> +#include <problems/tnlPDEProblem.h> + +template< typename Mesh, + typename Anisotropy = tnlConstanstFunction< Mesh > > +class tnlFastSweepingSolver : public tnlPDEProblem< Mesh, + typename Mesh::RealType, + typename Mesh::DeviceType, + typename Mesh::IndexType > +{ + public: + + typedef typename DifferentialOperator::RealType RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef typename DifferentialOperator::IndexType IndexType; + + typedef tnlMeshFunction< Mesh > MeshFunctionType; + typedef tnlPDEProblem< Mesh, TimeDependentProblem, RealType, DeviceType, IndexType > BaseType; + + using typename BaseType::MeshType; + using typename BaseType::DofVectorType; + using typename BaseType::MeshDependentDataType; +}; + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping_CUDA.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping_CUDA.h new file mode 100644 index 0000000000000000000000000000000000000000..310cdf3f3028eb68e71c31d821ffea1538615724 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/fast-sweeping/tnlFastSweeping_CUDA.h @@ -0,0 +1,194 @@ +/*************************************************************************** + tnlFastSweeping_CUDA.h - description + ------------------- + begin : Oct 15 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +#ifndef TNLFASTSWEEPING_H_ +#define TNLFASTSWEEPING_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> + +#include <functions/tnlMeshFunction.h> +#include <limits.h> +#include <core/tnlDevice.h> +#include <ctime> + + + + + +template< typename Mesh, + typename Real, + typename Index > +class tnlFastSweeping +{}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + tnlFastSweeping(); + + __host__ static String getType(); + __host__ bool init( const Config::ParameterContainer& parameters ); + __host__ bool run(); + +#ifdef HAVE_CUDA + __device__ bool initGrid(); + __device__ void updateValue(const Index i, const Index j); + __device__ void updateValue(const Index i, const Index j, double** sharedMem, const int k3); + __device__ Real fabsMin(const Real x, const Real y); + + tnlFastSweeping< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver; + double* cudaDofVector; + double* cudaDofVector2; + int counter; + __device__ void setupSquare1000(Index i, Index j); + __device__ void setupSquare1100(Index i, Index j); + __device__ void setupSquare1010(Index i, Index j); + __device__ void setupSquare1001(Index i, Index j); + __device__ void setupSquare1110(Index i, Index j); + __device__ void setupSquare1101(Index i, Index j); + __device__ void setupSquare1011(Index i, Index j); + __device__ void setupSquare1111(Index i, Index j); + __device__ void setupSquare0000(Index i, Index j); + __device__ void setupSquare0100(Index i, Index j); + __device__ void setupSquare0010(Index i, Index j); + __device__ void setupSquare0001(Index i, Index j); + __device__ void setupSquare0110(Index i, Index j); + __device__ void setupSquare0101(Index i, Index j); + __device__ void setupSquare0011(Index i, Index j); + __device__ void setupSquare0111(Index i, Index j); +#endif + + MeshType Mesh; + +protected: + + + + bool exactInput; + + tnlMeshFunction<MeshType> dofVector; + DofVectorType data; + + + RealType h; + + +}; + + + + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + + __host__ static String getType(); + __host__ bool init( const Config::ParameterContainer& parameters ); + __host__ bool run(); + +#ifdef HAVE_CUDA + __device__ bool initGrid(int i, int j, int k); + __device__ void updateValue(const Index i, const Index j, const Index k); + __device__ void updateValue(const Index i, const Index j, const Index k, double** sharedMem, const int k3); + __device__ Real fabsMin(const Real x, const Real y); + + tnlFastSweeping< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index >* cudaSolver; + double* cudaDofVector; + double* cudaDofVector2; + int counter; +#endif + + MeshType Mesh; + +protected: + + + + bool exactInput; + + tnlMeshFunction<MeshType> dofVector; + DofVectorType data; + + RealType h; + + +}; + + + + + + + +#ifdef HAVE_CUDA +//template<int sweep_t> +__global__ void runCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver, int sweep, int i); +__global__ void runCUDA(tnlFastSweeping< tnlGrid< 3,double, tnlHost, int >, double, int >* solver, int sweep, int i); + +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 2,double, tnlHost, int >, double, int >* solver); +__global__ void initCUDA(tnlFastSweeping< tnlGrid< 3,double, tnlHost, int >, double, int >* solver); +#endif + +/*various implementtions.... choose one*/ +//#include "tnlFastSweeping2D_CUDA_impl.h" +//#include "tnlFastSweeping2D_CUDA_v2_impl.h" +//#include "tnlFastSweeping2D_CUDA_v3_impl.h" +#include "tnlFastSweeping2D_CUDA_v4_impl.h" +//#include "tnlFastSweeping2D_CUDA_v5_impl.h" + + +#include "tnlFastSweeping3D_CUDA_impl.h" + +#endif /* TNLFASTSWEEPING_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..bd5ed12005cdec8df667d4feae4a4e0f65dbf46e --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/CMakeLists.txt @@ -0,0 +1,23 @@ +set( tnl_hamilton_jacobi_parallel_map_SOURCES +# MainBuildConfig.h +# tnlParallelMapSolver2D_impl.h +# tnlParallelMapSolver.h +# parallelMapConfig.h +# main.cu + main.cpp) + + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(hamilton-jacobi-parallel-map${debugExt} main.cu) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(hamilton-jacobi-parallel-map${debugExt} main.cpp) +ENDIF( BUILD_CUDA ) +target_link_libraries (hamilton-jacobi-parallel-map${debugExt} tnl${debugExt}-${tnlVersion} ) + + +INSTALL( TARGETS hamilton-jacobi-parallel-map${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +#INSTALL( FILES ${tnl_hamilton_jacobi_parallel_map_SOURCES} +# DESTINATION share/tnl-${tnlVersion}/examples/hamilton-jacobi-parallel-map ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/MainBuildConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/MainBuildConfig.h @@ -0,0 +1,64 @@ +/*************************************************************************** + MainBuildConfig.h - description + ------------------- + begin : Jul 7, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MAINBUILDCONFIG_H_ +#define MAINBUILDCONFIG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class MainBuildConfig +{ + public: + + static void print() { cerr << "MainBuildConfig" << endl; } +}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && + tnlConfigTagReal< MainBuildConfig, Real >::enabled && + tnlConfigTagDevice< MainBuildConfig, Device >::enabled && + tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* MAINBUILDCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/gnuplot.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/gnuplot.txt new file mode 100644 index 0000000000000000000000000000000000000000..d4ae61983910a676269a23e3d992f5f46ea83a8f --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/gnuplot.txt @@ -0,0 +1,32 @@ +tomas@tomas-linux:~/Desktop/VU_CPU_MAPA/work_dir$ gnuplot + + G N U P L O T + Version 4.6 patchlevel 4 last modified 2013-10-02 + Build System: Linux x86_64 + + Copyright (C) 1986-1993, 1998, 2004, 2007-2013 + Thomas Williams, Colin Kelley and many others + + gnuplot home: http://www.gnuplot.info + faq, bugs, etc: type "help FAQ" + immediate help: type "help" (plot window: hit 'h') + +Terminal type set to 'wxt' +gnuplot> set cntrparam levels 15 +gnuplot> set cntrparam bspline +gnuplot> set contour +gnuplot> splot 'u-00001.gplt' + +gnuplot> unset surface +gnuplot> splot 'u-00001.gplt' + +gnuplot> set table "test.gplt" +gnuplot> splot 'u-00001.gplt' +gnuplot> unset table + +gnuplot> set table "test2.gplt" +gnuplot> plot 'test.gplt' index 10 +gnuplot> unset table + +gnuplot> plot 'test2.gplt' + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b13498e17330fae7bb00a0bdc2abcc7a19f8e7a8 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7101976712e153d73c5f0979b211164a36ec648d --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.cu @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cu - description + ------------------- + begin : Mar 30 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.h new file mode 100644 index 0000000000000000000000000000000000000000..55a0942f81721c1e90e670aaae18941471f6e13d --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/main.h @@ -0,0 +1,98 @@ +/*************************************************************************** + main.h - description + ------------------- + begin : Mar 22 , 2016 + copyright : (C) 2016 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "tnlParallelMapSolver.h" +#include "parallelMapConfig.h" +#include "MainBuildConfig.h" +#include <solvers/tnlBuildConfigTags.h> +#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovMap.h> +#include <mesh/tnlGrid.h> +#include <core/tnlDevice.h> +#include <time.h> +#include <ctime> + +typedef MainBuildConfig BuildConfig; + +int main( int argc, char* argv[] ) +{ + time_t start; + time_t stop; + time(&start); + std::clock_t start2= std::clock(); + Config::ParameterContainer parameters; + tnlConfigDescription configDescription; + parallelMapConfig< BuildConfig >::configSetup( configDescription ); + + if( ! parseCommandLine( argc, argv, configDescription, parameters ) ) + return false; + + + tnlDeviceEnum device; + device = tnlHostDevice; + + const int& dim = parameters.getParameter< int >( "dim" ); + + if(dim == 2) + { + + typedef parallelGodunovMapScheme< tnlGrid<2,double,tnlHost, int>, double, int > SchemeTypeHost; +/*#ifdef HAVE_CUDA + typedef parallelGodunovMapScheme< tnlGrid<2,double,tnlCuda, int>, double, int > SchemeTypeDevice; +#endif +#ifndef HAVE_CUDA*/ + typedef parallelGodunovMapScheme< tnlGrid<2,double,tnlHost, int>, double, int > SchemeTypeDevice; +/*#endif*/ + + if(device==tnlHostDevice) + { + typedef tnlHost Device; + + + tnlParallelMapSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver loop..." << endl; + solver.run(); + } + else if(device==tnlCudaDevice ) + { + typedef tnlCuda Device; +//typedef parallelGodunovMapScheme< tnlGrid<2,double,Device, int>, double, int > SchemeType; + + tnlParallelMapSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver loop..." << endl; + solver.run(); + } + } + + + time(&stop); + cout << endl; + cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl; + return EXIT_SUCCESS; +} + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/mapa_png.png b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/mapa_png.png new file mode 100644 index 0000000000000000000000000000000000000000..668b6fe24b17b2fec486db28505b41e3beb2091a Binary files /dev/null and b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/mapa_png.png differ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/no-Makefile b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/no-Makefile new file mode 100644 index 0000000000000000000000000000000000000000..bfdc1ef236ca02ecfe6bc88f81d872e9524ec621 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/no-Makefile @@ -0,0 +1,41 @@ +TNL_VERSION=0.1 +TNL_INSTALL_DIR=${HOME}/local/lib +TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION} + +TARGET = hamiltonJacobiParallelSolver +#CONFIG_FILE = $(TARGET).cfg.desc +INSTALL_DIR = ${HOME}/local +CXX = g++ +CUDA_CXX = nvcc +OMP_FLAGS = -DHAVE_OPENMP -fopenmp +CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O3 $(OMP_FLAGS) -DDEBUG +LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-0.1 -lgomp + +SOURCES = main.cpp +HEADERS = +OBJECTS = main.o +DIST = $(SOURCES) Makefile + +all: $(TARGET) +clean: + rm -f $(OBJECTS) + rm -f $(TARGET)-conf.h + +dist: $(DIST) + tar zcvf $(TARGET).tgz $(DIST) + +install: $(TARGET) + cp $(TARGET) $(INSTALL_DIR)/bin + cp $(CONFIG_FILE) $(INSTALL_DIR)/share + +uninstall: $(TARGET) + rm -f $(INSTALL_DIR)/bin/$(TARGET) + rm -f $(CONFIG_FILE) $(INSTALL_DIR)/share + +$(TARGET): $(OBJECTS) + $(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS) + +%.o: %.cpp $(HEADERS) + $(CXX) -c -o $@ $(CXX_FLAGS) $< + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/parallelMapConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/parallelMapConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..c07ee95aa04bb8c7a1f3cc376aabd859ff7bc5be --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/parallelMapConfig.h @@ -0,0 +1,47 @@ +/*************************************************************************** + parallelMapConfig.h - description + ------------------- + begin : Mar 22 , 2016 + copyright : (C) 2016 by Tomas Sobotik + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef HAMILTONJACOBIPARALLELMAPPROBLEMCONFIG_H_ +#define HAMILTONJACOBIPARALLELMAPPROBLEMCONFIG_H_ + +#include <config/tnlConfigDescription.h> + +template< typename ConfigTag > +class parallelMapConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Parallel Eikonal solver settings:" ); + config.addEntry < String > ( "problem-name", "This defines particular problem.", "hamilton-jacobi-parallel" ); + config.addEntry < String > ( "scheme", "This defines scheme used for discretization.", "godunov" ); + config.addEntryEnum( "godunov" ); + config.addEntryEnum( "upwind" ); + config.addRequiredEntry < String > ( "initial-condition", "Initial condition for solver"); + config.addRequiredEntry < String > ( "map", "Gradient map for solver"); + config.addEntry < String > ( "mesh", "Name of mesh.", "mesh.tnl" ); + config.addEntry < double > ( "epsilon", "This defines epsilon for smoothening of sign().", 0.0 ); + config.addEntry < double > ( "delta", " Allowed difference on subgrid boundaries", 0.0 ); + config.addRequiredEntry < double > ( "stop-time", " Final time for solver"); + config.addRequiredEntry < double > ( "initial-tau", " initial tau for solver" ); + config.addEntry < double > ( "cfl-condition", " CFL condition", 0.0 ); + config.addEntry < int > ( "subgrid-size", "Subgrid size.", 16 ); + config.addRequiredEntry < int > ( "dim", "Dimension of problem."); + } +}; + +#endif /* HAMILTONJACOBIPARALLELMAPPROBLEMCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/run b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/run new file mode 100755 index 0000000000000000000000000000000000000000..48441996274633f8d391d9b32978b05b2e4fa263 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/run @@ -0,0 +1,43 @@ +#!/bin/bash + +dimensions=2 + +size=2 + +time=50 + +rm -r work_dir +mkdir work_dir +cp mapa_png.png work_dir/mapa_png.png +cd work_dir + +tnl-image-converter --image-format png\ + --input-images mapa_png.png + + +tnl-init --test-function sdf-para \ + --x-centre 0.5 \ + --y-centre 1.0 \ + --offset 0.05 \ + --output-file init.tnl \ + --final-time 0.0 \ + --snapshot-period 0.1 + +hamilton-jacobi-parallel-map-dbg --initial-condition init.tnl \ + --map mapa_png.tnl \ + --cfl-condition 50 \ + --mesh mesh.tnl \ + --initial-tau 1.0e-3 \ + --epsilon 4.0 \ + --delta 0.0 \ + --stop-time $time \ + --scheme godunov \ + --subgrid-size 8 \ + --dim $dimensions + + +#cp ../template.dat1 template.dat1 +#cp ../template.dat2 template.dat2 +#cp ../gplt2eps.py gplt2eps.py +cd .. + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnl-err2eoc-2.py b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnl-err2eoc-2.py new file mode 100755 index 0000000000000000000000000000000000000000..f8cde3768e9b76156507e133f8bc3ecaa526fc71 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnl-err2eoc-2.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +import sys, string, math + +arguments = sys. argv[1:] +format = "txt" +output_file_name = "eoc-table.txt" +input_files = [] +verbose = 1 +size = 1.0 + +i = 0 +while i < len( arguments ): + if arguments[ i ] == "--format": + format = arguments[ i + 1 ] + i = i + 2 + continue + if arguments[ i ] == "--output-file": + output_file_name = arguments[ i + 1 ] + i = i + 2 + continue + if arguments[ i ] == "--verbose": + verbose = float( arguments[ i + 1 ] ) + i = i +2 + continue + if arguments[ i ] == "--size": + size = float( arguments[ i + 1 ] ) + i = i +2 + continue + input_files. append( arguments[ i ] ) + i = i + 1 + +if not verbose == 0: + print "Writing to " + output_file_name + " in " + format + "." + +h_list = [] +l1_norm_list = [] +l2_norm_list = [] +max_norm_list = [] +items = 0 + +for file_name in input_files: + if not verbose == 0: + print "Processing file " + file_name + file = open( file_name, "r" ) + + l1_max = 0.0 + l_max_max = 0.0 + file.readline(); + file.readline(); + for line in file. readlines(): + data = string. split( line ) + h_list. append( size/(float(file_name[0:len(file_name)-5] ) - 1.0) ) + l1_norm_list. append( float( data[ 1 ] ) ) + l2_norm_list. append( float( data[ 2 ] ) ) + max_norm_list. append( float( data[ 3 ] ) ) + items = items + 1 + if not verbose == 0: + print line + file. close() + +h_width = 12 +err_width = 15 +file = open( output_file_name, "w" ) +if format == "latex": + file. write( "\\begin{tabular}{|r|l|l|l|l|l|l|}\\hline\n" ) + file. write( "\\raisebox{-1ex}[0ex]{$h$}& \n" ) + file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_1\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" ) + file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_2\\left(\\omega_h;\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" ) + file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_\\infty\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}\\\\ \\cline{2-7} \n" ) + file. write( " " + string. rjust( " ", h_width ) + "&" + + string. rjust( "Error", err_width ) + "&" + + string. rjust( "{\\bf EOC}", err_width ) + "&" + + string. rjust( "Error", err_width ) + "&" + + string. rjust( "{\\bf EOC}", err_width ) + "&" + + string. rjust( "Error.", err_width ) + "&" + + string. rjust( "{\\bf EOC}", err_width ) + + "\\\\ \\hline \\hline \n") +if format == "txt": + file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" ) + file. write( "| h | L1 Err. | L1 EOC. | L2 Err. | L2 EOC | MAX Err. | MAX EOC |\n" ) + file. write( "+==============+================+================+================+================+================+================+\n" ) + + +i = 0 +while i < items: + if i == 0: + if format == "latex": + file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" + + string. rjust( " ", err_width ) + "&"+ + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" + + string. rjust( " ", err_width ) + "&" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" + + string. rjust( " ", err_width ) + "\\\\\n" ) + if format == "txt": + file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" + + string. rjust( " ", err_width ) + " |" + + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" + + string. rjust( " ", err_width ) + " |" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" + + string. rjust( " ", err_width ) + " |\n" ) + file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" ) + i = i + 1; + continue + if h_list[ i ] == h_list[ i - 1 ]: + print "Unable to count eoc since h[ " + \ + str( i ) + " ] = h[ " + str( i - 1 ) + \ + " ] = " + str( h_list[ i ] ) + ". \n" + file. write( " eoc error: h[ " + \ + str( i ) + " ] = h[ " + str( i - 1 ) + \ + " ] = " + str( h_list[ i ] ) + ". \n" ) + else: + h_ratio = math. log( h_list[ i ] / h_list[ i - 1 ] ) + l1_ratio = math. log( l1_norm_list[ i ] / l1_norm_list[ i - 1 ] ) + l2_ratio = math. log( l2_norm_list[ i ] / l2_norm_list[ i - 1 ] ) + max_ratio = math. log( max_norm_list[ i ] / max_norm_list[ i - 1 ] ) + if format == "latex": + file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" + + string. rjust( "{\\bf " + "%.2g" % ( l1_ratio / h_ratio ) + "}", err_width ) + "&" + + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" + + string. rjust( "{\\bf " + "%.2g" % ( l2_ratio / h_ratio ) + "}", err_width ) + "&" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" + + string. rjust( "{\\bf " + "%.2g" % ( max_ratio / h_ratio ) + "}", err_width ) + "\\\\\n" ) + if format == "txt": + file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" + + string. rjust( "**" + "%.2g" % ( l1_ratio / h_ratio ) + "**", err_width ) + " |" + + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" + + string. rjust( "**" + "%.2g" % ( l2_ratio / h_ratio ) + "**", err_width ) + " |" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" + + string. rjust( "**" + "%.2g" % ( max_ratio / h_ratio ) + "**", err_width ) + " |\n" ) + file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" ) + i = i + 1 + +if format == "latex": + file. write( "\\hline \n" ) + file. write( "\\end{tabular} \n" ) + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..bf0a388166c89946727b95687eca1a74764739c3 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver.h @@ -0,0 +1,218 @@ +/*************************************************************************** + tnlParallelMapSolver.h - description + ------------------- + begin : Mar 22 , 2016 + copyright : (C) 2016 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLPARALLELMAPSOLVER_H_ +#define TNLPARALLELMAPSOLVER_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <functions/tnlMeshFunction.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> +#include <limits.h> +#include <core/tnlDevice.h> + + +#include <ctime> + +#ifdef HAVE_CUDA +#include <cuda.h> +#include <core/tnlCuda.h> +#endif + + +template< int Dimension, + typename SchemeHost, + typename SchemeDevice, + typename Device, + typename RealType = double, + typename IndexType = int > +class tnlParallelMapSolver +{}; + +template<typename SchemeHost, typename SchemeDevice, typename Device> +class tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int > +{ +public: + + typedef SchemeDevice SchemeTypeDevice; + typedef SchemeHost SchemeTypeHost; + typedef Device DeviceType; + typedef tnlVector< double, tnlHost, int > VectorType; + typedef tnlVector< int, tnlHost, int > IntVectorType; + typedef tnlGrid< 2, double, tnlHost, int > MeshType; +#ifdef HAVE_CUDA + typedef tnlVector< double, tnlHost, int > VectorTypeCUDA; + typedef tnlVector< int, tnlHost, int > IntVectorTypeCUDA; + typedef tnlGrid< 2, double, tnlHost, int > MeshTypeCUDA; +#endif + tnlParallelMapSolver(); + bool init( const Config::ParameterContainer& parameters ); + void run(); + + void test(); + +/*private:*/ + + + void synchronize(); + + int getOwner( int i) const; + + int getSubgridValue( int i ) const; + + void setSubgridValue( int i, int value ); + + int getBoundaryCondition( int i ) const; + + void setBoundaryCondition( int i, int value ); + + void stretchGrid(); + + void contractGrid(); + + VectorType getSubgrid( const int i ) const; + + void insertSubgrid( VectorType u, const int i ); + + VectorType runSubgrid( int boundaryCondition, VectorType u, int subGridID,VectorType map); + + + tnlMeshFunction<MeshType> u0; + VectorType work_u, map_stretched, map; + IntVectorType subgridValues, boundaryConditions, unusedCell, calculationsCount; + MeshType mesh, subMesh; + +// tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity; + + SchemeHost schemeHost; + SchemeDevice schemeDevice; + double delta, tau0, stopTime,cflCondition; + int gridRows, gridCols, gridLevels, currentStep, n; + + std::clock_t start; + double time_diff; + + + tnlDeviceEnum device; + + tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* getSelf() + { + return this; + }; + +#ifdef HAVE_CUDA + + tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver; + + double* work_u_cuda; + double* map_stretched_cuda; + + int* subgridValues_cuda; + int* boundaryConditions_cuda; + int* unusedCell_cuda; + int* calculationsCount_cuda; + double* tmpw; + double* tmp_map; + + + int* runcuda; + int run_host; + + + __device__ void getSubgridCUDA2D( const int i, tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a); + + __device__ void updateSubgridCUDA2D( const int i, tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a); + + __device__ void insertSubgridCUDA2D( double u, const int i ); + + __device__ void runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID); + + __device__ int getOwnerCUDA2D( int i) const; + + __device__ int getSubgridValueCUDA2D( int i ) const; + + __device__ void setSubgridValueCUDA2D( int i, int value ); + + __device__ int getBoundaryConditionCUDA2D( int i ) const; + + __device__ void setBoundaryConditionCUDA2D( int i, int value ); + +#endif + +}; + + + + + + + + + + + + + + +#ifdef HAVE_CUDA +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void runCUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void initRunCUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void initCUDA2D( tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr, int * ptr2, int* ptr3, double* tmp_map_ptr); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void synchronizeCUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void synchronize2CUDA2D(tnlParallelMapSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); + + + +__device__ +double fabsMin( double x, double y) +{ + double fx = abs(x); + + if(Min(fx,abs(y)) == fx) + return x; + else + return y; +} + +__device__ +double atomicFabsMin(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) )); + } while (assumed != old); + return __longlong_as_double(old); +} + +#endif + +#include "tnlParallelMapSolver2D_impl.h" +#endif /* TNLPARALLELMAPSOLVER_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..1cb730e42d0b0b72782e61e011b6081d2eddc6ef --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel-map/tnlParallelMapSolver2D_impl.h @@ -0,0 +1,1315 @@ +/*************************************************************************** + tnlParallelMapSolver2D_impl.h - description + ------------------- + begin : Mar 22 , 2016 + copyright : (C) 2016 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLPARALLELMAPSOLVER2D_IMPL_H_ +#define TNLPARALLELMAPSOLVER2D_IMPL_H_ + + +#include "tnlParallelMapSolver.h" +#include <core/mfilename.h> + + + + +#define MAP_SOLVER_MAX_VALUE 3 + + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::tnlParallelMapSolver() +{ + this->device = tnlHostDevice; /////////////// tnlCuda Device --- vypocet na GPU, tnlHostDevice --- vypocet na CPU + +#ifdef HAVE_CUDA + if(this->device == tnlCudaDevice) + { + run_host = 1; + } +#endif + +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::test() +{ +/* + for(int i =0; i < this->subgridValues.getSize(); i++ ) + { + insertSubgrid(getSubgrid(i), i); + } +*/ +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> + +bool tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::init( const Config::ParameterContainer& parameters ) +{ + cout << "Initializating solver..." << endl; + const String& meshLocation = parameters.getParameter <String>("mesh"); + this->mesh.load( meshLocation ); + + this->n = parameters.getParameter <int>("subgrid-size"); + cout << "Setting N to " << this->n << endl; + + this->subMesh.setDimensions( this->n, this->n ); + this->subMesh.setDomain( Containers::StaticVector<2,double>(0.0, 0.0), + Containers::StaticVector<2,double>(mesh.template getSpaceStepsProducts< 1, 0 >()*(double)(this->n), mesh.template getSpaceStepsProducts< 0, 1 >()*(double)(this->n)) ); + + this->subMesh.save("submesh.tnl"); + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + this->u0.load( initialCondition ); + + /* LOAD MAP */ + const String& mapFile = parameters.getParameter <String>("map"); + if(! this->map.load( mapFile )) + cout << "Failed to load map file : " << mapFile << endl; + + + this->delta = parameters.getParameter <double>("delta"); + this->delta *= mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >(); + + cout << "Setting delta to " << this->delta << endl; + + this->tau0 = parameters.getParameter <double>("initial-tau"); + cout << "Setting initial tau to " << this->tau0 << endl; + this->stopTime = parameters.getParameter <double>("stop-time"); + + this->cflCondition = parameters.getParameter <double>("cfl-condition"); + this -> cflCondition *= sqrt(mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >()); + cout << "Setting CFL to " << this->cflCondition << endl; + + stretchGrid(); + this->stopTime /= (double)(this->gridCols); + this->stopTime *= (1.0+1.0/((double)(this->n) - 2.0)); + cout << "Setting stopping time to " << this->stopTime << endl; + + cout << "Initializating scheme..." << endl; + if(!this->schemeHost.init(parameters)) + { + cerr << "SchemeHost failed to initialize." << endl; + return false; + } + cout << "Scheme initialized." << endl; + + test(); + + VectorType* tmp = new VectorType[subgridValues.getSize()]; + bool containsCurve = false; + +#ifdef HAVE_CUDA + + if(this->device == tnlCudaDevice) + { + cudaMalloc(&(this->cudaSolver), sizeof(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >)); + cudaMemcpy(this->cudaSolver, this,sizeof(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >), cudaMemcpyHostToDevice); + + double** tmpdev = NULL; + cudaMalloc(&tmpdev, sizeof(double*)); + cudaMalloc(&(this->tmpw), this->work_u.getSize()*sizeof(double)); + cudaMalloc(&(this->tmp_map), this->map_stretched.getSize()*sizeof(double)); + cudaMalloc(&(this->runcuda), sizeof(int)); + cudaDeviceSynchronize(); + checkCudaDevice; + + int* tmpUC; + cudaMalloc(&(tmpUC), this->work_u.getSize()*sizeof(int)); + cudaMemcpy(tmpUC, this->unusedCell.getData(), this->unusedCell.getSize()*sizeof(int), cudaMemcpyHostToDevice); + + initCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<1,1>>>(this->cudaSolver, (this->tmpw), (this->runcuda),tmpUC, tmp_map); + cudaDeviceSynchronize(); + checkCudaDevice; + + double* tmpu = NULL; + cudaMemcpy(&tmpu, tmpdev,sizeof(double*), cudaMemcpyDeviceToHost); + cudaMemcpy((this->tmpw), this->work_u.getData(), this->work_u.getSize()*sizeof(double), cudaMemcpyHostToDevice); + cudaMemcpy((this->tmp_map), this->map_stretched.getData(), this->map_stretched.getSize()*sizeof(double), cudaMemcpyHostToDevice); + cudaDeviceSynchronize(); + checkCudaDevice; + + } +#endif + + if(this->device == tnlHostDevice) + { + VectorType tmp_map; + tmp_map.setSize(this->n * this->n); + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + + if(! tmp[i].setSize(this->n * this->n)) + cout << "Could not allocate tmp["<< i <<"] array." << endl; + tmp[i] = getSubgrid(i); + containsCurve = false; + + for(int j = 0; j < tmp[i].getSize(); j++) + { + if(tmp[i][0]*tmp[i][j] <= 0.0) + { + containsCurve = true; + j=tmp[i].getSize(); + } + + } + if(containsCurve) + { + for( int j = 0; j < tmp_map.getSize(); j++) + { + tmp_map[j] = this->map_stretched[ (i / this->gridCols) * this->n*this->n*this->gridCols + + (i % this->gridCols) * this->n + + (j/this->n) * this->n*this->gridCols + + (j % this->n) ]; + } + //cout << "Computing initial SDF on subgrid " << i << "." << endl; + tmp[i] = runSubgrid(0, tmp[i],i,tmp_map); + insertSubgrid(tmp[i], i); + setSubgridValue(i, 4); + //cout << "Computed initial SDF on subgrid " << i << "." << endl; + } + containsCurve = false; + + } + } +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { + cudaDeviceSynchronize(); + checkCudaDevice; + dim3 threadsPerBlock(this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows); + cudaDeviceSynchronize(); + checkCudaDevice; + initRunCUDA2D<SchemeTypeHost,SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + + } +#endif + + + this->currentStep = 1; + if(this->device == tnlHostDevice) + synchronize(); +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { + dim3 threadsPerBlock(this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows); + + synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + } + +#endif + cout << "Solver initialized." << endl; + + return true; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::run() +{ + if(this->device == tnlHostDevice) + { + while ((this->boundaryConditions.max() > 0 )/* || !end*/) + { + +#ifdef HAVE_OPENMP +#pragma omp parallel for num_threads(4) schedule(dynamic) +#endif + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + if(getSubgridValue(i) != INT_MAX) + { + VectorType tmp, tmp_map; + tmp.setSize(this->n * this->n); + tmp_map.setSize(this->n * this->n); + for( int j = 0; j < tmp_map.getSize(); j++) + { + tmp_map[j] = this->map_stretched[ (i / this->gridCols) * this->n*this->n*this->gridCols + + (i % this->gridCols) * this->n + + (j/this->n) * this->n*this->gridCols + + (j % this->n) ]; + } + + if(getSubgridValue(i) == currentStep+4) + { + + if(getBoundaryCondition(i) & 1) + { + tmp = getSubgrid(i); + tmp = runSubgrid(1, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 2) + { + tmp = getSubgrid(i); + tmp = runSubgrid(2, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 4) + { + tmp = getSubgrid(i); + tmp = runSubgrid(4, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 8) + { + tmp = getSubgrid(i); + tmp = runSubgrid(8, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + } + else + { + + if(getBoundaryCondition(i) == 1) + { + tmp = getSubgrid(i); + tmp = runSubgrid(1, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) == 2) + { + tmp = getSubgrid(i); + tmp = runSubgrid(2, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) == 4) + { + tmp = getSubgrid(i); + tmp = runSubgrid(4, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) == 8) + { + tmp = getSubgrid(i); + tmp = runSubgrid(8, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + } + + if(getBoundaryCondition(i) & 3) + { + //cout << "3 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(3, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + } + if(getBoundaryCondition(i) & 5) + { + //cout << "5 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(5, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + } + if(getBoundaryCondition(i) & 10) + { + //cout << "10 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(10, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + } + if(getBoundaryCondition(i) & 12) + { + //cout << "12 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(12, tmp ,i,tmp_map); + insertSubgrid( tmp, i); + } + + + setBoundaryCondition(i, 0); + + setSubgridValue(i, getSubgridValue(i)-1); + + } + } + synchronize(); + } + } +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { + bool end_cuda = false; + dim3 threadsPerBlock(this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows); + cudaDeviceSynchronize(); + checkCudaDevice; + + bool* tmpb; + cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + checkCudaDevice; + + int i = 1; + time_diff = 0.0; + while (run_host || !end_cuda) + { + cout << "Computing at step "<< i++ << endl; + if(run_host != 0 ) + end_cuda = true; + else + end_cuda = false; + cudaDeviceSynchronize(); + checkCudaDevice; + start = std::clock(); + runCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver); + cudaDeviceSynchronize(); + time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC); + + //start = std::clock(); + synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + //time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC); + + cudaMemcpy(&run_host, (this->runcuda),sizeof(int), cudaMemcpyDeviceToHost); + } + cout << "Solving time was: " << time_diff << endl; + + cudaMemcpy(this->work_u.getData()/* test*/, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + + cudaDeviceSynchronize(); + } +#endif + contractGrid(); + this->u0.save("u-00001.tnl"); + cout << "Maximum number of calculations on one subgrid was " << this->calculationsCount.absMax() << endl; + cout << "Average number of calculations on one subgrid was " << ( (double) this->calculationsCount.sum() / (double) this->calculationsCount.getSize() ) << endl; + cout << "Solver finished" << endl; + +#ifdef HAVE_CUDA + if(this->device == tnlCudaDevice) + { + cudaFree(this->runcuda); + cudaFree(this->tmpw); + cudaFree(this->tmp_map); + cudaFree(this->cudaSolver); + } +#endif + +} + +//north - 1, east - 2, west - 4, south - 8 +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::synchronize() //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now +{ + cout << "Synchronizig..." << endl; + int tmp1, tmp2; + int grid1, grid2; + +// if(this->currentStep & 1) +// { + for(int j = 0; j < this->gridRows - 1; j++) + { + for (int i = 0; i < this->gridCols*this->n; i++) + { + tmp1 = this->gridCols*this->n*((this->n-1)+j*this->n) + i; + tmp2 = this->gridCols*this->n*((this->n)+j*this->n) + i; + grid1 = getSubgridValue(getOwner(tmp1)); + grid2 = getSubgridValue(getOwner(tmp2)); + if(getOwner(tmp1)==getOwner(tmp2)) + cout << "i, j" << i << "," << j << endl; + if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + this->unusedCell[tmp2] = 0; + if(grid2 == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp2)) & 8) ) + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+8); + } + else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + this->unusedCell[tmp1] = 0; + if(grid1 == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp1)) & 1) ) + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+1); + } + } + } + +// } +// else +// { + for(int i = 1; i < this->gridCols; i++) + { + for (int j = 0; j < this->gridRows*this->n; j++) + { + tmp1 = this->gridCols*this->n*j + i*this->n - 1; + tmp2 = this->gridCols*this->n*j + i*this->n ; + grid1 = getSubgridValue(getOwner(tmp1)); + grid2 = getSubgridValue(getOwner(tmp2)); + if(getOwner(tmp1)==getOwner(tmp2)) + cout << "i, j" << i << "," << j << endl; + if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + this->unusedCell[tmp2] = 0; + if(grid2 == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp2)) & 4) ) + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+4); + } + else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + this->unusedCell[tmp1] = 0; + if(grid1 == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp1)) & 2) ) + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+2); + } + } + } +// } + + + this->currentStep++; + int stepValue = this->currentStep + 4; + for (int i = 0; i < this->subgridValues.getSize(); i++) + { + if( getSubgridValue(i) == -INT_MAX ) + setSubgridValue(i, stepValue); + } + + cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl; + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwner(int i) const +{ + + return (i / (this->gridCols*this->n*this->n))*this->gridCols + (i % (this->gridCols*this->n))/this->n; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValue( int i ) const +{ + return this->subgridValues[i]; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValue(int i, int value) +{ + this->subgridValues[i] = value; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryCondition( int i ) const +{ + return this->boundaryConditions[i]; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryCondition(int i, int value) +{ + this->boundaryConditions[i] = value; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::stretchGrid() +{ + cout << "Stretching grid..." << endl; + + + this->gridCols = ceil( ((double)(this->mesh.getDimensions().x()-1)) / ((double)(this->n-1)) ); + this->gridRows = ceil( ((double)(this->mesh.getDimensions().y()-1)) / ((double)(this->n-1)) ); + + + cout << "Setting gridCols to " << this->gridCols << "." << endl; + cout << "Setting gridRows to " << this->gridRows << "." << endl; + + this->subgridValues.setSize(this->gridCols*this->gridRows); + this->subgridValues.setValue(0); + this->boundaryConditions.setSize(this->gridCols*this->gridRows); + this->boundaryConditions.setValue(0); + this->calculationsCount.setSize(this->gridCols*this->gridRows); + this->calculationsCount.setValue(0); + + for(int i = 0; i < this->subgridValues.getSize(); i++ ) + { + this->subgridValues[i] = INT_MAX; + this->boundaryConditions[i] = 0; + } + + int stretchedSize = this->n*this->n*this->gridCols*this->gridRows; + + if(!this->work_u.setSize(stretchedSize)) + cerr << "Could not allocate memory for stretched grid." << endl; + if(!this->map_stretched.setSize(stretchedSize)) + cerr << "Could not allocate memory for stretched map." << endl; + if(!this->unusedCell.setSize(stretchedSize)) + cerr << "Could not allocate memory for supporting stretched grid." << endl; + int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1); + cout << idealStretch << endl; + + for(int i = 0; i < stretchedSize; i++) + { + this->unusedCell[i] = 1; + int diff =(this->n*this->gridCols) - idealStretch ; + int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff; + + if(i%(this->n*this->gridCols) - idealStretch >= 0) + { + k+= i%(this->n*this->gridCols) - idealStretch +1 ; + } + + if(i/(this->n*this->gridCols) - idealStretch + 1 > 0) + { + k+= (i/(this->n*this->gridCols) - idealStretch +1 )* this->mesh.getDimensions().x() ; + } + + + if(fabs(this->u0[i-k]) < mesh.template getSpaceStepsProducts< 1, 0 >()+mesh.template getSpaceStepsProducts< 0, 1 >() ) + this->work_u[i] = this->u0[i-k]; + else + this->work_u[i] = sign(this->u0[i-k])*MAP_SOLVER_MAX_VALUE; + + this->map_stretched[i] = this->map[i-k]; + } + + + cout << "Grid stretched." << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::contractGrid() +{ + cout << "Contracting grid..." << endl; + int stretchedSize = this->n*this->n*this->gridCols*this->gridRows; + + int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1); + cout << idealStretch << endl; + + for(int i = 0; i < stretchedSize; i++) + { + int diff =(this->n*this->gridCols) - idealStretch ; + int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff; + + if((i%(this->n*this->gridCols) - idealStretch < 0) && (i/(this->n*this->gridCols) - idealStretch + 1 <= 0)) + { + this->u0[i-k] = this->work_u[i]; + } + + } + + cout << "Grid contracted" << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +typename tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType +tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgrid( const int i ) const +{ + VectorType u; + u.setSize(this->n*this->n); + + for( int j = 0; j < u.getSize(); j++) + { + u[j] = this->work_u[ (i / this->gridCols) * this->n*this->n*this->gridCols + + (i % this->gridCols) * this->n + + (j/this->n) * this->n*this->gridCols + + (j % this->n) ]; + } + return u; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgrid( VectorType u, const int i ) +{ + + for( int j = 0; j < this->n*this->n; j++) + { + int index = (i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n); + if( (fabs(this->work_u[index]) > fabs(u[j])) || (this->unusedCell[index] == 1) ) + { + this->work_u[index] = u[j]; + this->unusedCell[index] = 0; + } + } +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +typename tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType +tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgrid( int boundaryCondition, VectorType u, int subGridID,VectorType map) +{ + + VectorType fu; + + fu.setLike(u); + fu.setValue( 0.0 ); + + + + bool tmp = false; + for(int i = 0; i < u.getSize(); i++) + { + if(u[0]*u[i] <= 0.0) + tmp=true; + int centerGID = (this->n*(subGridID / this->gridRows)+ (this->n >> 1))*(this->n*this->gridCols) + this->n*(subGridID % this->gridRows) + (this->n >> 1); + if(this->unusedCell[centerGID] == 0 || boundaryCondition == 0) + tmp = true; + } + + + double value = sign(u[0]) * u.absMax(); + + if(tmp) + {} + + + //north - 1, east - 2, west - 4, south - 8 + else if(boundaryCondition == 4) + { + for(int i = 0; i < this->n; i++) + for(int j = 1;j < this->n; j++) + //if(fabs(u[i*this->n + j]) < fabs(u[i*this->n])) + u[i*this->n + j] = value;// u[i*this->n]; + } + else if(boundaryCondition == 2) + { + for(int i = 0; i < this->n; i++) + for(int j =0 ;j < this->n -1; j++) + //if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1])) + u[i*this->n + j] = value;// u[(i+1)*this->n - 1]; + } + else if(boundaryCondition == 1) + { + for(int j = 0; j < this->n; j++) + for(int i = 0;i < this->n - 1; i++) + //if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)])) + u[i*this->n + j] = value;// u[j + this->n*(this->n - 1)]; + } + else if(boundaryCondition == 8) + { + for(int j = 0; j < this->n; j++) + for(int i = 1;i < this->n; i++) + //if(fabs(u[i*this->n + j]) < fabs(u[j])) + u[i*this->n + j] = value;// u[j]; + } + + + + double time = 0.0; + double currentTau = this->tau0; + double finalTime = this->stopTime;// + 3.0*(u.max() - u.min()); + if( time + currentTau > finalTime ) currentTau = finalTime - time; + + double maxResidue( 1.0 ); + tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + + for( int i = 0; i < u.getSize(); i ++ ) + { + if(map[i] == 0.0) + { + u[i] = /*sign(u[l])**/MAP_SOLVER_MAX_VALUE; + } + } + + while( time < finalTime ) + { + /**** + * Compute the RHS + */ + + for( int i = 0; i < fu.getSize(); i ++ ) + { + Entity.setCoordinates(Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x())); + Entity.refresh(); + neighbourEntities.refresh(subMesh,Entity.getIndex()); + if(map[i] != 0.0) + fu[ i ] = schemeHost.getValue( this->subMesh, i, Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x()), u, time, boundaryCondition,neighbourEntities,map); + } + maxResidue = fu. absMax(); + + + if(maxResidue != 0.0) + currentTau = fabs(this -> cflCondition / maxResidue); + + + if(currentTau > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >()) + { + currentTau = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + + + if( time + currentTau > finalTime ) currentTau = finalTime - time; + + + + for( int i = 0; i < fu.getSize(); i ++ ) + { + if(map[i] != 0.0) + u[ i ] += currentTau * fu[ i ]; + } + time += currentTau; + + } + return u; +} + + +#ifdef HAVE_CUDA + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridCUDA2D( const int i ,tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a) +{ + int th = (blockIdx.y) * caller->n*caller->n*caller->gridCols + + (blockIdx.x) * caller->n + + threadIdx.y * caller->n*caller->gridCols + + threadIdx.x; + + *a = caller->work_u_cuda[th]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::updateSubgridCUDA2D( const int i ,tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a) +{ + int index = (blockIdx.y) * caller->n*caller->n*caller->gridCols + + (blockIdx.x) * caller->n + + threadIdx.y * caller->n*caller->gridCols + + threadIdx.x; + + if( (fabs(caller->work_u_cuda[index]) > fabs(*a)) || (caller->unusedCell_cuda[index] == 1) ) + { + caller->work_u_cuda[index] = *a; + caller->unusedCell_cuda[index] = 0; + + } + + *a = caller->work_u_cuda[index]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgridCUDA2D( double u, const int i ) +{ + int index = (blockIdx.y)*this->n*this->n*this->gridCols + + (blockIdx.x)*this->n + + threadIdx.y*this->n*this->gridCols + + threadIdx.x; + + if( (fabs(this->work_u_cuda[index]) > fabs(u)) || (this->unusedCell_cuda[index] == 1) ) + { + this->work_u_cuda[index] = u; + this->unusedCell_cuda[index] = 0; + + } + + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID) +{ + + __shared__ int tmp; + __shared__ double value; + volatile double* sharedTau = &u[blockDim.x*blockDim.y]; + double* map_local = &u[2*blockDim.x*blockDim.y]; + + int i = threadIdx.x; + int j = threadIdx.y; + int l = threadIdx.y * blockDim.x + threadIdx.x; + int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x; + + /* LOAD MAP */ + map_local[l]=this->map_stretched_cuda[gid]; + if(map_local[l] != 0.0) + map_local[l] = 1.0/map_local[l]; + /* LOADED */ + + bool computeFU = !((i == 0 && (boundaryCondition & 4)) or + (i == blockDim.x - 1 && (boundaryCondition & 2)) or + (j == 0 && (boundaryCondition & 8)) or + (j == blockDim.y - 1 && (boundaryCondition & 1))); + + if(l == 0) + { + tmp = 0; + int centerGID = (blockDim.y*blockIdx.y + (blockDim.y>>1))*(blockDim.x*gridDim.x) + blockDim.x*blockIdx.x + (blockDim.x>>1); + if(this->unusedCell_cuda[centerGID] == 0 || boundaryCondition == 0) + tmp = 1; + } + __syncthreads(); + + + if(tmp !=1) + { + if(computeFU) + { + if(boundaryCondition == 4) + u[l] = u[threadIdx.y * blockDim.x] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.x); + else if(boundaryCondition == 2) + u[l] = u[threadIdx.y * blockDim.x + blockDim.x - 1] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.x); + else if(boundaryCondition == 8) + u[l] = u[threadIdx.x] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.y); + else if(boundaryCondition == 1) + u[l] = u[(blockDim.y - 1)* blockDim.x + threadIdx.x] ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.y); + } + } + + double time = 0.0; + __shared__ double currentTau; + double cfl = this->cflCondition; + double fu = 0.0; + + double finalTime = this->stopTime; + if(boundaryCondition == 0) + finalTime*=2.0; + __syncthreads(); + + tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Entity.setCoordinates(Containers::StaticVector<2,int>(i,j)); + Entity.refresh(); + neighbourEntities.refresh(subMesh,Entity.getIndex()); + + + if(map_local[l] == 0.0) + { + u[l] = /*sign(u[l])**/MAP_SOLVER_MAX_VALUE; + computeFU = false; + } + __syncthreads(); + + + while( time < finalTime ) + { + sharedTau[l] = finalTime; + + if(computeFU) + { + fu = schemeHost.getValueDev( this->subMesh, l, Containers::StaticVector<2,int>(i,j), u, time, boundaryCondition, neighbourEntities, map_local); + sharedTau[l]=abs(cfl/fu); + } + + + + if(l == 0) + { + if(sharedTau[0] > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >()) sharedTau[0] = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + else if(l == blockDim.x*blockDim.y - 1) + if( time + sharedTau[l] > finalTime ) sharedTau[l] = finalTime - time; + + + if((blockDim.x == 16) && (l < 128)) sharedTau[l] = Min(sharedTau[l],sharedTau[l+128]); + __syncthreads(); + if((blockDim.x == 16) && (l < 64)) sharedTau[l] = Min(sharedTau[l],sharedTau[l+64]); + __syncthreads(); + if(l < 32) sharedTau[l] = Min(sharedTau[l],sharedTau[l+32]); + if(l < 16) sharedTau[l] = Min(sharedTau[l],sharedTau[l+16]); + if(l < 8) sharedTau[l] = Min(sharedTau[l],sharedTau[l+8]); + if(l < 4) sharedTau[l] = Min(sharedTau[l],sharedTau[l+4]); + if(l < 2) sharedTau[l] = Min(sharedTau[l],sharedTau[l+2]); + if(l < 1) currentTau = Min(sharedTau[l],sharedTau[l+1]); + __syncthreads(); + + u[l] += currentTau * fu; + time += currentTau; + } + + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwnerCUDA2D(int i) const +{ + + return ((i / (this->gridCols*this->n*this->n))*this->gridCols + + (i % (this->gridCols*this->n))/this->n); +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValueCUDA2D( int i ) const +{ + return this->subgridValues_cuda[i]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValueCUDA2D(int i, int value) +{ + this->subgridValues_cuda[i] = value; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryConditionCUDA2D( int i ) const +{ + return this->boundaryConditions_cuda[i]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryConditionCUDA2D(int i, int value) +{ + this->boundaryConditions_cuda[i] = value; +} + + + +//north - 1, east - 2, west - 4, south - 8 + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void synchronizeCUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now +{ + + __shared__ int boundary[4]; // north,east,west,south + __shared__ int subgridValue; + __shared__ int newSubgridValue; + + + int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x; + double u = cudaSolver->work_u_cuda[gid]; + double u_cmp; + int subgridValue_cmp=INT_MAX; + int boundary_index=0; + + + if(threadIdx.x+threadIdx.y == 0) + { + subgridValue = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x); + boundary[0] = 0; + boundary[1] = 0; + boundary[2] = 0; + boundary[3] = 0; + newSubgridValue = 0; + } + __syncthreads(); + + + + if( (threadIdx.x == 0 /* && !(cudaSolver->currentStep & 1)*/) || + (threadIdx.y == 0 /* && (cudaSolver->currentStep & 1)*/) || + (threadIdx.x == blockDim.x - 1 /* && !(cudaSolver->currentStep & 1)*/) || + (threadIdx.y == blockDim.y - 1 /* && (cudaSolver->currentStep & 1)*/) ) + { + if(threadIdx.x == 0 && (blockIdx.x != 0)/* && !(cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid - 1]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x - 1); + boundary_index = 2; + } + + if(threadIdx.x == blockDim.x - 1 && (blockIdx.x != gridDim.x - 1)/* && !(cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid + 1]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x + 1); + boundary_index = 1; + } + + __threadfence(); + if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX)) + { + cudaSolver->unusedCell_cuda[gid] = 0; + atomicMax(&newSubgridValue, INT_MAX); + atomicMax(&boundary[boundary_index], 1); + cudaSolver->work_u_cuda[gid] = u_cmp; + u=u_cmp; + } + __threadfence(); + if(threadIdx.y == 0 && (blockIdx.y != 0)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y - 1)*gridDim.x + blockIdx.x); + boundary_index = 3; + } + if(threadIdx.y == blockDim.y - 1 && (blockIdx.y != gridDim.y - 1)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y + 1)*gridDim.x + blockIdx.x); + boundary_index = 0; + } + + if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX)) + { + cudaSolver->unusedCell_cuda[gid] = 0; + atomicMax(&newSubgridValue, INT_MAX); + atomicMax(&boundary[boundary_index], 1); + cudaSolver->work_u_cuda[gid] = u_cmp; + } + } + __threadfence(); + __syncthreads(); + + if(threadIdx.x+threadIdx.y == 0) + { + if(subgridValue == INT_MAX && newSubgridValue !=0) + cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, -INT_MAX); + + cudaSolver->setBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, boundary[0] + + 2 * boundary[1] + + 4 * boundary[2] + + 8 * boundary[3]); + + + if(blockIdx.x+blockIdx.y ==0) + { + cudaSolver->currentStep += 1; + *(cudaSolver->runcuda) = 0; + } + } + +} + + + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void synchronize2CUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) +{ + + + int stepValue = cudaSolver->currentStep + 4; + if( cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX ) + cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, stepValue); + + atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x)); +} + + + + + + + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void initCUDA2D( tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr , int* ptr2, int* ptr3, double* tmp_map_ptr) +{ + + + cudaSolver->work_u_cuda = ptr; + cudaSolver->map_stretched_cuda = tmp_map_ptr; + cudaSolver->unusedCell_cuda = ptr3; + cudaSolver->subgridValues_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int)); + cudaSolver->boundaryConditions_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int)); + cudaSolver->runcuda = ptr2; + *(cudaSolver->runcuda) = 1; + +/* CHANGED !!!!!! from 1 to 0*/ cudaSolver->currentStep = 0; + + printf("GPU memory allocated.\n"); + + for(int i = 0; i < cudaSolver->gridCols*cudaSolver->gridRows; i++) + { + cudaSolver->subgridValues_cuda[i] = INT_MAX; + cudaSolver->boundaryConditions_cuda[i] = 0; + } + + printf("GPU memory initialized.\n"); +} + + + + +template< typename SchemeHost, typename SchemeDevice, typename Device > +__global__ +void initRunCUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller) + +{ + extern __shared__ double u[]; + + int i = blockIdx.y * gridDim.x + blockIdx.x; + int l = threadIdx.y * blockDim.x + threadIdx.x; + + __shared__ int containsCurve; + if(l == 0) + containsCurve = 0; + + + caller->getSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + + if(u[0] * u[l] <= 0.0) + atomicMax( &containsCurve, 1); + + __syncthreads(); + if(containsCurve == 1) + { + caller->runSubgridCUDA2D(0,u,i); + caller->insertSubgridCUDA2D(u[l],i); + __syncthreads(); + if(l == 0) + caller->setSubgridValueCUDA2D(i, 4); + } + + +} + + + + + +template< typename SchemeHost, typename SchemeDevice, typename Device > +__global__ +void runCUDA2D(tnlParallelMapSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller) +{ + extern __shared__ double u[]; + int i = blockIdx.y * gridDim.x + blockIdx.x; + int l = threadIdx.y * blockDim.x + threadIdx.x; + int bound = caller->getBoundaryConditionCUDA2D(i); + + if(caller->getSubgridValueCUDA2D(i) != INT_MAX && bound != 0 && caller->getSubgridValueCUDA2D(i) > 0) + { + caller->getSubgridCUDA2D(i,caller, &u[l]); + + + if(caller->getSubgridValueCUDA2D(i) == caller->currentStep+4) + { + if(bound & 1) + { + caller->runSubgridCUDA2D(1,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 2) + { + caller->runSubgridCUDA2D(2,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 4) + { + caller->runSubgridCUDA2D(4,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 8) + { + caller->runSubgridCUDA2D(8,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + } + else + { + + if(bound == 1) + { + caller->runSubgridCUDA2D(1,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound == 2) + { + caller->runSubgridCUDA2D(2,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound == 4) + { + caller->runSubgridCUDA2D(4,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound == 8) + { + caller->runSubgridCUDA2D(8,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + } + + if(bound & 3) + { + caller->runSubgridCUDA2D(3,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 5) + { + caller->runSubgridCUDA2D(5,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 10) + { + caller->runSubgridCUDA2D(10,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 12) + { + caller->runSubgridCUDA2D(12,u,i); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + + + if(l==0) + { + caller->setBoundaryConditionCUDA2D(i, 0); + caller->setSubgridValueCUDA2D(i, caller->getSubgridValueCUDA2D(i) - 1 ); + } + + + } + + + +} + +#endif /*HAVE_CUDA*/ + +#endif /* TNLPARALLELMAPSOLVER2D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..b65f3e6a4c8d0cc22a5e10dc46f298fcc5e0dfc0 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/CMakeLists.txt @@ -0,0 +1,23 @@ +set( tnl_hamilton_jacobi_parallel_SOURCES +# MainBuildConfig.h +# tnlParallelEikonalSolver2D_impl.h +# tnlParallelEikonalSolver3D_impl.h +# tnlParallelEikonalSolver.h +# parallelEikonalConfig.h + main.cpp) + + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(hamilton-jacobi-parallel${debugExt} main.cu) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(hamilton-jacobi-parallel${debugExt} main.cpp) +ENDIF( BUILD_CUDA ) +target_link_libraries (hamilton-jacobi-parallel${debugExt} tnl${debugExt}-${tnlVersion} ) + + +INSTALL( TARGETS hamilton-jacobi-parallel${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +#INSTALL( FILES ${tnl_hamilton_jacobi_parallel_SOURCES} +# DESTINATION share/tnl-${tnlVersion}/examples/hamilton-jacobi-parallel ) diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/MainBuildConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/MainBuildConfig.h @@ -0,0 +1,64 @@ +/*************************************************************************** + MainBuildConfig.h - description + ------------------- + begin : Jul 7, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MAINBUILDCONFIG_H_ +#define MAINBUILDCONFIG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class MainBuildConfig +{ + public: + + static void print() { cerr << "MainBuildConfig" << endl; } +}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && + tnlConfigTagReal< MainBuildConfig, Real >::enabled && + tnlConfigTagDevice< MainBuildConfig, Device >::enabled && + tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* MAINBUILDCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b13498e17330fae7bb00a0bdc2abcc7a19f8e7a8 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cpp @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7101976712e153d73c5f0979b211164a36ec648d --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.cu @@ -0,0 +1,17 @@ +/*************************************************************************** + main.cu - description + ------------------- + begin : Mar 30 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "main.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.h new file mode 100644 index 0000000000000000000000000000000000000000..3a976dae469a77dc33559cf562f722913de0ef28 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/main.h @@ -0,0 +1,142 @@ +/*************************************************************************** + main.h - description + ------------------- + begin : Mar 30 , 2015 + copyright : (C) 2015 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "tnlParallelEikonalSolver.h" +#include "parallelEikonalConfig.h" +#include "MainBuildConfig.h" +#include <solvers/tnlBuildConfigTags.h> +#include <operators/hamilton-jacobi/godunov-eikonal/parallelGodunovEikonal.h> +#include <mesh/tnlGrid.h> +#include <core/tnlDevice.h> +#include <time.h> +#include <ctime> + +typedef MainBuildConfig BuildConfig; + +int main( int argc, char* argv[] ) +{ + time_t start; + time_t stop; + time(&start); + std::clock_t start2= std::clock(); + Config::ParameterContainer parameters; + tnlConfigDescription configDescription; + parallelEikonalConfig< BuildConfig >::configSetup( configDescription ); + + if( ! parseCommandLine( argc, argv, configDescription, parameters ) ) + return false; + + //if (parameters.GetParameter <String>("scheme") == "godunov") + //{ + tnlDeviceEnum device; + device = tnlHostDevice; + + const int& dim = parameters.getParameter< int >( "dim" ); + + if(dim == 2) + { + + typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlHost, int>, double, int > SchemeTypeHost; + /*#ifdef HAVE_CUDA + typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlCuda, int>, double, int > SchemeTypeDevice; + #endif + #ifndef HAVE_CUDA*/ + typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlHost, int>, double, int > SchemeTypeDevice; + /*#endif*/ + + if(device==tnlHostDevice) + { + typedef tnlHost Device; + + + tnlParallelEikonalSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver loop..." << endl; + solver.run(); + } + else if(device==tnlCudaDevice ) + { + typedef tnlCuda Device; + //typedef parallelGodunovEikonalScheme< tnlGrid<2,double,Device, int>, double, int > SchemeType; + + tnlParallelEikonalSolver<2,SchemeTypeHost,SchemeTypeDevice, Device> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver loop..." << endl; + solver.run(); + } + // } + } + else if(dim == 3) + { + + typedef parallelGodunovEikonalScheme< tnlGrid<3,double,tnlHost, int>, double, int > SchemeTypeHost; + /*#ifdef HAVE_CUDA + typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlCuda, int>, double, int > SchemeTypeDevice; + #endif + #ifndef HAVE_CUDA*/ + typedef parallelGodunovEikonalScheme< tnlGrid<3,double,tnlHost, int>, double, int > SchemeTypeDevice; + /*#endif*/ + + if(device==tnlHostDevice) + { + typedef tnlHost Device; + + + tnlParallelEikonalSolver<3,SchemeTypeHost,SchemeTypeDevice, Device> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver loop..." << endl; + solver.run(); + } + else if(device==tnlCudaDevice ) + { + typedef tnlCuda Device; + //typedef parallelGodunovEikonalScheme< tnlGrid<2,double,Device, int>, double, int > SchemeType; + + tnlParallelEikonalSolver<3,SchemeTypeHost,SchemeTypeDevice, Device> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver loop..." << endl; + solver.run(); + } + // } + } + + time(&stop); + cout << endl; + cout << "Running time was: " << difftime(stop,start) << " .... " << (std::clock() - start2) / (double)(CLOCKS_PER_SEC) << endl; + return EXIT_SUCCESS; +} + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/no-Makefile b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/no-Makefile new file mode 100644 index 0000000000000000000000000000000000000000..bfdc1ef236ca02ecfe6bc88f81d872e9524ec621 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/no-Makefile @@ -0,0 +1,41 @@ +TNL_VERSION=0.1 +TNL_INSTALL_DIR=${HOME}/local/lib +TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION} + +TARGET = hamiltonJacobiParallelSolver +#CONFIG_FILE = $(TARGET).cfg.desc +INSTALL_DIR = ${HOME}/local +CXX = g++ +CUDA_CXX = nvcc +OMP_FLAGS = -DHAVE_OPENMP -fopenmp +CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O3 $(OMP_FLAGS) -DDEBUG +LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-0.1 -lgomp + +SOURCES = main.cpp +HEADERS = +OBJECTS = main.o +DIST = $(SOURCES) Makefile + +all: $(TARGET) +clean: + rm -f $(OBJECTS) + rm -f $(TARGET)-conf.h + +dist: $(DIST) + tar zcvf $(TARGET).tgz $(DIST) + +install: $(TARGET) + cp $(TARGET) $(INSTALL_DIR)/bin + cp $(CONFIG_FILE) $(INSTALL_DIR)/share + +uninstall: $(TARGET) + rm -f $(INSTALL_DIR)/bin/$(TARGET) + rm -f $(CONFIG_FILE) $(INSTALL_DIR)/share + +$(TARGET): $(OBJECTS) + $(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS) + +%.o: %.cpp $(HEADERS) + $(CXX) -c -o $@ $(CXX_FLAGS) $< + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/parallelEikonalConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/parallelEikonalConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..c27f5ebb39e5c4db31ed13d1a8e80b8ca8915d51 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/parallelEikonalConfig.h @@ -0,0 +1,46 @@ +/*************************************************************************** + parallelEikonalConfig.h - description + ------------------- + begin : Oct 5, 2014 + copyright : (C) 2014 by Tomas Sobotik + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef HAMILTONJACOBIPARALLELEIKONALPROBLEMCONFIG_H_ +#define HAMILTONJACOBIPARALLELEIKONALPROBLEMCONFIG_H_ + +#include <config/tnlConfigDescription.h> + +template< typename ConfigTag > +class parallelEikonalConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Parallel Eikonal solver settings:" ); + config.addEntry < String > ( "problem-name", "This defines particular problem.", "hamilton-jacobi-parallel" ); + config.addEntry < String > ( "scheme", "This defines scheme used for discretization.", "godunov" ); + config.addEntryEnum( "godunov" ); + config.addEntryEnum( "upwind" ); + config.addRequiredEntry < String > ( "initial-condition", "Initial condition for solver"); + config.addEntry < String > ( "mesh", "Name of mesh.", "mesh.tnl" ); + config.addEntry < double > ( "epsilon", "This defines epsilon for smoothening of sign().", 0.0 ); + config.addEntry < double > ( "delta", " Allowed difference on subgrid boundaries", 0.0 ); + config.addRequiredEntry < double > ( "stop-time", " Final time for solver"); + config.addRequiredEntry < double > ( "initial-tau", " initial tau for solver" ); + config.addEntry < double > ( "cfl-condition", " CFL condition", 0.0 ); + config.addEntry < int > ( "subgrid-size", "Subgrid size.", 16 ); + config.addRequiredEntry < int > ( "dim", "Dimension of problem."); + } +}; + +#endif /* HAMILTONJACOBIPARALLELEIKONALPROBLEMCONFIG_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/run b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/run new file mode 100755 index 0000000000000000000000000000000000000000..3aece294a9c1189cd885acbe459dba20be713716 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/run @@ -0,0 +1,64 @@ +#!/bin/bash + +#GRID_SIZES="0897" +GRID_SIZES="0008 0015 0029 0057 0113 0225 0449" +#GRID_SIZES="1793" + +dimensions=2 + +size=2 + +time=3 + +for grid_size in $GRID_SIZES; + +do + + rm -r grid-${grid_size} + mkdir grid-${grid_size} + cd grid-${grid_size} + + tnl-grid-setup --dimensions $dimensions \ + --origin-x -1.0 \ + --origin-y -1.0 \ + --origin-z -1.0 \ + --proportions-x $size \ + --proportions-y $size \ + --proportions-z $size \ + --size-x ${grid_size} \ + --size-y ${grid_size} \ + --size-z ${grid_size} + + tnl-init --test-function sdf-para \ + --offset 0.25 \ + --output-file init.tnl \ + --final-time 0.0 \ + --snapshot-period 0.1 \ + + + tnl-init --test-function sdf-para-sdf \ + --offset 0.25 \ + --output-file sdf.tnl \ + --final-time 0.0 \ + --snapshot-period 0.1 + + hamilton-jacobi-parallel --initial-condition init.tnl \ + --cfl-condition 1.0e-1 \ + --mesh mesh.tnl \ + --initial-tau 1.0e-3 \ + --epsilon 1.0 \ + --delta 0.0 \ + --stop-time $time \ + --scheme godunov \ + --subgrid-size 8 + + tnl-diff --mesh mesh.tnl --mode sequence --input-files sdf.tnl u-00001.tnl --write-difference yes --output-file ../${grid_size}.diff + + cd .. + +done + + +./tnl-err2eoc-2.py --format txt --size $size *.diff + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnl-err2eoc-2.py b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnl-err2eoc-2.py new file mode 100755 index 0000000000000000000000000000000000000000..f8cde3768e9b76156507e133f8bc3ecaa526fc71 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnl-err2eoc-2.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python + +import sys, string, math + +arguments = sys. argv[1:] +format = "txt" +output_file_name = "eoc-table.txt" +input_files = [] +verbose = 1 +size = 1.0 + +i = 0 +while i < len( arguments ): + if arguments[ i ] == "--format": + format = arguments[ i + 1 ] + i = i + 2 + continue + if arguments[ i ] == "--output-file": + output_file_name = arguments[ i + 1 ] + i = i + 2 + continue + if arguments[ i ] == "--verbose": + verbose = float( arguments[ i + 1 ] ) + i = i +2 + continue + if arguments[ i ] == "--size": + size = float( arguments[ i + 1 ] ) + i = i +2 + continue + input_files. append( arguments[ i ] ) + i = i + 1 + +if not verbose == 0: + print "Writing to " + output_file_name + " in " + format + "." + +h_list = [] +l1_norm_list = [] +l2_norm_list = [] +max_norm_list = [] +items = 0 + +for file_name in input_files: + if not verbose == 0: + print "Processing file " + file_name + file = open( file_name, "r" ) + + l1_max = 0.0 + l_max_max = 0.0 + file.readline(); + file.readline(); + for line in file. readlines(): + data = string. split( line ) + h_list. append( size/(float(file_name[0:len(file_name)-5] ) - 1.0) ) + l1_norm_list. append( float( data[ 1 ] ) ) + l2_norm_list. append( float( data[ 2 ] ) ) + max_norm_list. append( float( data[ 3 ] ) ) + items = items + 1 + if not verbose == 0: + print line + file. close() + +h_width = 12 +err_width = 15 +file = open( output_file_name, "w" ) +if format == "latex": + file. write( "\\begin{tabular}{|r|l|l|l|l|l|l|}\\hline\n" ) + file. write( "\\raisebox{-1ex}[0ex]{$h$}& \n" ) + file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_1\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" ) + file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_2\\left(\\omega_h;\left[0,T\\right]\\right)}^{h,\\tau}$}}& \n" ) + file. write( "\\multicolumn{2}{|c|}{\\raisebox{1ex}[3.5ex]{$\\left\| \\cdot \\right\\|_{L_\\infty\\left(\\omega_h;\\left[0,T\\right]\\right)}^{h,\\tau}$}}\\\\ \\cline{2-7} \n" ) + file. write( " " + string. rjust( " ", h_width ) + "&" + + string. rjust( "Error", err_width ) + "&" + + string. rjust( "{\\bf EOC}", err_width ) + "&" + + string. rjust( "Error", err_width ) + "&" + + string. rjust( "{\\bf EOC}", err_width ) + "&" + + string. rjust( "Error.", err_width ) + "&" + + string. rjust( "{\\bf EOC}", err_width ) + + "\\\\ \\hline \\hline \n") +if format == "txt": + file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" ) + file. write( "| h | L1 Err. | L1 EOC. | L2 Err. | L2 EOC | MAX Err. | MAX EOC |\n" ) + file. write( "+==============+================+================+================+================+================+================+\n" ) + + +i = 0 +while i < items: + if i == 0: + if format == "latex": + file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" + + string. rjust( " ", err_width ) + "&"+ + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" + + string. rjust( " ", err_width ) + "&" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" + + string. rjust( " ", err_width ) + "\\\\\n" ) + if format == "txt": + file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" + + string. rjust( " ", err_width ) + " |" + + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" + + string. rjust( " ", err_width ) + " |" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" + + string. rjust( " ", err_width ) + " |\n" ) + file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" ) + i = i + 1; + continue + if h_list[ i ] == h_list[ i - 1 ]: + print "Unable to count eoc since h[ " + \ + str( i ) + " ] = h[ " + str( i - 1 ) + \ + " ] = " + str( h_list[ i ] ) + ". \n" + file. write( " eoc error: h[ " + \ + str( i ) + " ] = h[ " + str( i - 1 ) + \ + " ] = " + str( h_list[ i ] ) + ". \n" ) + else: + h_ratio = math. log( h_list[ i ] / h_list[ i - 1 ] ) + l1_ratio = math. log( l1_norm_list[ i ] / l1_norm_list[ i - 1 ] ) + l2_ratio = math. log( l2_norm_list[ i ] / l2_norm_list[ i - 1 ] ) + max_ratio = math. log( max_norm_list[ i ] / max_norm_list[ i - 1 ] ) + if format == "latex": + file. write( " " + string. ljust( str( h_list[ i ] ), h_width ) + "&" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + "&" + + string. rjust( "{\\bf " + "%.2g" % ( l1_ratio / h_ratio ) + "}", err_width ) + "&" + + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + "&" + + string. rjust( "{\\bf " + "%.2g" % ( l2_ratio / h_ratio ) + "}", err_width ) + "&" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + "&" + + string. rjust( "{\\bf " + "%.2g" % ( max_ratio / h_ratio ) + "}", err_width ) + "\\\\\n" ) + if format == "txt": + file. write( "| " + string. ljust( str( h_list[ i ] ), h_width ) + " |" + + string. rjust( "%.2g" % l1_norm_list[ i ], err_width ) + " |" + + string. rjust( "**" + "%.2g" % ( l1_ratio / h_ratio ) + "**", err_width ) + " |" + + string. rjust( "%.2g" % l2_norm_list[ i ], err_width ) + " |" + + string. rjust( "**" + "%.2g" % ( l2_ratio / h_ratio ) + "**", err_width ) + " |" + + string. rjust( "%.2g" % max_norm_list[ i ], err_width ) + " |" + + string. rjust( "**" + "%.2g" % ( max_ratio / h_ratio ) + "**", err_width ) + " |\n" ) + file. write( "+--------------+----------------+----------------+----------------+----------------+----------------+----------------+\n" ) + i = i + 1 + +if format == "latex": + file. write( "\\hline \n" ) + file. write( "\\end{tabular} \n" ) + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..f79752b7187cf9de4f58299fa9add9ce72f2c407 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h @@ -0,0 +1,367 @@ +/*************************************************************************** + tnlParallelEikonalSolver.h - description + ------------------- + begin : Nov 28 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLPARALLELEIKONALSOLVER_H_ +#define TNLPARALLELEIKONALSOLVER_H_ + +#include <TNL/Config/ParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <TNL/Containers/StaticVector.h> +#include <functions/tnlMeshFunction.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <mesh/grids/tnlGridEntity.h> +#include <limits.h> +#include <core/tnlDevice.h> + #include <omp.h> + + +#include <ctime> + +#ifdef HAVE_CUDA +#include <cuda.h> +#include <core/tnlCuda.h> +#endif + + +template< int Dimension, + typename SchemeHost, + typename SchemeDevice, + typename Device, + typename RealType = double, + typename IndexType = int > +class tnlParallelEikonalSolver +{}; + +template<typename SchemeHost, typename SchemeDevice, typename Device> +class tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int > +{ +public: + + typedef SchemeDevice SchemeTypeDevice; + typedef SchemeHost SchemeTypeHost; + typedef Device DeviceType; + typedef tnlVector< double, tnlHost, int > VectorType; + typedef tnlVector< int, tnlHost, int > IntVectorType; + typedef tnlGrid< 2, double, tnlHost, int > MeshType; +#ifdef HAVE_CUDA + typedef tnlVector< double, tnlHost, int > VectorTypeCUDA; + typedef tnlVector< int, tnlHost, int > IntVectorTypeCUDA; + typedef tnlGrid< 2, double, tnlHost, int > MeshTypeCUDA; +#endif + tnlParallelEikonalSolver(); + bool init( const Config::ParameterContainer& parameters ); + void run(); + + void test(); + +/*private:*/ + + + void synchronize(); + + int getOwner( int i) const; + + int getSubgridValue( int i ) const; + + void setSubgridValue( int i, int value ); + + int getBoundaryCondition( int i ) const; + + void setBoundaryCondition( int i, int value ); + + void stretchGrid(); + + void contractGrid(); + + VectorType getSubgrid( const int i ) const; + + void insertSubgrid( VectorType u, const int i ); + + VectorType runSubgrid( int boundaryCondition, VectorType u, int subGridID); + + + tnlMeshFunction<MeshType> u0; + VectorType work_u; + IntVectorType subgridValues, boundaryConditions, unusedCell, calculationsCount; + MeshType mesh, subMesh; + +// tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage > Entity; + + SchemeHost schemeHost; + SchemeDevice schemeDevice; + double delta, tau0, stopTime,cflCondition; + int gridRows, gridCols, gridLevels, currentStep, n; + + std::clock_t start; + double time_diff; + + + tnlDeviceEnum device; + + tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* getSelf() + { + return this; + }; + +#ifdef HAVE_CUDA + + tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver; + + double* work_u_cuda; + + int* subgridValues_cuda; + int*boundaryConditions_cuda; + int* unusedCell_cuda; + int* calculationsCount_cuda; + double* tmpw; + //MeshTypeCUDA mesh_cuda, subMesh_cuda; + //SchemeDevice scheme_cuda; + //double delta_cuda, tau0_cuda, stopTime_cuda,cflCondition_cuda; + //int gridRows_cuda, gridCols_cuda, currentStep_cuda, n_cuda; + + int* runcuda; + int run_host; + + + __device__ void getSubgridCUDA2D( const int i, tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a); + + __device__ void updateSubgridCUDA2D( const int i, tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a); + + __device__ void insertSubgridCUDA2D( double u, const int i ); + + __device__ void runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID); + + /*__global__ void runCUDA();*/ + + //__device__ void synchronizeCUDA(); + + __device__ int getOwnerCUDA2D( int i) const; + + __device__ int getSubgridValueCUDA2D( int i ) const; + + __device__ void setSubgridValueCUDA2D( int i, int value ); + + __device__ int getBoundaryConditionCUDA2D( int i ) const; + + __device__ void setBoundaryConditionCUDA2D( int i, int value ); + + //__device__ bool initCUDA( tnlParallelEikonalSolver<SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); + + /*__global__ void initRunCUDA(tnlParallelEikonalSolver<Scheme, double, tnlHost, int >* caller);*/ + +#endif + +}; + + + + + + + + template<typename SchemeHost, typename SchemeDevice, typename Device> + class tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int > + { + public: + + typedef SchemeDevice SchemeTypeDevice; + typedef SchemeHost SchemeTypeHost; + typedef Device DeviceType; + typedef tnlVector< double, tnlHost, int > VectorType; + typedef tnlVector< int, tnlHost, int > IntVectorType; + typedef tnlGrid< 3, double, tnlHost, int > MeshType; + #ifdef HAVE_CUDA + typedef tnlVector< double, tnlHost, int > VectorTypeCUDA; + typedef tnlVector< int, tnlHost, int > IntVectorTypeCUDA; + typedef tnlGrid< 3, double, tnlHost, int > MeshTypeCUDA; + #endif + tnlParallelEikonalSolver(); + bool init( const Config::ParameterContainer& parameters ); + void run(); + + void test(); + + /*private:*/ + + + void synchronize(); + + int getOwner( int i) const; + + int getSubgridValue( int i ) const; + + void setSubgridValue( int i, int value ); + + int getBoundaryCondition( int i ) const; + + void setBoundaryCondition( int i, int value ); + + void stretchGrid(); + + void contractGrid(); + + VectorType getSubgrid( const int i ) const; + + void insertSubgrid( VectorType u, const int i ); + + VectorType runSubgrid( int boundaryCondition, VectorType u, int subGridID); + + + tnlMeshFunction<MeshType> u0; + VectorType work_u; + IntVectorType subgridValues, boundaryConditions, unusedCell, calculationsCount; + MeshType mesh, subMesh; + SchemeHost schemeHost; + SchemeDevice schemeDevice; + double delta, tau0, stopTime,cflCondition; + int gridRows, gridCols, gridLevels, currentStep, n; + + std::clock_t start; + double time_diff; + + + tnlDeviceEnum device; + + tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* getSelf() + { + return this; + }; + +#ifdef HAVE_CUDA + + tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver; + + double* work_u_cuda; + + int* subgridValues_cuda; + int*boundaryConditions_cuda; + int* unusedCell_cuda; + int* calculationsCount_cuda; + double* tmpw; + //MeshTypeCUDA mesh_cuda, subMesh_cuda; + //SchemeDevice scheme_cuda; + //double delta_cuda, tau0_cuda, stopTime_cuda,cflCondition_cuda; + //int gridRows_cuda, gridCols_cuda, currentStep_cuda, n_cuda; + + int* runcuda; + int run_host; + + + __device__ void getSubgridCUDA3D( const int i, tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a); + + __device__ void updateSubgridCUDA3D( const int i, tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller, double* a); + + __device__ void insertSubgridCUDA3D( double u, const int i ); + + __device__ void runSubgridCUDA3D( int boundaryCondition, double* u, int subGridID); + + /*__global__ void runCUDA();*/ + + //__device__ void synchronizeCUDA(); + + __device__ int getOwnerCUDA3D( int i) const; + + __device__ int getSubgridValueCUDA3D( int i ) const; + + __device__ void setSubgridValueCUDA3D( int i, int value ); + + __device__ int getBoundaryConditionCUDA3D( int i ) const; + + __device__ void setBoundaryConditionCUDA3D( int i, int value ); + + //__device__ bool initCUDA( tnlParallelEikonalSolver<SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); + + /*__global__ void initRunCUDA(tnlParallelEikonalSolver<Scheme, double, tnlHost, int >* caller);*/ + +#endif + +}; + + + + + + +#ifdef HAVE_CUDA +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void runCUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void initRunCUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* caller); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void initCUDA2D( tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr, int * ptr2, int* ptr3); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void synchronizeCUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void synchronize2CUDA2D(tnlParallelEikonalSolver<2, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); + + + + + + + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void runCUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void initRunCUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* caller); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void initCUDA3D( tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr, int * ptr2, int* ptr3); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void synchronizeCUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ void synchronize2CUDA3D(tnlParallelEikonalSolver<3, SchemeHost, SchemeDevice, Device, double, int >* cudaSolver); +#endif + + +#ifdef HAVE_CUDA +__cuda_callable__ +double fabsMin( double x, double y) +{ + double fx = fabs(x); + + if(Min(fx,fabs(y)) == fx) + return x; + else + return y; +} + +__cuda_callable__ +double atomicFabsMin(double* address, double val) +{ + unsigned long long int* address_as_ull = + (unsigned long long int*)address; + unsigned long long int old = *address_as_ull, assumed; + do { + assumed = old; + old = atomicCAS(address_as_ull, assumed,__double_as_longlong( fabsMin(__longlong_as_double(assumed),val) )); + } while (assumed != old); + return __longlong_as_double(old); +} + +#endif + +#include "tnlParallelEikonalSolver2D_impl.h" +#include "tnlParallelEikonalSolver3D_impl.h" +#endif /* TNLPARALLELEIKONALSOLVER_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..6279fbb805733172ebda8a78c68a128d0d33f92c --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver2D_impl.h @@ -0,0 +1,1928 @@ +/*************************************************************************** + tnlParallelEikonalSolver2D_impl.h - description + ------------------- + begin : Nov 28 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLPARALLELEIKONALSOLVER2D_IMPL_H_ +#define TNLPARALLELEIKONALSOLVER2D_IMPL_H_ + + +#include "tnlParallelEikonalSolver.h" +#include <core/mfilename.h> + +template< typename SchemeHost, typename SchemeDevice, typename Device> +tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::tnlParallelEikonalSolver() +{ + cout << "a" << endl; + this->device = tnlCudaDevice; /////////////// tnlCuda Device --- vypocet na GPU, tnlHostDevice --- vypocet na CPU + +#ifdef HAVE_CUDA + if(this->device == tnlCudaDevice) + { + run_host = 1; + } +#endif + + cout << "b" << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::test() +{ +/* + for(int i =0; i < this->subgridValues.getSize(); i++ ) + { + insertSubgrid(getSubgrid(i), i); + } +*/ +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> + +bool tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::init( const Config::ParameterContainer& parameters ) +{ + cout << "Initializating solver..." << endl; + const String& meshLocation = parameters.getParameter <String>("mesh"); + this->mesh.load( meshLocation ); + + this->n = parameters.getParameter <int>("subgrid-size"); + cout << "Setting N to " << this->n << endl; + + this->subMesh.setDimensions( this->n, this->n ); + this->subMesh.setDomain( Containers::StaticVector<2,double>(0.0, 0.0), + Containers::StaticVector<2,double>(mesh.template getSpaceStepsProducts< 1, 0 >()*(double)(this->n), mesh.template getSpaceStepsProducts< 0, 1 >()*(double)(this->n)) ); + + this->subMesh.save("submesh.tnl"); + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + this->u0.load( initialCondition ); + + //cout << this->mesh.getCellCenter(0) << endl; + + this->delta = parameters.getParameter <double>("delta"); + this->delta *= mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >(); + + cout << "Setting delta to " << this->delta << endl; + + this->tau0 = parameters.getParameter <double>("initial-tau"); + cout << "Setting initial tau to " << this->tau0 << endl; + this->stopTime = parameters.getParameter <double>("stop-time"); + + this->cflCondition = parameters.getParameter <double>("cfl-condition"); + this -> cflCondition *= sqrt(mesh.template getSpaceStepsProducts< 1, 0 >()*mesh.template getSpaceStepsProducts< 0, 1 >()); + cout << "Setting CFL to " << this->cflCondition << endl; + + stretchGrid(); + this->stopTime /= (double)(this->gridCols); + this->stopTime *= (1.0+1.0/((double)(this->n) - 2.0)); + cout << "Setting stopping time to " << this->stopTime << endl; + //this->stopTime = 1.5*((double)(this->n))*parameters.getParameter <double>("stop-time")*this->mesh.template getSpaceStepsProducts< 1, 0 >(); + //cout << "Setting stopping time to " << this->stopTime << endl; + + cout << "Initializating scheme..." << endl; + if(!this->schemeHost.init(parameters)) + { + cerr << "SchemeHost failed to initialize." << endl; + return false; + } + cout << "Scheme initialized." << endl; + + test(); + + VectorType* tmp = new VectorType[subgridValues.getSize()]; + bool containsCurve = false; + +#ifdef HAVE_CUDA + + if(this->device == tnlCudaDevice) + { + /*cout << "Testing... " << endl; + if(this->device == tnlCudaDevice) + { + if( !initCUDA2D(parameters, gridRows, gridCols) ) + return false; + }*/ + //cout << "s" << endl; + cudaMalloc(&(this->cudaSolver), sizeof(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >)); + //cout << "s" << endl; + cudaMemcpy(this->cudaSolver, this,sizeof(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >), cudaMemcpyHostToDevice); + //cout << "s" << endl; + double** tmpdev = NULL; + cudaMalloc(&tmpdev, sizeof(double*)); + //double* tmpw; + cudaMalloc(&(this->tmpw), this->work_u.getSize()*sizeof(double)); + cudaMalloc(&(this->runcuda), sizeof(int)); + cudaDeviceSynchronize(); + checkCudaDevice; + int* tmpUC; + cudaMalloc(&(tmpUC), this->work_u.getSize()*sizeof(int)); + cudaMemcpy(tmpUC, this->unusedCell.getData(), this->unusedCell.getSize()*sizeof(int), cudaMemcpyHostToDevice); + + initCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<1,1>>>(this->cudaSolver, (this->tmpw), (this->runcuda),tmpUC); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << "s " << endl; + //cudaMalloc(&(cudaSolver->work_u_cuda), this->work_u.getSize()*sizeof(double)); + double* tmpu = NULL; + + cudaMemcpy(&tmpu, tmpdev,sizeof(double*), cudaMemcpyDeviceToHost); + //printf("%p %p \n",tmpu,tmpw); + cudaMemcpy((this->tmpw), this->work_u.getData(), this->work_u.getSize()*sizeof(double), cudaMemcpyHostToDevice); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << "s "<< endl; + + } +#endif + + if(this->device == tnlHostDevice) + { + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + + if(! tmp[i].setSize(this->n * this->n)) + cout << "Could not allocate tmp["<< i <<"] array." << endl; + tmp[i] = getSubgrid(i); + containsCurve = false; + + for(int j = 0; j < tmp[i].getSize(); j++) + { + if(tmp[i][0]*tmp[i][j] <= 0.0) + { + containsCurve = true; + j=tmp[i].getSize(); + } + + } + if(containsCurve) + { + //cout << "Computing initial SDF on subgrid " << i << "." << endl; + tmp[i] = runSubgrid(0, tmp[i],i); + insertSubgrid(tmp[i], i); + setSubgridValue(i, 4); + //cout << "Computed initial SDF on subgrid " << i << "." << endl; + } + containsCurve = false; + + } + } +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { +// cout << "pre 1 kernel" << endl; + cudaDeviceSynchronize(); + checkCudaDevice; + dim3 threadsPerBlock(this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows); + cudaDeviceSynchronize(); + checkCudaDevice; + initRunCUDA2D<SchemeTypeHost,SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver); + cudaDeviceSynchronize(); +// cout << "post 1 kernel" << endl; + + } +#endif + + + this->currentStep = 1; + if(this->device == tnlHostDevice) + synchronize(); +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { + dim3 threadsPerBlock(this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows); + //double * test = (double*)malloc(this->work_u.getSize()*sizeof(double)); + //cout << test[0] <<" " << test[1] <<" " << test[2] <<" " << test[3] << endl; + //cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //cout << this->tmpw << " " << test[0] <<" " << test[1] << " " <<test[2] << " " <<test[3] << endl; + + checkCudaDevice; + + synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << test[0] << " " <<test[1] <<" " << test[2] << " " <<test[3] << endl; + //cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //checkCudaDevice; + //cout << this->tmpw << " " << test[0] << " " <<test[1] << " " <<test[2] <<" " << test[3] << endl; + //free(test); + + } + +#endif + cout << "Solver initialized." << endl; + + return true; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::run() +{ + if(this->device == tnlHostDevice) + { + + bool end = false; + while ((this->boundaryConditions.max() > 0 ) || !end) + { + if(this->boundaryConditions.max() == 0 ) + end=true; + else + end=false; +#ifdef HAVE_OPENMP +#pragma omp parallel for num_threads(4) schedule(dynamic) +#endif + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + if(getSubgridValue(i) != INT_MAX) + { + VectorType tmp; + tmp.setSize(this->n * this->n); + //cout << "subMesh: " << i << ", BC: " << getBoundaryCondition(i) << endl; + + if(getSubgridValue(i) == currentStep+4) + { + + if(getBoundaryCondition(i) & 1) + { + tmp = getSubgrid(i); + tmp = runSubgrid(1, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 2) + { + tmp = getSubgrid(i); + tmp = runSubgrid(1, tmp ,i); + insertSubgrid( tmp, 2); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 4) + { + tmp = getSubgrid(i); + tmp = runSubgrid(4, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 8) + { + tmp = getSubgrid(i); + tmp = runSubgrid(8, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + } + + if( ((getBoundaryCondition(i) & 2) )|| (getBoundaryCondition(i) & 1)//) + /* &&(!(getBoundaryCondition(i) & 5) && !(getBoundaryCondition(i) & 10)) */) + { + //cout << "3 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(1, tmp ,i); + insertSubgrid( tmp, 3); + } + if( ((getBoundaryCondition(i) & 4) )|| (getBoundaryCondition(i) & 1)//) + /* &&(!(getBoundaryCondition(i) & 3) && !(getBoundaryCondition(i) & 12)) */) + { + //cout << "5 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(5, tmp ,i); + insertSubgrid( tmp, i); + } + if( ((getBoundaryCondition(i) & 2) )|| (getBoundaryCondition(i) & 8)//) + /* &&(!(getBoundaryCondition(i) & 12) && !(getBoundaryCondition(i) & 3))*/ ) + { + //cout << "10 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(10, tmp ,i); + insertSubgrid( tmp, i); + } + if( ((getBoundaryCondition(i) & 4) )|| (getBoundaryCondition(i) & 8)//) + /*&&(!(getBoundaryCondition(i) & 10) && !(getBoundaryCondition(i) & 5)) */) + { + //cout << "12 @ " << getBoundaryCondition(i) << endl; + tmp = getSubgrid(i); + tmp = runSubgrid(12, tmp ,i); + insertSubgrid( tmp, i); + } + + + /*if(getBoundaryCondition(i)) + { + insertSubgrid( runSubgrid(15, getSubgrid(i),i), i); + }*/ + + setBoundaryCondition(i, 0); + + setSubgridValue(i, getSubgridValue(i)-1); + + } + } + synchronize(); + } + } +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { + //cout << "fn" << endl; + bool end_cuda = false; + dim3 threadsPerBlock(this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows); + cudaDeviceSynchronize(); + checkCudaDevice; + //cudaMalloc(&runcuda,sizeof(bool)); + //cudaMemcpy(runcuda, &run_host, sizeof(bool), cudaMemcpyHostToDevice); + //cout << "fn" << endl; + bool* tmpb; + //cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost); + //cudaDeviceSynchronize(); + //checkCudaDevice; + cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << "fn" << endl; + int i = 1; + time_diff = 0.0; + while (run_host || !end_cuda) + { + cout << "Computing at step "<< i++ << endl; + if(run_host != 0 ) + end_cuda = true; + else + end_cuda = false; + //cout << "a" << endl; + cudaDeviceSynchronize(); + checkCudaDevice; + start = std::clock(); + runCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,3*this->n*this->n*sizeof(double)>>>(this->cudaSolver); + //cout << "a" << endl; + cudaDeviceSynchronize(); + time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC); + + //start = std::clock(); + synchronizeCUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + synchronize2CUDA2D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + //time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC); + + + //cout << "a" << endl; + //run_host = false; + //cout << "in kernel loop" << run_host << endl; + //cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost); + cudaMemcpy(&run_host, (this->runcuda),sizeof(int), cudaMemcpyDeviceToHost); + //cout << "in kernel loop" << run_host << endl; + } + cout << "Solving time was: " << time_diff << endl; + //cout << "b" << endl; + + //double* tmpu; + //cudaMemcpy(tmpu, &(cudaSolver->work_u_cuda),sizeof(double*), cudaMemcpyHostToDevice); + //cudaMemcpy(this->work_u.getData(), tmpu, this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //cout << this->work_u.getData()[0] << endl; + + //double * test = (double*)malloc(this->work_u.getSize()*sizeof(double)); + //cout << test[0] << test[1] << test[2] << test[3] << endl; + cudaMemcpy(this->work_u.getData()/* test*/, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //cout << this->tmpw << " " << test[0] << test[1] << test[2] << test[3] << endl; + //free(test); + + cudaDeviceSynchronize(); + } +#endif + contractGrid(); + this->u0.save("u-00001.tnl"); + cout << "Maximum number of calculations on one subgrid was " << this->calculationsCount.absMax() << endl; + cout << "Average number of calculations on one subgrid was " << ( (double) this->calculationsCount.sum() / (double) this->calculationsCount.getSize() ) << endl; + cout << "Solver finished" << endl; + +#ifdef HAVE_CUDA + if(this->device == tnlCudaDevice) + { + cudaFree(this->runcuda); + cudaFree(this->tmpw); + cudaFree(this->cudaSolver); + } +#endif + +} + +//north - 1, east - 2, west - 4, south - 8 +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::synchronize() //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now +{ + cout << "Synchronizig..." << endl; + int tmp1, tmp2; + int grid1, grid2; + + if(this->currentStep & 1) + { + for(int j = 0; j < this->gridRows - 1; j++) + { + for (int i = 0; i < this->gridCols*this->n; i++) + { + tmp1 = this->gridCols*this->n*((this->n-1)+j*this->n) + i; + tmp2 = this->gridCols*this->n*((this->n)+j*this->n) + i; + grid1 = getSubgridValue(getOwner(tmp1)); + grid2 = getSubgridValue(getOwner(tmp2)); + if(getOwner(tmp1)==getOwner(tmp2)) + cout << "i, j" << i << "," << j << endl; + if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + this->unusedCell[tmp2] = 0; + if(grid2 == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp2)) & 8) ) + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+8); + } + else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + this->unusedCell[tmp1] = 0; + if(grid1 == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp1)) & 1) ) + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+1); + } + } + } + + } + else + { + for(int i = 1; i < this->gridCols; i++) + { + for (int j = 0; j < this->gridRows*this->n; j++) + { + tmp1 = this->gridCols*this->n*j + i*this->n - 1; + tmp2 = this->gridCols*this->n*j + i*this->n ; + grid1 = getSubgridValue(getOwner(tmp1)); + grid2 = getSubgridValue(getOwner(tmp2)); + if(getOwner(tmp1)==getOwner(tmp2)) + cout << "i, j" << i << "," << j << endl; + if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + this->unusedCell[tmp2] = 0; + if(grid2 == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp2)) & 4) ) + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+4); + } + else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + this->unusedCell[tmp1] = 0; + if(grid1 == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp1)) & 2) ) + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+2); + } + } + } + } + + + this->currentStep++; + int stepValue = this->currentStep + 4; + for (int i = 0; i < this->subgridValues.getSize(); i++) + { + if( getSubgridValue(i) == -INT_MAX ) + setSubgridValue(i, stepValue); + } + + cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl; + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwner(int i) const +{ + + return (i / (this->gridCols*this->n*this->n))*this->gridCols + (i % (this->gridCols*this->n))/this->n; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValue( int i ) const +{ + return this->subgridValues[i]; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValue(int i, int value) +{ + this->subgridValues[i] = value; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryCondition( int i ) const +{ + return this->boundaryConditions[i]; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryCondition(int i, int value) +{ + this->boundaryConditions[i] = value; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::stretchGrid() +{ + cout << "Stretching grid..." << endl; + + + this->gridCols = ceil( ((double)(this->mesh.getDimensions().x()-1)) / ((double)(this->n-1)) ); + this->gridRows = ceil( ((double)(this->mesh.getDimensions().y()-1)) / ((double)(this->n-1)) ); + + //this->gridCols = (this->mesh.getDimensions().x()-1) / (this->n-1) ; + //this->gridRows = (this->mesh.getDimensions().y()-1) / (this->n-1) ; + + cout << "Setting gridCols to " << this->gridCols << "." << endl; + cout << "Setting gridRows to " << this->gridRows << "." << endl; + + this->subgridValues.setSize(this->gridCols*this->gridRows); + this->subgridValues.setValue(0); + this->boundaryConditions.setSize(this->gridCols*this->gridRows); + this->boundaryConditions.setValue(0); + this->calculationsCount.setSize(this->gridCols*this->gridRows); + this->calculationsCount.setValue(0); + + for(int i = 0; i < this->subgridValues.getSize(); i++ ) + { + this->subgridValues[i] = INT_MAX; + this->boundaryConditions[i] = 0; + } + + int stretchedSize = this->n*this->n*this->gridCols*this->gridRows; + + if(!this->work_u.setSize(stretchedSize)) + cerr << "Could not allocate memory for stretched grid." << endl; + if(!this->unusedCell.setSize(stretchedSize)) + cerr << "Could not allocate memory for supporting stretched grid." << endl; + int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1); + cout << idealStretch << endl; + + for(int i = 0; i < stretchedSize; i++) + { + this->unusedCell[i] = 1; + int diff =(this->n*this->gridCols) - idealStretch ; + //cout << "diff = " << diff <<endl; + int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff; + + if(i%(this->n*this->gridCols) - idealStretch >= 0) + { + //cout << i%(this->n*this->gridCols) - idealStretch +1 << endl; + k+= i%(this->n*this->gridCols) - idealStretch +1 ; + } + + if(i/(this->n*this->gridCols) - idealStretch + 1 > 0) + { + //cout << i/(this->n*this->gridCols) - idealStretch + 1 << endl; + k+= (i/(this->n*this->gridCols) - idealStretch +1 )* this->mesh.getDimensions().x() ; + } + + //cout << "i = " << i << " : i-k = " << i-k << endl; + /*int j=(i % (this->n*this->gridCols)) - ( (this->mesh.getDimensions().x() - this->n)/(this->n - 1) + this->mesh.getDimensions().x() - 1) + + (this->n*this->gridCols - this->mesh.getDimensions().x())*(i/(this->n*this->n*this->gridCols)) ; + + if(j > 0) + k += j; + + int l = i-k - (this->u0.getSize() - 1); + int m = (l % this->mesh.getDimensions().x()); + + if(l>0) + k+= l + ( (l / this->mesh.getDimensions().x()) + 1 )*this->mesh.getDimensions().x() - (l % this->mesh.getDimensions().x());*/ + + this->work_u[i] = this->u0[i-k]; + //cout << (i-k) <<endl; + } + + + cout << "Grid stretched." << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::contractGrid() +{ + cout << "Contracting grid..." << endl; + int stretchedSize = this->n*this->n*this->gridCols*this->gridRows; + + int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1); + cout << idealStretch << endl; + + for(int i = 0; i < stretchedSize; i++) + { + int diff =(this->n*this->gridCols) - idealStretch ; + int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff; + + if((i%(this->n*this->gridCols) - idealStretch < 0) && (i/(this->n*this->gridCols) - idealStretch + 1 <= 0)) + { + //cout << i <<" : " <<i-k<< endl; + this->u0[i-k] = this->work_u[i]; + } + + } + + cout << "Grid contracted" << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +typename tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType +tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgrid( const int i ) const +{ + VectorType u; + u.setSize(this->n*this->n); + + for( int j = 0; j < u.getSize(); j++) + { + u[j] = this->work_u[ (i / this->gridCols) * this->n*this->n*this->gridCols + + (i % this->gridCols) * this->n + + (j/this->n) * this->n*this->gridCols + + (j % this->n) ]; + } + return u; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgrid( VectorType u, const int i ) +{ + + for( int j = 0; j < this->n*this->n; j++) + { + int index = (i / this->gridCols)*this->n*this->n*this->gridCols + + (i % this->gridCols)*this->n + + (j/this->n)*this->n*this->gridCols + + (j % this->n); + //OMP LOCK index + if( (fabs(this->work_u[index]) > fabs(u[j])) || (this->unusedCell[index] == 1) ) + { + this->work_u[index] = u[j]; + this->unusedCell[index] = 0; + } + //OMP UNLOCK index + } +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +typename tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::VectorType +tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgrid( int boundaryCondition, VectorType u, int subGridID) +{ + + VectorType fu; + + fu.setLike(u); + fu.setValue( 0.0 ); + +/* + * Insert Euler-Solver Here + */ + + /**/ + + /*for(int i = 0; i < u.getSize(); i++) + { + int x = this->subMesh.getCellCoordinates(i).x(); + int y = this->subMesh.getCellCoordinates(i).y(); + + if(x == 0 && (boundaryCondition & 4) && y ==0) + { + if((u[subMesh.getCellYSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0) + { + //cout << "x = 0; y = 0" << endl; + u[i] = u[subMesh.getCellYSuccessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >(); + } + } + else if(x == 0 && (boundaryCondition & 4) && y == subMesh.getDimensions().y() - 1) + { + if((u[subMesh.getCellYPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0) + { + //cout << "x = 0; y = n" << endl; + u[i] = u[subMesh.getCellYPredecessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >(); + } + } + + + else if(x == subMesh.getDimensions().x() - 1 && (boundaryCondition & 2) && y ==0) + { + if((u[subMesh.getCellYSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0) + { + //cout << "x = n; y = 0" << endl; + u[i] = u[subMesh.getCellYSuccessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >(); + } + } + else if(x == subMesh.getDimensions().x() - 1 && (boundaryCondition & 2) && y == subMesh.getDimensions().y() - 1) + { + if((u[subMesh.getCellYPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 0, 1 >() > 1.0) + { + //cout << "x = n; y = n" << endl; + u[i] = u[subMesh.getCellYPredecessor( i )] - subMesh.template getSpaceStepsProducts< 0, 1 >(); + } + } + + + else if(y == 0 && (boundaryCondition & 8) && x ==0) + { + if((u[subMesh.getCellXSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0) + { + //cout << "y = 0; x = 0" << endl; + u[i] = u[subMesh.getCellXSuccessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + } + else if(y == 0 && (boundaryCondition & 8) && x == subMesh.getDimensions().x() - 1) + { + if((u[subMesh.getCellXPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0) + { + //cout << "y = 0; x = n" << endl; + u[i] = u[subMesh.getCellXPredecessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + } + + + else if(y == subMesh.getDimensions().y() - 1 && (boundaryCondition & 1) && x ==0) + { + if((u[subMesh.getCellXSuccessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0) { + //cout << "y = n; x = 0" << endl; + u[i] = u[subMesh.getCellXSuccessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + } + else if(y == subMesh.getDimensions().y() - 1 && (boundaryCondition & 1) && x == subMesh.getDimensions().x() - 1) + { + if((u[subMesh.getCellXPredecessor( i )] - u[i])/subMesh.template getSpaceStepsProducts< 1, 0 >() > 1.0) + { + //cout << "y = n; x = n" << endl; + u[i] = u[subMesh.getCellXPredecessor( i )] - subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + } + }*/ + + /**/ + + +/* bool tmp = false; + for(int i = 0; i < u.getSize(); i++) + { + if(u[0]*u[i] <= 0.0) + tmp=true; + } + + + if(tmp) + {} + else if(boundaryCondition == 4) + { + int i; + for(i = 0; i < u.getSize() - subMesh.getDimensions().x() ; i=subMesh.getCellYSuccessor(i)) + { + int j; + for(j = i; j < subMesh.getDimensions().x() - 1; j=subMesh.getCellXSuccessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + } + int j; + for(j = i; j < subMesh.getDimensions().x() - 1; j=subMesh.getCellXSuccessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + } + else if(boundaryCondition == 8) + { + int i; + for(i = 0; i < subMesh.getDimensions().x() - 1; i=subMesh.getCellXSuccessor(i)) + { + int j; + for(j = i; j < u.getSize() - subMesh.getDimensions().x(); j=subMesh.getCellYSuccessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + } + int j; + for(j = i; j < u.getSize() - subMesh.getDimensions().x(); j=subMesh.getCellYSuccessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + + } + else if(boundaryCondition == 2) + { + int i; + for(i = subMesh.getDimensions().x() - 1; i < u.getSize() - subMesh.getDimensions().x() ; i=subMesh.getCellYSuccessor(i)) + { + int j; + for(j = i; j > (i-1)*subMesh.getDimensions().x(); j=subMesh.getCellXPredecessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + } + int j; + for(j = i; j > (i-1)*subMesh.getDimensions().x(); j=subMesh.getCellXPredecessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + } + else if(boundaryCondition == 1) + { + int i; + for(i = (subMesh.getDimensions().y() - 1)*subMesh.getDimensions().x(); i < u.getSize() - 1; i=subMesh.getCellXSuccessor(i)) + { + int j; + for(j = i; j >=subMesh.getDimensions().x(); j=subMesh.getCellYPredecessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + } + int j; + for(j = i; j >=subMesh.getDimensions().x(); j=subMesh.getCellYPredecessor(j)) + { + u[j] = u[i]; + } + u[j] = u[i]; + } +*/ + /**/ + + + + bool tmp = false; + for(int i = 0; i < u.getSize(); i++) + { + if(u[0]*u[i] <= 0.0) + tmp=true; + int centerGID = (this->n*(subGridID / this->gridRows)+ (this->n >> 1))*(this->n*this->gridCols) + this->n*(subGridID % this->gridRows) + (this->n >> 1); + if(this->unusedCell[centerGID] == 0 || boundaryCondition == 0) + tmp = true; + } + //if(this->currentStep + 3 < getSubgridValue(subGridID)) + //tmp = true; + + + double value = sign(u[0]) * u.absMax(); + + if(tmp) + {} + + + //north - 1, east - 2, west - 4, south - 8 + else if(boundaryCondition == 4) + { + for(int i = 0; i < this->n; i++) + for(int j = 1;j < this->n; j++) + //if(fabs(u[i*this->n + j]) < fabs(u[i*this->n])) + u[i*this->n + j] = value;// u[i*this->n]; + } + else if(boundaryCondition == 2) + { + for(int i = 0; i < this->n; i++) + for(int j =0 ;j < this->n -1; j++) + //if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1])) + u[i*this->n + j] = value;// u[(i+1)*this->n - 1]; + } + else if(boundaryCondition == 1) + { + for(int j = 0; j < this->n; j++) + for(int i = 0;i < this->n - 1; i++) + //if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)])) + u[i*this->n + j] = value;// u[j + this->n*(this->n - 1)]; + } + else if(boundaryCondition == 8) + { + for(int j = 0; j < this->n; j++) + for(int i = 1;i < this->n; i++) + //if(fabs(u[i*this->n + j]) < fabs(u[j])) + u[i*this->n + j] = value;// u[j]; + } + +/* + + else if(boundaryCondition == 5) + { + for(int i = 0; i < this->n - 1; i++) + for(int j = 1;j < this->n; j++) + //if(fabs(u[i*this->n + j]) < fabs(u[i*this->n])) + u[i*this->n + j] = value;// u[i*this->n]; + } + else if(boundaryCondition == 10) + { + for(int i = 1; i < this->n; i++) + for(int j =0 ;j < this->n -1; j++) + //if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1])) + u[i*this->n + j] = value;// u[(i+1)*this->n - 1]; + } + else if(boundaryCondition == 3) + { + for(int j = 0; j < this->n - 1; j++) + for(int i = 0;i < this->n - 1; i++) + //if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)])) + u[i*this->n + j] = value;// u[j + this->n*(this->n - 1)]; + } + else if(boundaryCondition == 12) + { + for(int j = 1; j < this->n; j++) + for(int i = 1;i < this->n; i++) + //if(fabs(u[i*this->n + j]) < fabs(u[j])) + u[i*this->n + j] = value;// u[j]; + } +*/ + + + /**/ + + /*if (u.max() > 0.0) + this->stopTime *=(double) this->gridCols;*/ + + + double time = 0.0; + double currentTau = this->tau0; + double finalTime = this->stopTime;// + 3.0*(u.max() - u.min()); + if( time + currentTau > finalTime ) currentTau = finalTime - time; + + double maxResidue( 1.0 ); + //double lastResidue( 10000.0 ); + tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + while( time < finalTime /*|| maxResidue > subMesh.template getSpaceStepsProducts< 1, 0 >()*/) + { + /**** + * Compute the RHS + */ + + for( int i = 0; i < fu.getSize(); i ++ ) + { + Entity.setCoordinates(Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x())); + Entity.refresh(); + neighbourEntities.refresh(subMesh,Entity.getIndex()); + fu[ i ] = schemeHost.getValue( this->subMesh, i, Containers::StaticVector<2,int>(i % subMesh.getDimensions().x(),i / subMesh.getDimensions().x()), u, time, boundaryCondition,neighbourEntities); + } + maxResidue = fu. absMax(); + + + if( this -> cflCondition * maxResidue != 0.0) + currentTau = this -> cflCondition / maxResidue; + + /* if (maxResidue < 0.05) + cout << "Max < 0.05" << endl;*/ + if(currentTau > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >()) + { + //cout << currentTau << " >= " << 2.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >() << endl; + currentTau = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + /*if(maxResidue > lastResidue) + currentTau *=(1.0/10.0);*/ + + + if( time + currentTau > finalTime ) currentTau = finalTime - time; +// for( int i = 0; i < fu.getSize(); i ++ ) +// { +// //cout << "Too big RHS! i = " << i << ", fu = " << fu[i] << ", u = " << u[i] << endl; +// if((u[i]+currentTau * fu[ i ])*u[i] < 0.0 && fu[i] != 0.0 && u[i] != 0.0 ) +// currentTau = fabs(u[i]/(2.0*fu[i])); +// +// } + + + for( int i = 0; i < fu.getSize(); i ++ ) + { + double add = u[i] + currentTau * fu[ i ]; + //if( fabs(u[i]) < fabs(add) or (this->subgridValues[subGridID] == this->currentStep +4) ) + u[ i ] = add; + } + time += currentTau; + + //cout << '\r' << flush; + //cout << maxResidue << " " << currentTau << " @ " << time << flush; + //lastResidue = maxResidue; + } + //cout << "Time: " << time << ", Res: " << maxResidue <<endl; + /*if (u.max() > 0.0) + this->stopTime /=(double) this->gridCols;*/ + + VectorType solution; + solution.setLike(u); + for( int i = 0; i < u.getSize(); i ++ ) + { + solution[i]=u[i]; + } + return solution; +} + + +#ifdef HAVE_CUDA + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridCUDA2D( const int i ,tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a) +{ + //int j = threadIdx.x + threadIdx.y * blockDim.x; + int th = (blockIdx.y) * caller->n*caller->n*caller->gridCols + + (blockIdx.x) * caller->n + + threadIdx.y * caller->n*caller->gridCols + + threadIdx.x; + //printf("i= %d,j= %d,th= %d\n",i,j,th); + *a = caller->work_u_cuda[th]; + //printf("Hi %f \n", *a); + //return ret; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::updateSubgridCUDA2D( const int i ,tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a) +{ +// int j = threadIdx.x + threadIdx.y * blockDim.x; + int index = (blockIdx.y) * caller->n*caller->n*caller->gridCols + + (blockIdx.x) * caller->n + + threadIdx.y * caller->n*caller->gridCols + + threadIdx.x; + + if( (fabs(caller->work_u_cuda[index]) > fabs(*a)) || (caller->unusedCell_cuda[index] == 1) ) + { + caller->work_u_cuda[index] = *a; + caller->unusedCell_cuda[index] = 0; + + } + + *a = caller->work_u_cuda[index]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::insertSubgridCUDA2D( double u, const int i ) +{ + + +// int j = threadIdx.x + threadIdx.y * blockDim.x; + //printf("j = %d, u = %f\n", j,u); + + int index = (blockIdx.y)*this->n*this->n*this->gridCols + + (blockIdx.x)*this->n + + threadIdx.y*this->n*this->gridCols + + threadIdx.x; + + //printf("i= %d,j= %d,index= %d\n",i,j,index); + if( (fabs(this->work_u_cuda[index]) > fabs(u)) || (this->unusedCell_cuda[index] == 1) ) + { + this->work_u_cuda[index] = u; + this->unusedCell_cuda[index] = 0; + + } + + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::runSubgridCUDA2D( int boundaryCondition, double* u, int subGridID) +{ + + __shared__ int tmp; + __shared__ double value; + //double tmpRes = 0.0; + volatile double* sharedTau = &u[blockDim.x*blockDim.y]; + volatile double* absVal = &u[2*blockDim.x*blockDim.y]; + int i = threadIdx.x; + int j = threadIdx.y; + int l = threadIdx.y * blockDim.x + threadIdx.x; + bool computeFU = !((i == 0 && (boundaryCondition & 4)) or + (i == blockDim.x - 1 && (boundaryCondition & 2)) or + (j == 0 && (boundaryCondition & 8)) or + (j == blockDim.y - 1 && (boundaryCondition & 1))); + + if(l == 0) + { + tmp = 0; + int centerGID = (blockDim.y*blockIdx.y + (blockDim.y>>1))*(blockDim.x*gridDim.x) + blockDim.x*blockIdx.x + (blockDim.x>>1); + if(this->unusedCell_cuda[centerGID] == 0 || boundaryCondition == 0) + tmp = 1; + } + __syncthreads(); + + /*if(!tmp && (u[0]*u[l] <= 0.0)) + atomicMax( &tmp, 1);*/ + + __syncthreads(); + if(tmp !=1) + { +// if(computeFU) +// absVal[l]=0.0; +// else +// absVal[l] = fabs(u[l]); +// +// __syncthreads(); +// +// if((blockDim.x == 16) && (l < 128)) absVal[l] = Max(absVal[l],absVal[l+128]); +// __syncthreads(); +// if((blockDim.x == 16) && (l < 64)) absVal[l] = Max(absVal[l],absVal[l+64]); +// __syncthreads(); +// if(l < 32) absVal[l] = Max(absVal[l],absVal[l+32]); +// if(l < 16) absVal[l] = Max(absVal[l],absVal[l+16]); +// if(l < 8) absVal[l] = Max(absVal[l],absVal[l+8]); +// if(l < 4) absVal[l] = Max(absVal[l],absVal[l+4]); +// if(l < 2) absVal[l] = Max(absVal[l],absVal[l+2]); +// if(l < 1) value = sign(u[0])*Max(absVal[l],absVal[l+1]); +// __syncthreads(); +// +// if(computeFU) +// u[l] = value; + if(computeFU) + { + if(boundaryCondition == 4) + u[l] = u[threadIdx.y * blockDim.x] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.x) ;//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.x+this->n); + else if(boundaryCondition == 2) + u[l] = u[threadIdx.y * blockDim.x + blockDim.x - 1] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.x);//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(blockDim.x - threadIdx.x - 1+this->n); + else if(boundaryCondition == 8) + u[l] = u[threadIdx.x] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.y) ;//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(threadIdx.y+this->n); + else if(boundaryCondition == 1) + u[l] = u[(blockDim.y - 1)* blockDim.x + threadIdx.x] + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(this->n - 1 - threadIdx.y) ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0 >()*(blockDim.y - threadIdx.y - 1 +this->n); + } + } + + double time = 0.0; + __shared__ double currentTau; + double cfl = this->cflCondition; + double fu = 0.0; +// if(threadIdx.x * threadIdx.y == 0) +// { +// currentTau = finalTime; +// } + double finalTime = this->stopTime; + __syncthreads(); +// if( time + currentTau > finalTime ) currentTau = finalTime - time; + + tnlGridEntity<MeshType, 2, tnlGridEntityNoStencilStorage > Entity(subMesh); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 2, tnlGridEntityNoStencilStorage >,2> neighbourEntities(Entity); + Entity.setCoordinates(Containers::StaticVector<2,int>(i,j)); + Entity.refresh(); + neighbourEntities.refresh(subMesh,Entity.getIndex()); + + + while( time < finalTime ) + { + if(computeFU) + fu = schemeHost.getValueDev( this->subMesh, l, Containers::StaticVector<2,int>(i,j)/*this->subMesh.getCellCoordinates(l)*/, u, time, boundaryCondition, neighbourEntities); + + sharedTau[l]=abs(cfl/fu); + + if(l == 0) + { + if(sharedTau[0] > 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >()) sharedTau[0] = 1.0 * this->subMesh.template getSpaceStepsProducts< 1, 0 >(); + } + else if(l == blockDim.x*blockDim.y - 1) + if( time + sharedTau[l] > finalTime ) sharedTau[l] = finalTime - time; + + +// if( (sign(u[l]+sharedTau[l]*fu) != sign(u[l])) && fu != 0.0 && fu != -0.0) +// { +// printf("orig: %10f", sharedTau[l]); +// sharedTau[l]=abs(u[l]/(1.1*fu)) ; +// printf(" new: %10f\n", sharedTau[l]); +// } + + + + if((blockDim.x == 16) && (l < 128)) sharedTau[l] = Min(sharedTau[l],sharedTau[l+128]); + __syncthreads(); + if((blockDim.x == 16) && (l < 64)) sharedTau[l] = Min(sharedTau[l],sharedTau[l+64]); + __syncthreads(); + if(l < 32) sharedTau[l] = Min(sharedTau[l],sharedTau[l+32]); + if(l < 16) sharedTau[l] = Min(sharedTau[l],sharedTau[l+16]); + if(l < 8) sharedTau[l] = Min(sharedTau[l],sharedTau[l+8]); + if(l < 4) sharedTau[l] = Min(sharedTau[l],sharedTau[l+4]); + if(l < 2) sharedTau[l] = Min(sharedTau[l],sharedTau[l+2]); + if(l < 1) currentTau = Min(sharedTau[l],sharedTau[l+1]); + __syncthreads(); + + u[l] += currentTau * fu; + time += currentTau; + } + + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getOwnerCUDA2D(int i) const +{ + + return ((i / (this->gridCols*this->n*this->n))*this->gridCols + + (i % (this->gridCols*this->n))/this->n); +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValueCUDA2D( int i ) const +{ + return this->subgridValues_cuda[i]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValueCUDA2D(int i, int value) +{ + this->subgridValues_cuda[i] = value; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryConditionCUDA2D( int i ) const +{ + return this->boundaryConditions_cuda[i]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryConditionCUDA2D(int i, int value) +{ + this->boundaryConditions_cuda[i] = value; +} + + + +//north - 1, east - 2, west - 4, south - 8 + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/synchronizeCUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now +{ + + __shared__ int boundary[4]; // north,east,west,south + __shared__ int subgridValue; + __shared__ int newSubgridValue; + + + int gid = (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + blockDim.x*blockIdx.x + threadIdx.x; + double u = cudaSolver->work_u_cuda[gid]; + double u_cmp; + int subgridValue_cmp=INT_MAX; + int boundary_index=0; + + + if(threadIdx.x+threadIdx.y == 0) + { + subgridValue = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x); + boundary[0] = 0; + boundary[1] = 0; + boundary[2] = 0; + boundary[3] = 0; + newSubgridValue = 0; + //printf("%d %d\n", blockDim.x, gridDim.x); + } + __syncthreads(); + + + + if( (threadIdx.x == 0 /* && !(cudaSolver->currentStep & 1)*/) || + (threadIdx.y == 0 /* && (cudaSolver->currentStep & 1)*/) || + (threadIdx.x == blockDim.x - 1 /* && !(cudaSolver->currentStep & 1)*/) || + (threadIdx.y == blockDim.y - 1 /* && (cudaSolver->currentStep & 1)*/) ) + { + if(threadIdx.x == 0 && (blockIdx.x != 0)/* && !(cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid - 1]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x - 1); + boundary_index = 2; + } + + if(threadIdx.x == blockDim.x - 1 && (blockIdx.x != gridDim.x - 1)/* && !(cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid + 1]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x + 1); + boundary_index = 1; + } + + __threadfence(); + if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX)) + { + cudaSolver->unusedCell_cuda[gid] = 0; + atomicMax(&newSubgridValue, INT_MAX); + atomicMax(&boundary[boundary_index], 1); + cudaSolver->work_u_cuda[gid] = u_cmp; + u=u_cmp; + } + __threadfence(); + if(threadIdx.y == 0 && (blockIdx.y != 0)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y - 1)*gridDim.x + blockIdx.x); + boundary_index = 3; + } + if(threadIdx.y == blockDim.y - 1 && (blockIdx.y != gridDim.y - 1)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA2D((blockIdx.y + 1)*gridDim.x + blockIdx.x); + boundary_index = 0; + } + +// __threadfence(); + if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX)) + { + cudaSolver->unusedCell_cuda[gid] = 0; + atomicMax(&newSubgridValue, INT_MAX); + atomicMax(&boundary[boundary_index], 1); + cudaSolver->work_u_cuda[gid] = u_cmp; + } + } + __threadfence(); + __syncthreads(); + + if(threadIdx.x+threadIdx.y == 0) + { + if(subgridValue == INT_MAX && newSubgridValue !=0) + cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, -INT_MAX); + + cudaSolver->setBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, boundary[0] + + 2 * boundary[1] + + 4 * boundary[2] + + 8 * boundary[3]); + + + if(blockIdx.x+blockIdx.y ==0) + { + cudaSolver->currentStep = cudaSolver->currentStep + 1; + *(cudaSolver->runcuda) = 0; + } +// +// int stepValue = cudaSolver->currentStep + 4; +// if( cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX ) +// cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, stepValue); +// +// atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x)); + } + + + /* + //printf("I am not an empty kernel!\n"); + //cout << "Synchronizig..." << endl; + int tmp1, tmp2; + int grid1, grid2; + + if(cudaSolver->currentStep & 1) + { + //printf("I am not an empty kernel! 1\n"); + for(int j = 0; j < cudaSolver->gridRows - 1; j++) + { + //printf("I am not an empty kernel! 3\n"); + for (int i = 0; i < cudaSolver->gridCols*cudaSolver->n; i++) + { + tmp1 = cudaSolver->gridCols*cudaSolver->n*((cudaSolver->n-1)+j*cudaSolver->n) + i; + tmp2 = cudaSolver->gridCols*cudaSolver->n*((cudaSolver->n)+j*cudaSolver->n) + i; + grid1 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1)); + grid2 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2)); + + if ((fabs(cudaSolver->work_u_cuda[tmp1]) < fabs(cudaSolver->work_u_cuda[tmp2]) - cudaSolver->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + //printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2)); + cudaSolver->work_u_cuda[tmp2] = cudaSolver->work_u_cuda[tmp1]; + cudaSolver->unusedCell_cuda[tmp2] = 0; + if(grid2 == INT_MAX) + { + cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), -INT_MAX); + } + if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2)) & 8) ) + cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2))+8); + } + else if ((fabs(cudaSolver->work_u_cuda[tmp1]) > fabs(cudaSolver->work_u_cuda[tmp2]) + cudaSolver->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + //printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2)); + cudaSolver->work_u_cuda[tmp1] = cudaSolver->work_u_cuda[tmp2]; + cudaSolver->unusedCell_cuda[tmp1] = 0; + if(grid1 == INT_MAX) + { + cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), -INT_MAX); + } + if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1)) & 1) ) + cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1))+1); + } + } + } + + } + else + { + //printf("I am not an empty kernel! 2\n"); + for(int i = 1; i < cudaSolver->gridCols; i++) + { + //printf("I am not an empty kernel! 4\n"); + for (int j = 0; j < cudaSolver->gridRows*cudaSolver->n; j++) + { + + tmp1 = cudaSolver->gridCols*cudaSolver->n*j + i*cudaSolver->n - 1; + tmp2 = cudaSolver->gridCols*cudaSolver->n*j + i*cudaSolver->n ; + grid1 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1)); + grid2 = cudaSolver->getSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2)); + + if ((fabs(cudaSolver->work_u_cuda[tmp1]) < fabs(cudaSolver->work_u_cuda[tmp2]) - cudaSolver->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + //printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2)); + cudaSolver->work_u_cuda[tmp2] = cudaSolver->work_u_cuda[tmp1]; + cudaSolver->unusedCell_cuda[tmp2] = 0; + if(grid2 == INT_MAX) + { + cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), -INT_MAX); + } + if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2)) & 4) ) + cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp2))+4); + } + else if ((fabs(cudaSolver->work_u_cuda[tmp1]) > fabs(cudaSolver->work_u_cuda[tmp2]) + cudaSolver->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + //printf("%d %d %d %d \n",tmp1,tmp2,cudaSolver->getOwnerCUDA2D(tmp1),cudaSolver->getOwnerCUDA2D(tmp2)); + cudaSolver->work_u_cuda[tmp1] = cudaSolver->work_u_cuda[tmp2]; + cudaSolver->unusedCell_cuda[tmp1] = 0; + if(grid1 == INT_MAX) + { + cudaSolver->setSubgridValueCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), -INT_MAX); + } + if(! (cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1)) & 2) ) + cudaSolver->setBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1), cudaSolver->getBoundaryConditionCUDA2D(cudaSolver->getOwnerCUDA2D(tmp1))+2); + } + } + } + } + //printf("I am not an empty kernel! 5 cudaSolver->currentStep : %d \n", cudaSolver->currentStep); + + cudaSolver->currentStep = cudaSolver->currentStep + 1; + int stepValue = cudaSolver->currentStep + 4; + for (int i = 0; i < cudaSolver->gridRows * cudaSolver->gridCols; i++) + { + if( cudaSolver->getSubgridValueCUDA2D(i) == -INT_MAX ) + cudaSolver->setSubgridValueCUDA2D(i, stepValue); + } + + int maxi = 0; + for(int q=0; q < cudaSolver->gridRows*cudaSolver->gridCols;q++) + { + //printf("%d : %d\n", q, cudaSolver->boundaryConditions_cuda[q]); + maxi=Max(maxi,cudaSolver->getBoundaryConditionCUDA2D(q)); + } + //printf("I am not an empty kernel! %d\n", maxi); + *(cudaSolver->runcuda) = (maxi > 0); + //printf("I am not an empty kernel! 7 %d\n", cudaSolver->boundaryConditions_cuda[0]); + //cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl; +*/ +} + + + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void synchronize2CUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) +{ +// if(blockIdx.x+blockIdx.y ==0) +// { +// cudaSolver->currentStep = cudaSolver->currentStep + 1; +// *(cudaSolver->runcuda) = 0; +// } + + int stepValue = cudaSolver->currentStep + 4; + if( cudaSolver->getSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX ) + cudaSolver->setSubgridValueCUDA2D(blockIdx.y*gridDim.x + blockIdx.x, stepValue); + + atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA2D(blockIdx.y*gridDim.x + blockIdx.x)); +} + + + + + + + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/initCUDA2D( tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr , int* ptr2, int* ptr3) +{ + //cout << "Initializating solver..." << endl; + //const String& meshLocation = parameters.getParameter <String>("mesh"); + //this->mesh_cuda.load( meshLocation ); + + //this->n_cuda = parameters.getParameter <int>("subgrid-size"); + //cout << "Setting N << this->n_cuda << endl; + + //this->subMesh_cuda.setDimensions( this->n_cuda, this->n_cuda ); + //this->subMesh_cuda.setDomain( Containers::StaticVector<2,double>(0.0, 0.0), + //Containers::StaticVector<2,double>(this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >()*(double)(this->n_cuda), this->mesh_cuda.template getSpaceStepsProducts< 0, 1 >()*(double)(this->n_cuda)) ); + + //this->subMesh_cuda.save("submesh.tnl"); + +// const String& initialCondition = parameters.getParameter <String>("initial-condition"); +// this->u0.load( initialCondition ); + + //cout << this->mesh.getCellCenter(0) << endl; + + //this->delta_cuda = parameters.getParameter <double>("delta"); + //this->delta_cuda *= this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >()*this->mesh_cuda.template getSpaceStepsProducts< 0, 1 >(); + + //cout << "Setting delta to " << this->delta << endl; + + //this->tau0_cuda = parameters.getParameter <double>("initial-tau"); + //cout << "Setting initial tau to " << this->tau0_cuda << endl; + //this->stopTime_cuda = parameters.getParameter <double>("stop-time"); + + //this->cflCondition_cuda = parameters.getParameter <double>("cfl-condition"); + //this -> cflCondition_cuda *= sqrt(this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >()*this->mesh_cuda.template getSpaceStepsProducts< 0, 1 >()); + //cout << "Setting CFL to " << this->cflCondition << endl; +//// +//// + +// this->gridRows_cuda = gridRows; +// this->gridCols_cuda = gridCols; + + cudaSolver->work_u_cuda = ptr;//(double*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(double)); + cudaSolver->unusedCell_cuda = ptr3;//(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(int)); + cudaSolver->subgridValues_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int)); + cudaSolver->boundaryConditions_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*sizeof(int)); + cudaSolver->runcuda = ptr2;//(bool*)malloc(sizeof(bool)); + *(cudaSolver->runcuda) = 1; + cudaSolver->currentStep = 1; + //cudaMemcpy(ptr,&(cudaSolver->work_u_cuda), sizeof(double*),cudaMemcpyDeviceToHost); + //ptr = cudaSolver->work_u_cuda; + printf("GPU memory allocated.\n"); + + for(int i = 0; i < cudaSolver->gridCols*cudaSolver->gridRows; i++) + { + cudaSolver->subgridValues_cuda[i] = INT_MAX; + cudaSolver->boundaryConditions_cuda[i] = 0; + } + + /*for(long int j = 0; j < cudaSolver->n*cudaSolver->n*cudaSolver->gridCols*cudaSolver->gridRows; j++) + { + printf("%d\n",j); + cudaSolver->unusedCell_cuda[ j] = 1; + }*/ + printf("GPU memory initialized.\n"); + + + //cudaSolver->work_u_cuda[50] = 32.153438; +//// +//// + //stretchGrid(); + //this->stopTime_cuda /= (double)(this->gridCols_cuda); + //this->stopTime_cuda *= (1.0+1.0/((double)(this->n_cuda) - 1.0)); + //cout << "Setting stopping time to " << this->stopTime << endl; + //this->stopTime_cuda = 1.5*((double)(this->n_cuda))*parameters.getParameter <double>("stop-time")*this->mesh_cuda.template getSpaceStepsProducts< 1, 0 >(); + //cout << "Setting stopping time to " << this->stopTime << endl; + + //cout << "Initializating scheme..." << endl; + //if(!this->schemeDevice.init(parameters)) +// { + //cerr << "Scheme failed to initialize." << endl; +// return false; +// } + //cout << "Scheme initialized." << endl; + + //test(); + +// this->currentStep_cuda = 1; + //return true; +} + + + + +//extern __shared__ double array[]; +template< typename SchemeHost, typename SchemeDevice, typename Device > +__global__ +void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/initRunCUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller) + +{ + + + extern __shared__ double u[]; + //printf("%p\n",caller->work_u_cuda); + + int i = blockIdx.y * gridDim.x + blockIdx.x; + int l = threadIdx.y * blockDim.x + threadIdx.x; + + __shared__ int containsCurve; + if(l == 0) + containsCurve = 0; + + //double a; + caller->getSubgridCUDA2D(i,caller, &u[l]); + //printf("%f %f\n",a , u[l]); + //u[l] = a; + //printf("Hi %f \n", u[l]); + __syncthreads(); + //printf("hurewrwr %f \n", u[l]); + if(u[0] * u[l] <= 0.0) + { + //printf("contains %d \n",i); + atomicMax( &containsCurve, 1); + } + + __syncthreads(); + //printf("hu"); + //printf("%d : %f\n", l, u[l]); + if(containsCurve == 1) + { + //printf("have curve \n"); + caller->runSubgridCUDA2D(0,u,i); + //printf("%d : %f\n", l, u[l]); + __syncthreads(); + caller->insertSubgridCUDA2D(u[l],i); + __syncthreads(); + if(l == 0) + caller->setSubgridValueCUDA2D(i, 4); + } + + +} + + + + + +template< typename SchemeHost, typename SchemeDevice, typename Device > +__global__ +void /*tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int>::*/runCUDA2D(tnlParallelEikonalSolver<2,SchemeHost, SchemeDevice, Device, double, int >* caller) +{ + extern __shared__ double u[]; + int i = blockIdx.y * gridDim.x + blockIdx.x; + int l = threadIdx.y * blockDim.x + threadIdx.x; + int bound = caller->getBoundaryConditionCUDA2D(i); + + if(caller->getSubgridValueCUDA2D(i) != INT_MAX && bound != 0 && caller->getSubgridValueCUDA2D(i) > 0) + { + caller->getSubgridCUDA2D(i,caller, &u[l]); + + //if(l == 0) + //printf("i = %d, bound = %d\n",i,caller->getSubgridValueCUDA2D(i)); + if(caller->getSubgridValueCUDA2D(i) == caller->currentStep+4) + { + if(bound & 1) + { + caller->runSubgridCUDA2D(1,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 2 ) + { + caller->runSubgridCUDA2D(2,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 4) + { + caller->runSubgridCUDA2D(4,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 8) + { + caller->runSubgridCUDA2D(8,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + + + + + + if( ((bound & 3 ))) + { + caller->runSubgridCUDA2D(3,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 5 ))) + { + caller->runSubgridCUDA2D(5,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 10 ))) + { + caller->runSubgridCUDA2D(10,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( (bound & 12 )) + { + caller->runSubgridCUDA2D(12,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + + + + + + } + + + else + { + + + + + + + + + + if( ((bound == 2))) + { + caller->runSubgridCUDA2D(2,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound == 1) )) + { + caller->runSubgridCUDA2D(1,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound == 8) )) + { + caller->runSubgridCUDA2D(8,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( (bound == 4)) + { + caller->runSubgridCUDA2D(4,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + + + + + + + + + + + if( ((bound & 3) )) + { + caller->runSubgridCUDA2D(3,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 5) )) + { + caller->runSubgridCUDA2D(5,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 10) )) + { + caller->runSubgridCUDA2D(10,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + if( (bound & 12) ) + { + caller->runSubgridCUDA2D(12,u,i); + //__syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + } + + + + + + + + + + + + + } + /*if( bound ) + { + caller->runSubgridCUDA2D(15,u,i); + __syncthreads(); + //caller->insertSubgridCUDA2D(u[l],i); + //__syncthreads(); + //caller->getSubgridCUDA2D(i,caller, &u[l]); + caller->updateSubgridCUDA2D(i,caller, &u[l]); + __syncthreads(); + }*/ + + if(l==0) + { + caller->setBoundaryConditionCUDA2D(i, 0); + caller->setSubgridValueCUDA2D(i, caller->getSubgridValueCUDA2D(i) - 1 ); + } + + + } + + + +} + +#endif /*HAVE_CUDA*/ + +#endif /* TNLPARALLELEIKONALSOLVER2D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver3D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..12d9003099643c923fdd6f4be18f2b07b35ebf3d --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi-parallel/tnlParallelEikonalSolver3D_impl.h @@ -0,0 +1,1706 @@ +/*************************************************************************** + tnlParallelEikonalSolver2D_impl.h - description + ------------------- + begin : Nov 28 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLPARALLELEIKONALSOLVER3D_IMPL_H_ +#define TNLPARALLELEIKONALSOLVER3D_IMPL_H_ + + +#include "tnlParallelEikonalSolver.h" +#include <core/mfilename.h> + +template< typename SchemeHost, typename SchemeDevice, typename Device> +tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::tnlParallelEikonalSolver() +{ + cout << "a" << endl; + this->device = tnlHostDevice; /////////////// tnlCuda Device --- vypocet na GPU, tnlHostDevice --- vypocet na CPU + +#ifdef HAVE_CUDA + if(this->device == tnlCudaDevice) + { + run_host = 1; + } +#endif + + cout << "b" << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::test() +{ +/* + for(int i =0; i < this->subgridValues.getSize(); i++ ) + { + insertSubgrid(getSubgrid(i), i); + } +*/ +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> + +bool tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::init( const Config::ParameterContainer& parameters ) +{ + cout << "Initializating solver..." << endl; + const String& meshLocation = parameters.getParameter <String>("mesh"); + this->mesh.load( meshLocation ); + + this->n = parameters.getParameter <int>("subgrid-size"); + cout << "Setting N to " << this->n << endl; + + this->subMesh.setDimensions( this->n, this->n, this->n ); + this->subMesh.setDomain( Containers::StaticVector<3,double>(0.0, 0.0, 0.0), + Containers::StaticVector<3,double>(mesh.template getSpaceStepsProducts< 1, 0, 0 >()*(double)(this->n), mesh.template getSpaceStepsProducts< 0, 1, 0 >()*(double)(this->n),mesh.template getSpaceStepsProducts< 0, 0, 1 >()*(double)(this->n)) ); + + this->subMesh.save("submesh.tnl"); + + const String& initialCondition = parameters.getParameter <String>("initial-condition"); + this->u0.load( initialCondition ); + + //cout << this->mesh.getCellCenter(0) << endl; + + this->delta = parameters.getParameter <double>("delta"); + this->delta *= mesh.template getSpaceStepsProducts< 1, 0, 0 >()*mesh.template getSpaceStepsProducts< 0, 1, 0 >(); + + cout << "Setting delta to " << this->delta << endl; + + this->tau0 = parameters.getParameter <double>("initial-tau"); + cout << "Setting initial tau to " << this->tau0 << endl; + this->stopTime = parameters.getParameter <double>("stop-time"); + + this->cflCondition = parameters.getParameter <double>("cfl-condition"); + this -> cflCondition *= sqrt(mesh.template getSpaceStepsProducts< 1, 0, 0 >()*mesh.template getSpaceStepsProducts< 0, 1, 0 >()); + cout << "Setting CFL to " << this->cflCondition << endl; + + stretchGrid(); + this->stopTime /= (double)(this->gridCols); + this->stopTime *= (1.0+1.0/((double)(this->n) - 2.0)); + cout << "Setting stopping time to " << this->stopTime << endl; + //this->stopTime = 1.5*((double)(this->n))*parameters.getParameter <double>("stop-time")*mesh.template getSpaceStepsProducts< 1, 0, 0 >(); + //cout << "Setting stopping time to " << this->stopTime << endl; + + cout << "Initializating scheme..." << endl; + if(!this->schemeHost.init(parameters)) + { + cerr << "SchemeHost failed to initialize." << endl; + return false; + } + cout << "Scheme initialized." << endl; + + test(); + + VectorType* tmp = new VectorType[subgridValues.getSize()]; + + +#ifdef HAVE_CUDA + + if(this->device == tnlCudaDevice) + { + /*cout << "Testing... " << endl; + if(this->device == tnlCudaDevice) + { + if( !initCUDA3D(parameters, gridRows, gridCols) ) + return false; + }*/ + //cout << "s" << endl; + cudaMalloc(&(this->cudaSolver), sizeof(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >)); + //cout << "s" << endl; + cudaMemcpy(this->cudaSolver, this,sizeof(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >), cudaMemcpyHostToDevice); + //cout << "s" << endl; + double** tmpdev = NULL; + cudaMalloc(&tmpdev, sizeof(double*)); + //double* tmpw; + cudaMalloc(&(this->tmpw), this->work_u.getSize()*sizeof(double)); + cudaMalloc(&(this->runcuda), sizeof(int)); + cudaDeviceSynchronize(); + checkCudaDevice; + int* tmpUC; + cudaMalloc(&(tmpUC), this->work_u.getSize()*sizeof(int)); + cudaMemcpy(tmpUC, this->unusedCell.getData(), this->unusedCell.getSize()*sizeof(int), cudaMemcpyHostToDevice); + + initCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<1,1>>>(this->cudaSolver, (this->tmpw), (this->runcuda),tmpUC); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << "s " << endl; + //cudaMalloc(&(cudaSolver->work_u_cuda), this->work_u.getSize()*sizeof(double)); + double* tmpu = NULL; + + cudaMemcpy(&tmpu, tmpdev,sizeof(double*), cudaMemcpyDeviceToHost); + //printf("%p %p \n",tmpu,tmpw); + cudaMemcpy((this->tmpw), this->work_u.getData(), this->work_u.getSize()*sizeof(double), cudaMemcpyHostToDevice); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << "s "<< endl; + + } +#endif + + if(this->device == tnlHostDevice) + { +#ifdef HAVE_OPENMP +#pragma omp parallel for num_threads(4) schedule(dynamic) +#endif + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + bool containsCurve = false; +// cout << "Working on subgrid " << i <<" --- check 1" << endl; + + if(! tmp[i].setSize(this->n*this->n*this->n)) + cout << "Could not allocate tmp["<< i <<"] array." << endl; +// cout << "Working on subgrid " << i <<" --- check 2" << endl; + + tmp[i] = getSubgrid(i); + containsCurve = false; +// cout << "Working on subgrid " << i <<" --- check 3" << endl; + + + for(int j = 0; j < tmp[i].getSize(); j++) + { + if(tmp[i][0]*tmp[i][j] <= 0.0) + { + containsCurve = true; + j=tmp[i].getSize(); +// cout << tmp[i][0] << " " << tmp[i][j] << endl; + } + + } +// cout << "Working on subgrid " << i <<" --- check 4" << endl; + + if(containsCurve) + { +// cout << "Computing initial SDF on subgrid " << i << "." << endl; + tmp[i] = runSubgrid(0, tmp[i] ,i); + insertSubgrid( tmp[i], i); + setSubgridValue(i, 4); +// cout << "Computed initial SDF on subgrid " << i << "." << endl; + } + containsCurve = false; + + } +// cout << "CPU: Curve found" << endl; + } +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { +// cout << "pre 1 kernel" << endl; + cudaDeviceSynchronize(); + checkCudaDevice; + dim3 threadsPerBlock(this->n, this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows,this->gridLevels); + cudaDeviceSynchronize(); + checkCudaDevice; + initRunCUDA3D<SchemeTypeHost,SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,2*this->n*this->n*this->n*sizeof(double)>>>(this->cudaSolver); + cudaDeviceSynchronize(); +// cout << "post 1 kernel" << endl; + + } +#endif + + + this->currentStep = 1; + if(this->device == tnlHostDevice) + synchronize(); +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { + dim3 threadsPerBlock(this->n, this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows,this->gridLevels); + //double * test = (double*)malloc(this->work_u.getSize()*sizeof(double)); + //cout << test[0] <<" " << test[1] <<" " << test[2] <<" " << test[3] << endl; + //cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //cout << this->tmpw << " " << test[0] <<" " << test[1] << " " <<test[2] << " " <<test[3] << endl; + + checkCudaDevice; + + synchronizeCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cout << cudaGetErrorString(cudaDeviceSynchronize()) << endl; + checkCudaDevice; + synchronize2CUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << test[0] << " " <<test[1] <<" " << test[2] << " " <<test[3] << endl; + //cudaMemcpy(/*this->work_u.getData()*/ test, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //checkCudaDevice; + //cout << this->tmpw << " " << test[0] << " " <<test[1] << " " <<test[2] <<" " << test[3] << endl; + //free(test); + + } + +#endif + cout << "Solver initialized." << endl; + + return true; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::run() +{ + if(this->device == tnlHostDevice) + { + + bool end = false; + while (/*(this->boundaryConditions.max() > 0 ) ||*/ !end) + { + if(this->boundaryConditions.max() == 0 || this->subgridValues.max() < 0) + end=true; + else + end=false; +#ifdef HAVE_OPENMP +#pragma omp parallel for num_threads(4) schedule(dynamic) +#endif + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + VectorType tmp; + tmp.setSize(this->n*this->n*this->n); + if(getSubgridValue(i) != INT_MAX) + { + //cout << "subMesh: " << i << ", BC: " << getBoundaryCondition(i) << endl; + + if(getSubgridValue(i) == currentStep+4) + { + + if(getBoundaryCondition(i) & 1) + { + tmp = getSubgrid(i); + tmp = runSubgrid(1, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 2) + { + tmp = getSubgrid(i); + tmp = runSubgrid(2, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 4) + { + tmp = getSubgrid(i); + tmp = runSubgrid(4, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 8) + { + tmp = getSubgrid(i); + tmp = runSubgrid(8, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 16) + { + tmp = getSubgrid(i); + tmp = runSubgrid(16, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + if(getBoundaryCondition(i) & 32) + { + tmp = getSubgrid(i); + tmp = runSubgrid(32, tmp ,i); + insertSubgrid( tmp, i); + this->calculationsCount[i]++; + } + } + + if( getBoundaryCondition(i) & 19) + { + tmp = getSubgrid(i); + tmp = runSubgrid(19, tmp ,i); + insertSubgrid( tmp, i); + } + if( getBoundaryCondition(i) & 21) + { + tmp = getSubgrid(i); + tmp = runSubgrid(21, tmp ,i); + insertSubgrid( tmp, i); + } + if( getBoundaryCondition(i) & 26) + { + tmp = getSubgrid(i); + tmp = runSubgrid(26, tmp ,i); + insertSubgrid( tmp, i); + } + if( getBoundaryCondition(i) & 28) + { + tmp = getSubgrid(i); + tmp = runSubgrid(28, tmp ,i); + insertSubgrid( tmp, i); + } + + if( getBoundaryCondition(i) & 35) + { + tmp = getSubgrid(i); + tmp = runSubgrid(35, tmp ,i); + insertSubgrid( tmp, i); + } + if( getBoundaryCondition(i) & 37) + { + tmp = getSubgrid(i); + tmp = runSubgrid(37, tmp ,i); + insertSubgrid( tmp, i); + } + if( getBoundaryCondition(i) & 42) + { + tmp = getSubgrid(i); + tmp = runSubgrid(42, tmp ,i); + insertSubgrid( tmp, i); + } + if( getBoundaryCondition(i) & 44) + { + tmp = getSubgrid(i); + tmp = runSubgrid(44, tmp ,i); + insertSubgrid( tmp, i); + } + + + setBoundaryCondition(i, 0); + setSubgridValue(i, getSubgridValue(i)-1); + + } + } + synchronize(); + } + } +#ifdef HAVE_CUDA + else if(this->device == tnlCudaDevice) + { + //cout << "fn" << endl; + bool end_cuda = false; + dim3 threadsPerBlock(this->n, this->n, this->n); + dim3 numBlocks(this->gridCols,this->gridRows,this->gridLevels); + cudaDeviceSynchronize(); + checkCudaDevice; + //cudaMalloc(&runcuda,sizeof(bool)); + //cudaMemcpy(runcuda, &run_host, sizeof(bool), cudaMemcpyHostToDevice); + //cout << "fn" << endl; + bool* tmpb; + //cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost); + //cudaDeviceSynchronize(); + //checkCudaDevice; + cudaMemcpy(&(this->run_host),this->runcuda,sizeof(int), cudaMemcpyDeviceToHost); + cudaDeviceSynchronize(); + checkCudaDevice; + //cout << "fn" << endl; + int i = 1; + time_diff = 0.0; + while (run_host || !end_cuda) + { + cout << "Computing at step "<< i++ << endl; + if(run_host != 0 ) + end_cuda = true; + else + end_cuda = false; + //cout << "a" << endl; + cudaDeviceSynchronize(); + checkCudaDevice; + start = std::clock(); + runCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock,2*this->n*this->n*this->n*sizeof(double)>>>(this->cudaSolver); + //cout << "a" << endl; + cudaDeviceSynchronize(); + time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC); + + //start = std::clock(); + synchronizeCUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,threadsPerBlock>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + synchronize2CUDA3D<SchemeTypeHost, SchemeTypeDevice, DeviceType><<<numBlocks,1>>>(this->cudaSolver); + cudaDeviceSynchronize(); + checkCudaDevice; + //time_diff += (std::clock() - start) / (double)(CLOCKS_PER_SEC); + + + //cout << "a" << endl; + //run_host = false; + //cout << "in kernel loop" << run_host << endl; + //cudaMemcpy(tmpb, &(cudaSolver->runcuda),sizeof(bool*), cudaMemcpyDeviceToHost); + cudaMemcpy(&run_host, (this->runcuda),sizeof(int), cudaMemcpyDeviceToHost); + //cout << "in kernel loop" << run_host << endl; + } + cout << "Solving time was: " << time_diff << endl; + //cout << "b" << endl; + + //double* tmpu; + //cudaMemcpy(tmpu, &(cudaSolver->work_u_cuda),sizeof(double*), cudaMemcpyHostToDevice); + //cudaMemcpy(this->work_u.getData(), tmpu, this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //cout << this->work_u.getData()[0] << endl; + + //double * test = (double*)malloc(this->work_u.getSize()*sizeof(double)); + //cout << test[0] << test[1] << test[2] << test[3] << endl; + cudaMemcpy(this->work_u.getData()/* test*/, (this->tmpw), this->work_u.getSize()*sizeof(double), cudaMemcpyDeviceToHost); + //cout << this->tmpw << " " << test[0] << test[1] << test[2] << test[3] << endl; + //free(test); + + cudaDeviceSynchronize(); + } +#endif + contractGrid(); + this->u0.save("u-00001.tnl"); + cout << "Maximum number of calculations on one subgrid was " << this->calculationsCount.absMax() << endl; + cout << "Average number of calculations on one subgrid was " << ( (double) this->calculationsCount.sum() / (double) this->calculationsCount.getSize() ) << endl; + cout << "Solver finished" << endl; + +#ifdef HAVE_CUDA + if(this->device == tnlCudaDevice) + { + cudaFree(this->runcuda); + cudaFree(this->tmpw); + cudaFree(this->cudaSolver); + } +#endif + +} + +//north - 1, east - 2, west - 4, south - 8 +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::synchronize() //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now +{ + cout << "Synchronizig..." << endl; + int tmp1, tmp2; + int grid1, grid2; + +// if(this->currentStep & 1) +// { + for(int j = 0; j < this->gridRows - 1; j++) + { + for (int i = 0; i < this->gridCols*this->n; i++) + { + for (int k = 0; k < this->gridLevels*this->n; k++) + { +// cout << "a" << endl; + tmp1 = this->gridCols*this->n*((this->n-1)+j*this->n) + i + k*this->gridCols*this->n*this->gridRows*this->n; +// cout << "b" << endl; + tmp2 = this->gridCols*this->n*((this->n)+j*this->n) + i + k*this->gridCols*this->n*this->gridRows*this->n; +// cout << "c" << endl; + if(tmp1 > work_u.getSize()) + cout << "tmp1: " << tmp1 << " x: " << j <<" y: " << i <<" z: " << k << endl; + if(tmp2 > work_u.getSize()) + cout << "tmp2: " << tmp2 << " x: " << j <<" y: " << i <<" z: " << k << endl; + grid1 = getSubgridValue(getOwner(tmp1)); +// cout << "d" << endl; + grid2 = getSubgridValue(getOwner(tmp2)); +// cout << "e" << endl; + if(getOwner(tmp1)==getOwner(tmp2)) + cout << "i, j, k" << i << "," << j << "," << k << endl; + if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; +// cout << "f" << endl; + this->unusedCell[tmp2] = 0; +// cout << "g" << endl; + if(grid2 == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } +// cout << "h" << endl; + if(! (getBoundaryCondition(getOwner(tmp2)) & 8) ) + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+8); +// cout << "i" << endl; + } + else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; +// cout << "j" << endl; + this->unusedCell[tmp1] = 0; +// cout << "k" << endl; + if(grid1 == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } +// cout << "l" << endl; + if(! (getBoundaryCondition(getOwner(tmp1)) & 1) ) + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+1); +// cout << "m" << endl; + } + } + } + } + +// } +// else +// { + + cout << "sync 2" << endl; + for(int i = 1; i < this->gridCols; i++) + { + for (int j = 0; j < this->gridRows*this->n; j++) + { + for (int k = 0; k < this->gridLevels*this->n; k++) + { + tmp1 = this->gridCols*this->n*j + i*this->n - 1 + k*this->gridCols*this->n*this->gridRows*this->n; + tmp2 = this->gridCols*this->n*j + i*this->n + k*this->gridCols*this->n*this->gridRows*this->n; + grid1 = getSubgridValue(getOwner(tmp1)); + grid2 = getSubgridValue(getOwner(tmp2)); + if(getOwner(tmp1)==getOwner(tmp2)) + cout << "i, j, k" << i << "," << j << "," << k << endl; + if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + this->unusedCell[tmp2] = 0; + if(grid2 == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp2)) & 4) ) + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+4); + } + else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + this->unusedCell[tmp1] = 0; + if(grid1 == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp1)) & 2) ) + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+2); + } + } + } + } + + cout << "sync 3" << endl; + + for(int k = 1; k < this->gridLevels; k++) + { + for (int j = 0; j < this->gridRows*this->n; j++) + { + for (int i = 0; i < this->gridCols*this->n; i++) + { + tmp1 = this->gridCols*this->n*j + i + (k*this->n-1)*this->gridCols*this->n*this->gridRows*this->n; + tmp2 = this->gridCols*this->n*j + i + k*this->n*this->gridCols*this->n*this->gridRows*this->n; + grid1 = getSubgridValue(getOwner(tmp1)); + grid2 = getSubgridValue(getOwner(tmp2)); + if(getOwner(tmp1)==getOwner(tmp2)) + cout << "i, j, k" << i << "," << j << "," << k << endl; + if ((fabs(this->work_u[tmp1]) < fabs(this->work_u[tmp2]) - this->delta || grid2 == INT_MAX || grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + this->unusedCell[tmp2] = 0; + if(grid2 == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp2)) & 32) ) + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+32); + } + else if ((fabs(this->work_u[tmp1]) > fabs(this->work_u[tmp2]) + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + this->unusedCell[tmp1] = 0; + if(grid1 == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + if(! (getBoundaryCondition(getOwner(tmp1)) & 16) ) + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+16); + } + } + } + } +// } + + + + this->currentStep++; + int stepValue = this->currentStep + 4; + for (int i = 0; i < this->subgridValues.getSize(); i++) + { + if( getSubgridValue(i) == -INT_MAX ) + setSubgridValue(i, stepValue); + } + + cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl; + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getOwner(int i) const +{ + + int j = i % (this->gridCols*this->gridRows*this->n*this->n); + + return ( (i / (this->gridCols*this->gridRows*this->n*this->n*this->n))*this->gridCols*this->gridRows + + (j / (this->gridCols*this->n*this->n))*this->gridCols + + (j % (this->gridCols*this->n))/this->n); +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValue( int i ) const +{ + return this->subgridValues[i]; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValue(int i, int value) +{ + this->subgridValues[i] = value; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryCondition( int i ) const +{ + return this->boundaryConditions[i]; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryCondition(int i, int value) +{ + this->boundaryConditions[i] = value; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::stretchGrid() +{ + cout << "Stretching grid..." << endl; + + + this->gridCols = ceil( ((double)(this->mesh.getDimensions().x()-1)) / ((double)(this->n-1)) ); + this->gridRows = ceil( ((double)(this->mesh.getDimensions().y()-1)) / ((double)(this->n-1)) ); + this->gridLevels = ceil( ((double)(this->mesh.getDimensions().z()-1)) / ((double)(this->n-1)) ); + + //this->gridCols = (this->mesh.getDimensions().x()-1) / (this->n-1) ; + //this->gridRows = (this->mesh.getDimensions().y()-1) / (this->n-1) ; + + cout << "Setting gridCols to " << this->gridCols << "." << endl; + cout << "Setting gridRows to " << this->gridRows << "." << endl; + cout << "Setting gridLevels to " << this->gridLevels << "." << endl; + + this->subgridValues.setSize(this->gridCols*this->gridRows*this->gridLevels); + this->subgridValues.setValue(0); + this->boundaryConditions.setSize(this->gridCols*this->gridRows*this->gridLevels); + this->boundaryConditions.setValue(0); + this->calculationsCount.setSize(this->gridCols*this->gridRows*this->gridLevels); + this->calculationsCount.setValue(0); + + for(int i = 0; i < this->subgridValues.getSize(); i++ ) + { + this->subgridValues[i] = INT_MAX; + this->boundaryConditions[i] = 0; + } + + int levelSize = this->n*this->n*this->gridCols*this->gridRows; + int stretchedSize = this->n*levelSize*this->gridLevels; + + if(!this->work_u.setSize(stretchedSize)) + cerr << "Could not allocate memory for stretched grid." << endl; + if(!this->unusedCell.setSize(stretchedSize)) + cerr << "Could not allocate memory for supporting stretched grid." << endl; + int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1); + cout << idealStretch << endl; + + + + + for(int i = 0; i < levelSize; i++) + { + int diff =(this->n*this->gridCols) - idealStretch ; + + int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff; + + if(i%(this->n*this->gridCols) - idealStretch >= 0) + { + k+= i%(this->n*this->gridCols) - idealStretch +1 ; + } + + if(i/(this->n*this->gridCols) - idealStretch + 1 > 0) + { + k+= (i/(this->n*this->gridCols) - idealStretch +1 )* this->mesh.getDimensions().x() ; + } + + for( int j = 0; j<this->n*this->gridLevels; j++) + { + this->unusedCell[i+j*levelSize] = 1; + int l = j/this->n; + + if(j - idealStretch >= 0) + { + l+= j - idealStretch + 1; + } + + this->work_u[i+j*levelSize] = this->u0[i+(j-l)*mesh.getDimensions().x()*mesh.getDimensions().y()-k]; + } + + } + + + + cout << "Grid stretched." << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::contractGrid() +{ + cout << "Contracting grid..." << endl; + int levelSize = this->n*this->n*this->gridCols*this->gridRows; + int stretchedSize = this->n*levelSize*this->gridLevels; + + int idealStretch =this->mesh.getDimensions().x() + (this->mesh.getDimensions().x()-2)/(this->n-1); + cout << idealStretch << endl; + + + for(int i = 0; i < levelSize; i++) + { + int diff =(this->n*this->gridCols) - idealStretch ; + int k = i/this->n - i/(this->n*this->gridCols) + this->mesh.getDimensions().x()*(i/(this->n*this->n*this->gridCols)) + (i/(this->n*this->gridCols))*diff; + + if((i%(this->n*this->gridCols) - idealStretch < 0) && (i/(this->n*this->gridCols) - idealStretch + 1 <= 0) ) + { + for( int j = 0; j<this->n*this->gridLevels; j++) + { + int l = j/this->n; + if(j - idealStretch < 0) + this->u0[i+(j-l)*mesh.getDimensions().x()*mesh.getDimensions().y()-k] = this->work_u[i+j*levelSize]; + } + } + + } + + cout << "Grid contracted" << endl; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +typename tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::VectorType +tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgrid( const int i ) const +{ + + VectorType u; + u.setSize(this->n*this->n*this->n); + + int idx, idy, idz; + idz = i / (gridRows*this->gridCols); + idy = (i % (this->gridRows*this->gridCols)) / this->gridCols; + idx = i % (this->gridCols); + + for( int j = 0; j < this->n; j++) + { + // int index = (i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n); + for( int k = 0; k < this->n; k++) + { + for( int l = 0; l < this->n; l++) + { + int index = (idz*this->n + l) * this->n*this->n*this->gridCols*this->gridRows + + (idy) * this->n*this->n*this->gridCols + + (idx) * this->n + + k * this->n*this->gridCols + + j; + + u[j + k*this->n + l*this->n*this->n] = this->work_u[ index ]; + } + } + } + return u; +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::insertSubgrid( VectorType u, const int i ) +{ + int idx, idy, idz; + idz = i / (this->gridRows*this->gridCols); + idy = (i % (this->gridRows*this->gridCols)) / this->gridCols; + idx = i % (this->gridCols); + + for( int j = 0; j < this->n; j++) + { + // int index = (i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n); + for( int k = 0; k < this->n; k++) + { + for( int l = 0; l < this->n; l++) + { + + int index = (idz*this->n + l) * this->n*this->n*this->gridCols*this->gridRows + + (idy) * this->n*this->n*this->gridCols + + (idx) * this->n + + k * this->n*this->gridCols + + j; + + //OMP LOCK index +// cout<< idx << " " << idy << " " << idz << " " << j << " " << k << " " << l << " " << idz << " " << unusedCell.getSize() << " " << u.getSize() << " " << index <<endl; + if( (fabs(this->work_u[index]) > fabs(u[j + k*this->n + l*this->n*this->n])) || (this->unusedCell[index] == 1) ) + { + this->work_u[index] = u[j + k*this->n + l*this->n*this->n]; + this->unusedCell[index] = 0; + } + //OMP UNLOCK index + } + } + } +} + +template< typename SchemeHost, typename SchemeDevice, typename Device> +typename tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::VectorType +tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::runSubgrid( int boundaryCondition, VectorType u, int subGridID) +{ + + VectorType fu; + + fu.setLike(u); + fu.setValue( 0.0 ); + + + bool tmp = false; + for(int i = 0; i < u.getSize(); i++) + { + if(u[0]*u[i] <= 0.0) + tmp=true; + } + int idx,idy,idz; + idz = subGridID / (this->gridRows*this->gridCols); + idy = (subGridID % (this->gridRows*this->gridCols)) / this->gridCols; + idx = subGridID % (this->gridCols); + int centerGID = (this->n*idy + (this->n>>1) )*(this->n*this->gridCols) + this->n*idx + (this->n>>1) + + ((this->n>>1)+this->n*idz)*this->n*this->n*this->gridRows*this->gridCols; + if(this->unusedCell[centerGID] == 0 || boundaryCondition == 0) + tmp = true; + //if(this->currentStep + 3 < getSubgridValue(subGridID)) + //tmp = true; + + + double value = sign(u[0]) * u.absMax(); + + if(tmp) + {} + + + //north - 1, east - 2, west - 4, south - 8 + else if(boundaryCondition == 4) + { + for(int i = 0; i < this->n; i++) + for(int j = 1;j < this->n; j++) + for(int k = 0;k < this->n; k++) + //if(fabs(u[i*this->n + j]) < fabs(u[i*this->n])) + u[k*this->n*this->n + i*this->n + j] = value;// u[i*this->n]; + } + else if(boundaryCondition == 2) + { + for(int i = 0; i < this->n; i++) + for(int j =0 ;j < this->n -1; j++) + for(int k = 0;k < this->n; k++) + //if(fabs(u[i*this->n + j]) < fabs(u[(i+1)*this->n - 1])) + u[k*this->n*this->n + i*this->n + j] = value;// u[(i+1)*this->n - 1]; + } + else if(boundaryCondition == 1) + { + for(int j = 0; j < this->n; j++) + for(int i = 0;i < this->n - 1; i++) + for(int k = 0;k < this->n; k++) + //if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)])) + u[k*this->n*this->n + i*this->n + j] = value;// u[j + this->n*(this->n - 1)]; + } + else if(boundaryCondition == 8) + { + for(int j = 0; j < this->n; j++) + for(int i = 1;i < this->n; i++) + for(int k = 0;k < this->n; k++) + //if(fabs(u[i*this->n + j]) < fabs(u[j])) + u[k*this->n*this->n + i*this->n + j] = value;// u[j]; + } + else if(boundaryCondition == 16) + { + for(int j = 0; j < this->n; j++) + for(int i = 0;i < this->n ; i++) + for(int k = 0;k < this->n-1; k++) + //if(fabs(u[i*this->n + j]) < fabs(u[j + this->n*(this->n - 1)])) + u[k*this->n*this->n + i*this->n + j] = value;// u[j + this->n*(this->n - 1)]; + } + else if(boundaryCondition == 32) + { + for(int j = 0; j < this->n; j++) + for(int i = 0;i < this->n; i++) + for(int k = 1;k < this->n; k++) + //if(fabs(u[i*this->n + j]) < fabs(u[j])) + u[k*this->n*this->n + i*this->n + j] = value;// u[j]; + } + + + double time = 0.0; + double currentTau = this->tau0; + double finalTime = this->stopTime;// + 3.0*(u.max() - u.min()); + if(boundaryCondition == 0) finalTime *= 2.0; + if( time + currentTau > finalTime ) currentTau = finalTime - time; + + double maxResidue( 1.0 ); + //double lastResidue( 10000.0 ); + tnlGridEntity<MeshType, 3, tnlGridEntityNoStencilStorage > Entity(subMesh); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity); + while( time < finalTime /*|| maxResidue > subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*/) + { + /**** + * Compute the RHS + */ + + for( int i = 0; i < fu.getSize(); i ++ ) + { +// cout << "i: " << i << ", time: " << time <<endl; + Containers::StaticVector<3,int> coords(i % subMesh.getDimensions().x(), + (i % (subMesh.getDimensions().x()*subMesh.getDimensions().y())) / subMesh.getDimensions().x(), + i / (subMesh.getDimensions().x()*subMesh.getDimensions().y())); +// cout << "b " << i << " " << i % subMesh.getDimensions().x() << " " << (i % (subMesh.getDimensions().x()*subMesh.getDimensions().y())) << " " << (i % subMesh.getDimensions().x()*subMesh.getDimensions().y()) / subMesh.getDimensions().x() << " " << subMesh.getDimensions().x()*subMesh.getDimensions().y() << " " <<endl; + Entity.setCoordinates(coords); +// cout <<"c" << coords << endl; + Entity.refresh(); +// cout << "d" <<endl; + neighbourEntities.refresh(subMesh,Entity.getIndex()); +// cout << "e" <<endl; + fu[ i ] = schemeHost.getValue( this->subMesh, i, coords,u, time, boundaryCondition, neighbourEntities ); +// cout << "f" <<endl; + } + maxResidue = fu. absMax(); + + + if( this -> cflCondition * maxResidue != 0.0) + currentTau = this -> cflCondition / maxResidue; + + /* if (maxResidue < 0.05) + cout << "Max < 0.05" << endl;*/ + if(currentTau > 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()) + currentTau = 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >(); + /*if(maxResidue > lastResidue) + currentTau *=(1.0/10.0);*/ + + + if( time + currentTau > finalTime ) currentTau = finalTime - time; +// for( int i = 0; i < fu.getSize(); i ++ ) +// { +// //cout << "Too big RHS! i = " << i << ", fu = " << fu[i] << ", u = " << u[i] << endl; +// if((u[i]+currentTau * fu[ i ])*u[i] < 0.0 && fu[i] != 0.0 && u[i] != 0.0 ) +// currentTau = fabs(u[i]/(2.0*fu[i])); +// +// } + + + for( int i = 0; i < fu.getSize(); i ++ ) + { + double add = u[i] + currentTau * fu[ i ]; + //if( fabs(u[i]) < fabs(add) or (this->subgridValues[subGridID] == this->currentStep +4) ) + u[ i ] = add; + } + time += currentTau; + + //cout << '\r' << flush; + //cout << maxResidue << " " << currentTau << " @ " << time << flush; + //lastResidue = maxResidue; + } + //cout << "Time: " << time << ", Res: " << maxResidue <<endl; + /*if (u.max() > 0.0) + this->stopTime /=(double) this->gridCols;*/ + +// VectorType solution; +// solution.setLike(u); +// for( int i = 0; i < u.getSize(); i ++ ) +// { +// solution[i]=u[i]; +// } +// return solution; + return u; +} + + +#ifdef HAVE_CUDA + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgridCUDA3D( const int i ,tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a) +{ + //int j = threadIdx.x + threadIdx.y * blockDim.x; +// int index = (blockIdx.z*this->n + threadIdx.z) * this->n*this->n*this->gridCols*this->gridRows +// + (blockIdx.y) * this->n*this->n*this->gridCols +// + (blockIdx.x) * this->n +// + threadIdx.y * this->n*this->gridCols +// + threadIdx.x; + + + int index = blockDim.x*blockIdx.x + threadIdx.x + + (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + + (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y; + + //printf("i= %d,j= %d,th= %d\n",i,j,th); + *a = caller->work_u_cuda[index]; + //printf("Hi %f \n", *a); + //return ret; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::updateSubgridCUDA3D( const int i ,tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller, double* a) +{ +// int j = threadIdx.x + threadIdx.y * blockDim.x; +// int index = (blockIdx.z*this->n + threadIdx.z) * this->n*this->n*this->gridCols*this->gridRows +// + (blockIdx.y) * this->n*this->n*this->gridCols +// + (blockIdx.x) * this->n +// + threadIdx.y * this->n*this->gridCols +// + threadIdx.x; + + int index = blockDim.x*blockIdx.x + threadIdx.x + + (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + + (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y; + + if( (fabs(caller->work_u_cuda[index]) > fabs(*a)) || (caller->unusedCell_cuda[index] == 1) ) + { + caller->work_u_cuda[index] = *a; + caller->unusedCell_cuda[index] = 0; + + } + + *a = caller->work_u_cuda[index]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::insertSubgridCUDA3D( double u, const int i ) +{ + + +// int j = threadIdx.x + threadIdx.y * blockDim.x; + //printf("j = %d, u = %f\n", j,u); + +// int index = (blockIdx.z*this->n + threadIdx.z) * this->n*this->n*this->gridCols*this->gridRows +// + (blockIdx.y) * this->n*this->n*this->gridCols +// + (blockIdx.x) * this->n +// + threadIdx.y * this->n*this->gridCols +// + threadIdx.x; + + int index = blockDim.x*blockIdx.x + threadIdx.x + + (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + + (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y; + + //printf("i= %d,j= %d,index= %d\n",i,j,index); + if( (fabs(this->work_u_cuda[index]) > fabs(u)) || (this->unusedCell_cuda[index] == 1) ) + { + this->work_u_cuda[index] = u; + this->unusedCell_cuda[index] = 0; + + } + + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::runSubgridCUDA3D( int boundaryCondition, double* u, int subGridID) +{ + + __shared__ int tmp; + __shared__ double value; + //double tmpRes = 0.0; + volatile double* sharedTau = &u[blockDim.x*blockDim.y*blockDim.z]; +// volatile double* absVal = &u[2*blockDim.x*blockDim.y*blockDim.z]; + int i = threadIdx.x; + int j = threadIdx.y; + int k = threadIdx.z; + int l = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z*blockDim.x*blockDim.y; + bool computeFU = !((i == 0 && (boundaryCondition & 4)) or + (i == blockDim.x - 1 && (boundaryCondition & 2)) or + (j == 0 && (boundaryCondition & 8)) or + (j == blockDim.y - 1 && (boundaryCondition & 1))or + (k == 0 && (boundaryCondition & 32)) or + (k == blockDim.z - 1 && (boundaryCondition & 16))); + + if(l == 0) + { + tmp = 0; + int centerGID = (blockDim.y*blockIdx.y + (blockDim.y>>1) )*(blockDim.x*gridDim.x) + blockDim.x*blockIdx.x + (blockDim.x>>1) + + ((blockDim.z>>1)+blockDim.z*blockIdx.z)*blockDim.x*blockDim.y*gridDim.x*gridDim.y; + if(this->unusedCell_cuda[centerGID] == 0 || boundaryCondition == 0) + tmp = 1; + } + __syncthreads(); + + + __syncthreads(); + if(tmp !=1) + { +// if(computeFU) +// absVal[l]=0.0; +// else +// absVal[l] = fabs(u[l]); +// +// __syncthreads(); +// +// if((blockDim.x == 16) && (l < 128)) absVal[l] = Max(absVal[l],absVal[l+128]); +// __syncthreads(); +// if((blockDim.x == 16) && (l < 64)) absVal[l] = Max(absVal[l],absVal[l+64]); +// __syncthreads(); +// if(l < 32) absVal[l] = Max(absVal[l],absVal[l+32]); +// if(l < 16) absVal[l] = Max(absVal[l],absVal[l+16]); +// if(l < 8) absVal[l] = Max(absVal[l],absVal[l+8]); +// if(l < 4) absVal[l] = Max(absVal[l],absVal[l+4]); +// if(l < 2) absVal[l] = Max(absVal[l],absVal[l+2]); +// if(l < 1) value = sign(u[0])*Max(absVal[l],absVal[l+1]); +// __syncthreads(); +// +// if(computeFU) +// u[l] = value; + if(computeFU) + { + tnlGridEntity<MeshType, 3, tnlGridEntityNoStencilStorage > Ent(subMesh); + if(boundaryCondition == 4) + { + Ent.setCoordinates(Containers::StaticVector<3,int>(0,j,k)); + Ent.refresh(); + u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(threadIdx.x) ;//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(threadIdx.x+this->n); + } + else if(boundaryCondition == 2) + { + Ent.setCoordinates(Containers::StaticVector<3,int>(blockDim.x - 1,j,k)); + Ent.refresh(); + u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(this->n - 1 - threadIdx.x);//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(blockDim.x - threadIdx.x - 1+this->n); + } + else if(boundaryCondition == 8) + { + Ent.setCoordinates(Containers::StaticVector<3,int>(i,0,k)); + Ent.refresh(); + u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 1, 0 >()*(threadIdx.y) ;//+ 2*sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(threadIdx.y+this->n); + } + else if(boundaryCondition == 1) + { + Ent.setCoordinates(Containers::StaticVector<3,int>(i,blockDim.y - 1,k)); + Ent.refresh(); + u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 1, 0 >()*(this->n - 1 - threadIdx.y) ;//+ sign(u[0])*this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()*(blockDim.y - threadIdx.y - 1 +this->n); + } + else if(boundaryCondition == 32) + { + Ent.setCoordinates(Containers::StaticVector<3,int>(i,j,0)); + Ent.refresh(); + u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 0, 1 >()*(threadIdx.z); + } + else if(boundaryCondition == 16) + { + Ent.setCoordinates(Containers::StaticVector<3,int>(i,j,blockDim.z - 1)); + Ent.refresh(); + u[l] = u[Ent.getIndex()];// + sign(u[0])*this->subMesh.template getSpaceStepsProducts< 0, 0, 1 >()*(this->n - 1 - threadIdx.z) ; + } + } + } + + double time = 0.0; + __shared__ double currentTau; + double cfl = this->cflCondition; + double fu = 0.0; +// if(threadIdx.x * threadIdx.y * threadIdx.z == 0) +// { +// currentTau = this->tau0; +// } + double finalTime = this->stopTime; + __syncthreads(); + if( boundaryCondition == 0 ) finalTime *= 2.0; + + tnlGridEntity<MeshType, 3, tnlGridEntityNoStencilStorage > Entity(subMesh); + tnlNeighbourGridEntityGetter<tnlGridEntity< MeshType, 3, tnlGridEntityNoStencilStorage >,3> neighbourEntities(Entity); + Entity.setCoordinates(Containers::StaticVector<3,int>(i,j,k)); + Entity.refresh(); + neighbourEntities.refresh(subMesh,Entity.getIndex()); + + + while( time < finalTime ) + { + sharedTau[l]=finalTime; + + if(computeFU) + { + fu = schemeHost.getValueDev( this->subMesh, l, Containers::StaticVector<3,int>(i,j,k), u, time, boundaryCondition, neighbourEntities); + if(abs(fu) > 0.0) + sharedTau[l]=abs(cfl/fu); + } + + if(l == 0) + { + if(sharedTau[0] > 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >()) sharedTau[0] = 0.5 * this->subMesh.template getSpaceStepsProducts< 1, 0, 0 >(); + } + else if(l == blockDim.x*blockDim.y*blockDim.z - 1) + { + if( time + sharedTau[l] > finalTime ) sharedTau[l] = finalTime - time; + } + + __syncthreads(); + if(l < 256) sharedTau[l] = Min(sharedTau[l],sharedTau[l+256]); + __syncthreads(); + if(l < 128) sharedTau[l] = Min(sharedTau[l],sharedTau[l+128]); + __syncthreads(); + if(l < 64) sharedTau[l] = Min(sharedTau[l],sharedTau[l+64]); + __syncthreads(); + if(l < 32) sharedTau[l] = Min(sharedTau[l],sharedTau[l+32]); + __syncthreads(); + if(l < 16) sharedTau[l] = Min(sharedTau[l],sharedTau[l+16]); + if(l < 8) sharedTau[l] = Min(sharedTau[l],sharedTau[l+8]); + if(l < 4) sharedTau[l] = Min(sharedTau[l],sharedTau[l+4]); + if(l < 2) sharedTau[l] = Min(sharedTau[l],sharedTau[l+2]); + if(l < 1) currentTau = Min(sharedTau[l],sharedTau[l+1]); + __syncthreads(); + +// if(abs(fu) < 10000.0) +// printf("bla"); + if(computeFU) + u[l] += currentTau * fu; + time += currentTau; + __syncthreads(); + } + + +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getOwnerCUDA3D(int i) const +{ + int j = i % (this->gridCols*this->gridRows*this->n*this->n); + + return ( (i / (this->gridCols*this->gridRows*this->n*this->n))*this->gridCols*this->gridRows + + (j / (this->gridCols*this->n*this->n))*this->gridCols + + (j % (this->gridCols*this->n))/this->n); +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getSubgridValueCUDA3D( int i ) const +{ + return this->subgridValues_cuda[i]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setSubgridValueCUDA3D(int i, int value) +{ + this->subgridValues_cuda[i] = value; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +int tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::getBoundaryConditionCUDA3D( int i ) const +{ + return this->boundaryConditions_cuda[i]; +} + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__device__ +void tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::setBoundaryConditionCUDA3D(int i, int value) +{ + this->boundaryConditions_cuda[i] = value; +} + + + +//north - 1, east - 2, west - 4, south - 8, up -16, down - 32 + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void /*tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int>::*/synchronizeCUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) //needs fix ---- maybe not anymore --- but frankly: yeah, it does -- aaaa-and maybe fixed now +{ + + __shared__ int boundary[6]; // north,east,west,south + __shared__ int subgridValue; + __shared__ int newSubgridValue; + + + int gid = blockDim.x*blockIdx.x + threadIdx.x + + (blockDim.y*blockIdx.y + threadIdx.y)*blockDim.x*gridDim.x + + (blockDim.z*blockIdx.z + threadIdx.z)*blockDim.x*gridDim.x*blockDim.y*gridDim.y; + double u = cudaSolver->work_u_cuda[gid]; + double u_cmp; + int subgridValue_cmp=INT_MAX; + int boundary_index=0; + + + if(threadIdx.x+threadIdx.y+threadIdx.z == 0) + { + subgridValue = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y); + boundary[0] = 0; + boundary[1] = 0; + boundary[2] = 0; + boundary[3] = 0; + boundary[4] = 0; + boundary[5] = 0; + newSubgridValue = 0; +// printf("aaa z = %d, y = %d, x = %d\n",blockIdx.z,blockIdx.y,blockIdx.x); + } + __syncthreads(); + + + + if( (threadIdx.x == 0 /* && !(cudaSolver->currentStep & 1)*/) || + (threadIdx.y == 0 /* && (cudaSolver->currentStep & 1)*/) || + (threadIdx.z == 0 /* && !(cudaSolver->currentStep & 1)*/) || + (threadIdx.x == blockDim.x - 1 /* && !(cudaSolver->currentStep & 1)*/) || + (threadIdx.y == blockDim.y - 1 /* && (cudaSolver->currentStep & 1)*/) || + (threadIdx.z == blockDim.z - 1 /* && (cudaSolver->currentStep & 1)*/) ) + { + if(threadIdx.x == 0 && (blockIdx.x != 0)/* && !(cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid - 1]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y - 1); + boundary_index = 2; + } + + if(threadIdx.x == blockDim.x - 1 && (blockIdx.x != gridDim.x - 1)/* && !(cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid + 1]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y + 1); + boundary_index = 1; + } + + __threadfence(); + if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX)) + { + cudaSolver->unusedCell_cuda[gid] = 0; + atomicMax(&newSubgridValue, INT_MAX); + atomicMax(&boundary[boundary_index], 1); + cudaSolver->work_u_cuda[gid] = u_cmp; + u=u_cmp; + } + __threadfence(); + if(threadIdx.y == 0 && (blockIdx.y != 0)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D((blockIdx.y - 1)*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y); + boundary_index = 3; + } + if(threadIdx.y == blockDim.y - 1 && (blockIdx.y != gridDim.y - 1)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D((blockIdx.y + 1)*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y); + boundary_index = 0; + } + + __threadfence(); + if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX)) + { + cudaSolver->unusedCell_cuda[gid] = 0; + atomicMax(&newSubgridValue, INT_MAX); + atomicMax(&boundary[boundary_index], 1); + cudaSolver->work_u_cuda[gid] = u_cmp; + u=u_cmp; + } + __threadfence(); + + if(threadIdx.z == 0 && (blockIdx.z != 0)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid - blockDim.x*gridDim.x*blockDim.y*gridDim.y]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + (blockIdx.z - 1)*gridDim.x*gridDim.y); + boundary_index = 5; + } + if(threadIdx.z == blockDim.z - 1 && (blockIdx.z != gridDim.z - 1)/* && (cudaSolver->currentStep & 1)*/) + { + u_cmp = cudaSolver->work_u_cuda[gid + blockDim.x*gridDim.x*blockDim.y*gridDim.y]; + subgridValue_cmp = cudaSolver->getSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + (blockIdx.z + 1)*gridDim.x*gridDim.y); + boundary_index = 4; + } + __threadfence(); + + if((subgridValue == INT_MAX || fabs(u_cmp) + cudaSolver->delta < fabs(u) ) && (subgridValue_cmp != INT_MAX && subgridValue_cmp != -INT_MAX)) + { + cudaSolver->unusedCell_cuda[gid] = 0; + atomicMax(&newSubgridValue, INT_MAX); + atomicMax(&boundary[boundary_index], 1); + cudaSolver->work_u_cuda[gid] = u_cmp; + } + __threadfence(); + + } + __syncthreads(); + + if(threadIdx.x+threadIdx.y+threadIdx.z == 0) + { + + if(subgridValue == INT_MAX && newSubgridValue != 0) + cudaSolver->setSubgridValueCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y, -INT_MAX); + + cudaSolver->setBoundaryConditionCUDA3D(blockIdx.y*gridDim.x + blockIdx.x + blockIdx.z*gridDim.x*gridDim.y, 1 * boundary[0] + + 2 * boundary[1] + + 4 * boundary[2] + + 8 * boundary[3] + + 16 * boundary[4] + + 32 * boundary[5] ); + if(blockIdx.x+blockIdx.y+blockIdx.z == 0) + { + cudaSolver->currentStep = cudaSolver->currentStep + 1; + *(cudaSolver->runcuda) = 0; + } + } +} + + + +template <typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void synchronize2CUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver) +{ + int stepValue = cudaSolver->currentStep + 4; + if( cudaSolver->getSubgridValueCUDA3D(blockIdx.z*gridDim.x*gridDim.y + blockIdx.y*gridDim.x + blockIdx.x) == -INT_MAX ) + cudaSolver->setSubgridValueCUDA3D(blockIdx.z*gridDim.x*gridDim.y + blockIdx.y*gridDim.x + blockIdx.x, stepValue); + + atomicMax((cudaSolver->runcuda),cudaSolver->getBoundaryConditionCUDA3D(blockIdx.z*gridDim.x*gridDim.y + blockIdx.y*gridDim.x + blockIdx.x)); +} + + + + + + + + +template< typename SchemeHost, typename SchemeDevice, typename Device> +__global__ +void initCUDA3D( tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* cudaSolver, double* ptr , int* ptr2, int* ptr3) +{ + + + cudaSolver->work_u_cuda = ptr;//(double*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(double)); + cudaSolver->unusedCell_cuda = ptr3;//(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->n*cudaSolver->n*sizeof(int)); + cudaSolver->subgridValues_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->gridLevels*sizeof(int)); + cudaSolver->boundaryConditions_cuda =(int*)malloc(cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->gridLevels*sizeof(int)); + cudaSolver->runcuda = ptr2;//(bool*)malloc(sizeof(bool)); + *(cudaSolver->runcuda) = 1; + cudaSolver->currentStep = 1; + //cudaMemcpy(ptr,&(cudaSolver->work_u_cuda), sizeof(double*),cudaMemcpyDeviceToHost); + //ptr = cudaSolver->work_u_cuda; + printf("GPU memory allocated.\n"); + + for(int i = 0; i < cudaSolver->gridCols*cudaSolver->gridRows*cudaSolver->gridLevels; i++) + { + cudaSolver->subgridValues_cuda[i] = INT_MAX; + cudaSolver->boundaryConditions_cuda[i] = 0; + } + + /*for(long int j = 0; j < cudaSolver->n*cudaSolver->n*cudaSolver->gridCols*cudaSolver->gridRows; j++) + { + printf("%d\n",j); + cudaSolver->unusedCell_cuda[ j] = 1; + }*/ + printf("GPU memory initialized.\n"); +} + + + + +//extern __shared__ double array[]; +template< typename SchemeHost, typename SchemeDevice, typename Device > +__global__ +void initRunCUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller) + +{ + + + extern __shared__ double u[]; + + int i = blockIdx.z * gridDim.x * gridDim.y + blockIdx.y * gridDim.x + blockIdx.x; + int l = threadIdx.z * blockDim.x * blockDim.y + threadIdx.y * blockDim.x + threadIdx.x; + + __shared__ int containsCurve; + if(l == 0) + { +// printf("z = %d, y = %d, x = %d\n",blockIdx.z,blockIdx.y,blockIdx.x); + containsCurve = 0; + } + + caller->getSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + if(u[0] * u[l] <= 0.0) + { + atomicMax( &containsCurve, 1); + } + + __syncthreads(); + if(containsCurve == 1) + { + caller->runSubgridCUDA3D(0,u,i); + __syncthreads(); +// caller->insertSubgridCUDA3D(u[l],i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + + __syncthreads(); + if(l == 0) + caller->setSubgridValueCUDA3D(i, 4); + } + + +} + + + + + +template< typename SchemeHost, typename SchemeDevice, typename Device > +__global__ +void runCUDA3D(tnlParallelEikonalSolver<3,SchemeHost, SchemeDevice, Device, double, int >* caller) +{ + extern __shared__ double u[]; + int i = blockIdx.z * gridDim.x * gridDim.y + blockIdx.y * gridDim.x + blockIdx.x; + int l = threadIdx.z * blockDim.x * blockDim.y + threadIdx.y * blockDim.x + threadIdx.x; + int bound = caller->getBoundaryConditionCUDA3D(i); + + if(caller->getSubgridValueCUDA3D(i) != INT_MAX && bound != 0 && caller->getSubgridValueCUDA3D(i) > 0) + { + caller->getSubgridCUDA3D(i,caller, &u[l]); + + //if(l == 0) + //printf("i = %d, bound = %d\n",i,caller->getSubgridValueCUDA3D(i)); + if(caller->getSubgridValueCUDA3D(i) == caller->currentStep+4) + { + if(bound & 1) + { + caller->runSubgridCUDA3D(1,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 2 ) + { + caller->runSubgridCUDA3D(2,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 4) + { + caller->runSubgridCUDA3D(4,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 8) + { + caller->runSubgridCUDA3D(8,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 16) + { + caller->runSubgridCUDA3D(16,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if(bound & 32) + { + caller->runSubgridCUDA3D(32,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + + } + else + { + if( ((bound == 2))) + { + caller->runSubgridCUDA3D(2,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound == 1) )) + { + caller->runSubgridCUDA3D(1,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound == 8) )) + { + caller->runSubgridCUDA3D(8,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if((bound == 4)) + { + caller->runSubgridCUDA3D(4,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if(bound == 16) + { + caller->runSubgridCUDA3D(16,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if(bound == 32) + { + caller->runSubgridCUDA3D(32,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + } + /* 1 2 4 8 16 32 */ + + if( ((bound & 19 ))) /* 1 1 0 0 1 0 */ + { + caller->runSubgridCUDA3D(19,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 21 ))) /* 1 0 1 0 1 0 */ + { + caller->runSubgridCUDA3D(21,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 26 ))) /* 0 1 0 1 1 0 */ + { + caller->runSubgridCUDA3D(26,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( (bound & 28 )) /* 0 0 1 1 1 0 */ + { + caller->runSubgridCUDA3D(28,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + + + + if( ((bound & 35 ))) /* 1 0 1 0 0 1 */ + { + caller->runSubgridCUDA3D(35,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 37 ))) /* 1 0 1 0 0 1 */ + { + caller->runSubgridCUDA3D(37,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( ((bound & 42 ))) /* 0 1 0 1 0 1 */ + { + caller->runSubgridCUDA3D(42,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + if( (bound & 44 )) /* 0 0 1 1 0 1 */ + { + caller->runSubgridCUDA3D(44,u,i); + caller->updateSubgridCUDA3D(i,caller, &u[l]); + __syncthreads(); + } + + if(l==0) + { + caller->setBoundaryConditionCUDA3D(i, 0); + caller->setSubgridValueCUDA3D(i, caller->getSubgridValueCUDA3D(i) - 1 ); + } + + + } + + + +} + +#endif /*HAVE_CUDA*/ + +#endif /* TNLPARALLELEIKONALSOLVER3D_IMPL_H_ */ diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..04348b8b5baa4bdbd772b67feaf9da3b32aed53d --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/CMakeLists.txt @@ -0,0 +1,21 @@ +set( tnl_hamilton_jacobi_SOURCES + hamiltonJacobiProblemSetter.h + hamiltonJacobiProblemSetter_impl.h + hamiltonJacobiProblemSolver.h + hamiltonJacobiProblemSolver_impl.h + main.cpp + hamiltonJacobiProblemConfig.h + tnl-direct-eikonal-solver.h ) + +ADD_EXECUTABLE(tnl-hamilton-jacobi${debugExt} main.cpp) +target_link_libraries (tnl-hamilton-jacobi${debugExt} tnl${debugExt}-${tnlVersion} ) + +ADD_EXECUTABLE(tnl-direct-eikonal-solver${debugExt} tnl-direct-eikonal-solver.cpp ) +target_link_libraries (tnl-direct-eikonal-solver${debugExt} tnl${debugExt}-${tnlVersion} ) + + +INSTALL( TARGETS tnl-hamilton-jacobi${debugExt} + tnl-direct-eikonal-solver${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem.h new file mode 100644 index 0000000000000000000000000000000000000000..a4182050ac311e21be33388ff22fded1428a88a0 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem.h @@ -0,0 +1,97 @@ +/*************************************************************************** + hamiltonJacobiProblem.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <problems/tnlPDEProblem.h> +#include <solvers/preconditioners/tnlDummyPreconditioner.h> +#include <solvers/tnlSolverMonitor.h> +#include <core/tnlLogger.h> +#include <core/vectors/tnlVector.h> +#include <solvers/pde/tnlExplicitUpdater.h> +#include <solvers/pde/tnlLinearSystemAssembler.h> +#include <functions/tnlMeshFunction.h> + +template< typename Mesh, + typename DifferentialOperator, + typename BoundaryCondition, + typename RightHandSide> +class HamiltonJacobiProblem : public tnlPDEProblem< Mesh, + TimeDependentProblem, + 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, TimeDependentProblem, RealType, DeviceType, IndexType > BaseType; + + using typename BaseType::MeshType; + using typename BaseType::DofVectorType; + using typename BaseType::MeshDependentDataType; + + static String getTypeStatic(); + + String getPrologHeader() const; + + void writeProlog( tnlLogger& logger, + const Config::ParameterContainer& parameters ) const; + + bool setup( const Config::ParameterContainer& parameters ); + + bool setInitialCondition( const Config::ParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ); + + 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 ); + + protected: + + MeshFunctionType solution; + + tnlExplicitUpdater< Mesh, MeshFunctionType, DifferentialOperator, BoundaryCondition, RightHandSide > explicitUpdater; + + DifferentialOperator differentialOperator; + + BoundaryCondition boundaryCondition; + + RightHandSide rightHandSide; +}; + +#include "HamiltonJacobiProblem_impl.h" + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..4e84c7d98966b3e35d86e263850a7df14d85ff13 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemConfig.h @@ -0,0 +1,37 @@ +/*************************************************************************** + hamiltonJacobiProblemConfig.h - description + ------------------- + begin : Oct 5, 2014 + copyright : (C) 2014 by Tomas Sobotik + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <config/tnlConfigDescription.h> + +template< typename ConfigTag > +class HamiltonJacobiProblemConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Hamilton-Jacobi solver settings:" ); + config.addEntry < String > ( "problem-name", "This defines particular problem.", "hamilton-jacobi" ); + config.addEntry < String > ( "scheme", "This defines scheme used for discretization.", "godunov" ); + config.addEntryEnum( "godunov" ); + config.addEntryEnum( "upwind" ); + config.addEntry < double > ( "epsilon", "This defines epsilon for smoothening of sign().", 3.0 ); + config.addEntry < double > ( "-value", "Constant value of RHS.", 0.0 ); + } +}; + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter.h new file mode 100644 index 0000000000000000000000000000000000000000..ce4209736e95d6e58e410cc2acef09c1542270b8 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter.h @@ -0,0 +1,35 @@ +/*************************************************************************** + hamiltonJacobiProblemSetter.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <TNL/Config/ParameterContainer.h> +#include "HamiltonJacobiProblem.h" + +template< typename RealType, + typename DeviceType, + typename IndexType, + typename MeshType, + typename ConfigTag, + typename SolverStarter > +class HamiltonJacobiProblemSetter +{ + public: + static bool run( const Config::ParameterContainer& parameters ); +}; + +#include "HamiltonJacobiProblemSetter_impl.h" + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..af1d427597ffe71d606bd3ca60f206470dcf2c92 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblemSetter_impl.h @@ -0,0 +1,75 @@ +/*************************************************************************** + hamiltonJacobiProblemSetter_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <mesh/tnlGrid.h> +#include <functions/tnlConstantFunction.h> +#include <operators/tnlNeumannBoundaryConditions.h> +#include <operators/tnlDirichletBoundaryConditions.h> +#include <operators/hamilton-jacobi/upwindEikonal.h> +#include <operators/hamilton-jacobi/godunovEikonal.h> +#include <operators/hamilton-jacobi/tnlEikonalOperator.h> + + +template< typename RealType, + typename DeviceType, + typename IndexType, + typename MeshType, + typename ConfigTag, + typename SolverStarter > +bool HamiltonJacobiProblemSetter< RealType, DeviceType, IndexType, MeshType, ConfigTag, SolverStarter > :: run( const Config::ParameterContainer& parameters ) +{ + static const int Dimensions = MeshType::getMeshDimensions(); + + if( Dimensions <= 0 || Dimensions > 3 ) + { + cerr << "The problem is not defined for " << Dimensions << "dimensions." << endl; + return false; + } + else + { + typedef Containers::StaticVector < Dimensions, RealType > Vertex; + typedef tnlConstantFunction< Dimensions, RealType > ConstantFunctionType; + typedef tnlNeumannBoundaryConditions< MeshType, ConstantFunctionType, RealType, IndexType > BoundaryConditions; + + SolverStarter solverStarter; + + const String& schemeName = parameters.getParameter< String >( "scheme" ); + + if( schemeName == "upwind" ) + { + typedef upwindEikonalScheme< MeshType, RealType, IndexType > GradientNormOperator; + typedef tnlConstantFunction< Dimensions, RealType > RightHandSide; + typedef tnlEikonalOperator< GradientNormOperator, RightHandSide > Operator; + typedef HamiltonJacobiProblem< MeshType, Operator, BoundaryConditions, RightHandSide > Solver; + return solverStarter.template run< Solver >( parameters ); + } + if( schemeName == "godunov" ) + { + typedef godunovEikonalScheme< MeshType, RealType, IndexType > GradientNormOperator; + typedef tnlConstantFunction< Dimensions, RealType > RightHandSide; + typedef tnlEikonalOperator< GradientNormOperator, RightHandSide > Operator; + typedef HamiltonJacobiProblem< MeshType, Operator, BoundaryConditions, RightHandSide > Solver; + return solverStarter.template run< Solver >( parameters ); + } + else + cerr << "Unknown scheme '" << schemeName << "'." << endl; + + + return false; + } +} diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..9917205ead68b98de8b55d8423042a99fb0848dd --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/HamiltonJacobiProblem_impl.h @@ -0,0 +1,199 @@ +/*************************************************************************** + HamiltonJacobiProblem_impl.h - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <core/mfilename.h> +#include <matrices/tnlMatrixSetter.h> +#include <exception> + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +String HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: getTypeStatic() +{ + return String( "hamiltonJacobiSolver< " ) + Mesh :: getTypeStatic() + " >"; +} + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +String HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: getPrologHeader() const +{ + return String( "Hamilton-Jacobi" ); +} + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +void HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: writeProlog( tnlLogger& logger, + const Config::ParameterContainer& parameters ) const +{ + //logger. WriteParameter< typename String >( "Problem name:", "problem-name", parameters ); + //logger. WriteParameter< String >( "Used scheme:", "scheme", parameters ); +} + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +bool HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide > :: setup( const Config::ParameterContainer& parameters ) +{ + this->boundaryCondition.getFunction().setConstant( 1.0 ); + //this->rightHandSide.getFunction().setConstant( 0.0 ); + //return true; +/* + const String& problemName = parameters. GetParameter< String >( "problem-name" ); + + this->schemeTest = parameters. GetParameter< int >( "scheme-test" ); + this->tested = false; + + const String& meshFile = parameters.GetParameter< String >( "mesh" ); + if( ! this->mesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + const IndexType& dofs = this->mesh.getDofs(); + dofVector. setSize( dofs ); + + this -> u. bind( & dofVector. getData()[ 0 * dofs ], dofs ); + this -> v. bind( & dofVector. getData()[ 1 * dofs ], dofs ); + +*/ + differentialOperator.getAnisotropy().setConstant( 1.0 ); //setup( parameters ); + differentialOperator.setSmoothing( 1.0 ); + return true; + +} + + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +typename HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::IndexType + HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >::getDofs( const MeshType& mesh ) const +{ + /**** + * Set-up DOFs and supporting grid functions + */ + return mesh.template getEntitiesCount< typename MeshType::Cell >(); +} + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +void HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >:: +bindDofs( const MeshType& mesh, + DofVectorType& dofVector ) +{ + //const IndexType dofs = mesh.template getEntitiesCount< typename MeshType::Cell >(); + this->solution.bind( mesh, dofVector ); +} + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +bool +HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >:: +setInitialCondition( const Config::ParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + this->bindDofs( mesh, dofs ); + const String& initialConditionFile = parameters.getParameter< String >( "initial-condition" ); + if( ! this->solution.boundLoad( initialConditionFile ) ) + { + cerr << "I am not able to load the initial condition from the file " << initialConditionFile << "." << endl; + return false; + } + return true; +} + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +bool +HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >:: +makeSnapshot( const RealType& time, + const IndexType& step, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshDependentData ) +{ + cout << endl << "Writing output at time " << time << " step " << step << "." << endl; + + String fileName; + FileNameBaseNumberEnding( "u-", step, 5, ".tnl", fileName ); + if( ! this->solution.save( fileName ) ) + return false; + + return true; +} + + +template< typename Mesh, + typename HamiltonJacobi, + typename BoundaryCondition, + typename RightHandSide> +void +HamiltonJacobiProblem< Mesh,HamiltonJacobi,BoundaryCondition,RightHandSide >:: +getExplicitRHS( const RealType& time, + const RealType& tau, + const MeshType& mesh, + DofVectorType& _u, + DofVectorType& _fu, + MeshDependentDataType& meshDependentData ) +{ + + /* + if(!(this->schemeTest)) + scheme.GetExplicitRHS(time, tau, _u, _fu); + else if(!(this->tested)) + { + this->tested = true; + DofVectorType tmp; + if(tmp.setLike(_u)) + tmp = _u; + scheme.GetExplicitRHS(time, tau, tmp, _u); + + } + */ + + //this->bindDofs( mesh, _u ); + MeshFunctionType u, fu; + u.bind( mesh, _u ); + fu.bind( mesh, _fu ); + explicitUpdater.template update< typename MeshType::Cell >( time, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + fu ); + //fu.save( "fu.tnl" ); + //std::cerr << "Enter." << std::endl; + //getchar(); +} diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h new file mode 100644 index 0000000000000000000000000000000000000000..1b904c0c8b1d096a72a6ee8c3cc3cd1979d164b4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/MainBuildConfig.h @@ -0,0 +1,64 @@ +/*************************************************************************** + MainBuildConfig.h - description + ------------------- + begin : Jul 7, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MAINBUILDCONFIG_H_ +#define MAINBUILDCONFIG_H_ + +#include <solvers/tnlBuildConfigTags.h> + +class MainBuildConfig +{ + public: + + static void print() { cerr << "MainBuildConfig" << endl; } +}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< MainBuildConfig, 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< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && + tnlConfigTagReal< MainBuildConfig, Real >::enabled && + tnlConfigTagDevice< MainBuildConfig, Device >::enabled && + tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* MAINBUILDCONFIG_H_ */ diff --git a/examples/mean-curvature-flow/Makefile b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/Makefile similarity index 55% rename from examples/mean-curvature-flow/Makefile rename to src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/Makefile index 71873be3fbafbf131bd8b092c7078a9dea9b167d..03620692c53d343adcb0e73060dba775223b1c7c 100644 --- a/examples/mean-curvature-flow/Makefile +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/Makefile @@ -1,36 +1,41 @@ -TNL_VERSION=0.1 -TNL_INSTALL_DIR=${HOME}/local/lib -TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION} - -TARGET = mean-curvature-flow-eoc -INSTALL_DIR = ${HOME}/local -CXX = g++ -CUDA_CXX = nvcc -CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O0 -g -LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-dbg-0.1 - -SOURCES = tnl-mean-curvature-flow-eoc.cpp -HEADERS = -OBJECTS = tnl-mean-curvature-flow-eoc.o -DIST = $(SOURCES) Makefile - -all: $(TARGET) -clean: - rm -f $(OBJECTS) - -dist: $(DIST) - tar zcvf $(TARGET).tgz $(DIST) - -install: $(TARGET) - cp $(TARGET) $(INSTALL_DIR)/bin - cp $(INSTALL_DIR)/share/tnl-0.1/examples/mean-curvature-flow - -uninstall: $(TARGET) - rm -f $(INSTALL_DIR)/bin/$(TARGET) - rm -f $(INSTALL_DIR)/share/tnl-0.1/examples/mean-curvature-flow - -$(TARGET): $(OBJECTS) - $(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS) - -%.o: %.cpp $(HEADERS) - $(CXX) -c -o $@ $(CXX_FLAGS) $< +TNL_VERSION=0.1 +TNL_INSTALL_DIR=${HOME}/local/lib +TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION} + +TARGET = hamiltonJacobiSolver +CONFIG_FILE = $(TARGET).cfg.desc +INSTALL_DIR = ${HOME}/local +CXX = g++ +CUDA_CXX = nvcc +OMP_FLAGS = -DHAVE_OPENMP -fopenmp +CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O3 $(OMP_FLAGS) +LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-0.1 -lgomp + +SOURCES = main.cpp +HEADERS = +OBJECTS = main.o +DIST = $(SOURCES) Makefile + +all: $(TARGET) +clean: + rm -f $(OBJECTS) + rm -f $(TARGET)-conf.h + +dist: $(DIST) + tar zcvf $(TARGET).tgz $(DIST) + +install: $(TARGET) + cp $(TARGET) $(INSTALL_DIR)/bin + cp $(CONFIG_FILE) $(INSTALL_DIR)/share + +uninstall: $(TARGET) + rm -f $(INSTALL_DIR)/bin/$(TARGET) + rm -f $(CONFIG_FILE) $(INSTALL_DIR)/share + +$(TARGET): $(OBJECTS) + $(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS) + +%.o: %.cpp $(HEADERS) + $(CXX) -c -o $@ $(CXX_FLAGS) $< + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/main.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3c6af1c9e610f76d67cc903c66d55c7f07b5f4ee --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/main.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "HamiltonJacobiProblemConfig.h" +#include "HamiltonJacobiProblemSetter.h" +#include <solvers/tnlSolver.h> +#include "MainBuildConfig.h" +#include <solvers/tnlBuildConfigTags.h> + +typedef MainBuildConfig BuildConfig; + +int main( int argc, char* argv[] ) +{ + tnlSolver< HamiltonJacobiProblemSetter, HamiltonJacobiProblemConfig, BuildConfig > solver; + if( ! solver. run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cpp b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4343837617b4c0c1416b209b6f755fcaf1476912 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cpp @@ -0,0 +1,14 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnl-direct-eikonal-solver.cpp + * Author: oberhuber + * + * Created on July 13, 2016, 1:13 PM + */ + +#include "tnl-direct-eikonal-solver.h" \ No newline at end of file diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cu b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cu new file mode 100644 index 0000000000000000000000000000000000000000..21b17dbdd425c1bb4c6a9664a1c7ba7e2df6d0c4 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.cu @@ -0,0 +1,14 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnl-direct-eikonal-solver.cu + * Author: oberhuber + * + * Created on July 13, 2016, 1:13 PM + */ + +#include "tnl-direct-eikonal-solver.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h new file mode 100644 index 0000000000000000000000000000000000000000..a36153011e3b2e8b8e5590a27e1c0bdcf895faf5 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-direct-eikonal-solver.h @@ -0,0 +1,72 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnl-direct-eikonal-solver.h + * Author: oberhuber + * + * Created on July 13, 2016, 1:09 PM + */ + +#pragma once + +#include <solvers/tnlSolver.h> +#include <solvers/tnlFastBuildConfigTag.h> +#include <solvers/tnlBuildConfigTags.h> +#include <functions/tnlConstantFunction.h> +#include <functions/tnlMeshFunction.h> +//#include <problems/tnlHeatEquationProblem.h> +#include <mesh/tnlGrid.h> +#include "tnlDirectEikonalProblem.h" + +//typedef tnlDefaultBuildMeshConfig BuildConfig; +typedef tnlFastBuildConfig BuildConfig; + +template< typename MeshConfig > +class tnlDirectEikonalSolverConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Direct eikonal equation solver settings:" ); + config.addRequiredEntry< String >( "input-file", "Input file." ); + }; +}; + +template< typename Real, + typename Device, + typename Index, + typename MeshType, + typename MeshConfig, + typename SolverStarter > +class tnlDirectEikonalSolverSetter +{ + public: + + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Containers::StaticVector< MeshType::meshDimensions, Real > Vertex; + + static bool run( const Config::ParameterContainer& parameters ) + { + enum { Dimensions = MeshType::meshDimensions }; + typedef tnlConstantFunction< Dimensions, Real > Anisotropy; + typedef tnlDirectEikonalProblem< MeshType, Anisotropy > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + }; +}; + +int main( int argc, char* argv[] ) +{ + if( ! tnlSolver< tnlDirectEikonalSolverSetter, tnlDirectEikonalSolverConfig, BuildConfig >::run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-eikonal-equation-eoc-test b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-eikonal-equation-eoc-test new file mode 100644 index 0000000000000000000000000000000000000000..bcc05ef15adf4f042fe813d875545b2bae09096a --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-eikonal-equation-eoc-test @@ -0,0 +1,201 @@ +#!/bin/bash + +device="host" +dimensions="1D 2D 3D" +#dimensions="1D" +sizes1D="16 32 64 128 256 512 1024 2048 4096" +#sizes1D="256" +sizes2D="16 32 64 128 256 512 1024" +#sizes2D="8" +sizes3D="16 32 64 128 256" +testFunctions="paraboloid" +snapshotPeriod=0.1 +finalTime=1.5 +solverName="tnl-hamilton-jacobi" +#solverName="gdb --args tnl-hamilton-jacobi-dbg" +# + +setupTestFunction() +{ + testFunction=$1 +# if test x${testFunction} = "xexp-bump"; +# then + origin=-1.0 + proportions=2.0 + amplitude=1.0 + waveLength=0.2 + waveLengthX=0.2 + waveLengthY=0.2 + waveLengthZ=0.2 + wavesNumber=3.0 + wavesNumberX=0.5 + wavesNumberY=2.0 + wavesNumberZ=3.0 + phase=0.1 + phaseX=0.0 + phaseY=0.0 + phaseZ=0.0 + sigma=0.5 +# fi +} + +setupGrid() +{ + dimensions=$1 + gridSize=$2 + tnl-grid-setup --dimensions ${dimensions} \ + --origin-x ${origin} \ + --origin-y ${origin} \ + --origin-z ${origin} \ + --proportions-x ${proportions} \ + --proportions-y ${proportions} \ + --proportions-z ${proportions} \ + --size-x ${gridSize} \ + --size-y ${gridSize} \ + --size-z ${gridSize} +} + +setInitialCondition() +{ + testFunction=$1 + tnl-init --test-function ${testFunction} \ + --output-file initial-u.tnl \ + --amplitude ${amplitude} \ + --wave-length ${waveLength} \ + --wave-length-x ${waveLengthX} \ + --wave-length-y ${waveLengthY} \ + --wave-length-z ${waveLengthZ} \ + --waves-number ${wavesNumber} \ + --waves-number-x ${wavesNumberX} \ + --waves-number-y ${wavesNumberY} \ + --waves-number-z ${wavesNumberZ} \ + --phase ${phase} \ + --phase-x ${phaseX} \ + --phase-y ${phaseY} \ + --phase-z ${phaseZ} \ + --sigma ${sigma} + + tnl-init --test-function ${testFunction}-sdf \ + --output-file final-u.tnl \ + --amplitude ${amplitude} \ + --wave-length ${waveLength} \ + --wave-length-x ${waveLengthX} \ + --wave-length-y ${waveLengthY} \ + --wave-length-z ${waveLengthZ} \ + --waves-number ${wavesNumber} \ + --waves-number-x ${wavesNumberX} \ + --waves-number-y ${wavesNumberY} \ + --waves-number-z ${wavesNumberZ} \ + --phase ${phase} \ + --phase-x ${phaseX} \ + --phase-y ${phaseY} \ + --phase-z ${phaseZ} \ + --sigma ${sigma} + +} + +solve() +{ + timeDiscretisation=$1 + discreteSolver=$2 + ${solverName} --device ${device} \ + --mesh mesh.tnl \ + --initial-condition initial-u.tnl \ + --time-discretisation ${timeDiscretisation} \ + --time-step 10 \ + --time-step-order 2 \ + --discrete-solver ${discreteSolver} \ + --merson-adaptivity 1.0e-5 \ + --min-iterations 20 \ + --convergence-residue 1.0e-12 \ + --snapshot-period ${snapshotPeriod} \ + --final-time ${finalTime} +} + +computeError() +{ + tnl-diff --mesh mesh.tnl \ + --input-files final-u.tnl u-*.tnl \ + --mode sequence \ + --snapshot-period ${snapshotPeriod} \ + --output-file errors.txt \ + --write-difference yes +} + +runTest() +{ + for testFunction in ${testFunctions}; + do + mkdir -p ${testFunction} + cd ${testFunction} + setupTestFunction ${testFunction} + + for dim in ${dimensions}; + do + mkdir -p $dim + cd ${dim} + if test $dim = 1D; + then + sizes=$sizes1D + fi + if test $dim = 2D; + then + sizes=$sizes2D + fi + if test $dim = 3D; + then + sizes=$sizes3D + fi + + lastSize="" + for size in $sizes; + do + mkdir -p $size + cd $size + echo "" + echo "" + echo "" + if test ! -f computation-done; + then + touch computation-in-progress + echo "=========================================================================" + echo "=== SETTING UP THE GRID ===" + echo "=========================================================================" + setupGrid $dim $size + echo "=========================================================================" + echo "=== WRITING THE EXACT SOLUTION ===" + echo "=========================================================================" + setInitialCondition $testFunction + echo "=========================================================================" + echo "=== STARTING THE SOLVER ===" + echo "=========================================================================" + solve explicit merson + #solve semi-implicit gmres + mv computation-in-progress computation-done + fi + echo "=========================================================================" + echo "=== COMPUTING THE ERROR ===" + echo "=========================================================================" + computeError + echo "=========================================================================" + echo "=== COMPUTING THE EOC ===" + echo "=========================================================================" + if test ! x$lastSize = x; + then + tnl-err2eoc ../$lastSize/errors.txt errors.txt + fi + echo "=========================================================================" + echo "=== COMPUTATION DONE ===" + echo "=========================================================================" + cd .. + lastSize=$size + done + + cd .. + done + cd .. + done +} + +runTest + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test new file mode 100755 index 0000000000000000000000000000000000000000..6d997ce230a9de4ad1deefc1ccaa1f926021a16f --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnl-run-fsm-eoc-test @@ -0,0 +1,204 @@ +#!/bin/bash + +device="host" +dimensions="2D 3D" +dimensions="2D" +sizes1D="16 32 64 128 256 512 1024 2048 4096" +#sizes1D="256" +sizes2D="16 32 64 128 256 512 1024" +#sizes2D="8" +sizes3D="16 32 64 128 256" +testFunctions="paraboloid" +snapshotPeriod=0.1 +finalTime=1.5 +solverName="tnl-direct-eikonal-solver" +#solverName="gdb --args tnl-direct-eikonal-solver-dbg" +# + +setupTestFunction() +{ + testFunction=$1 +# if test x${testFunction} = "xexp-bump"; +# then + origin=-1.0 + proportions=2.0 + amplitude=1.0 + waveLength=0.2 + waveLengthX=0.2 + waveLengthY=0.2 + waveLengthZ=0.2 + wavesNumber=3.0 + wavesNumberX=0.5 + wavesNumberY=2.0 + wavesNumberZ=3.0 + phase=0.1 + phaseX=0.0 + phaseY=0.0 + phaseZ=0.0 + sigma=0.5 + radius=0.5 +# fi +} + +setupGrid() +{ + dimensions=$1 + gridSize=$2 + tnl-grid-setup --dimensions ${dimensions} \ + --origin-x ${origin} \ + --origin-y ${origin} \ + --origin-z ${origin} \ + --proportions-x ${proportions} \ + --proportions-y ${proportions} \ + --proportions-z ${proportions} \ + --size-x ${gridSize} \ + --size-y ${gridSize} \ + --size-z ${gridSize} +} + +setInitialCondition() +{ + testFunction=$1 + tnl-init --test-function ${testFunction}-sdf \ + --output-file initial-u.tnl \ + --amplitude ${amplitude} \ + --wave-length ${waveLength} \ + --wave-length-x ${waveLengthX} \ + --wave-length-y ${waveLengthY} \ + --wave-length-z ${waveLengthZ} \ + --waves-number ${wavesNumber} \ + --waves-number-x ${wavesNumberX} \ + --waves-number-y ${wavesNumberY} \ + --waves-number-z ${wavesNumberZ} \ + --phase ${phase} \ + --phase-x ${phaseX} \ + --phase-y ${phaseY} \ + --phase-z ${phaseZ} \ + --sigma ${sigma} \ + --radius ${radius} + + tnl-init --test-function ${testFunction}-sdf \ + --output-file final-u.tnl \ + --amplitude ${amplitude} \ + --wave-length ${waveLength} \ + --wave-length-x ${waveLengthX} \ + --wave-length-y ${waveLengthY} \ + --wave-length-z ${waveLengthZ} \ + --waves-number ${wavesNumber} \ + --waves-number-x ${wavesNumberX} \ + --waves-number-y ${wavesNumberY} \ + --waves-number-z ${wavesNumberZ} \ + --phase ${phase} \ + --phase-x ${phaseX} \ + --phase-y ${phaseY} \ + --phase-z ${phaseZ} \ + --sigma ${sigma} \ + --radius ${radius} + +} + +solve() +{ + timeDiscretisation=$1 + discreteSolver=$2 + ${solverName} --device ${device} \ + --mesh mesh.tnl \ + --input-file initial-u.tnl \ + --time-discretisation ${timeDiscretisation} \ + --time-step 10 \ + --time-step-order 2 \ + --discrete-solver ${discreteSolver} \ + --merson-adaptivity 1.0e-5 \ + --min-iterations 20 \ + --convergence-residue 1.0e-12 \ + --snapshot-period ${snapshotPeriod} \ + --final-time ${finalTime} +} + +computeError() +{ + tnl-diff --mesh mesh.tnl \ + --input-files final-u.tnl u-*.tnl \ + --mode sequence \ + --snapshot-period ${snapshotPeriod} \ + --output-file errors.txt \ + --write-difference yes +} + +runTest() +{ + for testFunction in ${testFunctions}; + do + mkdir -p ${testFunction} + cd ${testFunction} + setupTestFunction ${testFunction} + + for dim in ${dimensions}; + do + mkdir -p $dim + cd ${dim} + if test $dim = 1D; + then + sizes=$sizes1D + fi + if test $dim = 2D; + then + sizes=$sizes2D + fi + if test $dim = 3D; + then + sizes=$sizes3D + fi + + lastSize="" + for size in $sizes; + do + mkdir -p $size + cd $size + echo "" + echo "" + echo "" + if test ! -f computation-done; + then + touch computation-in-progress + echo "=========================================================================" + echo "=== SETTING UP THE GRID ===" + echo "=========================================================================" + setupGrid $dim $size + echo "=========================================================================" + echo "=== WRITING THE EXACT SOLUTION ===" + echo "=========================================================================" + setInitialCondition $testFunction + echo "=========================================================================" + echo "=== STARTING THE SOLVER ===" + echo "=========================================================================" + solve explicit merson + #solve semi-implicit gmres + mv computation-in-progress computation-done + fi + echo "=========================================================================" + echo "=== COMPUTING THE ERROR ===" + echo "=========================================================================" + computeError + echo "=========================================================================" + echo "=== COMPUTING THE EOC ===" + echo "=========================================================================" + if test ! x$lastSize = x; + then + tnl-err2eoc ../$lastSize/errors.txt errors.txt + fi + echo "=========================================================================" + echo "=== COMPUTATION DONE ===" + echo "=========================================================================" + cd .. + lastSize=$size + done + + cd .. + done + cd .. + done +} + +runTest + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h new file mode 100644 index 0000000000000000000000000000000000000000..409a2d93a1d7eb719e3b4f93b6eb9b7da53f72e5 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase.h @@ -0,0 +1,89 @@ +/* + * File: tnlDirectEikonalMethodsBase.h + * Author: oberhuber + * + * Created on July 14, 2016, 3:17 PM + */ + +#pragma once + +#include <mesh/tnlGrid.h> +#include <functions/tnlMeshFunction.h> + +template< typename Mesh > +class tnlDirectEikonalMethodsBase +{ +}; + +template< typename Real, + typename Device, + typename Index > +class tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > > +{ + public: + + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef Real RealType; + typedef Device DevcieType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + typedef tnlMeshFunction< MeshType, 1, bool > InterfaceMapType; + + void initInterface( const MeshFunctionType& input, + MeshFunctionType& output, + InterfaceMapType& interfaceMap ); + + template< typename MeshEntity > + void updateCell( MeshFunctionType& u, + const MeshEntity& cell ); + +}; + + +template< typename Real, + typename Device, + typename Index > +class tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > > +{ + public: + + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef Real RealType; + typedef Device DevcieType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + typedef tnlMeshFunction< MeshType, 2, bool > InterfaceMapType; + + void initInterface( const MeshFunctionType& input, + MeshFunctionType& output, + InterfaceMapType& interfaceMap ); + + template< typename MeshEntity > + void updateCell( MeshFunctionType& u, + const MeshEntity& cell ); +}; + +template< typename Real, + typename Device, + typename Index > +class tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > > +{ + public: + + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef Real RealType; + typedef Device DevcieType; + typedef Index IndexType; + typedef tnlMeshFunction< MeshType > MeshFunctionType; + typedef tnlMeshFunction< MeshType, 3, bool > InterfaceMapType; + + void initInterface( const MeshFunctionType& input, + MeshFunctionType& output, + InterfaceMapType& interfaceMap ); + + template< typename MeshEntity > + void updateCell( MeshFunctionType& u, + const MeshEntity& cell ); +}; + +#include "tnlDirectEikonalMethodsBase_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..c2983fac2c12e1b7791bd86973a712a5fcc6c948 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalMethodsBase_impl.h @@ -0,0 +1,233 @@ +/* + * File: tnlDirectEikonalMethodsBase_impl.h + * Author: oberhuber + * + * Created on July 14, 2016, 3:22 PM + */ + +#pragma once + +#include <core/tnlTypeInfo.h> +#include <functions/tnlFunctions.h> + +template< typename Real, + typename Device, + typename Index > +void +tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > >:: +initInterface( const MeshFunctionType& input, + MeshFunctionType& output, + InterfaceMapType& interfaceMap ) +{ + const MeshType& mesh = input.getMesh(); + typedef typename MeshType::Cell Cell; + Cell cell( mesh ); + for( cell.getCoordinates().x() = 1; + cell.getCoordinates().x() < mesh.getDimensions().x() - 1; + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + const RealType& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + const auto& neighbours = cell.getNeighbourEntities(); + //const IndexType& c = cell.getIndex(); + const IndexType e = neighbours.template getEntityIndex< 1 >(); + const IndexType w = neighbours.template getEntityIndex< -1 >(); + + if( c * input[ e ] <= 0 || c * input[ w ] <= 0 ) + { + output[ cell.getIndex() ] = c; + interfaceMap[ cell.getIndex() ] = true; + continue; + } + } + output[ cell.getIndex() ] = + c > 0 ? tnlTypeInfo< RealType >::getMaxValue() : + -tnlTypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + } +} + +template< typename Real, + typename Device, + typename Index > + template< typename MeshEntity > +void +tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > >:: +updateCell( MeshFunctionType& u, + const MeshEntity& cell ) +{ +} + + +template< typename Real, + typename Device, + typename Index > +void +tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > >:: +initInterface( const MeshFunctionType& input, + MeshFunctionType& output, + InterfaceMapType& interfaceMap ) +{ + const MeshType& mesh = input.getMesh(); + typedef typename MeshType::Cell Cell; + Cell cell( mesh ); + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + const RealType& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbours = cell.getNeighbourEntities(); + const IndexType e = neighbours.template getEntityIndex< 1, 0 >(); + const IndexType w = neighbours.template getEntityIndex< -1, 0 >(); + const IndexType n = neighbours.template getEntityIndex< 0, 1 >(); + const IndexType s = neighbours.template getEntityIndex< 0, -1 >(); + if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || + c * input[ n ] <= 0 || c * input[ s ] <= 0 ) + { + output[ cell.getIndex() ] = c; + interfaceMap[ cell.getIndex() ] = true; + continue; + } + } + output[ cell.getIndex() ] = + c > 0 ? tnlTypeInfo< RealType >::getMaxValue() : + -tnlTypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + } +} + +template< typename Real, + typename Device, + typename Index > + template< typename MeshEntity > +void +tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > >:: +updateCell( MeshFunctionType& u, + const MeshEntity& cell ) +{ + const auto& neighbourEntities = cell.template getNeighbourEntities< 2 >(); + const MeshType& mesh = cell.getMesh(); + + const RealType& h = mesh.getSpaceSteps().x(); + const RealType value = u( cell ); + Real a, b, tmp; + + if( cell.getCoordinates().x() == 0 ) + a = u[ neighbourEntities.template getEntityIndex< 1, 0 >() ]; + else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 ) + a = u[ neighbourEntities.template getEntityIndex< -1, 0 >() ]; + else + { + a = ArgAbsMin( u[ neighbourEntities.template getEntityIndex< -1, 0 >() ], + u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] ); + } + + if( cell.getCoordinates().y() == 0 ) + b = u[ neighbourEntities.template getEntityIndex< 0, 1 >()]; + else if( cell.getCoordinates().y() == mesh.getDimensions().y() - 1 ) + b = u[ neighbourEntities.template getEntityIndex< 0, -1 >() ]; + else + { + b = ArgAbsMin( u[ neighbourEntities.template getEntityIndex< 0, -1 >() ], + u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] ); + } + + if( fabs( a ) == tnlTypeInfo< Real >::getMaxValue() && + fabs( b ) == tnlTypeInfo< Real >::getMaxValue() ) + return; + if( fabs( a ) == tnlTypeInfo< Real >::getMaxValue() || + fabs( b ) == tnlTypeInfo< Real >::getMaxValue() || + fabs( a - b ) >= h ) + { + tmp = ArgAbsMin( a, b ) + sign( value ) * h; + /* std::cerr << "a = " << a << " b = " << b << " h = " << h + << " ArgAbsMin( a, b ) = " << ArgAbsMin( a, b ) << " sign( value ) = " << sign( value ) + << " sign( value ) * h = " << sign( value ) * h + << " ArgAbsMin( a, b ) + sign( value ) * h = " << ArgAbsMin( a, b ) + sign( value ) * h + << " tmp = " << tmp << std::endl; + tmp = ArgAbsMin( a, b ) + sign( value ) * h; + tmp = ArgAbsMin( a, b ) + sign( value ) * h; + tmp = ArgAbsMin( a, b ) + sign( value ) * h; + res = ArgAbsMin( a, b ) + sign( value ) * h; + std::cerr << " tmp = " << tmp << std::endl; + std::cerr << " res = " << res << std::endl;*/ + + } + else + tmp = 0.5 * ( a + b + sign( value ) * sqrt( 2.0 * h * h - ( a - b ) * ( a - b ) ) ); + + u[ cell.getIndex() ] = ArgAbsMin( value, tmp ); + //std::cerr << ArgAbsMin( value, tmp ) << " "; +} + + +template< typename Real, + typename Device, + typename Index > +void +tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > >:: +initInterface( const MeshFunctionType& input, + MeshFunctionType& output, + InterfaceMapType& interfaceMap ) +{ + const MeshType& mesh = input.getMesh(); + typedef typename MeshType::Cell Cell; + Cell cell( mesh ); + for( cell.getCoordinates().z() = 1; + cell.getCoordinates().z() < mesh.getDimensions().z() - 1; + cell.getCoordinates().z() ++ ) + for( cell.getCoordinates().y() = 1; + cell.getCoordinates().y() < mesh.getDimensions().y() - 1; + cell.getCoordinates().y() ++ ) + for( cell.getCoordinates().x() = 1; + cell.getCoordinates().x() < mesh.getDimensions().x() - 1; + cell.getCoordinates().x() ++ ) + { + cell.refresh(); + const RealType& c = input( cell ); + if( ! cell.isBoundaryEntity() ) + { + auto neighbours = cell.getNeighbourEntities(); + //const IndexType& c = cell.getIndex(); + const IndexType e = neighbours.template getEntityIndex< 1, 0, 0 >(); + const IndexType w = neighbours.template getEntityIndex< -1, 0, 0 >(); + const IndexType n = neighbours.template getEntityIndex< 0, 1, 0 >(); + const IndexType s = neighbours.template getEntityIndex< 0, -1, 0 >(); + const IndexType t = neighbours.template getEntityIndex< 0, 0, 1 >(); + const IndexType b = neighbours.template getEntityIndex< 0, 0, -1 >(); + + if( c * input[ e ] <= 0 || c * input[ w ] <= 0 || + c * input[ n ] <= 0 || c * input[ s ] <= 0 || + c * input[ t ] <= 0 || c * input[ b ] <= 0 ) + { + output[ cell.getIndex() ] = c; + interfaceMap[ cell.getIndex() ] = true; + continue; + } + } + output[ cell.getIndex() ] = + c > 0 ? tnlTypeInfo< RealType >::getMaxValue() : + -tnlTypeInfo< RealType >::getMaxValue(); + interfaceMap[ cell.getIndex() ] = false; + } +} + +template< typename Real, + typename Device, + typename Index > + template< typename MeshEntity > +void +tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > >:: +updateCell( MeshFunctionType& u, + const MeshEntity& cell ) +{ + +} diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h new file mode 100644 index 0000000000000000000000000000000000000000..f4baba1528165a9ca95bf18b68eaebe09d0c7848 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem.h @@ -0,0 +1,80 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnlFastSweepingMethod.h + * Author: oberhuber + * + * Created on July 13, 2016, 1:19 PM + */ + +#pragma once + +#include <problems/tnlPDEProblem.h> +#include <functions/tnlMeshFunction.h> +#include "tnlFastSweepingMethod.h" + +template< typename Mesh, + typename Anisotropy, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class tnlDirectEikonalProblem + : public tnlPDEProblem< Mesh, + TimeIndependentProblem, + Real, + typename Mesh::DeviceType, + Index > +{ + public: + + typedef Real RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef Index IndexType; + typedef tnlMeshFunction< Mesh > MeshFunctionType; + typedef tnlPDEProblem< Mesh, TimeIndependentProblem, RealType, DeviceType, IndexType > BaseType; + typedef Anisotropy AnisotropyType; + + using typename BaseType::MeshType; + using typename BaseType::DofVectorType; + using typename BaseType::MeshDependentDataType; + + static String getTypeStatic(); + + String getPrologHeader() const; + + void writeProlog( tnlLogger& logger, + const Config::ParameterContainer& parameters ) const; + + bool writeEpilog( tnlLogger& logger ); + + + bool setup( const Config::ParameterContainer& parameters ); + + IndexType getDofs( const MeshType& mesh ) const; + + void bindDofs( const MeshType& mesh, + const DofVectorType& dofs ); + + bool setInitialData( const Config::ParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshdependentData ); + + bool solve( const MeshType& mesh, + DofVectorType& dosf ); + + + protected: + + MeshFunctionType u; + + MeshFunctionType initialData; + + AnisotropyType anisotropy; + +}; + +#include "tnlDirectEikonalProblem_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..9dcf2fb5fa40b49462bed8ced05b4ebf605c38d6 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlDirectEikonalProblem_impl.h @@ -0,0 +1,125 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnlFastSweepingMethod_impl.h + * Author: oberhuber + * + * Created on July 13, 2016, 1:46 PM + */ + +#pragma once + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +String +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +getTypeStatic() +{ + +} + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +String +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +getPrologHeader() const +{ + return String( "Direct eikonal solver" ); +} + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +void +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +writeProlog( tnlLogger& logger, + const Config::ParameterContainer& parameters ) const +{ + +} + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +bool +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +writeEpilog( tnlLogger& logger ) +{ + return true; +} + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +bool +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +setup( const Config::ParameterContainer& parameters ) +{ + return true; +} + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +Index +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +getDofs( const MeshType& mesh ) const +{ + return mesh.template getEntitiesCount< typename MeshType::Cell >(); +} + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +void +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +bindDofs( const MeshType& mesh, + const DofVectorType& dofs ) +{ + this->u.bind( mesh, dofs ); +} + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +bool +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +setInitialData( const Config::ParameterContainer& parameters, + const MeshType& mesh, + DofVectorType& dofs, + MeshDependentDataType& meshdependentData ) +{ + String inputFile = parameters.getParameter< String >( "input-file" ); + this->initialData.setMesh( mesh ); + if( !this->initialData.boundLoad( inputFile ) ) + return false; + return true; +} + + +template< typename Mesh, + typename Anisotropy, + typename Real, + typename Index > +bool +tnlDirectEikonalProblem< Mesh, Anisotropy, Real, Index >:: +solve( const MeshType& mesh, + DofVectorType& dofs ) +{ + tnlFastSweepingMethod< MeshType, AnisotropyType > fsm; + fsm.solve( mesh, anisotropy, initialData ); +} diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h new file mode 100644 index 0000000000000000000000000000000000000000..04332b0f6c398adb36e2df4c338775575dbbcc9e --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod.h @@ -0,0 +1,141 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnlFastSweepingMethod.h + * Author: oberhuber + * + * Created on July 14, 2016, 10:04 AM + */ + +#pragma once + +#include <mesh/tnlGrid.h> +#include <functions/tnlConstantFunction.h> +#include "tnlDirectEikonalMethodsBase.h" + +template< typename Mesh, + typename Anisotropy = tnlConstantFunction< Mesh::getMeshDimensions(), typename Mesh::RealType > > +class tnlFastSweepingMethod +{ +}; + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +class tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy > + : public tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > > +{ + static_assert( std::is_same< Device, tnlHost >::value, "The fast sweeping method works only on CPU." ); + + public: + + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef Real RealType; + typedef tnlHost DeviceType; + typedef Index IndexType; + typedef Anisotropy AnisotropyType; + typedef tnlDirectEikonalMethodsBase< tnlGrid< 1, Real, Device, Index > > BaseType; + + using typename BaseType::InterfaceMapType; + using typename BaseType::MeshFunctionType; + + tnlFastSweepingMethod(); + + const IndexType& getMaxIterations() const; + + void setMaxIterations( const IndexType& maxIterations ); + + void solve( const MeshType& mesh, + const AnisotropyType& anisotropy, + MeshFunctionType& u ); + + + protected: + + const IndexType maxIterations; +}; + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +class tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy > + : public tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > > +{ + static_assert( std::is_same< Device, tnlHost >::value, "The fast sweeping method works only on CPU." ); + + public: + + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef Real RealType; + typedef tnlHost DeviceType; + typedef Index IndexType; + typedef Anisotropy AnisotropyType; + typedef tnlDirectEikonalMethodsBase< tnlGrid< 2, Real, Device, Index > > BaseType; + + using typename BaseType::InterfaceMapType; + using typename BaseType::MeshFunctionType; + + tnlFastSweepingMethod(); + + const IndexType& getMaxIterations() const; + + void setMaxIterations( const IndexType& maxIterations ); + + void solve( const MeshType& mesh, + const AnisotropyType& anisotropy, + MeshFunctionType& u ); + + + protected: + + const IndexType maxIterations; +}; + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +class tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy > + : public tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > > +{ + static_assert( std::is_same< Device, tnlHost >::value, "The fast sweeping method works only on CPU." ); + + public: + + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef Real RealType; + typedef tnlHost DeviceType; + typedef Index IndexType; + typedef Anisotropy AnisotropyType; + typedef tnlDirectEikonalMethodsBase< tnlGrid< 3, Real, Device, Index > > BaseType; + + using typename BaseType::InterfaceMapType; + using typename BaseType::MeshFunctionType; + + tnlFastSweepingMethod(); + + const IndexType& getMaxIterations() const; + + void setMaxIterations( const IndexType& maxIterations ); + + void solve( const MeshType& mesh, + const AnisotropyType& anisotropy, + MeshFunctionType& u ); + + + protected: + + const IndexType maxIterations; +}; + + + +#include "tnlFastSweepingMethod1D_impl.h" +#include "tnlFastSweepingMethod2D_impl.h" +#include "tnlFastSweepingMethod3D_impl.h" diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..050bc6075454c3d23685f25a6e9d607b36c88d73 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod1D_impl.h @@ -0,0 +1,70 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnlFastSweepingMethod2D_impl.h + * Author: oberhuber + * + * Created on July 14, 2016, 10:32 AM + */ + +#pragma once + +#include "tnlFastSweepingMethod.h" + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >:: +tnlFastSweepingMethod() +: maxIterations( 1 ) +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +const Index& +tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >:: +getMaxIterations() const +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +void +tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >:: +setMaxIterations( const IndexType& maxIterations ) +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +void +tnlFastSweepingMethod< tnlGrid< 1, Real, Device, Index >, Anisotropy >:: +solve( const MeshType& mesh, + const AnisotropyType& anisotropy, + MeshFunctionType& u ) +{ + MeshFunctionType aux; + InterfaceMapType interfaceMap; + aux.setMesh( mesh ); + interfaceMap.setMesh( mesh ); + std::cout << "Initiating the interface cells ..." << std::endl; + BaseType::initInterface( u, aux, interfaceMap ); + aux.save( "aux-ini.tnl" ); + +} + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..cc2cfe9401c54aa7bff5e88f4c9d9ecf40f919cd --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod2D_impl.h @@ -0,0 +1,141 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnlFastSweepingMethod2D_impl.h + * Author: oberhuber + * + * Created on July 14, 2016, 10:32 AM + */ + +#pragma once + +#include "tnlFastSweepingMethod.h" + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >:: +tnlFastSweepingMethod() +: maxIterations( 1 ) +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +const Index& +tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >:: +getMaxIterations() const +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +void +tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >:: +setMaxIterations( const IndexType& maxIterations ) +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +void +tnlFastSweepingMethod< tnlGrid< 2, Real, Device, Index >, Anisotropy >:: +solve( const MeshType& mesh, + const AnisotropyType& anisotropy, + MeshFunctionType& u ) +{ + MeshFunctionType aux; + InterfaceMapType interfaceMap; + aux.setMesh( mesh ); + interfaceMap.setMesh( mesh ); + std::cout << "Initiating the interface cells ..." << std::endl; + BaseType::initInterface( u, aux, interfaceMap ); + //aux.save( "aux-ini.tnl" ); + + typename MeshType::Cell cell( mesh ); + + IndexType iteration( 0 ); + while( iteration < this->maxIterations ) + { + + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x()++ ) + { + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + //aux.save( "aux-1.tnl" ); + + for( cell.getCoordinates().y() = 0; + cell.getCoordinates().y() < mesh.getDimensions().y(); + cell.getCoordinates().y()++ ) + { + for( cell.getCoordinates().x() = mesh.getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "2 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + //aux.save( "aux-2.tnl" ); + + for( cell.getCoordinates().y() = mesh.getDimensions().y() - 1; + cell.getCoordinates().y() >= 0 ; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = 0; + cell.getCoordinates().x() < mesh.getDimensions().x(); + cell.getCoordinates().x()++ ) + { + //std::cerr << "3 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + //aux.save( "aux-3.tnl" ); + + + for( cell.getCoordinates().y() = mesh.getDimensions().y() - 1; + cell.getCoordinates().y() >= 0; + cell.getCoordinates().y()-- ) + { + for( cell.getCoordinates().x() = mesh.getDimensions().x() - 1; + cell.getCoordinates().x() >= 0 ; + cell.getCoordinates().x()-- ) + { + //std::cerr << "4 -> "; + cell.refresh(); + if( ! interfaceMap( cell ) ) + this->updateCell( aux, cell ); + } + } + //aux.save( "aux-4.tnl" ); + iteration++; + } +} + diff --git a/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..f252537148b9968b1a84421da7ca563169525ae7 --- /dev/null +++ b/src/TNL/Experimental/Hamilton-Jacobi/Solvers/hamilton-jacobi/tnlFastSweepingMethod3D_impl.h @@ -0,0 +1,69 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +/* + * File: tnlFastSweepingMethod2D_impl.h + * Author: oberhuber + * + * Created on July 14, 2016, 10:32 AM + */ + +#pragma once + +#include "tnlFastSweepingMethod.h" + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >:: +tnlFastSweepingMethod() +: maxIterations( 1 ) +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +const Index& +tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >:: +getMaxIterations() const +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +void +tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >:: +setMaxIterations( const IndexType& maxIterations ) +{ + +} + +template< typename Real, + typename Device, + typename Index, + typename Anisotropy > +void +tnlFastSweepingMethod< tnlGrid< 3, Real, Device, Index >, Anisotropy >:: +solve( const MeshType& mesh, + const AnisotropyType& anisotropy, + MeshFunctionType& u ) +{ + MeshFunctionType aux; + InterfaceMapType interfaceMap; + aux.setMesh( mesh ); + interfaceMap.setMesh( mesh ); + std::cout << "Initiating the interface cells ..." << std::endl; + BaseType::initInterface( u, aux, interfaceMap ); + aux.save( "aux-ini.tnl" ); +} + diff --git a/src/TNL/File.h b/src/TNL/File.h index 9ea11d299a1d160eec562d156ab35d9c9112b8f4..1eea42eae61b67867bfeb7218b0a1801932f2c14 100644 --- a/src/TNL/File.h +++ b/src/TNL/File.h @@ -119,4 +119,3 @@ bool fileExists( const String& fileName ); } // namespace TNL #include <TNL/File_impl.h> - diff --git a/src/TNL/Functions/Analytic/Blob.h b/src/TNL/Functions/Analytic/Blob.h index 56c6e22b7eab001f03b45137b23ba6f2582d4798..c436254d6af11f4563a2eb49db8f33149f4bdd8e 100644 --- a/src/TNL/Functions/Analytic/Blob.h +++ b/src/TNL/Functions/Analytic/Blob.h @@ -1,5 +1,5 @@ /*************************************************************************** - ExpBump.h - description + Blob.h - description ------------------- begin : Dec 5, 2013 copyright : (C) 2013 by Tomas Oberhuber diff --git a/src/TNL/Functions/Analytic/Blob_impl.h b/src/TNL/Functions/Analytic/Blob_impl.h index c6d969d38527cfab69858a39f3d2fac3b340287e..00328818b266d1e9c40674e3701c86116391a9c4 100644 --- a/src/TNL/Functions/Analytic/Blob_impl.h +++ b/src/TNL/Functions/Analytic/Blob_impl.h @@ -1,5 +1,5 @@ /*************************************************************************** - ExpBump_impl.h - description + Blob_impl.h - description ------------------- begin : Dec 5, 2013 copyright : (C) 2013 by Tomas Oberhuber diff --git a/src/TNL/Functions/Analytic/CMakeLists.txt b/src/TNL/Functions/Analytic/CMakeLists.txt index 01c91a1542b9b1cfdbb1bae7c2e37c4ce44fdb91..744345453d919ac82f2ef2a39186774f90c1b652 100755 --- a/src/TNL/Functions/Analytic/CMakeLists.txt +++ b/src/TNL/Functions/Analytic/CMakeLists.txt @@ -7,13 +7,21 @@ SET( headers Blob.h ExpBump.h ExpBump_impl.h Flowerpot.h - Flowerpot_impl.h + Flowerpot_impl.h + Paraboloid.h + Paraboloid_impl.h + ParaboloidSDF.h + ParaboloidSDF_impl.h PseudoSquare.h PseudoSquare_impl.h SinBumps.h SinBumps_impl.h + SinBumpsSDF.h + SinBumpsSDF_impl.h SinWave.h SinWave_impl.h + SinWaveSDF.h + SinWaveSDF_impl.h Twins.h Twins_impl.h ) diff --git a/src/TNL/Functions/Analytic/Constant.h b/src/TNL/Functions/Analytic/Constant.h index dc12be876f6adc50d423940d1c13c194adb26563..8e20cc6d5c816149e0422e615e499390d16bcaa7 100644 --- a/src/TNL/Functions/Analytic/Constant.h +++ b/src/TNL/Functions/Analytic/Constant.h @@ -44,7 +44,7 @@ class Constant : public Domain< dimensions, NonspaceDomain > int YDiffOrder, int ZDiffOrder > #else - template< int XDiffOrder, + template< int XDiffOrder = 0, int YDiffOrder = 0, int ZDiffOrder = 0 > #endif diff --git a/src/TNL/Functions/Analytic/Paraboloid.h b/src/TNL/Functions/Analytic/Paraboloid.h new file mode 100644 index 0000000000000000000000000000000000000000..e07963155dbcf2a8c9d54028c7e3846c1100be2f --- /dev/null +++ b/src/TNL/Functions/Analytic/Paraboloid.h @@ -0,0 +1,168 @@ +/*************************************************************************** + Paraboloid.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Containers/StaticVector.h> +#include <TNL/Functions/Domain.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< int dimensions, + typename Real = double > +class ParaboloidBase : public Functions::Domain< dimensions, SpaceDomain > +{ + public: + + ParaboloidBase(); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + void setXCenter( const Real& waveLength ); + + Real getXCenter() const; + + void setYCenter( const Real& waveLength ); + + Real getYCenter() const; + + void setZCenter( const Real& waveLength ); + + Real getZCenter() const; + + void setCoefficient( const Real& coefficient ); + + Real getCoefficient() const; + + void setOffset( const Real& offset ); + + Real getOffset() const; + + protected: + + Real xCenter, yCenter, zCenter, coefficient, radius; +}; + +template< int Dimensions, typename Real > +class Paraboloid +{ +}; + +template< typename Real > +class Paraboloid< 1, Real > : public ParaboloidBase< 1, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 1, RealType > VertexType; + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const + { + return this->getPartialDerivative< 0, 0, 0 >( v, time ); + } + +}; + +template< typename Real > +class Paraboloid< 2, Real > : public ParaboloidBase< 2, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 2, RealType > VertexType; + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const + { + return this->getPartialDerivative< 0, 0, 0 >( v, time ); + } + +}; + +template< typename Real > +class Paraboloid< 3, Real > : public ParaboloidBase< 3, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 3, RealType > VertexType; + + + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const + { + return this->getPartialDerivative< 0, 0, 0 >( v, time ); + } + +}; + +template< int Dimensions, + typename Real > +std::ostream& operator << ( std::ostream& str, const Paraboloid< Dimensions, Real >& f ) +{ + str << "SDF Paraboloid function: amplitude = " << f.getCoefficient() + << " offset = " << f.getOffset(); + return str; +} + + } // namespace Analytic + } // namespace Functions +} // namespace TNL + +#include <TNL/Functions/Analytic/Paraboloid_impl.h> + diff --git a/src/TNL/Functions/Analytic/ParaboloidSDF.h b/src/TNL/Functions/Analytic/ParaboloidSDF.h new file mode 100644 index 0000000000000000000000000000000000000000..4d3177e365cfd46b45d57064d39e57ee163fd74a --- /dev/null +++ b/src/TNL/Functions/Analytic/ParaboloidSDF.h @@ -0,0 +1,160 @@ +/*************************************************************************** + ParaboloidSDF.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Containers/StaticVector.h> +#include <TNL/Functions/Domain.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< int dimensions, + typename Real = double > +class ParaboloidSDFBase : public Functions::Domain< dimensions, SpaceDomain > +{ + public: + + ParaboloidSDFBase(); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + void setXCenter( const Real& waveLength ); + + Real getXCenter() const; + + void setYCenter( const Real& waveLength ); + + Real getYCenter() const; + + void setZCenter( const Real& waveLength ); + + Real getZCenter() const; + + void setCoefficient( const Real& coefficient ); + + Real getCoefficient() const; + + void setOffset( const Real& offset ); + + Real getOffset() const; + + protected: + + Real xCenter, yCenter, zCenter, coefficient, radius; +}; + +template< int Dimensions, typename Real > +class ParaboloidSDF +{ +}; + +template< typename Real > +class ParaboloidSDF< 1, Real > : public ParaboloidSDFBase< 1, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 1, RealType > VertexType; + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< typename Real > +class ParaboloidSDF< 2, Real > : public ParaboloidSDFBase< 2, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 2, RealType > VertexType; + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< typename Real > +class ParaboloidSDF< 3, Real > : public ParaboloidSDFBase< 3, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 3, RealType > VertexType; + + + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< int Dimensions, + typename Real > +std::ostream& operator << ( std::ostream& str, const ParaboloidSDF< Dimensions, Real >& f ) +{ + str << "SDF Paraboloid SDF function: amplitude = " << f.getCoefficient() + << " offset = " << f.getOffset(); + return str; +} + + } // namespace Analytic + } // namespace Functions +} // namespace TNL + + +#include <TNL/Functions/Analytic/ParaboloidSDF_impl.h> + diff --git a/src/TNL/Functions/Analytic/ParaboloidSDF_impl.h b/src/TNL/Functions/Analytic/ParaboloidSDF_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..a4c1be5a03c72943502974ae7987139b791c6c9c --- /dev/null +++ b/src/TNL/Functions/Analytic/ParaboloidSDF_impl.h @@ -0,0 +1,163 @@ +/*************************************************************************** + ParaboloidSDFSDF_impl.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Analytic/ParaboloidSDF.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< int dimensions, typename Real > +ParaboloidSDFBase< dimensions, Real >::ParaboloidSDFBase() +: xCenter( 0 ), yCenter( 0 ), zCenter( 0 ), + coefficient( 1 ), radius ( 0 ) +{ +} + +template< int dimensions, typename Real > +bool ParaboloidSDFBase< dimensions, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix) +{ + this->xCenter = parameters.getParameter< double >( "x-center" ); + this->yCenter = parameters.getParameter< double >( "y-center" ); + this->zCenter = parameters.getParameter< double >( "z-center" ); + this->coefficient = parameters.getParameter< double >( "coefficient" ); + this->radius = parameters.getParameter< double >( "radius" ); + + return true; +} + +template< int dimensions, typename Real > +void ParaboloidSDFBase< dimensions, Real >::setXCenter( const Real& xCenter ) +{ + this->xCenter = xCenter; +} + +template< int dimensions, typename Real > +Real ParaboloidSDFBase< dimensions, Real >::getXCenter() const +{ + return this->xCenter; +} + +template< int dimensions, typename Real > +void ParaboloidSDFBase< dimensions, Real >::setYCenter( const Real& yCenter ) +{ + this->yCenter = yCenter; +} + +template< int dimensions, typename Real > +Real ParaboloidSDFBase< dimensions, Real >::getYCenter() const +{ + return this->yCenter; +} +template< int dimensions, typename Real > +void ParaboloidSDFBase< dimensions, Real >::setZCenter( const Real& zCenter ) +{ + this->zCenter = zCenter; +} + +template< int dimensions, typename Real > +Real ParaboloidSDFBase< dimensions, Real >::getZCenter() const +{ + return this->zCenter; +} + +template< int dimensions, typename Real > +void ParaboloidSDFBase< dimensions, Real >::setCoefficient( const Real& amplitude ) +{ + this->coefficient = coefficient; +} + +template< int dimensions, typename Real > +Real ParaboloidSDFBase< dimensions, Real >::getCoefficient() const +{ + return this->coefficient; +} + +template< int dimensions, typename Real > +void ParaboloidSDFBase< dimensions, Real >::setOffset( const Real& offset ) +{ + this->radius = offset; +} + +template< int dimensions, typename Real > +Real ParaboloidSDFBase< dimensions, Real >::getOffset() const +{ + return this->radius; +} + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +ParaboloidSDF< 1, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const Real& x = v.x(); + if( YDiffOrder != 0 || ZDiffOrder != 0 ) + return 0.0; + if( XDiffOrder == 0 ) + return ::sqrt( ( x - this -> xCenter ) * ( x - this -> xCenter ) ) - this->radius; + if( XDiffOrder == 1 ) + return 1.0; + return 0.0; +} + + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +ParaboloidSDF< 2, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const Real& x = v.x(); + const Real& y = v.y(); + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + { + return ::sqrt ( ( x - this -> xCenter ) * ( x - this -> xCenter ) + + ( y - this -> yCenter ) * ( y - this -> yCenter ) ) - this->radius; + } + return 0.0; +} + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +ParaboloidSDF< 3, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const Real& x = v.x(); + const Real& y = v.y(); + const Real& z = v.z(); + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + { + return ::sqrt( ( x - this -> xCenter ) * ( x - this -> xCenter ) + + ( y - this -> yCenter ) * ( y - this -> yCenter ) + + ( z - this -> zCenter ) * ( z - this -> zCenter ) ) - this->radius; + } + return 0.0; +} + + } //namespace Analytic + } // namepsace Functions +} // namespace TNL diff --git a/src/TNL/Functions/Analytic/Paraboloid_impl.h b/src/TNL/Functions/Analytic/Paraboloid_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..24b8a7a6aa5cdbbcf4496678c2f5c4e12fc7b63e --- /dev/null +++ b/src/TNL/Functions/Analytic/Paraboloid_impl.h @@ -0,0 +1,185 @@ +/*************************************************************************** + Paraboloid_impl.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Analytic/Paraboloid.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< int dimensions, typename Real > +ParaboloidBase< dimensions, Real >::ParaboloidBase() +: xCenter( 0 ), yCenter( 0 ), zCenter( 0 ), + coefficient( 1 ), radius ( 0 ) +{ +} + +template< int dimensions, typename Real > +bool ParaboloidBase< dimensions, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix) +{ + this->xCenter = parameters.getParameter< double >( "x-center" ); + this->yCenter = parameters.getParameter< double >( "y-center" ); + this->zCenter = parameters.getParameter< double >( "z-center" ); + this->coefficient = parameters.getParameter< double >( "coefficient" ); + this->radius = parameters.getParameter< double >( "radius" ); + + return true; +} + +template< int dimensions, typename Real > +void ParaboloidBase< dimensions, Real >::setXCenter( const Real& xCenter ) +{ + this->xCenter = xCenter; +} + +template< int dimensions, typename Real > +Real ParaboloidBase< dimensions, Real >::getXCenter() const +{ + return this->xCenter; +} + +template< int dimensions, typename Real > +void ParaboloidBase< dimensions, Real >::setYCenter( const Real& yCenter ) +{ + this->yCenter = yCenter; +} + +template< int dimensions, typename Real > +Real ParaboloidBase< dimensions, Real >::getYCenter() const +{ + return this->yCenter; +} +template< int dimensions, typename Real > +void ParaboloidBase< dimensions, Real >::setZCenter( const Real& zCenter ) +{ + this->zCenter = zCenter; +} + +template< int dimensions, typename Real > +Real ParaboloidBase< dimensions, Real >::getZCenter() const +{ + return this->zCenter; +} + +template< int dimensions, typename Real > +void ParaboloidBase< dimensions, Real >::setCoefficient( const Real& amplitude ) +{ + this->coefficient = coefficient; +} + +template< int dimensions, typename Real > +Real ParaboloidBase< dimensions, Real >::getCoefficient() const +{ + return this->coefficient; +} + +template< int dimensions, typename Real > +void ParaboloidBase< dimensions, Real >::setOffset( const Real& offset ) +{ + this->radius = offset; +} + +template< int dimensions, typename Real > +Real ParaboloidBase< dimensions, Real >::getOffset() const +{ + return this->radius; +} + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +Paraboloid< 1, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const Real& x = v.x(); + if( YDiffOrder != 0 || ZDiffOrder != 0 ) + return 0.0; + if( XDiffOrder == 0 ) + return this->coefficient * ( ( x - this -> xCenter ) * ( x - this -> xCenter ) - this->radius*this->radius ); + if( XDiffOrder == 1 ) + return 2.0 * this->coefficient * ( x - this -> xCenter ); + return 0.0; +} + + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +Paraboloid< 2, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const Real& x = v.x(); + const Real& y = v.y(); + if( ZDiffOrder != 0 ) + return 0.0; + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + { + return this->coefficient * ( ( x - this -> xCenter ) * ( x - this -> xCenter ) + + ( y - this -> yCenter ) * ( y - this -> yCenter ) - this->radius*this->radius ); + } + if( XDiffOrder == 1 && YDiffOrder == 0) + return 2.0 * this->coefficient * ( x - this -> xCenter ); + if( YDiffOrder == 1 && XDiffOrder == 0) + return 2.0 * this->coefficient * ( y - this -> yCenter ); + if( XDiffOrder == 2 && YDiffOrder == 0) + return 2.0 * this->coefficient; + if( YDiffOrder == 2 && XDiffOrder == 0) + return 2.0 * this->coefficient; + return 0.0; +} + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +Paraboloid< 3, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const Real& x = v.x(); + const Real& y = v.y(); + const Real& z = v.z(); + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + { + return this->coefficient * ( ( x - this -> xCenter ) * ( x - this -> xCenter ) + + ( y - this -> yCenter ) * ( y - this -> yCenter ) + + ( z - this -> zCenter ) * ( z - this -> zCenter ) - this->radius*this->radius ); + } + if( XDiffOrder == 1 && YDiffOrder == 0 && ZDiffOrder == 0) + return 2.0 * this->coefficient * ( x - this -> xCenter ); + if( YDiffOrder == 1 && XDiffOrder == 0 && ZDiffOrder == 0) + return 2.0 * this->coefficient * ( y - this -> yCenter ); + if( ZDiffOrder == 1 && XDiffOrder == 0 && YDiffOrder == 0) + return 2.0 * this->coefficient * ( z - this -> zCenter ); + if( XDiffOrder == 2 && YDiffOrder == 0 && ZDiffOrder == 0) + return 2.0 * this->coefficient; + if( YDiffOrder == 2 && XDiffOrder == 0 && ZDiffOrder == 0) + return 2.0 * this->coefficient; + if( ZDiffOrder == 2 && XDiffOrder == 0 && YDiffOrder == 0) + return 2.0 * this->coefficient; + return 0.0; +} + + } // namespace Analytic + } // namedspace Functions +} // namespace TNL diff --git a/src/TNL/Functions/Analytic/PseudoSquare.h b/src/TNL/Functions/Analytic/PseudoSquare.h index 26d3086f23b1fa855acec067dc0b72a5ba878e1e..7f58906597338b78588cdf6e40940bd6b3b87d0b 100644 --- a/src/TNL/Functions/Analytic/PseudoSquare.h +++ b/src/TNL/Functions/Analytic/PseudoSquare.h @@ -1,5 +1,5 @@ /*************************************************************************** - ExpBump.h - description + PseudoSquare.h - description ------------------- begin : Dec 5, 2013 copyright : (C) 2013 by Tomas Oberhuber diff --git a/src/TNL/Functions/Analytic/PseudoSquare_impl.h b/src/TNL/Functions/Analytic/PseudoSquare_impl.h index 378e11ac11c720b573a46d922b4d66cdb63ee66b..ab81b85f0b3144f4cb8507f8a83cdfd1dbedf097 100644 --- a/src/TNL/Functions/Analytic/PseudoSquare_impl.h +++ b/src/TNL/Functions/Analytic/PseudoSquare_impl.h @@ -1,5 +1,5 @@ /*************************************************************************** - ExpBump_impl.h - description + PseudoSquare_impl.h - description ------------------- begin : Dec 5, 2013 copyright : (C) 2013 by Tomas Oberhuber diff --git a/src/TNL/Functions/Analytic/SDFSchemeTest.h b/src/TNL/Functions/Analytic/SDFSchemeTest.h new file mode 100644 index 0000000000000000000000000000000000000000..d3720fcb12f2a70c0593a1eafe7eeb8d00a58b0c --- /dev/null +++ b/src/TNL/Functions/Analytic/SDFSchemeTest.h @@ -0,0 +1,108 @@ +/*************************************************************************** + SDFSchemeTest.h - description + ------------------- + begin : Nov 19, 2013 + copyright : (C) 2013 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Containers/StaticVector.h> +#include <functions/tnlSDFSinWaveFunction.h> +#include <functions/tnlSDFSinWaveFunctionSDF.h> +#include <functions/tnlSDFSinBumps.h> +#include <functions/tnlSDFSinBumpsSDF.h> +#include <functions/tnlExpBumpFunction.h> +#include <functions/tnlSDFParaboloid.h> +#include <functions/tnlSDFParaboloidSDF.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< typename function, typename Real = double > +class SDFSchemeTestBase +{ + public: + + SDFSchemeTestBase(); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + + function f; +}; + +template< typename function, int Dimensions, typename Real > +class SDFSchemeTest +{ + +}; + +template< typename function, int Dimensions, typename Real > +class SDFSchemeTest< function, 1, Real > : public SDFSchemeTestBase< function, Real > +{ + public: + + + enum { Dimensions = 1 }; + typedef Vertex VertexType; + typedef typename VertexType::RealType RealType; + + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + RealType getValue( const VertexType& v, + const Real& time = 0.0 ) const; + + + +}; + +template< typename function, int Dimensions, typename Real > +class SDFSchemeTest< function, 2, Real > : public SDFSchemeTestBase< function, Real > +{ + public: + + + enum { Dimensions = 2 }; + typedef Vertex VertexType; + typedef typename VertexType::RealType RealType; + + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + RealType getValue( const VertexType& v, + const Real& time = 0.0 ) const; + + +}; + +template< typename function, int Dimensions, typename Real > +class SDFSchemeTest< function, 3, Real > : public SDFSchemeTestBase< function, Real > +{ + public: + + + enum { Dimensions = 3 }; + typedef Vertex VertexType; + typedef typename VertexType::RealType RealType; + + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + RealType getValue( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + + } // namespace Analytic + } // namespace Functions +} // namespace TNL + +#include <functions/SDFSchemeTest_impl.h> diff --git a/src/TNL/Functions/Analytic/SDFSchemeTest_impl.h b/src/TNL/Functions/Analytic/SDFSchemeTest_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..c2be9ef3433847562134f29aff2680d410378e3b --- /dev/null +++ b/src/TNL/Functions/Analytic/SDFSchemeTest_impl.h @@ -0,0 +1,78 @@ +/*************************************************************************** + SDFSchemeTest_impl.h - description + ------------------- + begin : Nov 19, 2013 + copyright : (C) 2013 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <functions/SDFSchemeTest.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< typename function, typename Real > +SDFSchemeTestBase< function, Real >::SDFSchemeTestBase() +{ +} + +template< typename function, typename Real > +bool SDFSchemeTestBase< function, Real >::v( const Config::ParameterContainer& parameters, + const String& prefix = "" ) +{ + f.init(parameters); + + return true; +} + + + +template< typename function, int Dimensions, typename Real > + template< int XDiffOrder, int YDiffOrder, int ZDiffOrder > +Real SDFSchemeTest< function, 1, Real >::getValue( const Vertex& v, + const Real& time = 0.0 ) const +{ + if( YDiffOrder != 0 || ZDiffOrder != 0 || XDiffOrder != 0 ) + return 0.0; + + return sign( this->f.getValue<0,0,0>(v))* + ( 1-sqrt(this->f.getValue<1,0,0>(v)*this->f.getValue<1,0,0>(v)) ); +} + + +template< typename function, int Dimensions, typename Real > + template< int XDiffOrder, int YDiffOrder, int ZDiffOrder > +Real SDFSchemeTest< function, 2, Real >::getValue( const Vertex& v, + const Real& time = 0.0 ) const +{ + if( YDiffOrder != 0 || ZDiffOrder != 0 || XDiffOrder != 0 ) + return 0.0; + + return sign( this->f.getValue<0,0,0>(v))* + ( 1-sqrt(this->f.getValue<1,0,0>(v)*this->f.getValue<1,0,0>(v) + + this->f.getValue<0,1,0>(v)*this->f.getValue<0,1,0>(v)) ); +} + +template< typename function, int Dimensions, typename Real > + template< int XDiffOrder, int YDiffOrder, int ZDiffOrder > +Real SDFSchemeTest< function, 3, Real >::getValue( const Vertex& v, + const Real& time = 0.0 ) const +{ + if( YDiffOrder != 0 || ZDiffOrder != 0 || XDiffOrder != 0 ) + return 0.0; + + return sign( this->f.getValue<0,0,0>(v))* + ( 1.0-sqrt(this->f.getValue<1,0,0>(v)*this->f.getValue<1,0,0>(v) + + this->f.getValue<0,1,0>(v)*this->f.getValue<0,1,0>(v) + + this->f.getValue<0,0,1>(v)*this->f.getValue<0,0,1>(v)) ); +} + + } // namespace Analytic + } // namespace Functions +} // namespace TNL + diff --git a/src/TNL/Functions/Analytic/SinBumps.h b/src/TNL/Functions/Analytic/SinBumps.h index d3cc0434582e8b0c6df273f3063f382d1bef3ebb..ea37dec8e547f4a11b1b9c422ab6fe78b8694a20 100644 --- a/src/TNL/Functions/Analytic/SinBumps.h +++ b/src/TNL/Functions/Analytic/SinBumps.h @@ -8,7 +8,11 @@ /* See Copyright Notice in tnl/Copyright */ -#pragma once +/**** + * Tomas Sobotik + */ + +#pragma once #include <TNL/Config/ParameterContainer.h> #include <TNL/Containers/StaticVector.h> @@ -39,11 +43,15 @@ class SinBumpsBase : public Domain< Vertex::size, SpaceDomain > const VertexType& getPhase() const; + void setWavesNumber( const VertexType& wavesNumber ); + + const VertexType& getWavesNumber() const; + protected: RealType amplitude; - VertexType waveLength, phase; + VertexType waveLength, phase, wavesNumber; }; template< int Dimensions, typename Real > @@ -59,7 +67,6 @@ class SinBumps< 1, Real > : public SinBumpsBase< Containers::StaticVector< 1, R typedef Real RealType; typedef Containers::StaticVector< 1, RealType > VertexType; - SinBumps(); bool setup( const Config::ParameterContainer& parameters, @@ -91,7 +98,6 @@ class SinBumps< 2, Real > : public SinBumpsBase< Containers::StaticVector< 2, Re typedef Real RealType; typedef Containers::StaticVector< 2, RealType > VertexType; - SinBumps(); @@ -163,4 +169,4 @@ std::ostream& operator << ( std::ostream& str, const SinBumps< Dimensions, Real } // namespace Functions } // namespace TNL -#include <TNL/Functions/Analytic/SinBumps_impl.h> \ No newline at end of file +#include <TNL/Functions/Analytic/SinBumps_impl.h> diff --git a/src/TNL/Functions/Analytic/SinBumpsSDF.h b/src/TNL/Functions/Analytic/SinBumpsSDF.h new file mode 100644 index 0000000000000000000000000000000000000000..e402872d27958478e5adca8a0d17e6f24e12fa2e --- /dev/null +++ b/src/TNL/Functions/Analytic/SinBumpsSDF.h @@ -0,0 +1,172 @@ +/*************************************************************************** + SinBumpsSDF.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Containers/StaticVector.h> +#include <TNL/Functions/Domain.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + + +template< typename Vertex > +class SinBumpsSDFBase : public Domain< Vertex::size, SpaceDomain > +{ + public: + + typedef Vertex VertexType; + typedef typename Vertex::RealType RealType; + enum { Dimensions = VertexType::size }; + + void setWaveLength( const VertexType& waveLength ); + + const VertexType& getWaveLength() const; + + void setAmplitude( const RealType& amplitude ); + + const RealType& getAmplitude() const; + + void setPhase( const VertexType& phase ); + + const VertexType& getPhase() const; + + void setWavesNumber( const VertexType& wavesNumber ); + + const VertexType& getWavesNumber() const; + + protected: + + RealType amplitude; + + VertexType waveLength, phase, wavesNumber; +}; + +template< int Dimensions, typename Real > +class SinBumpsSDF +{ +}; + +template< typename Real > +class SinBumpsSDF< 1, Real > : public SinBumpsSDFBase< Containers::StaticVector< 1, Real > > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 1, RealType > VertexType; + + + SinBumpsSDF(); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< typename Real > +class SinBumpsSDF< 2, Real > : public SinBumpsSDFBase< Containers::StaticVector< 2, Real > > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 2, RealType > VertexType; + + + SinBumpsSDF(); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< typename Real > +class SinBumpsSDF< 3, Real > : public SinBumpsSDFBase< Containers::StaticVector< 3, Real > > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 3, RealType > VertexType; + + SinBumpsSDF(); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< int Dimensions, + typename Real > +std::ostream& operator << ( std::ostream& str, const SinBumpsSDF< Dimensions, Real >& f ) +{ + str << "SDF Sin Bumps SDF. function: amplitude = " << f.getAmplitude() + << " wavelength = " << f.getWaveLength() + << " phase = " << f.getPhase(); + return str; +} + + + } // namespace Analytic + } // namespace Functions +} // namespace TNL + +#include <TNL/Functions/Analytic/SinBumpsSDF_impl.h> diff --git a/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h b/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..6b38ae51238dfdca01404bcbb4002a663f409211 --- /dev/null +++ b/src/TNL/Functions/Analytic/SinBumpsSDF_impl.h @@ -0,0 +1,242 @@ +/*************************************************************************** + SinBumpsSDFSDF_impl.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Analytic/SinBumpsSDF.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< typename Vertex > +void SinBumpsSDFBase< Vertex >::setWaveLength( const Vertex& waveLength ) +{ + this->waveLength = waveLength; +} + +template< typename Vertex > +const Vertex& SinBumpsSDFBase< Vertex >::getWaveLength() const +{ + return this->waveLength; +} + +template< typename Vertex > +void SinBumpsSDFBase< Vertex >::setAmplitude( const typename Vertex::RealType& amplitude ) +{ + this->amplitude = amplitude; +} + +template< typename Vertex > +const typename Vertex::RealType& SinBumpsSDFBase< Vertex >::getAmplitude() const +{ + return this->amplitude; +} + +template< typename Vertex > +void SinBumpsSDFBase< Vertex >::setPhase( const Vertex& phase ) +{ + this->phase = phase; +} + +template< typename Vertex > +const Vertex& SinBumpsSDFBase< Vertex >::getPhase() const +{ + return this->phase; +} + +/*** + * 1D + */ + +template< typename Real > +SinBumpsSDF< 1, Real >::SinBumpsSDF() +{ +} + +template< typename Real > +bool SinBumpsSDF< 1, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix) +{ + this->amplitude = parameters.getParameter< double >( prefix+"amplitude" ); + this->waveLength.x() = parameters.getParameter< double >( prefix+"wave-length-x" ); + while(this->waveLength.x() > 2.0*M_PI) + this->waveLength.x() -= 2.0*M_PI; + this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) ); + this->phase.x() = parameters.getParameter< double >( prefix+"phase-x" ); + return true; +} + + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +__cuda_callable__ +Real +SinBumpsSDF< 1, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const RealType& x = v.x(); + RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / ( 2.0*M_PI ); + if( this->wavesNumber.x() != 0.0 && xp > this->wavesNumber.x() * this->waveLength.x() ) + return 0.0; + if( YDiffOrder != 0 || ZDiffOrder != 0 ) + return 0.0; + if( XDiffOrder == 0 ) + return sign( xp - round( (2.0 * xp ) / this->waveLength.x() ) * this->waveLength.x() / 2.0 ) + * ( xp- round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0) + * sign( ::sin(this-> phase.x() + 2.0 * M_PI * x / this->waveLength.x())); + if( XDiffOrder == 1 ) + return 1.0; + return 0.0; +} + +/**** + * 2D + */ + +template< typename Real > +SinBumpsSDF< 2, Real >::SinBumpsSDF() +{ +} + +template< typename Real > +bool SinBumpsSDF< 2, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + this->amplitude = parameters.getParameter< double >( prefix+"amplitude" ); + this->waveLength.x() = parameters.getParameter< double >( prefix+"wave-length-x" ); + this->waveLength.y() = parameters.getParameter< double >( prefix+"wave-length-y" ); + while(this->waveLength.x() > 2.0*M_PI) + this->waveLength.x() -= 2.0*M_PI; + while(this->waveLength.y() > 2.0*M_PI) + this->waveLength.y() -= 2.0*M_PI; + this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) ); + this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) ); + this->phase.x() = parameters.getParameter< double >( prefix+"phase-x" ); + this->phase.y() = parameters.getParameter< double >( prefix+"phase-y" ); + return true; +} + + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +__cuda_callable__ +Real +SinBumpsSDF< 2, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const RealType& x = v.x(); + const RealType& y = v.y(); + RealType xp = ::sqrt(x*x) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI); + RealType yp = ::sqrt(y*y) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI); + if( ( xp > this->wavesNumber.x()*this->waveLength.x() && this->wavesNumber.x() != 0.0 ) || + ( yp > this->wavesNumber.y()*this->waveLength.y() && this->wavesNumber.y() != 0.0 ) ) + return 0.0; + const RealType sx = sign(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0) + *(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0); + const RealType sy = sign(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0) + *(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0); + RealType sxy; + if(sx < sy) + sxy = sx; + else + sxy = sy; + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + { + return sxy * sign( ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) + * ::sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) ); + } + return 0.0; +} + +/**** + * 3D + */ + +template< typename Real > +SinBumpsSDF< 3, Real >::SinBumpsSDF() +{ +} + +template< typename Real > +bool SinBumpsSDF< 3, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + this->amplitude = parameters.getParameter< double >( prefix+"amplitude" ); + this->waveLength.x() = parameters.getParameter< double >( prefix+"wave-length-x" ); + this->waveLength.y() = parameters.getParameter< double >( prefix+"wave-length-y" ); + this->waveLength.z() = parameters.getParameter< double >( prefix+"wave-length-z" ); + while(this->waveLength.x() > 2.0*M_PI) + this->waveLength.x() -= 2.0*M_PI; + while(this->waveLength.y() > 2.0*M_PI) + this->waveLength.y() -= 2.0*M_PI; + while(this->waveLength.z() > 2.0*M_PI) + this->waveLength.z() -= 2.0*M_PI; + this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) ); + this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) ); + this->wavesNumber.z() = ceil( parameters.getParameter< double >( prefix+"waves-number-z" ) ); + this->phase.x() = parameters.getParameter< double >( prefix+"phase-x" ); + this->phase.y() = parameters.getParameter< double >( prefix+"phase-y" ); + this->phase.z() = parameters.getParameter< double >(prefix+"phase-z" ); + return true; +} + + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +__cuda_callable__ +Real +SinBumpsSDF< 3, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const RealType& x = v.x(); + const RealType& y = v.y(); + const RealType& z = v.z(); + RealType xp = ::sqrt(x*x) + sign(x)*(this->phase.x())*(this->waveLength.x())/(2.0*M_PI); + RealType yp = ::sqrt(y*y) + sign(y)*(this->phase.y())*(this->waveLength.y())/(2.0*M_PI); + RealType zp = ::sqrt(z*z) + sign(z)*(this->phase.z())*(this->waveLength.z())/(2.0*M_PI); + if ( ( xp > this->wavesNumber.x()*this->waveLength.x() && this->wavesNumber.x() != 0.0 ) || + (yp > this->wavesNumber.y()*this->waveLength.y() && this->wavesNumber.y() != 0.0 ) || + (::sqrt(z*z) > this->wavesNumber.z()*this->waveLength.z() && this->wavesNumber.z() != 0.0 ) ) + return 0.0; + const RealType sx = sign(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0) + *(xp - round((2.0 * xp)/this->waveLength.x())* this->waveLength.x()/2.0); + const RealType sy = sign(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0) + *(yp - round((2.0 * yp)/this->waveLength.y())* this->waveLength.y()/2.0); + const RealType sz = sign(zp - round((2.0 * zp)/this->waveLength.z())* this->waveLength.z()/2.0) + *(zp - round((2.0 * zp)/this->waveLength.z())* this->waveLength.z()/2.0); + RealType sxyz; + if(sx <= sy && sx <= sz) + sxyz = sx; + else if ( sy <= sx && sy <= sz) + sxyz = sy; + else + sxyz = sz; + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + { + return sxyz * sign( ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) + * ::sin( this->phase.y() + 2.0 * M_PI * y / this->waveLength.y() ) + * ::sin( this->phase.z() + 2.0 * M_PI * z / this->waveLength.z() ) ); + } + return 0.0; +} + + } // namespace Analytic + } // namespace Fucntions +} // namespace TNL \ No newline at end of file diff --git a/src/TNL/Functions/Analytic/SinBumps_impl.h b/src/TNL/Functions/Analytic/SinBumps_impl.h index 8ae3eeb6abdce64ee0db3df89c5e59ada351f58b..337b7db27296a1f72ae3d874f93a6979fb4fc434 100644 --- a/src/TNL/Functions/Analytic/SinBumps_impl.h +++ b/src/TNL/Functions/Analytic/SinBumps_impl.h @@ -8,6 +8,9 @@ /* See Copyright Notice in tnl/Copyright */ +/**** + * Tomas Sobotik + */ #pragma once #include <TNL/Functions/Analytic/SinBumps.h> @@ -52,10 +55,21 @@ const Vertex& SinBumpsBase< Vertex >::getPhase() const return this->phase; } +template< typename Vertex > +void SinBumpsBase< Vertex >::setWavesNumber( const Vertex& wavesNumber ) +{ + this->wavesNumber = wavesNumber; +} + +template< typename Vertex > +const Vertex& SinBumpsBase< Vertex >::getWavesNumber() const +{ + return this->wavesNumber; +} + /*** * 1D */ - template< typename Real > SinBumps< 1, Real >::SinBumps() { @@ -68,6 +82,7 @@ bool SinBumps< 1, Real >::setup( const Config::ParameterContainer& parameters, this->amplitude = parameters.getParameter< double >( prefix + "amplitude" ); this->waveLength.x() = parameters.getParameter< double >( prefix + "wave-length-x" ); this->phase.x() = parameters.getParameter< double >( prefix + "phase-x" ); + this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) ); return true; } @@ -82,9 +97,14 @@ SinBumps< 1, Real >:: getPartialDerivative( const VertexType& v, const Real& time ) const { - const RealType& x = v.x(); if( YDiffOrder != 0 || ZDiffOrder != 0 ) return 0.0; + + const RealType& x = v.x(); + const RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI); + if( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() ) + return 0.0; + if( XDiffOrder == 0 ) return this->amplitude * ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ); if( XDiffOrder == 1 ) @@ -108,7 +128,6 @@ operator()( const VertexType& v, /**** * 2D */ - template< typename Real > SinBumps< 2, Real >::SinBumps() { @@ -123,10 +142,11 @@ bool SinBumps< 2, Real >::setup( const Config::ParameterContainer& parameters, this->waveLength.y() = parameters.getParameter< double >( prefix + "wave-length-y" ); this->phase.x() = parameters.getParameter< double >( prefix + "phase-x" ); this->phase.y() = parameters.getParameter< double >( prefix + "phase-y" ); + this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) ); + this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) ); return true; } - template< typename Real > template< int XDiffOrder, int YDiffOrder, @@ -137,10 +157,18 @@ SinBumps< 2, Real>:: getPartialDerivative( const VertexType& v, const Real& time ) const { + if( ZDiffOrder != 0 ) + return 0.0; + const RealType& x = v.x(); const RealType& y = v.y(); - if( ZDiffOrder != 0 ) + const RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI); + const RealType yp = ::fabs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI); + //std::cerr << "this->wavesNumber.x() = " << this->wavesNumber.x() << "fabs( x ) = " << fabs( x ) << " 2.0*M_PI * this->waveLength.x() * this->wavesNumber.x() = " << 2.0*M_PI * this->waveLength.x() * this->wavesNumber.x() << std::endl; + if( ( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() ) || + ( this->wavesNumber.y() != 0.0 && yp > this->waveLength.y() * this->wavesNumber.y() ) ) return 0.0; + if( XDiffOrder == 0 && YDiffOrder == 0 ) return this->amplitude * ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) * @@ -171,7 +199,6 @@ operator()( const VertexType& v, /**** * 3D */ - template< typename Real > SinBumps< 3, Real >::SinBumps() { @@ -188,10 +215,12 @@ bool SinBumps< 3, Real >::setup( const Config::ParameterContainer& parameters, this->phase.x() = parameters.getParameter< double >( prefix + "phase-x" ); this->phase.y() = parameters.getParameter< double >( prefix + "phase-y" ); this->phase.z() = parameters.getParameter< double >( prefix + "phase-z" ); + this->wavesNumber.x() = ceil( parameters.getParameter< double >( prefix+"waves-number-x" ) ); + this->wavesNumber.y() = ceil( parameters.getParameter< double >( prefix+"waves-number-y" ) ); + this->wavesNumber.z() = ceil( parameters.getParameter< double >( prefix+"waves-number-z" ) ); return true; } - template< typename Real > template< int XDiffOrder, int YDiffOrder, @@ -205,6 +234,16 @@ getPartialDerivative( const VertexType& v, const RealType& x = v.x(); const RealType& y = v.y(); const RealType& z = v.z(); + + const RealType xp = ::fabs( x ) + sign( x ) * this->phase.x() * this->waveLength.x() / (2.0*M_PI); + const RealType yp = ::fabs( y ) + sign( y ) * this->phase.y() * this->waveLength.y() / (2.0*M_PI); + const RealType zp = ::fabs( z ) + sign( z ) * this->phase.z() * this->waveLength.z() / (2.0*M_PI); + + if( ( this->wavesNumber.x() != 0.0 && xp > this->waveLength.x() * this->wavesNumber.x() ) || + ( this->wavesNumber.y() != 0.0 && yp > this->waveLength.y() * this->wavesNumber.y() ) || + ( this->wavesNumber.z() != 0.0 && zp > this->waveLength.z() * this->wavesNumber.z() ) ) + return 0.0; + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0) return this->amplitude * ::sin( this->phase.x() + 2.0 * M_PI * x / this->waveLength.x() ) * diff --git a/src/TNL/Functions/Analytic/SinWave.h b/src/TNL/Functions/Analytic/SinWave.h index 98c8cdddc6e8f9d0a0433fca653ade91d5d85665..24549851fa98a8817e28430f909ad99e497811f8 100644 --- a/src/TNL/Functions/Analytic/SinWave.h +++ b/src/TNL/Functions/Analytic/SinWave.h @@ -8,6 +8,9 @@ /* See Copyright Notice in tnl/Copyright */ +/**** + * Tomas Sobotik + */ #pragma once #include <TNL/Config/ParameterContainer.h> @@ -24,26 +27,32 @@ class SinWaveBase : public Domain< dimensions, SpaceDomain > { public: - SinWaveBase(); + SinWaveBase(); - bool setup( const Config::ParameterContainer& parameters, - const String& prefix = "" ); + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); - void setWaveLength( const Real& waveLength ); + void setWaveLength( const Real& waveLength ); + + Real getWaveLength() const; - Real getWaveLength() const; + void setAmplitude( const Real& amplitude ); - void setAmplitude( const Real& amplitude ); + Real getAmplitude() const; - Real getAmplitude() const; + void setPhase( const Real& phase ); - void setPhase( const Real& phase ); + Real getPhase() const; - Real getPhase() const; + void setWavesNumber( const Real& wavesNumber ); + + Real getWavesNumber() const; protected: + + bool isInsideWaves( const Real& distance ) const; - Real waveLength, amplitude, phase, wavesNumber; + Real waveLength, amplitude, phase, wavesNumber; }; template< int Dimensions, typename Real > @@ -140,7 +149,8 @@ std::ostream& operator << ( std::ostream& str, const SinWave< Dimensions, Real > { str << "Sin Wave. function: amplitude = " << f.getAmplitude() << " wavelength = " << f.getWaveLength() - << " phase = " << f.getPhase(); + << " phase = " << f.getPhase() + << " waves number = " << f.getWavesNumber(); return str; } diff --git a/src/TNL/Functions/Analytic/SinWaveSDF.h b/src/TNL/Functions/Analytic/SinWaveSDF.h new file mode 100644 index 0000000000000000000000000000000000000000..29278c35878b7b5c8f5eba6630959ee80b8df75f --- /dev/null +++ b/src/TNL/Functions/Analytic/SinWaveSDF.h @@ -0,0 +1,159 @@ +/*************************************************************************** + SinWaveSDF.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Containers/StaticVector.h> +#include <TNL/Functions/Domain.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< int dimensions, + typename Real = double > +class SinWaveSDFBase : public Functions::Domain< dimensions, SpaceDomain > +{ + public: + + SinWaveSDFBase(); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + void setWaveLength( const Real& waveLength ); + + Real getWaveLength() const; + + void setAmplitude( const Real& amplitude ); + + Real getAmplitude() const; + + void setPhase( const Real& phase ); + + Real getPhase() const; + + void setWavesNumber( const Real& wavesNumber ); + + Real getWavesNumber() const; + + protected: + + __cuda_callable__ + Real sinWaveFunctionSDF( const Real& r ) const; + + Real waveLength, amplitude, phase, wavesNumber; +}; + +template< int Dimensions, typename Real > +class SinWaveSDF +{ +}; + +template< typename Real > +class SinWaveSDF< 1, Real > : public SinWaveSDFBase< 1, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 1, RealType > VertexType; + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< typename Real > +class SinWaveSDF< 2, Real > : public SinWaveSDFBase< 2, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 2, RealType > VertexType; + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< typename Real > +class SinWaveSDF< 3, Real > : public SinWaveSDFBase< 3, Real > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< 3, RealType > VertexType; + + + +#ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > +#else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > +#endif + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const; + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const; + +}; + +template< int Dimensions, + typename Real > +std::ostream& operator << ( std::ostream& str, const SinWaveSDF< Dimensions, Real >& f ) +{ + str << "SDF Sin Wave SDF. function: amplitude = " << f.getAmplitude() + << " wavelength = " << f.getWaveLength() + << " phase = " << f.getPhase() + << " # of waves = " << f.getWavesNumber(); + return str; +} + + } // namespace Analytic + } // namespace Functions +} // namespace TNL + +#include <TNL/Functions/Analytic/SinWaveSDF_impl.h> diff --git a/src/TNL/Functions/Analytic/SinWaveSDF_impl.h b/src/TNL/Functions/Analytic/SinWaveSDF_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..5d010df173f833e1d480c28a92886ada7c59e460 --- /dev/null +++ b/src/TNL/Functions/Analytic/SinWaveSDF_impl.h @@ -0,0 +1,167 @@ +/*************************************************************************** + tnlSDFSinWaveFunctionSDFSDF_impl.h - description + ------------------- + begin : Oct 13, 2014 + copyright : (C) 2014 by Tomas Sobotik + + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Analytic/SinWaveSDF.h> + +namespace TNL { + namespace Functions { + namespace Analytic { + +template< int dimensions, typename Real > +SinWaveSDFBase< dimensions, Real >::SinWaveSDFBase() +: waveLength( 1.0 ), + amplitude( 1.0 ), + phase( 0 ), + wavesNumber( 0 ) +{ +} + +template< int dimensions, typename Real > +bool SinWaveSDFBase< dimensions, Real >::setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + this->waveLength = parameters.getParameter< double >( prefix + "wave-length" ); + this->amplitude = parameters.getParameter< double >( prefix + "amplitude" ); + this->phase = parameters.getParameter< double >( prefix + "phase" ); + while(this->phase >2.0*M_PI) + this->phase -= 2.0*M_PI; + this->wavesNumber = ceil( parameters.getParameter< double >( prefix + "waves-number" ) ); + return true; +} + +template< int dimensions, typename Real > +void SinWaveSDFBase< dimensions, Real >::setWaveLength( const Real& waveLength ) +{ + this->waveLength = waveLength; +} + +template< int dimensions, typename Real > +Real SinWaveSDFBase< dimensions, Real >::getWaveLength() const +{ + return this->waveLength; +} + +template< int dimensions, typename Real > +void SinWaveSDFBase< dimensions, Real >::setAmplitude( const Real& amplitude ) +{ + this->amplitude = amplitude; +} + +template< int dimensions, typename Real > +Real SinWaveSDFBase< dimensions, Real >::getAmplitude() const +{ + return this->amplitude; +} + +template< int dimensions, typename Real > +void SinWaveSDFBase< dimensions, Real >::setPhase( const Real& phase ) +{ + this->phase = phase; +} + +template< int dimensions, typename Real > +Real SinWaveSDFBase< dimensions, Real >::getPhase() const +{ + return this->phase; +} + +template< int dimensions, typename Real > +void SinWaveSDFBase< dimensions, Real >::setWavesNumber( const Real& wavesNumber ) +{ + this->wavesNumber = wavesNumber; +} + +template< int dimensions, typename Real > +Real SinWaveSDFBase< dimensions, Real >::getWavesNumber() const +{ + return this->wavesNumber; +} + +template< int dimensions, typename Real > +__cuda_callable__ +Real SinWaveSDFBase< dimensions, Real >::sinWaveFunctionSDF( const Real& r ) const +{ + if( this->wavesNumber == 0.0 || r < this->wavesNumber * this->waveLength ) + return sign( r - round( 2.0 * r / this->waveLength ) * this->waveLength / 2.0 ) + * ( r - round( 2.0 * r / this->waveLength ) * this->waveLength / 2.0 ) + * sign( ::sin( 2.0 * M_PI * r / this->waveLength ) ); + else + return r - this->wavesNumber * this->waveLength; +} + + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +SinWaveSDF< 1, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + if( YDiffOrder != 0 || ZDiffOrder != 0 ) + return 0.0; + const RealType& x = v.x(); + const RealType distance = ::sqrt( x * x ) + this->phase * this->waveLength / (2.0*M_PI); + if( XDiffOrder == 0 ) + return this->sinWaveFunctionSDF( distance ); + TNL_ASSERT( false, std::cerr << "TODO: implement this" ); + return 0.0; +} + + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +SinWaveSDF< 2, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + if( ZDiffOrder != 0 ) + return 0.0; + + const RealType& x = v.x(); + const RealType& y = v.y(); + const RealType distance = ::sqrt( x * x + y * y ) + this->phase * this->waveLength / (2.0*M_PI); + if( XDiffOrder == 0 && YDiffOrder == 0) + return this->sinWaveFunctionSDF( distance ); + TNL_ASSERT( false, std::cerr << "TODO: implement this" ); + return 0.0; +} + +template< typename Real > + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder> +__cuda_callable__ +Real +SinWaveSDF< 3, Real >:: +getPartialDerivative( const VertexType& v, + const Real& time ) const +{ + const RealType& x = v.x(); + const RealType& y = v.y(); + const RealType& z = v.z(); + const RealType distance = ::sqrt( x * x + y * y + z * z ) + this->phase * this->waveLength / (2.0*M_PI); + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + return this->sinWaveFunctionSDF( distance ); + TNL_ASSERT( false, std::cerr << "TODO: implement this" ); + return 0.0; +} + + } // namespace Analytic + } // namespace Functions +} // namespace TNL diff --git a/src/TNL/Functions/Analytic/Twins.h b/src/TNL/Functions/Analytic/Twins.h index ebdb507ac79e84681396715254ff4d4e30ff1b9e..d6627cdef82b7f28e69b202c48fe9bd1f91870ed 100644 --- a/src/TNL/Functions/Analytic/Twins.h +++ b/src/TNL/Functions/Analytic/Twins.h @@ -1,5 +1,5 @@ /*************************************************************************** - ExpBump.h - description + Twins.h - description ------------------- begin : Dec 5, 2013 copyright : (C) 2013 by Tomas Oberhuber diff --git a/src/TNL/Functions/Analytic/Twins_impl.h b/src/TNL/Functions/Analytic/Twins_impl.h index 222f9a452adf289bcc9282c75cf2014ecc23c289..2b294320fed642d15cc9b2d7355ff2aa3f7f7a02 100644 --- a/src/TNL/Functions/Analytic/Twins_impl.h +++ b/src/TNL/Functions/Analytic/Twins_impl.h @@ -1,5 +1,5 @@ /*************************************************************************** - ExpBump_impl.h - description + Twins_impl.h - description ------------------- begin : Dec 5, 2013 copyright : (C) 2013 by Tomas Oberhuber diff --git a/src/TNL/Functions/Analytic/VectorNorm.h b/src/TNL/Functions/Analytic/VectorNorm.h new file mode 100644 index 0000000000000000000000000000000000000000..7dd48b1a320c62d222934ed71d8481cb64ef1da1 --- /dev/null +++ b/src/TNL/Functions/Analytic/VectorNorm.h @@ -0,0 +1,293 @@ +/*************************************************************************** + VectorNorm.h - description + ------------------- + begin : Feb 12, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Math.h> +#include <TNL/Assert.h> + +namespace TNL { +namespace Functions { +namespace Analytic { + +template< int Dimensions_, + typename Real > +class VectorNormBase : public Domain< Dimensions_, SpaceDomain > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< Dimensions_, RealType > VertexType; + + VectorNormBase() + : center( 0.0 ), + anisotropy( 1.0 ), + power( 2.0 ), + radius( 0.0 ), + multiplicator( 1.0 ), + maxNorm( false ){}; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "center-0", "x-coordinate of the coordinates origin for the vector norm.", 0.0 ); + config.addEntry< double >( prefix + "center-1", "y-coordinate of the coordinates origin for the vector norm.", 0.0 ); + config.addEntry< double >( prefix + "center-2", "z-coordinate of the coordinates origin for the vector norm.", 0.0 ); + config.addEntry< double >( prefix + "anisotropy-0", "x-coordinate of the linear anisotropy of the vector norm.", 1.0 ); + config.addEntry< double >( prefix + "anisotropy-1", "y-coordinate of the linear anisotropy of the vector norm.", 1.0 ); + config.addEntry< double >( prefix + "anisotropy-2", "z-coordinate of the linear anisotropy of the vector norm.", 1.0 ); + config.addEntry< double >( prefix + "power", "The p coefficient of the L-p vector norm", 2.0 ); + config.addEntry< double >( prefix + "radius", "Radius of the zero-th level-set.", 0.0 ); + config.addEntry< double >( prefix + "multiplicator", "Outer multiplicator of the norm - -1.0 turns the function graph upside/down.", 1.0 ); + config.addEntry< bool >( prefix + "max-norm", "Turn to 'true' to get maximum norm.", false ); + } + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->power = parameters.template getParameter< double >( prefix + "power" ); + this->maxNorm = parameters.template getParameter< bool >( prefix + "max-norm" ); + this->radius = parameters.template getParameter< double >( prefix + "radius" ); + this->multiplicator = parameters.template getParameter< double >( prefix + "multiplicator" ); + return( this->center.setup( parameters, prefix + "center-") && + this->anisotropy.setup( parameters, prefix + "anisotropy-" ) ); + }; + + void setCenter( const VertexType& center ) + { + this->center = center; + }; + + const RealType& getCenter() const + { + return this->center; + } + + void setAnisotropy( const VertexType& anisotropy ) + { + this->anisotropy = anisotropy; + }; + + const RealType& getAnisotropy() const + { + return this->anisotropy; + } + + void setPower( const RealType& power ) + { + this->power = power; + } + + const RealType& getPower() const + { + return this->power; + } + + void setRadius( const RealType& radius ) + { + this->radius = radius; + } + + const RealType& getRadius() const + { + return this->radius; + } + + void setMultiplicator( const RealType& multiplicator ) + { + this->multiplicator = multiplicator; + } + + const RealType& getMultiplicator() const + { + return this->multiplicator; + } + + void setMaxNorm( bool maxNorm ) + { + this->maxNorm = maxNorm; + } + + const RealType& getMaxNorm() const + { + return this->maxNorm; + } + + protected: + + VertexType center, anisotropy; + + RealType power, radius, multiplicator; + + bool maxNorm; +}; + +template< int Dimensions, + typename Real > +class VectorNorm +{ +}; + +template< typename Real > +class VectorNorm< 1, Real > : public VectorNormBase< 1, Real > +{ + public: + + typedef VectorNormBase< 1, Real > BaseType; + using typename BaseType::RealType; + using typename BaseType::VertexType; + + static String getType(); + + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const + { + const RealType& x = v.x() - this->center.x(); + if( YDiffOrder != 0 || ZDiffOrder != 0 ) + return 0.0; + if( XDiffOrder == 0 ) + { + return this->multiplicator * ( TNL::abs( x ) * this->anisotropy.x() - this->radius ); + } + if( XDiffOrder == 1 ) + { + return this->multiplicator * TNL::sign( x ) * this->anisotropy.x(); + } + return 0.0; + } + + __cuda_callable__ + RealType operator()( const VertexType& v, + const RealType& time = 0.0 ) const + { + return this->template getPartialDerivative< 0, 0, 0 >( v, time ); + } +}; + +template< typename Real > +class VectorNorm< 2, Real > : public VectorNormBase< 2, Real > +{ + public: + + typedef VectorNormBase< 2, Real > BaseType; + using typename BaseType::RealType; + using typename BaseType::VertexType; + + static String getType(); + + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ inline + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const + { + const RealType& x = v.x() - this->center.x(); + const RealType& y = v.y() - this->center.y(); + if( ZDiffOrder != 0 ) + return 0.0; + if( XDiffOrder == 0 && YDiffOrder == 0 ) + { + if( this->maxNorm ) + return ( TNL::max( TNL::abs( x ) * this->anisotropy.x(), + TNL::abs( y ) * this->anisotropy.y() ) - this->radius ) * this->multiplicator; + if( this->power == 1.0 ) + return ( ( TNL::abs( x ) * this->anisotropy.x() + + TNL::abs( y ) * this->anisotropy.y() ) - this->radius ) * this->multiplicator; + if( this->power == 2.0 ) + return ( std::sqrt( x * x * this->anisotropy.x() + + y * y * this->anisotropy.y() ) - this->radius ) * this->multiplicator; + return ( std::pow( std::pow( TNL::abs( x ), this->power ) * this->anisotropy.x() + + std::pow( TNL::abs( y ), this->power ) * this->anisotropy.y(), 1.0 / this-> power ) - this->radius ) * this->multiplicator; + } + TNL_ASSERT( false, std::cerr << "Not implemented yet." << std::endl ); + return 0.0; + } + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const + { + return this->template getPartialDerivative< 0, 0, 0 >( v, time ); + } +}; + +template< typename Real > +class VectorNorm< 3, Real > : public VectorNormBase< 3, Real > +{ + public: + + typedef VectorNormBase< 3, Real > BaseType; + using typename BaseType::RealType; + using typename BaseType::VertexType; + + static String getType(); + + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ + RealType getPartialDerivative( const VertexType& v, + const Real& time = 0.0 ) const + { + const RealType& x = v.x() - this->center.x(); + const RealType& y = v.y() - this->center.y(); + const RealType& z = v.z() - this->center.z(); + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + { + if( this->maxNorm ) + return ( TNL::max( TNL::max( TNL::abs( x ) * this->anisotropy.x(), + TNL::abs( y ) * this->anisotropy.y() ), + TNL::abs( z ) * this->anisotropy.z() ) - this->radius ) * this->multiplicator; + if( this->power == 1.0 ) + return ( ( TNL::abs( x ) * this->anisotropy.x() + + TNL::abs( y ) * this->anisotropy.y() + + TNL::abs( z ) * this->anisotropy.z() ) - this->radius ) * this->multiplicator; + if( this->power == 2.0 ) + return ( std::sqrt( x * x * this->anisotropy.x() + + y * y * this->anisotropy.y() + + z * z * this->anisotropy.z() ) - this->radius ) * this->multiplicator ; + return ( std::pow( std::pow( TNL::abs( x ), this->power ) * this->anisotropy.x() + + std::pow( TNL::abs( y ), this->power ) * this->anisotropy.y() + + std::pow( TNL::abs( z ), this->power ) * this->anisotropy.z(), 1.0 / this-> power ) - this->radius ) * this->multiplicator; + } + TNL_ASSERT( false, std::cerr << "Not implemented yet." << std::endl ); + return 0.0; + } + + __cuda_callable__ + RealType operator()( const VertexType& v, + const Real& time = 0.0 ) const + { + return this->template getPartialDerivative< 0, 0, 0 >( v, time ); + } +}; + +template< int Dimensions, + typename Real > +std::ostream& operator << ( std::ostream& str, const VectorNorm< Dimensions, Real >& f ) +{ + str << "VectorNorm. function: multiplicator = " << f.getMultiplicator() << " sigma = " << f.getSigma(); + return str; +} + +} // namespace Analytic +} // namespace Functions +} // namespace TNL + + + + + + diff --git a/src/TNL/Functions/CMakeLists.txt b/src/TNL/Functions/CMakeLists.txt index 04fe4b86805ddbdd11f0d9a73492918db7baeb5d..7727d5539ffb2a475e3c27f3b71b6ba997a23f52 100755 --- a/src/TNL/Functions/CMakeLists.txt +++ b/src/TNL/Functions/CMakeLists.txt @@ -14,7 +14,11 @@ SET( headers Domain.h MeshFunctionVTKWriter_impl.h OperatorFunction.h TestFunction.h - TestFunction_impl.h ) + TestFunction_impl.h + VectorField.h + VectorFieldGnuplotWriter.h + VectorFieldGnuplotWriter_impl.h + ) SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Functions ) set( common_SOURCES diff --git a/src/TNL/Functions/MeshFunction.h b/src/TNL/Functions/MeshFunction.h index a3cf8a46c307312ff0e10127da53339c48ddb3e4..35fee42d13beb047bc4d11b108edeb0ca1890f08 100644 --- a/src/TNL/Functions/MeshFunction.h +++ b/src/TNL/Functions/MeshFunction.h @@ -84,7 +84,6 @@ class MeshFunction : const SharedPointer< Vector >& dataPtr, const IndexType& offset = 0 ); - void setMesh( const MeshPointer& meshPointer ); template< typename Device = Devices::Host > @@ -93,6 +92,8 @@ class MeshFunction : const MeshPointer& getMeshPointer() const; + __cuda_callable__ static IndexType getDofs( const MeshPointer& meshPointer ); + __cuda_callable__ const VectorType& getData() const; __cuda_callable__ VectorType& getData(); @@ -144,7 +145,8 @@ class MeshFunction : bool boundLoad( File& file ); bool write( const String& fileName, - const String& format = "vtk" ) const; + const String& format = "vtk", + const double& scale = 1.0 ) const; using Object::save; diff --git a/src/TNL/Functions/MeshFunctionGnuplotWriter.h b/src/TNL/Functions/MeshFunctionGnuplotWriter.h index 887498711e8f3e4422a7cc99994cfecc2301504d..2c21a10328d4bd49bb6f3501246ce476cca83bd2 100644 --- a/src/TNL/Functions/MeshFunctionGnuplotWriter.h +++ b/src/TNL/Functions/MeshFunctionGnuplotWriter.h @@ -23,7 +23,8 @@ class MeshFunctionGnuplotWriter public: static bool write( const MeshFunction& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; /*** @@ -41,7 +42,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; /*** @@ -59,7 +61,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; @@ -78,7 +81,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; /*** @@ -96,7 +100,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; /*** @@ -114,7 +119,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; @@ -133,7 +139,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device typedef Functions::MeshFunction< MeshType, 3, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; /*** @@ -151,7 +158,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; /*** @@ -169,7 +177,8 @@ class MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); }; } // namespace Functions diff --git a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h index 341ed711a4cb4da60f3f6501a5dec0f8b736925a..9c442de639194e909ca5d3f54c491eede082f945 100644 --- a/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h +++ b/src/TNL/Functions/MeshFunctionGnuplotWriter_impl.h @@ -19,7 +19,8 @@ template< typename MeshFunction > bool MeshFunctionGnuplotWriter< MeshFunction >:: write( const MeshFunction& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { std::cerr << "Gnuplot writer for mesh functions defined on mesh type " << MeshFunction::MeshType::getType() << " is not (yet) implemented." << std::endl; return false; @@ -35,7 +36,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typename MeshType::Cell entity( mesh ); @@ -46,7 +48,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; } @@ -61,7 +63,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typename MeshType::Vertex entity( mesh ); @@ -72,7 +75,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; } @@ -88,7 +91,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typename MeshType::Cell entity( mesh ); @@ -103,7 +107,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -120,7 +124,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typedef typename MeshType::Face EntityType; @@ -139,7 +144,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -158,7 +163,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -176,7 +181,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typename MeshType::Vertex entity( mesh ); @@ -191,7 +197,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -209,7 +215,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typename MeshType::Cell entity( mesh ); @@ -227,7 +234,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " << v.z() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -244,7 +251,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typedef typename MeshType::Face EntityType; @@ -266,7 +274,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " << v.z() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -286,7 +294,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " << v.z() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -306,7 +314,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " << v.z() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } @@ -324,7 +332,8 @@ template< typename MeshReal, bool MeshFunctionGnuplotWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { const MeshType& mesh = function.getMesh(); typename MeshType::Vertex entity( mesh ); @@ -342,7 +351,7 @@ write( const MeshFunctionType& function, entity.refresh(); typename MeshType::VertexType v = entity.getCenter(); str << v.x() << " " << v.y() << " " << v.z() << " " - << function.getData().getElement( entity.getIndex() ) << std::endl; + << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } str << std::endl; } diff --git a/src/TNL/Functions/MeshFunctionVTKWriter.h b/src/TNL/Functions/MeshFunctionVTKWriter.h index 39651c27450c407639c1278f62220b82f51f240b..b4d18e4490901c2824ff922fe10f18607198e780 100644 --- a/src/TNL/Functions/MeshFunctionVTKWriter.h +++ b/src/TNL/Functions/MeshFunctionVTKWriter.h @@ -23,7 +23,9 @@ class MeshFunctionVTKWriter public: static bool write( const MeshFunction& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunction& function, std::ostream& str ){} }; @@ -43,7 +45,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -63,7 +67,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -83,7 +89,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -103,7 +111,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -123,7 +133,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -143,7 +155,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 3, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -163,7 +177,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 2, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -183,7 +199,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 1, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; @@ -203,7 +221,9 @@ class MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, Me typedef Functions::MeshFunction< MeshType, 0, RealType > MeshFunctionType; static bool write( const MeshFunctionType& function, - std::ostream& str ); + std::ostream& str, + const double& scale ); + static void writeHeader(const MeshFunctionType& function, std::ostream& str ); }; diff --git a/src/TNL/Functions/MeshFunctionVTKWriter_impl.h b/src/TNL/Functions/MeshFunctionVTKWriter_impl.h index b432671764c0545c64e5c8ea241c820525f20f05..91a589bbe81c6261b0ee61882a3b03824d970b62 100644 --- a/src/TNL/Functions/MeshFunctionVTKWriter_impl.h +++ b/src/TNL/Functions/MeshFunctionVTKWriter_impl.h @@ -19,7 +19,8 @@ template< typename MeshFunction > bool MeshFunctionVTKWriter< MeshFunction >:: write( const MeshFunction& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { std::cerr << "VTK writer for mesh functions defined on mesh type " << MeshFunction::MeshType::getType() << " is not (yet) implemented." << std::endl; return false; @@ -54,7 +55,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { writeHeader(function, str); @@ -88,7 +90,7 @@ write( const MeshFunctionType& function, { typename MeshType::Cell entity = mesh.template getEntity< typename MeshType::Cell >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -123,7 +125,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { writeHeader(function, str); @@ -157,7 +160,7 @@ write( const MeshFunctionType& function, { typename MeshType::Vertex entity = mesh.template getEntity< typename MeshType::Vertex >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -192,7 +195,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { writeHeader(function, str); @@ -237,7 +241,7 @@ write( const MeshFunctionType& function, { typename MeshType::Cell entity = mesh.template getEntity< typename MeshType::Cell >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -272,7 +276,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { typedef typename MeshType::template MeshEntity< 0 > Vertex; typedef typename MeshType::template MeshEntity< 1 > Face; @@ -326,7 +331,7 @@ write( const MeshFunctionType& function, { typename MeshType::Face entity = mesh.template getEntity< typename MeshType::Face >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -361,7 +366,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { typedef typename MeshType::template MeshEntity< 0 > Vertex; writeHeader(function, str); @@ -405,7 +411,7 @@ write( const MeshFunctionType& function, { typename MeshType::Vertex entity = mesh.template getEntity< typename MeshType::Vertex >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -440,7 +446,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { writeHeader(function, str); @@ -501,7 +508,7 @@ write( const MeshFunctionType& function, { typename MeshType::Cell entity = mesh.template getEntity< typename MeshType::Cell >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -536,7 +543,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { writeHeader(function, str); @@ -620,7 +628,7 @@ write( const MeshFunctionType& function, { typename MeshType::Face entity = mesh.template getEntity< typename MeshType::Face >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -655,7 +663,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 1, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { writeHeader(function, str); @@ -733,7 +742,7 @@ write( const MeshFunctionType& function, { typename MeshType::Edge entity = mesh.template getEntity< typename MeshType::Edge >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; @@ -768,7 +777,8 @@ template< typename MeshReal, bool MeshFunctionVTKWriter< MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > >:: write( const MeshFunctionType& function, - std::ostream& str ) + std::ostream& str, + const double& scale ) { writeHeader(function, str); @@ -820,7 +830,7 @@ write( const MeshFunctionType& function, { typename MeshType::Vertex entity = mesh.template getEntity< typename MeshType::Vertex >( i ); entity.refresh(); - str << function.getData().getElement( entity.getIndex() ) << std::endl; + str << scale * function.getData().getElement( entity.getIndex() ) << std::endl; } return true; diff --git a/src/TNL/Functions/MeshFunction_impl.h b/src/TNL/Functions/MeshFunction_impl.h index 53ab95680738b8ee77c7a76ca7de9e7344f3f3a8..8f365c4d88a9993ee1c28a74fc0547d7f02cb8f4 100644 --- a/src/TNL/Functions/MeshFunction_impl.h +++ b/src/TNL/Functions/MeshFunction_impl.h @@ -163,6 +163,7 @@ setup( const MeshPointer& meshPointer, else { std::cerr << "Missing parameter " << prefix << "file." << std::endl; + throw(0); return false; } return true; @@ -250,6 +251,17 @@ getMeshPointer() const return this->meshPointer; } +template< typename Mesh, + int MeshEntityDimensions, + typename Real > +__cuda_callable__ +typename MeshFunction< Mesh, MeshEntityDimensions, Real >::IndexType +MeshFunction< Mesh, MeshEntityDimensions, Real >:: +getDofs( const MeshPointer& meshPointer ) +{ + return meshPointer->template getEntitiesCount< MeshEntityDimensions >(); +} + template< typename Mesh, int MeshEntityDimensions, typename Real > @@ -482,19 +494,20 @@ template< typename Mesh, bool MeshFunction< Mesh, MeshEntityDimensions, Real >:: write( const String& fileName, - const String& format ) const + const String& format, + const double& scale ) const { std::fstream file; file.open( fileName.getString(), std::ios::out ); if( ! file ) { - std::cerr << "Unbable to open a file " << fileName << "." << std::endl; + std::cerr << "Unable to open a file " << fileName << "." << std::endl; return false; } if( format == "vtk" ) - return MeshFunctionVTKWriter< ThisType >::write( *this, file ); + return MeshFunctionVTKWriter< ThisType >::write( *this, file, scale ); else if( format == "gnuplot" ) - return MeshFunctionGnuplotWriter< ThisType >::write( *this, file ); + return MeshFunctionGnuplotWriter< ThisType >::write( *this, file, scale ); else { std::cerr << "Unknown output format: " << format << std::endl; return false; diff --git a/src/TNL/Functions/OperatorFunction.h b/src/TNL/Functions/OperatorFunction.h index 628191165d38d3ae12052091e15b01ba43e852b7..4eaf24156e0152ac8d74210cef3c3c83752f1c38 100644 --- a/src/TNL/Functions/OperatorFunction.h +++ b/src/TNL/Functions/OperatorFunction.h @@ -30,18 +30,19 @@ namespace Functions { */ template< typename Operator, - typename MeshFunction, + typename Function = typename Operator::FunctionType, typename BoundaryConditions = void, - bool EvaluateOnFly = false > + bool EvaluateOnFly = false, + bool IsAnalytic = ( Function::getDomainType() == SpaceDomain || Function::getDomainType() == NonspaceDomain ) > class OperatorFunction{}; /**** * Specialization for 'On the fly' evaluation with the boundary conditions does not make sense. */ template< typename Operator, - typename MeshFunction, + typename Function, typename BoundaryConditions > -class OperatorFunction< Operator, MeshFunction, BoundaryConditions, true > +class OperatorFunction< Operator, Function, BoundaryConditions, true, false > : public Domain< Operator::getMeshDimensions(), MeshDomain > { }; @@ -50,21 +51,21 @@ class OperatorFunction< Operator, MeshFunction, BoundaryConditions, true > * Specialization for 'On the fly' evaluation and no boundary conditions. */ template< typename Operator, - typename MeshFunctionT > -class OperatorFunction< Operator, MeshFunctionT, void, true > + typename Function > +class OperatorFunction< Operator, Function, void, true, false > : public Domain< Operator::getDomainDimensions(), Operator::getDomainType() > { public: - static_assert( MeshFunctionT::getDomainType() == MeshDomain || - MeshFunctionT::getDomainType() == MeshInteriorDomain || - MeshFunctionT::getDomainType() == MeshBoundaryDomain, - "Only mesh preimageFunctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." ); - static_assert( std::is_same< typename Operator::MeshType, typename MeshFunctionT::MeshType >::value, + static_assert( Function::getDomainType() == MeshDomain || + Function::getDomainType() == MeshInteriorDomain || + Function::getDomainType() == MeshBoundaryDomain, + "Only mesh preimageFnctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." ); + static_assert( std::is_same< typename Operator::MeshType, typename Function::MeshType >::value, "Both, operator and mesh preimageFunction must be defined on the same mesh." ); typedef Operator OperatorType; - typedef MeshFunctionT FunctionType; + typedef Function FunctionType; typedef typename OperatorType::MeshType MeshType; typedef typename OperatorType::RealType RealType; typedef typename OperatorType::DeviceType DeviceType; @@ -90,7 +91,7 @@ class OperatorFunction< Operator, MeshFunctionT, void, true > const MeshPointer& getMeshPointer() const { - tnlTNL_ASSERT( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl ); + TNL_ASSERT( this->preimageFunction, std::cerr << "The preimage function was not set." << std::endl ); return this->preimageFunction->getMeshPointer(); }; @@ -128,17 +129,17 @@ class OperatorFunction< Operator, MeshFunctionT, void, true > * Specialization for precomputed evaluation and no boundary conditions. */ template< typename Operator, - typename PreimageFunction > -class OperatorFunction< Operator, PreimageFunction, void, false > + typename Function > +class OperatorFunction< Operator, Function, void, false, false > : public Domain< Operator::getDomainDimensions(), Operator::getDomainType() > { public: - static_assert( PreimageFunction::getDomainType() == MeshDomain || - PreimageFunction::getDomainType() == MeshInteriorDomain || - PreimageFunction::getDomainType() == MeshBoundaryDomain, + static_assert( Function::getDomainType() == MeshDomain || + Function::getDomainType() == MeshInteriorDomain || + Function::getDomainType() == MeshBoundaryDomain, "Only mesh preimageFunctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." ); - static_assert( std::is_same< typename Operator::MeshType, typename PreimageFunction::MeshType >::value, + static_assert( std::is_same< typename Operator::MeshType, typename Function::MeshType >::value, "Both, operator and mesh preimageFunction must be defined on the same mesh." ); typedef Operator OperatorType; @@ -146,9 +147,9 @@ class OperatorFunction< Operator, PreimageFunction, void, false > typedef typename OperatorType::RealType RealType; typedef typename OperatorType::DeviceType DeviceType; typedef typename OperatorType::IndexType IndexType; - typedef PreimageFunction PreimageFunctionType; + typedef Function PreimageFunctionType; typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType; - typedef OperatorFunction< Operator, PreimageFunction, void, true > OperatorFunctionType; + typedef OperatorFunction< Operator, Function, void, true > OperatorFunctionType; typedef typename OperatorType::ExactOperatorType ExactOperatorType; typedef SharedPointer< MeshType, DeviceType > MeshPointer; @@ -172,7 +173,7 @@ class OperatorFunction< Operator, PreimageFunction, void, false > const ImageFunctionType& getImageFunction() const { return this->imageFunction; }; - void setPreimageFunction( PreimageFunction& preimageFunction ) + void setPreimageFunction( PreimageFunctionType& preimageFunction ) { this->preimageFunction = &preimageFunction; this->imageFunction.setMesh( preimageFunction.getMeshPointer() ); @@ -232,18 +233,18 @@ class OperatorFunction< Operator, PreimageFunction, void, false > * Specialization for precomputed evaluation and with boundary conditions. */ template< typename Operator, - typename PreimageFunction, + typename Function, typename BoundaryConditions > -class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false > +class OperatorFunction< Operator, Function, BoundaryConditions, false, false > : public Domain< Operator::getMeshDimensions(), MeshDomain > { public: - static_assert( PreimageFunction::getDomainType() == MeshDomain || - PreimageFunction::getDomainType() == MeshInteriorDomain || - PreimageFunction::getDomainType() == MeshBoundaryDomain, + static_assert( Function::getDomainType() == MeshDomain || + Function::getDomainType() == MeshInteriorDomain || + Function::getDomainType() == MeshBoundaryDomain, "Only mesh preimageFunctions may be used in the operator preimageFunction. Use ExactOperatorFunction instead of OperatorFunction." ); - static_assert( std::is_same< typename Operator::MeshType, typename PreimageFunction::MeshType >::value, + static_assert( std::is_same< typename Operator::MeshType, typename Function::MeshType >::value, "Both, operator and mesh preimageFunction must be defined on the same mesh." ); static_assert( std::is_same< typename BoundaryConditions::MeshType, typename Operator::MeshType >::value, "The operator and the boundary conditions are defined on different mesh types." ); @@ -254,10 +255,10 @@ class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false > typedef typename OperatorType::RealType RealType; typedef typename OperatorType::DeviceType DeviceType; typedef typename OperatorType::IndexType IndexType; - typedef PreimageFunction PreimageFunctionType; + typedef Function PreimageFunctionType; typedef Functions::MeshFunction< MeshType, Operator::getImageEntitiesDimensions() > ImageFunctionType; typedef BoundaryConditions BoundaryConditionsType; - typedef OperatorFunction< Operator, PreimageFunction, void, true > OperatorFunctionType; + typedef OperatorFunction< Operator, Function, void, true > OperatorFunctionType; typedef typename OperatorType::ExactOperatorType ExactOperatorType; static constexpr int getEntitiesDimensions() { return OperatorType::getImageEntitiesDimensions(); }; @@ -286,7 +287,7 @@ class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false > const MeshPointer& getMeshPointer() const { return imageFunction.getMeshPointer(); }; - void setPreimageFunction( const PreimageFunction& preimageFunction ) + void setPreimageFunction( const PreimageFunctionType& preimageFunction ) { this->preimageFunction = &preimageFunction; } @@ -357,6 +358,67 @@ class OperatorFunction< Operator, PreimageFunction, BoundaryConditions, false > template< typename, typename > friend class MeshFunctionEvaluator; }; +/**** + * Specialization for precomputed evaluation and with boundary conditions. + */ +template< typename Operator, + typename Function > +class OperatorFunction< Operator, Function, void, false, true > + : public Domain< Function::getDomainDimensions(), Function::getDomainType() > +{ + public: + + typedef Function FunctionType; + typedef typename FunctionType::RealType RealType; + typedef typename FunctionType::VertexType VertexType; + typedef Operator OperatorType; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return( this->function.setup( parameters, prefix) && + this->operator_.setup( parameters, prefix ) ); + } + + __cuda_callable__ + FunctionType& getFunction() + { + return this->function; + } + + __cuda_callable__ + const FunctionType& getFunction() const + { + return this->function; + } + + __cuda_callable__ + OperatorType& getOperator() + { + return this->operator_; + } + + __cuda_callable__ + const OperatorType& getOperator() const + { + return this->operator_; + } + + __cuda_callable__ + RealType operator()( const VertexType& v, + const RealType& time = 0.0 ) const + { + return this->operator_( this->function, v, time ); + } + + protected: + + Function function; + + Operator operator_; + +}; + } // namespace Functions } // namespace TNL diff --git a/src/TNL/Functions/TestFunction.h b/src/TNL/Functions/TestFunction.h index 55e50c4f9df42f064590b06a62fd8622e5ba0492..d1b78ffb89ce6ba324d455fb3292dc1c214ffdf1 100644 --- a/src/TNL/Functions/TestFunction.h +++ b/src/TNL/Functions/TestFunction.h @@ -26,109 +26,129 @@ class TestFunction : public Domain< FunctionDimensions, SpaceDomain > { protected: - enum TestFunctions{ constant, - expBump, - sinBumps, - sinWave, - cylinder, - flowerpot, - twins, - pseudoSquare, - blob }; - - enum TimeDependence { none, - linear, - quadratic, - cosine }; + enum TestFunctions{ constant, + paraboloid, + expBump, + sinBumps, + sinWave, + cylinder, + flowerpot, + twins, + pseudoSquare, + blob, + vectorNorm, + paraboloidSDF, + sinWaveSDF, + sinBumpsSDF }; + + enum TimeDependence { none, + linear, + quadratic, + cosine }; + + enum Operators { identity, + heaviside }; public: - enum{ Dimensions = FunctionDimensions }; - typedef Real RealType; - typedef Containers::StaticVector< Dimensions, Real > VertexType; + enum{ Dimensions = FunctionDimensions }; + typedef Real RealType; + typedef Containers::StaticVector< Dimensions, Real > VertexType; + + TestFunction(); + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + const TestFunction& operator = ( const TestFunction& function ); + + #ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > + #else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + #endif + __cuda_callable__ + Real getPartialDerivative( const VertexType& vertex, + const Real& time = 0 ) const; + + __cuda_callable__ + Real operator()( const VertexType& vertex, + const Real& time = 0 ) const + { + return this->getPartialDerivative< 0, 0, 0 >( vertex, time ); + } + + + #ifdef HAVE_NOT_CXX11 + template< int XDiffOrder, + int YDiffOrder, + int ZDiffOrder > + #else + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + #endif + __cuda_callable__ + Real getTimeDerivative( const VertexType& vertex, + const Real& time = 0 ) const; - TestFunction(); + #ifdef HAVE_NOT_CXX11 + template< typename Vertex > + __cuda_callable__ + Real getTimeDerivative( const Vertex& vertex, + const Real& time = 0 ) const + { + return this->getTimeDerivative< 0, 0, 0, Vertex >( vertex, time ); + } + #endif - static void configSetup( Config::ConfigDescription& config, - const String& prefix = "" ); + std::ostream& print( std::ostream& str ) const; - bool setup( const Config::ParameterContainer& parameters, - const String& prefix = "" ); + ~TestFunction(); - const TestFunction& operator = ( const TestFunction& function ); + protected: -#ifdef HAVE_NOT_CXX11 - template< int XDiffOrder, - int YDiffOrder, - int ZDiffOrder > -#else - template< int XDiffOrder = 0, - int YDiffOrder = 0, - int ZDiffOrder = 0 > -#endif - __cuda_callable__ - Real getPartialDerivative( const VertexType& vertex, - const Real& time = 0 ) const; + template< typename FunctionType > + bool setupFunction( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + template< typename OperatorType > + bool setupOperator( const Config::ParameterContainer& parameters, + const String& prefix = "" ); - __cuda_callable__ - Real operator()( const VertexType& vertex, - const Real& time = 0 ) const - { - return this->getPartialDerivative< 0, 0, 0 >( vertex, time ); - } - - -#ifdef HAVE_NOT_CXX11 - template< int XDiffOrder, - int YDiffOrder, - int ZDiffOrder > -#else - template< int XDiffOrder = 0, - int YDiffOrder = 0, - int ZDiffOrder = 0 > -#endif - __cuda_callable__ - Real getTimeDerivative( const VertexType& vertex, - const Real& time = 0 ) const; - -#ifdef HAVE_NOT_CXX11 - template< typename Vertex > - __cuda_callable__ - Real getTimeDerivative( const Vertex& vertex, - const Real& time = 0 ) const - { - return this->getTimeDerivative< 0, 0, 0, Vertex >( vertex, time ); - } -#endif - - std::ostream& print( std::ostream& str ) const; - - ~TestFunction(); - protected: + template< typename FunctionType > + void deleteFunction(); - template< typename FunctionType > - bool setupFunction( const Config::ParameterContainer& parameters, - const String& prefix = "" ); + template< typename OperatorType > + void deleteOperator(); - template< typename FunctionType > - void deleteFunction(); + void deleteFunctions(); - void deleteFunctions(); + template< typename FunctionType > + void copyFunction( const void* function ); - template< typename FunctionType > - void copyFunction( const void* function ); + template< typename FunctionType > + std::ostream& printFunction( std::ostream& str ) const; - template< typename FunctionType > - std::ostream& printFunction( std::ostream& str ) const; + void* function; - void* function; + void* operator_; - TestFunctions functionType; + TestFunctions functionType; + + Operators operatorType; - TimeDependence timeDependence; + TimeDependence timeDependence; - Real timeScale; + Real timeScale; }; diff --git a/src/TNL/Functions/TestFunction_impl.h b/src/TNL/Functions/TestFunction_impl.h index 506f536518d1946e33da00f749097b168bd8d09d..a7bfdf513f3e9a088dff1354c26f26d77129dbda 100644 --- a/src/TNL/Functions/TestFunction_impl.h +++ b/src/TNL/Functions/TestFunction_impl.h @@ -24,16 +24,29 @@ #include <TNL/Functions/Analytic/Twins.h> #include <TNL/Functions/Analytic/Blob.h> #include <TNL/Functions/Analytic/PseudoSquare.h> +#include <TNL/Functions/Analytic/Paraboloid.h> +#include <TNL/Functions/Analytic/VectorNorm.h> +/**** + * The signed distance test functions + */ +#include <TNL/Functions/Analytic/SinBumpsSDF.h> +#include <TNL/Functions/Analytic/SinWaveSDF.h> +#include <TNL/Functions/Analytic/ParaboloidSDF.h> + +#include <TNL/Operators/Analytic/Identity.h> +#include <TNL/Operators/Analytic/Heaviside.h> namespace TNL { namespace Functions { + template< int FunctionDimensions, typename Real, typename Device > TestFunction< FunctionDimensions, Real, Device >:: TestFunction() : function( 0 ), + operator_( 0 ), timeDependence( none ), timeScale( 1.0 ) { @@ -49,6 +62,7 @@ configSetup( Config::ConfigDescription& config, { config.addRequiredEntry< String >( prefix + "test-function", "Testing function." ); config.addEntryEnum( "constant" ); + config.addEntryEnum( "paraboloid" ); config.addEntryEnum( "exp-bump" ); config.addEntryEnum( "sin-wave" ); config.addEntryEnum( "sin-bumps" ); @@ -57,6 +71,11 @@ configSetup( Config::ConfigDescription& config, config.addEntryEnum( "twins" ); config.addEntryEnum( "pseudoSquare" ); config.addEntryEnum( "blob" ); + config.addEntryEnum( "paraboloid-sdf" ); + config.addEntryEnum( "sin-wave-sdf" ); + config.addEntryEnum( "sin-bumps-sdf" ); + config.addEntryEnum( "heaviside-of-vector-norm" ); + config.addEntry < double >( prefix + "constant", "Value of the constant function.", 0.0 ); config.addEntry < double >( prefix + "wave-length", "Wave length of the sine based test functions.", 1.0 ); config.addEntry < double >( prefix + "wave-length-x", "Wave length of the sine based test functions.", 1.0 ); @@ -72,8 +91,14 @@ configSetup( Config::ConfigDescription& config, config.addEntry < double >( prefix + "waves-number-y", "Cut-off for the sine based test functions.", 0.0 ); config.addEntry < double >( prefix + "waves-number-z", "Cut-off for the sine based test functions.", 0.0 ); config.addEntry < double >( prefix + "sigma", "Sigma for the exp based test functions.", 1.0 ); + config.addEntry < double >( prefix + "radius", "Radius for paraboloids.", 1.0 ); + config.addEntry < double >( prefix + "coefficient", "Coefficient for paraboloids.", 1.0 ); + config.addEntry < double >( prefix + "x-center", "x-center for paraboloids.", 0.0 ); + config.addEntry < double >( prefix + "y-center", "y-center for paraboloids.", 0.0 ); + config.addEntry < double >( prefix + "z-center", "z-center for paraboloids.", 0.0 ); config.addEntry < double >( prefix + "diameter", "Diameter for the cylinder, flowerpot test functions.", 1.0 ); - config.addEntry < double >( prefix + "height", "Height of zero-level-set function for the blob, pseudosquare test functions.", 1.0 ); + config.addEntry < double >( prefix + "height", "Height of zero-level-set function for the blob, pseudosquare test functions.", 1.0 ); + Analytic::VectorNorm< 3, double >::configSetup( config, "vector-norm-" ); config.addEntry < String >( prefix + "time-dependence", "Time dependence of the test function.", "none" ); config.addEntryEnum( "none" ); config.addEntryEnum( "linear" ); @@ -113,6 +138,36 @@ setupFunction( const Config::ParameterContainer& parameters, return true; } +template< int FunctionDimensions, + typename Real, + typename Device > + template< typename OperatorType > +bool +TestFunction< FunctionDimensions, Real, Device >:: +setupOperator( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + OperatorType* auxOperator = new OperatorType; + if( ! auxOperator->setup( parameters, prefix ) ) + { + delete auxOperator; + return false; + } + + if( std::is_same< Device, Devices::Host >::value ) + { + this->operator_ = auxOperator; + } + if( std::is_same< Device, Devices::Cuda >::value ) + { + this->operator_ = Devices::Cuda::passToDevice( *auxOperator ); + delete auxOperator; + if( ! checkCudaDevice ) + return false; + } + return true; +} + template< int FunctionDimensions, typename Real, typename Device > @@ -122,6 +177,7 @@ setup( const Config::ParameterContainer& parameters, const String& prefix ) { using namespace TNL::Functions::Analytic; + using namespace TNL::Operators::Analytic; std::cout << "Test function setup ... " << std::endl; const String& timeDependence = parameters.getParameter< String >( @@ -140,60 +196,141 @@ setup( const Config::ParameterContainer& parameters, this->timeScale = parameters.getParameter< double >( prefix + "time-scale" ); const String& testFunction = parameters.getParameter< String >( prefix + "test-function" ); - std::cout << "Test function ... " << testFunction << std::endl; + std::cout << "Test function ... " << testFunction << std::endl; if( testFunction == "constant" ) { typedef Constant< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = constant; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } + if( testFunction == "paraboloid" ) + { + typedef Paraboloid< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + functionType = paraboloid; + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); + } if( testFunction == "exp-bump" ) { typedef ExpBump< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = expBump; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } if( testFunction == "sin-bumps" ) { typedef SinBumps< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = sinBumps; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } if( testFunction == "sin-wave" ) { typedef SinWave< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = sinWave; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } if( testFunction == "cylinder" ) { typedef Cylinder< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = cylinder; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } if( testFunction == "flowerpot" ) { typedef Flowerpot< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = flowerpot; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } if( testFunction == "twins" ) { typedef Twins< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = twins; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } if( testFunction == "pseudoSquare" ) { typedef PseudoSquare< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = pseudoSquare; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } if( testFunction == "blob" ) { typedef Blob< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; functionType = blob; - return setupFunction< FunctionType >( parameters ); + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); + } + if( testFunction == "paraboloid-sdf" ) + { + typedef ParaboloidSDF< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + functionType = paraboloidSDF; + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); + } + if( testFunction == "sin-bumps-sdf" ) + { + typedef SinBumpsSDF< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + functionType = sinBumpsSDF; + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); + } + if( testFunction == "sin-wave-sdf" ) + { + typedef SinWaveSDF< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + functionType = sinWaveSDF; + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); + } + if( testFunction == "vector-norm" ) + { + typedef VectorNorm< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + functionType = vectorNorm; + operatorType = identity; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); + } + if( testFunction == "heaviside-of-vector-norm" ) + { + typedef VectorNorm< Dimensions, Real > FunctionType; + typedef Heaviside< Dimensions, Real > OperatorType; + functionType = vectorNorm; + operatorType = heaviside; + return ( setupFunction< FunctionType >( parameters, prefix ) && + setupOperator< OperatorType >( parameters, prefix ) ); } std::cerr << "Unknown function " << testFunction << std::endl; return false; @@ -246,11 +383,20 @@ operator = ( const TestFunction& function ) case blob: this->copyFunction< Blob< FunctionDimensions, Real > >( function.function ); break; + + case paraboloidSDF: + this->copyFunction< Paraboloid< FunctionDimensions, Real > >( function.function ); + break; + case sinBumpsSDF: + this->copyFunction< SinBumpsSDF< FunctionDimensions, Real > >( function.function ); + break; + case sinWaveSDF: + this->copyFunction< SinWaveSDF< FunctionDimensions, Real > >( function.function ); + break; default: TNL_ASSERT( false, ); break; } - } template< int FunctionDimensions, @@ -263,9 +409,10 @@ __cuda_callable__ Real TestFunction< FunctionDimensions, Real, Device >:: getPartialDerivative( const VertexType& vertex, - const Real& time ) const + const Real& time ) const { using namespace TNL::Functions::Analytic; + using namespace TNL::Operators::Analytic; Real scale( 1.0 ); switch( this->timeDependence ) { @@ -286,32 +433,138 @@ getPartialDerivative( const VertexType& vertex, switch( functionType ) { case constant: - return scale * ( ( Constant< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef Constant< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + case paraboloid: + { + typedef Paraboloid< Dimensions, Real > FunctionType; + if( operatorType == identity ) + { + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + if( operatorType == heaviside ) + { + typedef Heaviside< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + } case expBump: - return scale * ( ( ExpBump< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef ExpBump< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } case sinBumps: - return scale * ( ( SinBumps< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef SinBumps< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } case sinWave: - return scale * ( ( SinWave< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef SinWave< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } case cylinder: - return scale * ( ( Cylinder< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef Cylinder< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } case flowerpot: - return scale * ( ( Flowerpot< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef Flowerpot< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } case twins: - return scale * ( ( Twins< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef Twins< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } case pseudoSquare: - return scale * ( ( PseudoSquare< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef PseudoSquare< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } case blob: - return scale * ( ( Blob< Dimensions, Real >* ) function )-> - template getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + { + typedef Blob< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + case vectorNorm: + { + typedef VectorNorm< Dimensions, Real > FunctionType; + if( operatorType == identity ) + { + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + if( operatorType == heaviside ) + { + typedef Heaviside< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + } + case sinBumpsSDF: + { + typedef SinBumpsSDF< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + case sinWaveSDF: + { + typedef SinWaveSDF< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + case paraboloidSDF: + { + typedef ParaboloidSDF< Dimensions, Real > FunctionType; + typedef Identity< Dimensions, Real > OperatorType; + + return scale * ( ( OperatorType* ) this->operator_ )-> + template getPartialDerivative< FunctionType, XDiffOrder, YDiffOrder, ZDiffOrder >( * ( FunctionType*) this->function, vertex, time ); + } + default: return 0.0; } @@ -348,38 +601,91 @@ getTimeDerivative( const VertexType& vertex, switch( functionType ) { case constant: - return scale * ( ( Constant< Dimensions, Real >* ) function )-> + { + typedef Constant< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> + getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } + case paraboloid: + { + typedef Paraboloid< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } case expBump: - return scale * ( ( ExpBump< Dimensions, Real >* ) function )-> + { + typedef ExpBump< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } case sinBumps: - return scale * ( ( SinBumps< Dimensions, Real >* ) function )-> + { + typedef SinBumps< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } case sinWave: - return scale * ( ( SinWave< Dimensions, Real >* ) function )-> + { + typedef SinWave< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); break; + } case cylinder: - return scale * ( ( Cylinder< Dimensions, Real >* ) function )-> + { + typedef Cylinder< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); break; + } case flowerpot: - return scale * ( ( Flowerpot< Dimensions, Real >* ) function )-> + { + typedef Flowerpot< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); break; + } case twins: - return scale * ( ( Twins< Dimensions, Real >* ) function )-> + { + typedef Twins< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); break; + } case pseudoSquare: - return scale * ( ( PseudoSquare< Dimensions, Real >* ) function )-> + { + typedef PseudoSquare< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); break; + } case blob: - return scale * ( ( Blob< Dimensions, Real >* ) function )-> + { + typedef Blob< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); break; + } + + + case paraboloidSDF: + { + typedef ParaboloidSDF< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> + getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } + case sinBumpsSDF: + { + typedef SinBumpsSDF< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> + getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } + case sinWaveSDF: + { + typedef SinWaveSDF< Dimensions, Real > FunctionType; + return scale * ( ( FunctionType* ) function )-> + getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } default: return 0.0; } @@ -405,6 +711,26 @@ deleteFunction() } } +template< int FunctionDimensions, + typename Real, + typename Device > + template< typename OperatorType > +void +TestFunction< FunctionDimensions, Real, Device >:: +deleteOperator() +{ + if( std::is_same< Device, Devices::Host >::value ) + { + if( operator_ ) + delete ( OperatorType * ) operator_; + } + if( std::is_same< Device, Devices::Cuda >::value ) + { + if( operator_ ) + Devices::Cuda::freeFromDevice( ( OperatorType * ) operator_ ); + } +} + template< int FunctionDimensions, typename Real, typename Device > @@ -413,35 +739,112 @@ TestFunction< FunctionDimensions, Real, Device >:: deleteFunctions() { using namespace TNL::Functions::Analytic; + using namespace TNL::Operators::Analytic; switch( functionType ) { case constant: - deleteFunction< Constant< Dimensions, Real> >(); - break; + { + typedef Constant< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); + break; + } + case paraboloid: + { + typedef Paraboloid< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + if( operatorType == identity ) + deleteOperator< Identity< Dimensions, Real > >(); + if( operatorType == heaviside ) + deleteOperator< Heaviside< Dimensions, Real > >(); + break; + } case expBump: - deleteFunction< ExpBump< Dimensions, Real> >(); + { + typedef ExpBump< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); break; + } case sinBumps: - deleteFunction< SinBumps< Dimensions, Real> >(); + { + typedef SinBumps< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); break; + } case sinWave: - deleteFunction< SinWave< Dimensions, Real> >(); + { + typedef SinWave< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); break; + } case cylinder: - deleteFunction< Cylinder< Dimensions, Real> >(); + { + typedef Cylinder< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); break; + } case flowerpot: - deleteFunction< Flowerpot< Dimensions, Real> >(); + { + typedef Flowerpot< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); break; + } case twins: - deleteFunction< Twins< Dimensions, Real> >(); + { + typedef Twins< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); break; + } case pseudoSquare: - deleteFunction< PseudoSquare< Dimensions, Real> >(); + { + typedef PseudoSquare< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); break; + } case blob: - deleteFunction< Blob< Dimensions, Real> >(); - break; + { + typedef Blob< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); + break; + } + case vectorNorm: + { + typedef VectorNorm< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); + break; + } + + + case paraboloidSDF: + { + typedef ParaboloidSDF< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); + break; + } + case sinBumpsSDF: + { + typedef SinBumpsSDF< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); + break; + } + case sinWaveSDF: + { + typedef SinWaveSDF< Dimensions, Real> FunctionType; + deleteFunction< FunctionType >(); + deleteOperator< Identity< Dimensions, Real > >(); + break; + } } } @@ -484,7 +887,6 @@ printFunction( std::ostream& str ) const Devices::Cuda::print( f, str ); return str; } - return str; } template< int FunctionDimensions, diff --git a/src/TNL/Functions/VectorField.h b/src/TNL/Functions/VectorField.h new file mode 100644 index 0000000000000000000000000000000000000000..5f98b65fcc1370166c38e49760fb7836eeecfd7c --- /dev/null +++ b/src/TNL/Functions/VectorField.h @@ -0,0 +1,278 @@ +/*************************************************************************** + VectorField.h - description + ------------------- + begin : Feb 6, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Domain.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Functions/MeshFunction.h> +#include <TNL/Functions/VectorFieldGnuplotWriter.h> + +namespace TNL { +namespace Functions { + +template< int Size, + typename Function > +class VectorField + : public Functions::Domain< Function::getDomainDimensions(), + Function::getDomainType() > +{ + public: + + typedef Function FunctionType; + typedef typename FunctionType::RealType RealType; + typedef typename FunctionType::VertexType VertexType; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + for( int i = 0; i < Size; i++ ) + FunctionType::configSetup( config, prefix + String( i ) + "-" ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + for( int i = 0; i < Size; i++ ) + if( ! vectorField[ i ].setup( parameters, prefix + String( i ) + "-" ) ) + { + std::cerr << "Unable to setup " << i << "-th coordinate of the vector field." << std::endl; + return false; + } + return true; + } + + __cuda_callable__ + const FunctionType& operator[]( int i ) const + { + return this->vectorField[ i ]; + } + + __cuda_callable__ + FunctionType& operator[]( int i ) + { + return this->vectorField[ i ]; + } + + protected: + + Containers::StaticArray< Size, FunctionType > vectorField; +}; + + +template< int Size, + typename Mesh, + int MeshEntityDimensions, + typename Real > +class VectorField< Size, MeshFunction< Mesh, MeshEntityDimensions, Real > > +: public Functions::Domain< MeshFunction< Mesh, MeshEntityDimensions, Real >::getDomainDimensions(), + MeshFunction< Mesh, MeshEntityDimensions, Real >::getDomainType() >, + public Object +{ + public: + + typedef Mesh MeshType; + typedef Real RealType; + typedef SharedPointer< MeshType > MeshPointer; + typedef MeshFunction< MeshType, MeshEntityDimensions, RealType > FunctionType; + typedef SharedPointer< FunctionType > FunctionPointer; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + typedef VectorField< Size, MeshFunction< Mesh, MeshEntityDimensions, RealType > > ThisType; + typedef Containers::StaticVector< Size, RealType > VectorType; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + for( int i = 0; i < Size; i++ ) + FunctionType::configSetup( config, prefix + String( i ) + "-" ); + } + + VectorField() {}; + + VectorField( const MeshPointer& meshPointer ) + { + for( int i = 0; i < Size; i++ ) + this->vectorField[ i ]->setMesh( meshPointer ); + }; + + static String getType() + { + return String( "Functions::VectorField< " ) + + String( Size) + ", " + + FunctionType::getType() + + " >"; + } + + String getTypeVirtual() const + { + return this->getType(); + } + + static String getSerializationType() + { + return String( "Functions::VectorField< " ) + + String( Size) + ", " + + FunctionType::getSerializationType() + + " >"; + } + + virtual String getSerializationTypeVirtual() const + { + return this->getSerializationType(); + } + + + void setMesh( const MeshPointer& meshPointer ) + { + for( int i = 0; i < Size; i++ ) + this->vectorField[ i ]->setMesh( meshPointer ); + } + + template< typename Device = Devices::Host > + __cuda_callable__ + const MeshType& getMesh() const + { + return this->vectorField[ 0 ].template getData< Device >().template getMesh< Device >(); + } + + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + for( int i = 0; i < Size; i++ ) + if( ! vectorField[ i ].setup( meshPointer, parameters, prefix + String( i ) + "-" ) ) + { + std::cerr << "Unable to setup " << i << "-th coordinate of the vector field." << std::endl; + return false; + } + return true; + } + + static IndexType getDofs( const MeshPointer& meshPointer ) + { + return Size * FunctionType::getDofs( meshPointer ); + } + + __cuda_callable__ + const FunctionPointer& operator[]( int i ) const + { + return this->vectorField[ i ]; + } + + __cuda_callable__ + FunctionPointer& operator[]( int i ) + { + return this->vectorField[ i ]; + } + + __cuda_callable__ + VectorType getVector( const IndexType index ) const + { + VectorType v; + for( int i = 0; i < Size; i++ ) + v[ i ] = ( *this->vectorField[ i ] )[ index ]; + return v; + } + + template< typename EntityType > + __cuda_callable__ + VectorType getVector( const EntityType& meshEntity ) const + { + VectorType v; + for( int i = 0; i < Size; i++ ) + v[ i ] = ( *this->vectorField[ i ] )( meshEntity ); + return v; + } + + bool save( File& file ) const + { + if( ! Object::save( file ) ) + return false; + for( int i = 0; i < Size; i++ ) + if( ! vectorField[ i ]->save( file ) ) + return false; + return true; + } + + bool load( File& file ) + { + if( ! Object::load( file ) ) + return false; + for( int i = 0; i < Size; i++ ) + if( ! vectorField[ i ]->load( file ) ) + return false; + return true; + } + + bool boundLoad( File& file ) + { + if( ! Object::load( file ) ) + return false; + for( int i = 0; i < Size; i++ ) + if( ! vectorField[ i ]->boundLoad( file ) ) + return false; + return true; + } + + bool write( const String& fileName, + const String& format = "vtk", + const double& scale = 1.0 ) const + { + std::fstream file; + file.open( fileName.getString(), std::ios::out ); + if( ! file ) + { + std::cerr << "Unable to open a file " << fileName << "." << std::endl; + return false; + } + if( format == "vtk" ) + return false; //MeshFunctionVTKWriter< ThisType >::write( *this, file ); + else if( format == "gnuplot" ) + return VectorFieldGnuplotWriter< ThisType >::write( *this, file, scale ); + else { + std::cerr << "Unknown output format: " << format << std::endl; + return false; + } + return true; + } + + using Object::save; + + using Object::load; + + using Object::boundLoad; + + protected: + + Containers::StaticArray< Size, FunctionPointer > vectorField; + +}; + +template< int Dimensions, + typename Function > +std::ostream& operator << ( std::ostream& str, const VectorField< Dimensions, Function >& f ) +{ + for( int i = 0; i < Dimensions; i++ ) + { + str << "[ " << f[ i ] << " ]"; + if( i < Dimensions - 1 ) + str << ", "; + } + return str; +} + + +} //namespace Functions +} //namepsace TNL diff --git a/src/TNL/Functions/VectorFieldGnuplotWriter.h b/src/TNL/Functions/VectorFieldGnuplotWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..41b59d511d680568d62ed545a8f230efc43dd575 --- /dev/null +++ b/src/TNL/Functions/VectorFieldGnuplotWriter.h @@ -0,0 +1,195 @@ +/*************************************************************************** + VectorFieldGnuplotWriter.h - description + ------------------- + begin : Feb 16, 2017 + copyright : (C) 2017 by oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Meshes/Grid.h> + +namespace TNL { +namespace Functions { + +template< int, typename > class VectorField; + +template< typename VectorField > +class VectorFieldGnuplotWriter +{ + public: + + static bool write( const VectorField& function, + std::ostream& str, + const double& scale ); +}; + +/*** + * 1D grids cells + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > > > +{ + public: + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 1, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + +/*** + * 1D grids vertices + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > > > +{ + public: + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 0, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + + +/*** + * 2D grids cells + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > > > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 2, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + +/*** + * 2D grids faces + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > > > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 1, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + +/*** + * 2D grids vertices + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > > > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 0, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + + +/*** + * 3D grids cells + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > > > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 3, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + +/*** + * 3D grids faces + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > > > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 2, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + +/*** + * 3D grids vertices + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +class VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > > > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Functions::VectorField< VectorFieldSize, MeshFunction< MeshType, 0, RealType > > VectorFieldType; + + static bool write( const VectorFieldType& function, + std::ostream& str, + const double& scale ); +}; + +} // namespace Functions +} // namespace TNL + +#include <TNL/Functions/VectorFieldGnuplotWriter_impl.h> diff --git a/src/TNL/Functions/VectorFieldGnuplotWriter_impl.h b/src/TNL/Functions/VectorFieldGnuplotWriter_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..6ec84a722e7897fb0d58cc226628c208000dc86e --- /dev/null +++ b/src/TNL/Functions/VectorFieldGnuplotWriter_impl.h @@ -0,0 +1,394 @@ +/*************************************************************************** + VectorFieldGnuplotWriter.h - description + ------------------- + begin : Feb 16, 2017 + copyright : (C) 2017 by oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <iostream> +#include <TNL/Functions/VectorFieldGnuplotWriter.h> + +namespace TNL { +namespace Functions { + +template< typename VectorField > +bool +VectorFieldGnuplotWriter< VectorField >:: +write( const VectorField& vectorField, + std::ostream& str, + const double& scale ) +{ + std::cerr << "Gnuplot writer for mesh vectorFields defined on mesh type " << VectorField::MeshType::getType() << " is not (yet) implemented." << std::endl; + return false; +} + +/**** + * 1D grid, cells + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 1, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typename MeshType::Cell entity( mesh ); + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() < mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + return true; +} + +/**** + * 1D grid, vertices + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, 0, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typename MeshType::Vertex entity( mesh ); + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() <= mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + return true; +} + + +/**** + * 2D grid, cells + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 2, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typename MeshType::Cell entity( mesh ); + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() < mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() < mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + return true; +} + +/**** + * 2D grid, faces + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 1, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typedef typename MeshType::Face EntityType; + typedef typename EntityType::EntityOrientationType EntityOrientation; + EntityType entity( mesh ); + + entity.setOrientation( EntityOrientation( 1.0, 0.0 ) ); + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() < mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() <= mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + + entity.setOrientation( EntityOrientation( 0.0, 1.0 ) ); + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() < mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + + { + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() <= mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + return true; +} + + +/**** + * 2D grid, vertices + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, 0, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typename MeshType::Vertex entity( mesh ); + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() <= mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() <= mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + return true; +} + + +/**** + * 3D grid, cells + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 3, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typename MeshType::Cell entity( mesh ); + for( entity.getCoordinates().z() = 0; + entity.getCoordinates().z() < mesh.getDimensions().z(); + entity.getCoordinates().z() ++ ) + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() < mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() < mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y() << " " << v.z(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + return true; +} + +/**** + * 3D grid, faces + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 2, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typedef typename MeshType::Face EntityType; + typedef typename EntityType::EntityOrientationType EntityOrientation; + EntityType entity( mesh ); + + entity.setOrientation( EntityOrientation( 1.0, 0.0, 0.0 ) ); + for( entity.getCoordinates().z() = 0; + entity.getCoordinates().z() < mesh.getDimensions().z(); + entity.getCoordinates().z() ++ ) + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() < mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() <= mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y() << " " << v.z(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + + entity.setOrientation( EntityOrientation( 0.0, 1.0, 0.0 ) ); + for( entity.getCoordinates().z() = 0; + entity.getCoordinates().z() < mesh.getDimensions().z(); + entity.getCoordinates().z() ++ ) + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() < mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() <= mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y() << " " << v.z(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + + entity.setOrientation( EntityOrientation( 0.0, 0.0, 1.0 ) ); + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() < mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() <= mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + for( entity.getCoordinates().z() = 0; + entity.getCoordinates().z() < mesh.getDimensions().z(); + entity.getCoordinates().z() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y() << " " << v.z(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + return true; +} + + +/**** + * 3D grid, vertices + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + int VectorFieldSize > +bool +VectorFieldGnuplotWriter< VectorField< VectorFieldSize, MeshFunction< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, 0, Real > > >:: +write( const VectorFieldType& vectorField, + std::ostream& str, + const double& scale ) +{ + const MeshType& mesh = vectorField.getMesh(); + typename MeshType::Vertex entity( mesh ); + for( entity.getCoordinates().z() = 0; + entity.getCoordinates().z() <= mesh.getDimensions().z(); + entity.getCoordinates().z() ++ ) + for( entity.getCoordinates().y() = 0; + entity.getCoordinates().y() <= mesh.getDimensions().y(); + entity.getCoordinates().y() ++ ) + { + for( entity.getCoordinates().x() = 0; + entity.getCoordinates().x() <= mesh.getDimensions().x(); + entity.getCoordinates().x() ++ ) + { + entity.refresh(); + typename MeshType::VertexType v = entity.getCenter(); + str << v.x() << " " << v.y() << " " << v.z(); + for( int i = 0; i < VectorFieldSize; i++ ) + str << " " << scale * vectorField[ i ]->getData().getElement( entity.getIndex() ); + str << std::endl; + } + str << std::endl; + } + return true; +} + +} // namespace Functions +} // namespace TNL + diff --git a/src/TNL/Images/PGMImage_impl.h b/src/TNL/Images/PGMImage_impl.h index eb6d59d3c15a54993a83d277880703f6b3d3371e..8939dd71d1156a7eabd030266fd5d57519fcc31d 100644 --- a/src/TNL/Images/PGMImage_impl.h +++ b/src/TNL/Images/PGMImage_impl.h @@ -186,16 +186,15 @@ write( const Meshes::Grid< 2, Real, Device, Index >& grid, unsigned char color = 255 * vector.getElement( cell.getIndex() ); if ( ! this->binary ) - { - int color_aux = (int)color; - this->file << color_aux; - this->file << ' '; - } - else this->file << color; - } - + { + int color_aux = (int)color; + this->file << color_aux; + this->file << ' '; + } + else this->file << color; + } if ( ! this->binary ) - this->file << '\n'; + this->file << '\n'; } return true; } diff --git a/src/TNL/Math.h b/src/TNL/Math.h index 62ff2bb95e7aaac0b7e9686ef43019f58cff9ae0..1ff7cc923c8eed40b6676bed16e8371137b88c04 100644 --- a/src/TNL/Math.h +++ b/src/TNL/Math.h @@ -182,9 +182,9 @@ template< class T > __cuda_callable__ T sign( const T& a ) { - if( a < ( T ) 0 ) return -1; - if( a == ( T ) 0 ) return 0; - return 1; + if( a < ( T ) 0 ) return ( T ) -1; + if( a == ( T ) 0 ) return ( T ) 0; + return ( T ) 1; }; template< typename Real > diff --git a/src/TNL/Matrices/Dense_impl.h b/src/TNL/Matrices/Dense_impl.h index 783e3b6035a8120c2525da5a9832dd86ecef28ae..bec9ec70df66818844d2ceea852cd8c1d304958f 100644 --- a/src/TNL/Matrices/Dense_impl.h +++ b/src/TNL/Matrices/Dense_impl.h @@ -153,8 +153,8 @@ template< typename Real, typename Device, typename Index > bool Dense< Real, Device, Index >::setElement( const IndexType row, - const IndexType column, - const RealType& value ) + const IndexType column, + const RealType& value ) { this->values.setElement( this->getElementIndex( row, column ), value ); return true; @@ -166,9 +166,9 @@ template< typename Real, typename Index > __cuda_callable__ bool Dense< Real, Device, Index >::addElementFast( const IndexType row, - const IndexType column, - const RealType& value, - const RealType& thisElementMultiplicator ) + const IndexType column, + const RealType& value, + const RealType& thisElementMultiplicator ) { TNL_ASSERT( row >= 0 && row < this->getRows() && column >= 0 && column < this->getColumns(), diff --git a/src/TNL/Meshes/GridDetails/Grid1D.h b/src/TNL/Meshes/GridDetails/Grid1D.h index d2a96c4ad5bae4bf19374c90a60cfbd5d146b100..514e964a94f6e569b8757d0c72aa14a99e0b374f 100644 --- a/src/TNL/Meshes/GridDetails/Grid1D.h +++ b/src/TNL/Meshes/GridDetails/Grid1D.h @@ -63,30 +63,35 @@ class Grid< 1, Real, Device, Index > : public Object void setDimensions( const CoordinatesType& dimensions ); - __cuda_callable__ inline + __cuda_callable__ const CoordinatesType& getDimensions() const; void setDomain( const VertexType& origin, const VertexType& proportions ); __cuda_callable__ - inline const VertexType& getOrigin() const; + const VertexType& getOrigin() const; __cuda_callable__ - inline const VertexType& getProportions() const; - + const VertexType& getProportions() const; + template< typename EntityType > __cuda_callable__ - inline IndexType getEntitiesCount() const; - + IndexType getEntitiesCount() const; + + template< int EntiytDimensions > + __cuda_callable__ + IndexType getEntitiesCount() const; + + template< typename EntityType > __cuda_callable__ - inline EntityType getEntity( const IndexType& entityIndex ) const; - + EntityType getEntity( const IndexType& entityIndex ) const; + template< typename EntityType > __cuda_callable__ - inline Index getEntityIndex( const EntityType& entity ) const; - + Index getEntityIndex( const EntityType& entity ) const; + template< typename EntityType > __cuda_callable__ RealType getEntityMeasure( const EntityType& entity ) const; @@ -95,14 +100,14 @@ class Grid< 1, Real, Device, Index > : public Object inline const RealType& getCellMeasure() const; __cuda_callable__ - inline const VertexType& getSpaceSteps() const; + const VertexType& getSpaceSteps() const { return this->spaceSteps;} template< int xPow > __cuda_callable__ - inline const RealType& getSpaceStepsProducts() const; - + const RealType& getSpaceStepsProducts() const; + __cuda_callable__ - inline RealType getSmallestSpaceStep() const; + RealType getSmallestSpaceStep() const; template< typename GridFunction > diff --git a/src/TNL/Meshes/GridDetails/Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Grid1D_impl.h index cac0ad3da8884483d4f48e91b62baba5b30b0dda..fc82381ebb27dffe37df27dd30caec473c8ffa56 100644 --- a/src/TNL/Meshes/GridDetails/Grid1D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid1D_impl.h @@ -168,6 +168,29 @@ getEntitiesCount() const return -1; } +template< typename Real, + typename Device, + typename Index > + template< int EntityDimensions > +__cuda_callable__ inline +Index +Grid< 1, Real, Device, Index >:: +getEntitiesCount() const +{ + static_assert( EntityDimensions <= 1 && + EntityDimensions >= 0, "Wrong grid entity dimensions." ); + + switch( EntityDimensions ) + { + case 1: + return this->numberOfCells; + case 0: + return this->numberOfVertices; + } + return -1; +} + + template< typename Real, typename Device, typename Index > @@ -221,16 +244,16 @@ getCellMeasure() const return this->template getSpaceStepsProducts< 1 >(); } -template< typename Real, +/*template< typename Real, typename Device, typename Index > -__cuda_callable__ inline -const typename Grid< 1, Real, Device, Index >::VertexType& +__cuda_callable__ +typename Grid< 1, Real, Device, Index >::VertexType Grid< 1, Real, Device, Index >:: getSpaceSteps() const { return this->spaceSteps; -} +}*/ template< typename Real, typename Device, diff --git a/src/TNL/Meshes/GridDetails/Grid2D.h b/src/TNL/Meshes/GridDetails/Grid2D.h index 6c7dfca7f61089f61c8ec2d9e5d4be995f3c9906..1a403508f7d0b69d5ec4620436df2769b63c7096 100644 --- a/src/TNL/Meshes/GridDetails/Grid2D.h +++ b/src/TNL/Meshes/GridDetails/Grid2D.h @@ -69,27 +69,32 @@ class Grid< 2, Real, Device, Index > : public Object void setDimensions( const CoordinatesType& dimensions ); __cuda_callable__ - inline const CoordinatesType& getDimensions() const; + const CoordinatesType& getDimensions() const; void setDomain( const VertexType& origin, const VertexType& proportions ); __cuda_callable__ - inline const VertexType& getOrigin() const; + const VertexType& getOrigin() const; __cuda_callable__ - inline const VertexType& getProportions() const; + const VertexType& getProportions() const; + + template< int EntityDimensions > + __cuda_callable__ + IndexType getEntitiesCount() const; + template< typename EntityType > __cuda_callable__ - inline IndexType getEntitiesCount() const; - + IndexType getEntitiesCount() const; + template< typename EntityType > __cuda_callable__ - inline EntityType getEntity( const IndexType& entityIndex ) const; - + EntityType getEntity( const IndexType& entityIndex ) const; + template< typename EntityType > __cuda_callable__ - inline Index getEntityIndex( const EntityType& entity ) const; + Index getEntityIndex( const EntityType& entity ) const; template< typename EntityType > __cuda_callable__ @@ -99,14 +104,14 @@ class Grid< 2, Real, Device, Index > : public Object inline const RealType& getCellMeasure() const; __cuda_callable__ - inline const VertexType& getSpaceSteps() const; + const VertexType& getSpaceSteps() const { return this->spaceSteps; } template< int xPow, int yPow > __cuda_callable__ - inline const RealType& getSpaceStepsProducts() const; - + const RealType& getSpaceStepsProducts() const; + __cuda_callable__ - inline RealType getSmallestSpaceStep() const; + RealType getSmallestSpaceStep() const; template< typename GridFunction > diff --git a/src/TNL/Meshes/GridDetails/Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Grid2D_impl.h index 4d0d87fb2f1d7f752c6330c94c90137b7cb3830d..f0aa205d420be259ce63cfae6a98dcd9644d25c1 100644 --- a/src/TNL/Meshes/GridDetails/Grid2D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid2D_impl.h @@ -196,6 +196,31 @@ const typename Grid< 2, Real, Device, Index > :: VertexType& return this->proportions; } +template< typename Real, + typename Device, + typename Index > + template< int EntityDimensions > +__cuda_callable__ inline +Index +Grid< 2, Real, Device, Index >:: +getEntitiesCount() const +{ + static_assert( EntityDimensions <= 2 && + EntityDimensions >= 0, "Wrong grid entity dimensions." ); + + switch( EntityDimensions ) + { + case 2: + return this->numberOfCells; + case 1: + return this->numberOfFaces; + case 0: + return this->numberOfVertices; + } + return -1; +} + + template< typename Real, typename Device, typename Index > @@ -274,16 +299,16 @@ getCellMeasure() const } -template< typename Real, +/*template< typename Real, typename Device, typename Index > -__cuda_callable__ inline -const typename Grid< 2, Real, Device, Index >::VertexType& +__cuda_callable__ +typename Grid< 2, Real, Device, Index >::VertexType& Grid< 2, Real, Device, Index >:: getSpaceSteps() const { return this->spaceSteps; -} +}*/ template< typename Real, typename Device, diff --git a/src/TNL/Meshes/GridDetails/Grid3D.h b/src/TNL/Meshes/GridDetails/Grid3D.h index 860b5e473528cf0de601648a77bb0bd6f0aba490..fd1e91ac0e1298b05f917a1df383db989437b11f 100644 --- a/src/TNL/Meshes/GridDetails/Grid3D.h +++ b/src/TNL/Meshes/GridDetails/Grid3D.h @@ -62,28 +62,32 @@ class Grid< 3, Real, Device, Index > : public Object void setDimensions( const CoordinatesType& ); __cuda_callable__ - inline const CoordinatesType& getDimensions() const; + const CoordinatesType& getDimensions() const; void setDomain( const VertexType& origin, const VertexType& proportions ); __cuda_callable__ - inline const VertexType& getOrigin() const; + const VertexType& getOrigin() const; __cuda_callable__ - inline const VertexType& getProportions() const; + const VertexType& getProportions() const; template< typename EntityType > __cuda_callable__ - inline IndexType getEntitiesCount() const; - + IndexType getEntitiesCount() const; + + template< int Dimensions > + __cuda_callable__ + IndexType getEntitiesCount() const; + template< typename EntityType > __cuda_callable__ - inline EntityType getEntity( const IndexType& entityIndex ) const; - + EntityType getEntity( const IndexType& entityIndex ) const; + template< typename EntityType > __cuda_callable__ - inline Index getEntityIndex( const EntityType& entity ) const; - + Index getEntityIndex( const EntityType& entity ) const; + template< typename EntityType > __cuda_callable__ RealType getEntityMeasure( const EntityType& entity ) const; @@ -92,16 +96,16 @@ class Grid< 3, Real, Device, Index > : public Object inline const RealType& getCellMeasure() const; __cuda_callable__ - inline const VertexType& getSpaceSteps() const; - + const VertexType& getSpaceSteps() const { return this->spaceSteps; }; + template< int xPow, int yPow, int zPow > __cuda_callable__ - inline const RealType& getSpaceStepsProducts() const; + const RealType& getSpaceStepsProducts() const; __cuda_callable__ - inline RealType getSmallestSpaceStep() const; - + RealType getSmallestSpaceStep() const; + template< typename GridFunction > typename GridFunction::RealType getAbsMax( const GridFunction& f ) const; diff --git a/src/TNL/Meshes/GridDetails/Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Grid3D_impl.h index d9cdaa1dfe62359328f11c369cd16d0a43d168d5..9282d1500e1ccb18d58810654dfdbc989304e73c 100644 --- a/src/TNL/Meshes/GridDetails/Grid3D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid3D_impl.h @@ -268,6 +268,32 @@ getEntitiesCount() const return -1; } +template< typename Real, + typename Device, + typename Index > + template< int EntityDimensions > +__cuda_callable__ inline +Index +Grid< 3, Real, Device, Index >:: +getEntitiesCount() const +{ + static_assert( EntityDimensions <= 3 && + EntityDimensions >= 0, "Wrong grid entity dimensions." ); + + switch( EntityDimensions ) + { + case 3: + return this->numberOfCells; + case 2: + return this->numberOfFaces; + case 1: + return this->numberOfEdges; + case 0: + return this->numberOfVertices; + } + return -1; +} + template< typename Real, typename Device, typename Index > @@ -321,16 +347,16 @@ getCellMeasure() const return this->template getSpaceStepsProducts< 1, 1, 1 >(); } -template< typename Real, +/*template< typename Real, typename Device, typename Index > -__cuda_callable__ inline -const typename Grid< 3, Real, Device, Index >::VertexType& +__cuda_callable__ +typename Grid< 3, Real, Device, Index >::VertexType& Grid< 3, Real, Device, Index >:: getSpaceSteps() const { return this->spaceSteps; -} +}*/ template< typename Real, typename Device, diff --git a/src/TNL/Operators/Advection/CMakeLists.txt b/src/TNL/Operators/Advection/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..5dff0bfc3dc52d76e01bfb2b8102946c27c451dd --- /dev/null +++ b/src/TNL/Operators/Advection/CMakeLists.txt @@ -0,0 +1,6 @@ +SET( headers LaxFridrichs.h ) + +SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Operators/Advection ) + + +INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Operators/Advection ) diff --git a/src/TNL/Operators/Advection/LaxFridrichs.h b/src/TNL/Operators/Advection/LaxFridrichs.h new file mode 100644 index 0000000000000000000000000000000000000000..9b939e184cee92bfbdef1edff999b15cdf539aee --- /dev/null +++ b/src/TNL/Operators/Advection/LaxFridrichs.h @@ -0,0 +1,317 @@ +#ifndef LaxFridrichs_H +#define LaxFridrichs_H + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/SharedPointer.h> + +namespace TNL { + namespace Operators { + namespace Advection { + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType, + typename VelocityFunction = Functions::MeshFunction< Mesh > > +class LaxFridrichs +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename VelocityFunction > +class LaxFridrichs< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef SharedPointer< MeshType > MeshPointer; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef VelocityFunction VelocityFunctionType; + typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + LaxFridrichs() + : artificialViscosity( 1.0 ) {} + + LaxFridrichs( const VelocityFieldPointer& velocityField ) + : artificialViscosity( 1.0 ), velocityField( velocityField ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + return true; + } + + static String getType(); + + void setViscosity(const Real& artificalViscosity) + { + this->artificialViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocityField( const VelocityFieldPointer& velocityField ) + { + this->velocityField = velocityField; + } + + const VelocityFieldPointer& getVelocityField() const + { + return this->velocityField; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + return ( 0.5 / this->tau ) * this->artificialViscosity * ( u[ west ]- 2.0 * u[ center ] + u[ east ] ) - + FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ], entity, time ) * ( u[ east ] - u[ west ] ) * hxInverse * 0.5; + } + + protected: + + RealType tau; + + RealType artificialViscosity; + + VelocityFieldPointer velocityField; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename VelocityFunction > +class LaxFridrichs< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction > +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef SharedPointer< MeshType > MeshPointer; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef VelocityFunction VelocityFunctionType; + typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + LaxFridrichs() + : artificialViscosity( 1.0 ) {} + + LaxFridrichs( const VelocityFieldPointer& velocityField ) + : artificialViscosity( 1.0 ), velocityField( velocityField ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + return true; + } + + static String getType(); + + void setViscosity(const Real& artificalViscosity) + { + this->artificialViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocityField( const VelocityFieldPointer& velocityField ) + { + this->velocityField = velocityField; + } + + const VelocityFieldPointer& getVelocityField() const + { + return this->velocityField; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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 >(); + + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + return ( 0.25 / this->tau ) * this->artificialViscosity * ( u[ west ] + u[ east ] + u[ north ] + u[ south ] - 4.0 * u[ center ] ) - + 0.5 * ( FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ], entity, time ) * ( u[ east ] - u[ west ] ) * hxInverse + + FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 1 ], entity, time ) * ( u[ north ] - u[ south ] ) * hyInverse ); + } + + protected: + + RealType tau; + + RealType artificialViscosity; + + VelocityFieldPointer velocityField; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename VelocityFunction > +class LaxFridrichs< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef SharedPointer< MeshType > MeshPointer; + static const int Dimensions = MeshType::getMeshDimensions(); + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef VelocityFunction VelocityFunctionType; + typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + LaxFridrichs() + : artificialViscosity( 1.0 ) {} + + LaxFridrichs( const VelocityFieldPointer& velocityField ) + : artificialViscosity( 1.0 ), velocityField( velocityField ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + return true; + } + + static String getType(); + + void setViscosity(const Real& artificalViscosity) + { + this->artificialViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocityField( const VelocityFieldPointer& velocityField ) + { + this->velocityField = velocityField; + } + + const VelocityFieldPointer& getVelocityField() const + { + return this->velocityField; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + 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& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + 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 >(); + + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + return ( 0.25 / this->tau ) * this->artificialViscosity * ( u[ west ] + u[ east ] + u[ north ] + u[ south ] + u[ up ] + u[ down ] - 6.0 * u[ center ] ) - + 0.5 * ( FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ], entity, time ) * ( u[ east ] - u[ west ] ) * hxInverse + + FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 1 ], entity, time ) * ( u[ north ] - u[ south ] ) * hyInverse + + FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 2 ], entity, time ) * ( u[ up ] - u[ down ] ) * hzInverse ); + } + + protected: + + RealType tau; + + RealType artificialViscosity; + + VelocityFieldPointer velocityField; +}; + + }// namespace Advection + } // namepsace Operators +} // namespace TNL + +#endif /* LaxFridrichs_H */ diff --git a/src/TNL/Operators/Analytic/CMakeLists.txt b/src/TNL/Operators/Analytic/CMakeLists.txt new file mode 100755 index 0000000000000000000000000000000000000000..8cc44ea6f704cdb0086ab9925e60e7c580e125ac --- /dev/null +++ b/src/TNL/Operators/Analytic/CMakeLists.txt @@ -0,0 +1,11 @@ +SET( headers Sign.h + Heaviside.h + Identity.h + SmoothHeaviside.h + Shift.h + Rotation.h ) + +SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Operators/Analytic ) + + +INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/TNL/Operators/Analytic ) diff --git a/src/TNL/Operators/Analytic/Heaviside.h b/src/TNL/Operators/Analytic/Heaviside.h new file mode 100644 index 0000000000000000000000000000000000000000..4449998015aee2936bc7599843e3c40ed3f29d2b --- /dev/null +++ b/src/TNL/Operators/Analytic/Heaviside.h @@ -0,0 +1,83 @@ +/*************************************************************************** + Heaviside.h - description + ------------------- + begin : Feb 6, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Domain.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Functions/Domain.h> + +namespace TNL { +namespace Operators { +namespace Analytic { + + +template< int Dimensions, + typename Real = double > +class Heaviside : public Functions::Domain< Dimensions, Functions::SpaceDomain > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< Dimensions, + RealType > VertexType; + + Heaviside() : multiplicator( 1.0 ) {} + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "multiplicator", "Outer multiplicator of the Heaviside operator - -1.0 turns the function graph upside/down.", 1.0 ); + } + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->multiplicator = parameters.getParameter< double >( prefix + "multiplicator" ); + return true; + }; + + + template< typename Function > + __cuda_callable__ + RealType operator()( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + const RealType aux = function( vertex, time ); + if( aux > 0.0 ) + return 1.0; + return 0.0; + } + + template< typename Function, + int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ + RealType getPartialDerivative( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + return this->operator()( function, vertex, time ); + return 0.0; + } + + protected: + + RealType multiplicator; + +}; + +} // namespace Analytic +} // namespace Operators +} // namespace TNL \ No newline at end of file diff --git a/src/TNL/Operators/Analytic/Identity.h b/src/TNL/Operators/Analytic/Identity.h new file mode 100644 index 0000000000000000000000000000000000000000..fdc4824480735c3fe7e780966628340202370d72 --- /dev/null +++ b/src/TNL/Operators/Analytic/Identity.h @@ -0,0 +1,62 @@ +/*************************************************************************** + Identity.h - description + ------------------- + begin : Dec 5, 2013 + copyright : (C) 2013 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Domain.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Config/ParameterContainer.h> + +namespace TNL { +namespace Operators { +namespace Analytic { + + +template< int Dimensions, typename Real > +class Identity : public Functions::Domain< Dimensions, Functions::SpaceDomain > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< Dimensions, RealType > VertexType; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return true; + }; + + + template< typename Function > + __cuda_callable__ + RealType operator()( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + return function( vertex, time ); + } + + template< typename Function, + int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ + RealType getPartialDerivative( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + return function.getPartialDerivative< XDiffOrder, YDiffOrder, ZDiffOrder >( vertex, time ); + } + +}; + +} // namespace Analytic +} // namespace Operators +} // namespace TNL \ No newline at end of file diff --git a/src/TNL/Operators/Analytic/Rotation.h b/src/TNL/Operators/Analytic/Rotation.h new file mode 100644 index 0000000000000000000000000000000000000000..272e9ae85ca877e6bfa0caf551e055fb8aef5ae4 --- /dev/null +++ b/src/TNL/Operators/Analytic/Rotation.h @@ -0,0 +1,81 @@ +/*************************************************************************** + Rotation.h - description + ------------------- + begin : Feb 6, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Domain.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Config/ParameterContainer.h> + + +namespace TNL { +namespace Operators { +namespace Analytic { + + +// TODO: Implement RotationXY, RotationXZ and RotationYZ in all dimensions. +// Where it does not make sense, the operator does nothing. + +template< typename Real, + int Dimensions > +class RotationBase +{ + public: + typedef Real RealType; + typedef Containers::StaticVector< Dimenions, RealType > VertexType; + + RotationBase() : center( 0.0 ) {}; + + void setCenter( const VertexType& center ) + { + this->center = center; + } + + __cuda_callable__ + const VertexType& getCenter() const + { + return this->center; + } + + protected: + + VertexType center; +}; + +template< typename Function, + int Dimensions = Function::getDomainDimenions() > +class Rotation; + +template< typename Function, 1 > +class Rotation: public Functions::Domain< Function::getDomainDimenions(), + Function::getDomainType() > +{ + public: + + typedef typename Function::RealType RealType; + typedef Containers::StaticVector< Function::getDomainDimenions(), + RealType > VertexType; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ){}; + + + __cuda_callable__ + RealType operator()( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + return function( vertex, time ); + } +}; + +} // namespace Analytic +} // namespace Operators +} // namespace TNL diff --git a/src/TNL/Operators/Analytic/Shift.h b/src/TNL/Operators/Analytic/Shift.h new file mode 100644 index 0000000000000000000000000000000000000000..d5e8580ccf338972ed196d32f911d3655477d67f --- /dev/null +++ b/src/TNL/Operators/Analytic/Shift.h @@ -0,0 +1,91 @@ +/*************************************************************************** + Shift.h - description + ------------------- + begin : Feb 6, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Domain.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Config/ParameterContainer.h> +#include <TNL/Containers/StaticVector.h> + +namespace TNL { +namespace Operators { +namespace Analytic { + + +template< int Dimensions, typename Real > +class Shift : public Functions::Domain< Dimensions, Functions::SpaceDomain > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< Dimensions, RealType > VertexType; + + + Shift() : shift( 0.0 ) {}; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "shift-0", "x-coordinate of the shift vector.", 0.0 ); + config.addEntry< double >( prefix + "shift-1", "y-coordinate of the shift vector.", 0.0 ); + config.addEntry< double >( prefix + "shift-2", "z-coordinate of the shift vector.", 0.0 ); + } + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return shift.setup( parameters, prefix + "shift-" ); + }; + + + void setShift( const VertexType& shift ) + { + this->shift = shift; + } + + __cuda_callable__ + const VertexType& getShift() const + { + return this->shift; + } + + template< typename Function > + __cuda_callable__ + RealType operator()( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + return function( vertex - this->shift, time ); + } + + template< typename Function, + int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ + RealType getPartialDerivative( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + return this->operator()( function, vertex - this->shift, time ); + // TODO: implement the rest + } + + + protected: + + VertexType shift; +}; + +} // namespace Analytic +} // namespace Operators +} // namespace TNL diff --git a/src/TNL/Operators/Analytic/Sign.h b/src/TNL/Operators/Analytic/Sign.h new file mode 100644 index 0000000000000000000000000000000000000000..ea18af636270b28372c5196c0a85f88e95b6c445 --- /dev/null +++ b/src/TNL/Operators/Analytic/Sign.h @@ -0,0 +1,120 @@ +/*************************************************************************** + Sign.h - description + ------------------- + begin : Feb 6, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Domain.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Config/ParameterContainer.h> + +namespace TNL { +namespace Operators { +namespace Analytic { + + +template< int Dimensions, + typename Real > +class Sign : public Functions::Domain< Dimensions, Functions::SpaceDomain > +{ + public: + + typedef Real RealType; + typedef Containers::StaticVector< Dimensions, RealType > VertexType; + + Sign() + : positiveValue( 1.0 ), + negativeValue( -1.0 ), + zeroValue( 0.0 ) {} + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "positive-value", "Value returned for positive argument.", 1.0 ); + config.addEntry< double >( prefix + "negative-value", "Value returned for negative argument.", -1.0 ); + config.addEntry< double >( prefix + "zero-value", "Value returned for zero argument.", 0.0 ); + } + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->positiveValue = parameters.getParameter< double >( prefix + "positive-value" ); + this->negativeValue = parameters.getParameter< double >( prefix + "negative-value" ); + this->zeroValue = parameters.getParameter< double >( prefix + "zero-value" ); + return true; + }; + + void setPositiveValue( const RealType& value ) + { + this->positiveValue = value; + } + + const RealType& getPositiveValue() const + { + return this->positiveValue; + } + + void setNegativeValue( const RealType& value ) + { + this->negativeValue = value; + } + + const RealType& getNegativeValue() const + { + return this->negativeValue; + } + + void setZeroValue( const RealType& value ) + { + this->zeroValue = value; + } + + const RealType& getZeroValue() const + { + return this->zeroValue; + } + + template< typename Function > + __cuda_callable__ + RealType operator()( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + const RealType aux = function( vertex, time ); + if( aux > 0.0 ) + return this->positiveValue; + else + if( aux < 0.0 ) + return this->negativeValue; + return this->zeroValue; + } + + template< typename Function, + int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ + RealType getPartialDerivative( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + return this->operator()( function, vertex, time ); + return 0.0; + } + + protected: + + RealType positiveValue, negativeValue, zeroValue; + +}; + +} // namespace Analytic +} // namespace Operators +} // namespace TNL diff --git a/src/TNL/Operators/Analytic/SmoothHeaviside.h b/src/TNL/Operators/Analytic/SmoothHeaviside.h new file mode 100644 index 0000000000000000000000000000000000000000..e3f13c4d7fe8c3db79605f4556ff21106e4ca619 --- /dev/null +++ b/src/TNL/Operators/Analytic/SmoothHeaviside.h @@ -0,0 +1,79 @@ +/*************************************************************************** + SmoothHeaviside.h - description + ------------------- + begin : Feb 6, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Functions/Domain.h> +#include <TNL/Devices/Cuda.h> +#include <TNL/Config/ParameterContainer.h> + +namespace TNL { +namespace Operators { +namespace Analytic { + + +template< typename Function > +class SmoothHeaviside : public Functions::Domain< Function::getDomainDimenions(), + Function::getDomainTyep() > +{ + public: + + typedef typename Function::RealType RealType; + typedef Containers::StaticVector< Function::getDomainDimenions(), + RealType > VertexType; + + SmoothHeaviside() + : sharpness( 1.0 ){} + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ){}; + + + void setSharpness( const RealType& sharpness ) + { + this->sharpness = sharpness; + } + + __cuda_callable__ + const RealType getShaprness() const + { + return this->sharpness; + } + + __cuda_callable__ + RealType operator()( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + const RealType aux = function( vertex, time ); + return 1.0 / ( 1.0 + exp( -2.0 * sharpness * aux ) ); + } + + template< int XDiffOrder = 0, + int YDiffOrder = 0, + int ZDiffOrder = 0 > + __cuda_callable__ + RealType getPartialDerivative( const Function& function, + const VertexType& vertex, + const RealType& time = 0 ) const + { + if( XDiffOrder == 0 && YDiffOrder == 0 && ZDiffOrder == 0 ) + return this->operator()( function, vertex, time ); + // TODO: implement the rest + } + + protected: + + RealType sharpness; +}; + +} // namespace Analytic +} // namespace Operators +} // namespace TNL diff --git a/src/TNL/Operators/CMakeLists.txt b/src/TNL/Operators/CMakeLists.txt index dcdb7d3ddaae05cffedbe0d9468002b63ca41328..63385c2a49e16c771f1c7970180ddd97ac3be5f4 100755 --- a/src/TNL/Operators/CMakeLists.txt +++ b/src/TNL/Operators/CMakeLists.txt @@ -1,9 +1,12 @@ +ADD_SUBDIRECTORY( Advection ) +ADD_SUBDIRECTORY( Analytic ) ADD_SUBDIRECTORY( diffusion ) ADD_SUBDIRECTORY( euler ) ADD_SUBDIRECTORY( interpolants ) ADD_SUBDIRECTORY( operator-Q ) ADD_SUBDIRECTORY( operator-curvature ) + SET( headers DirichletBoundaryConditions.h ExactFunctionInverseOperator.h ExactIdentityOperator.h @@ -23,6 +26,11 @@ if( BUILD_CUDA) ${tnl_operators_diffusion_CUDA__SOURCES} ${tnl_operators_gradient_CUDA__SOURCES} ${tnl_operators_euler_CUDA__SOURCES} +# ${tnl_operators_godunov_CUDA__SOURCES} + ${tnl_operators_godunov-eikonal_CUDA__SOURCES} +# ${tnl_operators_upwind_CUDA__SOURCES} +# ${tnl_operators_upwind-eikonal_CUDA__SOURCES} + ${common_SOURCES} ${common_SOURCES} PARENT_SCOPE ) endif() @@ -31,6 +39,10 @@ set( tnl_operators_SOURCES ${tnl_operators_diffusion_SOURCES} ${tnl_operators_gradient_SOURCES} ${tnl_operators_euler_SOURCES} +# ${tnl_operators_godunov_SOURCES} + ${tnl_operators_godunov-eikonal_SOURCES} +# ${tnl_operators_upwind_SOURCES} +# ${tnl_operators_upwind-eikonal_SOURCES} ${common_SOURCES} PARENT_SCOPE ) diff --git a/src/TNL/Operators/NeumannBoundaryConditions.h b/src/TNL/Operators/NeumannBoundaryConditions.h index 1461135eebaa135043e1f60452a178f2633b4737..f39eb64744df7ecf29823ca79e92bdb494711d53 100644 --- a/src/TNL/Operators/NeumannBoundaryConditions.h +++ b/src/TNL/Operators/NeumannBoundaryConditions.h @@ -49,10 +49,22 @@ class NeumannBoundaryConditionsBase return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); } + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + void setFunction( const FunctionType& function ) { this->function = function; - } + }; FunctionType& getFunction() { @@ -112,7 +124,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, const auto& neighbourEntities = entity.getNeighbourEntities(); const IndexType& index = entity.getIndex(); if( entity.getCoordinates().x() == 0 ) - return u[ neighbourEntities.template getEntityIndex< 1 >() ] - entity.getMesh().getSpaceSteps().x() * + return u[ neighbourEntities.template getEntityIndex< 1 >() ] + entity.getMesh().getSpaceSteps().x() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); else return u[ neighbourEntities.template getEntityIndex< -1 >() ] + entity.getMesh().getSpaceSteps().x() * @@ -149,7 +161,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, { matrixRow.setElement( 0, index, 1.0 ); matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1 >(), -1.0 ); - b[ index ] = - entity.getMesh().getSpaceSteps().x() * + b[ index ] = entity.getMesh().getSpaceSteps().x() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } else @@ -207,7 +219,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, const IndexType& index = entity.getIndex(); if( entity.getCoordinates().x() == 0 ) { - return u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] - entity.getMesh().getSpaceSteps().x() * + return u[ neighbourEntities.template getEntityIndex< 1, 0 >() ] + entity.getMesh().getSpaceSteps().x() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) @@ -217,7 +229,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, } if( entity.getCoordinates().y() == 0 ) { - return u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] - entity.getMesh().getSpaceSteps().y() * + return u[ neighbourEntities.template getEntityIndex< 0, 1 >() ] + entity.getMesh().getSpaceSteps().y() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } // The following line is commented to avoid compiler warning @@ -256,7 +268,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, { matrixRow.setElement( 0, index, 1.0 ); matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1, 0 >(), -1.0 ); - b[ index ] = - entity.getMesh().getSpaceSteps().x() * + b[ index ] = entity.getMesh().getSpaceSteps().x() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) @@ -270,7 +282,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, { matrixRow.setElement( 0, index, 1.0 ); matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 1 >(), -1.0 ); - b[ index ] = - entity.getMesh().getSpaceSteps().y() * + b[ index ] = entity.getMesh().getSpaceSteps().y() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) @@ -326,7 +338,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, const IndexType& index = entity.getIndex(); if( entity.getCoordinates().x() == 0 ) { - return u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] - entity.getMesh().getSpaceSteps().x() * + return u[ neighbourEntities.template getEntityIndex< 1, 0, 0 >() ] + entity.getMesh().getSpaceSteps().x() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) @@ -336,7 +348,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, } if( entity.getCoordinates().y() == 0 ) { - return u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] - entity.getMesh().getSpaceSteps().y() * + return u[ neighbourEntities.template getEntityIndex< 0, 1, 0 >() ] + entity.getMesh().getSpaceSteps().y() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) @@ -346,7 +358,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, } if( entity.getCoordinates().z() == 0 ) { - return u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] - entity.getMesh().getSpaceSteps().z() * + return u[ neighbourEntities.template getEntityIndex< 0, 0, 1 >() ] + entity.getMesh().getSpaceSteps().z() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } // The following line is commented to avoid compiler warning @@ -386,7 +398,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, { matrixRow.setElement( 0, index, 1.0 ); matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); - b[ index ] = - entity.getMesh().getSpaceSteps().x() * + b[ index ] = entity.getMesh().getSpaceSteps().x() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) @@ -400,7 +412,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, { matrixRow.setElement( 0, index, 1.0 ); matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); - b[ index ] = - entity.getMesh().getSpaceSteps().y() * + b[ index ] = entity.getMesh().getSpaceSteps().y() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) @@ -414,7 +426,7 @@ class NeumannBoundaryConditions< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, { matrixRow.setElement( 0, index, 1.0 ); matrixRow.setElement( 1, neighbourEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); - b[ index ] = - entity.getMesh().getSpaceSteps().z() * + b[ index ] = entity.getMesh().getSpaceSteps().z() * Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); } if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) @@ -440,4 +452,3 @@ std::ostream& operator << ( std::ostream& str, const NeumannBoundaryConditions< } // namespace Operators } // namespace TNL - diff --git a/src/TNL/Problems/HeatEquationProblem.h b/src/TNL/Problems/HeatEquationProblem.h index 33046f58cc847a3654057da2150504ef77447de5..59d57ff2f56e7c55ee1d09eff951cf92ee36a9ae 100644 --- a/src/TNL/Problems/HeatEquationProblem.h +++ b/src/TNL/Problems/HeatEquationProblem.h @@ -32,9 +32,9 @@ template< typename Mesh, typename DifferentialOperator = Operators::LinearDiffusion< Mesh, typename BoundaryCondition::RealType > > class HeatEquationProblem : public PDEProblem< Mesh, - typename DifferentialOperator::RealType, - typename Mesh::DeviceType, - typename DifferentialOperator::IndexType > + typename DifferentialOperator::RealType, + typename Mesh::DeviceType, + typename DifferentialOperator::IndexType > { public: diff --git a/src/TNL/Problems/HeatEquationProblem_impl.h b/src/TNL/Problems/HeatEquationProblem_impl.h index 6dc77992669e167ca200a820a87bf32be79d4178..e4e8818a99004a6168dbd367acb45c6c1cbd3a64 100644 --- a/src/TNL/Problems/HeatEquationProblem_impl.h +++ b/src/TNL/Problems/HeatEquationProblem_impl.h @@ -183,10 +183,10 @@ makeSnapshot( const RealType& time, DofVectorPointer& dofs, MeshDependentDataPointer& meshDependentData ) { - std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl; + std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl; this->bindDofs( meshPointer, dofs ); - //cout << "dofs = " << dofs << endl; + FileName fileName; fileName.setFileNameBase( "u-" ); fileName.setExtension( "tnl" ); diff --git a/src/TNL/Solvers/IterativeSolver_impl.h b/src/TNL/Solvers/IterativeSolver_impl.h index 5f8c084d799c88a33f7a00c51532c9d233b810cf..da811762ae2b5d1f11f5748e37d52b4026a7f78e 100644 --- a/src/TNL/Solvers/IterativeSolver_impl.h +++ b/src/TNL/Solvers/IterativeSolver_impl.h @@ -111,7 +111,7 @@ bool IterativeSolver< Real, Index> :: checkNextIteration() this->getIterations() > this->getMaxIterations() || ( this->getResidue() > this->getDivergenceResidue() && this->getIterations() >= this->getMinIterations() ) || ( this->getResidue() < this->getConvergenceResidue() && this->getIterations() >= this->getMinIterations() ) ) - return false; + return false; return true; } diff --git a/src/TNL/Solvers/ODE/Euler_impl.h b/src/TNL/Solvers/ODE/Euler_impl.h index 46706cf24c8796ed6e92681cadbfed46fddad102..6571dee4d0d2ccf3c097a0ec358e22118d64c0a5 100644 --- a/src/TNL/Solvers/ODE/Euler_impl.h +++ b/src/TNL/Solvers/ODE/Euler_impl.h @@ -27,8 +27,6 @@ template< typename Problem > Euler< Problem > :: Euler() : cflCondition( 0.0 ) { - //timer.reset(); - //updateTimer.reset(); }; template< typename Problem > @@ -60,13 +58,13 @@ bool Euler< Problem > :: setup( const Config::ParameterContainer& parameters, template< typename Problem > void Euler< Problem > :: setCFLCondition( const RealType& cfl ) { - this->cflCondition = cfl; + this -> cflCondition = cfl; } template< typename Problem > const typename Problem :: RealType& Euler< Problem > :: getCFLCondition() const { - return this->cflCondition; + return this -> cflCondition; } template< typename Problem > @@ -94,7 +92,7 @@ bool Euler< Problem > :: solve( DofVectorPointer& u ) this->resetIterations(); this->setResidue( this->getConvergenceResidue() + 1.0 ); - this->refreshSolverMonitor(); + this -> refreshSolverMonitor(); /**** * Start the main loop @@ -104,13 +102,11 @@ bool Euler< Problem > :: solve( DofVectorPointer& u ) /**** * Compute the RHS */ - //timer.stop(); this->problem->getExplicitRHS( time, currentTau, u, k1 ); - //timer.start(); RealType lastResidue = this->getResidue(); RealType maxResidue( 0.0 ); - if( this->cflCondition != 0.0 ) + if( this -> cflCondition != 0.0 ) { maxResidue = k1->absMax(); if( currentTau * maxResidue > this->cflCondition ) @@ -120,16 +116,14 @@ bool Euler< Problem > :: solve( DofVectorPointer& u ) } } RealType newResidue( 0.0 ); - //updateTimer.start(); computeNewTimeLevel( u, currentTau, newResidue ); - //updateTimer.stop(); this->setResidue( newResidue ); /**** * When time is close to stopTime the new residue * may be inaccurate significantly. */ - if( currentTau + time == this->stopTime ) this->setResidue( lastResidue ); + if( currentTau + time == this -> stopTime ) this->setResidue( lastResidue ); time += currentTau; if( ! this->nextIteration() ) @@ -138,25 +132,23 @@ bool Euler< Problem > :: solve( DofVectorPointer& u ) /**** * Compute the new time step. */ - if( time + currentTau > this->getStopTime() ) - currentTau = this->getStopTime() - time; //we don't want to keep such tau - else this->tau = currentTau; + if( time + currentTau > this -> getStopTime() ) + currentTau = this -> getStopTime() - time; //we don't want to keep such tau + else this -> tau = currentTau; - this->refreshSolverMonitor(); + this -> refreshSolverMonitor(); /**** * Check stop conditions. */ if( time >= this->getStopTime() || - ( this->getConvergenceResidue() != 0.0 && this->getResidue() < this->getConvergenceResidue() ) ) + ( this -> getConvergenceResidue() != 0.0 && this->getResidue() < this -> getConvergenceResidue() ) ) { - this->refreshSolverMonitor(); - //std::cerr << std::endl << "RHS Timer = " << timer.getRealTime() << std::endl; - //std::cerr << std::endl << "Update Timer = " << updateTimer.getRealTime() << std::endl; + this -> refreshSolverMonitor(); return true; } - if( this->cflCondition != 0.0 ) + if( this -> cflCondition != 0.0 ) { currentTau /= 0.95; currentTau = min( currentTau, this->getMaxTau() ); diff --git a/src/TNL/Solvers/ODE/ExplicitSolver.h b/src/TNL/Solvers/ODE/ExplicitSolver.h index c988e4092444c659b248df0b77656aae98ec1dc8..4c1743c66471c04fa4707730d9d629e9d02f6f50 100644 --- a/src/TNL/Solvers/ODE/ExplicitSolver.h +++ b/src/TNL/Solvers/ODE/ExplicitSolver.h @@ -76,7 +76,7 @@ class ExplicitSolver : public IterativeSolver< typename Problem::RealType, void setRefreshRate( const IndexType& refreshRate ); - void refreshSolverMonitor(); + void refreshSolverMonitor( bool force = false ); protected: diff --git a/src/TNL/Solvers/ODE/ExplicitSolver_impl.h b/src/TNL/Solvers/ODE/ExplicitSolver_impl.h index f40e1018cf2ec4722da9f185627e829354b0d4cb..11cd7f19285e21d92ddeeb4bcff98897ab59f0d9 100644 --- a/src/TNL/Solvers/ODE/ExplicitSolver_impl.h +++ b/src/TNL/Solvers/ODE/ExplicitSolver_impl.h @@ -150,7 +150,7 @@ setTimer( Timer* timer ) template< class Problem > void ExplicitSolver< Problem >:: -refreshSolverMonitor() +refreshSolverMonitor( bool force ) { if( this->solverMonitor ) { @@ -159,7 +159,7 @@ refreshSolverMonitor() this->solverMonitor->setTimeStep( this->getTau() ); this->solverMonitor->setTime( this->getTime() ); this->solverMonitor->setRefreshRate( this->refreshRate ); - this->solverMonitor->refresh(); + this->solverMonitor->refresh( force ); } } diff --git a/src/TNL/Solvers/ODE/Merson_impl.h b/src/TNL/Solvers/ODE/Merson_impl.h index 868bc32b59ce652acd55c7f1c58c39a172478e45..13afdb4df56fb94438272c4fb4e8f94750b68b57 100644 --- a/src/TNL/Solvers/ODE/Merson_impl.h +++ b/src/TNL/Solvers/ODE/Merson_impl.h @@ -170,7 +170,7 @@ bool Merson< Problem > :: solve( DofVectorPointer& u ) /**** * Start the main loop */ - while( 1 ) + while( this->checkNextIteration() ) { /**** * Compute Runge-Kutta coefficients @@ -227,10 +227,13 @@ bool Merson< Problem > :: solve( DofVectorPointer& u ) if( time >= this->getStopTime() || ( this->getConvergenceResidue() != 0.0 && this->getResidue() < this->getConvergenceResidue() ) ) { - this->refreshSolverMonitor(); + this->refreshSolverMonitor( true ); return true; } } + this->refreshSolverMonitor( true ); + return this->checkConvergence(); + }; template< typename Problem > diff --git a/src/TNL/Solvers/PDE/CMakeLists.txt b/src/TNL/Solvers/PDE/CMakeLists.txt index 0f98d12a9f92b80279e810041ec9e4ba42f7bfaa..e01c13e93a3228e51c01915ad133077987112969 100755 --- a/src/TNL/Solvers/PDE/CMakeLists.txt +++ b/src/TNL/Solvers/PDE/CMakeLists.txt @@ -7,8 +7,10 @@ SET( headers BackwardTimeDiscretisation.h LinearSystemAssembler.h LinearSystemAssembler_impl.h NoTimeDiscretisation.h - PDESolver.h - PDESolver_impl.h + TimeDependentPDESolver.h + TimeDependentPDESolver_impl.h + TimeIndependentPDESolver.h + TimeIndependentPDESolver_impl.h SemiImplicitTimeStepper.h SemiImplicitTimeStepper_impl.h ) diff --git a/src/TNL/Solvers/PDE/PDESolver.h b/src/TNL/Solvers/PDE/TimeDependentPDESolver.h similarity index 93% rename from src/TNL/Solvers/PDE/PDESolver.h rename to src/TNL/Solvers/PDE/TimeDependentPDESolver.h index a4f47ef51c8e6472c8d4807254c98db8cdc5f661..c6a1baa174b64b985e9590372eb913eda784cd47 100644 --- a/src/TNL/Solvers/PDE/PDESolver.h +++ b/src/TNL/Solvers/PDE/TimeDependentPDESolver.h @@ -1,5 +1,5 @@ /*************************************************************************** - PDESolver.h - description + TimeDependentPDESolver.h - description ------------------- begin : Jan 15, 2013 copyright : (C) 2013 by Tomas Oberhuber @@ -23,7 +23,7 @@ namespace PDE { template< typename Problem, typename TimeStepper > -class PDESolver : public Object +class TimeDependentPDESolver : public Object { public: @@ -38,7 +38,7 @@ class PDESolver : public Object typedef SharedPointer< DofVectorType, DeviceType > DofVectorPointer; typedef SharedPointer< MeshDependentDataType, DeviceType > MeshDependentDataPointer; - PDESolver(); + TimeDependentPDESolver(); static void configSetup( Config::ConfigDescription& config, const String& prefix = "" ); @@ -102,4 +102,4 @@ class PDESolver : public Object } // namespace Solvers } // namespace TNL -#include <TNL/Solvers/PDE/PDESolver_impl.h> +#include <TNL/Solvers/PDE/TimeDependentPDESolver_impl.h> diff --git a/src/TNL/Solvers/PDE/PDESolver_impl.h b/src/TNL/Solvers/PDE/TimeDependentPDESolver_impl.h similarity index 86% rename from src/TNL/Solvers/PDE/PDESolver_impl.h rename to src/TNL/Solvers/PDE/TimeDependentPDESolver_impl.h index 139d8fcc95169bd2938eb2ba9397b51425b962d4..2a22201d1e54f2d75b809c5b2e914abb332bd390 100644 --- a/src/TNL/Solvers/PDE/PDESolver_impl.h +++ b/src/TNL/Solvers/PDE/TimeDependentPDESolver_impl.h @@ -1,5 +1,5 @@ /*************************************************************************** - PDESolver_impl.h - description + TimeDependentPDESolver_impl.h - description ------------------- begin : Jan 15, 2013 copyright : (C) 2013 by Tomas Oberhuber @@ -10,7 +10,7 @@ #pragma once -#include "PDESolver.h" +#include "TimeDependentPDESolver.h" namespace TNL { namespace Solvers { @@ -18,8 +18,8 @@ namespace PDE { template< typename Problem, typename TimeStepper > -PDESolver< Problem, TimeStepper >:: -PDESolver() +TimeDependentPDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver() : timeStepper( 0 ), initialTime( 0.0 ), finalTime( 0.0 ), @@ -35,7 +35,7 @@ PDESolver() template< typename Problem, typename TimeStepper > void -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: configSetup( Config::ConfigDescription& config, const String& prefix ) { @@ -50,7 +50,7 @@ configSetup( Config::ConfigDescription& config, template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setup( const Config::ParameterContainer& parameters, const String& prefix ) { @@ -121,7 +121,7 @@ setup( const Config::ParameterContainer& parameters, template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: writeProlog( Logger& logger, const Config::ParameterContainer& parameters ) { @@ -172,7 +172,7 @@ writeProlog( Logger& logger, template< typename Problem, typename TimeStepper > void -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setTimeStepper( TimeStepper& timeStepper ) { this->timeStepper = &timeStepper; @@ -181,7 +181,7 @@ setTimeStepper( TimeStepper& timeStepper ) template< typename Problem, typename TimeStepper > void -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setProblem( ProblemType& problem ) { this->problem = &problem; @@ -190,7 +190,7 @@ setProblem( ProblemType& problem ) template< typename Problem, typename TimeStepper > void -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setInitialTime( const RealType& initialTime ) { this->initialTime = initialTime; @@ -199,7 +199,7 @@ setInitialTime( const RealType& initialTime ) template< typename Problem, typename TimeStepper > const typename TimeStepper :: RealType& -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: getInitialTime() const { return this->initialTime; @@ -209,12 +209,12 @@ getInitialTime() const template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setFinalTime( const RealType& finalTime ) { if( finalTime <= this->initialTime ) { - std::cerr << "Final time for PDESolver must larger than the initial time which is now " << this->initialTime << "." << std::endl; + std::cerr << "Final time for TimeDependentPDESolver must larger than the initial time which is now " << this->initialTime << "." << std::endl; return false; } this->finalTime = finalTime; @@ -224,7 +224,7 @@ setFinalTime( const RealType& finalTime ) template< typename Problem, typename TimeStepper > const typename TimeStepper :: RealType& -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: getFinalTime() const { return this->finalTime; @@ -233,12 +233,12 @@ getFinalTime() const template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setSnapshotPeriod( const RealType& period ) { if( period <= 0 ) { - std::cerr << "Snapshot tau for PDESolver must be positive value." << std::endl; + std::cerr << "Snapshot tau for TimeDependentPDESolver must be positive value." << std::endl; return false; } this->snapshotPeriod = period; @@ -248,7 +248,7 @@ setSnapshotPeriod( const RealType& period ) template< typename Problem, typename TimeStepper > const typename TimeStepper::RealType& -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: getSnapshotPeriod() const { return this->snapshotPeriod; @@ -257,12 +257,12 @@ getSnapshotPeriod() const template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setTimeStep( const RealType& timeStep ) { if( timeStep <= 0 ) { - std::cerr << "The time step for PDESolver must be positive value." << std::endl; + std::cerr << "The time step for TimeDependentPDESolver must be positive value." << std::endl; return false; } this->timeStep = timeStep; @@ -272,7 +272,7 @@ setTimeStep( const RealType& timeStep ) template< typename Problem, typename TimeStepper > const typename TimeStepper::RealType& -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: getTimeStep() const { return this->timeStep; @@ -281,12 +281,12 @@ getTimeStep() const template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: setTimeStepOrder( const RealType& timeStepOrder ) { if( timeStepOrder < 0 ) { - std::cerr << "The time step order for PDESolver must be zero or positive value." << std::endl; + std::cerr << "The time step order for TimeDependentPDESolver must be zero or positive value." << std::endl; return false; } this->timeStepOrder = timeStepOrder; @@ -296,27 +296,27 @@ setTimeStepOrder( const RealType& timeStepOrder ) template< typename Problem, typename TimeStepper > const typename TimeStepper::RealType& -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: getTimeStepOrder() const { return this->timeStepOrder; } template< typename Problem, typename TimeStepper > -void PDESolver< Problem, TimeStepper > :: setIoTimer( Timer& ioTimer ) +void TimeDependentPDESolver< Problem, TimeStepper > :: setIoTimer( Timer& ioTimer ) { this->ioTimer = &ioTimer; } template< typename Problem, typename TimeStepper > -void PDESolver< Problem, TimeStepper > :: setComputeTimer( Timer& computeTimer ) +void TimeDependentPDESolver< Problem, TimeStepper > :: setComputeTimer( Timer& computeTimer ) { this->computeTimer = &computeTimer; } template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: solve() { TNL_ASSERT( timeStepper != 0, @@ -326,7 +326,7 @@ solve() if( snapshotPeriod == 0 ) { - std::cerr << "No snapshot tau was set in PDESolver." << std::endl; + std::cerr << "No snapshot tau was set in TimeDependentPDESolver." << std::endl; return false; } RealType t( this->initialTime ); @@ -376,7 +376,7 @@ solve() template< typename Problem, typename TimeStepper > bool -PDESolver< Problem, TimeStepper >:: +TimeDependentPDESolver< Problem, TimeStepper >:: writeEpilog( Logger& logger ) const { return ( this->timeStepper->writeEpilog( logger ) && diff --git a/src/TNL/Solvers/PDE/TimeIndependentPDESolver.h b/src/TNL/Solvers/PDE/TimeIndependentPDESolver.h new file mode 100644 index 0000000000000000000000000000000000000000..41b6a47b5135fa74822804b5551f0dabbc81a3d4 --- /dev/null +++ b/src/TNL/Solvers/PDE/TimeIndependentPDESolver.h @@ -0,0 +1,75 @@ +/*************************************************************************** + tnlTimeIndependentPDESolver.h - description + ------------------- + begin : Jan 15, 2013 + copyright : (C) 2013 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <core/tnlObject.h> +#include <config/tnlConfigDescription.h> +#include <TNL/Config/ParameterContainer.h> +#include <solvers/tnlSolverMonitor.h> +#include <core/tnlLogger.h> + +template< typename Problem > +class tnlTimeIndependentPDESolver : public tnlObject +{ + public: + + typedef Problem ProblemType; + typedef typename ProblemType::RealType RealType; + typedef typename ProblemType::DeviceType DeviceType; + typedef typename ProblemType::IndexType IndexType; + typedef typename ProblemType::MeshType MeshType; + typedef typename ProblemType::DofVectorType DofVectorType; + typedef typename ProblemType::MeshDependentDataType MeshDependentDataType; + + tnlTimeIndependentPDESolver(); + + static void configSetup( tnlConfigDescription& config, + const String& prefix = "" ); + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + bool writeProlog( tnlLogger& logger, + const Config::ParameterContainer& parameters ); + + + void setProblem( ProblemType& problem ); + + void setComputeTimer( tnlTimer& computeTimer ); + + void setIoTimer( tnlTimer& ioTimer ); + + bool solve(); + + bool writeEpilog( tnlLogger& logger ) const; + + protected: + + MeshType mesh; + + DofVectorType dofs; + + MeshDependentDataType meshDependentData; + + ProblemType* problem; + + tnlTimer *computeTimer; +}; + +#include <solvers/pde/tnlTimeIndependentPDESolver_impl.h> + diff --git a/src/TNL/Solvers/PDE/TimeIndependentPDESolver_impl.h b/src/TNL/Solvers/PDE/TimeIndependentPDESolver_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..0f27de6489ffc3ee7a4ec37d6ca1d69c766f913a --- /dev/null +++ b/src/TNL/Solvers/PDE/TimeIndependentPDESolver_impl.h @@ -0,0 +1,172 @@ +/*************************************************************************** + tnlTimeIndependentPDESolver_impl.h - description + ------------------- + begin : Jan 15, 2013 + copyright : (C) 2013 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#pragma once + +#include <solvers/pde/tnlTimeIndependentPDESolver.h> + +template< typename Problem > +tnlTimeIndependentPDESolver< Problem >:: +tnlTimeIndependentPDESolver() +: problem( 0 ), + computeTimer( 0 ) +{ +} + +template< typename Problem > +void +tnlTimeIndependentPDESolver< Problem >:: +configSetup( tnlConfigDescription& config, + const String& prefix ) +{ +} + +template< typename Problem > +bool +tnlTimeIndependentPDESolver< Problem >:: +setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + /**** + * Load the mesh from the mesh file + */ + const String& meshFile = parameters.getParameter< String >( "mesh" ); + cout << "Loading a mesh from the file " << meshFile << "..."; + if( ! this->mesh.load( meshFile ) ) + { + cerr << endl; + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + cerr << " You may create it with tools like tnl-grid-setup or tnl-mesh-convert." << endl; + return false; + } + cout << " [ OK ] " << endl; + + /**** + * Set DOFs (degrees of freedom) + */ + TNL_ASSERT( problem->getDofs( this->mesh ) != 0, ); + cout << "Allocating dofs ... "; + if( ! this->dofs.setSize( problem->getDofs( this->mesh ) ) ) + { + cerr << endl; + cerr << "I am not able to allocate DOFs (degrees of freedom)." << endl; + return false; + } + cout << " [ OK ]" << endl; + this->dofs.setValue( 0.0 ); + this->problem->bindDofs( this->mesh, this->dofs ); + + /**** + * Set mesh dependent data + */ + this->problem->setMeshDependentData( this->mesh, this->meshDependentData ); + this->problem->bindMeshDependentData( this->mesh, this->meshDependentData ); + + /*** + * Set-up the initial condition + */ + cout << "Setting up the initial condition ... "; + typedef typename Problem :: DofVectorType DofVectorType; + if( ! this->problem->setInitialData( parameters, this->mesh, this->dofs, this->meshDependentData ) ) + return false; + cout << " [ OK ]" << endl; + + + return true; +} + +template< typename Problem > +bool +tnlTimeIndependentPDESolver< Problem >:: +writeProlog( tnlLogger& logger, + const Config::ParameterContainer& parameters ) +{ + logger.writeHeader( problem->getPrologHeader() ); + problem->writeProlog( logger, parameters ); + logger.writeSeparator(); + mesh.writeProlog( logger ); + logger.writeSeparator(); + const String& solverName = parameters. getParameter< String >( "discrete-solver" ); + logger.writeParameter< String >( "Discrete solver:", "discrete-solver", parameters ); + if( solverName == "merson" ) + logger.writeParameter< double >( "Adaptivity:", "merson-adaptivity", parameters, 1 ); + if( solverName == "sor" ) + logger.writeParameter< double >( "Omega:", "sor-omega", parameters, 1 ); + if( solverName == "gmres" ) + logger.writeParameter< int >( "Restarting:", "gmres-restarting", parameters, 1 ); + logger.writeParameter< double >( "Convergence residue:", "convergence-residue", parameters ); + logger.writeParameter< double >( "Divergence residue:", "divergence-residue", parameters ); + logger.writeParameter< int >( "Maximal number of iterations:", "max-iterations", parameters ); + logger.writeParameter< int >( "Minimal number of iterations:", "min-iterations", parameters ); + logger.writeSeparator(); + logger.writeParameter< String >( "Real type:", "real-type", parameters, 0 ); + logger.writeParameter< String >( "Index type:", "index-type", parameters, 0 ); + logger.writeParameter< String >( "Device:", "device", parameters, 0 ); + logger.writeSeparator(); + logger.writeSystemInformation( parameters ); + logger.writeSeparator(); + logger.writeCurrentTime( "Started at:" ); + logger.writeSeparator(); + return true; +} + +template< typename Problem > +void +tnlTimeIndependentPDESolver< Problem >:: +setProblem( ProblemType& problem ) +{ + this->problem = &problem; +} + +template< typename Problem > +void tnlTimeIndependentPDESolver< Problem > :: setIoTimer( tnlTimer& ioTimer ) +{ + // this->ioTimer = &ioTimer; +} + +template< typename Problem > +void tnlTimeIndependentPDESolver< Problem > :: setComputeTimer( tnlTimer& computeTimer ) +{ + this->computeTimer = &computeTimer; +} + +template< typename Problem > +bool +tnlTimeIndependentPDESolver< Problem >:: +solve() +{ + TNL_ASSERT( problem != 0, + cerr << "No problem was set in tnlPDESolver." ); + + this->computeTimer->reset(); + this->computeTimer->start(); + if( ! this->problem->solve( this->mesh, this->dofs ) ) + { + this->computeTimer->stop(); + return false; + } + this->computeTimer->stop(); + return true; +} + +template< typename Problem > +bool +tnlTimeIndependentPDESolver< Problem >:: +writeEpilog( tnlLogger& logger ) const +{ + return this->problem->writeEpilog( logger ); +} diff --git a/src/TNL/Solvers/SolverConfig_impl.h b/src/TNL/Solvers/SolverConfig_impl.h index eb981bb35b9ade583e8538376978443e04584e14..a191add046b7f1b4e2b317a26e4abd23ee96606d 100644 --- a/src/TNL/Solvers/SolverConfig_impl.h +++ b/src/TNL/Solvers/SolverConfig_impl.h @@ -14,7 +14,7 @@ #include <TNL/Solvers/BuildConfigTags.h> #include <TNL/Solvers/DummyProblem.h> #include <TNL/Solvers/PDE/ExplicitTimeStepper.h> -#include <TNL/Solvers/PDE/PDESolver.h> +#include <TNL/Solvers/PDE/TimeDependentPDESolver.h> namespace TNL { namespace Solvers { @@ -79,7 +79,7 @@ bool SolverConfig< ConfigTag, ProblemConfig >::configSetup( Config::ConfigDescri */ config.addDelimiter( " === Time discretisation parameters ==== " ); typedef PDE::ExplicitTimeStepper< DummyProblemType, ODE::Euler > ExplicitTimeStepper; - PDE::PDESolver< DummyProblemType, ExplicitTimeStepper >::configSetup( config ); + PDE::TimeDependentPDESolver< DummyProblemType, ExplicitTimeStepper >::configSetup( config ); ExplicitTimeStepper::configSetup( config ); if( ConfigTagTimeDiscretisation< ConfigTag, ExplicitTimeDiscretisationTag >::enabled || ConfigTagTimeDiscretisation< ConfigTag, SemiImplicitTimeDiscretisationTag >::enabled || diff --git a/src/TNL/Solvers/SolverStarter_impl.h b/src/TNL/Solvers/SolverStarter_impl.h index 2d988c8b4120920ca346dd7e8e205b43f64660f9..516dab97d42bf11b0aa4185bc1acf01db2ab1542 100644 --- a/src/TNL/Solvers/SolverStarter_impl.h +++ b/src/TNL/Solvers/SolverStarter_impl.h @@ -27,7 +27,7 @@ #include <TNL/Solvers/Linear/Preconditioners/Diagonal.h> #include <TNL/Solvers/PDE/ExplicitTimeStepper.h> #include <TNL/Solvers/PDE/SemiImplicitTimeStepper.h> -#include <TNL/Solvers/PDE/PDESolver.h> +#include <TNL/Solvers/PDE/TimeDependentPDESolver.h> namespace TNL { namespace Solvers { @@ -358,7 +358,7 @@ bool SolverStarter< ConfigTag > :: runPDESolver( Problem& problem, /**** * Set-up the PDE solver */ - PDE::PDESolver< Problem, TimeStepper > solver; + PDE::TimeDependentPDESolver< Problem, TimeStepper > solver; solver.setProblem( problem ); solver.setTimeStepper( timeStepper ); if( ! solver.setup( parameters ) ) diff --git a/src/Tools/tnl-compile.in b/src/Tools/tnl-compile.in index 62dd15771afa36e3ccf44468f14644929bce4405..bf196432c86c188f1f5ac7a5dcc9532af478c8f0 100644 --- a/src/Tools/tnl-compile.in +++ b/src/Tools/tnl-compile.in @@ -13,3 +13,4 @@ do done echo -I@CMAKE_INSTALL_PREFIX@/include/tnl-@tnlVersion@ ${CUDA_FLAGS} ${CXX_STD_FLAGS} ${DEBUG_FLAGS} + diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index 73036199d0dcb70c3d32ad1fcfae7d1f4e68318e..d8ee5077cc1f0e3d3eb7e239d75e710463f81933 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -416,7 +416,7 @@ bool setElementType( const MeshPointer& meshPointer, std::cerr << "Unable to parse object type " << elementType << "." << std::endl; return false; } - if( parsedElementType[ 0 ] == "tnlStaticVector" ) + if( parsedElementType[ 0 ] == "Containers::StaticVector" ) return setTupleType< MeshPointer >( meshPointer, inputFileName, parsedObjectType, parsedElementType, parameters ); std::cerr << "Unknown element type " << elementType << "." << std::endl; diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h index 60c366c4aa581f4cb107d12b1357aef61e966440..4f0456aea2dc44edd4eb0f94b8237ea5dd8dfbe8 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -19,6 +19,7 @@ #include <TNL/Containers/MultiVector.h> #include <TNL/Meshes/Grid.h> #include <TNL/Functions/MeshFunction.h> +#include <TNL/Functions/VectorField.h> using namespace TNL; @@ -48,6 +49,7 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer, const String& inputFileName, const Config::ParameterContainer& parameters ) { + MeshFunction function( meshPointer ); std::cout << "Mesh function: " << function.getType() << std::endl; if( ! function.load( inputFileName ) ) @@ -58,6 +60,7 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer, int verbose = parameters. getParameter< int >( "verbose"); String outputFormat = parameters. getParameter< String >( "output-format" ); + double scale = parameters. getParameter< double >( "scale" ); String outputFileName; if( ! getOutputFileName( inputFileName, outputFormat, @@ -66,38 +69,73 @@ bool writeMeshFunction( const typename MeshFunction::MeshPointer& meshPointer, if( verbose ) std::cout << " writing to " << outputFileName << " ... " << std::flush; - return function.write( outputFileName, outputFormat ); + return function.write( outputFileName, outputFormat, scale ); } +template< typename VectorField > +bool writeVectorField( const typename VectorField::FunctionType::MeshPointer& meshPointer, + const String& inputFileName, + const Config::ParameterContainer& parameters ) +{ + + VectorField field( meshPointer ); + std::cout << "VectorField: " << field.getType() << std::endl; + if( ! field.load( inputFileName ) ) + { + std::cerr << "Unable to load vector field from a file " << inputFileName << "." << std::endl; + return false; + } + + int verbose = parameters. getParameter< int >( "verbose"); + String outputFormat = parameters. getParameter< String >( "output-format" ); + double scale = parameters. getParameter< double >( "scale" ); + String outputFileName; + if( ! getOutputFileName( inputFileName, + outputFormat, + outputFileName ) ) + return false; + if( verbose ) + std::cout << " writing to " << outputFileName << " ... " << std::flush; + + return field.write( outputFileName, outputFormat, scale ); +} + + template< typename MeshPointer, int EntityDimensions, - typename Real > + typename Real, + int VectorFieldSize > bool setMeshFunctionRealType( const MeshPointer& meshPointer, const String& inputFileName, + const Containers::List< String >& parsedObjectType, const Config::ParameterContainer& parameters ) { - return writeMeshFunction< Functions::MeshFunction< typename MeshPointer::ObjectType, EntityDimensions, Real > >( meshPointer, inputFileName, parameters ); + if( VectorFieldSize == 0 ) + return writeMeshFunction< Functions::MeshFunction< typename MeshPointer::ObjectType, EntityDimensions, Real > >( meshPointer, inputFileName, parameters ); + return writeVectorField< Functions::VectorField< VectorFieldSize, Functions::MeshFunction< typename MeshPointer::ObjectType, EntityDimensions, Real > > >( meshPointer, inputFileName, parameters ); } template< typename MeshPointer, - int EntityDimensions > + int EntityDimensions, + int VectorFieldSize > bool setMeshEntityType( const MeshPointer& meshPointer, const String& inputFileName, const Containers::List< String >& parsedObjectType, const Config::ParameterContainer& parameters ) { if( parsedObjectType[ 3 ] == "float" ) - return setMeshFunctionRealType< MeshPointer, EntityDimensions, float >( meshPointer, inputFileName, parameters ); + return setMeshFunctionRealType< MeshPointer, EntityDimensions, float, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); if( parsedObjectType[ 3 ] == "double" ) - return setMeshFunctionRealType< MeshPointer, EntityDimensions, double >( meshPointer, inputFileName, parameters ); + return setMeshFunctionRealType< MeshPointer, EntityDimensions, double, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); if( parsedObjectType[ 3 ] == "long double" ) - return setMeshFunctionRealType< MeshPointer, EntityDimensions, long double >( meshPointer, inputFileName, parameters ); + return setMeshFunctionRealType< MeshPointer, EntityDimensions, long double, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); std::cerr << "Unsupported arithmetics " << parsedObjectType[ 3 ] << " in mesh function " << inputFileName << std::endl; return false; } template< typename MeshReal, - typename MeshIndex > + typename MeshIndex, + int VectorFieldSize > bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 1, MeshReal, Devices::Host, MeshIndex > >& meshPointer, const String& inputFileName, const Containers::List< String >& parsedObjectType, @@ -109,10 +147,10 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 1, MeshReal, De switch( meshEntityDimensions ) { case 0: - return setMeshEntityType< MeshPointer, 0 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 0, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; case 1: - return setMeshEntityType< MeshPointer, 1 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 1, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; default: std::cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << std::endl; @@ -121,7 +159,8 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 1, MeshReal, De } template< typename MeshReal, - typename MeshIndex > + typename MeshIndex, + int VectorFieldSize > bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 2, MeshReal, Devices::Host, MeshIndex > >& meshPointer, const String& inputFileName, const Containers::List< String >& parsedObjectType, @@ -133,13 +172,13 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 2, MeshReal, De switch( meshEntityDimensions ) { case 0: - return setMeshEntityType< MeshPointer, 0 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 0, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; case 1: - return setMeshEntityType< MeshPointer, 1 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 1, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; case 2: - return setMeshEntityType< MeshPointer, 2 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 2, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; default: std::cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << std::endl; @@ -148,7 +187,8 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 2, MeshReal, De } template< typename MeshReal, - typename MeshIndex > + typename MeshIndex, + int VectorFieldSize > bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 3, MeshReal, Devices::Host, MeshIndex > >& meshPointer, const String& inputFileName, const Containers::List< String >& parsedObjectType, @@ -160,16 +200,16 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 3, MeshReal, De switch( meshEntityDimensions ) { case 0: - return setMeshEntityType< MeshPointer, 0 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 0, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; case 1: - return setMeshEntityType< MeshPointer, 1 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 1, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; case 2: - return setMeshEntityType< MeshPointer, 2 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 2, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; case 3: - return setMeshEntityType< MeshPointer, 3 >( meshPointer, inputFileName, parsedObjectType, parameters ); + return setMeshEntityType< MeshPointer, 3, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); break; default: std::cerr << "Unsupported mesh functions entity dimensions count " << meshEntityDimensions << "." << std::endl; @@ -177,20 +217,48 @@ bool setMeshEntityDimensions( const SharedPointer< Meshes::Grid< 3, MeshReal, De } } -template< typename MeshPointer > +template< typename MeshPointer, int VectorFieldSize = 0 > bool setMeshFunction( const MeshPointer& meshPointer, const String& inputFileName, const Containers::List< String >& parsedObjectType, const Config::ParameterContainer& parameters ) { + std::cerr << parsedObjectType[ 1 ] << std::endl; if( parsedObjectType[ 1 ] != meshPointer->getSerializationType() ) { std::cerr << "Incompatible mesh type for the mesh function " << inputFileName << "." << std::endl; return false; } - return setMeshEntityDimensions( meshPointer, inputFileName, parsedObjectType, parameters ); + typedef typename MeshPointer::ObjectType::RealType RealType; + typedef typename MeshPointer::ObjectType::IndexType IndexType; + return setMeshEntityDimensions< RealType, IndexType, VectorFieldSize >( meshPointer, inputFileName, parsedObjectType, parameters ); } +template< typename MeshPointer > +bool setVectorFieldSize( const MeshPointer& meshPointer, + const String& inputFileName, + Containers::List< String >& parsedObjectType, + const Config::ParameterContainer& parameters ) +{ + int vectorFieldSize = atoi( parsedObjectType[ 1 ].getString() ); + Containers::List< String > parsedMeshFunctionType; + if( ! parseObjectType( parsedObjectType[ 2 ], parsedMeshFunctionType ) ) + { + std::cerr << "Unable to parse mesh function type " << parsedObjectType[ 2 ] << " in a vector field." << std::endl; + return false; + } + switch( vectorFieldSize ) + { + case 1: + return setMeshFunction< MeshPointer, 1 >( meshPointer, inputFileName, parsedMeshFunctionType, parameters ); + case 2: + return setMeshFunction< MeshPointer, 2 >( meshPointer, inputFileName, parsedMeshFunctionType, parameters ); + case 3: + return setMeshFunction< MeshPointer, 3 >( meshPointer, inputFileName, parsedMeshFunctionType, parameters ); + } + std::cerr << "Unsupported vector field size " << vectorFieldSize << "." << std::endl; + return false; +} template< typename MeshPointer, typename Element, typename Real, typename Index, int Dimensions > bool convertObject( const MeshPointer& meshPointer, @@ -380,7 +448,7 @@ bool setElementType( const MeshPointer& meshPointer, return false; } if( parsedElementType[ 0 ] == "Containers::StaticVector" || - parsedElementType[ 0 ] == "tnlStaticVector" ) // TODO: remove deprecated type names + parsedElementType[ 0 ] == "Containers::StaticVector" ) // TODO: remove deprecated type names return setTupleType< MeshPointer >( meshPointer, inputFileName, parsedObjectType, parsedElementType, parameters ); std::cerr << "Unknown element type " << elementType << "." << std::endl; @@ -456,6 +524,8 @@ bool processFiles( const Config::ParameterContainer& parameters ) if( parsedObjectType[ 0 ] == "Functions::MeshFunction" || parsedObjectType[ 0 ] == "tnlMeshFunction" ) // TODO: remove deprecated type names setMeshFunction< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); + if( parsedObjectType[ 0 ] == "Functions::VectorField" ) + setVectorFieldSize< MeshPointer >( meshPointer, inputFiles[ i ], parsedObjectType, parameters ); if( verbose ) std::cout << "[ OK ]. " << std::endl; } diff --git a/src/UnitTests/StringTest.cpp b/src/UnitTests/StringTest.cpp index 1063d139dc9781af1fafc2f8ecf34e2a6c8401fe..3a0444ed64801402a95cec5a2ba80aa739e05163 100644 --- a/src/UnitTests/StringTest.cpp +++ b/src/UnitTests/StringTest.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - tnlStringTest.cpp - description + StringTest.cpp - description ------------------- begin : Jul 22, 2013 copyright : (C) 2013 by Tomas Oberhuber diff --git a/src/core/tnlTypeInfo.h b/src/core/tnlTypeInfo.h new file mode 100644 index 0000000000000000000000000000000000000000..5d5282f3c4ed13bcc190446f7c1026ac28663944 --- /dev/null +++ b/src/core/tnlTypeInfo.h @@ -0,0 +1,39 @@ +/* + * File: tnlTypeInfo.h + * Author: oberhuber + * + * Created on July 14, 2016, 3:46 PM + */ + +#pragma once + +#include <limits> + +template< typename Type > +class tnlTypeInfo +{ +}; + +template<> +class tnlTypeInfo< double > +{ + public: + + typedef double Type; + + static __cuda_callable__ + Type getMaxValue() { return DBL_MAX; }; +}; + +template<> +class tnlTypeInfo< float > +{ + public: + + typedef float Type; + + static __cuda_callable__ + Type getMaxValue() { return FLT_MAX; }; +}; + + diff --git a/src/functions/tnlFunctions.h b/src/functions/tnlFunctions.h new file mode 100644 index 0000000000000000000000000000000000000000..326fa6024b37256360fb6653d195310fe6eb9a98 --- /dev/null +++ b/src/functions/tnlFunctions.h @@ -0,0 +1,52 @@ +/* + * File: tnlFunctions.h + * Author: oberhuber + * + * Created on July 11, 2016, 6:01 PM + */ + +#pragma once + +#include <core/tnlCuda.h> + +template< typename Real > +__cuda_callable__ +Real sign( const Real& x, const Real& smoothing = 0.0 ) +{ + if( x > smoothing ) + return 1.0; + else if( x < -smoothing ) + return -1.0; + if( smoothing == 0.0 ) + return 0.0; + return sin( ( M_PI * x ) / ( 2.0 * smoothing ) ); +} + +template< typename Real > +__cuda_callable__ +Real positivePart( const Real& arg) +{ + return arg > 0.0 ? arg : 0.0; +} + +template< typename Real > +__cuda_callable__ +Real negativePart( const Real& arg) +{ + return arg < 0.0 ? arg : 0.0; +} + +template< typename Real > +__cuda_callable__ +Real ArgAbsMin( const Real& x, const Real& y ) +{ + return fabs( x ) < fabs( y ) ? x : y; +} + +template< typename Real > +__cuda_callable__ +Real ArgAbsMax( const Real& x, const Real& y ) +{ + return fabs( x ) > fabs( y ) ? x : y; +} + diff --git a/src/operators/tnlDirichletBoundaryConditions_impl.h b/src/operators/tnlDirichletBoundaryConditions_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..70d5e6f7915056de349fc91616c0dfeb682c3d8e --- /dev/null +++ b/src/operators/tnlDirichletBoundaryConditions_impl.h @@ -0,0 +1,144 @@ +/*************************************************************************** + tnlDirichletBoundaryConditions_impl.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLDIRICHLETBOUNDARYCONDITIONS_IMPL_H_ +#define TNLDIRICHLETBOUNDARYCONDITIONS_IMPL_H_ + +#include <functions/tnlFunctionAdapter.h> + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > +void +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +configSetup( tnlConfigDescription& config, + const String& prefix ) +{ + Function::configSetup( config ); +} + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > +bool +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + return this->function.setup( parameters ); +} + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > +void +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +setFunction( const Function& function ) +{ + this->function = function; +} + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > +Function& +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +getFunction() +{ + return this->function; +} + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > +const Function& +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +getFunction() const +{ + return *this->function; +} + + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > +template< typename EntityType, + typename MeshFunction > +__cuda_callable__ +const Real +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time ) const +{ + //static_assert( EntityType::getDimensions() == MeshEntitiesDimensions, "Wrong mesh entity dimensions." ); + return tnlFunctionAdapter< MeshType, Function >::template getValue( this->function, entity, time ); +} + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > + template< typename EntityType > +__cuda_callable__ +Index +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const +{ + return 1; +} + +template< typename Mesh, + typename Function, + int MeshEntitiesDimensions, + typename Real, + typename Index > + template< typename Matrix, + typename EntityType, + typename MeshFunction > +__cuda_callable__ +void +tnlDirichletBoundaryConditions< Mesh, Function, MeshEntitiesDimensions, Real, Index >:: +updateLinearSystem( const RealType& time, + const MeshType& mesh, + const IndexType& index, + const EntityType& entity, + const MeshFunction& u, + DofVectorType& b, + Matrix& matrix ) const +{ + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + matrixRow.setElement( 0, index, 1.0 ); + b[ index ] = tnlFunctionAdapter< MeshType, Function >::getValue( this->function, entity, time ); +} + +#endif /* TNLDIRICHLETBOUNDARYCONDITIONS_IMPL_H_ */ diff --git a/src/operators/tnlNeumannReflectionBoundaryConditions.h b/src/operators/tnlNeumannReflectionBoundaryConditions.h new file mode 100644 index 0000000000000000000000000000000000000000..86fe650a3dbd39de6bcb24691d7e901043c9830e --- /dev/null +++ b/src/operators/tnlNeumannReflectionBoundaryConditions.h @@ -0,0 +1,126 @@ +#pragma once + +#include <TNL/Containers/StaticVector.h> +#include <core/vectors/tnlSharedVector.h> +#include <TNL/Config/ParameterContainer.h> +#include <functions/tnlConstantFunction.h> + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class tnlNeumannReflectionBoundaryConditions +{ + +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlNeumannReflectionBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef tnlGrid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > VertexType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const; + + CoordinatesType tmp; + +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlNeumannReflectionBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef tnlGrid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > VertexType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const; + + + CoordinatesType tmp; + + +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class tnlNeumannReflectionBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef tnlGrid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef tnlSharedVector< RealType, DeviceType, IndexType > SharedVector; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > VertexType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const; + + private: + + CoordinatesType tmp; + + +}; + +#include <operators/tnlNeumannReflectionBoundaryConditions_impl.h> + +#endif /* TNLNEUMANNREFLECTIONBOUNDARYCONDITIONS_H */ diff --git a/src/operators/tnlNeumannReflectionBoundaryConditions_impl.h b/src/operators/tnlNeumannReflectionBoundaryConditions_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..d791383520bd267beae784fe640d012ddd3147e0 --- /dev/null +++ b/src/operators/tnlNeumannReflectionBoundaryConditions_impl.h @@ -0,0 +1,171 @@ +#pragma once + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool +tnlNeumannReflectionBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: +setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + return true; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename EntityType, + typename MeshFunction > +__cuda_callable__ +const Real +tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >:: +operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time ) const + +#ifdef HAVE_CUDA + __device__ __host__ +#endif +void tnlNeumannReflectionBoundaryConditions< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index >:: +setBoundaryConditions( const RealType& time, + const MeshType& mesh, + const IndexType index, + const CoordinatesType& coordinates, + DofVectorType& u, + DofVectorType& fu ) +{ + tmp = coordinates; + + if(coordinates.x() == 0) + tmp.x() = 1; + else if(coordinates.x() == mesh. getDimensions().x() - 1) + tmp.x() = coordinates.x() - 2; + + u[ index ] = u[mesh.getCellIndex( tmp )]; +} + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool +tnlNeumannReflectionBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + return true; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename EntityType, + typename MeshFunction > +__cuda_callable__ +const Real +tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >:: +operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time ) const + +#ifdef HAVE_CUDA + __device__ __host__ +#endif +void tnlNeumannReflectionBoundaryConditions< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: +setBoundaryConditions( const RealType& time, + const MeshType& mesh, + const IndexType index, + const CoordinatesType& coordinates, + DofVectorType& u, + DofVectorType& fu ) +{ + + tmp = coordinates; + + if(coordinates.x() == 0) + tmp.x() = coordinates.x() + 2; + else if(coordinates.x() == mesh. getDimensions().x() - 1) + tmp.x() = coordinates.x() - 2; + + if(coordinates.y() == 0) + tmp.y() = coordinates.y() + 2; + else if(coordinates.y() == mesh. getDimensions().y() - 1) + tmp.y() = coordinates.y() - 2; + + u[ index ] = u[mesh.getCellIndex( tmp )]; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool +tnlNeumannReflectionBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +setup( const Config::ParameterContainer& parameters, + const String& prefix ) +{ + return true; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > + template< typename EntityType, + typename MeshFunction > +__cuda_callable__ +const Real +tnlNeumannBoundaryConditions< tnlGrid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index >:: +operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time ) const + +#ifdef HAVE_CUDA + __device__ __host__ +#endif +void tnlNeumannReflectionBoundaryConditions< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: +setBoundaryConditions( const RealType& time, + const MeshType& mesh, + const IndexType index, + const CoordinatesType& coordinates, + DofVectorType& u, + DofVectorType& fu ) +{ + tmp = coordinates; + + if(coordinates.x() == 0) + tmp.x() = coordinates.x() + 2; + else if(coordinates.x() == mesh. getDimensions().x() - 1) + tmp.x() = coordinates.x() - 2; + + if(coordinates.y() == 0) + tmp.y() = coordinates.y() + 2; + else if(coordinates.y() == mesh. getDimensions().y() - 1) + tmp.y() = coordinates.y() - 2; + + if(coordinates.z() == 0) + tmp.z() = coordinates.z() + 2; + else if(coordinates.z() == mesh. getDimensions().z() - 1) + tmp.z() = coordinates.z() - 2; + + u[ index ] = u[mesh.getCellIndex( tmp )]; +} + + + +#endif /* TNLNEUMANNREFLECTIONBOUNDARYCONDITIONS_IMPL_H */ + diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h b/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h index c4d33c9b06b9942b35cd04c0c4ff069e1050c44a..16d1fe51fa458b60d0c3a648720380f9ce16eba7 100644 --- a/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h +++ b/tests/benchmarks/heat-equation-benchmark/tnlTestGrid2D.h @@ -14,7 +14,7 @@ #include <core/tnlObject.h> #include <core/Devices::Host.h> -#include <core/vectors/tnlStaticVector.h> +#include <TNL/Containers/StaticVector.h> #include <core/vectors/tnlVector.h> template< int Dimensions, @@ -50,8 +50,8 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject typedef Real RealType; typedef Device DeviceType; typedef Index IndexType; - typedef tnlStaticVector< 2, Real > VertexType; - typedef tnlStaticVector< 2, Index > CoordinatesType; + typedef Containers::StaticVector< 2, Real > VertexType; + typedef Containers::StaticVector< 2, Index > CoordinatesType; typedef Meshes::Grid< 2, Real, Devices::Host, Index > HostType; typedef Meshes::Grid< 2, Real, tnlCuda, Index > CudaType; typedef Meshes::Grid< 2, Real, Device, Index > ThisType; @@ -78,13 +78,13 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject Grid(); - static tnlString getType(); + static String getType(); - tnlString getTypeVirtual() const; + String getTypeVirtual() const; - static tnlString getSerializationType(); + static String getSerializationType(); - virtual tnlString getSerializationTypeVirtual() const; + virtual String getSerializationTypeVirtual() const; void setDimensions( const Index xSize, const Index ySize ); @@ -153,17 +153,17 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject //! Method for restoring the object from a file bool load( tnlFile& file ); - bool save( const tnlString& fileName ) const; + bool save( const String& fileName ) const; - bool load( const tnlString& fileName ); + bool load( const String& fileName ); - bool writeMesh( const tnlString& fileName, - const tnlString& format ) const; + bool writeMesh( const String& fileName, + const String& format ) const; template< typename MeshFunction > bool write( const MeshFunction& function, - const tnlString& fileName, - const tnlString& format ) const; + const String& fileName, + const String& format ) const; void writeProlog( tnlLogger& logger ); @@ -212,19 +212,19 @@ Meshes::Grid< 2, Real, Device, Index > :: Grid() template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getType() +String Meshes::Grid< 2, Real, Device, Index > :: getType() { - return tnlString( "Meshes::Grid< " ) + - tnlString( getMeshDimensions() ) + ", " + - tnlString( ::getType< RealType >() ) + ", " + - tnlString( Device :: getDeviceType() ) + ", " + - tnlString( ::getType< IndexType >() ) + " >"; + return String( "Meshes::Grid< " ) + + String( getMeshDimensions() ) + ", " + + String( ::getType< RealType >() ) + ", " + + String( Device :: getDeviceType() ) + ", " + + String( ::getType< IndexType >() ) + " >"; } template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const +String Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const { return this->getType(); } @@ -232,7 +232,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType() +String Meshes::Grid< 2, Real, Device, Index > :: getSerializationType() { return HostType::getType(); }; @@ -240,7 +240,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType() template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const +String Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const { return this->getSerializationType(); }; @@ -596,7 +596,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( tnlFile& file ) template< typename Real, typename Device, typename Index > -bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName ) const +bool Meshes::Grid< 2, Real, Device, Index > :: save( const String& fileName ) const { return tnlObject :: save( fileName ); }; @@ -604,7 +604,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName ) template< typename Real, typename Device, typename Index > -bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName ) +bool Meshes::Grid< 2, Real, Device, Index > :: load( const String& fileName ) { return tnlObject :: load( fileName ); }; @@ -612,8 +612,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName ) template< typename Real, typename Device, typename Index > -bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName, - const tnlString& format ) const +bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName, + const String& format ) const { fstream file; file. open( fileName. getString(), ios :: out ); @@ -739,8 +739,8 @@ template< typename Real, typename Index > template< typename MeshFunction > bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& function, - const tnlString& fileName, - const tnlString& format ) const + const String& fileName, + const String& format ) const { if( this->template getEntitiesCount< Cell >() != function. getSize() ) { @@ -826,8 +826,8 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject typedef Real RealType; typedef Device DeviceType; typedef Index IndexType; - typedef tnlStaticVector< 2, Real > VertexType; - typedef tnlStaticVector< 2, Index > CoordinatesType; + typedef Containers::StaticVector< 2, Real > VertexType; + typedef Containers::StaticVector< 2, Index > CoordinatesType; typedef Meshes::Grid< 2, Real, Devices::Host, Index > HostType; typedef Meshes::Grid< 2, Real, tnlCuda, Index > CudaType; typedef Meshes::Grid< 2, Real, Device, Index > ThisType; @@ -854,13 +854,13 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject Grid(); - static tnlString getType(); + static String getType(); - tnlString getTypeVirtual() const; + String getTypeVirtual() const; - static tnlString getSerializationType(); + static String getSerializationType(); - virtual tnlString getSerializationTypeVirtual() const; + virtual String getSerializationTypeVirtual() const; void setDimensions( const Index xSize, const Index ySize ); @@ -929,17 +929,17 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject //! Method for restoring the object from a file bool load( tnlFile& file ); - bool save( const tnlString& fileName ) const; + bool save( const String& fileName ) const; - bool load( const tnlString& fileName ); + bool load( const String& fileName ); - bool writeMesh( const tnlString& fileName, - const tnlString& format ) const; + bool writeMesh( const String& fileName, + const String& format ) const; template< typename MeshFunction > bool write( const MeshFunction& function, - const tnlString& fileName, - const tnlString& format ) const; + const String& fileName, + const String& format ) const; void writeProlog( tnlLogger& logger ); @@ -977,19 +977,19 @@ Meshes::Grid< 2, Real, Device, Index > :: Grid() template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getType() +String Meshes::Grid< 2, Real, Device, Index > :: getType() { - return tnlString( "Meshes::Grid< " ) + - tnlString( getMeshDimensions() ) + ", " + - tnlString( ::getType< RealType >() ) + ", " + - tnlString( Device :: getDeviceType() ) + ", " + - tnlString( ::getType< IndexType >() ) + " >"; + return String( "Meshes::Grid< " ) + + String( getMeshDimensions() ) + ", " + + String( ::getType< RealType >() ) + ", " + + String( Device :: getDeviceType() ) + ", " + + String( ::getType< IndexType >() ) + " >"; } template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const +String Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const { return this->getType(); } @@ -997,7 +997,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getTypeVirtual() const template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType() +String Meshes::Grid< 2, Real, Device, Index > :: getSerializationType() { return HostType::getType(); }; @@ -1005,7 +1005,7 @@ tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationType() template< typename Real, typename Device, typename Index > -tnlString Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const +String Meshes::Grid< 2, Real, Device, Index > :: getSerializationTypeVirtual() const { return this->getSerializationType(); }; @@ -1361,7 +1361,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( tnlFile& file ) template< typename Real, typename Device, typename Index > -bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName ) const +bool Meshes::Grid< 2, Real, Device, Index > :: save( const String& fileName ) const { return tnlObject :: save( fileName ); }; @@ -1369,7 +1369,7 @@ bool Meshes::Grid< 2, Real, Device, Index > :: save( const tnlString& fileName ) template< typename Real, typename Device, typename Index > -bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName ) +bool Meshes::Grid< 2, Real, Device, Index > :: load( const String& fileName ) { return tnlObject :: load( fileName ); }; @@ -1377,8 +1377,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: load( const tnlString& fileName ) template< typename Real, typename Device, typename Index > -bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const tnlString& fileName, - const tnlString& format ) const +bool Meshes::Grid< 2, Real, Device, Index > :: writeMesh( const String& fileName, + const String& format ) const { fstream file; file. open( fileName. getString(), ios :: out ); @@ -1504,8 +1504,8 @@ template< typename Real, typename Index > template< typename MeshFunction > bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& function, - const tnlString& fileName, - const tnlString& format ) const + const String& fileName, + const String& format ) const { if( this->template getEntitiesCount< Cell >() != function. getSize() ) { diff --git a/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h b/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h index db0228ff1685026ca9a9a55b86ba1195fa58f4b0..8773d9254fe7673a0c69e7961744a2900265dfd5 100644 --- a/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h +++ b/tests/benchmarks/heat-equation-benchmark/tnlTestGridEntity.h @@ -53,8 +53,8 @@ class tnlTestGridEntity< Meshes::Grid< Dimensions, Real, Device, Index >, Dimens constexpr static int getMeshDimensions() { return meshDimensions; }; - typedef tnlStaticVector< meshDimensions, IndexType > EntityOrientationType; - typedef tnlStaticVector< meshDimensions, IndexType > EntityBasisType; + typedef Containers::StaticVector< meshDimensions, IndexType > EntityOrientationType; + typedef Containers::StaticVector< meshDimensions, IndexType > EntityBasisType; typedef tnlTestGridEntity< GridType, entityDimensions, Config > ThisType; //typedef tnlTestNeighbourGridEntitiesStorage< ThisType > NeighbourGridEntitiesStorageType;