diff --git a/.gitignore b/.gitignore index 14140a23bf24c01df069e7251eeae28ff0834364..a091f8bf52373138593d57914c5d04378cc2c015 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ # build/output directories /builddir +/build-tinyxml2 /Documentation/html/ /Documentation/output_snippets/ diff --git a/src/Benchmarks/CMakeLists.txt b/src/Benchmarks/CMakeLists.txt index 50e46776282b3a13845337c26ddb9d83c31751ae..54f61a311fb4f076cda5d4ef2da08fd2abc28320 100644 --- a/src/Benchmarks/CMakeLists.txt +++ b/src/Benchmarks/CMakeLists.txt @@ -1,4 +1,6 @@ -add_subdirectory( HeatEquation ) +#add_subdirectory( HeatEquation ) +add_subdirectory( HeatEquationGrid ) +add_subdirectory( Grid ) add_subdirectory( BLAS ) add_subdirectory( NDArray ) add_subdirectory( SpMV ) @@ -6,5 +8,4 @@ add_subdirectory( DistSpMV ) add_subdirectory( LinearSolvers ) #add_subdirectory( ODESolvers ) add_subdirectory( Sorting ) -add_subdirectory( Traversers ) -add_subdirectory( Mesh ) +#add_subdirectory( Traversers ) diff --git a/src/Benchmarks/Grid/CMakeLists.txt b/src/Benchmarks/Grid/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3b927665152de564e3cce00b2a1e79dcdaa11883 --- /dev/null +++ b/src/Benchmarks/Grid/CMakeLists.txt @@ -0,0 +1,28 @@ + +function(generate_executables HEADER SUFFIX MAIN_FILE_PATH ARGS) +get_filename_component(MODULE_NAME ${HEADER} NAME_WE) + +if (${BUILD_CUDA}) + SET(SUPPORT_FILENAME ${MODULE_NAME}.cu) +else() + SET(SUPPORT_FILENAME ${MODULE_NAME}.cpp) +endif() + +# Targets are separated by suffix provided +set(MODULE_NAME ${MODULE_NAME}_${SUFFIX}) + +if (${BUILD_CUDA}) + CUDA_ADD_EXECUTABLE(${MODULE_NAME} ${HEADER} ${SUPPORT_FILENAME} OPTIONS ${CUDA_TESTS_FLAGS}) + TARGET_LINK_LIBRARIES(${MODULE_NAME} ${TESTS_LIBRARIES}) +else() + ADD_EXECUTABLE(${MODULE_NAME} ${HEADER} ${SUPPORT_FILENAME}) + TARGET_COMPILE_OPTIONS(${MODULE_NAME} PRIVATE ${CXX_TESTS_FLAGS}) +endif() + +endfunction() + +SET(SOME_ARGS "") + +generate_executables(Grid1D.h "OperationBenchmark" "Grid1D.h" SOME_ARGS) +generate_executables(Grid2D.h "OperationBenchmark" "Grid2D.h" SOME_ARGS) +generate_executables(Grid3D.h "OperationBenchmark" "Grid3D.h" SOME_ARGS) diff --git a/src/Benchmarks/Grid/Grid1D.cpp b/src/Benchmarks/Grid/Grid1D.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2ffba53d970751a1fe5c31d6e5c07e3065924821 --- /dev/null +++ b/src/Benchmarks/Grid/Grid1D.cpp @@ -0,0 +1,2 @@ + +#include "Grid1D.h" diff --git a/src/Benchmarks/Grid/Grid1D.cu b/src/Benchmarks/Grid/Grid1D.cu new file mode 100644 index 0000000000000000000000000000000000000000..2ffba53d970751a1fe5c31d6e5c07e3065924821 --- /dev/null +++ b/src/Benchmarks/Grid/Grid1D.cu @@ -0,0 +1,2 @@ + +#include "Grid1D.h" diff --git a/src/Benchmarks/Grid/Grid1D.h b/src/Benchmarks/Grid/Grid1D.h new file mode 100644 index 0000000000000000000000000000000000000000..df7cb1c17e3df2865e3a8111de98ac0558888427 --- /dev/null +++ b/src/Benchmarks/Grid/Grid1D.h @@ -0,0 +1,19 @@ + +#pragma once + +#include "GridBenchmark.h" + +#define GRID_DIMENSION 1 + +int main(int argc, char* argv[]) { + GridBenchmark benchmark; + + auto config = GridBenchmark::makeInputConfig(GRID_DIMENSION); + + TNL::Config::ParameterContainer parameters; + + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + return benchmark.runBenchmark(parameters); +} diff --git a/src/Benchmarks/Grid/Grid2D.cpp b/src/Benchmarks/Grid/Grid2D.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6ff75c9621a9f6a8ab5c38f93f8992a423833ac7 --- /dev/null +++ b/src/Benchmarks/Grid/Grid2D.cpp @@ -0,0 +1,2 @@ + +#include "Grid2D.h" diff --git a/src/Benchmarks/Grid/Grid2D.cu b/src/Benchmarks/Grid/Grid2D.cu new file mode 100644 index 0000000000000000000000000000000000000000..6ff75c9621a9f6a8ab5c38f93f8992a423833ac7 --- /dev/null +++ b/src/Benchmarks/Grid/Grid2D.cu @@ -0,0 +1,2 @@ + +#include "Grid2D.h" diff --git a/src/Benchmarks/Grid/Grid2D.h b/src/Benchmarks/Grid/Grid2D.h new file mode 100644 index 0000000000000000000000000000000000000000..9d8488cace2547da9ff8e0b0eff67e395b5fcc99 --- /dev/null +++ b/src/Benchmarks/Grid/Grid2D.h @@ -0,0 +1,19 @@ + +#pragma once + +#include "GridBenchmark.h" + +#define GRID_DIMENSION 2 + +int main(int argc, char* argv[]) { + GridBenchmark benchmark; + + auto config = GridBenchmark::makeInputConfig(GRID_DIMENSION); + + TNL::Config::ParameterContainer parameters; + + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + return benchmark.runBenchmark(parameters); +} diff --git a/src/Benchmarks/Grid/Grid3D.cpp b/src/Benchmarks/Grid/Grid3D.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9fb7d12358b8972d74fa82b4b45c5bb78114fa72 --- /dev/null +++ b/src/Benchmarks/Grid/Grid3D.cpp @@ -0,0 +1,2 @@ + +#include "Grid3D.h" diff --git a/src/Benchmarks/Grid/Grid3D.cu b/src/Benchmarks/Grid/Grid3D.cu new file mode 100644 index 0000000000000000000000000000000000000000..9fb7d12358b8972d74fa82b4b45c5bb78114fa72 --- /dev/null +++ b/src/Benchmarks/Grid/Grid3D.cu @@ -0,0 +1,2 @@ + +#include "Grid3D.h" diff --git a/src/Benchmarks/Grid/Grid3D.h b/src/Benchmarks/Grid/Grid3D.h new file mode 100644 index 0000000000000000000000000000000000000000..a31d17d947809549f78ad0dc9400ff03761fda33 --- /dev/null +++ b/src/Benchmarks/Grid/Grid3D.h @@ -0,0 +1,19 @@ + +#pragma once + +#include "GridBenchmark.h" + +#define GRID_DIMENSION 3 + +int main(int argc, char* argv[]) { + GridBenchmark benchmark; + + auto config = GridBenchmark::makeInputConfig(GRID_DIMENSION); + + TNL::Config::ParameterContainer parameters; + + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + return benchmark.runBenchmark(parameters); +} diff --git a/src/Benchmarks/Grid/GridBenchmark.h b/src/Benchmarks/Grid/GridBenchmark.h new file mode 100644 index 0000000000000000000000000000000000000000..767f62cacb130b738b157a85f31191c99694c65d --- /dev/null +++ b/src/Benchmarks/Grid/GridBenchmark.h @@ -0,0 +1,197 @@ + +#pragma once + +#include "Operations.h" + +#include + +#include +#include + +#include +#include + +#include + +static std::vector dimensionParameterIds = { "x-dimension", "y-dimension", "z-dimension" }; + +class GridBenchmark { + public: + using Benchmark = typename TNL::Benchmarks::Benchmark<>; + + template + int runBenchmark(const TNL::Config::ParameterContainer& parameters) const { + if (!TNL::Devices::Host::setup( parameters ) || !TNL::Devices::Cuda::setup( parameters ) ) + return EXIT_FAILURE; + + const TNL::String logFileName = parameters.getParameter( "log-file" ); + const TNL::String outputMode = parameters.getParameter( "output-mode" ); + const TNL::String precision = parameters.getParameter( "precision" ); + const TNL::String device = parameters.getParameter("device"); + + const int verbose = parameters.getParameter< int >("verbose"); + const int loops = parameters.getParameter< int >("loops"); + + auto mode = std::ios::out; + + if( outputMode == "append" ) + mode |= std::ios::app; + + std::ofstream logFile( logFileName.getString(), mode ); + + Benchmark benchmark(logFile, loops, verbose); + + // write global metadata into a separate file + std::map< std::string, std::string > metadata = TNL::Benchmarks::getHardwareMetadata(); + TNL::Benchmarks::writeMapAsJson( metadata, logFileName, ".metadata.json" ); + + if (device == "host" || device == "all") { + if (precision == "all" || precision == "float") + time(benchmark, parameters); + if (precision == "all" || precision == "double") + time(benchmark, parameters); + } + + #ifdef HAVE_CUDA + if (device == "cuda" || device == "all") { + if (precision == "all" || precision == "float") + time(benchmark, parameters); + if (precision == "all" || precision == "double") + time(benchmark, parameters); + } + #endif + + return 0; + } + + template + void time(Benchmark& benchmark, const TNL::Config::ParameterContainer& parameters) const { + using Grid = typename TNL::Meshes::Grid; + using Coordinate = typename Grid::Coordinate; + + Coordinate dimensions; + + for (int i = 0; i < GridDimension; i++) + dimensions[i] = parameters.getParameter(dimensionParameterIds[i]); + + Grid grid; + + grid.setDimensions(dimensions); + + auto forEachEntityDimension = [&](const auto entityDimension) { + using Entity = TNL::Meshes::GridEntity; + + timeTraverse(benchmark, grid); + + timeTraverse(benchmark, grid); + timeTraverse(benchmark, grid); + timeTraverse(benchmark, grid); + timeTraverse(benchmark, grid); + timeTraverse(benchmark, grid); + + timeTraverse(benchmark, grid); + timeTraverse(benchmark, grid); + timeTraverse(benchmark, grid); + }; + + TNL::Meshes::Templates::DescendingFor::exec(forEachEntityDimension); + } + + static TNL::Config::ConfigDescription makeInputConfig(int gridDimension) { + TNL_ASSERT_LE(gridDimension, 3, "Only support for grids with dimension less or equal 3"); + TNL::Config::ConfigDescription config; + + config.addDelimiter("Benchmark settings:"); + config.addEntry("id", "Identifier of the run", "unknown"); + config.addEntry("log-file", "Log file name.", "output.log"); + config.addEntry("output-mode", "Mode for opening the log file.", "overwrite"); + config.addEntryEnum("append"); + config.addEntryEnum("overwrite"); + + config.addEntry("device", "Device the computation will run on.", "cuda"); + config.addEntryEnum("all"); + config.addEntryEnum("host"); + + #ifdef HAVE_CUDA + config.addEntryEnum("cuda"); + #endif + + config.addEntry("precision", "Precision of the arithmetics.", "double"); + config.addEntryEnum("float"); + config.addEntryEnum("double"); + config.addEntryEnum("all"); + + config.addEntry("loops", "Number of iterations for every computation.", 10); + config.addEntry("verbose", "Verbose mode.", 1); + + for (int i = 0; i < gridDimension; i++) + config.addEntry(dimensionParameterIds[i], "The " + dimensionParameterIds[i] + " of grid:", 100); + + config.addDelimiter("Device settings:"); + TNL::Devices::Host::configSetup( config ); + + #ifdef HAVE_CUDA + TNL::Devices::Cuda::configSetup( config ); + #endif + + return config; + } + + template + void timeTraverse(Benchmark& benchmark, const Grid& grid) const { + auto exec = [] __cuda_callable__ (typename Grid::EntityType& entity) mutable { + Operation::exec(entity); + }; + + auto device = TNL::getType(); + auto operation = TNL::getType(); + + const Benchmark::MetadataColumns columns = { + { "operation_id", operation }, + { "dimensions", TNL::convertToString(grid.getDimensions()) }, + { "entity_dimension", TNL::convertToString(EntityDimension) }, + { "entitiesCounts", TNL::convertToString(grid.getEntitiesCount(EntityDimension)) } + }; + + Benchmark::MetadataColumns forAllColumns = { + { "traverse_id", "forAll" } + }; + + forAllColumns.insert(forAllColumns.end(), columns.begin(), columns.end()); + benchmark.setMetadataColumns(forAllColumns); + + auto measureAll = [=]() { + grid.template forAll(exec); + }; + + benchmark.time(device, measureAll); + + + Benchmark::MetadataColumns forInteriorColumns = { + { "traverse_id", "forInterior" } + }; + + forInteriorColumns.insert(forInteriorColumns.end(), columns.begin(), columns.end()); + benchmark.setMetadataColumns(forInteriorColumns); + + auto measureInterior = [=]() { + grid.template forInterior(exec); + }; + + benchmark.time(device, measureInterior); + + + Benchmark::MetadataColumns forBoundaryColumns = { + { "traverse_id", "forBoundary" } + }; + + forBoundaryColumns.insert(forBoundaryColumns.end(), columns.begin(), columns.end()); + benchmark.setMetadataColumns(forInteriorColumns); + + auto measureBoundary = [=]() { + grid.template forBoundary(exec); + }; + + benchmark.time(device, measureBoundary); + } +}; diff --git a/src/Benchmarks/Grid/Operations.h b/src/Benchmarks/Grid/Operations.h new file mode 100644 index 0000000000000000000000000000000000000000..ec3f6426a3af1048dd3d555844fe17e0f8ad8038 --- /dev/null +++ b/src/Benchmarks/Grid/Operations.h @@ -0,0 +1,102 @@ + +#pragma once + +#include +#include + + +struct VoidOperation { + public: + + template + __cuda_callable__ inline + static void exec(Entity& entity) {} +}; + + +struct GetEntityIsBoundaryOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + bool isBoundary = entity.isBoundary(); + + if (isBoundary) + isBoundary = false; + } +}; + +struct GetEntityCoordinateOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + typename Entity::GridType::Coordinate coordinate = entity.getCoordinates(); + + coordinate.x() += 1; + } +}; + +struct GetEntityIndexOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + int index = entity.getIndex(); + + index += 1; + } +}; + +struct GetEntityBasisOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + typename Entity::GridType::Coordinate coordinate = entity.getBasis(); + + coordinate.x() += 1; + } +}; + +struct RefreshEntityOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + entity.refresh(); + } +}; + +struct GetMeshDimensionOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + typename Entity::GridType::Coordinate coordinate = entity.getMesh().getDimensions(); + + coordinate.x() += 1; + } +}; + +struct GetOriginOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + typename Entity::GridType::Point coordinate = entity.getMesh().getOrigin(); + + coordinate.x() += 1; + } +}; + +struct GetEntitiesCountsOperation { + public: + template + __cuda_callable__ inline + static void exec(Entity& entity) { + typename Entity::GridType::EntitiesCounts coordinate = entity.getMesh().getEntitiesCounts(); + + coordinate.x() += 1; + } +}; diff --git a/src/Benchmarks/HeatEquation/CMakeLists.txt b/src/Benchmarks/HeatEquation/CMakeLists.txt index 64a5d9fbe0b3c5c3d06b6f6d28f04f532be53e07..616ab6658de45581e227025aff4529302128d4b8 100644 --- a/src/Benchmarks/HeatEquation/CMakeLists.txt +++ b/src/Benchmarks/HeatEquation/CMakeLists.txt @@ -12,7 +12,7 @@ ENDIF() INSTALL( TARGETS -# tnl-benchmark-heat-equation + tnl-benchmark-heat-equation tnl-benchmark-simple-heat-equation RUNTIME DESTINATION bin ) @@ -20,4 +20,7 @@ if( BUILD_CUDA ) INSTALL( TARGETS tnl-benchmark-simple-heat-equation-bug RUNTIME DESTINATION bin ) -endif() \ No newline at end of file +endif() + + + diff --git a/src/Benchmarks/HeatEquation/tnlTestGrid2D.h b/src/Benchmarks/HeatEquation/tnlTestGrid2D.h index b589e5a6582d11edb9dbd2e22405d075108da694..705d3ea2783110a6cafcd8b2ba219d4ddf7cf0b1 100644 --- a/src/Benchmarks/HeatEquation/tnlTestGrid2D.h +++ b/src/Benchmarks/HeatEquation/tnlTestGrid2D.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once @@ -21,8 +21,6 @@ class Grid : public tnlObject //#include //#include - -#include #include #include #include @@ -45,25 +43,25 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject typedef Index IndexType; typedef Containers::StaticVector< 2, Real > PointType; typedef Containers::StaticVector< 2, Index > CoordinatesType; - + static const int meshDimension = 2; - //template< int EntityDimension, + //template< int EntityDimension, // typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > > //using MeshEntity = GridEntity< ThisType, EntityDimension, Config >; - + //typedef MeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > Cell; //typedef MeshEntity< meshDimension - 1, GridEntityNoStencilStorage > Face; //typedef MeshEntity< 0 > Point; - + // TODO: remove this - template< int EntityDimension, + template< int EntityDimension, typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > > using TestMeshEntity = tnlTestGridEntity< ThisType, EntityDimension, Config >; typedef TestMeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > TestCell; ///// - + static constexpr int getMeshDimension() { return meshDimension; }; Grid(); @@ -90,11 +88,11 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject template< typename EntityType > __cuda_callable__ inline IndexType getEntitiesCount() const; - + template< typename EntityType > __cuda_callable__ inline EntityType getEntity( const IndexType& entityIndex ) const; - + template< typename EntityType > __cuda_callable__ inline Index getEntityIndex( const EntityType& entity ) const; @@ -102,21 +100,21 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject template< typename EntityType > __cuda_callable__ RealType getEntityMeasure( const EntityType& entity ) const; - + __cuda_callable__ RealType getCellMeasure() const; - + __cuda_callable__ inline PointType getSpaceSteps() const; template< int xPow, int yPow > __cuda_callable__ inline const RealType& getSpaceStepsProducts() const; - + __cuda_callable__ inline RealType getSmallestSpaceStep() const; - + template< typename GridFunction > typename GridFunction::RealType getAbsMax( const GridFunction& f ) const; @@ -159,16 +157,16 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject void computeSpaceSteps(); CoordinatesType dimensions; - + IndexType numberOfCells, numberOfNxFaces, numberOfNyFaces, numberOfFaces, numberOfVertices; PointType origin, proportions; - + PointType spaceSteps; - + RealType spaceStepsProducts[ 5 ][ 5 ]; - - template< typename, typename, int > + + template< typename, typename, int > friend class GridEntityGetter; }; @@ -225,9 +223,9 @@ void Meshes::Grid< 2, Real, Device, Index > :: computeSpaceSteps() { this->spaceSteps.x() = this->proportions.x() / ( Real ) this->getDimensions().x(); this->spaceSteps.y() = this->proportions.y() / ( Real ) this->getDimensions().y(); - const RealType& hx = this->spaceSteps.x(); + const RealType& hx = this->spaceSteps.x(); const RealType& hy = this->spaceSteps.y(); - + Real auxX, auxY; for( int i = 0; i < 5; i++ ) { @@ -269,7 +267,7 @@ void Meshes::Grid< 2, Real, Device, Index > :: computeSpaceSteps() auxY = hy * hy; break; } - this->spaceStepsProducts[ i ][ j ] = auxX * auxY; + this->spaceStepsProducts[ i ][ j ] = auxX * auxY; } } } @@ -325,7 +323,7 @@ void Meshes::Grid< 2, Real, Device, Index > :: setDomain( const PointType& origi template< typename Real, typename Device, typename Index > -__cuda_callable__ inline +__cuda_callable__ inline const typename Meshes::Grid< 2, Real, Device, Index >::PointType& Meshes::Grid< 2, Real, Device, Index >::getOrigin() const { @@ -335,7 +333,7 @@ Meshes::Grid< 2, Real, Device, Index >::getOrigin() const template< typename Real, typename Device, typename Index > -__cuda_callable__ inline +__cuda_callable__ inline const typename Meshes::Grid< 2, Real, Device, Index > :: PointType& Meshes::Grid< 2, Real, Device, Index > :: getProportions() const { @@ -346,23 +344,23 @@ template< typename Real, typename Device, typename Index > template< typename EntityType > -__cuda_callable__ inline +__cuda_callable__ inline Index -Meshes::Grid< 2, Real, Device, Index >:: +Meshes::Grid< 2, Real, Device, Index >:: getEntitiesCount() const { static_assert( EntityType::entityDimension <= 2 && EntityType::entityDimension >= 0, "Wrong grid entity dimension." ); - + switch( EntityType::entityDimension ) { case 2: return this->numberOfCells; case 1: - return this->numberOfFaces; + return this->numberOfFaces; case 0: return this->numberOfVertices; - } + } return -1; } @@ -370,14 +368,14 @@ template< typename Real, typename Device, typename Index > template< typename EntityType > -__cuda_callable__ inline +__cuda_callable__ inline EntityType Meshes::Grid< 2, Real, Device, Index >:: getEntity( const IndexType& entityIndex ) const { static_assert( EntityType::entityDimension <= 2 && EntityType::entityDimension >= 0, "Wrong grid entity dimension." ); - + return GridEntityGetter< ThisType, EntityType >::getEntity( *this, entityIndex ); } @@ -385,14 +383,14 @@ template< typename Real, typename Device, typename Index > template< typename EntityType > -__cuda_callable__ inline +__cuda_callable__ inline Index Meshes::Grid< 2, Real, Device, Index >:: getEntityIndex( const EntityType& entity ) const { static_assert( EntityType::entityDimension <= 2 && EntityType::entityDimension >= 0, "Wrong grid entity dimension." ); - + return GridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity ); } @@ -435,14 +433,14 @@ template< typename Real, typename Device, typename Index > template< int xPow, int yPow > -__cuda_callable__ inline -const Real& +__cuda_callable__ inline +const Real& Meshes::Grid< 2, Real, Device, Index >:: getSpaceStepsProducts() const { - tnlTNL_ASSERT( xPow >= -2 && xPow <= 2, + tnlTNL_ASSERT( xPow >= -2 && xPow <= 2, std::cerr << " xPow = " << xPow ); - tnlTNL_ASSERT( yPow >= -2 && yPow <= 2, + tnlTNL_ASSERT( yPow >= -2 && yPow <= 2, std::cerr << " yPow = " << yPow ); return this->spaceStepsProducts[ yPow + 2 ][ xPow + 2 ]; @@ -714,8 +712,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& functi { if( this->template getEntitiesCount< Cell >() != function. getSize() ) { - std::cerr << "The size ( " << function. getSize() - << " ) of a mesh function does not agree with the DOFs ( " + std::cerr << "The size ( " << function. getSize() + << " ) of a mesh function does not agree with the DOFs ( " << this->template getEntitiesCount< Cell >() << " ) of a mesh." < : public tnlObject typedef Index IndexType; typedef Containers::StaticVector< 2, Real > PointType; typedef Containers::StaticVector< 2, Index > CoordinatesType; - + static const int meshDimension = 2; - /*template< int EntityDimension, + /*template< int EntityDimension, typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > > using MeshEntity = GridEntity< ThisType, EntityDimension, Config >; - + typedef MeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > Cell; typedef MeshEntity< meshDimension - 1, GridEntityNoStencilStorage > Face; typedef MeshEntity< 0 > Point;*/ - + // TODO: remove this - template< int EntityDimension, + template< int EntityDimension, typename Config = GridEntityNoStencilStorage >//CrossStencilStorage< 1 > > using TestMeshEntity = tnlTestGridEntity< ThisType, EntityDimension, Config >; typedef TestMeshEntity< meshDimension, GridEntityCrossStencilStorage< 1 > > Cell; ///// - + static constexpr int getMeshDimension() { return meshDimension; }; Grid(); @@ -843,11 +841,11 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject template< typename EntityType > __cuda_callable__ inline IndexType getEntitiesCount() const; - + template< typename EntityType > __cuda_callable__ inline EntityType getEntity( const IndexType& entityIndex ) const; - + template< typename EntityType > __cuda_callable__ inline Index getEntityIndex( const EntityType& entity ) const; @@ -855,21 +853,21 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject template< typename EntityType > __cuda_callable__ RealType getEntityMeasure( const EntityType& entity ) const; - + __cuda_callable__ RealType getCellMeasure() const; - + __cuda_callable__ inline PointType getSpaceSteps() const; template< int xPow, int yPow > __cuda_callable__ inline const RealType& getSpaceStepsProducts() const; - + __cuda_callable__ inline RealType getSmallestSpaceStep() const; - + template< typename GridFunction > typename GridFunction::RealType getAbsMax( const GridFunction& f ) const; @@ -912,16 +910,16 @@ class Meshes::Grid< 2, Real, Device, Index > : public tnlObject void computeSpaceSteps(); CoordinatesType dimensions; - + IndexType numberOfCells, numberOfNxFaces, numberOfNyFaces, numberOfFaces, numberOfVertices; PointType origin, proportions; - + PointType spaceSteps; - + RealType spaceStepsProducts[ 5 ][ 5 ]; - - template< typename, typename, int > + + template< typename, typename, int > friend class GridEntityGetter; }; @@ -967,9 +965,9 @@ void Meshes::Grid< 2, Real, Device, Index > :: computeSpaceSteps() { this->spaceSteps.x() = this->proportions.x() / ( Real ) this->getDimensions().x(); this->spaceSteps.y() = this->proportions.y() / ( Real ) this->getDimensions().y(); - const RealType& hx = this->spaceSteps.x(); + const RealType& hx = this->spaceSteps.x(); const RealType& hy = this->spaceSteps.y(); - + Real auxX, auxY; for( int i = 0; i < 5; i++ ) { @@ -1011,7 +1009,7 @@ void Meshes::Grid< 2, Real, Device, Index > :: computeSpaceSteps() auxY = hy * hy; break; } - this->spaceStepsProducts[ i ][ j ] = auxX * auxY; + this->spaceStepsProducts[ i ][ j ] = auxX * auxY; } } } @@ -1067,7 +1065,7 @@ void Meshes::Grid< 2, Real, Device, Index > :: setDomain( const PointType& origi template< typename Real, typename Device, typename Index > -__cuda_callable__ inline +__cuda_callable__ inline const typename Meshes::Grid< 2, Real, Device, Index >::PointType& Meshes::Grid< 2, Real, Device, Index >::getOrigin() const { @@ -1077,7 +1075,7 @@ Meshes::Grid< 2, Real, Device, Index >::getOrigin() const template< typename Real, typename Device, typename Index > -__cuda_callable__ inline +__cuda_callable__ inline const typename Meshes::Grid< 2, Real, Device, Index > :: PointType& Meshes::Grid< 2, Real, Device, Index > :: getProportions() const { @@ -1088,23 +1086,23 @@ template< typename Real, typename Device, typename Index > template< typename EntityType > -__cuda_callable__ inline +__cuda_callable__ inline Index -Meshes::Grid< 2, Real, Device, Index >:: +Meshes::Grid< 2, Real, Device, Index >:: getEntitiesCount() const { static_assert( EntityType::entityDimension <= 2 && EntityType::entityDimension >= 0, "Wrong grid entity dimension." ); - + switch( EntityType::entityDimension ) { case 2: return this->numberOfCells; case 1: - return this->numberOfFaces; + return this->numberOfFaces; case 0: return this->numberOfVertices; - } + } return -1; } @@ -1112,14 +1110,14 @@ template< typename Real, typename Device, typename Index > template< typename EntityType > -__cuda_callable__ inline +__cuda_callable__ inline EntityType Meshes::Grid< 2, Real, Device, Index >:: getEntity( const IndexType& entityIndex ) const { static_assert( EntityType::entityDimension <= 2 && EntityType::entityDimension >= 0, "Wrong grid entity dimension." ); - + return GridEntityGetter< ThisType, EntityType >::getEntity( *this, entityIndex ); } @@ -1127,14 +1125,14 @@ template< typename Real, typename Device, typename Index > template< typename EntityType > -__cuda_callable__ inline +__cuda_callable__ inline Index Meshes::Grid< 2, Real, Device, Index >:: getEntityIndex( const EntityType& entity ) const { static_assert( EntityType::entityDimension <= 2 && EntityType::entityDimension >= 0, "Wrong grid entity dimension." ); - + return GridEntityGetter< ThisType, EntityType >::getEntityIndex( *this, entity ); } @@ -1177,14 +1175,14 @@ template< typename Real, typename Device, typename Index > template< int xPow, int yPow > -__cuda_callable__ inline -const Real& +__cuda_callable__ inline +const Real& Meshes::Grid< 2, Real, Device, Index >:: getSpaceStepsProducts() const { - tnlTNL_ASSERT( xPow >= -2 && xPow <= 2, + tnlTNL_ASSERT( xPow >= -2 && xPow <= 2, std::cerr << " xPow = " << xPow ); - tnlTNL_ASSERT( yPow >= -2 && yPow <= 2, + tnlTNL_ASSERT( yPow >= -2 && yPow <= 2, std::cerr << " yPow = " << yPow ); return this->spaceStepsProducts[ yPow + 2 ][ xPow + 2 ]; @@ -1456,8 +1454,8 @@ bool Meshes::Grid< 2, Real, Device, Index > :: write( const MeshFunction& functi { if( this->template getEntitiesCount< Cell >() != function. getSize() ) { - std::cerr << "The size ( " << function. getSize() - << " ) of a mesh function does not agree with the DOFs ( " + std::cerr << "The size ( " << function. getSize() + << " ) of a mesh function does not agree with the DOFs ( " << this->template getEntitiesCount< Cell >() << " ) of a mesh." << std::endl; return false; } @@ -1503,7 +1501,3 @@ writeProlog( tnlLogger& logger ) logger.writeParameter( "Space steps:", this->getSpaceSteps() ); } #endif - - - - diff --git a/src/Benchmarks/HeatEquationGrid/Base/HeatmapSolver.h b/src/Benchmarks/HeatEquationGrid/Base/HeatmapSolver.h new file mode 100644 index 0000000000000000000000000000000000000000..aedb46332269dbf328cce67b57711821153d22e5 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/Base/HeatmapSolver.h @@ -0,0 +1,113 @@ + +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +template +class HeatmapSolver +{ +public: + class Parameters + { + public: + const int xSize, ySize; + const Real xDomainSize, yDomainSize; + const Real sigma; + const Real timeStep, finalTime; + const bool outputData; + const bool verbose; + + Parameters(const TNL::Config::ParameterContainer ¶meters); + Parameters(const int xSize, const int ySize, + const Real xDomainSize, const Real yDomainSize, + const Real sigma, + const Real timeStep, const Real finalTime, + const bool outputData, + const bool verbose): + xSize(xSize), ySize(ySize), + xDomainSize(xDomainSize), yDomainSize(yDomainSize), + sigma(sigma), + timeStep(timeStep), finalTime(finalTime), + outputData(outputData), verbose(verbose) {} + + static TNL::Config::ConfigDescription makeInputConfig(); + }; + + template + bool solve(const Parameters ¶meters) const; +private: + template + bool writeGNUPlot(const std::string &filename, + const Parameters ¶meters, + const TNL::Containers::Array &map) const; +}; + +template +TNL::Config::ConfigDescription HeatmapSolver::Parameters::makeInputConfig() +{ + TNL::Config::ConfigDescription config; + + config.addEntry("device", "Device the computation will run on.", "cuda"); + config.addEntryEnum("host"); + +#ifdef HAVE_CUDA + config.addEntryEnum("cuda"); +#endif + config.addEntry("grid-x-size", "Grid size along x-axis.", 100); + config.addEntry("grid-y-size", "Grid size along y-axis.", 100); + + config.addEntry("domain-x-size", "Domain size along x-axis.", 2.0); + config.addEntry("domain-y-size", "Domain size along y-axis.", 2.0); + + config.addEntry("sigma", "Sigma in exponential initial condition.", 1.0); + + config.addEntry("time-step", "Time step. By default it is proportional to one over space step square.", 0.00001); + config.addEntry("final-time", "Final time of the simulation.", 0.012); + config.addEntry("verbose", "Verbose mode.", true); + + return config; +} + +template +HeatmapSolver::Parameters::Parameters(const TNL::Config::ParameterContainer ¶meters) : xSize(parameters.getParameter("grid-x-size")), + ySize(parameters.getParameter("grid-y-size")), + xDomainSize(parameters.getParameter("domain-x-size")), + yDomainSize(parameters.getParameter("domain-y-size")), + sigma(parameters.getParameter("sigma")), + timeStep(parameters.getParameter("time-step")), + finalTime(parameters.getParameter("final-time")), + outputData(parameters.getParameter("outputData")), + verbose(parameters.getParameter("verbose")) {} + +template +template +bool HeatmapSolver::writeGNUPlot(const std::string &filename, + const HeatmapSolver::Parameters ¶ms, + const TNL::Containers::Array &map) const { + if (std::is_same::value) { + TNL::Containers::Array host(map); + + return writeGNUPlot(filename, params, host); + } + + if (!params.outputData) + return true; + + std::ofstream out(filename, std::ios::out); + + if (!out.is_open()) + return false; + + for (int j = 0; j < params.ySize; j++) + for (int i = 0; i < params.xSize; i++) + out << i << " " << j << " " << map[j * params.xSize + i] << std::endl; + + return out.good(); +} diff --git a/src/Benchmarks/HeatEquationGrid/Base/HeatmapSolverBenchmark.h b/src/Benchmarks/HeatEquationGrid/Base/HeatmapSolverBenchmark.h new file mode 100644 index 0000000000000000000000000000000000000000..e3eecad975708d71da956c467128bca6b56327d0 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/Base/HeatmapSolverBenchmark.h @@ -0,0 +1,203 @@ + +#include + +#include +#include + +#include + +#include "HeatmapSolver.h" + +#pragma once + +class HeatmapSolverBenchmark { + public: + template + void exec(const typename HeatmapSolver::Parameters& params) const; + + template + void runBenchmark(TNL::Benchmarks::Benchmark<> & benchmark, + const std::size_t minXDimension, + const std::size_t maxXDimension, + const std::size_t xStepSizeFactor, + const std::size_t minYDimension, + const std::size_t maxYDimension, + const std::size_t yStepSizeFactor, + const TNL::Config::ParameterContainer& parameters) const; + + static TNL::Config::ConfigDescription makeInputConfig(); +}; + +TNL::Config::ConfigDescription HeatmapSolverBenchmark::makeInputConfig() { + TNL::Config::ConfigDescription config; + + config.addDelimiter("Benchmark settings:"); + config.addEntry("id", "Identifier of the run", "unknown"); + config.addEntry("log-file", "Log file name.", "tnl-benchmark-heatmap.log"); + config.addEntry("output-mode", "Mode for opening the log file.", "overwrite"); + config.addEntryEnum("append"); + config.addEntryEnum("overwrite"); + + config.addEntry("device", "Device the computation will run on.", "cuda"); + config.addEntryEnum("all"); + config.addEntryEnum("host"); + +#ifdef HAVE_CUDA + config.addEntryEnum("cuda"); +#endif + + config.addEntry("precision", "Precision of the arithmetics.", "double"); + config.addEntryEnum("float"); + config.addEntryEnum("double"); + config.addEntryEnum("all"); + + config.addEntry("min-x-dimension", "Minimum dimension over x axis used in the benchmark.", 100); + config.addEntry("max-x-dimension", "Maximum dimension over x axis used in the benchmark.", 200); + config.addEntry("x-size-step-factor", "Factor determining the dimension grows over x axis. First size is min-x-dimension and each following size is stepFactor*previousSize, up to max-x-dimension.", 2); + + config.addEntry("min-y-dimension", "Minimum dimension over x axis used in the benchmark.", 100); + config.addEntry("max-y-dimension", "Maximum dimension over x axis used in the benchmark.", 200); + config.addEntry("y-size-step-factor", "Factor determining the dimension grows over y axis. First size is min-y-dimension and each following size is stepFactor*previousSize, up to max-y-dimension.", 2); + + config.addEntry("loops", "Number of iterations for every computation.", 10); + + config.addEntry("verbose", "Verbose mode.", 1); + + config.addDelimiter("Problem settings:"); + config.addEntry("domain-x-size", "Domain size along x-axis.", 2.0); + config.addEntry("domain-y-size", "Domain size along y-axis.", 2.0); + + config.addEntry("sigma", "Sigma in exponential initial condition.", 1.0); + + config.addEntry("time-step", "Time step. By default it is proportional to one over space step square.", 0.000001); + config.addEntry("final-time", "Final time of the simulation.", 0.01); + + config.addDelimiter("Device settings:"); + TNL::Devices::Host::configSetup( config ); + TNL::Devices::Cuda::configSetup( config ); + + return config; +} + +template +void HeatmapSolverBenchmark::exec(const typename HeatmapSolver::Parameters& params) const { + HeatmapSolver solver; + + auto result = solver.template solve(params); + + if (!result) + printf("Fail to solve for grid size (%d,%d)", params.xSize, params.ySize); +} + +template +void HeatmapSolverBenchmark::runBenchmark(TNL::Benchmarks::Benchmark<>& benchmark, + const std::size_t minXDimension, + const std::size_t maxXDimension, + const std::size_t xStepSizeFactor, + const std::size_t minYDimension, + const std::size_t maxYDimension, + const std::size_t yStepSizeFactor, + const TNL::Config::ParameterContainer& parameters) const { + Real xDomainSize = parameters.getParameter("domain-x-size"); + Real yDomainSize = parameters.getParameter("domain-y-size"); + Real sigma = parameters.getParameter("sigma"); + Real timeStep = parameters.getParameter("time-step"); + Real finalTime = parameters.getParameter("final-time"); + + auto precision = TNL::getType(), device = TNL::getType(); + + std::cout << "Heatmap grid with (" + precision + ", host allocator " + device + ")" << std::endl; + + for(std::size_t xSize = minXDimension; xSize <= maxXDimension; xSize *= xStepSizeFactor) { + for(std::size_t ySize = minXDimension; ySize <= maxXDimension; ySize *= yStepSizeFactor) { + benchmark.setMetadataColumns( TNL::Benchmarks::Benchmark<>::MetadataColumns({ + { "precision", precision }, + { "xSize", TNL::convertToString(xSize) }, + { "ySize", TNL::convertToString(ySize) }, + { "id", parameters.getParameter("id") } + })); + + benchmark.setDatasetSize(xSize * ySize); + + auto lambda = [=]() { + typename HeatmapSolver::Parameters params(xSize, ySize, xDomainSize, yDomainSize, sigma, timeStep, finalTime, false, false); + + exec(params); + }; + + benchmark.time(device, lambda); + } + } +} + +int main(int argc, char* argv[]) { + HeatmapSolverBenchmark solver; + + auto config = HeatmapSolverBenchmark::makeInputConfig(); + + TNL::Config::ParameterContainer parameters; + + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + if (!TNL::Devices::Host::setup( parameters ) || !TNL::Devices::Cuda::setup( parameters ) ) + return EXIT_FAILURE; + + const TNL::String logFileName = parameters.getParameter( "log-file" ); + const TNL::String outputMode = parameters.getParameter( "output-mode" ); + const TNL::String precision = parameters.getParameter( "precision" ); + + const std::size_t minXDimension = parameters.getParameter("min-x-dimension"); + const std::size_t maxXDimension = parameters.getParameter("max-x-dimension"); + const std::size_t xSizeStepFactor = parameters.getParameter("x-size-step-factor"); + + if(xSizeStepFactor <= 1) { + std::cerr << "The value of --x-size-step-factor must be greater than 1." << std::endl; + return EXIT_FAILURE; + } + + const std::size_t minYDimension = parameters.getParameter("min-y-dimension"); + const std::size_t maxYDimension = parameters.getParameter("max-y-dimension"); + const std::size_t ySizeStepFactor = parameters.getParameter("y-size-step-factor"); + + const int loops = parameters.getParameter< int >("loops"); + const int verbose = parameters.getParameter< int >("verbose"); + + if(ySizeStepFactor <= 1) { + std::cerr << "The value of --y-size-step-factor must be greater than 1." << std::endl; + return EXIT_FAILURE; + } + + auto mode = std::ios::out; + + if( outputMode == "append" ) + mode |= std::ios::app; + + std::ofstream logFile( logFileName.getString(), mode ); + + TNL::Benchmarks::Benchmark<> benchmark(logFile, loops, verbose); + + // write global metadata into a separate file + std::map< std::string, std::string > metadata = TNL::Benchmarks::getHardwareMetadata(); + TNL::Benchmarks::writeMapAsJson( metadata, logFileName, ".metadata.json" ); + + auto device = parameters.getParameter("device"); + + if (device == "host" || device == "all") { + if(precision == "all" || precision == "float") + solver.runBenchmark(benchmark, minXDimension, maxXDimension, xSizeStepFactor, minYDimension, maxYDimension, ySizeStepFactor, parameters); + if(precision == "all" || precision == "double") + solver.runBenchmark(benchmark, minXDimension, maxXDimension, xSizeStepFactor, minYDimension, maxYDimension, ySizeStepFactor, parameters); + } + +#ifdef HAVE_CUDA + if (device == "cuda" || device == "all") { + if( precision == "all" || precision == "float" ) + solver.runBenchmark(benchmark, minXDimension, maxXDimension, xSizeStepFactor, minYDimension, maxYDimension, ySizeStepFactor, parameters); + if( precision == "all" || precision == "double" ) + solver.runBenchmark(benchmark, minXDimension, maxXDimension, xSizeStepFactor, minYDimension, maxYDimension, ySizeStepFactor, parameters); + } +#endif + + return EXIT_SUCCESS; +} diff --git a/src/Benchmarks/HeatEquationGrid/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..aadec614b021ec6d247f9988d5ba90a728837770 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/CMakeLists.txt @@ -0,0 +1,4 @@ +ADD_SUBDIRECTORY( HeatmapParallelFor ) +ADD_SUBDIRECTORY( HeatmapNDimGrid ) +ADD_SUBDIRECTORY( HeatmapTNLGrid ) +ADD_SUBDIRECTORY( HeatmapTNLGridWithMemoryLoad ) diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..58c97ef0d44b742043c4005d632847dd547c15ee --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY( benchmark ) +ADD_SUBDIRECTORY( solution ) diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b52b3909d50511a2b5fac608b4ca1272dd3a9a32 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_n_dim_grid_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cu ) +ELSE() + add_executable( heat_n_dim_grid_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.h new file mode 100644 index 0000000000000000000000000000000000000000..24eb97da82bf5bbd553d20b9965f22e9ec74d75c --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/benchmark/main.h @@ -0,0 +1,6 @@ + +#include "../../Base/HeatmapSolver.h" +#include "../../Base/HeatmapSolverBenchmark.h" +#include "../implementation.h" + +#pragma once diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/implementation.h b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/implementation.h new file mode 100644 index 0000000000000000000000000000000000000000..0245096c281b3677f1405014281da382ac94c642 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/implementation.h @@ -0,0 +1,423 @@ + +#include +#include +#include +#include +#include +#include + +#include "../Base/HeatmapSolver.h" + +#include +#include +#include +#include +#include + +#pragma once + +template struct bool_pack {}; + +template +using conjunction = std::is_same, bool_pack>; + +template 0)>, + typename = std::enable_if_t::value>> +using Container = TNL::Containers::StaticArray; + +template 0)>, + typename = std::enable_if_t::value>> +class GridEntity { + public: + __cuda_callable__ + inline explicit GridEntity(const Index& vertexIndex, + const Container& coordinates, + const Container& direction) : + vertexIndex(vertexIndex), + coordinates(coordinates), + direction(direction) {}; + + __cuda_callable__ + ~GridEntity() {}; + + __cuda_callable__ + inline Container getCoordinates() const noexcept { + return coordinates; + } + + __cuda_callable__ + inline Index getIndex() const noexcept { + return vertexIndex; + } + private: + const Index vertexIndex; + const Container coordinates; + const Container direction; +}; + +template 0)>> +class Grid { + public: + Grid() {} + ~Grid() {} + + /** + * @brief - Specifies dimensions of the grid + * @param[in] dimensions - A parameter pack, which specifies points count in the specific dimension. + * Most significant dimension is in the beginning of the list. + * Least significant dimension is in the end of the list + */ + template ::value...>::value>, + typename = std::enable_if_t> + void setDimensions(Dimensions... dimensions) noexcept { + Index i = 0; + + for (auto x: { dimensions... }) { + TNL_ASSERT_GT(x, 0, "Dimension must be positive"); + this -> dimensions[i] = x; + i++; + } + + refreshDimensionMaps(); + } + /** + * @param[in] index - index of dimension + */ + inline __cuda_callable__ Index getDimension(Index index) const noexcept { + TNL_ASSERT_GE(index, 0, "Index must be greater than zero"); + TNL_ASSERT_LT(index, Dimension, "Index must be less than Dimension"); + + return dimensions[index]; + } + /** + * @param[in] indices - A dimension index pack + */ + template ::value...>::value>, + typename = std::enable_if_t<(sizeof...(DimensionIndex) > 0)>> + Container getDimensions(DimensionIndex... indices) const noexcept { + Container result{indices...}; + + for (std::size_t i = 0; i < sizeof...(DimensionIndex); i++) + result[i] = this -> getDimension(result[i]); + + return result; + } + /** + * @param[in] index - index of dimension + */ + inline __cuda_callable__ Index getEntitiesCount(Index index) const noexcept { + TNL_ASSERT_GE(index, 0, "Index must be greater than zero"); + TNL_ASSERT_LE(index, Dimension, "Index must be less than or equal to Dimension"); + + return cumulativeDimensionMap(index); + } + /** + * @brief - Returns the number of entities of specific dimension + */ + template ::value...>::value>, + typename = std::enable_if_t<(sizeof...(DimensionIndex) > 0)>> + Container getEntitiesCounts(DimensionIndex... indices) const noexcept { + Container result{indices...}; + + for (std::size_t i = 0; i < sizeof...(DimensionIndex); i++) + result[i] = this -> getEntitiesCount(result[i]); + + return result; + } + /** + * @param[in] index - index of dimension + */ + inline __cuda_callable__ Index getEndIndex(Index index) const noexcept { + TNL_ASSERT_GE(index, 0, "Index must be greater than zero"); + TNL_ASSERT_LT(index, Dimension, "Index must be less than or equal to Dimension"); + + return this -> getDimension(index) - 1; + } + /** + * @brief - Returns the last index of specific dimensions + */ + template ::value...>::value>, + typename = std::enable_if_t<(sizeof...(DimensionIndex) > 0)>> + Container getEndIndices(DimensionIndex... indices) const noexcept { + Container result{ indices... }; + + for (std::size_t i = 0; i < sizeof...(DimensionIndex); i++) + result[i] = this->getEndIndex(result[i]); + + return result; + } + /** + * @brief - Traversers all elements in the grid + */ + template + void traverseAll(Function function, FunctionArgs... args) const noexcept { + auto lambda = [=] __cuda_callable__(const Index index, FunctionArgs... args) mutable { + function(index, args...); + }; + + TNL::Algorithms::ParallelFor::exec(0, cumulativeDimensionMap[0], lambda, args...); + } + /** + * @brief - Traverses a grid from start index to end index. + * + * @param[in] start - a start index of point + * @param[in] end - an end index of point + * @param[in] directions - A pack of boolean vector flags with the size of the dimension. + * For example, let's have the 3-dimensional grid. + * A pack {false, false, false} will call function for all points + * A pack {true, false, false} will call function for edges directed over dimension at index of true + * A pack {true, true, false} will call function for faces directed over dimension at index of true + * A pack {true, true, true} will call function for cells directed over + * + */ + template + void traverse(const Container& firstVertex, + const Container& secondVertex, + const TNL::Containers::Array, Device>& directions, + Function function, + FunctionArgs... args) const noexcept { + Index verticesCount = 1; + Container traverseRectOrigin, traverseRectDimensions, + dimensionsProducts, traverseRectDimensionsProducts; + + for (Index i = 0; i < Dimension; i++) { + traverseRectDimensions[i] = abs(secondVertex[i] - firstVertex[i]) + 1; + verticesCount *= traverseRectDimensions[i]; + traverseRectOrigin[i] = std::min(firstVertex[i], secondVertex[i]); + + TNL_ASSERT_LT(firstVertex[i], dimensions[i], "End index must be in dimensions range"); + TNL_ASSERT_LT(secondVertex[i], dimensions[i], "Start index must be in dimensions range"); + } + + dimensionsProducts = getDimensionProducts(dimensions); + traverseRectDimensionsProducts = getDimensionProducts(traverseRectDimensions); + + auto outerFunction = [=] __cuda_callable__(Index offset, + const Container& traverseRectOrigin, + const Container& traverseRectDimensions, + const Container& traverseRectDimensionsProducts, + const Container& dimensionsProducts, + FunctionArgs... args) mutable { + auto entity = this -> makeEntitity(offset, + traverseRectOrigin, traverseRectDimensions, + traverseRectDimensionsProducts, dimensionsProducts); + + function(entity, args...); + }; + + Index lowerBound = 0, upperBound = verticesCount; + + for (Index i = 0; i < directions.getSize(); i++) { + TNL::Algorithms::ParallelFor::exec(lowerBound, upperBound, outerFunction, + traverseRectOrigin, + traverseRectDimensions, + traverseRectDimensionsProducts, + dimensionsProducts, + args...); + } + } + private: + Container dimensions; + /** + * @brief - A dimension map is a store for dimension limits over all combinations of basis. + * First, (n choose 0) elements will contain the count of 0 dimension elements + * Second, (n choose 1) elements will contain the count of 1-dimension elements + * .... + * + * For example, let's have a 3-d grid, then the map indexing will be the next: + * 0 - 0 - count of vertices + * 1, 2, 3 - count of edges in x, y, z plane + * 4, 5, 6 - count of faces in xy, yz, zy plane + * 7 - count of cells in z y x plane + * + * @warning - The ordering of is lexigraphical. + */ + Container<1 << Dimension, Index> dimensionMap; + /** + * @brief - A cumulative map over dimensions. + */ + Container cumulativeDimensionMap; + /** + * @brief - Fills dimensions map for N-dimensional Grid. + * + * @complexity - O(2 ^ Dimension) + */ + void refreshDimensionMaps() noexcept { + std::array combinationBuffer = {}; + std::size_t j = 0; + + for (std::size_t i = 0; i < Dimension + 1; i++) + cumulativeDimensionMap[i] = 0; + + for (std::size_t i = 0; i <= Dimension; i++) { + std::fill(combinationBuffer.begin(), combinationBuffer.end(), false); + std::fill(combinationBuffer.end() - i, combinationBuffer.end(), true); + + do { + int result = 1; + + for (std::size_t k = 0; k < combinationBuffer.size(); k++) + result *= combinationBuffer[k] ? dimensions[Dimension - k - 1] - 1 : dimensions[Dimension - k - 1]; + + dimensionMap[j] = result; + cumulativeDimensionMap[i] += result; + + j++; + } while (std::next_permutation(combinationBuffer.begin(), combinationBuffer.end())); + } + } + + __cuda_callable__ inline + GridEntity makeEntitity(const Index& index, + const Container& traverseRectOrigin, + const Container& traverseRectDimensions, + const Container& traverseRectDimensionsProducts, + const Container& dimensionsProducts) const { + //Container traverseCoordinates = 0; + Container traverseCoordinates = getCoordinates(index, traverseRectDimensions); + Container globalCoordinates = 0; + + for (Index i = 0; i < Dimension; i++) + globalCoordinates[i] = traverseRectOrigin[i] + traverseCoordinates[i]; + + const auto globalIndex = getIndex(globalCoordinates, dimensionsProducts); + + return GridEntity(globalIndex, globalCoordinates, {}); + } + /** + * Calculates position in the specific boundaries + */ + __cuda_callable__ inline + Container getCoordinates(const Index& index, + const Container &dimensions) const { + Container coordinates = 0; + Index tmpIndex = index; + + Index dimensionIndex = 0; + + while (tmpIndex && dimensionIndex < Dimension) { + Index dimension = dimensions[dimensionIndex], + quotient = tmpIndex / dimension, + reminder = tmpIndex - (dimension * quotient); + + coordinates[dimensionIndex] = reminder; + tmpIndex = quotient; + + dimensionIndex += 1; + } + + return coordinates; + } + /** + * Calculates product matrix based on the dimension + */ + __cuda_callable__ inline + Container getDimensionProducts(const Container& dimensions) const noexcept { + Container products = 0; + + products[0] = 1; + + for (Index i = 1; i < Dimension; i++) + products[i] = dimensions[i - 1] * products[i - 1]; + + return products; + } + /** + * Calculates index based on the dimension + */ + __cuda_callable__ inline + Index getIndex(const Container& coordinates, + const Container& dimensionProducts) const { + Index index = 0; + + for (Index i = 0; i < Dimension; i++) + index += coordinates[i] * dimensionProducts[i]; + + return index; + } + +}; + +template +template +bool HeatmapSolver::solve(const HeatmapSolver::Parameters ¶ms) const { + Grid<2, int, Device> grid; + + grid.setDimensions(params.xSize, params.ySize); + + const Real hx = params.xDomainSize / (Real)grid.getDimension(0); + const Real hy = params.yDomainSize / (Real)grid.getDimension(1); + const Real hx_inv = 1. / (hx * hx); + const Real hy_inv = 1. / (hy * hy); + + auto entitiesCount = grid.getEntitiesCount(0); + auto timestep = params.timeStep ? params.timeStep : std::min(hx * hx, hy * hy); + auto xDomainSize = params.xDomainSize; + auto yDomainSize = params.yDomainSize; + auto sigma = params.sigma; + + TNL::Containers::Array ux(entitiesCount), // data at step u + aux(entitiesCount);// data at step u + 1 + + auto uxView = ux.getView(), auxView = aux.getView(); + + // Invalidate ux/aux + ux = 0; + aux = 0; + + auto init = [=] __cuda_callable__(const GridEntity<2, int>& entity) mutable { + auto position = entity.getCoordinates(); + auto index = entity.getIndex(); + + auto x = position[0] * hx - xDomainSize / 2; + auto y = position[1] * hx - yDomainSize / 2; + + uxView[index] = exp(sigma * (x * x + y * y)); + }; + + const Container<2, bool> direction{ false, false }; + + grid.traverse({ 1, 1 }, + { grid.getEndIndex(0) - 1, grid.getEndIndex(1) - 1 }, + { direction }, + init); + + if (!writeGNUPlot("data.txt", params, ux)) + return false; + + auto xDimension = grid.getDimension(0); + + auto next = [=] __cuda_callable__(const GridEntity<2, int>& entity) mutable { + auto index = entity.getIndex(); + auto center = 2 * uxView[index]; + + auxView[index] = ((uxView[index - 1] - center + uxView[index + 1]) * hx_inv + + (uxView[index - xDimension] - center + uxView[index + xDimension]) * hy_inv) * timestep; + }; + + Real start = 0; + + while (start < params.finalTime) { + grid.traverse({ 1, 1 }, + { grid.getEndIndex(0) - 1, grid.getEndIndex(1) - 1 }, + { direction }, + next); + + auxView.swap(uxView); + + start += timestep; + } + + return writeGNUPlot("data_final.txt", params, ux); +}; diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ab54f05ab86c43f566476f46f68038c4f6a1d8a --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_n_dim_grid ../implementation.h ../../Base/HeatmapSolver.h main.h main.cu ) +ELSE() + add_executable( heat_n_dim_grid ../implementation.h ../../Base/HeatmapSolver.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.h new file mode 100644 index 0000000000000000000000000000000000000000..54d0c86f0d3b1c093152aee294e6d8396e9344cf --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapNDimGrid/solution/main.h @@ -0,0 +1,38 @@ + +#include +#include +#include +#include +#include +#include + +#include "../../Base/HeatmapSolver.h" +#include "../implementation.h" + +int main(int argc, char* argv[]) { + using Real = double; + + auto config = HeatmapSolver::Parameters::makeInputConfig(); + + TNL::Config::ParameterContainer parameters; + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + auto device = parameters.getParameter("device"); + + parameters.addParameter("outputData", true); + + auto params = HeatmapSolver::Parameters(parameters); + + HeatmapSolver solver; + + if (device == "host" && !solver.solve(params)) + return EXIT_FAILURE; + +#ifdef HAVE_CUDA + if (device == "cuda" && !solver.solve(params)) + return EXIT_FAILURE; +#endif + + return EXIT_SUCCESS; +} diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..58c97ef0d44b742043c4005d632847dd547c15ee --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY( benchmark ) +ADD_SUBDIRECTORY( solution ) diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..364b4a99f0d172d0c59e335df8653a86986a5323 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_parallel_for_grid_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cu ) +ELSE() + add_executable( heat_parallel_for_grid_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.h new file mode 100644 index 0000000000000000000000000000000000000000..64defc7d172ae4f2864ec73d4716dbe863b0db54 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/benchmark/main.h @@ -0,0 +1,5 @@ +#include "../../Base/HeatmapSolver.h" +#include "../../Base/HeatmapSolverBenchmark.h" +#include "../implementation.h" + +#pragma once diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/implementation.h b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/implementation.h new file mode 100644 index 0000000000000000000000000000000000000000..856ce4e2af157a4a9d2eab2cf672cdefa5c1fcc1 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/implementation.h @@ -0,0 +1,92 @@ + +#include +#include + +#include + +#include "../Base/HeatmapSolver.h" + +#pragma once + +/*** + * Grid parameters: + * + * ySize-1|j (ySize - 1) * xSize + xSize - 1 + * |------------------------------------------------------ + * | + * | + * | + * | + * | + * | + * | + * | + * | + * |------------------------------------------------------> + * + * 0 xSize-1|i + * + * j * xSize + i + ***/ +template +template +bool HeatmapSolver::solve(const HeatmapSolver::Parameters ¶ms) const +{ + TNL::Containers::Array ux(params.xSize * params.ySize); // data at step u + TNL::Containers::Array aux(params.xSize * params.ySize);// data at step u + 1 + + // Invalidate ux/aux + ux = 0; + aux = 0; + + const Real hx = params.xDomainSize / (Real)params.xSize; + const Real hy = params.yDomainSize / (Real)params.ySize; + const Real hx_inv = 1. / (hx * hx); + const Real hy_inv = 1. / (hy * hy); + + auto timestep = params.timeStep ? params.timeStep : std::min(hx * hx, hy * hy); + + auto uxView = ux.getView(), auxView = aux.getView(); + + auto xSize = params.xSize; + auto xDomainSize = params.xDomainSize; + auto yDomainSize = params.yDomainSize; + auto sigma = params.sigma; + + auto init = [=] __cuda_callable__(int i, int j) mutable + { + auto index = j * xSize + i; + + auto x = i * hx - xDomainSize / 2.; + auto y = j * hy - yDomainSize / 2.; + + uxView[index] = exp(sigma * (x * x + y * y)); + }; + + TNL::Algorithms::ParallelFor2D::exec(1, 1, params.xSize - 1, params.ySize - 1, init); + + if (!writeGNUPlot("data.txt", params, ux)) + return false; + + auto next = [=] __cuda_callable__(int i, int j) mutable + { + auto index = j * xSize + i; + auto center = 2 * uxView[index]; + + auxView[index] = ((uxView[index - 1] - center + uxView[index + 1]) * hx_inv + + (uxView[index - xSize] - center + uxView[index + xSize]) * hy_inv) * timestep; + }; + + Real start = 0; + + while (start < params.finalTime) + { + TNL::Algorithms::ParallelFor2D::exec(1, 1, params.xSize - 1, params.ySize - 1, next); + + auxView.swap(uxView); + + start += timestep; + } + + return writeGNUPlot("data_final.txt", params, ux); +} diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8cc2bdf69d424e9e992a47889c52cc522bcc3930 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_parallel_for_grid ../implementation.h ../../Base/HeatmapSolver.h main.h main.cu ) +ELSE() + add_executable( heat_parallel_for_grid ../implementation.h ../../Base/HeatmapSolver.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.h new file mode 100644 index 0000000000000000000000000000000000000000..31c5ded3a8d6f14e47dc63b53c7a3e1380a87400 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapParallelFor/solution/main.h @@ -0,0 +1,37 @@ + +#include +#include +#include +#include +#include +#include + +#include "../../Base/HeatmapSolver.h" +#include "../implementation.h" + +int main(int argc, char *argv[]) { + using Real = double; + + auto config = HeatmapSolver::Parameters::makeInputConfig(); + + TNL::Config::ParameterContainer parameters; + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + parameters.addParameter("outputData", true); + + auto device = parameters.getParameter("device"); + auto params = HeatmapSolver::Parameters(parameters); + + HeatmapSolver solver; + + if (device == "host" && !solver.template solve(params)) + return EXIT_FAILURE; + +#ifdef HAVE_CUDA + if (device == "cuda" && !solver.template solve(params)) + return EXIT_FAILURE; +#endif + + return EXIT_SUCCESS; +} diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..58c97ef0d44b742043c4005d632847dd547c15ee --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY( benchmark ) +ADD_SUBDIRECTORY( solution ) diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f8f5f4e5f14a0c5b15dab357f1324390b6fd2017 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_tnl_grid_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cu ) +ELSE() + add_executable( heat_tnl_grid_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.h new file mode 100644 index 0000000000000000000000000000000000000000..64defc7d172ae4f2864ec73d4716dbe863b0db54 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/benchmark/main.h @@ -0,0 +1,5 @@ +#include "../../Base/HeatmapSolver.h" +#include "../../Base/HeatmapSolverBenchmark.h" +#include "../implementation.h" + +#pragma once diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/implementation.h b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/implementation.h new file mode 100644 index 0000000000000000000000000000000000000000..121a48c213d1aa6a609359bafea79e75d7095695 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/implementation.h @@ -0,0 +1,75 @@ +#pragma once + +#include "TNL/Meshes/Grid.h" +#include "../Base/HeatmapSolver.h" + +template +template +bool HeatmapSolver::solve(const HeatmapSolver::Parameters& params) const { + using Grid2D = TNL::Meshes::Grid<2, Real, Device, int>; + + Grid2D grid; + + // Grid implementation defines its dimensions in the amount of edges. + // To align it size to all other benchmarks substract 1 + grid.setDimensions(params.xSize - 1, params.ySize - 1); + + // TODO: - Improve style of access. It is counterintuitive for person, who doesn't know C++ well + auto verticesCount = grid.template getEntitiesCount<0>(); + + TNL::Containers::Array ux(verticesCount), // data at step u + aux(verticesCount);// data at step u + 1 + + // Invalidate ux/aux + ux = 0; + aux = 0; + + const Real hx = params.xDomainSize / (Real)params.xSize; + const Real hy = params.yDomainSize / (Real)params.ySize; + const Real hx_inv = 1. / (hx * hx); + const Real hy_inv = 1. / (hy * hy); + + auto timestep = params.timeStep ? params.timeStep : std::min(hx * hx, hy * hy); + + auto uxView = ux.getView(), + auxView = aux.getView(); + + auto xDomainSize = params.xDomainSize; + auto yDomainSize = params.yDomainSize; + auto sigma = params.sigma; + + auto init = [=] __cuda_callable__(const typename Grid2D::EntityType<0> &entity) mutable { + auto index = entity.getIndex(); + + auto x = entity.getCoordinates().x() * hx - xDomainSize / 2.; + auto y = entity.getCoordinates().y() * hy - yDomainSize / 2.; + + uxView[index] = exp(sigma * (x * x + y * y)); + }; + + grid.template forInterior<0>(init); + + if (!writeGNUPlot("data.txt", params, ux)) + return false; + + auto width = grid.getDimensions().x() + 1; + auto next = [=] __cuda_callable__(const typename Grid2D::EntityType<0>&entity) mutable { + auto index = entity.getIndex(); + auto center = 2 * uxView[index]; + + auxView[index] = ((uxView[index - 1] - center + uxView[index + 1]) * hx_inv + + (uxView[index - width] - center + uxView[index + width]) * hy_inv) * timestep; + }; + + Real start = 0; + + while (start < params.finalTime) { + grid.template forInterior<0>(next); + + auxView.swap(uxView); + + start += timestep; + } + + return writeGNUPlot("data_final.txt", params, ux); +} diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d5efbfc814d5f52a9f79adceef709cedeb677b00 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_tnl_grid ../implementation.h ../../Base/HeatmapSolver.h main.h main.cu ) +ELSE() + add_executable( heat_tnl_grid ../implementation.h ../../Base/HeatmapSolver.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.h new file mode 100644 index 0000000000000000000000000000000000000000..6d888d753a03c071b54f0e86b947708564b2ed5e --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGrid/solution/main.h @@ -0,0 +1,37 @@ + +#include +#include +#include +#include +#include +#include + +#include "../../Base/HeatmapSolver.h" +#include "../implementation.h" + +int main(int argc, char *argv[]) { + using Real = double; + + auto config = HeatmapSolver::Parameters::makeInputConfig(); + + TNL::Config::ParameterContainer parameters; + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + parameters.addParameter("outputData", true); + + auto device = parameters.getParameter("device"); + auto params = HeatmapSolver::Parameters(parameters); + + HeatmapSolver solver; + + if (device == "host" && !solver.solve(params)) + return EXIT_FAILURE; + +#ifdef HAVE_CUDA + if (device == "cuda" && !solver.solve(params)) + return EXIT_FAILURE; +#endif + + return EXIT_SUCCESS; +} diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..58c97ef0d44b742043c4005d632847dd547c15ee --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY( benchmark ) +ADD_SUBDIRECTORY( solution ) diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d7f695bc71309739b018a74e4a1f50654ffed883 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_parallel_for_with_memory_load_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cu ) +ELSE() + add_executable( heat_parallel_for_with_memory_load_benchmark ../implementation.h ../../Base/HeatmapSolver.h ../../Base/HeatmapSolverBenchmark.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.h new file mode 100644 index 0000000000000000000000000000000000000000..64defc7d172ae4f2864ec73d4716dbe863b0db54 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/benchmark/main.h @@ -0,0 +1,5 @@ +#include "../../Base/HeatmapSolver.h" +#include "../../Base/HeatmapSolverBenchmark.h" +#include "../implementation.h" + +#pragma once diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/implementation.h b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/implementation.h new file mode 100644 index 0000000000000000000000000000000000000000..87e87bd2c36707a30dc8bf9f3eb2b4eef317aaa9 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/implementation.h @@ -0,0 +1,144 @@ + +#include +#include +#include + +#include "../Base/HeatmapSolver.h" + +#pragma once + +template +class Entity; + +template +constexpr size_t pow() { + size_t result = 1; + + for (size_t i = 0; i < Power; i++) { + result *= Value; + } + + return result; +} + +constexpr int spaceStepsPowers = 5; + +template +class Grid { + public: + __cuda_callable__ inline + Entity getEntity(Index i, Index j) const { + Entity entity(*this); + + entity.i = i; + entity.j = j; + + return entity; + } + + TNL::Containers::StaticVector dimensions; + TNL::Containers::StaticVector<1 << Size, Index> entitiesCountAlongBases; + TNL::Containers::StaticVector cumulativeEntitiesCountAlongBases; + + TNL::Containers::StaticVector origin, proportions, spaceSteps; + + TNL::Containers::StaticVector()>::value, Real> spaceProducts; +}; + +template +class Entity { + public: + __cuda_callable__ inline + Entity(const Grid& grid): grid(grid) {}; + + const Grid& grid; + + Index i, j; + Index index; + Index orientation; + TNL::Containers::StaticVector coordinates, basis; +}; + +/*** + * Grid parameters: + * + * ySize-1|j (ySize - 1) * xSize + xSize - 1 + * |------------------------------------------------------ + * | + * | + * | + * | + * | + * | + * | + * | + * | + * |------------------------------------------------------> + * + * 0 xSize-1|i + * + * j * xSize + i + ***/ +template +template +bool HeatmapSolver::solve(const HeatmapSolver::Parameters ¶ms) const { + TNL::Containers::Array ux(params.xSize * params.ySize), // data at step u + aux(params.xSize * params.ySize); // data at step u + 1 + + // Invalidate ux/aux + ux = 0; + aux = 0; + + const Real hx = params.xDomainSize / (Real)params.xSize; + const Real hy = params.yDomainSize / (Real)params.ySize; + const Real hx_inv = 1. / (hx * hx); + const Real hy_inv = 1. / (hy * hy); + + auto timestep = params.timeStep ? params.timeStep : std::min(hx * hx, hy * hy); + + auto uxView = ux.getView(), auxView = aux.getView(); + + auto xSize = params.xSize; + auto xDomainSize = params.xDomainSize; + auto yDomainSize = params.yDomainSize; + auto sigma = params.sigma; + + Grid<2, int, Real> grid; + + auto init = [=] __cuda_callable__(int i, int j) mutable { + auto entity = grid.getEntity(i, j); + + auto index = entity.j * xSize + entity.i; + + auto x = entity.i * hx - xDomainSize / 2.; + auto y = entity.j * hy - yDomainSize / 2.; + + uxView[index] = exp(sigma * (x * x + y * y)); + }; + + TNL::Algorithms::ParallelFor2D::exec(1, 1, params.xSize - 1, params.ySize - 1, init); + + if (!writeGNUPlot("data.txt", params, ux)) return false; + + auto next = [=] __cuda_callable__(int i, int j) mutable { + auto entity = grid.getEntity(i, j); + + auto index = entity.j * xSize + entity.i; + auto center = 2 * uxView[index]; + + auxView[index] = ((uxView[index - 1] - center + uxView[index + 1]) * hx_inv + + (uxView[index - xSize] - center + uxView[index + xSize]) * hy_inv) * timestep; + }; + + Real start = 0; + + while (start < params.finalTime) { + TNL::Algorithms::ParallelFor2D::exec(1, 1, params.xSize - 1, params.ySize - 1, next); + + auxView.swap(uxView); + + start += timestep; + } + + return writeGNUPlot("data_final.txt", params, ux); +} diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/CMakeLists.txt b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1ebdec4d60838706643e03f45320bbc590bef63a --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/CMakeLists.txt @@ -0,0 +1,5 @@ +if (BUILD_CUDA) + CUDA_ADD_EXECUTABLE( heat_parallel_for_with_memory_load ../implementation.h ../../Base/HeatmapSolver.h main.h main.cu ) +ELSE() + add_executable( heat_parallel_for_with_memory_load ../implementation.h ../../Base/HeatmapSolver.h main.h main.cpp ) +ENDIF() diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.cpp b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.cpp @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.cu b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.cu new file mode 100644 index 0000000000000000000000000000000000000000..7a7a28956b887a99bcb3c646b18d0bef52c9d320 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.cu @@ -0,0 +1,2 @@ + +#include "main.h" diff --git a/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.h b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.h new file mode 100644 index 0000000000000000000000000000000000000000..31c5ded3a8d6f14e47dc63b53c7a3e1380a87400 --- /dev/null +++ b/src/Benchmarks/HeatEquationGrid/HeatmapTNLGridWithMemoryLoad/solution/main.h @@ -0,0 +1,37 @@ + +#include +#include +#include +#include +#include +#include + +#include "../../Base/HeatmapSolver.h" +#include "../implementation.h" + +int main(int argc, char *argv[]) { + using Real = double; + + auto config = HeatmapSolver::Parameters::makeInputConfig(); + + TNL::Config::ParameterContainer parameters; + if (!parseCommandLine(argc, argv, config, parameters)) + return EXIT_FAILURE; + + parameters.addParameter("outputData", true); + + auto device = parameters.getParameter("device"); + auto params = HeatmapSolver::Parameters(parameters); + + HeatmapSolver solver; + + if (device == "host" && !solver.template solve(params)) + return EXIT_FAILURE; + +#ifdef HAVE_CUDA + if (device == "cuda" && !solver.template solve(params)) + return EXIT_FAILURE; +#endif + + return EXIT_SUCCESS; +} diff --git a/src/Python/pytnl/tnl/Grid.h b/src/Python/pytnl/tnl/Grid.h index c0b7c89c06f39d8784b172e0f5a41a0d85ec085a..c9643cb13e431b7eb55e2820e8ce96f58e36d108 100644 --- a/src/Python/pytnl/tnl/Grid.h +++ b/src/Python/pytnl/tnl/Grid.h @@ -20,8 +20,7 @@ void export_GridEntity( PyGrid & scope, const char* name ) py::return_value_policy::reference_internal ) .def( py::init< typename GridEntity::GridType, typename GridEntity::CoordinatesType, - typename GridEntity::EntityOrientationType, - typename GridEntity::EntityBasisType >(), + typename GridEntity::EntityOrientationType >(), py::return_value_policy::reference_internal ) .def("getEntityDimension", &GridEntity::getEntityDimension) .def("getMeshDimension", &GridEntity::getMeshDimension) @@ -34,9 +33,6 @@ void export_GridEntity( PyGrid & scope, const char* name ) // FIXME: some templates return reference, others value // .def("getOrientation", &GridEntity::getOrientation, py::return_internal_reference<>(), py::return_value_policy()) .def("setOrientation", &GridEntity::setOrientation) - // FIXME: some templates return reference, others value -// .def("getBasis", &GridEntity::getBasis, py::return_internal_reference<>(), py::return_value_policy()) - .def("setBasis", &GridEntity::setBasis) // TODO: getNeighbourEntities .def("isBoundaryEntity", &GridEntity::isBoundaryEntity) .def("getCenter", &GridEntity::getCenter) diff --git a/src/TNL/Algorithms/reduce.h b/src/TNL/Algorithms/reduce.h index 95beb098f85a27037d25956717c52af3b3987d34..67056343764c9eff901f4e446dc47e043e83b3fe 100644 --- a/src/TNL/Algorithms/reduce.h +++ b/src/TNL/Algorithms/reduce.h @@ -16,7 +16,6 @@ namespace TNL { namespace Algorithms { - /** * \brief \e reduce implements [(parallel) reduction](https://en.wikipedia.org/wiki/Reduce_(parallel_pattern)) * for vectors and arrays. diff --git a/src/TNL/Containers/StaticArray.h b/src/TNL/Containers/StaticArray.h index 50c11b34248618e65189b9ec2e70c46ba4fcf948..26a89c3918574517d31f29ae5c0165de631b7405 100644 --- a/src/TNL/Containers/StaticArray.h +++ b/src/TNL/Containers/StaticArray.h @@ -62,7 +62,7 @@ public: * \param v Reference to a value. */ __cuda_callable__ - StaticArray( const Value& v ); + constexpr StaticArray( const Value& v ); /** * \brief Copy constructor. @@ -90,7 +90,7 @@ public: * \param v2 Value of the second array component. */ __cuda_callable__ - StaticArray( const Value& v1, const Value& v2 ); + constexpr StaticArray( const Value& v1, const Value& v2 ); /** * \brief Constructor that sets components of arrays with Size = 3. @@ -100,7 +100,18 @@ public: * \param v3 Value of the third array component. */ __cuda_callable__ - StaticArray( const Value& v1, const Value& v2, const Value& v3 ); + constexpr StaticArray( const Value& v1, const Value& v2, const Value& v3 ); + + /** + * \brief Constructor that sets components of arrays with Size = 4. + * + * \param v1 Value of the first array component. + * \param v2 Value of the second array component. + * \param v3 Value of the third array component. + * \param v4 Value of the forth array component. + */ + __cuda_callable__ + constexpr StaticArray( const Value& v1, const Value& v2, const Value& v3, const Value& v4 ); /** * \brief Gets pointer to data of this static array. @@ -122,7 +133,7 @@ public: * \param i Index position of an element. */ __cuda_callable__ - const Value& + constexpr const Value& operator[]( int i ) const; /** @@ -131,7 +142,7 @@ public: * \param i Index position of an element. */ __cuda_callable__ - Value& + constexpr Value& operator[]( int i ); /** @@ -140,7 +151,7 @@ public: * Equivalent to \ref operator[]. */ __cuda_callable__ - const Value& + constexpr const Value& operator()( int i ) const; /** @@ -149,50 +160,50 @@ public: * Equivalent to \ref operator[]. */ __cuda_callable__ - Value& + constexpr Value& operator()( int i ); /** * \brief Returns reference to the first coordinate. */ __cuda_callable__ - Value& - x(); + constexpr + Value& x(); /** * \brief Returns constant reference to the first coordinate. */ __cuda_callable__ - const Value& - x() const; + constexpr const + Value& x() const; /** * \brief Returns reference to the second coordinate for arrays with Size >= 2. */ __cuda_callable__ - Value& - y(); + constexpr + Value& y(); /** * \brief Returns constant reference to the second coordinate for arrays with Size >= 2. */ __cuda_callable__ - const Value& - y() const; + constexpr const + Value& y() const; /** * \brief Returns reference to the third coordinate for arrays with Size >= 3. */ __cuda_callable__ - Value& - z(); + constexpr + Value& z(); /** * \brief Returns constant reference to the third coordinate for arrays with Size >= 3. */ __cuda_callable__ - const Value& - z() const; + constexpr const + Value& z() const; /** * \brief Assigns another static \e array to this array. @@ -223,7 +234,7 @@ public: */ template< typename Array > __cuda_callable__ - bool + constexpr bool operator==( const Array& array ) const; /** @@ -233,7 +244,7 @@ public: */ template< typename Array > __cuda_callable__ - bool + constexpr bool operator!=( const Array& array ) const; /** diff --git a/src/TNL/Containers/StaticArray.hpp b/src/TNL/Containers/StaticArray.hpp index 683346812581fe64fd030b9430883498d27753c8..d93d1cc2017c65b8d514026e4ac304d449b4c41d 100644 --- a/src/TNL/Containers/StaticArray.hpp +++ b/src/TNL/Containers/StaticArray.hpp @@ -107,7 +107,7 @@ StaticArray< Size, Value >::StaticArray( const Value v[ Size ] ) template< int Size, typename Value > __cuda_callable__ -StaticArray< Size, Value >::StaticArray( const Value& v ) +constexpr StaticArray< Size, Value >::StaticArray( const Value& v ) { Algorithms::unrolledFor< int, 0, Size >( [ & ]( int i ) mutable @@ -137,8 +137,8 @@ StaticArray< Size, Value >::StaticArray( const std::initializer_list< Value >& e } template< int Size, typename Value > -__cuda_callable__ -StaticArray< Size, Value >::StaticArray( const Value& v1, const Value& v2 ) + __cuda_callable__ +constexpr StaticArray< Size, Value >::StaticArray( const Value& v1, const Value& v2 ) { static_assert( Size == 2, "This constructor can be called only for arrays with Size = 2." ); data[ 0 ] = v1; @@ -146,8 +146,8 @@ StaticArray< Size, Value >::StaticArray( const Value& v1, const Value& v2 ) } template< int Size, typename Value > -__cuda_callable__ -StaticArray< Size, Value >::StaticArray( const Value& v1, const Value& v2, const Value& v3 ) + __cuda_callable__ +constexpr StaticArray< Size, Value >::StaticArray( const Value& v1, const Value& v2, const Value& v3 ) { static_assert( Size == 3, "This constructor can be called only for arrays with Size = 3." ); data[ 0 ] = v1; @@ -155,6 +155,17 @@ StaticArray< Size, Value >::StaticArray( const Value& v1, const Value& v2, const data[ 2 ] = v3; } +template< int Size, typename Value > + __cuda_callable__ +constexpr StaticArray< Size, Value >::StaticArray( const Value& v1, const Value& v2, const Value& v3, const Value& v4 ) +{ + static_assert( Size == 4, "This constructor can be called only for arrays with Size = 4." ); + data[ 0 ] = v1; + data[ 1 ] = v2; + data[ 2 ] = v3; + data[ 3 ] = v4; +} + template< int Size, typename Value > __cuda_callable__ Value* @@ -173,8 +184,7 @@ StaticArray< Size, Value >::getData() const template< int Size, typename Value > __cuda_callable__ -const Value& -StaticArray< Size, Value >::operator[]( int i ) const +constexpr const Value& StaticArray< Size, Value >::operator[]( int i ) const { TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); TNL_ASSERT_LT( i, Size, "Element index is out of bounds." ); @@ -183,8 +193,7 @@ StaticArray< Size, Value >::operator[]( int i ) const template< int Size, typename Value > __cuda_callable__ -Value& -StaticArray< Size, Value >::operator[]( int i ) +constexpr Value& StaticArray< Size, Value >::operator[]( int i ) { TNL_ASSERT_GE( i, 0, "Element index must be non-negative." ); TNL_ASSERT_LT( i, Size, "Element index is out of bounds." ); @@ -193,40 +202,35 @@ StaticArray< Size, Value >::operator[]( int i ) template< int Size, typename Value > __cuda_callable__ -const Value& -StaticArray< Size, Value >::operator()( int i ) const +constexpr const Value& StaticArray< Size, Value >::operator()( int i ) const { return operator[]( i ); } template< int Size, typename Value > __cuda_callable__ -Value& -StaticArray< Size, Value >::operator()( int i ) +constexpr Value& StaticArray< Size, Value >::operator()( int i ) { return operator[]( i ); } template< int Size, typename Value > __cuda_callable__ -Value& -StaticArray< Size, Value >::x() +constexpr Value& StaticArray< Size, Value >::x() { return data[ 0 ]; } template< int Size, typename Value > __cuda_callable__ -const Value& -StaticArray< Size, Value >::x() const +constexpr const Value& StaticArray< Size, Value >::x() const { return data[ 0 ]; } template< int Size, typename Value > __cuda_callable__ -Value& -StaticArray< Size, Value >::y() +constexpr Value& StaticArray< Size, Value >::y() { static_assert( Size > 1, "Cannot call StaticArray< Size, Value >::y() for arrays with Size < 2." ); return data[ 1 ]; @@ -234,8 +238,7 @@ StaticArray< Size, Value >::y() template< int Size, typename Value > __cuda_callable__ -const Value& -StaticArray< Size, Value >::y() const +constexpr const Value& StaticArray< Size, Value >::y() const { static_assert( Size > 1, "Cannot call StaticArray< Size, Value >::y() for arrays with Size < 2." ); return data[ 1 ]; @@ -243,8 +246,7 @@ StaticArray< Size, Value >::y() const template< int Size, typename Value > __cuda_callable__ -Value& -StaticArray< Size, Value >::z() +constexpr Value& StaticArray< Size, Value >::z() { static_assert( Size > 1, "Cannot call StaticArray< Size, Value >::z() for arrays with Size < 3." ); return data[ 2 ]; @@ -252,8 +254,7 @@ StaticArray< Size, Value >::z() template< int Size, typename Value > __cuda_callable__ -const Value& -StaticArray< Size, Value >::z() const +constexpr const Value& StaticArray< Size, Value >::z() const { static_assert( Size > 1, "Cannot call StaticArray< Size, Value >::z() for arrays with Size < 3." ); return data[ 2 ]; @@ -285,8 +286,7 @@ StaticArray< Size, Value >::operator=( const T& v ) template< int Size, typename Value > template< typename Array > __cuda_callable__ -bool -StaticArray< Size, Value >::operator==( const Array& array ) const +constexpr bool StaticArray< Size, Value >::operator==( const Array& array ) const { return detail::StaticArrayComparator< Size, Value, typename Array::ValueType, 0 >::EQ( *this, array ); } @@ -294,8 +294,7 @@ StaticArray< Size, Value >::operator==( const Array& array ) const template< int Size, typename Value > template< typename Array > __cuda_callable__ -bool -StaticArray< Size, Value >::operator!=( const Array& array ) const +constexpr bool StaticArray< Size, Value >::operator!=( const Array& array ) const { return ! this->operator==( array ); } diff --git a/src/TNL/Meshes/Grid.h b/src/TNL/Meshes/Grid.h index 4ad322f308f23c769d229cf2323e22a001d7f032..ffef20e4b2b90df75d0c97fff83f89c2a5a8e5b5 100644 --- a/src/TNL/Meshes/Grid.h +++ b/src/TNL/Meshes/Grid.h @@ -6,42 +6,29 @@ #pragma once -#include +#include namespace TNL { namespace Meshes { -template< int Dimension, typename Real = double, typename Device = Devices::Host, typename Index = int > -class Grid; - -template< int Dimension, typename Real, typename Device, typename Index > -bool -operator==( const Grid< Dimension, Real, Device, Index >& lhs, const Grid< Dimension, Real, Device, Index >& rhs ) -{ - return lhs.getDimensions() == rhs.getDimensions() && lhs.getOrigin() == rhs.getOrigin() - && lhs.getProportions() == rhs.getProportions(); -} - -template< int Dimension, typename Real, typename Device, typename Index > -bool -operator!=( const Grid< Dimension, Real, Device, Index >& lhs, const Grid< Dimension, Real, Device, Index >& rhs ) -{ - return ! ( lhs == rhs ); -} - -template< int Dimension, typename Real, typename Device, typename Index > -std::ostream& -operator<<( std::ostream& str, const Grid< Dimension, Real, Device, Index >& grid ) -{ - str << "Grid dimensions: " << grid.getDimensions() << std::endl; - str << " origin: " << grid.getOrigin() << std::endl; - str << " proportions: " << grid.getProportions() << std::endl; - str << " localBegin: " << grid.getLocalBegin() << std::endl; - str << " localEnd: " << grid.getLocalEnd() << std::endl; - str << " interiorBegin: " << grid.getInteriorBegin() << std::endl; - str << " interiorEnd: " << grid.getInteriorEnd() << std::endl; - return str; -} +template +class Grid: public NDimGrid {}; + +// template< int Dimension, typename Real, typename Device, typename Index > +// bool operator==( const Grid< Dimension, Real, Device, Index >& lhs, +// const Grid< Dimension, Real, Device, Index >& rhs ) +// { +// return lhs.getDimensions() == rhs.getDimensions() +// && lhs.getOrigin() == rhs.getOrigin() +// && lhs.getProportions() == rhs.getProportions(); +// } + +// template< int Dimension, typename Real, typename Device, typename Index > +// bool operator!=( const Grid< Dimension, Real, Device, Index >& lhs, +// const Grid< Dimension, Real, Device, Index >& rhs ) +// { +// return ! (lhs == rhs); +// } } // namespace Meshes } // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/BasisGetter.h b/src/TNL/Meshes/GridDetails/BasisGetter.h new file mode 100644 index 0000000000000000000000000000000000000000..54aa3aad7284d52e48fd65948a53852e51419ca5 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/BasisGetter.h @@ -0,0 +1,42 @@ + +#pragma once + +#include +#include +#include + +namespace TNL { +namespace Meshes { + +template +struct BasisGetter { + public: + using Coordinate = TNL::Containers::StaticVector; + using OrientationBasesContainer = TNL::Containers::StaticVector; + using Permutations = Templates::make_int_permutations< + GridDimension, + Templates::build_ones_pack + >; + + template = true> + constexpr static Coordinate getBasis() { + using Value = Templates::get; + + return BuildBasis::build(); + } + private: + template + struct BuildBasis; + + template + struct BuildBasis> { + public: + constexpr static Coordinate build() { return Coordinate(Values...); } + }; +}; + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/BoundaryGridEntityChecker.h b/src/TNL/Meshes/GridDetails/BoundaryGridEntityChecker.h index 6a4d798b23cf985e5249d9fde1ed3fa6d707b8bb..cdaecfee113bdab7915cfa8ecb5d2ee65ff5afc0 100644 --- a/src/TNL/Meshes/GridDetails/BoundaryGridEntityChecker.h +++ b/src/TNL/Meshes/GridDetails/BoundaryGridEntityChecker.h @@ -9,186 +9,13 @@ namespace TNL { namespace Meshes { -template< typename GridEntity > -class BoundaryGridEntityChecker -{}; +template +class GridEntity; -/*** - * 1D grids - */ -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config > > -{ -public: - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 1, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config > > -{ -public: - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 0, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() ); - } -}; - -/**** - * 2D grids - */ -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 2, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( entity.getCoordinates().x() == 0 || entity.getCoordinates().y() == 0 - || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 - || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 1, Config > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 1, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( - ( entity.getOrientation().x() - && ( entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() ) ) - || ( entity.getOrientation().y() - && ( entity.getCoordinates().y() == 0 - || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() ) ) ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 0, Config > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 0, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( entity.getCoordinates().x() == 0 || entity.getCoordinates().y() == 0 - || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() ); - } -}; - -/*** - * 3D grid - */ -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 3, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( entity.getCoordinates().x() == 0 || entity.getCoordinates().y() == 0 || entity.getCoordinates().z() == 0 - || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 - || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 - || entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 2, Config > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 2, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( - ( entity.getOrientation().x() - && ( entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() ) ) - || ( entity.getOrientation().y() - && ( entity.getCoordinates().y() == 0 || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() ) ) - || ( entity.getOrientation().z() - && ( entity.getCoordinates().z() == 0 - || entity.getCoordinates().z() == entity.getMesh().getDimensions().z() ) ) ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 1, Config > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 1, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( - ( entity.getOrientation().x() - && ( entity.getCoordinates().y() == 0 || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - || entity.getCoordinates().z() == 0 || entity.getCoordinates().z() == entity.getMesh().getDimensions().z() ) ) - || ( entity.getOrientation().y() - && ( entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - || entity.getCoordinates().z() == 0 - || entity.getCoordinates().z() == entity.getMesh().getDimensions().z() ) ) - || ( entity.getOrientation().z() - && ( entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - || entity.getCoordinates().y() == 0 - || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() ) ) ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class BoundaryGridEntityChecker< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 0, Config > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 0, Config >; - - __cuda_callable__ - inline static bool - isBoundaryEntity( const GridEntityType& entity ) - { - return ( entity.getCoordinates().x() == 0 || entity.getCoordinates().y() == 0 || entity.getCoordinates().z() == 0 - || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - || entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - || entity.getCoordinates().z() == entity.getMesh().getDimensions().z() ); - } -}; +template +class BoundaryGridEntityChecker; } // namespace Meshes } // namespace TNL + +#include diff --git a/src/TNL/Meshes/GridDetails/Grid1D.h b/src/TNL/Meshes/GridDetails/Grid1D.h index cf3bc8337f36ee23b1d56b7a136e3cd9ecf54131..2cbcff8d7b1708bb8278ad84c1450b80f6bc9182 100644 --- a/src/TNL/Meshes/GridDetails/Grid1D.h +++ b/src/TNL/Meshes/GridDetails/Grid1D.h @@ -6,237 +6,81 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include namespace TNL { namespace Meshes { -template< typename Real, typename Device, typename Index > -class Grid< 1, Real, Device, Index > -{ -public: - using RealType = Real; - using DeviceType = Device; - using GlobalIndexType = Index; - using PointType = Containers::StaticVector< 1, Real >; - using CoordinatesType = Containers::StaticVector< 1, Index >; +template +class GridEntity; - // TODO: deprecated and to be removed (GlobalIndexType shall be used instead) - using IndexType = Index; +template +class Grid<1, Real, Device, Index> : public NDimGrid<1, Real, Device, Index> { + public: + template + using EntityType = GridEntity; - /** - * \brief Returns number of this mesh grid dimensions. - */ - static constexpr int - getMeshDimension() - { - return 1; - }; - - template< int EntityDimension, typename Config = GridEntityCrossStencilStorage< 1 > > - using EntityType = GridEntity< Grid, EntityDimension, Config >; - - using Cell = EntityType< getMeshDimension(), GridEntityCrossStencilStorage< 1 > >; - using Face = EntityType< 0 >; - using Vertex = EntityType< 0 >; - - /** - * \brief Basic constructor. - */ - Grid() = default; - - Grid( Index xSize ); - - // empty destructor is needed only to avoid crappy nvcc warnings - ~Grid() = default; - - /** - * \brief Sets the size of dimensions. - * \param xSize Size of dimesion x. - */ - void - setDimensions( Index xSize ); - - /** - * \brief Sets the number of dimensions. - * \param dimensions Number of dimensions. - */ - void - setDimensions( const CoordinatesType& dimensions ); - - __cuda_callable__ - const CoordinatesType& - getDimensions() const; - - void - setLocalBegin( const CoordinatesType& begin ); - - __cuda_callable__ - const CoordinatesType& - getLocalBegin() const; - - void - setLocalEnd( const CoordinatesType& end ); - - __cuda_callable__ - const CoordinatesType& - getLocalEnd() const; - - void - setInteriorBegin( const CoordinatesType& begin ); - - __cuda_callable__ - const CoordinatesType& - getInteriorBegin() const; - - void - setInteriorEnd( const CoordinatesType& end ); - - __cuda_callable__ - const CoordinatesType& - getInteriorEnd() const; - - /** - * \brief Sets the origin. - * \param origin Starting point of this grid. - */ - void - setOrigin( const PointType& origin ); + using Base = NDimGrid<1, Real, Device, Index>; + using Coordinate = typename Base::Coordinate; + using Point = typename Base::Point; + using EntitiesCounts = typename Base::EntitiesCounts; - /** - * \brief Sets the origin and proportions of this grid. - * \param origin Point where this grid starts. - * \param proportions Total length of this grid. - */ - void - setDomain( const PointType& origin, const PointType& proportions ); + Grid(); - /** - * \brief Returns the origin. - * \param origin Starting point of this grid. - */ - __cuda_callable__ - inline const PointType& - getOrigin() const; - - /** - * \brief Gets length of one entity of this grid. - */ - __cuda_callable__ - inline const PointType& - getProportions() const; - - /** - * \brief Gets number of entities in this grid. - * \tparam EntityDimension Integer specifying dimension of the entity. - */ - template< int EntityDimension > - __cuda_callable__ - IndexType - getEntitiesCount() const; - - /** - * \brief Gets number of entities in this grid. - * \tparam Entity Type of the entity. - */ - template< typename Entity > - __cuda_callable__ - IndexType - getEntitiesCount() const; + Grid(const Index xSize); /** - * \brief Gets entity type using entity index. - * \param entityIndex Index of entity. + * @brief Gets entity index using entity type. + * \param entity Type of entity. * \tparam Entity Type of the entity. */ - template< typename Entity > - __cuda_callable__ - inline Entity - getEntity( const IndexType& entityIndex ) const; + template + __cuda_callable__ inline Index getEntityIndex(const Entity& entity) const; /** - * \brief Gets entity index using entity type. - * \param entity Type of entity. - * \tparam Entity Type of the entity. + * @brief Traverser all elements in rect */ - template< typename Entity > - __cuda_callable__ - inline Index - getEntityIndex( const Entity& entity ) const; + template + inline void forAll(Func func, FuncArgs... args) const; /** - * \brief Returns the length of one step. + * @brief Traverser all elements in rect + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - __cuda_callable__ - inline const PointType& - getSpaceSteps() const; + template + inline void forAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; /** - * \brief Sets the length of steps. - * \param steps Length of one step. + * @brief Traverser interior elements in rect */ - inline void - setSpaceSteps( const PointType& steps ); + template + inline void forInterior(Func func, FuncArgs... args) const; /** - * \brief Returns product of space steps to the xPow. - * \tparam xPow Exponent. + * @brief Traverser interior elements + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - template< int xPow > - __cuda_callable__ - const RealType& - getSpaceStepsProducts() const; + template + inline void forInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; /** - * \breif Returns the measure (length) of a cell in this grid. + * @brief Traverser boundary elements in rect */ - __cuda_callable__ - inline const RealType& - getCellMeasure() const; + template + inline void forBoundary(Func func, FuncArgs... args) const; /** - * \brief Returns the smallest length of step out of all coordinates (axes). + * @brief Traverser boundary elements in rect + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - __cuda_callable__ - inline RealType - getSmallestSpaceStep() const; - - void - writeProlog( Logger& logger ) const; - -protected: - void - computeProportions(); - - void - computeSpaceStepPowers(); - - void - computeSpaceSteps(); - - CoordinatesType dimensions = { 0 }; - CoordinatesType localBegin = { 0 }; - CoordinatesType localEnd = { 0 }; - CoordinatesType interiorBegin = { 0 }; - CoordinatesType interiorEnd = { 0 }; - - IndexType numberOfCells = 0; - IndexType numberOfVertices = 0; - - PointType origin = { 0 }; - PointType proportions = { 0 }; - PointType spaceSteps = { 0 }; - - RealType spaceStepsProducts[ 5 ]; + template + inline void forBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; }; } // namespace Meshes } // namespace TNL -#include +#include diff --git a/src/TNL/Meshes/GridDetails/Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Grid1D_impl.h deleted file mode 100644 index 7deb52e22b8ce8e5c350b747b2bead7ddb19c161..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Grid1D_impl.h +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename Real, typename Device, typename Index > -Grid< 1, Real, Device, Index >::Grid( Index xSize ) -{ - this->setDimensions( xSize ); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::computeSpaceSteps() -{ - if( this->getDimensions().x() != 0 ) { - this->spaceSteps.x() = this->proportions.x() / (Real) this->getDimensions().x(); - this->computeSpaceStepPowers(); - } -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::computeSpaceStepPowers() -{ - const RealType& hx = this->spaceSteps.x(); - this->spaceStepsProducts[ 0 ] = 1.0 / ( hx * hx ); - this->spaceStepsProducts[ 1 ] = 1.0 / hx; - this->spaceStepsProducts[ 2 ] = 1.0; - this->spaceStepsProducts[ 3 ] = hx; - this->spaceStepsProducts[ 4 ] = hx * hx; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::computeProportions() -{ - this->proportions.x() = this->dimensions.x() * this->spaceSteps.x(); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setOrigin( const PointType& origin ) -{ - this->origin = origin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setDimensions( Index xSize ) -{ - TNL_ASSERT_GE( xSize, 0, "Grid size must be non-negative." ); - this->dimensions.x() = xSize; - this->numberOfCells = xSize; - this->numberOfVertices = xSize + 1; - computeSpaceSteps(); - - // only default behaviour, DistributedGrid must use the setters explicitly after setDimensions - localBegin = 0; - interiorBegin = 1; - localEnd = dimensions; - interiorEnd = dimensions - 1; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setDimensions( const CoordinatesType& dimensions ) -{ - this->setDimensions( dimensions.x() ); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 1, Real, Device, Index >::CoordinatesType& -Grid< 1, Real, Device, Index >::getDimensions() const -{ - return this->dimensions; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setLocalBegin( const CoordinatesType& begin ) -{ - localBegin = begin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 1, Real, Device, Index >::CoordinatesType& -Grid< 1, Real, Device, Index >::getLocalBegin() const -{ - return localBegin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setLocalEnd( const CoordinatesType& end ) -{ - localEnd = end; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 1, Real, Device, Index >::CoordinatesType& -Grid< 1, Real, Device, Index >::getLocalEnd() const -{ - return localEnd; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setInteriorBegin( const CoordinatesType& begin ) -{ - interiorBegin = begin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 1, Real, Device, Index >::CoordinatesType& -Grid< 1, Real, Device, Index >::getInteriorBegin() const -{ - return interiorBegin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setInteriorEnd( const CoordinatesType& end ) -{ - interiorEnd = end; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 1, Real, Device, Index >::CoordinatesType& -Grid< 1, Real, Device, Index >::getInteriorEnd() const -{ - return interiorEnd; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::setDomain( const PointType& origin, const PointType& proportions ) -{ - this->origin = origin; - this->proportions = proportions; - computeSpaceSteps(); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 1, Real, Device, Index >::PointType& -Grid< 1, Real, Device, Index >::getOrigin() const -{ - return this->origin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 1, Real, Device, Index >::PointType& -Grid< 1, Real, Device, Index >::getProportions() const -{ - return this->proportions; -} - -template< typename Real, typename Device, typename Index > -template< int EntityDimension > -__cuda_callable__ -inline Index -Grid< 1, Real, Device, Index >::getEntitiesCount() const -{ - static_assert( EntityDimension <= 1 && EntityDimension >= 0, "Wrong grid entity dimensions." ); - - switch( EntityDimension ) { - case 1: - return this->numberOfCells; - case 0: - return this->numberOfVertices; - } - return -1; -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Index -Grid< 1, Real, Device, Index >::getEntitiesCount() const -{ - return getEntitiesCount< Entity::getEntityDimension() >(); -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Entity -Grid< 1, Real, Device, Index >::getEntity( const IndexType& entityIndex ) const -{ - static_assert( Entity::getEntityDimension() <= 1 && Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." ); - - return GridEntityGetter< Grid, Entity >::getEntity( *this, entityIndex ); -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Index -Grid< 1, Real, Device, Index >::getEntityIndex( const Entity& entity ) const -{ - static_assert( Entity::getEntityDimension() <= 1 && Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." ); - - return GridEntityGetter< Grid, Entity >::getEntityIndex( *this, entity ); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 1, Real, Device, Index >::PointType& -Grid< 1, Real, Device, Index >::getSpaceSteps() const -{ - return this->spaceSteps; -} - -template< typename Real, typename Device, typename Index > -inline void -Grid< 1, Real, Device, Index >::setSpaceSteps( const typename Grid< 1, Real, Device, Index >::PointType& steps ) -{ - this->spaceSteps = steps; - computeSpaceStepPowers(); - computeProportions(); -} - -template< typename Real, typename Device, typename Index > -template< int xPow > -__cuda_callable__ -inline const Real& -Grid< 1, Real, Device, Index >::getSpaceStepsProducts() const -{ - static_assert( xPow >= -2 && xPow <= 2, "unsupported value of xPow" ); - return this->spaceStepsProducts[ xPow + 2 ]; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const Real& -Grid< 1, Real, Device, Index >::getCellMeasure() const -{ - return this->template getSpaceStepsProducts< 1 >(); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline Real -Grid< 1, Real, Device, Index >::getSmallestSpaceStep() const -{ - return this->spaceSteps.x(); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 1, Real, Device, Index >::writeProlog( Logger& logger ) const -{ - logger.writeParameter( "Dimension:", getMeshDimension() ); - logger.writeParameter( "Domain origin:", this->origin ); - logger.writeParameter( "Domain proportions:", this->proportions ); - logger.writeParameter( "Domain dimensions:", this->dimensions ); - logger.writeParameter( "Space steps:", this->getSpaceSteps() ); - logger.writeParameter( "Number of cells:", getEntitiesCount< Cell >() ); - logger.writeParameter( "Number of vertices:", getEntitiesCount< Vertex >() ); -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Grid2D.h b/src/TNL/Meshes/GridDetails/Grid2D.h index 17eb80837d582678e4f1f28c90cd2c7a68def34c..d7cdcf0d2a2bbcbd412d478832b8604d49ebc174 100644 --- a/src/TNL/Meshes/GridDetails/Grid2D.h +++ b/src/TNL/Meshes/GridDetails/Grid2D.h @@ -6,244 +6,82 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include namespace TNL { namespace Meshes { -template< typename Real, typename Device, typename Index > -class Grid< 2, Real, Device, Index > -{ -public: - using RealType = Real; - using DeviceType = Device; - using GlobalIndexType = Index; - using PointType = Containers::StaticVector< 2, Real >; - using CoordinatesType = Containers::StaticVector< 2, Index >; +template +class GridEntity; - // TODO: deprecated and to be removed (GlobalIndexType shall be used instead) - using IndexType = Index; +template +class Grid<2, Real, Device, Index> : public NDimGrid<2, Real, Device, Index> { + public: + template + using EntityType = GridEntity; - static constexpr int - getMeshDimension() - { - return 2; - }; - - template< int EntityDimension, typename Config = GridEntityCrossStencilStorage< 1 > > - using EntityType = GridEntity< Grid, EntityDimension, Config >; - - using Cell = EntityType< getMeshDimension(), GridEntityCrossStencilStorage< 1 > >; - using Face = EntityType< getMeshDimension() - 1 >; - using Vertex = EntityType< 0 >; + using Base = NDimGrid<2, Real, Device, Index>; + using Coordinate = typename Base::Coordinate; + using Point = typename Base::Point; + using EntitiesCounts = typename Base::EntitiesCounts; /** * \brief See Grid1D::Grid(). */ Grid() = default; - Grid( Index xSize, Index ySize ); - - // empty destructor is needed only to avoid crappy nvcc warnings - ~Grid() = default; - - /** - * \brief Sets the size of dimensions. - * \param xSize Size of dimension x. - * \param ySize Size of dimension y. - */ - void - setDimensions( Index xSize, Index ySize ); - - /** - * \brief See Grid1D::setDimensions( const CoordinatesType& dimensions ). - */ - void - setDimensions( const CoordinatesType& dimensions ); - - /** - * \brief See Grid1D::getDimensions(). - */ - __cuda_callable__ - const CoordinatesType& - getDimensions() const; - - void - setLocalBegin( const CoordinatesType& begin ); - - __cuda_callable__ - const CoordinatesType& - getLocalBegin() const; - - void - setLocalEnd( const CoordinatesType& end ); - - __cuda_callable__ - const CoordinatesType& - getLocalEnd() const; - - void - setInteriorBegin( const CoordinatesType& begin ); - - __cuda_callable__ - const CoordinatesType& - getInteriorBegin() const; - - void - setInteriorEnd( const CoordinatesType& end ); - - __cuda_callable__ - const CoordinatesType& - getInteriorEnd() const; - - /** - * \brief See Grid1D::setDomain(). - */ - void - setDomain( const PointType& origin, const PointType& proportions ); - - /** - * \brief See Grid1D::setOrigin() - */ - void - setOrigin( const PointType& origin ); - - /** - * \brief See Grid1D::getOrigin(). - */ - __cuda_callable__ - inline const PointType& - getOrigin() const; - - /** - * \brief See Grid1D::getProportions(). - */ - __cuda_callable__ - inline const PointType& - getProportions() const; - - /** - * \brief Gets number of entities in this grid. - * \tparam EntityDimension Integer specifying dimension of the entity. - */ - template< int EntityDimension > - __cuda_callable__ - IndexType - getEntitiesCount() const; - - /** - * \brief Gets number of entities in this grid. - * \tparam Entity Type of the entity. - */ - template< typename Entity > - __cuda_callable__ - inline IndexType - getEntitiesCount() const; - - /** - * \brief See Grid1D::getEntity(). - */ - template< typename Entity > - __cuda_callable__ - inline Entity - getEntity( const IndexType& entityIndex ) const; + Grid(const Index xSize, const Index ySize); /** * \brief See Grid1D::getEntityIndex(). */ - template< typename Entity > - __cuda_callable__ - inline Index - getEntityIndex( const Entity& entity ) const; + template + __cuda_callable__ inline Index getEntityIndex(const Entity& entity) const; /** - * \brief See Grid1D::getSpaceSteps(). + * @brief Traverser all elements in rect */ - __cuda_callable__ - inline const PointType& - getSpaceSteps() const; + template + inline void forAll(Func func, FuncArgs... args) const; /** - * \brief See Grid1D::setSpaceSteps(). + * @brief Traverser all elements in rect + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - inline void - setSpaceSteps( const PointType& steps ); + template + inline void forAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; /** - * \brief Returns product of space steps to the xPow. - * \tparam xPow Exponent for dimension x. - * \tparam yPow Exponent for dimension y. + * @brief Traverser interior elements in rect */ - template< int xPow, int yPow > - __cuda_callable__ - const RealType& - getSpaceStepsProducts() const; + template + inline void forInterior(Func func, FuncArgs... args) const; /** - * \brief Returns the number of x-normal faces. + * @brief Traverser interior elements + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - __cuda_callable__ - IndexType - getNumberOfNxFaces() const; + template + inline void forInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; /** - * \breif Returns the measure (area) of a cell in this grid. + * @brief Traverser boundary elements in rect */ - __cuda_callable__ - inline const RealType& - getCellMeasure() const; + template + inline void forBoundary(Func func, FuncArgs... args) const; /** - * \brief See Grid1D::getSmallestSpaceStep(). + * @brief Traverser boundary elements in rect + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - __cuda_callable__ - inline RealType - getSmallestSpaceStep() const; - - void - writeProlog( Logger& logger ) const; - -protected: - void - computeProportions(); - - __cuda_callable__ - void - computeSpaceStepPowers(); - - __cuda_callable__ - void - computeSpaceSteps(); - - CoordinatesType dimensions = { 0, 0 }; - CoordinatesType localBegin = { 0, 0 }; - CoordinatesType localEnd = { 0, 0 }; - CoordinatesType interiorBegin = { 0, 0 }; - CoordinatesType interiorEnd = { 0, 0 }; - - IndexType numberOfCells = 0; - IndexType numberOfNxFaces = 0; - IndexType numberOfNyFaces = 0; - IndexType numberOfFaces = 0; - IndexType numberOfVertices = 0; - - PointType origin = { 0, 0 }; - PointType proportions = { 0, 0 }; - PointType spaceSteps = { 0, 0 }; - - RealType spaceStepsProducts[ 5 ][ 5 ]; - - template< typename, typename, int > - friend class GridEntityGetter; + template + inline void forBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; }; } // namespace Meshes } // namespace TNL -#include +#include diff --git a/src/TNL/Meshes/GridDetails/Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Grid2D_impl.h deleted file mode 100644 index 91b45bec83dee72f2f519b63af3fb243930e28f6..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Grid2D_impl.h +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename Real, typename Device, typename Index > -Grid< 2, Real, Device, Index >::Grid( Index xSize, Index ySize ) -{ - this->setDimensions( xSize, ySize ); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -void -Grid< 2, Real, Device, Index >::computeSpaceSteps() -{ - if( this->getDimensions().x() > 0 && this->getDimensions().y() > 0 ) { - this->spaceSteps.x() = this->proportions.x() / (Real) this->getDimensions().x(); - this->spaceSteps.y() = this->proportions.y() / (Real) this->getDimensions().y(); - this->computeSpaceStepPowers(); - } -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -void -Grid< 2, Real, Device, Index >::computeSpaceStepPowers() -{ - const RealType& hx = this->spaceSteps.x(); - const RealType& hy = this->spaceSteps.y(); - - Real auxX; - Real auxY; - for( int i = 0; i < 5; i++ ) { - switch( i ) { - case 0: - auxX = 1.0 / ( hx * hx ); - break; - case 1: - auxX = 1.0 / hx; - break; - case 2: - auxX = 1.0; - break; - case 3: - auxX = hx; - break; - case 4: - auxX = hx * hx; - break; - } - for( int j = 0; j < 5; j++ ) { - switch( j ) { - case 0: - auxY = 1.0 / ( hy * hy ); - break; - case 1: - auxY = 1.0 / hy; - break; - case 2: - auxY = 1.0; - break; - case 3: - auxY = hy; - break; - case 4: - auxY = hy * hy; - break; - } - this->spaceStepsProducts[ i ][ j ] = auxX * auxY; - } - } -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::computeProportions() -{ - this->proportions.x() = this->dimensions.x() * this->spaceSteps.x(); - this->proportions.y() = this->dimensions.y() * this->spaceSteps.y(); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setDimensions( Index xSize, Index ySize ) -{ - TNL_ASSERT_GE( xSize, 0, "Grid size must be non-negative." ); - TNL_ASSERT_GE( ySize, 0, "Grid size must be non-negative." ); - - this->dimensions.x() = xSize; - this->dimensions.y() = ySize; - this->numberOfCells = xSize * ySize; - this->numberOfNxFaces = ySize * ( xSize + 1 ); - this->numberOfNyFaces = xSize * ( ySize + 1 ); - this->numberOfFaces = this->numberOfNxFaces + this->numberOfNyFaces; - this->numberOfVertices = ( xSize + 1 ) * ( ySize + 1 ); - computeSpaceSteps(); - - // only default behaviour, DistributedGrid must use the setters explicitly after setDimensions - localBegin = 0; - interiorBegin = 1; - localEnd = dimensions; - interiorEnd = dimensions - 1; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setDimensions( const CoordinatesType& dimensions ) -{ - return this->setDimensions( dimensions.x(), dimensions.y() ); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 2, Real, Device, Index >::CoordinatesType& -Grid< 2, Real, Device, Index >::getDimensions() const -{ - return this->dimensions; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setLocalBegin( const CoordinatesType& begin ) -{ - localBegin = begin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 2, Real, Device, Index >::CoordinatesType& -Grid< 2, Real, Device, Index >::getLocalBegin() const -{ - return localBegin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setLocalEnd( const CoordinatesType& end ) -{ - localEnd = end; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 2, Real, Device, Index >::CoordinatesType& -Grid< 2, Real, Device, Index >::getLocalEnd() const -{ - return localEnd; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setInteriorBegin( const CoordinatesType& begin ) -{ - interiorBegin = begin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 2, Real, Device, Index >::CoordinatesType& -Grid< 2, Real, Device, Index >::getInteriorBegin() const -{ - return interiorBegin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setInteriorEnd( const CoordinatesType& end ) -{ - interiorEnd = end; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 2, Real, Device, Index >::CoordinatesType& -Grid< 2, Real, Device, Index >::getInteriorEnd() const -{ - return interiorEnd; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setDomain( const PointType& origin, const PointType& proportions ) -{ - this->origin = origin; - this->proportions = proportions; - computeSpaceSteps(); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::setOrigin( const PointType& origin ) -{ - this->origin = origin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 2, Real, Device, Index >::PointType& -Grid< 2, Real, Device, Index >::getOrigin() const -{ - return this->origin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 2, Real, Device, Index >::PointType& -Grid< 2, Real, Device, Index >::getProportions() const -{ - return this->proportions; -} - -template< typename Real, typename Device, typename Index > -template< int EntityDimension > -__cuda_callable__ -inline Index -Grid< 2, Real, Device, Index >::getEntitiesCount() const -{ - static_assert( EntityDimension <= 2 && EntityDimension >= 0, "Wrong grid entity dimensions." ); - - switch( EntityDimension ) { - case 2: - return this->numberOfCells; - case 1: - return this->numberOfFaces; - case 0: - return this->numberOfVertices; - } - return -1; -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Index -Grid< 2, Real, Device, Index >::getEntitiesCount() const -{ - return getEntitiesCount< Entity::getEntityDimension() >(); -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Entity -Grid< 2, Real, Device, Index >::getEntity( const IndexType& entityIndex ) const -{ - static_assert( Entity::getEntityDimension() <= 2 && Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." ); - - return GridEntityGetter< Grid, Entity >::getEntity( *this, entityIndex ); -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Index -Grid< 2, Real, Device, Index >::getEntityIndex( const Entity& entity ) const -{ - static_assert( Entity::getEntityDimension() <= 2 && Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." ); - - return GridEntityGetter< Grid, Entity >::getEntityIndex( *this, entity ); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 2, Real, Device, Index >::PointType& -Grid< 2, Real, Device, Index >::getSpaceSteps() const -{ - return this->spaceSteps; -} - -template< typename Real, typename Device, typename Index > -inline void -Grid< 2, Real, Device, Index >::setSpaceSteps( const typename Grid< 2, Real, Device, Index >::PointType& steps ) -{ - this->spaceSteps = steps; - computeSpaceStepPowers(); - computeProportions(); -} - -template< typename Real, typename Device, typename Index > -template< int xPow, int yPow > -__cuda_callable__ -inline const Real& -Grid< 2, Real, Device, Index >::getSpaceStepsProducts() const -{ - static_assert( xPow >= -2 && xPow <= 2, "unsupported value of xPow" ); - static_assert( yPow >= -2 && yPow <= 2, "unsupported value of yPow" ); - return this->spaceStepsProducts[ xPow + 2 ][ yPow + 2 ]; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -Index -Grid< 2, Real, Device, Index >::getNumberOfNxFaces() const -{ - return numberOfNxFaces; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const Real& -Grid< 2, Real, Device, Index >::getCellMeasure() const -{ - return this->template getSpaceStepsProducts< 1, 1 >(); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline Real -Grid< 2, Real, Device, Index >::getSmallestSpaceStep() const -{ - return min( this->spaceSteps.x(), this->spaceSteps.y() ); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 2, Real, Device, Index >::writeProlog( Logger& logger ) const -{ - logger.writeParameter( "Dimension:", getMeshDimension() ); - logger.writeParameter( "Domain origin:", this->origin ); - logger.writeParameter( "Domain proportions:", this->proportions ); - logger.writeParameter( "Domain dimensions:", this->dimensions ); - logger.writeParameter( "Space steps:", this->getSpaceSteps() ); - logger.writeParameter( "Number of cells:", getEntitiesCount< Cell >() ); - logger.writeParameter( "Number of faces:", getEntitiesCount< Face >() ); - logger.writeParameter( "Number of vertices:", getEntitiesCount< Vertex >() ); -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Grid3D.h b/src/TNL/Meshes/GridDetails/Grid3D.h index 0ec5144f62f788624837ee15bfb20acb03240c65..7a08654cc858f8ed8aa8668930a9db9a01121a07 100644 --- a/src/TNL/Meshes/GridDetails/Grid3D.h +++ b/src/TNL/Meshes/GridDetails/Grid3D.h @@ -6,263 +6,84 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include namespace TNL { namespace Meshes { -template< typename Real, typename Device, typename Index > -class Grid< 3, Real, Device, Index > -{ -public: - using RealType = Real; - using DeviceType = Device; - using GlobalIndexType = Index; - using PointType = Containers::StaticVector< 3, Real >; - using CoordinatesType = Containers::StaticVector< 3, Index >; +template +class GridEntity; - // TODO: deprecated and to be removed (GlobalIndexType shall be used instead) - using IndexType = Index; +template +class Grid<3, Real, Device, Index> : public NDimGrid<3, Real, Device, Index> { + public: + template + using EntityType = GridEntity; - static constexpr int - getMeshDimension() - { - return 3; - }; - - template< int EntityDimension, typename Config = GridEntityCrossStencilStorage< 1 > > - using EntityType = GridEntity< Grid, EntityDimension, Config >; - - using Cell = EntityType< getMeshDimension(), GridEntityCrossStencilStorage< 1 > >; - using Face = EntityType< getMeshDimension() - 1 >; - using Edge = EntityType< 1 >; - using Vertex = EntityType< 0 >; + using Base = NDimGrid<3, Real, Device, Index>; + using Coordinate = typename Base::Coordinate; + using Point = typename Base::Point; + using EntitiesCounts = typename Base::EntitiesCounts; /** * \brief See Grid1D::Grid(). */ - Grid() = default; - - Grid( Index xSize, Index ySize, Index zSize ); - - // empty destructor is needed only to avoid crappy nvcc warnings - ~Grid() = default; - - /** - * \brief Sets the size of dimensions. - * \param xSize Size of dimesion x. - * \param ySize Size of dimesion y. - * \param zSize Size of dimesion z. - */ - void - setDimensions( Index xSize, Index ySize, Index zSize ); - - /** - * \brief See Grid1D::setDimensions( const CoordinatesType& dimensions ). - */ - void - setDimensions( const CoordinatesType& dimensions ); - - /** - * \brief See Grid1D::getDimensions(). - */ - __cuda_callable__ - const CoordinatesType& - getDimensions() const; - - void - setLocalBegin( const CoordinatesType& begin ); - - __cuda_callable__ - const CoordinatesType& - getLocalBegin() const; - - void - setLocalEnd( const CoordinatesType& end ); - - __cuda_callable__ - const CoordinatesType& - getLocalEnd() const; - - void - setInteriorBegin( const CoordinatesType& begin ); - - __cuda_callable__ - const CoordinatesType& - getInteriorBegin() const; - - void - setInteriorEnd( const CoordinatesType& end ); - - __cuda_callable__ - const CoordinatesType& - getInteriorEnd() const; - - /** - * \brief See Grid1D::setDomain(). - */ - void - setDomain( const PointType& origin, const PointType& proportions ); - - /** - * \brief See Grid1D::setOrigin() - */ - void - setOrigin( const PointType& origin ); + Grid(); - /** - * \brief See Grid1D::getOrigin(). - */ - __cuda_callable__ - inline const PointType& - getOrigin() const; - - /** - * \brief See Grid1D::getProportions(). - */ - __cuda_callable__ - inline const PointType& - getProportions() const; - - /** - * \brief Gets number of entities in this grid. - * \tparam EntityDimension Integer specifying dimension of the entity. - */ - template< int EntityDimension > - __cuda_callable__ - IndexType - getEntitiesCount() const; + Grid(const Index xSize, const Index ySize, const Index zSize); /** - * \brief Gets number of entities in this grid. + * @brief Gets entity index using entity type. + * \param entity Type of entity. * \tparam Entity Type of the entity. */ - template< typename Entity > - __cuda_callable__ - IndexType - getEntitiesCount() const; - - /** - * \brief See Grid1D::getEntity(). - */ - template< typename Entity > - __cuda_callable__ - inline Entity - getEntity( const IndexType& entityIndex ) const; - - /** - * \brief See Grid1D::getEntityIndex(). - */ - template< typename Entity > - __cuda_callable__ - inline Index - getEntityIndex( const Entity& entity ) const; + template + __cuda_callable__ inline Index getEntityIndex(const Entity& entity) const; /** - * \brief See Grid1D::getSpaceSteps(). + * @brief Traverser all elements in rect */ - __cuda_callable__ - inline const PointType& - getSpaceSteps() const; + template + inline void forAll(Func func, FuncArgs... args) const; /** - * \brief See Grid1D::setSpaceSteps(). + * @brief Traverser all elements in rect + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - inline void - setSpaceSteps( const PointType& steps ); + template + inline void forAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; /** - * \brief Returns product of space steps to the xPow. - * \tparam xPow Exponent for dimension x. - * \tparam yPow Exponent for dimension y. - * \tparam zPow Exponent for dimension z. + * @brief Traverser interior elements in rect */ - template< int xPow, int yPow, int zPow > - __cuda_callable__ - const RealType& - getSpaceStepsProducts() const; + template + inline void forInterior(Func func, FuncArgs... args) const; /** - * \brief Returns the number of x-normal faces. + * @brief Traverser interior elements + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - __cuda_callable__ - IndexType - getNumberOfNxFaces() const; + template + inline void forInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; /** - * \brief Returns the number of x-normal and y-normal faces. + * @brief Traverser boundary elements in rect */ - __cuda_callable__ - IndexType - getNumberOfNxAndNyFaces() const; + template + inline void forBoundary(Func func, FuncArgs... args) const; /** - * \breif Returns the measure (volume) of a cell in this grid. + * @brief Traverser boundary elements in rect + * @param from - bottom left anchor of traverse rect + * @param to - top right anchor of traverse rect */ - __cuda_callable__ - inline const RealType& - getCellMeasure() const; - - /** - * \brief See Grid1D::getSmallestSpaceStep(). - */ - __cuda_callable__ - RealType - getSmallestSpaceStep() const; - - void - writeProlog( Logger& logger ) const; - -protected: - void - computeProportions(); - - void - computeSpaceStepPowers(); - - void - computeSpaceSteps(); - - CoordinatesType dimensions = { 0, 0, 0 }; - CoordinatesType localBegin = { 0, 0, 0 }; - CoordinatesType localEnd = { 0, 0, 0 }; - CoordinatesType interiorBegin = { 0, 0, 0 }; - CoordinatesType interiorEnd = { 0, 0, 0 }; - - IndexType numberOfCells = 0; - IndexType numberOfNxFaces = 0; - IndexType numberOfNyFaces = 0; - IndexType numberOfNzFaces = 0; - IndexType numberOfNxAndNyFaces = 0; - IndexType numberOfFaces = 0; - IndexType numberOfDxEdges = 0; - IndexType numberOfDyEdges = 0; - IndexType numberOfDzEdges = 0; - IndexType numberOfDxAndDyEdges = 0; - IndexType numberOfEdges = 0; - IndexType numberOfVertices = 0; - IndexType cellZNeighborsStep = 0; - - PointType origin = { 0, 0, 0 }; - PointType proportions = { 0, 0, 0 }; - PointType spaceSteps = { 0, 0, 0 }; - - RealType spaceStepsProducts[ 5 ][ 5 ][ 5 ]; - - template< typename, typename, int > - friend class GridEntityGetter; - - template< typename, int, typename > - friend class NeighborGridEntityGetter; + template + inline void forBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; }; } // namespace Meshes } // namespace TNL -#include +#include diff --git a/src/TNL/Meshes/GridDetails/Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Grid3D_impl.h deleted file mode 100644 index 671afcf4e80c2e11a6abfbc7ba1903bbd14151cc..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Grid3D_impl.h +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename Real, typename Device, typename Index > -Grid< 3, Real, Device, Index >::Grid( Index xSize, Index ySize, Index zSize ) -{ - this->setDimensions( xSize, ySize, zSize ); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::computeSpaceSteps() -{ - if( this->getDimensions().x() > 0 && this->getDimensions().y() > 0 && this->getDimensions().z() > 0 ) { - this->spaceSteps.x() = this->proportions.x() / (Real) this->getDimensions().x(); - this->spaceSteps.y() = this->proportions.y() / (Real) this->getDimensions().y(); - this->spaceSteps.z() = this->proportions.z() / (Real) this->getDimensions().z(); - - this->computeSpaceStepPowers(); - } -}; - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::computeSpaceStepPowers() -{ - const RealType& hx = this->spaceSteps.x(); - const RealType& hy = this->spaceSteps.y(); - const RealType& hz = this->spaceSteps.z(); - - Real auxX; - Real auxY; - Real auxZ; - for( int i = 0; i < 5; i++ ) { - switch( i ) { - case 0: - auxX = 1.0 / ( hx * hx ); - break; - case 1: - auxX = 1.0 / hx; - break; - case 2: - auxX = 1.0; - break; - case 3: - auxX = hx; - break; - case 4: - auxX = hx * hx; - break; - } - for( int j = 0; j < 5; j++ ) { - switch( j ) { - case 0: - auxY = 1.0 / ( hy * hy ); - break; - case 1: - auxY = 1.0 / hy; - break; - case 2: - auxY = 1.0; - break; - case 3: - auxY = hy; - break; - case 4: - auxY = hy * hy; - break; - } - for( int k = 0; k < 5; k++ ) { - switch( k ) { - case 0: - auxZ = 1.0 / ( hz * hz ); - break; - case 1: - auxZ = 1.0 / hz; - break; - case 2: - auxZ = 1.0; - break; - case 3: - auxZ = hz; - break; - case 4: - auxZ = hz * hz; - break; - } - this->spaceStepsProducts[ i ][ j ][ k ] = auxX * auxY * auxZ; - } - } - } -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::computeProportions() -{ - this->proportions.x() = this->dimensions.x() * this->spaceSteps.x(); - this->proportions.y() = this->dimensions.y() * this->spaceSteps.y(); - this->proportions.z() = this->dimensions.z() * this->spaceSteps.z(); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setOrigin( const PointType& origin ) -{ - this->origin = origin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setSpaceSteps( const PointType& steps ) -{ - this->spaceSteps = steps; - computeSpaceStepPowers(); - computeProportions(); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setDimensions( Index xSize, Index ySize, Index zSize ) -{ - TNL_ASSERT_GE( xSize, 0, "Grid size must be non-negative." ); - TNL_ASSERT_GE( ySize, 0, "Grid size must be non-negative." ); - TNL_ASSERT_GE( zSize, 0, "Grid size must be non-negative." ); - - this->dimensions.x() = xSize; - this->dimensions.y() = ySize; - this->dimensions.z() = zSize; - this->numberOfCells = xSize * ySize * zSize; - this->numberOfNxFaces = ( xSize + 1 ) * ySize * zSize; - this->numberOfNyFaces = xSize * ( ySize + 1 ) * zSize; - this->numberOfNzFaces = xSize * ySize * ( zSize + 1 ); - this->numberOfNxAndNyFaces = this->numberOfNxFaces + this->numberOfNyFaces; - this->numberOfFaces = this->numberOfNxFaces + this->numberOfNyFaces + this->numberOfNzFaces; - this->numberOfDxEdges = xSize * ( ySize + 1 ) * ( zSize + 1 ); - this->numberOfDyEdges = ( xSize + 1 ) * ySize * ( zSize + 1 ); - this->numberOfDzEdges = ( xSize + 1 ) * ( ySize + 1 ) * zSize; - this->numberOfDxAndDyEdges = this->numberOfDxEdges + this->numberOfDyEdges; - this->numberOfEdges = this->numberOfDxEdges + this->numberOfDyEdges + this->numberOfDzEdges; - this->numberOfVertices = ( xSize + 1 ) * ( ySize + 1 ) * ( zSize + 1 ); - - this->cellZNeighborsStep = xSize * ySize; - - computeSpaceSteps(); - - // only default behaviour, DistributedGrid must use the setters explicitly after setDimensions - localBegin = 0; - interiorBegin = 1; - localEnd = dimensions; - interiorEnd = dimensions - 1; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setDimensions( const CoordinatesType& dimensions ) -{ - return this->setDimensions( dimensions.x(), dimensions.y(), dimensions.z() ); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 3, Real, Device, Index >::CoordinatesType& -Grid< 3, Real, Device, Index >::getDimensions() const -{ - return this->dimensions; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setLocalBegin( const CoordinatesType& begin ) -{ - localBegin = begin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 3, Real, Device, Index >::CoordinatesType& -Grid< 3, Real, Device, Index >::getLocalBegin() const -{ - return localBegin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setLocalEnd( const CoordinatesType& end ) -{ - localEnd = end; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 3, Real, Device, Index >::CoordinatesType& -Grid< 3, Real, Device, Index >::getLocalEnd() const -{ - return localEnd; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setInteriorBegin( const CoordinatesType& begin ) -{ - interiorBegin = begin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 3, Real, Device, Index >::CoordinatesType& -Grid< 3, Real, Device, Index >::getInteriorBegin() const -{ - return interiorBegin; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setInteriorEnd( const CoordinatesType& end ) -{ - interiorEnd = end; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const typename Grid< 3, Real, Device, Index >::CoordinatesType& -Grid< 3, Real, Device, Index >::getInteriorEnd() const -{ - return interiorEnd; -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::setDomain( const PointType& origin, const PointType& proportions ) -{ - this->origin = origin; - this->proportions = proportions; - computeSpaceSteps(); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 3, Real, Device, Index >::PointType& -Grid< 3, Real, Device, Index >::getOrigin() const -{ - return this->origin; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 3, Real, Device, Index >::PointType& -Grid< 3, Real, Device, Index >::getProportions() const -{ - return this->proportions; -} - -template< typename Real, typename Device, typename Index > -template< int EntityDimension > -__cuda_callable__ -inline Index -Grid< 3, Real, Device, Index >::getEntitiesCount() const -{ - static_assert( EntityDimension <= 3 && EntityDimension >= 0, "Wrong grid entity dimensions." ); - - switch( EntityDimension ) { - 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 > -template< typename Entity > -__cuda_callable__ -inline Index -Grid< 3, Real, Device, Index >::getEntitiesCount() const -{ - return getEntitiesCount< Entity::getEntityDimension() >(); -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Entity -Grid< 3, Real, Device, Index >::getEntity( const IndexType& entityIndex ) const -{ - static_assert( Entity::getEntityDimension() <= 3 && Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." ); - - return GridEntityGetter< Grid, Entity >::getEntity( *this, entityIndex ); -} - -template< typename Real, typename Device, typename Index > -template< typename Entity > -__cuda_callable__ -inline Index -Grid< 3, Real, Device, Index >::getEntityIndex( const Entity& entity ) const -{ - static_assert( Entity::getEntityDimension() <= 3 && Entity::getEntityDimension() >= 0, "Wrong grid entity dimensions." ); - - return GridEntityGetter< Grid, Entity >::getEntityIndex( *this, entity ); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline const typename Grid< 3, Real, Device, Index >::PointType& -Grid< 3, Real, Device, Index >::getSpaceSteps() const -{ - return this->spaceSteps; -} - -template< typename Real, typename Device, typename Index > -template< int xPow, int yPow, int zPow > -__cuda_callable__ -inline const Real& -Grid< 3, Real, Device, Index >::getSpaceStepsProducts() const -{ - static_assert( xPow >= -2 && xPow <= 2, "unsupported value of xPow" ); - static_assert( yPow >= -2 && yPow <= 2, "unsupported value of yPow" ); - static_assert( zPow >= -2 && zPow <= 2, "unsupported value of zPow" ); - return this->spaceStepsProducts[ xPow + 2 ][ yPow + 2 ][ zPow + 2 ]; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -Index -Grid< 3, Real, Device, Index >::getNumberOfNxFaces() const -{ - return numberOfNxFaces; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -Index -Grid< 3, Real, Device, Index >::getNumberOfNxAndNyFaces() const -{ - return numberOfNxAndNyFaces; -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -const Real& -Grid< 3, Real, Device, Index >::getCellMeasure() const -{ - return this->template getSpaceStepsProducts< 1, 1, 1 >(); -} - -template< typename Real, typename Device, typename Index > -__cuda_callable__ -inline Real -Grid< 3, Real, Device, Index >::getSmallestSpaceStep() const -{ - return min( this->spaceSteps.x(), min( this->spaceSteps.y(), this->spaceSteps.z() ) ); -} - -template< typename Real, typename Device, typename Index > -void -Grid< 3, Real, Device, Index >::writeProlog( Logger& logger ) const -{ - logger.writeParameter( "Dimension:", getMeshDimension() ); - logger.writeParameter( "Domain origin:", this->origin ); - logger.writeParameter( "Domain proportions:", this->proportions ); - logger.writeParameter( "Domain dimensions:", this->dimensions ); - logger.writeParameter( "Space steps:", this->getSpaceSteps() ); - logger.writeParameter( "Number of cells:", getEntitiesCount< Cell >() ); - logger.writeParameter( "Number of faces:", getEntitiesCount< Face >() ); - logger.writeParameter( "Number of vertices:", getEntitiesCount< Vertex >() ); -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h b/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h index af30ce8f97d8cca270232d34acb5f1be43405393..fc7ba322936b24ee2bf8c5512c6ff2fb5bba853c 100644 --- a/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h +++ b/src/TNL/Meshes/GridDetails/GridEntityCenterGetter.h @@ -9,165 +9,13 @@ namespace TNL { namespace Meshes { -template< typename GridEntity > -class GridEntityCenterGetter -{}; +template +class GridEntity; -/*** - * 1D grids - */ -template< typename Real, typename Device, typename Index, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config > > -{ -public: - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 1, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 ) * grid.getSpaceSteps().x() ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config > > -{ -public: - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 0, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( grid.getOrigin().x() + ( entity.getCoordinates().x() ) * grid.getSpaceSteps().x() ); - } -}; - -/**** - * 2D grids - */ -template< typename Real, typename Device, typename Index, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 2, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 ) * grid.getSpaceSteps().x(), - grid.getOrigin().y() + ( entity.getCoordinates().y() + 0.5 ) * grid.getSpaceSteps().y() ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 1, Config > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 1, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( - grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 * entity.getBasis().x() ) * grid.getSpaceSteps().x(), - grid.getOrigin().y() + ( entity.getCoordinates().y() + 0.5 * entity.getBasis().y() ) * grid.getSpaceSteps().y() ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 0, Config > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 0, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( grid.getOrigin().x() + entity.getCoordinates().x() * grid.getSpaceSteps().x(), - grid.getOrigin().y() + entity.getCoordinates().y() * grid.getSpaceSteps().y() ); - } -}; - -/*** - * 3D grid - */ -template< typename Real, typename Device, typename Index, int EntityDimension, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, EntityDimension, Config > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( - grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 * entity.getBasis().x() ) * grid.getSpaceSteps().x(), - grid.getOrigin().y() + ( entity.getCoordinates().y() + 0.5 * entity.getBasis().y() ) * grid.getSpaceSteps().y(), - grid.getOrigin().z() + ( entity.getCoordinates().z() + 0.5 * entity.getBasis().z() ) * grid.getSpaceSteps().z() ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 3, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( grid.getOrigin().x() + ( entity.getCoordinates().x() + 0.5 ) * grid.getSpaceSteps().x(), - grid.getOrigin().y() + ( entity.getCoordinates().y() + 0.5 ) * grid.getSpaceSteps().y(), - grid.getOrigin().z() + ( entity.getCoordinates().z() + 0.5 ) * grid.getSpaceSteps().z() ); - } -}; - -template< typename Real, typename Device, typename Index, typename Config > -class GridEntityCenterGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 0, Config > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, 0, Config >; - using PointType = typename GridType::PointType; - - __cuda_callable__ - inline static PointType - getEntityCenter( const GridEntityType& entity ) - { - const GridType& grid = entity.getMesh(); - return PointType( grid.getOrigin().x() + ( entity.getCoordinates().x() ) * grid.getSpaceSteps().x(), - grid.getOrigin().y() + ( entity.getCoordinates().y() ) * grid.getSpaceSteps().y(), - grid.getOrigin().z() + ( entity.getCoordinates().z() ) * grid.getSpaceSteps().z() ); - } -}; +template +class GridEntityCenterGetter; } // namespace Meshes } // namespace TNL + +#include diff --git a/src/TNL/Meshes/GridDetails/GridEntityGetter.h b/src/TNL/Meshes/GridDetails/GridEntityGetter.h index 72008111212132b33c31c6644ca9a1772f97d0ea..aebab212dd73cb07069093f5104f1d1f7455b12c 100644 --- a/src/TNL/Meshes/GridDetails/GridEntityGetter.h +++ b/src/TNL/Meshes/GridDetails/GridEntityGetter.h @@ -6,18 +6,18 @@ #pragma once +#include + namespace TNL { namespace Meshes { -template< typename Grid, typename GridEntity, int EntityDimension = GridEntity::getEntityDimension() > -class GridEntityGetter -{ - // static_assert( false, "Wrong mesh type or entity topology." ); -}; +template +class GridEntity; -/*** - * The main code is in template specializations in GridEntityIndexer.h - */ +template +class GridEntityGetter; } // namespace Meshes } // namespace TNL + +#include diff --git a/src/TNL/Meshes/GridDetails/GridEntityGetter_impl.h b/src/TNL/Meshes/GridDetails/GridEntityGetter_impl.h deleted file mode 100644 index b4914a1b7ade6e45028f3895d2b52b4dc0305d53..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/GridEntityGetter_impl.h +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -/**** - * 1D grid - */ -template< typename Real, typename Device, typename Index, typename GridEntity, int EntityDimension > -class GridEntityGetter< Meshes::Grid< 1, Real, Device, Index >, GridEntity, EntityDimension > -{ -public: - static constexpr int entityDimension = EntityDimension; - - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - return GridEntity( grid, - CoordinatesType( index ), - typename GridEntity::EntityOrientationType( 0 ), - typename GridEntity::EntityBasisType( EntityDimension ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( - entity.getCoordinates(), grid.getDimensions() + CoordinatesType( 1 - entityDimension ), "wrong coordinates" ); - return entity.getCoordinates().x(); - } -}; - -/**** - * 2D grid - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 > -{ -public: - static constexpr int entityDimension = 2; - - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - - const CoordinatesType& dimensions = grid.getDimensions(); - - return GridEntity( grid, - CoordinatesType( index % dimensions.x(), index / dimensions.x() ), - typename GridEntity::EntityOrientationType( 0, 0 ), - typename GridEntity::EntityBasisType( 1, 1 ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" ); - - // const CoordinatesType coordinates = entity.getCoordinates(); - // const CoordinatesType dimensions = grid.getDimensions(); - - return entity.getCoordinates().y() * grid.getDimensions().x() + entity.getCoordinates().x(); - } -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 > -{ -public: - static constexpr int entityDimension = 1; - - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension, EntityConfig > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - - const CoordinatesType dimensions = grid.getDimensions(); - - if( index < grid.numberOfNxFaces ) { - const IndexType aux = dimensions.x() + 1; - return GridEntity( grid, - CoordinatesType( index % aux, index / aux ), - typename GridEntity::EntityOrientationType( 1, 0 ), - typename GridEntity::EntityBasisType( 0, 1 ) ); - } - const IndexType i = index - grid.numberOfNxFaces; - const IndexType& aux = dimensions.x(); - return GridEntity( grid, - CoordinatesType( i % aux, i / aux ), - typename GridEntity::EntityOrientationType( 0, 1 ), - typename GridEntity::EntityBasisType( 1, 0 ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions() + abs( entity.getOrientation() ), "wrong coordinates" ); - - const CoordinatesType coordinates = entity.getCoordinates(); - const CoordinatesType dimensions = grid.getDimensions(); - - if( entity.getOrientation().x() ) - return coordinates.y() * ( dimensions.x() + 1 ) + coordinates.x(); - return grid.numberOfNxFaces + coordinates.y() * dimensions.x() + coordinates.x(); - } -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class GridEntityGetter< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 > -{ -public: - static constexpr int entityDimension = 0; - - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - - const CoordinatesType& dimensions = grid.getDimensions(); - - const IndexType aux = dimensions.x() + 1; - return GridEntity( grid, - CoordinatesType( index % aux, index / aux ), - typename GridEntity::EntityOrientationType( 0, 0 ), - typename GridEntity::EntityBasisType( 0, 0 ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" ); - - const CoordinatesType& coordinates = entity.getCoordinates(); - const CoordinatesType& dimensions = grid.getDimensions(); - - return coordinates.y() * ( dimensions.x() + 1 ) + coordinates.x(); - } -}; - -/**** - * 3D grid - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 > -{ -public: - static constexpr int entityDimension = 3; - - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - - const CoordinatesType& dimensions = grid.getDimensions(); - - return GridEntity( grid, - CoordinatesType( index % dimensions.x(), - ( index / dimensions.x() ) % dimensions.y(), - index / ( dimensions.x() * dimensions.y() ) ), - typename GridEntity::EntityOrientationType( 0, 0, 0 ), - typename GridEntity::EntityBasisType( 1, 1, 1 ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" ); - - const CoordinatesType& coordinates = entity.getCoordinates(); - const CoordinatesType& dimensions = grid.getDimensions(); - - return ( coordinates.z() * dimensions.y() + coordinates.y() ) * dimensions.x() + coordinates.x(); - } -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 > -{ -public: - static constexpr int entityDimension = 2; - - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - - const CoordinatesType dimensions = grid.getDimensions(); - - if( index < grid.numberOfNxFaces ) { - const IndexType aux = dimensions.x() + 1; - return GridEntity( grid, - CoordinatesType( index % aux, ( index / aux ) % dimensions.y(), index / ( aux * dimensions.y() ) ), - typename GridEntity::EntityOrientationType( 1, 0, 0 ), - typename GridEntity::EntityBasisType( 0, 1, 1 ) ); - } - if( index < grid.numberOfNxAndNyFaces ) { - const IndexType i = index - grid.numberOfNxFaces; - const IndexType aux = dimensions.y() + 1; - return GridEntity( grid, - CoordinatesType( i % dimensions.x(), ( i / dimensions.x() ) % aux, i / ( aux * dimensions.x() ) ), - typename GridEntity::EntityOrientationType( 0, 1, 0 ), - typename GridEntity::EntityBasisType( 1, 0, 1 ) ); - } - const IndexType i = index - grid.numberOfNxAndNyFaces; - return GridEntity( grid, - CoordinatesType( i % dimensions.x(), - ( i / dimensions.x() ) % dimensions.y(), - i / ( dimensions.x() * dimensions.y() ) ), - typename GridEntity::EntityOrientationType( 0, 0, 1 ), - typename GridEntity::EntityBasisType( 1, 1, 0 ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), grid.getDimensions() + abs( entity.getOrientation() ), "wrong coordinates" ); - - const CoordinatesType coordinates = entity.getCoordinates(); - const CoordinatesType dimensions = grid.getDimensions(); - - if( entity.getOrientation().x() ) { - return ( coordinates.z() * dimensions.y() + coordinates.y() ) * ( dimensions.x() + 1 ) + coordinates.x(); - } - if( entity.getOrientation().y() ) { - return grid.numberOfNxFaces + ( coordinates.z() * ( dimensions.y() + 1 ) + coordinates.y() ) * dimensions.x() - + coordinates.x(); - } - return grid.numberOfNxAndNyFaces + ( coordinates.z() * dimensions.y() + coordinates.y() ) * dimensions.x() - + coordinates.x(); - } -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 > -{ -public: - static constexpr int entityDimension = 1; - - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - - const CoordinatesType dimensions = grid.getDimensions(); - - if( index < grid.numberOfDxEdges ) { - const IndexType aux = dimensions.y() + 1; - return GridEntity( - grid, - CoordinatesType( index % dimensions.x(), ( index / dimensions.x() ) % aux, index / ( dimensions.x() * aux ) ), - typename GridEntity::EntityOrientationType( 0, 0, 0 ), - typename GridEntity::EntityBasisType( 1, 0, 0 ) ); - } - if( index < grid.numberOfDxAndDyEdges ) { - const IndexType i = index - grid.numberOfDxEdges; - const IndexType aux = dimensions.x() + 1; - return GridEntity( grid, - CoordinatesType( i % aux, ( i / aux ) % dimensions.y(), i / ( aux * dimensions.y() ) ), - typename GridEntity::EntityOrientationType( 0, 0, 0 ), - typename GridEntity::EntityBasisType( 0, 1, 0 ) ); - } - const IndexType i = index - grid.numberOfDxAndDyEdges; - const IndexType aux1 = dimensions.x() + 1; - const IndexType aux2 = dimensions.y() + 1; - return GridEntity( grid, - CoordinatesType( i % aux1, ( i / aux1 ) % aux2, i / ( aux1 * aux2 ) ), - typename GridEntity::EntityOrientationType( 0, 0, 0 ), - typename GridEntity::EntityBasisType( 0, 0, 1 ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( - entity.getCoordinates(), grid.getDimensions() + CoordinatesType( 1, 1, 1 ) - entity.getBasis(), "wrong coordinates" ); - - const CoordinatesType coordinates = entity.getCoordinates(); - const CoordinatesType dimensions = grid.getDimensions(); - - if( entity.getBasis().x() ) - return ( coordinates.z() * ( dimensions.y() + 1 ) + coordinates.y() ) * dimensions.x() + coordinates.x(); - if( entity.getBasis().y() ) - return grid.numberOfDxEdges + ( coordinates.z() * dimensions.y() + coordinates.y() ) * ( dimensions.x() + 1 ) - + coordinates.x(); - return grid.numberOfDxAndDyEdges + ( coordinates.z() * ( dimensions.y() + 1 ) + coordinates.y() ) * ( dimensions.x() + 1 ) - + coordinates.x(); - } -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class GridEntityGetter< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 > -{ -public: - static constexpr int entityDimension = 0; - - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - // typedef typename GridType::template GridEntity< entityDimension > GridEntity; - - __cuda_callable__ - inline static GridEntity - getEntity( const GridType& grid, const IndexType& index ) - { - TNL_ASSERT_GE( index, 0, "Index must be non-negative." ); - TNL_ASSERT_LT( index, grid.template getEntitiesCount< GridEntity >(), "Index is out of bounds." ); - - const CoordinatesType& dimensions = grid.getDimensions(); - - const IndexType auxX = dimensions.x() + 1; - const IndexType auxY = dimensions.y() + 1; - return GridEntity( grid, - CoordinatesType( index % auxX, ( index / auxX ) % auxY, index / ( auxX * auxY ) ), - typename GridEntity::EntityOrientationType( 0, 0, 0 ), - typename GridEntity::EntityBasisType( 0, 0, 0 ) ); - } - - __cuda_callable__ - inline static IndexType - getEntityIndex( const GridType& grid, const GridEntity& entity ) - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), grid.getDimensions(), "wrong coordinates" ); - - const CoordinatesType& coordinates = entity.getCoordinates(); - const CoordinatesType& dimensions = grid.getDimensions(); - - return ( coordinates.z() * ( dimensions.y() + 1 ) + coordinates.y() ) * ( dimensions.x() + 1 ) + coordinates.x(); - } -}; - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h b/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h index 539c6e247db04fcff32f5ed75a0825cbcf0853a6..1f0080365c032b86e68308a616697a868781af76 100644 --- a/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h +++ b/src/TNL/Meshes/GridDetails/GridEntityMeasureGetter.h @@ -4,145 +4,17 @@ // // SPDX-License-Identifier: MIT +#include + #pragma once namespace TNL { namespace Meshes { -template< typename Grid, int EntityDimension > -class GridEntityMeasureGetter -{}; - -/*** - * Common implementation for vertices - */ -template< int Dimension, typename Real, typename Device, typename Index > -class GridEntityMeasureGetter< Meshes::Grid< Dimension, Real, Device, Index >, 0 > -{ -public: - using GridType = Meshes::Grid< Dimension, Real, Device, Index >; - - template< typename EntityType > - __cuda_callable__ - inline static Real - getMeasure( const GridType& grid, const EntityType& entity ) - { - return 0.0; - } -}; - -/**** - * 1D grid - */ - -template< typename Real, typename Device, typename Index > -class GridEntityMeasureGetter< Meshes::Grid< 1, Real, Device, Index >, 1 > -{ -public: - using GridType = Meshes::Grid< 1, Real, Device, Index >; - - template< typename EntityType > - __cuda_callable__ - inline static const Real& - getMeasure( const GridType& grid, const EntityType& entity ) - { - return grid.template getSpaceStepsProducts< 1 >(); - } -}; - -/**** - * 2D grid - */ -template< typename Real, typename Device, typename Index > -class GridEntityMeasureGetter< Meshes::Grid< 2, Real, Device, Index >, 2 > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - - template< typename EntityType > - __cuda_callable__ - inline static const Real& - getMeasure( const GridType& grid, const EntityType& entity ) - { - return grid.template getSpaceStepsProducts< 1, 1 >(); - } -}; - -template< typename Real, typename Device, typename Index > -class GridEntityMeasureGetter< Meshes::Grid< 2, Real, Device, Index >, 1 > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - - template< typename EntityType > - __cuda_callable__ - inline static const Real& - getMeasure( const GridType& grid, const EntityType& entity ) - { - if( entity.getOrientation().x() ) - return grid.template getSpaceStepsProducts< 0, 1 >(); - else - return grid.template getSpaceStepsProducts< 1, 0 >(); - } -}; - -/**** - * 3D grid - */ -template< typename Real, typename Device, typename Index > -class GridEntityMeasureGetter< Meshes::Grid< 3, Real, Device, Index >, 3 > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - - template< typename EntityType > - __cuda_callable__ - inline static const Real& - getMeasure( const GridType& grid, const EntityType& entity ) - { - return grid.template getSpaceStepsProducts< 1, 1, 1 >(); - } -}; - -template< typename Real, typename Device, typename Index > -class GridEntityMeasureGetter< Meshes::Grid< 3, Real, Device, Index >, 2 > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - - template< typename EntityType > - __cuda_callable__ - inline static const Real& - getMeasure( const GridType& grid, const EntityType& entity ) - { - if( entity.getOrientation().x() ) - return grid.template getSpaceStepsProducts< 0, 1, 1 >(); - if( entity.getOrientation().y() ) - return grid.template getSpaceStepsProducts< 1, 0, 1 >(); - else - return grid.template getSpaceStepsProducts< 1, 1, 0 >(); - } -}; - -template< typename Real, typename Device, typename Index > -class GridEntityMeasureGetter< Meshes::Grid< 3, Real, Device, Index >, 1 > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; +template +class GridEntityMeasureGetter; - template< typename EntityType > - __cuda_callable__ - inline static const Real& - getMeasure( const GridType& grid, const EntityType& entity ) - { - if( entity.getBasis().x() ) - return grid.template getSpaceStepsProducts< 1, 0, 0 >(); - if( entity.getBasis().y() ) - return grid.template getSpaceStepsProducts< 0, 1, 0 >(); - else - return grid.template getSpaceStepsProducts< 0, 0, 1 >(); - } -}; +} // namespace Meshes +} // namespace TNL -} // namespace Meshes -} // namespace TNL +#include diff --git a/src/TNL/Meshes/GridDetails/GridEntityTopology.h b/src/TNL/Meshes/GridDetails/GridEntityTopology.h deleted file mode 100644 index 3f4d0baaec08e9df184dbcd0502a18f69e8cd3d1..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/GridEntityTopology.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -namespace TNL { -namespace Meshes { - -template< typename Grid, int EntityDimension, typename EntityOrientation_, typename EntityProportions_ > -class GridEntityTopology -{ -public: - using GridType = Grid; - - static constexpr int meshDimension = GridType::getMeshDimension(); - - static constexpr int entityDimension = EntityDimension; - - using EntityOrientation = EntityOrientation_; - - using EntityProportions = EntityProportions_; - - // TODO: restore when CUDA allows it - // static_assert( meshDimension == EntityOrientation_::size, - // "Entity orientation is not a proper static multiindex." ); -}; - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/GridEntity_impl.h b/src/TNL/Meshes/GridDetails/GridEntity_impl.h deleted file mode 100644 index 6fdb0a85f886ecf1bae952a8582576e670d6d805..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/GridEntity_impl.h +++ /dev/null @@ -1,453 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -/*template< int Dimension, - typename Real, - typename Device, - typename Index, typename Config, - int EntityDimension > -__cuda_callable__ inline -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension >:: -GridEntity() -{ -}*/ - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::GridEntity( - const Meshes::Grid< Dimension, Real, Device, Index >& grid ) -: grid( grid ), entityIndex( -1 ), coordinates( 0 ), orientation( 0 ), basis( 0 ), neighborEntitiesStorage( *this ) -{} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::GridEntity( - const Meshes::Grid< Dimension, Real, Device, Index >& grid, - const CoordinatesType& coordinates, - const EntityOrientationType& orientation, - const EntityBasisType& basis ) -: grid( grid ), entityIndex( -1 ), coordinates( coordinates ), orientation( orientation ), basis( basis ), - neighborEntitiesStorage( *this ) -{} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::CoordinatesType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getCoordinates() const -{ - return this->coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::CoordinatesType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getCoordinates() -{ - return this->coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::setCoordinates( - const CoordinatesType& coordinates ) -{ - this->coordinates = coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::refresh() -{ - this->entityIndex = this->grid.getEntityIndex( *this ); - this->neighborEntitiesStorage.refresh( this->grid, this->entityIndex ); -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline Index -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getIndex() const -{ - using GridType = Meshes::Grid< Dimension, Real, Device, Index >; - using EntityType = typename GridType::template EntityType< EntityDimension >; - TNL_ASSERT_GE( this->entityIndex, 0, "Entity index is not non-negative." ); - TNL_ASSERT_LT( this->entityIndex, grid.template getEntitiesCount< EntityDimension >(), "Entity index is out of bounds." ); - TNL_ASSERT_EQ( this->entityIndex, grid.getEntityIndex( *this ), "Wrong value of stored index." ); - return this->entityIndex; -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >:: - EntityOrientationType& - GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getOrientation() const -{ - return this->orientation; -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::setOrientation( - const EntityOrientationType& orientation ) -{ - this->orientation = orientation; - this->basis = EntityBasisType( 1 ) - abs( orientation ); -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::EntityBasisType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getBasis() const -{ - return this->basis; -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::setBasis( const EntityBasisType& basis ) -{ - this->basis = basis; - this->orientation = EntityOrientationType( 1 ) - abs( basis ); -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -template< int NeighborEntityDimension > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >:: - template NeighborEntities< NeighborEntityDimension >& - GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getNeighborEntities() const -{ - return neighborEntitiesStorage.template getNeighborEntities< NeighborEntityDimension >(); -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline bool -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::isBoundaryEntity() const -{ - return BoundaryGridEntityChecker< GridEntity >::isBoundaryEntity( *this ); -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline typename Meshes::Grid< Dimension, Real, Device, Index >::PointType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getCenter() const -{ - return GridEntityCenterGetter< GridEntity >::getEntityCenter( *this ); -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::RealType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getMeasure() const -{ - return GridEntityMeasureGetter< GridType, EntityDimension >::getMeasure( this->getMesh(), *this ); -} - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::GridType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >::getMesh() const -{ - return this->grid; -} - -/**** - * Specialization for cells - */ -/*template< int Dimension, - typename Real, - typename Device, - typename Index > -__cuda_callable__ inline -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension >:: -GridEntity() -{ -}*/ - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::GridEntity( const GridType& grid ) -: grid( grid ), entityIndex( -1 ), neighborEntitiesStorage( *this ) -{ - this->coordinates = CoordinatesType( (Index) 0 ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::GridEntity( - const GridType& grid, - const CoordinatesType& coordinates, - const EntityOrientationType& orientation, - const EntityBasisType& basis ) -: grid( grid ), entityIndex( -1 ), coordinates( coordinates ), neighborEntitiesStorage( *this ) -{} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::CoordinatesType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getCoordinates() const -{ - return this->coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::CoordinatesType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getCoordinates() -{ - return this->coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::setCoordinates( - const CoordinatesType& coordinates ) -{ - this->coordinates = coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::refresh() -{ - this->entityIndex = this->grid.getEntityIndex( *this ); - this->neighborEntitiesStorage.refresh( this->grid, this->entityIndex ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline Index -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getIndex() const -{ - TNL_ASSERT_GE( this->entityIndex, 0, "Entity index is not non-negative." ); - TNL_ASSERT_LT( this->entityIndex, grid.template getEntitiesCount< Dimension >(), "Entity index is out of bounds." ); - TNL_ASSERT_EQ( this->entityIndex, grid.getEntityIndex( *this ), "Wrong value of stored index." ); - return this->entityIndex; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::EntityOrientationType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getOrientation() const -{ - return EntityOrientationType( (IndexType) 0 ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::EntityBasisType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getBasis() const -{ - return EntityBasisType( (IndexType) 1 ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -template< int NeighborEntityDimension > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >:: - template NeighborEntities< NeighborEntityDimension >& - GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getNeighborEntities() const -{ - return neighborEntitiesStorage.template getNeighborEntities< NeighborEntityDimension >(); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline bool -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::isBoundaryEntity() const -{ - return BoundaryGridEntityChecker< GridEntity >::isBoundaryEntity( *this ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline typename Meshes::Grid< Dimension, Real, Device, Index >::PointType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getCenter() const -{ - return GridEntityCenterGetter< GridEntity >::getEntityCenter( *this ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::RealType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getMeasure() const -{ - return this->getMesh().getCellMeasure(); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::PointType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getEntityProportions() const -{ - return grid.getSpaceSteps(); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::GridType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >::getMesh() const -{ - return this->grid; -} - -/**** - * Specialization for vertices - */ -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::GridEntity( const GridType& grid ) -: grid( grid ), entityIndex( -1 ), coordinates( 0 ), neighborEntitiesStorage( *this ) -{} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::GridEntity( - const GridType& grid, - const CoordinatesType& coordinates, - const EntityOrientationType& orientation, - const EntityBasisType& basis ) -: grid( grid ), entityIndex( -1 ), coordinates( coordinates ), neighborEntitiesStorage( *this ) -{} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::CoordinatesType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getCoordinates() const -{ - return this->coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::CoordinatesType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getCoordinates() -{ - return this->coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::setCoordinates( const CoordinatesType& coordinates ) -{ - this->coordinates = coordinates; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline void -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::refresh() -{ - this->entityIndex = this->grid.getEntityIndex( *this ); - this->neighborEntitiesStorage.refresh( this->grid, this->entityIndex ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline Index -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getIndex() const -{ - using GridType = Meshes::Grid< Dimension, Real, Device, Index >; - using Vertex = typename GridType::Vertex; - TNL_ASSERT_GE( this->entityIndex, 0, "Entity index is not non-negative." ); - TNL_ASSERT_LT( this->entityIndex, grid.template getEntitiesCount< 0 >(), "Entity index is out of bounds." ); - TNL_ASSERT_EQ( this->entityIndex, grid.getEntityIndex( *this ), "Wrong value of stored index." ); - return this->entityIndex; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::EntityOrientationType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getOrientation() const -{ - return EntityOrientationType( (IndexType) 0 ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::EntityBasisType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getBasis() const -{ - return EntityBasisType( (IndexType) 0 ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -template< int NeighborEntityDimension > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::template NeighborEntities< - NeighborEntityDimension >& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getNeighborEntities() const -{ - return neighborEntitiesStorage.template getNeighborEntities< NeighborEntityDimension >(); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline bool -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::isBoundaryEntity() const -{ - return BoundaryGridEntityChecker< GridEntity >::isBoundaryEntity( *this ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline typename Meshes::Grid< Dimension, Real, Device, Index >::PointType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getCenter() const -{ - return GridEntityCenterGetter< GridEntity >::getEntityCenter( *this ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline typename Meshes::Grid< Dimension, Real, Device, Index >::PointType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getPoint() const -{ - return getCenter(); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::RealType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getMeasure() const -{ - return 0.0; -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::PointType -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getEntityProportions() const -{ - return PointType( 0.0 ); -} - -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -__cuda_callable__ -inline const typename GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::GridType& -GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >::getMesh() const -{ - return this->grid; -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/GridTraverser.h b/src/TNL/Meshes/GridDetails/GridTraverser.h deleted file mode 100644 index 3077328eb9e36b365606f27447e4acfb19f93796..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/GridTraverser.h +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include - -namespace TNL { -namespace Meshes { - -/**** - * This is only a helper class for Traverser specializations for Grid. - */ -template< typename Grid > -class GridTraverser -{}; - -enum GridTraverserMode -{ - synchronousMode, - asynchronousMode -}; - -/**** - * 1D grid, Devices::Host - */ -template< typename Real, typename Index > -class GridTraverser< Meshes::Grid< 1, Real, Devices::Host, Index > > -{ -public: - using GridType = Meshes::Grid< 1, Real, Devices::Host, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using RealType = Real; - using DeviceType = Devices::Host; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename GridEntity, typename EntitiesProcessor, typename UserData, bool processOnlyBoundaryEntities > - static void - processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode = synchronousMode, - const int& stream = 0 ); -}; - -/**** - * 1D grid, Devices::Cuda - */ -template< typename Real, typename Index > -class GridTraverser< Meshes::Grid< 1, Real, Devices::Cuda, Index > > -{ -public: - using GridType = Meshes::Grid< 1, Real, Devices::Cuda, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using RealType = Real; - using DeviceType = Devices::Cuda; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename GridEntity, typename EntitiesProcessor, typename UserData, bool processOnlyBoundaryEntities > - static void - processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode = synchronousMode, - const int& stream = 0 ); -}; - -/**** - * 2D grid, Devices::Host - */ -template< typename Real, typename Index > -class GridTraverser< Meshes::Grid< 2, Real, Devices::Host, Index > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Devices::Host, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using RealType = Real; - using DeviceType = Devices::Host; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary = 1, - int YOrthogonalBoundary = 1, - typename... GridEntityParameters > - static void - processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - // FIXME: hack around nvcc bug (error: default argument not at end of parameter list) - // GridTraverserMode mode = synchronousMode, - GridTraverserMode mode, - // const int& stream = 0, - const int& stream, - // gridEntityParameters are passed to GridEntity's constructor - // (i.e. orientation and basis for faces) - const GridEntityParameters&... gridEntityParameters ); -}; - -/**** - * 2D grid, Devices::Cuda - */ -template< typename Real, typename Index > -class GridTraverser< Meshes::Grid< 2, Real, Devices::Cuda, Index > > -{ -public: - using GridType = Meshes::Grid< 2, Real, Devices::Cuda, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using RealType = Real; - using DeviceType = Devices::Cuda; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary = 1, - int YOrthogonalBoundary = 1, - typename... GridEntityParameters > - static void - processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - // FIXME: hack around nvcc bug (error: default argument not at end of parameter list) - // GridTraverserMode mode = synchronousMode, - GridTraverserMode mode, - // const int& stream = 0, - const int& stream, - // gridEntityParameters are passed to GridEntity's constructor - // (i.e. orientation and basis for faces) - const GridEntityParameters&... gridEntityParameters ); -}; - -/**** - * 3D grid, Devices::Host - */ -template< typename Real, typename Index > -class GridTraverser< Meshes::Grid< 3, Real, Devices::Host, Index > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Devices::Host, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using RealType = Real; - using DeviceType = Devices::Host; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary = 1, - int YOrthogonalBoundary = 1, - int ZOrthogonalBoundary = 1, - typename... GridEntityParameters > - static void - processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - // FIXME: hack around nvcc bug (error: default argument not at end of parameter list) - // GridTraverserMode mode = synchronousMode, - GridTraverserMode mode, - // const int& stream = 0, - const int& stream, - // gridEntityParameters are passed to GridEntity's constructor - // (i.e. orientation and basis for faces and edges) - const GridEntityParameters&... gridEntityParameters ); -}; - -/**** - * 3D grid, Devices::Cuda - */ -template< typename Real, typename Index > -class GridTraverser< Meshes::Grid< 3, Real, Devices::Cuda, Index > > -{ -public: - using GridType = Meshes::Grid< 3, Real, Devices::Cuda, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using RealType = Real; - using DeviceType = Devices::Cuda; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary = 1, - int YOrthogonalBoundary = 1, - int ZOrthogonalBoundary = 1, - typename... GridEntityParameters > - static void - processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - // FIXME: hack around nvcc bug (error: default argument not at end of parameter list) - // GridTraverserMode mode = synchronousMode, - GridTraverserMode mode, - // const int& stream = 0, - const int& stream, - // gridEntityParameters are passed to GridEntity's constructor - // (i.e. orientation and basis for faces and edges) - const GridEntityParameters&... gridEntityParameters ); -}; - -} // namespace Meshes -} // namespace TNL - -#include -#include -#include diff --git a/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp b/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp deleted file mode 100644 index b71c2a6ac0e3a37748d5785e9c2c321a7cb8e1ac..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/GridTraverser_1D.hpp +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -// Implemented by: Tomas Oberhuber, -// Jakub Klinkovsky, -// Vit Hanousek - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -/**** - * 1D traverser, host - */ -template< typename Real, typename Index > -template< typename GridEntity, typename EntitiesProcessor, typename UserData, bool processOnlyBoundaryEntities > -void -GridTraverser< Meshes::Grid< 1, Real, Devices::Host, Index > >::processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode, - const int& stream ) -{ - GridEntity entity( *gridPointer ); - if( processOnlyBoundaryEntities ) { - GridEntity entity( *gridPointer ); - - entity.getCoordinates() = begin; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - entity.getCoordinates() = end - 1; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - else { -#ifdef HAVE_OPENMP - if( Devices::Host::isOMPEnabled() && end.x() - begin.x() > 512 ) { - #pragma omp parallel firstprivate( begin, end ) - { - GridEntity entity( *gridPointer ); - #pragma omp for - // TODO: g++ 5.5 crashes when coding this loop without auxiliary x as bellow - for( IndexType x = begin.x(); x < end.x(); x++ ) { - entity.getCoordinates().x() = x; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } - } - else { - GridEntity entity( *gridPointer ); - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) { - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } -#else - GridEntity entity( *gridPointer ); - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) { - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } -#endif - } -} - -/**** - * 1D traverser, CUDA - */ -#ifdef HAVE_CUDA -template< typename Real, typename Index, typename GridEntity, typename UserData, typename EntitiesProcessor > -__global__ -void -GridTraverser1D( const Meshes::Grid< 1, Real, Devices::Cuda, Index >* grid, - UserData userData, - const typename GridEntity::CoordinatesType begin, - const typename GridEntity::CoordinatesType end, - const Index gridIdx ) -{ - typedef Real RealType; - typedef Index IndexType; - typedef Meshes::Grid< 1, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = begin.x() + ( gridIdx * Cuda::getMaxGridSize() + blockIdx.x ) * blockDim.x + threadIdx.x; - if( coordinates < end ) { - GridEntity entity( *grid, coordinates ); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } -} - -template< typename Real, typename Index, typename GridEntity, typename UserData, typename EntitiesProcessor > -__global__ -void -GridBoundaryTraverser1D( const Meshes::Grid< 1, Real, Devices::Cuda, Index >* grid, - UserData userData, - const typename GridEntity::CoordinatesType begin, - const typename GridEntity::CoordinatesType end ) -{ - typedef Real RealType; - typedef Index IndexType; - typedef Meshes::Grid< 1, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - if( threadIdx.x == 0 ) { - coordinates.x() = begin.x(); - GridEntity entity( *grid, coordinates ); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - if( threadIdx.x == 1 ) { - coordinates.x() = end.x() - 1; - GridEntity entity( *grid, coordinates ); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } -} - -#endif - -template< typename Real, typename Index > -template< typename GridEntity, typename EntitiesProcessor, typename UserData, bool processOnlyBoundaryEntities > -void -GridTraverser< Meshes::Grid< 1, Real, Devices::Cuda, Index > >::processEntities( const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode, - const int& stream ) -{ -#ifdef HAVE_CUDA - auto& pool = Cuda::StreamPool::getInstance(); - const cudaStream_t& s = pool.getStream( stream ); - - Pointers::synchronizeSmartPointersOnDevice< Devices::Cuda >(); - if( processOnlyBoundaryEntities ) { - dim3 cudaBlockSize( 2 ); - dim3 cudaBlocks( 1 ); - GridBoundaryTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor > <<< cudaBlocks, - cudaBlockSize, 0, s >>>( &gridPointer.template getData< Devices::Cuda >(), userData, begin, end ); - } - else { - dim3 blockSize( 256 ), blocksCount, gridsCount; - Cuda::setupThreads( blockSize, blocksCount, gridsCount, end.x() - begin.x() ); - dim3 gridIdx; - for( gridIdx.x = 0; gridIdx.x < gridsCount.x; gridIdx.x++ ) { - dim3 gridSize; - Cuda::setupGrid( blocksCount, gridsCount, gridIdx, gridSize ); - GridTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor > <<< blocksCount, blockSize, 0, - s >>>( &gridPointer.template getData< Devices::Cuda >(), userData, begin, end, gridIdx.x ); - } - - /*dim3 cudaBlockSize( 256 ); - dim3 cudaBlocks; - cudaBlocks.x = Cuda::getNumberOfBlocks( end.x() - begin.x(), cudaBlockSize.x ); - const IndexType cudaXGrids = Cuda::getNumberOfGrids( cudaBlocks.x ); - - for( IndexType gridXIdx = 0; gridXIdx < cudaXGrids; gridXIdx ++ ) - GridTraverser1D< Real, Index, GridEntity, UserData, EntitiesProcessor > - <<< cudaBlocks, cudaBlockSize, 0, s >>> - ( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin, - end, - gridXIdx );*/ - } - - #ifdef NDEBUG - if( mode == synchronousMode ) { - cudaStreamSynchronize( s ); - TNL_CHECK_CUDA_DEVICE; - } - #else - cudaStreamSynchronize( s ); - TNL_CHECK_CUDA_DEVICE; - #endif - -#else - throw Exceptions::CudaSupportMissing(); -#endif -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/GridTraverser_2D.hpp b/src/TNL/Meshes/GridDetails/GridTraverser_2D.hpp deleted file mode 100644 index 77171e24cf978507408956c8263c19bbdbb6f4e6..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/GridTraverser_2D.hpp +++ /dev/null @@ -1,524 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -//#define GRID_TRAVERSER_USE_STREAMS - -/**** - * 2D traverser, host - */ -template< typename Real, typename Index > -template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary, - int YOrthogonalBoundary, - typename... GridEntityParameters > -void -GridTraverser< Meshes::Grid< 2, Real, Devices::Host, Index > >::processEntities( - const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode, - const int& stream, - const GridEntityParameters&... gridEntityParameters ) -{ - if( processOnlyBoundaryEntities ) { - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - - if( YOrthogonalBoundary ) - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) { - entity.getCoordinates().y() = begin.y(); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - entity.getCoordinates().y() = end.y() - 1; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - if( XOrthogonalBoundary ) - for( entity.getCoordinates().y() = begin.y(); entity.getCoordinates().y() < end.y(); entity.getCoordinates().y()++ ) { - entity.getCoordinates().x() = begin.x(); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - entity.getCoordinates().x() = end.x() - 1; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } - else { -#ifdef HAVE_OPENMP - if( Devices::Host::isOMPEnabled() ) { - #pragma omp parallel firstprivate( begin, end ) - { - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - #pragma omp for - // TODO: g++ 5.5 crashes when coding this loop without auxiliary x and y as bellow - for( IndexType y = begin.y(); y < end.y(); y++ ) - for( IndexType x = begin.x(); x < end.x(); x++ ) { - entity.getCoordinates().x() = x; - entity.getCoordinates().y() = y; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } - } - else { - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - for( entity.getCoordinates().y() = begin.y(); entity.getCoordinates().y() < end.y(); entity.getCoordinates().y()++ ) - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) - { - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } -#else - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - for( entity.getCoordinates().y() = begin.y(); entity.getCoordinates().y() < end.y(); entity.getCoordinates().y()++ ) - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) { - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } -#endif - } -} - -/**** - * 2D traverser, CUDA - */ -#ifdef HAVE_CUDA -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser2D( const Meshes::Grid< 2, Real, Devices::Cuda, Index >* grid, - UserData userData, - const typename GridEntity::CoordinatesType begin, - const typename GridEntity::CoordinatesType end, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - typedef Meshes::Grid< 2, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = begin.x() + Cuda::getGlobalThreadIdx_x( gridIdx ); - coordinates.y() = begin.y() + Cuda::getGlobalThreadIdx_y( gridIdx ); - - if( coordinates < end ) { - GridEntity entity( *grid, coordinates, gridEntityParameters... ); - entity.refresh(); - if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() ) { - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - } -} - -// Boundary traverser using streams -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser2DBoundaryAlongX( const Meshes::Grid< 2, Real, Devices::Cuda, Index >* grid, - UserData userData, - const Index beginX, - const Index endX, - const Index fixedY, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - typedef Meshes::Grid< 2, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = beginX + Cuda::getGlobalThreadIdx_x( gridIdx ); - coordinates.y() = fixedY; - - if( coordinates.x() < endX ) { - GridEntity entity( *grid, coordinates, gridEntityParameters... ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } -} - -// Boundary traverser using streams -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser2DBoundaryAlongY( const Meshes::Grid< 2, Real, Devices::Cuda, Index >* grid, - UserData userData, - const Index beginY, - const Index endY, - const Index fixedX, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - typedef Meshes::Grid< 2, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = fixedX; - coordinates.y() = beginY + Cuda::getGlobalThreadIdx_x( gridIdx ); - - if( coordinates.y() < endY ) { - GridEntity entity( *grid, coordinates, gridEntityParameters... ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } -} - -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser2DBoundary( const Meshes::Grid< 2, Real, Devices::Cuda, Index >* grid, - UserData userData, - const Index beginX, - const Index endX, - const Index beginY, - const Index endY, - const Index blocksPerFace, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - using GridType = Meshes::Grid< 2, Real, Devices::Cuda, Index >; - using CoordinatesType = typename GridType::CoordinatesType; - - const Index faceIdx = blockIdx.x / blocksPerFace; - const Index faceBlockIdx = blockIdx.x % blocksPerFace; - const Index threadId = faceBlockIdx * blockDim.x + threadIdx.x; - if( faceIdx < 2 ) { - const Index entitiesAlongX = endX - beginX; - if( threadId < entitiesAlongX ) { - GridEntity entity( - *grid, CoordinatesType( beginX + threadId, faceIdx == 0 ? beginY : endY - 1 ), gridEntityParameters... ); - // printf( "faceIdx %d Thread %d -> %d %d \n ", faceIdx, threadId, entity.getCoordinates().x(), - // entity.getCoordinates().y() ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - } - else { - const Index entitiesAlongY = endY - beginY; - if( threadId < entitiesAlongY ) { - GridEntity entity( - *grid, CoordinatesType( faceIdx == 2 ? beginX : endX - 1, beginY + threadId + 1 ), gridEntityParameters... ); - // printf( "faceIdx %d Thread %d -> %d %d \n ", faceIdx, threadId, entity.getCoordinates().x(), - // entity.getCoordinates().y() ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - } - - /*const Index aux = max( entitiesAlongX, entitiesAlongY ); - const Index& warpSize = Cuda::getWarpSize(); - const Index threadsPerAxis = warpSize * ( aux / warpSize + ( aux % warpSize != 0 ) ); - - Index threadId = Cuda::getGlobalThreadIdx_x( gridIdx ); - GridEntity entity( *grid, - CoordinatesType( 0, 0 ), - gridEntityParameters... ); - CoordinatesType& coordinates = entity.getCoordinates(); - const Index axisIndex = threadId / threadsPerAxis; - //printf( "axisIndex %d, threadId %d thradsPerAxis %d \n", axisIndex, threadId, threadsPerAxis ); - threadId -= axisIndex * threadsPerAxis; - switch( axisIndex ) - { - case 1: - coordinates = CoordinatesType( beginX + threadId, beginY ); - if( threadId < entitiesAlongX ) - { - //printf( "X1: Thread %d -> %d %d \n ", threadId, coordinates.x(), coordinates.y() ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - break; - case 2: - coordinates = CoordinatesType( beginX + threadId, endY - 1 ); - if( threadId < entitiesAlongX ) - { - //printf( "X2: Thread %d -> %d %d \n ", threadId, coordinates.x(), coordinates.y() ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - break; - case 3: - coordinates = CoordinatesType( beginX, beginY + threadId + 1 ); - if( threadId < entitiesAlongY ) - { - //printf( "Y1: Thread %d -> %d %d \n ", threadId, coordinates.x(), coordinates.y() ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - break; - case 4: - coordinates = CoordinatesType( endX - 1, beginY + threadId + 1 ); - if( threadId < entitiesAlongY ) - { - //printf( "Y2: Thread %d -> %d %d \n ", threadId, coordinates.x(), coordinates.y() ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - break; - }*/ - - /*if( threadId < entitiesAlongX ) - { - GridEntity entity( *grid, - CoordinatesType( beginX + threadId, beginY ), - gridEntityParameters... ); - //printf( "X1: Thread %d -> %d %d x %d %d \n ", threadId, - // entity.getCoordinates().x(), entity.getCoordinates().y(), - // grid->getDimensions().x(), grid->getDimensions().y() ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - else if( ( threadId -= entitiesAlongX ) < entitiesAlongX && threadId >= 0 ) - { - GridEntity entity( *grid, - CoordinatesType( beginX + threadId, endY - 1 ), - gridEntityParameters... ); - entity.refresh(); - //printf( "X2: Thread %d -> %d %d \n ", threadId, entity.getCoordinates().x(), entity.getCoordinates().y() ); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - else if( ( ( threadId -= entitiesAlongX ) < entitiesAlongY - 1 ) && threadId >= 0 ) - { - GridEntity entity( *grid, - CoordinatesType( beginX, beginY + threadId + 1 ), - gridEntityParameters... ); - entity.refresh(); - //printf( "Y1: Thread %d -> %d %d \n ", threadId, entity.getCoordinates().x(), entity.getCoordinates().y() ); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - else if( ( ( threadId -= entitiesAlongY - 1 ) < entitiesAlongY - 1 ) && threadId >= 0 ) - { - GridEntity entity( *grid, - CoordinatesType( endX - 1, beginY + threadId + 1 ), - gridEntityParameters... ); - entity.refresh(); - //printf( "Y2: Thread %d -> %d %d \n ", threadId, entity.getCoordinates().x(), entity.getCoordinates().y() ); - EntitiesProcessor::processEntity( *grid, userData, entity ); - }*/ -} - -#endif // HAVE_CUDA - -template< typename Real, typename Index > -template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary, - int YOrthogonalBoundary, - typename... GridEntityParameters > -void -GridTraverser< Meshes::Grid< 2, Real, Devices::Cuda, Index > >::processEntities( - const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode, - const int& stream, - const GridEntityParameters&... gridEntityParameters ) -{ -#ifdef HAVE_CUDA - if( processOnlyBoundaryEntities && ( GridEntity::getEntityDimension() == 2 || GridEntity::getEntityDimension() == 0 ) ) { - #ifdef GRID_TRAVERSER_USE_STREAMS - dim3 cudaBlockSize( 256 ); - dim3 cudaBlocksCountAlongX, cudaGridsCountAlongX, cudaBlocksCountAlongY, cudaGridsCountAlongY; - Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongX, cudaGridsCountAlongX, end.x() - begin.x() ); - Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongY, cudaGridsCountAlongY, end.y() - begin.y() - 2 ); - - auto& pool = Cuda::StreamPool::getInstance(); - Pointers::synchronizeSmartPointersOnDevice< Devices::Cuda >(); - - const cudaStream_t& s1 = pool.getStream( stream ); - const cudaStream_t& s2 = pool.getStream( stream + 1 ); - dim3 gridIdx, cudaGridSize; - for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongX.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCountAlongX, cudaGridsCountAlongX, gridIdx, cudaGridSize ); - // Cuda::printThreadsSetup( cudaBlockSize, cudaBlocksCountAlongX, cudaGridSize, cudaGridsCountAlongX ); - GridTraverser2DBoundaryAlongX< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaGridSize, cudaBlockSize, 0, - s1 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.x(), - end.x(), - begin.y(), - gridIdx, - gridEntityParameters... ); - GridTraverser2DBoundaryAlongX< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaGridSize, cudaBlockSize, 0, - s2 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.x(), - end.x(), - end.y(), - gridIdx, - gridEntityParameters... ); - } - const cudaStream_t& s3 = pool.getStream( stream + 2 ); - const cudaStream_t& s4 = pool.getStream( stream + 3 ); - for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongY.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCountAlongY, cudaGridsCountAlongY, gridIdx, cudaGridSize ); - GridTraverser2DBoundaryAlongY< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaGridSize, cudaBlockSize, 0, - s3 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.y() + 1, - end.y() - 1, - begin.x(), - gridIdx, - gridEntityParameters... ); - GridTraverser2DBoundaryAlongY< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaGridSize, cudaBlockSize, 0, - s4 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.y() + 1, - end.y() - 1, - end.x(), - gridIdx, - gridEntityParameters... ); - } - cudaStreamSynchronize( s1 ); - cudaStreamSynchronize( s2 ); - cudaStreamSynchronize( s3 ); - cudaStreamSynchronize( s4 ); - #else // not defined GRID_TRAVERSER_USE_STREAMS - dim3 cudaBlockSize( 256 ); - dim3 cudaBlocksCount, cudaGridsCount; - const IndexType entitiesAlongX = end.x() - begin.x(); - const IndexType entitiesAlongY = end.x() - begin.x() - 2; - const IndexType maxFaceSize = max( entitiesAlongX, entitiesAlongY ); - const IndexType blocksPerFace = maxFaceSize / cudaBlockSize.x + ( maxFaceSize % cudaBlockSize.x != 0 ); - IndexType cudaThreadsCount = 4 * cudaBlockSize.x * blocksPerFace; - Cuda::setupThreads( cudaBlockSize, cudaBlocksCount, cudaGridsCount, cudaThreadsCount ); - // std::cerr << "blocksPerFace = " << blocksPerFace << "Threads count = " << cudaThreadsCount - // << "cudaBlockCount = " << cudaBlocksCount.x << std::endl; - dim3 gridIdx, cudaGridSize; - Pointers::synchronizeSmartPointersOnDevice< Devices::Cuda >(); - for( gridIdx.x = 0; gridIdx.x < cudaGridsCount.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCount, cudaGridsCount, gridIdx, cudaGridSize ); - // Cuda::printThreadsSetup( cudaBlockSize, cudaBlocksCountAlongX, cudaGridSize, cudaGridsCountAlongX ); - GridTraverser2DBoundary< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaGridSize, cudaBlockSize >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.x(), - end.x(), - begin.y(), - end.y(), - blocksPerFace, - gridIdx, - gridEntityParameters... ); - } - #endif // GRID_TRAVERSER_USE_STREAMS - // getchar(); - TNL_CHECK_CUDA_DEVICE; - } - else { - dim3 cudaBlockSize( 16, 16 ); - dim3 cudaBlocksCount, cudaGridsCount; - Cuda::setupThreads( cudaBlockSize, cudaBlocksCount, cudaGridsCount, end.x() - begin.x(), end.y() - begin.y() ); - - auto& pool = Cuda::StreamPool::getInstance(); - const cudaStream_t& s = pool.getStream( stream ); - - Pointers::synchronizeSmartPointersOnDevice< Devices::Cuda >(); - dim3 gridIdx, cudaGridSize; - for( gridIdx.y = 0; gridIdx.y < cudaGridsCount.y; gridIdx.y++ ) - for( gridIdx.x = 0; gridIdx.x < cudaGridsCount.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCount, cudaGridsCount, gridIdx, cudaGridSize ); - // Cuda::printThreadsSetup( cudaBlockSize, cudaBlocksCount, cudaGridSize, cudaGridsCount ); - GridTraverser2D< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaGridSize, cudaBlockSize, 0, - s >>>( - &gridPointer.template getData< Devices::Cuda >(), userData, begin, end, gridIdx, gridEntityParameters... ); - } - - #ifdef NDEBUG - if( mode == synchronousMode ) { - cudaStreamSynchronize( s ); - TNL_CHECK_CUDA_DEVICE; - } - #else - cudaStreamSynchronize( s ); - TNL_CHECK_CUDA_DEVICE; - #endif - } - -#else - throw Exceptions::CudaSupportMissing(); -#endif -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/GridTraverser_3D.hpp b/src/TNL/Meshes/GridDetails/GridTraverser_3D.hpp deleted file mode 100644 index 332360080a5afbf8559f9220760665dc1884c8fc..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/GridTraverser_3D.hpp +++ /dev/null @@ -1,463 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -/**** - * 3D traverser, host - */ -template< typename Real, typename Index > -template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary, - int YOrthogonalBoundary, - int ZOrthogonalBoundary, - typename... GridEntityParameters > -void -GridTraverser< Meshes::Grid< 3, Real, Devices::Host, Index > >::processEntities( - const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode, - const int& stream, - const GridEntityParameters&... gridEntityParameters ) -{ - if( processOnlyBoundaryEntities ) { - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - - if( ZOrthogonalBoundary ) - for( entity.getCoordinates().y() = begin.y(); entity.getCoordinates().y() < end.y(); entity.getCoordinates().y()++ ) - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) - { - entity.getCoordinates().z() = begin.z(); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - entity.getCoordinates().z() = end.z() - 1; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - if( YOrthogonalBoundary ) - for( entity.getCoordinates().z() = begin.z(); entity.getCoordinates().z() < end.z(); entity.getCoordinates().z()++ ) - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) - { - entity.getCoordinates().y() = begin.y(); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - entity.getCoordinates().y() = end.y() - 1; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - if( XOrthogonalBoundary ) - for( entity.getCoordinates().z() = begin.z(); entity.getCoordinates().z() < end.z(); entity.getCoordinates().z()++ ) - for( entity.getCoordinates().y() = begin.y(); entity.getCoordinates().y() < end.y(); entity.getCoordinates().y()++ ) - { - entity.getCoordinates().x() = begin.x(); - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - entity.getCoordinates().x() = end.x() - 1; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } - else { -#ifdef HAVE_OPENMP - if( Devices::Host::isOMPEnabled() ) { - #pragma omp parallel firstprivate( begin, end ) - { - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - #pragma omp for - // TODO: g++ 5.5 crashes when coding this loop without auxiliary x and y as bellow - for( IndexType z = begin.z(); z < end.z(); z++ ) - for( IndexType y = begin.y(); y < end.y(); y++ ) - for( IndexType x = begin.x(); x < end.x(); x++ ) { - entity.getCoordinates().x() = x; - entity.getCoordinates().y() = y; - entity.getCoordinates().z() = z; - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } - } - else { - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - for( entity.getCoordinates().z() = begin.z(); entity.getCoordinates().z() < end.z(); entity.getCoordinates().z()++ ) - for( entity.getCoordinates().y() = begin.y(); entity.getCoordinates().y() < end.y(); entity.getCoordinates().y()++ ) - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); - entity.getCoordinates().x()++ ) { - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } - } -#else - GridEntity entity( *gridPointer, begin, gridEntityParameters... ); - for( entity.getCoordinates().z() = begin.z(); entity.getCoordinates().z() < end.z(); entity.getCoordinates().z()++ ) - for( entity.getCoordinates().y() = begin.y(); entity.getCoordinates().y() < end.y(); entity.getCoordinates().y()++ ) - for( entity.getCoordinates().x() = begin.x(); entity.getCoordinates().x() < end.x(); entity.getCoordinates().x()++ ) - { - entity.refresh(); - EntitiesProcessor::processEntity( entity.getMesh(), userData, entity ); - } -#endif - } -} - -/**** - * 3D traverser, CUDA - */ -#ifdef HAVE_CUDA -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser3D( const Meshes::Grid< 3, Real, Devices::Cuda, Index >* grid, - UserData userData, - const typename GridEntity::CoordinatesType begin, - const typename GridEntity::CoordinatesType end, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = begin.x() + Cuda::getGlobalThreadIdx_x( gridIdx ); - coordinates.y() = begin.y() + Cuda::getGlobalThreadIdx_y( gridIdx ); - coordinates.z() = begin.z() + Cuda::getGlobalThreadIdx_z( gridIdx ); - - if( coordinates < end ) { - GridEntity entity( *grid, coordinates, gridEntityParameters... ); - entity.refresh(); - if( ! processOnlyBoundaryEntities || entity.isBoundaryEntity() ) { - EntitiesProcessor::processEntity( *grid, userData, entity ); - } - } -} - -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser3DBoundaryAlongXY( const Meshes::Grid< 3, Real, Devices::Cuda, Index >* grid, - UserData userData, - const Index beginX, - const Index endX, - const Index beginY, - const Index endY, - const Index fixedZ, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = beginX + Cuda::getGlobalThreadIdx_x( gridIdx ); - coordinates.y() = beginY + Cuda::getGlobalThreadIdx_y( gridIdx ); - coordinates.z() = fixedZ; - - if( coordinates.x() < endX && coordinates.y() < endY ) { - GridEntity entity( *grid, coordinates, gridEntityParameters... ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } -} - -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser3DBoundaryAlongXZ( const Meshes::Grid< 3, Real, Devices::Cuda, Index >* grid, - UserData userData, - const Index beginX, - const Index endX, - const Index beginZ, - const Index endZ, - const Index fixedY, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = beginX + Cuda::getGlobalThreadIdx_x( gridIdx ); - coordinates.y() = fixedY; - coordinates.z() = beginZ + Cuda::getGlobalThreadIdx_y( gridIdx ); - - if( coordinates.x() < endX && coordinates.z() < endZ ) { - GridEntity entity( *grid, coordinates, gridEntityParameters... ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } -} - -template< typename Real, - typename Index, - typename GridEntity, - typename UserData, - typename EntitiesProcessor, - bool processOnlyBoundaryEntities, - typename... GridEntityParameters > -__global__ -void -GridTraverser3DBoundaryAlongYZ( const Meshes::Grid< 3, Real, Devices::Cuda, Index >* grid, - UserData userData, - const Index beginY, - const Index endY, - const Index beginZ, - const Index endZ, - const Index fixedX, - const dim3 gridIdx, - const GridEntityParameters... gridEntityParameters ) -{ - typedef Meshes::Grid< 3, Real, Devices::Cuda, Index > GridType; - typename GridType::CoordinatesType coordinates; - - coordinates.x() = fixedX; - coordinates.y() = beginY + Cuda::getGlobalThreadIdx_x( gridIdx ); - coordinates.z() = beginZ + Cuda::getGlobalThreadIdx_y( gridIdx ); - - if( coordinates.y() < endY && coordinates.z() < endZ ) { - GridEntity entity( *grid, coordinates, gridEntityParameters... ); - entity.refresh(); - EntitiesProcessor::processEntity( *grid, userData, entity ); - } -} -#endif - -template< typename Real, typename Index > -template< typename GridEntity, - typename EntitiesProcessor, - typename UserData, - bool processOnlyBoundaryEntities, - int XOrthogonalBoundary, - int YOrthogonalBoundary, - int ZOrthogonalBoundary, - typename... GridEntityParameters > -void -GridTraverser< Meshes::Grid< 3, Real, Devices::Cuda, Index > >::processEntities( - const GridPointer& gridPointer, - const CoordinatesType& begin, - const CoordinatesType& end, - UserData& userData, - GridTraverserMode mode, - const int& stream, - const GridEntityParameters&... gridEntityParameters ) -{ -#ifdef HAVE_CUDA - if( processOnlyBoundaryEntities && ( GridEntity::getEntityDimension() == 3 || GridEntity::getEntityDimension() == 0 ) ) { - dim3 cudaBlockSize( 16, 16 ); - const IndexType entitiesAlongX = end.x() - begin.x(); - const IndexType entitiesAlongY = end.y() - begin.y(); - const IndexType entitiesAlongZ = end.z() - begin.z(); - - dim3 cudaBlocksCountAlongXY, cudaBlocksCountAlongXZ, cudaBlocksCountAlongYZ, cudaGridsCountAlongXY, cudaGridsCountAlongXZ, - cudaGridsCountAlongYZ; - - Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongXY, cudaGridsCountAlongXY, entitiesAlongX, entitiesAlongY ); - Cuda::setupThreads( cudaBlockSize, cudaBlocksCountAlongXZ, cudaGridsCountAlongXZ, entitiesAlongX, entitiesAlongZ - 2 ); - Cuda::setupThreads( - cudaBlockSize, cudaBlocksCountAlongYZ, cudaGridsCountAlongYZ, entitiesAlongY - 2, entitiesAlongZ - 2 ); - - auto& pool = Cuda::StreamPool::getInstance(); - Pointers::synchronizeSmartPointersOnDevice< Devices::Cuda >(); - - const cudaStream_t& s1 = pool.getStream( stream ); - const cudaStream_t& s2 = pool.getStream( stream + 1 ); - const cudaStream_t& s3 = pool.getStream( stream + 2 ); - const cudaStream_t& s4 = pool.getStream( stream + 3 ); - const cudaStream_t& s5 = pool.getStream( stream + 4 ); - const cudaStream_t& s6 = pool.getStream( stream + 5 ); - - dim3 gridIdx, gridSize; - for( gridIdx.y = 0; gridIdx.y < cudaGridsCountAlongXY.y; gridIdx.y++ ) - for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongXY.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCountAlongXY, cudaGridsCountAlongXY, gridIdx, gridSize ); - GridTraverser3DBoundaryAlongXY< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaBlocksCountAlongXY, cudaBlockSize, 0, - s1 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.x(), - end.x(), - begin.y(), - end.y(), - begin.z(), - gridIdx, - gridEntityParameters... ); - GridTraverser3DBoundaryAlongXY< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaBlocksCountAlongXY, cudaBlockSize, 0, - s2 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.x(), - end.x(), - begin.y(), - end.y(), - end.z(), - gridIdx, - gridEntityParameters... ); - } - for( gridIdx.y = 0; gridIdx.y < cudaGridsCountAlongXZ.y; gridIdx.y++ ) - for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongXZ.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCountAlongXZ, cudaGridsCountAlongXZ, gridIdx, gridSize ); - GridTraverser3DBoundaryAlongXZ< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaBlocksCountAlongXZ, cudaBlockSize, 0, - s3 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.x(), - end.x(), - begin.z() + 1, - end.z() - 1, - begin.y(), - gridIdx, - gridEntityParameters... ); - GridTraverser3DBoundaryAlongXZ< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaBlocksCountAlongXZ, cudaBlockSize, 0, - s4 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.x(), - end.x(), - begin.z() + 1, - end.z() - 1, - end.y(), - gridIdx, - gridEntityParameters... ); - } - for( gridIdx.y = 0; gridIdx.y < cudaGridsCountAlongYZ.y; gridIdx.y++ ) - for( gridIdx.x = 0; gridIdx.x < cudaGridsCountAlongYZ.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCountAlongYZ, cudaGridsCountAlongYZ, gridIdx, gridSize ); - GridTraverser3DBoundaryAlongYZ< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaBlocksCountAlongYZ, cudaBlockSize, 0, - s5 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.y() + 1, - end.y() - 1, - begin.z() + 1, - end.z() - 1, - begin.x(), - gridIdx, - gridEntityParameters... ); - GridTraverser3DBoundaryAlongYZ< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< cudaBlocksCountAlongYZ, cudaBlockSize, 0, - s6 >>>( &gridPointer.template getData< Devices::Cuda >(), - userData, - begin.y() + 1, - end.y() - 1, - begin.z() + 1, - end.z() - 1, - end.x(), - gridIdx, - gridEntityParameters... ); - } - cudaStreamSynchronize( s1 ); - cudaStreamSynchronize( s2 ); - cudaStreamSynchronize( s3 ); - cudaStreamSynchronize( s4 ); - cudaStreamSynchronize( s5 ); - cudaStreamSynchronize( s6 ); - TNL_CHECK_CUDA_DEVICE; - } - else { - dim3 cudaBlockSize( 8, 8, 8 ); - dim3 cudaBlocksCount, cudaGridsCount; - - Cuda::setupThreads( - cudaBlockSize, cudaBlocksCount, cudaGridsCount, end.x() - begin.x(), end.y() - begin.y(), end.z() - begin.z() ); - - auto& pool = Cuda::StreamPool::getInstance(); - const cudaStream_t& s = pool.getStream( stream ); - - Pointers::synchronizeSmartPointersOnDevice< Devices::Cuda >(); - dim3 gridIdx, gridSize; - for( gridIdx.z = 0; gridIdx.z < cudaGridsCount.z; gridIdx.z++ ) - for( gridIdx.y = 0; gridIdx.y < cudaGridsCount.y; gridIdx.y++ ) - for( gridIdx.x = 0; gridIdx.x < cudaGridsCount.x; gridIdx.x++ ) { - Cuda::setupGrid( cudaBlocksCount, cudaGridsCount, gridIdx, gridSize ); - GridTraverser3D< Real, - Index, - GridEntity, - UserData, - EntitiesProcessor, - processOnlyBoundaryEntities, - GridEntityParameters... > - <<< gridSize, cudaBlockSize, 0, - s >>>( - &gridPointer.template getData< Devices::Cuda >(), userData, begin, end, gridIdx, gridEntityParameters... ); - } - - // only launches into the stream 0 are synchronized - if( stream == 0 ) { - cudaStreamSynchronize( s ); - TNL_CHECK_CUDA_DEVICE; - } - } -#else - throw Exceptions::CudaSupportMissing(); -#endif -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/BoundaryGridEntityChecker.hpp b/src/TNL/Meshes/GridDetails/Implementations/BoundaryGridEntityChecker.hpp new file mode 100644 index 0000000000000000000000000000000000000000..fbf1cd8241559a04284566d4801c2f394381b3b8 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/BoundaryGridEntityChecker.hpp @@ -0,0 +1,141 @@ +/*************************************************************************** + BoundaryGridEntityChecker.h - description + ------------------- + begin : Dec 2, 2015 + copyright : (C) 2015 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include + +namespace TNL { +namespace Meshes { + +/*** + * 1D grids + */ +template +class BoundaryGridEntityChecker, 1>> { + public: + using Entity = GridEntity, 1>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return (entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1); + } +}; + +template +class BoundaryGridEntityChecker, 0>> { + public: + using Entity = GridEntity, 0>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return (entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x()); + } +}; + +/**** + * 2D grids + */ +template +class BoundaryGridEntityChecker, 2>> { + public: + using Entity = GridEntity, 2>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return (entity.getCoordinates().x() == 0 || + entity.getCoordinates().y() == 0 || + entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 || + entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1); + } +}; + +template +class BoundaryGridEntityChecker, 1>> { + public: + using Entity = GridEntity, 1>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return ((entity.getBasis().x() && (entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x())) || + (entity.getBasis().y() && (entity.getCoordinates().y() == 0 || entity.getCoordinates().y() == entity.getMesh().getDimensions().y()))); + } +}; + +template +class BoundaryGridEntityChecker, 0>> { + public: + using Entity = GridEntity, 0>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return (entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x()) || + (entity.getCoordinates().y() == 0 || entity.getCoordinates().y() == entity.getMesh().getDimensions().y()); + } +}; + +/*** + * 3D grid + */ +template +class BoundaryGridEntityChecker, 3>> { + public: + using Entity = GridEntity, 3>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return (entity.getCoordinates().x() == 0 || entity.getCoordinates().y() == 0 || entity.getCoordinates().z() == 0 || + entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 || + entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 || + entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1); + } +}; + +template +class BoundaryGridEntityChecker, 2>> { + public: + using Entity = GridEntity, 2>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return ((entity.getBasis().x() && (entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x())) || + (entity.getBasis().y() && (entity.getCoordinates().y() == 0 || entity.getCoordinates().y() == entity.getMesh().getDimensions().y())) || + (entity.getBasis().z() && (entity.getCoordinates().z() == 0 || entity.getCoordinates().z() == entity.getMesh().getDimensions().z()))); + } +}; + +template +class BoundaryGridEntityChecker, 1>> { + public: + using Entity = GridEntity, 1>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return ((entity.getBasis().x() && (entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x())) || + (entity.getBasis().y() && (entity.getCoordinates().y() == 0 || entity.getCoordinates().y() == entity.getMesh().getDimensions().y())) || + (entity.getBasis().z() && (entity.getCoordinates().z() == 0 || entity.getCoordinates().z() == entity.getMesh().getDimensions().z()))); + } +}; + +template +class BoundaryGridEntityChecker, 0>> { + public: + using Entity = GridEntity, 0>; + + __cuda_callable__ inline + static bool isBoundaryEntity(const Entity& entity) { + return (entity.getCoordinates().x() == 0 || entity.getCoordinates().x() == entity.getMesh().getDimensions().x()) || + (entity.getCoordinates().y() == 0 || entity.getCoordinates().y() == entity.getMesh().getDimensions().y()) || + (entity.getCoordinates().z() == 0 || entity.getCoordinates().z() == entity.getMesh().getDimensions().z()); + } +}; + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/Grid1D.hpp b/src/TNL/Meshes/GridDetails/Implementations/Grid1D.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0ac356210c5043e4a1b207f6507ed56df88daf4e --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/Grid1D.hpp @@ -0,0 +1,150 @@ +// Copyright (c) 2004-2022 Tomáš Oberhuber et al. +// +// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include + +namespace TNL { +namespace Meshes { + +#define __GRID_1D_TEMPLATE__ template +#define __GRID_1D_PREFIX__ Grid<1, Real, Device, Index> + +__GRID_1D_TEMPLATE__ +__GRID_1D_PREFIX__::Grid() { + this->setDimensions(0); +} + +__GRID_1D_TEMPLATE__ +__GRID_1D_PREFIX__::Grid(const Index xSize) { + this->setDimensions(xSize); +} + +__GRID_1D_TEMPLATE__ +template +__cuda_callable__ inline Index __GRID_1D_PREFIX__::getEntityIndex(const Entity &entity) const { + static_assert(Templates::isInClosedInterval(0, Entity::entityDimension, 1), "Wrong grid entity dimensions."); + + return GridEntityGetter::getEntityIndex(*this, entity); +} + +__GRID_1D_TEMPLATE__ +template +inline +void __GRID_1D_PREFIX__::forAll(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__ (const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid &grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + entity.refresh(); + + func(entity, args...); + }; + + this -> template traverseAll(exec, *this, args...); +} + +__GRID_1D_TEMPLATE__ +template +inline +void __GRID_1D_PREFIX__::forAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__ (const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid &grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + entity.refresh(); + + func(entity, args...); + }; + + this -> template traverseAll(from, to, exec, *this, args...); +} + +__GRID_1D_TEMPLATE__ +template +inline +void __GRID_1D_PREFIX__::forBoundary(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseBoundary(exec, *this, args...); +} + +__GRID_1D_TEMPLATE__ +template +inline +void __GRID_1D_PREFIX__::forBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseBoundary(from, to, exec, *this, args...); +} + +__GRID_1D_TEMPLATE__ +template +inline +void __GRID_1D_PREFIX__::forInterior(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__ (const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid &grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this -> template traverseInterior(exec, *this, args...); +} + +__GRID_1D_TEMPLATE__ +template +inline +void __GRID_1D_PREFIX__::forInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseInterior(from, to, exec, *this, args...); +} + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/Grid2D.hpp b/src/TNL/Meshes/GridDetails/Implementations/Grid2D.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0dc0d16b26ca358c469b8dcbb38b4cfbe4313a9d --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/Grid2D.hpp @@ -0,0 +1,152 @@ +// Copyright (c) 2004-2022 Tomáš Oberhuber et al. +// +// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include + +namespace TNL { +namespace Meshes { + +#define __GRID_2D_TEMPLATE__ template +#define __GRID_2D_PREFIX__ Grid<2, Real, Device, Index> + +__GRID_2D_TEMPLATE__ +__GRID_2D_PREFIX__::Grid() { + this->setDimensions(0, 0); +} + +__GRID_2D_TEMPLATE__ +__GRID_2D_PREFIX__::Grid(const Index xSize, const Index ySize) { + this->setDimensions(xSize, ySize); +} + +__GRID_2D_TEMPLATE__ +template +__cuda_callable__ inline Index __GRID_2D_PREFIX__::getEntityIndex(const Entity& entity) const { + static_assert(Entity::entityDimension <= 2 && Entity::entityDimension >= 0, "Wrong grid entity dimensions."); + + return GridEntityGetter::getEntityIndex(*this, entity); +} + +__GRID_2D_TEMPLATE__ +template +inline +void __GRID_2D_PREFIX__::forAll(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__ (const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid &grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this -> template traverseAll(exec, *this, args...); +} + +__GRID_2D_TEMPLATE__ +template +inline +void __GRID_2D_PREFIX__::forAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__ (const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid &grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + entity.refresh(); + + func(entity, args...); + }; + + this -> template traverseAll(from, to, exec, *this, args...); +} + +__GRID_2D_TEMPLATE__ +template +inline +void __GRID_2D_PREFIX__::forInterior(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__ (const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid &grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this -> template traverseInterior(exec, *this, args...); +} + + +__GRID_2D_TEMPLATE__ +template +inline +void __GRID_2D_PREFIX__::forInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseInterior(from, to, exec, *this, args...); +} + +__GRID_2D_TEMPLATE__ +template +inline +void __GRID_2D_PREFIX__::forBoundary(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseBoundary(exec, *this, args...); +} + +__GRID_2D_TEMPLATE__ +template +inline +void __GRID_2D_PREFIX__::forBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseBoundary(from, to, exec, *this, args...); +} + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/Grid3D.hpp b/src/TNL/Meshes/GridDetails/Implementations/Grid3D.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d35a6fb11064725e5ccd42f67bdb42980deb6b05 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/Grid3D.hpp @@ -0,0 +1,152 @@ +/*************************************************************************** + Grid3D_impl.h - description + ------------------- + begin : Jan 16, 2013 + copyright : (C) 2013 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include +#include +#include + +namespace TNL { +namespace Meshes { + +#define __GRID_3D_TEMPLATE__ template +#define __GRID_3D_PREFIX__ Grid<3, Real, Device, Index> + +__GRID_3D_TEMPLATE__ +__GRID_3D_PREFIX__::Grid() { this->setDimensions(0, 0, 0); } + +__GRID_3D_TEMPLATE__ +__GRID_3D_PREFIX__::Grid(const Index xSize, const Index ySize, const Index zSize) { + this->setDimensions(xSize, ySize, zSize); +} + +__GRID_3D_TEMPLATE__ +template +__cuda_callable__ inline Index __GRID_3D_PREFIX__::getEntityIndex(const Entity& entity) const { + static_assert(Entity::entityDimension <= 3 && Entity::entityDimension >= 0, "Wrong grid entity dimensions."); + + return GridEntityGetter::getEntityIndex(*this, entity); +} + +__GRID_3D_TEMPLATE__ +template +inline void __GRID_3D_PREFIX__::forAll(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseAll(exec, *this, args...); +} + +__GRID_3D_TEMPLATE__ +template +inline +void __GRID_3D_PREFIX__::forAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__ (const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid &grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + entity.refresh(); + + func(entity, args...); + }; + + this -> template traverseAll(from, to, exec, *this, args...); +} + +__GRID_3D_TEMPLATE__ +template +inline void __GRID_3D_PREFIX__::forInterior(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseInterior(exec, *this, args...); +} + +__GRID_3D_TEMPLATE__ +template +inline +void __GRID_3D_PREFIX__::forInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseInterior(from, to, exec, *this, args...); +} + + +__GRID_3D_TEMPLATE__ +template +inline void __GRID_3D_PREFIX__::forBoundary(Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseBoundary(exec, *this, args...); +} + +__GRID_3D_TEMPLATE__ +template +inline +void __GRID_3D_PREFIX__::forBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + auto exec = [=] __cuda_callable__(const Coordinate& coordinate, + const Coordinate& basis, + const Index orientation, + const Grid& grid, + FuncArgs... args) mutable { + EntityType entity(grid, coordinate, basis, orientation); + + entity.refresh(); + + func(entity, args...); + }; + + this->template traverseBoundary(from, to, exec, *this, args...); +} + + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/GridEntity.hpp b/src/TNL/Meshes/GridDetails/Implementations/GridEntity.hpp new file mode 100644 index 0000000000000000000000000000000000000000..df9f0ad3eb75dc65cdfbd1d0f43d296118925406 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/GridEntity.hpp @@ -0,0 +1,139 @@ +// Copyright (c) 2004-2022 Tomáš Oberhuber et al. +// +// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include +#include +#include + +namespace TNL { +namespace Meshes { + +#define __GRID_ENTITY_TEMPLATE__ template +#define __GRID_ENTITY_PREFIX__ GridEntity + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +const typename __GRID_ENTITY_PREFIX__::Coordinate& __GRID_ENTITY_PREFIX__::getCoordinates() const { + return this -> coordinates; +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +typename __GRID_ENTITY_PREFIX__::Coordinate& __GRID_ENTITY_PREFIX__::getCoordinates() { + return this -> coordinates; +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +void __GRID_ENTITY_PREFIX__::setCoordinates(const Coordinate& coordinates) { + this -> coordinates = coordinates; +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +void __GRID_ENTITY_PREFIX__::refresh() { + this -> index = this -> grid.getEntityIndex( *this ); +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +typename __GRID_ENTITY_PREFIX__::Index __GRID_ENTITY_PREFIX__::getIndex() const { + TNL_ASSERT_GE( this->index, 0, "Entity index is not non-negative." ); + TNL_ASSERT_LT( this->index, grid.template getEntitiesCount(), "Entity index is out of bounds." ); + TNL_ASSERT_EQ( this->index, grid.getEntityIndex( *this ), "Wrong value of stored index." ); + + return this->index; +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +bool __GRID_ENTITY_PREFIX__::isBoundary() const { + return BoundaryGridEntityChecker::isBoundaryEntity(*this); +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +const typename __GRID_ENTITY_PREFIX__::Point __GRID_ENTITY_PREFIX__::getCenter() const { + return GridEntityCenterGetter::getEntityCenter(*this); +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +typename __GRID_ENTITY_PREFIX__::Real __GRID_ENTITY_PREFIX__::getMeasure() const { + return GridEntityMeasureGetter::getMeasure(this->getMesh(), *this); +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +const Grid& __GRID_ENTITY_PREFIX__::getMesh() const { + return this -> grid; +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +const typename __GRID_ENTITY_PREFIX__::Coordinate& __GRID_ENTITY_PREFIX__::getBasis() const { + return this -> basis; +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +void __GRID_ENTITY_PREFIX__::setBasis(const Coordinate& basis) { + this -> basis = basis; +} + +__GRID_ENTITY_TEMPLATE__ +__cuda_callable__ inline +typename __GRID_ENTITY_PREFIX__::Index __GRID_ENTITY_PREFIX__::getOrientation() const { + return this -> orientation; +} + +__GRID_ENTITY_TEMPLATE__ +template> +__cuda_callable__ inline +GridEntity __GRID_ENTITY_PREFIX__::getNeighbourEntity() const { + using Getter = NeighbourGridEntityGetter; + + return Getter::template getEntity(*this); +} + +__GRID_ENTITY_TEMPLATE__ +template> +__cuda_callable__ inline +GridEntity __GRID_ENTITY_PREFIX__::getNeighbourEntity() const { + using Getter = NeighbourGridEntityGetter; + + return Getter::template getEntity(*this); +} + +__GRID_ENTITY_TEMPLATE__ +template +__cuda_callable__ inline +GridEntity __GRID_ENTITY_PREFIX__::getNeighbourEntity(const Coordinate& offset) const { + using Getter = NeighbourGridEntityGetter; + + return Getter::template getEntity(*this, offset); +} + +__GRID_ENTITY_TEMPLATE__ +template +__cuda_callable__ inline +GridEntity __GRID_ENTITY_PREFIX__::getNeighbourEntity(const Coordinate& offset) const { + using Getter = NeighbourGridEntityGetter; + + return Getter::template getEntity(*this, offset); +} + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/GridEntityCenterGetter.hpp b/src/TNL/Meshes/GridDetails/Implementations/GridEntityCenterGetter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..27ef0be99f020ae557336b96d9ec66ff64123146 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/GridEntityCenterGetter.hpp @@ -0,0 +1,139 @@ + +#pragma once + +#include + +namespace TNL { +namespace Meshes { +/*** + * 1D grids + */ +template +class GridEntityCenterGetter, 1> > { + public: + using Grid = Meshes::Grid<1, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + (entity.getCoordinates().x() + 0.5) * grid.getSpaceSteps().x()); + } +}; + +template +class GridEntityCenterGetter, 0>> { + public: + using Grid = Meshes::Grid<1, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + (entity.getCoordinates().x()) * grid.getSpaceSteps().x()); + } +}; + +/**** + * 2D grids + */ +template +class GridEntityCenterGetter, 2>> { + public: + using Grid = Meshes::Grid<2, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + (entity.getCoordinates().x() + 0.5) * grid.getSpaceSteps().x(), + grid.getOrigin().y() + (entity.getCoordinates().y() + 0.5) * grid.getSpaceSteps().y()); + } +}; + +template +class GridEntityCenterGetter, 1> > { + public: + using Grid = Meshes::Grid<2, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + (entity.getCoordinates().x() + 0.5 * !entity.getBasis().x()) * grid.getSpaceSteps().x(), + grid.getOrigin().y() + (entity.getCoordinates().y() + 0.5 * !entity.getBasis().y()) * grid.getSpaceSteps().y()); + } +}; + +template +class GridEntityCenterGetter, 0>> { + public: + using Grid = Meshes::Grid<2, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + entity.getCoordinates().x() * grid.getSpaceSteps().x(), + grid.getOrigin().y() + entity.getCoordinates().y() * grid.getSpaceSteps().y()); + } +}; + +/*** + * 3D grid + */ +template +class GridEntityCenterGetter, EntityDimension>> { + public: + using Grid = Meshes::Grid<3, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + (entity.getCoordinates().x() + 0.5 * !entity.getBasis().x()) * grid.getSpaceSteps().x(), + grid.getOrigin().y() + (entity.getCoordinates().y() + 0.5 * !entity.getBasis().y()) * grid.getSpaceSteps().y(), + grid.getOrigin().z() + (entity.getCoordinates().z() + 0.5 * !entity.getBasis().z()) * grid.getSpaceSteps().z()); + } +}; + +template +class GridEntityCenterGetter, 3>> { + public: + using Grid = Meshes::Grid<3, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + (entity.getCoordinates().x() + 0.5) * grid.getSpaceSteps().x(), + grid.getOrigin().y() + (entity.getCoordinates().y() + 0.5) * grid.getSpaceSteps().y(), + grid.getOrigin().z() + (entity.getCoordinates().z() + 0.5) * grid.getSpaceSteps().z()); + } +}; + +template +class GridEntityCenterGetter, 0>> { + public: + using Grid = Meshes::Grid<3, Real, Device, Index>; + using Entity = GridEntity; + using Point = typename Grid::Point; + + __cuda_callable__ inline + static Point getEntityCenter(const Entity& entity) { + const Grid& grid = entity.getMesh(); + return Point(grid.getOrigin().x() + (entity.getCoordinates().x()) * grid.getSpaceSteps().x(), + grid.getOrigin().y() + (entity.getCoordinates().y()) * grid.getSpaceSteps().y(), + grid.getOrigin().z() + (entity.getCoordinates().z()) * grid.getSpaceSteps().z()); + } +}; + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/GridEntityGetter.hpp b/src/TNL/Meshes/GridDetails/Implementations/GridEntityGetter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..09678e62bcb233c27963b00fc48c4ffe83409200 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/GridEntityGetter.hpp @@ -0,0 +1,201 @@ + +#pragma once + +#include + +namespace TNL { +namespace Meshes { + +/**** + * 1D grid + */ +template +class GridEntityGetter, EntityDimension> { + public: + static constexpr int entityDimension = EntityDimension; + + using Grid = Meshes::Grid<1, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + return entity.getCoordinates().x(); + } +}; + +/**** + * 2D grid + */ +template +class GridEntityGetter, 2> { + public: + static constexpr int entityDimension = 2; + + using Grid = Meshes::Grid<2, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0, 0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + return entity.getCoordinates().y() * grid.getDimensions().x() + entity.getCoordinates().x(); + } +}; + +template +class GridEntityGetter, 1> { + public: + static constexpr int entityDimension = 1; + + using Grid = Meshes::Grid<2, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0, 0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + const Coordinate& coordinates = entity.getCoordinates(); + const Coordinate& dimensions = grid.getDimensions(); + + if (entity.getOrientation() == 0) + return coordinates.y() * (dimensions.x()) + coordinates.x(); + + return grid.template getOrientedEntitiesCount<1, 0>() + coordinates.y() * (dimensions.x() + 1) + coordinates.x(); + } +}; + +template +class GridEntityGetter, 0> { + public: + static constexpr int entityDimension = 0; + + using Grid = Meshes::Grid<2, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0, 0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + const Coordinate& coordinates = entity.getCoordinates(); + const Coordinate& dimensions = grid.getDimensions(); + + return coordinates.y() * (dimensions.x() + 1) + coordinates.x(); + } +}; + +/**** + * 3D grid + */ +template +class GridEntityGetter, 3> { + public: + static constexpr int entityDimension = 3; + + using Grid = Meshes::Grid<3, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0, 0, 0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + const Coordinate coordinates = entity.getCoordinates(); + const Coordinate dimensions = grid.getDimensions(); + + return (coordinates.z() * dimensions.y() + coordinates.y()) * dimensions.x() + coordinates.x(); + } +}; + +template +class GridEntityGetter, 2> { + public: + static constexpr int entityDimension = 2; + + using Grid = Meshes::Grid<3, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0, 0, 0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + const Coordinate& coordinates = entity.getCoordinates(); + const Coordinate& dimensions = grid.getDimensions(); + + if (entity.getOrientation() == 0) + return (coordinates.z() * dimensions.y() + coordinates.y()) * (dimensions.x()) + coordinates.x(); + + if (entity.getOrientation() == 1) + return grid.template getOrientedEntitiesCount<2, 0>() + (coordinates.z() * (dimensions.y() + 1) + coordinates.y()) * dimensions.x() + coordinates.x(); + + return grid.template getOrientedEntitiesCount<2, 1>() + + grid.template getOrientedEntitiesCount<2, 0>() + + (coordinates.z() * dimensions.y() + coordinates.y()) * (dimensions.x() + 1) + coordinates.x(); + } +}; + +template +class GridEntityGetter, 1> { + public: + static constexpr int entityDimension = 1; + + using Grid = Meshes::Grid<3, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0, 0, 0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + const Coordinate& coordinates = entity.getCoordinates(); + const Coordinate& dimensions = grid.getDimensions(); + + if (entity.getOrientation() == 0) + return (coordinates.z() * (dimensions.y() + 1) + coordinates.y()) * dimensions.x() + coordinates.x(); + + if (entity.getOrientation() == 1) + return grid.template getOrientedEntitiesCount<1, 0>() + (coordinates.z() * dimensions.y() + coordinates.y()) * (dimensions.x() + 1) + coordinates.x(); + + return grid.template getOrientedEntitiesCount<1, 1>() + + grid.template getOrientedEntitiesCount<1, 0>() + + (coordinates.z() * (dimensions.y() + 1) + coordinates.y()) * (dimensions.x() + 1) + coordinates.x(); + } +}; + +template +class GridEntityGetter, 0> { + public: + static constexpr int entityDimension = 0; + + using Grid = Meshes::Grid<3, Real, Device, Index>; + using Entity = GridEntity; + using Coordinate = typename Grid::Coordinate; + + __cuda_callable__ inline + static Index getEntityIndex(const Grid& grid, const Entity& entity) { + TNL_ASSERT_GE(entity.getCoordinates(), Coordinate(0, 0, 0), "wrong coordinates"); + TNL_ASSERT_LT(entity.getCoordinates(), grid.getDimensions() + entity.getBasis(), "wrong coordinates"); + + const Coordinate coordinates = entity.getCoordinates(); + const Coordinate dimensions = grid.getDimensions(); + + return (coordinates.z() * (dimensions.y() + 1) + coordinates.y()) * (dimensions.x() + 1) + coordinates.x(); + } +}; + + +} +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/GridEntityMeasureGetter.hpp b/src/TNL/Meshes/GridDetails/Implementations/GridEntityMeasureGetter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6239c5ee6f143ea30b7dec30d46c9f3e5377ca06 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/GridEntityMeasureGetter.hpp @@ -0,0 +1,115 @@ + +#pragma once + +#include + +namespace TNL { +namespace Meshes { + +/*** + * Common implementation for vertices + */ +template +class GridEntityMeasureGetter, 0> { + public: + using GridType = Grid; + + template + __cuda_callable__ inline static Real getMeasure(const GridType& grid, const EntityType& entity) { + return 0.0; + } +}; + +/**** + * 1D grid + */ + +template +class GridEntityMeasureGetter, 1> { + public: + using GridType = Grid<1, Real, Device, Index>; + + template + __cuda_callable__ inline static Real getMeasure(const GridType& grid, const EntityType& entity) { + return grid.template getSpaceStepsProducts<1>(); + } +}; + +/**** + * 2D grid + */ +template +class GridEntityMeasureGetter, 2> { + public: + using GridType = Grid<2, Real, Device, Index>; + + template + __cuda_callable__ inline static Real getMeasure(const GridType& grid, const EntityType& entity) { + return grid.template getSpaceStepsProducts<1, 1>(); + } +}; + +template +class GridEntityMeasureGetter, 1> { + public: + using GridType = Grid<2, Real, Device, Index>; + + template + __cuda_callable__ inline static Real getMeasure(const GridType& grid, const EntityType& entity) { + if (entity.getOrientation() == 0) + return grid.template getSpaceStepsProducts<1, 0>(); + + return grid.template getSpaceStepsProducts<0, 1>(); + } +}; + +/**** + * 3D grid + */ +template +class GridEntityMeasureGetter, 3> { + public: + using GridType = Grid<3, Real, Device, Index>; + + template + __cuda_callable__ inline static Real getMeasure(const GridType& grid, const EntityType& entity) { + return grid.template getSpaceStepsProducts<1, 1, 1>(); + } +}; + +template +class GridEntityMeasureGetter, 2> { + public: + using GridType = Grid<3, Real, Device, Index>; + + template + __cuda_callable__ inline static Real getMeasure(const GridType& grid, const EntityType& entity) { + if (entity.getOrientation() == 0) + return grid.template getSpaceStepsProducts<1, 1, 0>(); + + if (entity.getOrientation() == 1) + return grid.template getSpaceStepsProducts<1, 0, 1>(); + + return grid.template getSpaceStepsProducts<0, 1, 1>(); + } +}; + +template +class GridEntityMeasureGetter, 1> { + public: + using GridType = Grid<3, Real, Device, Index>; + + template + __cuda_callable__ inline static Real getMeasure(const GridType& grid, const EntityType& entity) { + if (entity.getOrientation() == 0) + return grid.template getSpaceStepsProducts<1, 0, 0>(); + + if (entity.getOrientation() == 1) + return grid.template getSpaceStepsProducts<0, 1, 0>(); + + return grid.template getSpaceStepsProducts<0, 0, 1>(); + } +}; + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/NDimGrid.hpp b/src/TNL/Meshes/GridDetails/Implementations/NDimGrid.hpp new file mode 100644 index 0000000000000000000000000000000000000000..375faf553724a4f6d8d8a07aaa072fcca4c899d1 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/NDimGrid.hpp @@ -0,0 +1,537 @@ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace TNL { +namespace Meshes { + +#define __NDIMGRID_TEMPLATE__ template +#define __NDIM_PREFIX__ NDimGrid + +__NDIMGRID_TEMPLATE__ +constexpr Index __NDIM_PREFIX__::getEntityOrientationsCount(const Index entityDimension) { + return Templates::combination(entityDimension, Dimension); +} + +__NDIMGRID_TEMPLATE__ +template ...>, bool>, + std::enable_if_t> +void __NDIM_PREFIX__::setDimensions(Dimensions... dimensions) { + this->dimensions = Coordinate(dimensions...); + + TNL_ASSERT_GE(this -> dimensions, Coordinate(0), "Dimension must be positive"); + + fillEntitiesCount(); + fillSpaceSteps(); +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::setDimensions(const typename __NDIM_PREFIX__::Coordinate &dimensions) { + this -> dimensions = dimensions; + + TNL_ASSERT_GE(this -> dimensions, Coordinate(0), "Dimension must be positive"); + + fillEntitiesCount(); + fillSpaceSteps(); +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline Index __NDIM_PREFIX__::getDimension(const Index index) const { + TNL_ASSERT_GE(index, 0, "Index must be greater or equal to zero"); + TNL_ASSERT_LT(index, Dimension, "Index must be less than Dimension"); + + return dimensions[index]; +} + +__NDIMGRID_TEMPLATE__ +template ...>, bool>, + std::enable_if_t<(sizeof...(DimensionIndex) > 0), bool>> +__cuda_callable__ inline __NDIM_PREFIX__::Container __NDIM_PREFIX__::getDimensions( + DimensionIndex... indices) const noexcept { + Container result{indices...}; + + for (std::size_t i = 0; i < sizeof...(DimensionIndex); i++) + result[i] = this->getDimension(result[i]); + + return result; +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline const typename __NDIM_PREFIX__::Container &__NDIM_PREFIX__::getDimensions() const noexcept { + return this->dimensions; +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline Index __NDIM_PREFIX__::getEntitiesCount(const Index index) const { + TNL_ASSERT_GE(index, 0, "Index must be greater than zero"); + TNL_ASSERT_LE(index, Dimension, "Index must be less than or equal to Dimension"); + + return this->cumulativeEntitiesCountAlongBases(index); +} + +__NDIMGRID_TEMPLATE__ +template > +__cuda_callable__ inline Index __NDIM_PREFIX__::getEntitiesCount() const noexcept { + return this->cumulativeEntitiesCountAlongBases(EntityDimension); +} + +__NDIMGRID_TEMPLATE__ +template ...>, bool>, + std::enable_if_t<(sizeof...(DimensionIndex) > 0), bool>> +__cuda_callable__ inline __NDIM_PREFIX__::Container __NDIM_PREFIX__::getEntitiesCounts( + DimensionIndex... indices) const { + Container result{indices...}; + + for (std::size_t i = 0; i < sizeof...(DimensionIndex); i++) + result[i] = this->cumulativeEntitiesCountAlongBases(result[i]); + + return result; +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline const typename __NDIM_PREFIX__::EntitiesCounts& __NDIM_PREFIX__::getEntitiesCounts() const noexcept { + return this->cumulativeEntitiesCountAlongBases; +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::setOrigin(const typename __NDIM_PREFIX__::Point &origin) noexcept { this->origin = origin; } + +__NDIMGRID_TEMPLATE__ +template ...>, bool>, + std::enable_if_t> +void __NDIM_PREFIX__::setOrigin(Coordinates... coordinates) noexcept { + this->origin = Point(coordinates...); +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline +Index __NDIM_PREFIX__::getOrientedEntitiesCount(const Index dimension, const Index orientation) const { + TNL_ASSERT_GE(dimension, 0, "Dimension must be greater than zero"); + TNL_ASSERT_LE(dimension, Dimension, "Requested dimension must be less than or equal to Dimension"); + + if (dimension == 0 || dimension == Dimension) + return this -> getEntitiesCount(dimension); + + Index index = Templates::firstKCombinationSum(dimension, Dimension) + orientation; + + return this -> entitiesCountAlongBases[index]; +} + +__NDIMGRID_TEMPLATE__ +template +__cuda_callable__ inline +typename __NDIM_PREFIX__::Coordinate __NDIM_PREFIX__::getBasis(Index orientation) const noexcept { + constexpr Index index = Templates::firstKCombinationSum(EntityDimension, Dimension); + + return this -> bases(index + orientation); +} + +__NDIMGRID_TEMPLATE__ +template , + std::enable_if_t> +__cuda_callable__ inline +Index __NDIM_PREFIX__::getOrientedEntitiesCount() const noexcept { + if (EntityDimension == 0 || EntityDimension == Dimension) + return this -> getEntitiesCount(EntityDimension); + + constexpr Index index = Templates::firstKCombinationSum(EntityDimension, Dimension) + EntityOrientation; + + return this -> entitiesCountAlongBases[index]; +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline const typename __NDIM_PREFIX__::Point &__NDIM_PREFIX__::getOrigin() const noexcept { return this->origin; } + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::setDomain(const typename __NDIM_PREFIX__::Point &origin, const typename __NDIM_PREFIX__::Point &proportions) { + this->origin = origin; + this->proportions = proportions; + + this->fillSpaceSteps(); +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::setSpaceSteps(const typename __NDIM_PREFIX__::Point &spaceSteps) noexcept { + this->spaceSteps = spaceSteps; + + fillSpaceStepsPowers(); + fillProportions(); +} + +__NDIMGRID_TEMPLATE__ +template ...>, bool>, + std::enable_if_t> +void __NDIM_PREFIX__::setSpaceSteps(Steps... spaceSteps) noexcept { + this->spaceSteps = Point(spaceSteps...); + + fillSpaceStepsPowers(); + fillProportions(); +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline const typename __NDIM_PREFIX__::Point &__NDIM_PREFIX__::getSpaceSteps() const noexcept { return this->spaceSteps; } + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline const typename __NDIM_PREFIX__::Point &__NDIM_PREFIX__::getProportions() const noexcept { return this->proportions; } + +__NDIMGRID_TEMPLATE__ +template ...>, bool>, + std::enable_if_t> +__cuda_callable__ inline +Real __NDIM_PREFIX__::getSpaceStepsProducts(Powers... powers) const { + int index = Templates::makeCollapsedIndex(this -> spaceStepsPowersSize, Coordinate(powers...)); + + return this->spaceStepsProducts(index); +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline Real __NDIM_PREFIX__::getSpaceStepsProducts(const Coordinate& powers) const { + int index = Templates::makeCollapsedIndex(this -> spaceStepsPowersSize, powers); + + return this->spaceStepsProducts(index); +} + +__NDIMGRID_TEMPLATE__ +template > +__cuda_callable__ inline +Real __NDIM_PREFIX__::getSpaceStepsProducts() const noexcept { + constexpr int index = Templates::makeCollapsedIndex(this -> spaceStepsPowersSize); + + return this -> spaceStepsProducts(index); +} + +__NDIMGRID_TEMPLATE__ +__cuda_callable__ inline Real __NDIM_PREFIX__::getSmallestSpaceStep() const noexcept { + Real minStep = this->spaceSteps[0]; + Index i = 1; + + while (i != Dimension) + minStep = min(minStep, this->spaceSteps[i++]); + + return minStep; +} + +__NDIMGRID_TEMPLATE__ +template +inline +void __NDIM_PREFIX__::traverseAll(Func func, FuncArgs... args) const { + this -> traverseAll(Coordinate(0), + this -> getDimensions(), + func, + args...); +} + +__NDIMGRID_TEMPLATE__ +template +inline +void __NDIM_PREFIX__::traverseAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + TNL_ASSERT_GE(from, Coordinate(0), "Traverse rect must be in the grid dimensions"); + TNL_ASSERT_LE(to, this -> getDimensions(), "Traverse rect be in the grid dimensions"); + TNL_ASSERT_LE(from, to, "Traverse rect must be defined from leading bottom anchor to trailing top anchor"); + + auto exec = [&](const Index orientation, const Coordinate& basis) { + Templates::ParallelFor::exec(from, + to + basis, + func, + basis, + orientation, + args...); + }; + + Templates::ForEachOrientation::exec(exec); +} + +__NDIMGRID_TEMPLATE__ +template +inline +void __NDIM_PREFIX__::traverseInterior(Func func, FuncArgs... args) const { + this -> traverseInterior(Coordinate(0), + this -> getDimensions(), + func, + args...); +} + +__NDIMGRID_TEMPLATE__ +template +inline +void __NDIM_PREFIX__::traverseInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + TNL_ASSERT_GE(from, Coordinate(0), "Traverse rect must be in the grid dimensions"); + TNL_ASSERT_LE(to, this -> getDimensions(), "Traverse rect be in the grid dimensions"); + TNL_ASSERT_LE(from, to, "Traverse rect must be defined from leading bottom anchor to trailing top anchor"); + + auto exec = [&](const Index orientation, const Coordinate& basis) { + switch (EntityDimension) { + case 0: { + Templates::ParallelFor::exec(from + Coordinate(1), + to, + func, + basis, + orientation, + args...); + break; + } + case Dimension: { + Templates::ParallelFor::exec(from + Coordinate(1), + to - Coordinate(1), + func, + basis, + orientation, + args...); + break; + } + default: { + Templates::ParallelFor::exec(from + basis, + to, + func, + basis, + orientation, + args...); + break; + } + } + }; + + Templates::ForEachOrientation::exec(exec); +} + +__NDIMGRID_TEMPLATE__ +template +inline + void __NDIM_PREFIX__::traverseBoundary(Func func, FuncArgs... args) const { + this -> traverseBoundary(Coordinate(0), + this -> getDimensions(), + func, + args...); +} + +__NDIMGRID_TEMPLATE__ +template +inline +void __NDIM_PREFIX__::traverseBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const { + // Boundaries of the grid are formed by the entities of Dimension - 1. + // We need to traverse each orientation independently. + constexpr int orientationsCount = getEntityOrientationsCount(Dimension - 1); + constexpr bool isDirectedEntity = EntityDimension != 0 && EntityDimension != Dimension; + constexpr bool isAnyBoundaryIntersects = EntityDimension != Dimension - 1; + + Container isBoundaryTraversed(0); + + auto forBoundary = [&](const auto orthogonalOrientation, const auto orientation, const Coordinate& basis) { + Coordinate start = from; + Coordinate end = to + basis; + + if (isAnyBoundaryIntersects) { + #pragma unroll + for (Index i = 0; i < Dimension; i++) { + start[i] = (!isDirectedEntity || basis[i]) && isBoundaryTraversed[i] ? 1 : 0; + end[i] = end[i] - ((!isDirectedEntity || basis[i]) && isBoundaryTraversed[i] ? 1 : 0); + } + } + + start[orthogonalOrientation] = end[orthogonalOrientation] - 1; + + Templates::ParallelFor::exec(start, + end, + func, + basis, + orientation, + args...); + + // Skip entities defined only once + if (!start[orthogonalOrientation] && end[orthogonalOrientation]) return; + + start[orthogonalOrientation] = 0; + end[orthogonalOrientation] = 1; + + Templates::ParallelFor::exec(start, + end, + func, + basis, + orientation, + args...); + }; + + if (!isAnyBoundaryIntersects) { + auto exec = [&](const auto orientation, const Coordinate& basis) { + constexpr int orthogonalOrientation = EntityDimension - orientation; + + forBoundary(orthogonalOrientation, orientation, basis); + }; + + Templates::ForEachOrientation::exec(exec); + return; + } + + auto exec = [&](const auto orthogonalOrientation) { + auto exec = [&](const auto orientation, const Coordinate& basis) { + forBoundary(orthogonalOrientation, orientation, basis); + }; + + if (EntityDimension == 0 || EntityDimension == Dimension) { + Templates::ForEachOrientation::exec(exec); + } else { + Templates::ForEachOrientation::exec(exec); + } + + isBoundaryTraversed[orthogonalOrientation] = 1; + }; + + Templates::DescendingFor::exec(exec); +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::writeProlog(Logger& logger) const noexcept { + logger.writeParameter("Dimensions:", this->dimensions); + + logger.writeParameter("Origin:", this->origin); + logger.writeParameter("Proportions:", this->proportions); + logger.writeParameter("Space steps:", this->spaceSteps); + + for (Index i = 0; i <= Dimension; i++) { + String tmp = String("Entities count along dimension ") + String(i) + ":"; + + logger.writeParameter(tmp, this->cumulativeEntitiesCountAlongBases[i]); + } +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::fillEntitiesCount() { + Index j = 0; + + for (Index i = 0; i < Dimension + 1; i++) cumulativeEntitiesCountAlongBases[i] = 0; + + // In case, if some dimension is zero. Clear all counts + for (Index i = 0; i < Dimension; i++) { + if (dimensions[i] == 0) { + for (Index k = 0; k < (Index)entitiesCountAlongBases.getSize(); k++) + entitiesCountAlongBases[k] = 0; + + return; + } + } + + for (Index i = 0; i <= Dimension; i++) { + forEachPermutation(Dimension - i, Dimension, [&](const std::vector& permutation) { + int result = 1; + + for (Index k = 0; k < (Index)permutation.size(); k++) + result *= dimensions[k] + permutation[k]; + + entitiesCountAlongBases[j] = result; + cumulativeEntitiesCountAlongBases[i] += result; + + j++; + }); + } +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::fillProportions() { + Index i = 0; + + while (i != Dimension) { + this->proportions[i] = this->spaceSteps[i] * this->dimensions[i]; + i++; + } +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::fillSpaceSteps() { + bool hasAnyInvalidDimension = false; + + for (Index i = 0; i < Dimension; i++) { + if (this->dimensions[i] <= 0) { + hasAnyInvalidDimension = true; + break; + } + } + + if (!hasAnyInvalidDimension) { + for (Index i = 0; i < Dimension; i++) + this->spaceSteps[i] = this->proportions[i] / this->dimensions[i]; + + fillSpaceStepsPowers(); + } +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::fillSpaceStepsPowers() { + Container powers; + + for (Index i = 0; i < Dimension; i++) { + Index power = -(this -> spaceStepsPowersSize >> 1); + + for (Index j = 0; j < spaceStepsPowersSize; j++) { + powers[i * spaceStepsPowersSize + j] = pow(this->spaceSteps[i], power); + power++; + } + } + + for (Index i = 0; i < this->spaceStepsProducts.getSize(); i++) { + Real product = 1; + Index index = i; + + for (Index j = 0; j < Dimension; j++) { + Index residual = index % this->spaceStepsPowersSize; + + index /= this->spaceStepsPowersSize; + + product *= powers[j * spaceStepsPowersSize + residual]; + } + + spaceStepsProducts[i] = product; + } +} + +__NDIMGRID_TEMPLATE__ +void __NDIM_PREFIX__::fillBases() { + OrientationBasesContainer container; + + int index = container.getSize() - 1; + + auto forEachEntityDimension = [&](const auto entityDimension) { + constexpr Index combinationsCount = this -> getEntityOrientationsCount(entityDimension); + + auto forEachOrientation = [&](const auto orientation, const auto entityDimension) { + container[index--] = BasisGetter::template getBasis(); + }; + + Templates::DescendingFor::exec(forEachOrientation, entityDimension); + }; + + Templates::DescendingFor::exec(forEachEntityDimension); + + this -> bases = container; +} + +__NDIMGRID_TEMPLATE__ +template +void __NDIM_PREFIX__::forEachPermutation(const Index k, const Index n, Func func, FuncArgs... args) const { + std::vector buffer = {}; + + buffer.resize(n); + + std::fill(buffer.begin(), buffer.end(), 0); + std::fill(buffer.end() - k, buffer.end(), 1); + + do { + func(buffer, args...); + } while (std::next_permutation(buffer.begin(), buffer.end())); +} + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Implementations/NeighbourGridEntityGetter.hpp b/src/TNL/Meshes/GridDetails/Implementations/NeighbourGridEntityGetter.hpp new file mode 100644 index 0000000000000000000000000000000000000000..594cee0cfca5774a1e27359c11c1322debc666f7 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Implementations/NeighbourGridEntityGetter.hpp @@ -0,0 +1,113 @@ + +#pragma once + +#include +#include + +namespace TNL { +namespace Meshes { + +template +class NeighbourGridEntityGetter { + public: + template + static + __cuda_callable__ inline + GridEntity getEntity(const GridEntity& entity, const typename Grid::Coordinate& offset) { + using BasisGetterType = BasisGetter; + using Coordinate = typename Grid::Coordinate; + + constexpr int orientationsCount = Templates::combination(NeighbourEntityDimension, GridDimension); + + const Coordinate coordinate = entity.getCoordinates() + offset; + const int orientation = TNL::min(orientationsCount - 1, entity.getOrientation()); + const Coordinate basis = entity.getMesh().template getBasis(orientation); + + TNL_ASSERT_GE(coordinate, Coordinate(0), "wrong coordinate"); + TNL_ASSERT_LT(coordinate, entity.getMesh().getDimensions() + basis, "wrong coordinate"); + + return { + entity.getMesh(), + coordinate, + basis, + orientation + }; + } + + template = true> + static + __cuda_callable__ inline + GridEntity getEntity(const GridEntity& entity) { + using BasisGetterType = BasisGetter; + using Coordinate = typename Grid::Coordinate; + + constexpr int orientationsCount = Templates::combination(NeighbourEntityDimension, GridDimension); + + const Coordinate coordinate = entity.getCoordinates() + Coordinate(Steps...); + const int orientation = TNL::min(orientationsCount - 1, entity.getOrientation()); + const Coordinate basis = entity.getMesh().template getBasis(orientation); + + TNL_ASSERT_GE(coordinate, Coordinate(0), "wrong coordinate"); + TNL_ASSERT_LT(coordinate, entity.getMesh().getDimensions() + basis, "wrong coordinate"); + + return { + entity.getMesh(), + coordinate, + basis, + orientation + }; + } + + template = true> + static + __cuda_callable__ inline + GridEntity getEntity(const GridEntity& entity, const typename Grid::Coordinate& offset) { + using BasisGetterType = BasisGetter; + using Coordinate = typename Grid::Coordinate; + + const Coordinate coordinate = entity.getCoordinates() + offset; + const Coordinate basis = BasisGetterType::template getBasis(); + + TNL_ASSERT_GE(coordinate, Coordinate(0), "wrong coordinate"); + TNL_ASSERT_LT(coordinate, entity.getMesh().getDimensions() + basis, "wrong coordinate"); + + return { + entity.getMesh(), + coordinate, + basis, + Orientation + }; + } + + template = true, + std::enable_if_t = true> + static + __cuda_callable__ inline + GridEntity getEntity(const GridEntity& entity) { + using BasisGetterType = BasisGetter; + using Coordinate = typename Grid::Coordinate; + + const Coordinate coordinate = entity.getCoordinates() + Coordinate(Steps...); + const Coordinate basis { BasisGetterType::template getBasis() }; + + TNL_ASSERT_GE(coordinate, Coordinate(0), "wrong coordinate"); + TNL_ASSERT_LT(coordinate, entity.getMesh().getDimensions() + basis, "wrong coordinate"); + + return { + entity.getMesh(), + coordinate, + basis, + Orientation + }; + } +}; + +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/NDimGrid.h b/src/TNL/Meshes/GridDetails/NDimGrid.h new file mode 100644 index 0000000000000000000000000000000000000000..0489fd74588287f45b551026dcc4522e6c0d32ff --- /dev/null +++ b/src/TNL/Meshes/GridDetails/NDimGrid.h @@ -0,0 +1,245 @@ + +#pragma once + +#include +#include +#include +#include + +#include + +namespace TNL { +namespace Meshes { + +template +class NDimGrid { + public: + template 0), bool> = true> + using Container = TNL::Containers::StaticVector; + + using IndexType = Index; + using DeviceType = Device; + using RealType = Real; + + using Coordinate = Container; + using Point = Container; + using EntitiesCounts = Container; + + using OrientationBasesContainer = Container<1 << Dimension, Coordinate>; + + /** + * @brief Returns the dimension of grid + */ + static constexpr int getMeshDimension() { return Dimension; }; + /** + * @brief Returns the coefficient powers size. + */ + static constexpr int spaceStepsPowersSize = 5; + + using SpaceProductsContainer = Container::value, Real>; + + NDimGrid() { + fillBases(); + } + + /** + * @brief Returns the number of orientations for entity dimension. + * For example in 2-D Grid the edge can be vertical or horizontal. + */ + static constexpr Index getEntityOrientationsCount(const Index entityDimension); + + template ...>, bool> = true, + std::enable_if_t = true> + void setDimensions(Dimensions... dimensions); + + void setDimensions(const Container& dimensions); + + /** + * @brief - Returns dimensions as a count of edges along each axis + * @param[in] index - Index of dimension + */ + __cuda_callable__ inline Index getDimension(const Index index) const; + /** + * @brief - Returns dimensions as a count of edges along each axis + * @param[in] indices - A list of indices + */ + template ...>, bool> = true, + std::enable_if_t<(sizeof...(DimensionIndex) > 0), bool> = true> + __cuda_callable__ inline Container getDimensions(DimensionIndex... indices) const noexcept; + /** + * @brief - Returns dimensions as a count of edges along each axis + */ + __cuda_callable__ inline const Coordinate& getDimensions() const noexcept; + /** + * @brief - Returns count of entities of specific dimension + */ + __cuda_callable__ inline Index getEntitiesCount(const Index index) const; + /** + * @brief - Returns count of entities of specific dimension + */ + template = true> + __cuda_callable__ inline Index getEntitiesCount() const noexcept; + /** + * @brief - Returns count of entities of specific dimension + */ + template ...>, bool> = true, + std::enable_if_t<(sizeof...(DimensionIndex) > 0), bool> = true> + __cuda_callable__ inline Container getEntitiesCounts(DimensionIndex... indices) const; + /** + * @brief - Returns count of entities of specific dimension + */ + __cuda_callable__ inline const EntitiesCounts& getEntitiesCounts() const noexcept; + /** + * @brief - Returns count of entities of specific dimension and orientation + * + * @param[in] dimension + * @param[in] orientation - orientation of the entity + */ + __cuda_callable__ inline Index getOrientedEntitiesCount(const Index dimension, const Index orientation) const; + /** + * @brief - Returns count of entities of specific dimension and orientation + * + * @param[in] dimension + * @param[in] orientation - orientation of the entity + */ + template = true, + std::enable_if_t = true> + __cuda_callable__ inline Index getOrientedEntitiesCount() const noexcept; + /** + * @brief - Returns basis of the entity with the specific orientation + * + * @param[in] dimension + * @param[in] orientation - orientation of the entity + */ + template + __cuda_callable__ inline Coordinate getBasis(Index orientation) const noexcept; + /** + * \brief Sets the origin and proportions of this grid. + * + * \param origin Point where this grid starts. + * \param proportions Total length of this grid. + */ + void setDomain(const Point& origin, const Point& proportions); + /** + * @brief Set the Origin of the grid + */ + void setOrigin(const Point& origin) noexcept; + /** + * @brief Set the Origin of the grid + */ + template ...>, bool> = true, + std::enable_if_t = true> + void setOrigin(Coordinates... coordinates) noexcept; + /** + * @brief - Returns the origin of the grid + */ + __cuda_callable__ inline const Point& getOrigin() const noexcept; + /** + * @brief Set the Space Steps along each dimension of the grid + */ + void setSpaceSteps(const Point& steps) noexcept; + /** + * @brief - Specifies space steps of the grid + */ + template ...>, bool> = true, + std::enable_if_t = true> + void setSpaceSteps(Steps... spaceSteps) noexcept; + /** + * @brief - Returns the space staps of the grid + */ + __cuda_callable__ inline const Point& getSpaceSteps() const noexcept; + /** + * @brief Returns product of space steps + */ + template ...>, bool> = true, + std::enable_if_t = true> + __cuda_callable__ inline Real getSpaceStepsProducts(Powers... powers) const; + /** + * @brief Returns product of space steps + */ + __cuda_callable__ inline Real getSpaceStepsProducts(const Coordinate& powers) const; + /** + * @brief Returns product of space step + */ + template = true> + __cuda_callable__ inline Real getSpaceStepsProducts() const noexcept; + /** + * @brief Get the Smalles Space Steps object + */ + __cuda_callable__ inline Real getSmallestSpaceStep() const noexcept; + /** + * @brief Get the proportions of the Grid + */ + __cuda_callable__ inline const Point& getProportions() const noexcept; + /** + * @brief Writes info about the grid + */ + void writeProlog(Logger& logger) const noexcept; + + protected: + Coordinate dimensions; + /** + * @brief - A list of elements count along specific directions. + * First, (n choose 0) elements will contain the count of 0 + * dimension elements Second, (n choose 1) elements will contain the count + * of 1-dimension elements.... + * + * For example, let's have a 3-d grid, then the map indexing will + * be the next: 0 - 0 - count of vertices 1, 2, 3 - count of edges in x, y, + * z plane 4, 5, 6 - count of faces in xy, yz, zy plane 7 - count of cells + * in z y x plane + * + * @warning - The ordering of is lexigraphical. + */ + Container<1 << Dimension, Index> entitiesCountAlongBases; + /** + * @brief - A cumulative map over dimensions. + */ + Container cumulativeEntitiesCountAlongBases; + + Point origin, proportions, spaceSteps; + + OrientationBasesContainer bases; + SpaceProductsContainer spaceStepsProducts; + + void fillEntitiesCount(); + void fillSpaceSteps(); + void fillSpaceStepsPowers(); + void fillProportions(); + void fillBases(); + + template + inline void traverseAll(Func func, FuncArgs... args) const; + + template + inline void traverseAll(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; + + template + inline void traverseInterior(Func func, FuncArgs... args) const; + + template + inline void traverseInterior(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; + + template + inline void traverseBoundary(Func func, FuncArgs... args) const; + + template + inline void traverseBoundary(const Coordinate& from, const Coordinate& to, Func func, FuncArgs... args) const; + + template + void forEachPermutation(const Index k, const Index n, Func func, FuncArgs... args) const; +}; +} // namespace Meshes +} // namespace TNL + +#include diff --git a/src/TNL/Meshes/GridDetails/NeighborGridEntitiesStorage.h b/src/TNL/Meshes/GridDetails/NeighborGridEntitiesStorage.h deleted file mode 100644 index ffd68c334580793e3972f70d3593dda28364c337..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/NeighborGridEntitiesStorage.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename GridEntity, - int NeighborEntityDimension, - typename GridEntityConfig, - bool storage = GridEntityConfig::template neighborEntityStorage< GridEntity >( NeighborEntityDimension ) > -class NeighborGridEntityLayer : public NeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1, GridEntityConfig > -{ -public: - using BaseType = NeighborGridEntityLayer< GridEntity, NeighborEntityDimension - 1, GridEntityConfig >; - using NeighborEntityGetterType = NeighborGridEntityGetter< GridEntity, NeighborEntityDimension >; - - using BaseType::getNeighborEntities; - - __cuda_callable__ - NeighborGridEntityLayer( const GridEntity& entity ) : BaseType( entity ), neighborEntities( entity ) {} - - __cuda_callable__ - const NeighborEntityGetterType& - getNeighborEntities( const DimensionTag< NeighborEntityDimension >& tag ) const - { - return this->neighborEntities; - } - - __cuda_callable__ - void - refresh( const typename GridEntity::GridType& grid, const typename GridEntity::GridType::IndexType& entityIndex ) - { - BaseType::refresh( grid, entityIndex ); - neighborEntities.refresh( grid, entityIndex ); - } - -protected: - NeighborEntityGetterType neighborEntities; -}; - -template< typename GridEntity, typename GridEntityConfig, bool storage > -class NeighborGridEntityLayer< GridEntity, 0, GridEntityConfig, storage > -{ -public: - using NeighborEntityGetterType = NeighborGridEntityGetter< GridEntity, 0 >; - - __cuda_callable__ - NeighborGridEntityLayer( const GridEntity& entity ) : neighborEntities( entity ) {} - - __cuda_callable__ - const NeighborEntityGetterType& - getNeighborEntities( const DimensionTag< 0 >& tag ) const - { - return this->neighborEntities; - } - - __cuda_callable__ - void - refresh( const typename GridEntity::GridType& grid, const typename GridEntity::GridType::IndexType& entityIndex ) - { - neighborEntities.refresh( grid, entityIndex ); - } - -protected: - NeighborEntityGetterType neighborEntities; -}; - -template< typename GridEntity, typename GridEntityConfig > -class NeighborGridEntitiesStorage -: public NeighborGridEntityLayer< GridEntity, GridEntity::getMeshDimension(), GridEntityConfig > -{ - using BaseType = NeighborGridEntityLayer< GridEntity, GridEntity::getMeshDimension(), GridEntityConfig >; - -public: - using BaseType::getNeighborEntities; - using BaseType::refresh; - - __cuda_callable__ - NeighborGridEntitiesStorage( const GridEntity& entity ) : BaseType( entity ) {} - - template< int EntityDimension > - __cuda_callable__ - const NeighborGridEntityGetter< GridEntity, EntityDimension >& - getNeighborEntities() const - { - return BaseType::getNeighborEntities( DimensionTag< EntityDimension >() ); - } -}; - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter.h deleted file mode 100644 index b597751fda5abafcc47a6a293e989b7a2b72f9f7..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename GridEntity, - int NeighborEntityDimension, - typename EntityStencilTag = GridEntityStencilStorageTag< - GridEntity::ConfigType::template neighborEntityStorage< GridEntity >( NeighborEntityDimension ) > > -class NeighborGridEntityGetter -{ -public: - // TODO: not all specializations are implemented yet - - __cuda_callable__ - NeighborGridEntityGetter( const GridEntity& entity ) - { - // TNL_ASSERT( false, ); - } - - __cuda_callable__ - void - refresh( const typename GridEntity::GridType& grid, const typename GridEntity::IndexType& entityIndex ) - { - // TNL_ASSERT( false, ); - } -}; - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter1D_impl.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter1D_impl.h deleted file mode 100644 index c9db445e6d938d2384f5cf7fc43e827eb5ba9cc3..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter1D_impl.h +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 1 | 1 | ---- | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config >, - 1, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 1; - static constexpr int NeighborEntityDimension = 1; - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int step > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) - && entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) ); - } - - template< int step > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) - && entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() + step; - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 1 | 1 | Cross/Full | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config, typename StencilStorage > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config >, 1, StencilStorage > -{ -public: - static constexpr int EntityDimension = 1; - static constexpr int NeighborEntityDimension = 1; - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - static constexpr int stencilSize = Config::getStencilSize(); - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int step > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) - && entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + step ) ); - } - - template< int step > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( step ) >= CoordinatesType( 0 ) - && entity.getCoordinates() + CoordinatesType( step ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); -#ifndef HAVE_CUDA // TODO: fix it -- does not work with nvcc - if( step < -stencilSize || step > stencilSize ) - return this->entity.getIndex() + step; - return stencil[ stencilSize + step ]; -#else - return this->entity.getIndex() + step; -#endif - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ) - { -#ifndef HAVE_CUDA // TODO: fix it -- does not work with nvcc - Algorithms::staticFor< IndexType, -stencilSize, stencilSize + 1 >( - [ & ]( auto index ) - { - stencil[ index + stencilSize ] = entityIndex + index; - } ); -#endif - }; - -protected: - const GridEntityType& entity; - - IndexType stencil[ 2 * stencilSize + 1 ]; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 1 | 0 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 1, Config >, - 0, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 1; - static constexpr int NeighborEntityDimension = 0; - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int step > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step + ( step < 0 ) >= CoordinatesType( 0 ) - && entity.getCoordinates().x() + step + ( step < 0 ) <= entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step + ( step < 0 ) ) ); - } - - template< int step > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step + ( step < 0 ) >= CoordinatesType( 0 ).x() - && entity.getCoordinates().x() + step + ( step < 0 ) <= entity.getMesh().getDimensions().x(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() + step + ( step < 0 ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 0 | 1 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config, typename StencilStorage > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config >, - 1, - StencilStorage > // GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 0; - static constexpr int NeighborEntityDimension = 1; - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - void - test() const - { - std::cerr << "***" << std::endl; - }; - - template< int step > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) - && entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) ); - } - - template< int step > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= 0 - && entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions().x(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() + step - ( step > 0 ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; -}; - -/**** TODO: Implement this, now it is only a copy of specialization for none stencil storage - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 0 | 1 | Cross | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config >, - 1, - GridEntityStencilStorageTag< GridEntityCrossStencil > > -{ -public: - static constexpr int EntityDimension = 0; - static constexpr int NeighborEntityDimension = 1; - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int step > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) - && entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step - ( step > 0 ) ) ); - } - - template< int step > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step - ( step > 0 ) >= CoordinatesType( 0 ) - && entity.getCoordinates().x() + step - ( step > 0 ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() + step - ( step > 0 ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 0 | 0 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 1, Real, Device, Index >, 0, Config >, - 0, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 0; - static constexpr int NeighborEntityDimension = 0; - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int step > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) - && entity.getCoordinates().x() + step <= entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - return NeighborGridEntity( CoordinatesType( entity.getCoordinates().x() + step ) ); - } - - template< int step > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates().x() + step >= CoordinatesType( 0 ) - && entity.getCoordinates().x() + step <= entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() = " << entity.getCoordinates() << " entity.getMesh().getDimensions() = " - << entity.getMesh().getDimensions() << " EntityDimension = " << EntityDimension ); - - return this->entity.getIndex() + step; - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; -}; - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter2D_impl.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter2D_impl.h deleted file mode 100644 index dde6019d9f68bb08f8b709b33f56c5f4fa90339f..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter2D_impl.h +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stencil Storage | - * +-----------------+---------------------------+-------------------+ - * | 2 | 2 | No specialization | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config, typename StencilStorage > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >, 2, StencilStorage > -{ -public: - static constexpr int EntityDimension = 2; - static constexpr int NeighborEntityDimension = 2; - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( - this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + stepX, entity.getCoordinates().y() + stepY ) ); - } - - template< int stepX, int stepY > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() + stepY * entity.getMesh().getDimensions().x() + stepX; - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stencil Storage | - * +-----------------+---------------------------+-------------------+ - * | 2 | 2 | Cross | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >, - 2, - GridEntityStencilStorageTag< GridEntityCrossStencil > > -{ -public: - static constexpr int EntityDimension = 2; - static constexpr int NeighborEntityDimension = 2; - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - using StencilStorage = GridEntityStencilStorageTag< GridEntityCrossStencil >; - - static constexpr int stencilSize = Config::getStencilSize(); - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( - this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + stepX, entity.getCoordinates().y() + stepY ) ); - } - - template< int stepX, int stepY > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); -#ifndef HAVE_CUDA // TODO: fix this to work with CUDA - if( ( stepX != 0 && stepY != 0 ) - || ( stepX < -stencilSize || stepX > stencilSize || stepY < -stencilSize || stepY > stencilSize ) ) - return this->entity.getIndex() + stepY * entity.getMesh().getDimensions().x() + stepX; - if( stepY == 0 ) - return stencilX[ stepX + stencilSize ]; - return stencilY[ stepY + stencilSize ]; -#else - return this->entity.getIndex() + stepY * entity.getMesh().getDimensions().x() + stepX; -#endif - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ) - { -#ifndef HAVE_CUDA // TODO: fix this to work with CUDA - auto stencilXRefresher = [ & ]( auto index ) - { - stencilX[ index + stencilSize ] = entityIndex + index; - }; - auto stencilYRefresher = [ & ]( auto index ) - { - stencilY[ index + stencilSize ] = entityIndex + index * entity.getMesh().getDimensions().x(); - }; - Algorithms::staticFor< IndexType, -stencilSize, 0 >( stencilYRefresher ); - Algorithms::staticFor< IndexType, 1, stencilSize + 1 >( stencilYRefresher ); - Algorithms::staticFor< IndexType, -stencilSize, stencilSize + 1 >( stencilXRefresher ); -#endif - }; - -protected: - const GridEntityType& entity; - - IndexType stencilX[ 2 * stencilSize + 1 ]; - IndexType stencilY[ 2 * stencilSize + 1 ]; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stencil Storage | - * +-----------------+---------------------------+-------------------+ - * | 2 | 1 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config, typename StencilStorage > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >, 1, StencilStorage > -{ -public: - static constexpr int EntityDimension = 2; - static constexpr int NeighborEntityDimension = 1; - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - using EntityOrientationType = typename GridEntityType::EntityOrientationType; - using EntityBasisType = typename GridEntityType::EntityBasisType; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - static_assert( ! stepX + ! stepY == 1, "Only one of the steps can be non-zero." ); - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) - >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) - < entity.getMesh().getDimensions() + CoordinatesType( ( stepX > 0 ), ( stepY > 0 ) ), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) = " - << entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( - this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ), - entity.getCoordinates().y() + stepY + ( stepY < 0 ) ), - EntityOrientationType( stepX ? ( stepX > 0 ? 1 : -1 ) : 0, stepY ? ( stepY > 0 ? 1 : -1 ) : 0 ), - EntityBasisType( ! stepX, ! stepY ) ); - } - - template< int stepX, int stepY > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( this->entity.getMesh(), this->template getEntity< stepX, stepY >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stencil Storage | - * +-----------------+---------------------------+-------------------+ - * | 2 | 0 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config, typename StencilStorage > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 2, Config >, 0, StencilStorage > -{ -public: - static constexpr int EntityDimension = 2; - static constexpr int NeighborEntityDimension = 0; - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT( stepX != 0 && stepY != 0, std::cerr << " stepX = " << stepX << " stepY = " << stepY ); - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) - >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) - < entity.getMesh().getDimensions() + CoordinatesType( ( stepX > 0 ), ( stepY > 0 ) ), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) = " - << entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) - << " entity.getMesh().getDimensions() + CoordinatesType( sign( stepX ), sign( stepY ) ) = " - << entity.getMesh().getDimensions() + CoordinatesType( sign( stepX ), sign( stepY ) ) - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ), - entity.getCoordinates().y() + stepY + ( stepY < 0 ) ) ); - } - - template< int stepX, int stepY > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( this->entity.getMesh(), this->template getEntity< stepX, stepY >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stencil Storage | - * +-----------------+---------------------------+-------------------+ - * | 1 | 2 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config, typename StencilStorage > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 1, Config >, 2, StencilStorage > -{ -public: - static constexpr int EntityDimension = 1; - static constexpr int NeighborEntityDimension = 2; - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - /*TNL_ASSERT( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) && - ( ( !! stepY ) == ( !! entity.getOrientation().y() ) ), - std::cerr << "( stepX, stepY ) cannot be perpendicular to entity coordinates: stepX = " << stepX << " stepY = " - << stepY - << " entity.getOrientation() = " << entity.getOrientation() );*/ - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( - entity.getCoordinates(), entity.getMesh().getDimensions() + TNL::abs( entity.getOrientation() ), "wrong coordinates" ); - TNL_ASSERT( - entity.getCoordinates() - + CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), - stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) - >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() - + CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), - stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) - < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ) * ( entity.getOrientation().x() != " - "0.0 ), stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != 0.0 ) ) = " - << entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ) ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( - this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), - entity.getCoordinates().y() + stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ) ) ); - } - - template< int stepX, int stepY > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( this->entity.getMesh(), this->template getEntity< stepX, stepY >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stencil Storage | - * +-----------------+---------------------------+-------------------+ - * | 0 | 0 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config, typename StencilStorage > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 2, Real, Device, Index >, 0, Config >, 0, StencilStorage > -{ -public: - static constexpr int EntityDimension = 0; - static constexpr int NeighborEntityDimension = 0; - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( - this->entity.getMesh(), CoordinatesType( entity.getCoordinates().x() + stepX, entity.getCoordinates().y() + stepY ) ); - } - - template< int stepX, int stepY > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY ) <= entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() + stepY * ( entity.getMesh().getDimensions().x() + 1 ) + stepX; - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter3D_impl.h b/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter3D_impl.h deleted file mode 100644 index 405184a32096e1b96994a3310a02b47b5784a472..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/NeighborGridEntityGetter3D_impl.h +++ /dev/null @@ -1,655 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include -#include -#include -#include - -namespace TNL { -namespace Meshes { - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 3 | 3 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >, - 3, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 3; - static constexpr int NeighborEntityDimension = 3; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY ) >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX, - entity.getCoordinates().y() + stepY, - entity.getCoordinates().z() + stepZ ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() - + ( stepZ * entity.getMesh().getDimensions().y() + stepY ) * entity.getMesh().getDimensions().x() + stepX; - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 3 | 3 | Cross | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >, - 3, - GridEntityStencilStorageTag< GridEntityCrossStencil > > -{ -public: - static constexpr int EntityDimension = 3; - static constexpr int NeighborEntityDimension = 3; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - using StencilStorage = GridEntityStencilStorageTag< GridEntityCrossStencil >; - - static constexpr int stencilSize = Config::getStencilSize(); - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX, - entity.getCoordinates().y() + stepY, - entity.getCoordinates().z() + stepZ ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); -#ifndef HAVE_CUDA // TODO: fix this to work with CUDA - if( ( stepX != 0 && stepY != 0 ) || ( stepX != 0 && stepZ != 0 ) || ( stepY != 0 && stepZ != 0 ) - || ( stepX < -stencilSize || stepX > stencilSize || stepY < -stencilSize || stepY > stencilSize - || stepZ < -stencilSize || stepZ > stencilSize ) ) - return this->entity.getIndex() - + ( stepZ * entity.getMesh().getDimensions().y() + stepY ) * entity.getMesh().getDimensions().x() + stepX; - if( stepY == 0 && stepZ == 0 ) - return stencilX[ stepX + stencilSize ]; - if( stepZ == 0 ) - return stencilY[ stepY + stencilSize ]; - return stencilZ[ stepZ + stencilSize ]; -#else - return this->entity.getIndex() - + ( stepZ * entity.getMesh().getDimensions().y() + stepY ) * entity.getMesh().getDimensions().x() + stepX; -#endif - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ) - { -#ifndef HAVE_CUDA // TODO: fix this to work with CUDA - auto stencilXRefresher = [ & ]( auto index ) - { - stencilX[ index + stencilSize ] = entityIndex + index; - }; - auto stencilYRefresher = [ & ]( auto index ) - { - stencilY[ index + stencilSize ] = entityIndex + index * entity.getMesh().getDimensions().x(); - }; - auto stencilZRefresher = [ & ]( auto index ) - { - stencilZ[ index + stencilSize ] = entityIndex + index * entity.getMesh().cellZNeighborsStep; - }; - Algorithms::staticFor< IndexType, -stencilSize, 0 >( stencilZRefresher ); - Algorithms::staticFor< IndexType, 1, stencilSize + 1 >( stencilZRefresher ); - Algorithms::staticFor< IndexType, -stencilSize, 0 >( stencilYRefresher ); - Algorithms::staticFor< IndexType, 1, stencilSize + 1 >( stencilYRefresher ); - Algorithms::staticFor< IndexType, -stencilSize, stencilSize + 1 >( stencilXRefresher ); -#endif - }; - -protected: - const GridEntityType& entity; - - IndexType stencilX[ 2 * stencilSize + 1 ]; - IndexType stencilY[ 2 * stencilSize + 1 ]; - IndexType stencilZ[ 2 * stencilSize + 1 ]; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 3 | 2 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >, - 2, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 3; - static constexpr int NeighborEntityDimension = 2; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - using EntityOrientationType = typename GridEntityType::EntityOrientationType; - using EntityBasisType = typename GridEntityType::EntityBasisType; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - static_assert( ! stepX + ! stepY + ! stepZ == 2, "Only one of the steps can be non-zero." ); - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( - entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - < entity.getMesh().getDimensions() + CoordinatesType( ( stepX > 0 ), ( stepY > 0 ), ( stepZ > 0 ) ), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( " - "stepZ < 0 ) ) = " - << entity.getCoordinates() - + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ), - entity.getCoordinates().y() + stepY + ( stepY < 0 ), - entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ), - EntityOrientationType( stepX ? ( stepX > 0 ? 1 : -1 ) : 0, - stepY ? ( stepY > 0 ? 1 : -1 ) : 0, - stepZ ? ( stepZ > 0 ? 1 : -1 ) : 0 ), - EntityBasisType( ! stepX, ! stepY, ! stepZ ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( this->entity.getMesh(), getEntity< stepX, stepY, stepZ >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** TODO: Finish it, knonw it is only a copy of specialization for none stored stencil - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 3 | 2 | Cross | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >, - 2, - GridEntityStencilStorageTag< GridEntityCrossStencil > > -{ -public: - static constexpr int EntityDimension = 3; - static constexpr int NeighborEntityDimension = 2; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - using EntityOrientationType = typename GridEntityType::EntityOrientationType; - using EntityBasisType = typename GridEntityType::EntityBasisType; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - static_assert( ! stepX + ! stepY + ! stepZ == 2, "Only one of the steps can be non-zero." ); - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( - entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - < entity.getMesh().getDimensions() + CoordinatesType( ( stepX > 0 ), ( stepY > 0 ), ( stepZ > 0 ) ), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( " - "stepZ < 0 ) ) = " - << entity.getCoordinates() - + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ), - entity.getCoordinates().y() + stepY + ( stepY < 0 ), - entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ), - EntityOrientationType( stepX ? ( stepX > 0 ? 1 : -1 ) : 0, - stepY ? ( stepY > 0 ? 1 : -1 ) : 0, - stepZ ? ( stepZ > 0 ? 1 : -1 ) : 0 ), - EntityBasisType( ! stepX, ! stepY, ! stepZ ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( this->entity.getMesh(), getEntity< stepX, stepY, stepZ >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 3 | 1 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >, - 1, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 3; - static constexpr int NeighborEntityDimension = 1; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - using EntityOrientationType = typename GridEntityType::EntityOrientationType; - using EntityBasisType = typename GridEntityType::EntityBasisType; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - static_assert( ! stepX + ! stepY + ! stepZ == 1, "Exactly two of the steps must be non-zero." ); - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( - entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - < entity.getMesh().getDimensions() + CoordinatesType( ( stepX > 0 ), ( stepY > 0 ), ( stepZ > 0 ) ), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( " - "stepZ < 0 ) ) = " - << entity.getCoordinates() - + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ), - entity.getCoordinates().y() + stepY + ( stepY < 0 ), - entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ), - EntityOrientationType( ! ! stepX, ! ! stepY, ! ! stepZ ), - EntityBasisType( ! stepX, ! stepY, ! stepZ ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( this->entity.getMesh(), getEntity< stepX, stepY, stepZ >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 3 | 0 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 3, Config >, - 0, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 3; - static constexpr int NeighborEntityDimension = 0; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT( stepX != 0 && stepY != 0 && stepZ != 0, - std::cerr << " stepX = " << stepX << " stepY = " << stepY << " stepZ = " << stepZ ); - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( - entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - < entity.getMesh().getDimensions() + CoordinatesType( ( stepX > 0 ), ( stepY > 0 ), ( stepZ > 0 ) ), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( " - "stepZ < 0 ) ) = " - << entity.getCoordinates() - + CoordinatesType( stepX + ( stepX < 0 ), stepY + ( stepY < 0 ), stepZ + ( stepZ < 0 ) ) - << " entity.getMesh().getDimensions() + CoordinatesType( sign( stepX ), sign( stepY ), sign( stepZ ) ) = " - << entity.getMesh().getDimensions() + CoordinatesType( sign( stepX ), sign( stepY ), sign( stepZ ) ) - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX + ( stepX < 0 ), - entity.getCoordinates().y() + stepY + ( stepY < 0 ), - entity.getCoordinates().z() + stepZ + ( stepZ < 0 ) ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( entity.getMesh(), getEntity< stepX, stepY, stepZ >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 2 | 3 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 2, Config >, - 3, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 2; - static constexpr int NeighborEntityDimension = 3; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - /*TNL_ASSERT( ( ( !! stepX ) == ( !! entity.getOrientation().x() ) ) && - ( ( !! stepY ) == ( !! entity.getOrientation().y() ) ) && - ( ( !! stepZ ) == ( !! entity.getOrientation().z() ) ), - std::cerr << "( stepX, stepY, stepZ ) cannot be perpendicular to entity coordinates: stepX = " << stepX - << " stepY = " << stepY << " stepZ = " << stepZ - << " entity.getOrientation() = " << entity.getOrientation() );*/ - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LT( - entity.getCoordinates(), entity.getMesh().getDimensions() + TNL::abs( entity.getOrientation() ), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() - + CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), - stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ), - stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) - >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() - + CoordinatesType( stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), - stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ), - stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) - < entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX + ( stepX < 0 ) * ( " - "entity.getOrientation().x() != 0.0 ), stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != " - "0.0 ), stepZ + ( stepZ < 0 ) * ( entity.getOrientation().z() != 0.0 ) ) = " - << entity.getCoordinates() - + CoordinatesType( stepX + ( stepX < 0 ) * ( entity.getOrientation().x() != 0.0 ), - stepY + ( stepY < 0 ) * ( entity.getOrientation().y() != 0.0 ), - stepZ + ( stepZ < 0 ) * ( entity.getOrientation().z() != 0.0 ) ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( - this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX - ( stepX > 0 ) * ( entity.getOrientation().x() != 0.0 ), - entity.getCoordinates().y() + stepY - ( stepY > 0 ) * ( entity.getOrientation().y() != 0.0 ), - entity.getCoordinates().z() + stepZ - ( stepZ > 0 ) * ( entity.getOrientation().z() != 0.0 ) ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - return GridEntityGetterType::getEntityIndex( entity.getMesh(), getEntity< stepX, stepY, stepZ >() ); - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -/**** - * +-----------------+---------------------------+-------------------+ - * | EntityDimenions | NeighborEntityDimension | Stored Stencil | - * +-----------------+---------------------------+-------------------+ - * | 0 | 0 | None | - * +-----------------+---------------------------+-------------------+ - */ -template< typename Real, typename Device, typename Index, typename Config > -class NeighborGridEntityGetter< GridEntity< Meshes::Grid< 3, Real, Device, Index >, 0, Config >, - 0, - GridEntityStencilStorageTag< GridEntityNoStencil > > -{ -public: - static constexpr int EntityDimension = 0; - static constexpr int NeighborEntityDimension = 0; - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridEntityType = GridEntity< GridType, EntityDimension, Config >; - using NeighborGridEntityType = GridEntity< GridType, NeighborEntityDimension, Config >; - using RealType = Real; - using IndexType = Index; - using CoordinatesType = typename GridType::CoordinatesType; - using GridEntityGetterType = GridEntityGetter< GridType, NeighborGridEntityType >; - - __cuda_callable__ - inline NeighborGridEntityGetter( const GridEntityType& entity ) : entity( entity ) {} - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline NeighborGridEntityType - getEntity() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return NeighborGridEntityType( this->entity.getMesh(), - CoordinatesType( entity.getCoordinates().x() + stepX, - entity.getCoordinates().y() + stepY, - entity.getCoordinates().z() + stepZ ) ); - } - - template< int stepX, int stepY, int stepZ > - __cuda_callable__ - inline IndexType - getEntityIndex() const - { - TNL_ASSERT_GE( entity.getCoordinates(), CoordinatesType( 0, 0, 0 ), "wrong coordinates" ); - TNL_ASSERT_LE( entity.getCoordinates(), entity.getMesh().getDimensions(), "wrong coordinates" ); - TNL_ASSERT( entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) >= CoordinatesType( 0, 0, 0 ) - && entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) <= entity.getMesh().getDimensions(), - std::cerr << "entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) = " - << entity.getCoordinates() + CoordinatesType( stepX, stepY, stepZ ) - << " entity.getMesh().getDimensions() = " << entity.getMesh().getDimensions() - << " EntityDimension = " << EntityDimension ); - return this->entity.getIndex() - + stepZ * ( entity.getMesh().getDimensions().y() + 1 + stepY ) * ( entity.getMesh().getDimensions().x() + 1 ) - + stepX; - } - - __cuda_callable__ - void - refresh( const GridType& grid, const IndexType& entityIndex ){}; - -protected: - const GridEntityType& entity; - - // NeighborGridEntityGetter(){}; -}; - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h b/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h new file mode 100644 index 0000000000000000000000000000000000000000..f50903ce2397cb6c12ca11ea940c33b6f50ebed2 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/NeighbourGridEntityGetter.h @@ -0,0 +1,25 @@ +/*************************************************************************** + NeighbourGridEntityGetter.h - description + ------------------- + begin : Nov 23, 2015 + copyright : (C) 2015 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +namespace TNL { +namespace Meshes { + +template +class GridEntity; + +template +class NeighbourGridEntityGetter; + +} // namespace Meshes +} // namespace TNL + +#include diff --git a/src/TNL/Meshes/GridDetails/Templates/BooleanOperations.h b/src/TNL/Meshes/GridDetails/Templates/BooleanOperations.h new file mode 100644 index 0000000000000000000000000000000000000000..70ad23f6165478229c72d04d346d42c3989182f3 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Templates/BooleanOperations.h @@ -0,0 +1,48 @@ + +#pragma once + +#include + +namespace TNL { +namespace Meshes { +namespace Templates { + +/** + * One of the possible implementation of the conjuction operator. + * + * This one is taken from https://en.cppreference.com/w/cpp/types/conjunction + */ + +template +struct conjuction : std::true_type {}; + +template +struct conjuction : Type {}; + +template +struct conjuction : std::conditional_t, Head> {}; + +template +constexpr bool conjunction_v = conjuction::value; + +/** + * One of the possible implementation of the conjuction operator. + * + * This one is taken from https://en.cppreference.com/w/cpp/types/disjunction + */ + +template +struct disjunction : std::false_type {}; + +template +struct disjunction : Type {}; + +template +struct disjunction : std::conditional_t> {}; + +template +constexpr bool disjunction_v = disjunction::value; + +} // namespace Templates +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Templates/DescendingFor.h b/src/TNL/Meshes/GridDetails/Templates/DescendingFor.h new file mode 100644 index 0000000000000000000000000000000000000000..d9cae8b04b9d15f26cb5b5afdf003e5033785923 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Templates/DescendingFor.h @@ -0,0 +1,43 @@ + +#pragma once + +#include + +namespace TNL { +namespace Meshes { +namespace Templates { + +/* + * A compiler-friendly implementation of the templated for-cycle, because + * the template specializations count is O(Value) bounded. + */ +template +struct DescendingFor; + +template +struct DescendingFor { + public: + template + inline + static void exec(Func&& func, FuncArgs&&... args) { + static_assert(Value > 0, "Couldn't descend for negative values"); + + func(std::integral_constant(), std::forward(args)...); + + DescendingFor::exec(std::forward(func), std::forward(args)...); + } +}; + +template <> +struct DescendingFor<0> { + public: + template + inline + static void exec(Func&& func, FuncArgs&&... args) { + func(std::integral_constant(), std::forward(args)...); + } +}; + +} // namespace Templates +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Templates/ForEachOrientation.h b/src/TNL/Meshes/GridDetails/Templates/ForEachOrientation.h new file mode 100644 index 0000000000000000000000000000000000000000..cb0eedce916098d1f8af3f1e7ed39d078c06cdc5 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Templates/ForEachOrientation.h @@ -0,0 +1,62 @@ + +#pragma once + +#include + +namespace TNL { +namespace Meshes { +namespace Templates { + +template +struct _ForEachOrientationMain; + +template +struct _ForEachOrientationSupport { + using BasisGetterType = BasisGetter; + + public: + template + inline static void exec(Func func) { + func(std::integral_constant(), BasisGetterType::template getBasis()); + + _ForEachOrientationMain::exec(func); + } +}; + +template +struct _ForEachOrientationSupport { + public: + using BasisGetterType = BasisGetter; + + template + inline static void exec(Func func) { + func(std::integral_constant(), BasisGetterType::template getBasis<0>()); + } +}; + +template +struct _ForEachOrientationSupport { + public: + template + inline static void exec(Func func) {} +}; + +template +struct _ForEachOrientationMain + : std::conditional_t, + _ForEachOrientationSupport> {}; + +template +struct ForEachOrientation : _ForEachOrientationMain {}; +} // namespace Templates +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Templates/ParallelFor.h b/src/TNL/Meshes/GridDetails/Templates/ParallelFor.h new file mode 100644 index 0000000000000000000000000000000000000000..eb257204a33c8c159306cedae83191a3c0e99a99 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Templates/ParallelFor.h @@ -0,0 +1,78 @@ + +#pragma once + +#include +#include + +namespace TNL { +namespace Meshes { +namespace Templates { + +/** + * A dimension-based interface of ParallelFor algorithm + */ +template +struct ParallelFor; + +template +struct ParallelFor<1, Device, Index> { + public: + template + inline + static void exec(const TNL::Containers::StaticVector<1, Index>& from, + const TNL::Containers::StaticVector<1, Index>& to, + Func func, + FuncArgs... args) { + auto groupIndex = [=] __cuda_callable__ (Index i, FuncArgs... args) mutable { + func(TNL::Containers::StaticVector<1, Index>(i), args...); + }; + + TNL::Algorithms::ParallelFor::exec(from.x(), to.x(), + groupIndex, + args...); + } +}; + +template +struct ParallelFor<2, Device, Index> { + public: + template + inline + static void exec(const TNL::Containers::StaticVector<2, Index>& from, + const TNL::Containers::StaticVector<2, Index>& to, + Func func, + FuncArgs... args) { + auto groupIndex = [=] __cuda_callable__ (Index i, Index j, FuncArgs... args) mutable { + func(TNL::Containers::StaticVector<2, Index>(i, j), args...); + }; + + TNL::Algorithms::ParallelFor2D::exec(from.x(), from.y(), + to.x(), to.y(), + groupIndex, + args...); + } +}; + +template +struct ParallelFor<3, Device, Index> { + public: + template + inline + static void exec(const TNL::Containers::StaticVector<3, Index>& from, + const TNL::Containers::StaticVector<3, Index>& to, + Func func, + FuncArgs... args) { + auto groupIndex = [=] __cuda_callable__ (Index i, Index j, Index k, FuncArgs... args) mutable { + func(TNL::Containers::StaticVector<3, Index>(i, j, k), args...); + }; + + TNL::Algorithms::ParallelFor3D::exec(from.x(), from.y(), from.z(), + to.x(), to.y(), to.z(), + groupIndex, + args...); + } +}; + +} +} +} diff --git a/src/TNL/Meshes/GridDetails/Templates/Permutations.h b/src/TNL/Meshes/GridDetails/Templates/Permutations.h new file mode 100644 index 0000000000000000000000000000000000000000..af18b625c72b5f6aaf10442385a097b6353c1a42 --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Templates/Permutations.h @@ -0,0 +1,266 @@ + +#pragma once + +#include +#include + +namespace TNL { +namespace Meshes { +namespace Templates { + +/* + * A pack of type and its count + */ +template +struct counted_pack {}; + +/* + * A pack of types + */ +template +struct pack {}; + +/* + * A pack of int values + */ +template +struct int_pack {}; + +/** + * A merge operation between to packs. + * + * Merge -> type + * Merge, pack> -> pack + * Merge, int_pack> -> int_pack + * Merge, pack, ..., pack> -> pack + * Merge, int_pack, ..., int_pack> -> int_pack + */ + +template +struct Merge; + +template +struct Merge

{ + public: + using type = P; +}; + +template +struct Merge, pack> { + public: + using type = pack; +}; + +template +struct Merge, int_pack> { + public: + using type = int_pack; +}; + +template +struct Merge : Merge::type> {}; + +template +using merge = typename Merge::type; + +/** + * Prepends a type to a parameter pack + */ + +template +struct Prepend {}; + +template +struct Prepend> { + using type = pack; +}; + +template +using prepend = typename Prepend::type; + +/** + * Pushes type to the CountedTypes pack. + * + * If type exists in the CountedTypes pack, then will increment a count of type. + * Otherwise appends a type to the CountedTypes pack. + */ + +template +struct Push; + +template +struct Push...>> { + public: + using type = std::conditional_t...>::value, + pack::value ? 1 : 0)>...>, + pack..., counted_pack>>; +}; + +template +using push = typename Push::type; + +/** + * Removes first occurance of type in the pack + */ + +template +struct RemoveFirst; + +template +struct RemoveFirst> { + public: + using type = pack<>; +}; + +template +using remove_first = typename RemoveFirst::type; + +template +struct RemoveFirst> { + public: + using type = std::conditional_t::value, pack, prepend>>>; +}; + +/* + * Pops type out of the CountedTypes pack. + * + * If type exists in the CountedTypes pack, then decrease it count by one. + * If the count of type in the CountedTypes pack is zero, then pop it. + */ +template +struct Pop; + +template +struct Pop...>> { + using type = remove_first, pack::value ? 1 : 0)>...>>; +}; + +template +using pop = typename Pop::type; + +/* + * Builds CountedTypes pack by counting the occurances of the types in input. + */ +template > +struct CountTypes { + using type = CountedTypes; +}; + +template +struct CountTypes, CountedTypes> : CountTypes, push> {}; + +// For int_pack count every int value as a separate type (push) +template +struct CountTypes, CountedTypes> : CountTypes, push, CountedTypes>> {}; + +template +using count_types = typename CountTypes::type; + +/* + * An identity type + */ +template +struct identity { + using type = T; +}; + +/** + * Generates all permutations with repetitions of length N from the pack of types. + * + * Thanks for idea: https://stackoverflow.com/questions/36465889/permutation-pn-r-of-types-in-compile-time + */ + +template > +struct MakePermutations; + +// Workaround for GCC's partial ordering failure +template +struct MakePermutationsImpl; + +template +struct MakePermutationsImpl...>, pack> { + // The next item can be anything in Types... + // We append it to Current... and pop it from the list of types, then + // recursively generate the remaining items + // Do this for every type in Types..., and concatenate the result. + using type = merge...>>, pack>::type...>; +}; + +template +struct MakePermutations...>, pack> { + // Note that we don't attempt to evaluate MakePermutationsImpl<...>::type + // until we are sure that N > 0 + using type = typename std::conditional_t>>, + MakePermutationsImpl...>, pack>>::type; +}; + +template +using make_permutations = typename MakePermutations>::type; + +/* + * Recursively goes through pack tree and merges specified level. + */ + +template +struct GroupLevel {}; + +template +struct GroupLevel> { + using type = pack::type...>; +}; + +template +struct GroupLevel<0, pack> { + using type = merge; +}; + +template +using group_level = typename GroupLevel::type; + +/* + * A support for the int_pack permutations. + * The result of make_permutations is pack, int_pack<>...>, ...>, that's why we merge the 1 level. + */ +template +using make_int_permutations = group_level<1, make_permutations>; + +/** + * Builds the pack with k ones at the end. + */ +template > +struct BuildOnesPack; + +template +struct BuildOnesPack> : std::conditional_t>, + BuildOnesPack>> {}; + +template +struct BuildOnesPack> { + public: + using type = int_pack; +}; + +template +using build_ones_pack = typename BuildOnesPack::type; + +/* + * Gets specific element from the parameter pack + */ +template +struct Get; + +template +struct Get> : Get> {}; + +template +struct Get<0, pack> { + public: + using type = Head; +}; + +template +using get = typename Get::type; + +} +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Templates/Templates.h b/src/TNL/Meshes/GridDetails/Templates/Templates.h new file mode 100644 index 0000000000000000000000000000000000000000..b5552d34edd5b8364f6e5b0dff97fb717458828f --- /dev/null +++ b/src/TNL/Meshes/GridDetails/Templates/Templates.h @@ -0,0 +1,96 @@ + +#pragma once + +#include +#include + +namespace TNL { +namespace Meshes { +namespace Templates { + +constexpr size_t pow(size_t Value, size_t Power) { + size_t result = 1; + + for (size_t i = 0; i < Power; i++) result *= Value; + + return result; +} + +template +constexpr Index product(Index from, Index to) { + Index result = 1; + + if (from <= to) + for (Index i = from; i <= to; i++) result *= i; + + return result; +} + +template +constexpr Index combination(Index k, Index n) { + return product(k + 1, n) / product(1, n - k); +} + +/** + * @brief A help method to calculate collapsed index the next way: + * base ^ 0 * (power_0 + base/2) + base ^ 1 * (power_1 + base/2) + * + * @tparam Powers + * @param base - base value of the series + * @param powers - powers values + * @return constexpr int + */ +template +constexpr Index makeCollapsedIndex(const Index base, const TNL::Containers::StaticVector powers) { + Index index = 0; + Index currentBase = 1; + Index halfBase = base >> 1; + + for (Index i = 0; i < powers.getSize(); i++) { + index += (powers[i] + halfBase) * currentBase; + currentBase *= base; + } + + return index; +} + +template +constexpr Index makeCollapsedIndex(const int base) { + Index index = 0; + Index currentBase = 1; + Index halfBase = base >> 1; + + for (const auto x: { Powers... }) { + index += (x + halfBase) * currentBase; + currentBase *= base; + } + + return index; +} + +template +constexpr Index firstKCombinationSum(Index k, Index n) { + if (k == 0) return 0; + + if (k == n) return (1 << n) - 1; + + Index result = 0; + + // Fraction simplification of k-combination + for (Index i = 0; i < k; i++) + result += combination(i, n); + + return result; +} + +constexpr bool isInClosedInterval(int lower, int value, int upper) { + return lower <= value && value <= upper; +} + +constexpr bool isInLeftClosedRightOpenInterval(int lower, int value, int upper) { + return lower <= value && value < upper; +} + +} // namespace Templates +} // namespace Meshes +} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid1D.h b/src/TNL/Meshes/GridDetails/Traverser_Grid1D.h deleted file mode 100644 index 67b7cc619a4d601a4113358d5c9f8916488ffc76..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Traverser_Grid1D.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 > -{ -public: - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 > -{ -public: - using GridType = Meshes::Grid< 1, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -} // namespace Meshes -} // namespace TNL - -#include diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Traverser_Grid1D_impl.h deleted file mode 100644 index 2ddfbffcee8a65ea9555123d5992150de85cddc6..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Traverser_Grid1D_impl.h +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include - -namespace TNL { -namespace Meshes { - -/**** - * Grid 1D, cells - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary cells - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimensions." ); - - if( gridPointer->getLocalBegin() < gridPointer->getInteriorBegin() - && gridPointer->getInteriorEnd() < gridPointer->getLocalEnd() ) - { - // 2 boundaries (left and right) - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true >( - gridPointer, gridPointer->getInteriorBegin() - 1, gridPointer->getInteriorEnd() + 1, userData, asynchronousMode ); - } - else if( gridPointer->getLocalBegin() < gridPointer->getInteriorBegin() ) { - // 1 boundary (left) - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getInteriorBegin() - 1, gridPointer->getInteriorBegin(), userData, asynchronousMode ); - } - else if( gridPointer->getInteriorEnd() < gridPointer->getLocalEnd() ) { - // 1 boundary (right) - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getInteriorEnd(), gridPointer->getInteriorEnd() + 1, userData, asynchronousMode ); - } -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior cells - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getInteriorBegin(), gridPointer->getInteriorEnd(), userData, asynchronousMode ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 1 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All cells - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimensions." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getLocalBegin(), gridPointer->getLocalEnd(), userData, asynchronousMode ); -} - -/**** - * Grid 1D, vertices - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true >( - gridPointer, CoordinatesType( 0 ), gridPointer->getDimensions() + 1, userData, asynchronousMode ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, CoordinatesType( 1 ), gridPointer->getDimensions(), userData, asynchronousMode ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 1, Real, Device, Index >, GridEntity, 0 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, CoordinatesType( 0 ), gridPointer->getDimensions() + 1, userData, asynchronousMode ); -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid2D.h b/src/TNL/Meshes/GridDetails/Traverser_Grid2D.h deleted file mode 100644 index 0473c1236b8b219ab655789abaade6d941b8ebac..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Traverser_Grid2D.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 > -{ -public: - using GridType = Meshes::Grid< 2, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -} // namespace Meshes -} // namespace TNL - -#include diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Traverser_Grid2D_impl.h deleted file mode 100644 index 56740c4c964ae78b6bf36a9ef7ef694283e64e2c..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Traverser_Grid2D_impl.h +++ /dev/null @@ -1,253 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include - -namespace TNL { -namespace Meshes { - -/**** - * Grid 2D, cells - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary cells - */ - static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." ); - - if( gridPointer->getLocalBegin() < gridPointer->getInteriorBegin() - && gridPointer->getInteriorEnd() < gridPointer->getLocalEnd() ) - { - // 4 boundaries (left, right, down, up) - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1 >( - gridPointer, gridPointer->getInteriorBegin() - 1, gridPointer->getInteriorEnd() + 1, userData, asynchronousMode, 0 ); - } - else { - const CoordinatesType begin = gridPointer->getLocalBegin(); - const CoordinatesType end = gridPointer->getLocalEnd(); - const CoordinatesType skipBegin = gridPointer->getInteriorBegin(); - const CoordinatesType skipEnd = gridPointer->getInteriorEnd(); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, begin, CoordinatesType( end.x(), skipBegin.y() ), userData, asynchronousMode, 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, CoordinatesType( begin.x(), skipEnd.y() ), end, userData, asynchronousMode, 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( begin.x(), skipBegin.y() ), - CoordinatesType( skipBegin.x(), skipEnd.y() ), - userData, - asynchronousMode, - 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( skipEnd.x(), skipBegin.y() ), - CoordinatesType( end.x(), skipEnd.y() ), - userData, - asynchronousMode, - 0 ); - } -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior cells - */ - static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimensions." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getInteriorBegin(), gridPointer->getInteriorEnd(), userData, asynchronousMode, 0 ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 2 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All cells - */ - static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getLocalBegin(), gridPointer->getLocalEnd(), userData, asynchronousMode, 0 ); -} - -/**** - * Grid 2D, faces - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary faces - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 0 ), - userData, - asynchronousMode, - 1, - CoordinatesType( 1, 0 ), - CoordinatesType( 0, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 1 ), - userData, - asynchronousMode, - 0, - CoordinatesType( 0, 1 ), - CoordinatesType( 1, 0 ) ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior faces - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 1, 0 ), - gridPointer->getDimensions(), - userData, - asynchronousMode, - 1, - CoordinatesType( 1, 0 ), - CoordinatesType( 0, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 1 ), - gridPointer->getDimensions(), - userData, - asynchronousMode, - 0, - CoordinatesType( 0, 1 ), - CoordinatesType( 1, 0 ) ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 1 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All faces - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 0 ), - userData, - asynchronousMode, - 1, - CoordinatesType( 1, 0 ), - CoordinatesType( 0, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 1 ), - userData, - asynchronousMode, - 0, - CoordinatesType( 0, 1 ), - CoordinatesType( 1, 0 ) ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1 >( - gridPointer, - CoordinatesType( 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 1 ), - userData, - asynchronousMode, - 0 ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, CoordinatesType( 1, 1 ), gridPointer->getDimensions(), userData, asynchronousMode, 0 ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 2, Real, Device, Index >, GridEntity, 0 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 1 ), - userData, - asynchronousMode, - 0 ); -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid3D.h b/src/TNL/Meshes/GridDetails/Traverser_Grid3D.h deleted file mode 100644 index 002f63203e27649ab5280ccd40a05cd20fa49b96..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Traverser_Grid3D.h +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include - -namespace TNL { -namespace Meshes { - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -template< typename Real, typename Device, typename Index, typename GridEntity > -class Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 > -{ -public: - using GridType = Meshes::Grid< 3, Real, Device, Index >; - using GridPointer = Pointers::SharedPointer< GridType >; - using CoordinatesType = typename GridType::CoordinatesType; - - template< typename EntitiesProcessor, typename UserData > - void - processBoundaryEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processInteriorEntities( const GridPointer& gridPointer, UserData& userData ) const; - - template< typename EntitiesProcessor, typename UserData > - void - processAllEntities( const GridPointer& gridPointer, UserData& userData ) const; -}; - -} // namespace Meshes -} // namespace TNL - -#include diff --git a/src/TNL/Meshes/GridDetails/Traverser_Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Traverser_Grid3D_impl.h deleted file mode 100644 index f00b4dec391dbc7b3f865c166378329cc61e5139..0000000000000000000000000000000000000000 --- a/src/TNL/Meshes/GridDetails/Traverser_Grid3D_impl.h +++ /dev/null @@ -1,441 +0,0 @@ -// Copyright (c) 2004-2022 Tomáš Oberhuber et al. -// -// This file is part of TNL - Template Numerical Library (https://tnl-project.org/) -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include - -#include "Traverser_Grid3D.h" - -namespace TNL { -namespace Meshes { - -/**** - * Grid 3D, cells - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary cells - */ - static_assert( GridEntity::getEntityDimension() == 3, "The entity has wrong dimension." ); - - if( gridPointer->getLocalBegin() < gridPointer->getInteriorBegin() - && gridPointer->getInteriorEnd() < gridPointer->getLocalEnd() ) - { - // 6 boundaries (left, right, down, up, front, back) - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 1 >( - gridPointer, gridPointer->getInteriorBegin() - 1, gridPointer->getInteriorEnd() + 1, userData, asynchronousMode, 0 ); - } - else { - const CoordinatesType begin = gridPointer->getLocalBegin(); - const CoordinatesType end = gridPointer->getLocalEnd(); - const CoordinatesType skipBegin = gridPointer->getInteriorBegin(); - const CoordinatesType skipEnd = gridPointer->getInteriorEnd(); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, begin, CoordinatesType( end.x(), end.y(), skipBegin.z() ), userData, asynchronousMode, 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, CoordinatesType( begin.x(), begin.y(), skipEnd.z() ), end, userData, asynchronousMode, 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( begin.x(), begin.y(), skipBegin.z() ), - CoordinatesType( end.x(), skipBegin.y(), skipEnd.z() ), - userData, - asynchronousMode, - 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( begin.x(), skipEnd.y(), skipBegin.z() ), - CoordinatesType( end.x(), end.y(), skipEnd.z() ), - userData, - asynchronousMode, - 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( begin.x(), skipBegin.y(), skipBegin.z() ), - CoordinatesType( skipBegin.x(), skipEnd.y(), skipEnd.z() ), - userData, - asynchronousMode, - 0 ); - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( skipEnd.x(), skipBegin.y(), skipBegin.z() ), - CoordinatesType( end.x(), skipEnd.y(), skipEnd.z() ), - userData, - asynchronousMode, - 0 ); - } -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior cells - */ - static_assert( GridEntity::getEntityDimension() == 3, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getInteriorBegin(), gridPointer->getInteriorEnd(), userData, asynchronousMode, 0 ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 3 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All cells - */ - static_assert( GridEntity::getEntityDimension() == 3, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, gridPointer->getLocalBegin(), gridPointer->getLocalEnd(), userData, asynchronousMode, 0 ); -} - -/**** - * Grid 3D, faces - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary faces - */ - static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0, 0, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 0, 0 ), - userData, - asynchronousMode, - 2, - CoordinatesType( 1, 0, 0 ), - CoordinatesType( 0, 1, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 1, 0, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 1, 0 ), - userData, - asynchronousMode, - 1, - CoordinatesType( 0, 1, 0 ), - CoordinatesType( 1, 0, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 0, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 0, 1 ), - userData, - asynchronousMode, - 0, - CoordinatesType( 0, 0, 1 ), - CoordinatesType( 1, 1, 0 ) ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior faces - */ - static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 1, 0, 0 ), - gridPointer->getDimensions(), - userData, - asynchronousMode, - 2, - CoordinatesType( 1, 0, 0 ), - CoordinatesType( 0, 1, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 1, 0 ), - gridPointer->getDimensions(), - userData, - asynchronousMode, - 1, - CoordinatesType( 0, 1, 0 ), - CoordinatesType( 1, 0, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 1 ), - gridPointer->getDimensions(), - userData, - asynchronousMode, - 0, - CoordinatesType( 0, 0, 1 ), - CoordinatesType( 1, 1, 0 ) ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 2 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All faces - */ - static_assert( GridEntity::getEntityDimension() == 2, "The entity has wrong dimension." ); - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 0, 0 ), - userData, - asynchronousMode, - 2, - CoordinatesType( 1, 0, 0 ), - CoordinatesType( 0, 1, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 1, 0 ), - userData, - asynchronousMode, - 1, - CoordinatesType( 0, 1, 0 ), - CoordinatesType( 1, 0, 1 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 0, 1 ), - userData, - asynchronousMode, - 0, - CoordinatesType( 0, 0, 1 ), - CoordinatesType( 1, 1, 0 ) ); -} - -/**** - * Grid 3D, edges - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary edges - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 0, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 1, 1 ), - userData, - asynchronousMode, - 2, - CoordinatesType( 0, 1, 1 ), - CoordinatesType( 1, 0, 0 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 0, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 0, 1 ), - userData, - asynchronousMode, - 1, - CoordinatesType( 1, 0, 1 ), - CoordinatesType( 0, 1, 0 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 0, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 1, 0 ), - userData, - asynchronousMode, - 0, - CoordinatesType( 1, 1, 0 ), - CoordinatesType( 0, 0, 1 ) ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior edges - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 1, 1 ), - gridPointer->getDimensions() + CoordinatesType( 1, 0, 0 ), - userData, - asynchronousMode, - 2, - CoordinatesType( 0, 1, 1 ), - CoordinatesType( 1, 0, 0 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 1, 0, 1 ), - gridPointer->getDimensions() + CoordinatesType( 0, 1, 0 ), - userData, - asynchronousMode, - 1, - CoordinatesType( 1, 0, 1 ), - CoordinatesType( 0, 1, 0 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 1, 1, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 0, 1 ), - userData, - asynchronousMode, - 0, - CoordinatesType( 1, 1, 0 ), - CoordinatesType( 0, 0, 1 ) ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 1 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All edges - */ - static_assert( GridEntity::getEntityDimension() == 1, "The entity has wrong dimension." ); - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 0, 1, 1 ), - userData, - asynchronousMode, - 2, - CoordinatesType( 0, 1, 1 ), - CoordinatesType( 1, 0, 0 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 0, 1 ), - userData, - asynchronousMode, - 1, - CoordinatesType( 1, 0, 1 ), - CoordinatesType( 0, 1, 0 ) ); - - GridTraverser< GridType >:: - template processEntities< GridEntity, EntitiesProcessor, UserData, false, 1, 1, 1, CoordinatesType, CoordinatesType >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 1, 0 ), - userData, - asynchronousMode, - 0, - CoordinatesType( 1, 1, 0 ), - CoordinatesType( 0, 0, 1 ) ); -} - -/**** - * Grid 3D, vertices - */ -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >::processBoundaryEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Boundary vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, true, 1, 1, 1 >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 1, 1 ), - userData, - asynchronousMode, - 0 ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >::processInteriorEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * Interior vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, CoordinatesType( 1, 1, 1 ), gridPointer->getDimensions(), userData, asynchronousMode, 0 ); -} - -template< typename Real, typename Device, typename Index, typename GridEntity > -template< typename EntitiesProcessor, typename UserData > -void -Traverser< Meshes::Grid< 3, Real, Device, Index >, GridEntity, 0 >::processAllEntities( const GridPointer& gridPointer, - UserData& userData ) const -{ - /**** - * All vertices - */ - static_assert( GridEntity::getEntityDimension() == 0, "The entity has wrong dimension." ); - - GridTraverser< GridType >::template processEntities< GridEntity, EntitiesProcessor, UserData, false >( - gridPointer, - CoordinatesType( 0, 0, 0 ), - gridPointer->getDimensions() + CoordinatesType( 1, 1, 1 ), - userData, - asynchronousMode, - 0 ); -} - -} // namespace Meshes -} // namespace TNL diff --git a/src/TNL/Meshes/GridEntity.h b/src/TNL/Meshes/GridEntity.h index a7c863db5445a2b162445fbf5a0ddd975ece88ae..dd710be6b357b84ce25b1c704a0c046c1a4d6558 100644 --- a/src/TNL/Meshes/GridEntity.h +++ b/src/TNL/Meshes/GridEntity.h @@ -6,415 +6,157 @@ #pragma once -#include -#include +#include namespace TNL { namespace Meshes { -template< typename GridEntity, int NeighborEntityDimension, typename StencilStorage > -class NeighborGridEntityGetter; +template +class NeighbourGridEntityGetter; -template< typename GridEntityType > +template class BoundaryGridEntityChecker; -template< typename GridEntityType > +template class GridEntityCenterGetter; -template< typename Grid, int EntityDimension, typename Config > -class GridEntity -{}; - -template< int Dimension, typename Real, typename Device, typename Index, int EntityDimension, typename Config > -class GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config > -{ -public: - using GridType = Meshes::Grid< Dimension, Real, Device, Index >; - using MeshType = GridType; - using RealType = typename GridType::RealType; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - using ConfigType = Config; - - constexpr static int - getMeshDimension() - { - return GridType::getMeshDimension(); - }; - - constexpr static int - getEntityDimension() - { - return EntityDimension; - }; - - using EntityOrientationType = Containers::StaticVector< getMeshDimension(), IndexType >; - using EntityBasisType = Containers::StaticVector< getMeshDimension(), IndexType >; - using PointType = typename GridType::PointType; - - using NeighborGridEntitiesStorageType = NeighborGridEntitiesStorage< GridEntity, Config >; - - template< int NeighborEntityDimension = getEntityDimension() > - using NeighborEntities = - NeighborGridEntityGetter< GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, EntityDimension, Config >, - NeighborEntityDimension >; - - __cuda_callable__ - inline GridEntity( const GridType& grid ); - - __cuda_callable__ - inline GridEntity( const GridType& grid, - const CoordinatesType& coordinates, - const EntityOrientationType& orientation, - const EntityBasisType& basis ); - - __cuda_callable__ - inline const CoordinatesType& - getCoordinates() const; - - __cuda_callable__ - inline CoordinatesType& - getCoordinates(); - - __cuda_callable__ - inline void - setCoordinates( const CoordinatesType& coordinates ); - - /*** - * Call this method every time the coordinates are changed - * to recompute the mesh entity index. The reason for this strange - * mechanism is a performance. - */ - __cuda_callable__ - inline - // void setIndex( IndexType entityIndex ); - void - refresh(); - - __cuda_callable__ - inline Index - getIndex() const; - - __cuda_callable__ - inline const EntityOrientationType& - getOrientation() const; - - __cuda_callable__ - inline void - setOrientation( const EntityOrientationType& orientation ); - - __cuda_callable__ - inline const EntityBasisType& - getBasis() const; - - __cuda_callable__ - inline void - setBasis( const EntityBasisType& basis ); - - template< int NeighborEntityDimension = getEntityDimension() > - __cuda_callable__ - inline const NeighborEntities< NeighborEntityDimension >& - getNeighborEntities() const; - - __cuda_callable__ - inline bool - isBoundaryEntity() const; - - __cuda_callable__ - inline PointType - getCenter() const; - - __cuda_callable__ - inline const RealType& - getMeasure() const; - - __cuda_callable__ - inline const GridType& - getMesh() const; - -protected: - const GridType& grid; - - IndexType entityIndex; - - CoordinatesType coordinates; - - EntityOrientationType orientation; - - EntityBasisType basis; - - NeighborGridEntitiesStorageType neighborEntitiesStorage; - - //__cuda_callable__ inline - // GridEntity(); - - friend class BoundaryGridEntityChecker< GridEntity >; - - friend class GridEntityCenterGetter< GridEntity >; -}; - -/**** - * Specializations for cells - */ -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -class GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config > -{ -public: - using GridType = Meshes::Grid< Dimension, Real, Device, Index >; - using MeshType = GridType; - using RealType = typename GridType::RealType; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - using PointType = typename GridType::PointType; - using ConfigType = Config; - - constexpr static int - getMeshDimension() - { - return GridType::getMeshDimension(); - }; - - constexpr static int - getEntityDimension() - { - return getMeshDimension(); - }; - - using EntityOrientationType = Containers::StaticVector< getMeshDimension(), IndexType >; - using EntityBasisType = Containers::StaticVector< getMeshDimension(), IndexType >; - using NeighborGridEntitiesStorageType = NeighborGridEntitiesStorage< GridEntity, Config >; - - template< int NeighborEntityDimension = getEntityDimension() > - using NeighborEntities = - NeighborGridEntityGetter< GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, Dimension, Config >, - NeighborEntityDimension >; - - __cuda_callable__ - inline GridEntity( const GridType& grid ); - - __cuda_callable__ - inline GridEntity( const GridType& grid, - const CoordinatesType& coordinates, - const EntityOrientationType& orientation = EntityOrientationType( (Index) 0 ), - const EntityBasisType& basis = EntityBasisType( (Index) 1 ) ); - - __cuda_callable__ - inline const CoordinatesType& - getCoordinates() const; - - __cuda_callable__ - inline CoordinatesType& - getCoordinates(); - - __cuda_callable__ - inline void - setCoordinates( const CoordinatesType& coordinates ); - - /*** - * Call this method every time the coordinates are changed - * to recompute the mesh entity index. The reason for this strange - * mechanism is a performance. - */ - __cuda_callable__ - inline - // void setIndex( IndexType entityIndex ); - void - refresh(); - - __cuda_callable__ - inline Index - getIndex() const; - - __cuda_callable__ - inline const EntityOrientationType - getOrientation() const; - - __cuda_callable__ - inline void - setOrientation( const EntityOrientationType& orientation ){}; - - __cuda_callable__ - inline const EntityBasisType - getBasis() const; - - __cuda_callable__ - inline void - setBasis( const EntityBasisType& basis ){}; - - template< int NeighborEntityDimension = Dimension > - __cuda_callable__ - inline const NeighborEntities< NeighborEntityDimension >& - getNeighborEntities() const; - - __cuda_callable__ - inline bool - isBoundaryEntity() const; - - __cuda_callable__ - inline PointType - getCenter() const; - - __cuda_callable__ - inline const RealType& - getMeasure() const; - - __cuda_callable__ - inline const PointType& - getEntityProportions() const; - - __cuda_callable__ - inline const GridType& - getMesh() const; - -protected: - const GridType& grid; - - IndexType entityIndex; - - CoordinatesType coordinates; - - NeighborGridEntitiesStorageType neighborEntitiesStorage; - - //__cuda_callable__ inline - // GridEntity(); - - friend class BoundaryGridEntityChecker< GridEntity >; - - friend class GridEntityCenterGetter< GridEntity >; -}; - -/**** - * Specialization for vertices - */ -template< int Dimension, typename Real, typename Device, typename Index, typename Config > -class GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config > -{ -public: - using GridType = Meshes::Grid< Dimension, Real, Device, Index >; - using MeshType = GridType; - using RealType = typename GridType::RealType; - using IndexType = typename GridType::IndexType; - using CoordinatesType = typename GridType::CoordinatesType; - using PointType = typename GridType::PointType; - using ConfigType = Config; - - constexpr static int - getMeshDimension() - { - return GridType::getMeshDimension(); - }; - - constexpr static int - getEntityDimension() - { - return 0; - }; - - using EntityOrientationType = Containers::StaticVector< getMeshDimension(), IndexType >; - using EntityBasisType = Containers::StaticVector< getMeshDimension(), IndexType >; - using NeighborGridEntitiesStorageType = NeighborGridEntitiesStorage< GridEntity, Config >; - - template< int NeighborEntityDimension = getEntityDimension() > - using NeighborEntities = NeighborGridEntityGetter< GridEntity< Meshes::Grid< Dimension, Real, Device, Index >, 0, Config >, - NeighborEntityDimension >; - - __cuda_callable__ - inline GridEntity( const GridType& grid ); - - __cuda_callable__ - inline GridEntity( const GridType& grid, - const CoordinatesType& coordinates, - const EntityOrientationType& orientation = EntityOrientationType( (Index) 0 ), - const EntityBasisType& basis = EntityOrientationType( (Index) 0 ) ); - - __cuda_callable__ - inline const CoordinatesType& - getCoordinates() const; - - __cuda_callable__ - inline CoordinatesType& - getCoordinates(); - - __cuda_callable__ - inline void - setCoordinates( const CoordinatesType& coordinates ); - - /*** - * Call this method every time the coordinates are changed - * to recompute the mesh entity index. The reason for this strange - * mechanism is a performance. - */ - __cuda_callable__ - inline - // void setIndex( IndexType entityIndex ); - void - refresh(); - - __cuda_callable__ - inline Index - getIndex() const; - - __cuda_callable__ - inline const EntityOrientationType - getOrientation() const; - - __cuda_callable__ - inline void - setOrientation( const EntityOrientationType& orientation ){}; - - __cuda_callable__ - inline const EntityBasisType - getBasis() const; - - __cuda_callable__ - inline void - setBasis( const EntityBasisType& basis ){}; - - template< int NeighborEntityDimension = getEntityDimension() > - __cuda_callable__ - inline const NeighborEntities< NeighborEntityDimension >& - getNeighborEntities() const; - - __cuda_callable__ - inline bool - isBoundaryEntity() const; - - __cuda_callable__ - inline PointType - getCenter() const; - - // compatibility with meshes, equivalent to getCenter - __cuda_callable__ - inline PointType - getPoint() const; - - __cuda_callable__ - inline const RealType - getMeasure() const; - - __cuda_callable__ - inline PointType - getEntityProportions() const; - - __cuda_callable__ - inline const GridType& - getMesh() const; - -protected: - const GridType& grid; - - IndexType entityIndex; - - CoordinatesType coordinates; - - NeighborGridEntitiesStorageType neighborEntitiesStorage; - - friend class BoundaryGridEntityChecker< GridEntity >; - - friend class GridEntityCenterGetter< GridEntity >; +template +class GridEntity { + public: + using GridType = Grid; + using Index = typename Grid::IndexType; + using Device = typename Grid::DeviceType; + using Real = typename Grid::RealType; + + using Coordinate = typename Grid::Coordinate; + using Point = typename Grid::Point; + + constexpr static int meshDimension = Grid::getMeshDimension(); + constexpr static int entityDimension = EntityDimension; + + __cuda_callable__ inline + GridEntity(const Grid& grid, + const Coordinate& coordinates, + const Coordinate& basis, + const Index orientation): grid(grid), coordinates(coordinates), basis(basis), orientation(orientation) {} + + __cuda_callable__ inline + const Coordinate& getCoordinates() const; + + __cuda_callable__ inline + Coordinate& getCoordinates(); + + __cuda_callable__ inline + void setCoordinates(const Coordinate& coordinates); + + /*** + * @brief - Recalculates entity index. + * + * @warning - Call this method every time the coordinates are changed + */ + __cuda_callable__ inline + void refresh(); + + /** + * @brief Get the entity index in global grid + */ + __cuda_callable__ inline + Index getIndex() const; + + /** + * @brief Tells, if entity is boundary + */ + __cuda_callable__ inline + bool isBoundary() const; + + /** + * @brief Returns, the center of the entity + */ + __cuda_callable__ inline + const Point getCenter() const; + + /** + * @brief Returns, the measure (volume) of the entity + */ + __cuda_callable__ inline + Real getMeasure() const; + + __cuda_callable__ inline + const Grid& getMesh() const; + + __cuda_callable__ inline + void setBasis(const Coordinate& orientation); + + /** + * @brief Returns, the entity basis + */ + __cuda_callable__ inline + const Coordinate& getBasis() const; + + /** + * @brief Returns, the entity orientation + * + * Orientation is always paired with the basis. In other words, if orientations, entityDimensions and dimensions are equal, then bases are equal also. + */ + __cuda_callable__ inline + Index getOrientation() const; + + /** + * @brief Returns, the neighbour entity + * + * @warning - In case, if the parent entity orientation is greater than possible orientations of neighbour entity, + * then orientation is reduces. For example, 3-d cell neighbour of edge with orientaiton 1, will have + * orientation 0 + * @warning - You should refresh index manually + */ + template = true> + __cuda_callable__ inline + GridEntity getNeighbourEntity() const; + + /** + * @brief Returns, the neighbour entity + * + * @warning - You should refresh index manually + */ + template = true> + __cuda_callable__ inline + GridEntity getNeighbourEntity() const; + + /** + * @brief Returns, the neighbour entity + * + * @warning - In case, if the parent entity orientation is greater than possible orientations of neighbour entity, + * then orientation is reduces. For example, 3-d cell neighbour of edge with orientaiton 1, will have + * orientation 0 + * @warning - You should refresh index manually + */ + template + __cuda_callable__ inline + GridEntity getNeighbourEntity(const Coordinate& offset) const; + + /** + * @brief Returns, the neighbour entity + * + * @warning - You should refresh index manually + */ + template + __cuda_callable__ inline + GridEntity getNeighbourEntity(const Coordinate& offset) const; + protected: + const Grid& grid; + + Index index; + Coordinate coordinates; + Coordinate basis; + Index orientation; }; } // namespace Meshes } // namespace TNL -#include +#include diff --git a/src/TNL/Meshes/GridDetails/GnuplotWriter.h b/src/TNL/Meshes/Writers/GnuplotWriter.h similarity index 100% rename from src/TNL/Meshes/GridDetails/GnuplotWriter.h rename to src/TNL/Meshes/Writers/GnuplotWriter.h diff --git a/src/UnitTests/CMakeLists.txt b/src/UnitTests/CMakeLists.txt index 0deb077d307abfa4356f1f7ec956a5aa599f3da3..c28e4da750775dae3814324ddbdd2c636102c174 100644 --- a/src/UnitTests/CMakeLists.txt +++ b/src/UnitTests/CMakeLists.txt @@ -1,7 +1,7 @@ ADD_SUBDIRECTORY( Algorithms ) ADD_SUBDIRECTORY( Arithmetics ) ADD_SUBDIRECTORY( Containers ) -ADD_SUBDIRECTORY( Functions ) +#ADD_SUBDIRECTORY( Functions ) # Matrices are included from src/CMakeLists.txt ADD_SUBDIRECTORY( Meshes ) ADD_SUBDIRECTORY( MPI ) diff --git a/src/UnitTests/Containers/CMakeLists.txt b/src/UnitTests/Containers/CMakeLists.txt index b2d0994dd9bd3e6105a202afc6ee1d938179310f..cddfb958e4177ea642624378a38bfe1117f4eaf3 100644 --- a/src/UnitTests/Containers/CMakeLists.txt +++ b/src/UnitTests/Containers/CMakeLists.txt @@ -15,9 +15,9 @@ set( CPP_TESTS VectorOfStaticVectorsTest ) set( CUDA_TESTS - ArrayTestCuda + # ArrayTestCuda ArrayViewTestCuda - VectorTestCuda + # VectorTestCuda VectorEvaluateAndReduceTestCuda VectorBinaryOperationsTestCuda VectorUnaryOperationsTestCuda diff --git a/src/UnitTests/Meshes/CMakeLists.txt b/src/UnitTests/Meshes/CMakeLists.txt index c8e71e9552977a7a4898d47a1f224fc2ceceac7a..68e44fa04e5fd9f9b3347f44cb4ca2c2f1531544 100644 --- a/src/UnitTests/Meshes/CMakeLists.txt +++ b/src/UnitTests/Meshes/CMakeLists.txt @@ -1,4 +1,5 @@ ADD_SUBDIRECTORY( DistributedMeshes ) +ADD_SUBDIRECTORY( GridTests ) ADD_EXECUTABLE( EntityTagsTest EntityTagsTest.cpp ) TARGET_COMPILE_OPTIONS( EntityTagsTest PRIVATE ${CXX_TESTS_FLAGS} ) diff --git a/src/UnitTests/Meshes/DistributedMeshes/CMakeLists.txt b/src/UnitTests/Meshes/DistributedMeshes/CMakeLists.txt index 1d7aaadaa46ff057be9a1463d8389494b122847a..d5160f6752cf91714d183c639e838a4ce76551d1 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/CMakeLists.txt +++ b/src/UnitTests/Meshes/DistributedMeshes/CMakeLists.txt @@ -3,10 +3,10 @@ ADD_EXECUTABLE( DirectionsTest DirectionsTest.cpp ) TARGET_LINK_LIBRARIES( DirectionsTest ${TESTS_LIBRARIES} ) target_link_options( DirectionsTest PRIVATE ${TESTS_LINKER_FLAGS} ) -ADD_EXECUTABLE( CopyEntitesTest CopyEntitiesTest.cpp ) - TARGET_COMPILE_OPTIONS( CopyEntitesTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( CopyEntitesTest ${TESTS_LIBRARIES} ) - target_link_options( CopyEntitesTest PRIVATE ${TESTS_LINKER_FLAGS} ) +# ADD_EXECUTABLE( CopyEntitesTest CopyEntitiesTest.cpp ) +# TARGET_COMPILE_OPTIONS( CopyEntitesTest PRIVATE ${CXX_TESTS_FLAGS} ) +# TARGET_LINK_LIBRARIES( CopyEntitesTest ${TESTS_LIBRARIES} ) +# target_link_options( CopyEntitesTest PRIVATE ${TESTS_LINKER_FLAGS} ) # FIXME: DistributedGrid refucktoring #ADD_EXECUTABLE( CutMeshFunctionTest CutMeshFunctionTest.cpp ) @@ -15,79 +15,78 @@ ADD_EXECUTABLE( CopyEntitesTest CopyEntitiesTest.cpp ) # target_link_options( CutMeshFunctionTest PRIVATE ${TESTS_LINKER_FLAGS} ) ADD_TEST( NAME DirectionsTest COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DirectionsTest${CMAKE_EXECUTABLE_SUFFIX} ) -ADD_TEST( NAME CopyEntitesTest COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CopyEntitesTest${CMAKE_EXECUTABLE_SUFFIX} ) +#ADD_TEST( NAME CopyEntitesTest COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CopyEntitesTest${CMAKE_EXECUTABLE_SUFFIX} ) #ADD_TEST( NAME CutMeshFunctionTest COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CutMeshFunctionTest${CMAKE_EXECUTABLE_SUFFIX} ) if( BUILD_MPI ) -ADD_EXECUTABLE( DistributedGridTest_1D DistributedGridTest_1D.cpp ) - TARGET_COMPILE_OPTIONS( DistributedGridTest_1D PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DistributedGridTest_1D ${TESTS_LIBRARIES} ) - target_link_options( DistributedGridTest_1D PRIVATE ${TESTS_LINKER_FLAGS} ) - -ADD_EXECUTABLE( DistributedGridTest_2D DistributedGridTest_2D.cpp ) - TARGET_COMPILE_OPTIONS( DistributedGridTest_2D PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DistributedGridTest_2D ${TESTS_LIBRARIES} ) - target_link_options( DistributedGridTest_2D PRIVATE ${TESTS_LINKER_FLAGS} ) - -ADD_EXECUTABLE( DistributedGridTest_3D DistributedGridTest_3D.cpp ) - TARGET_COMPILE_OPTIONS( DistributedGridTest_3D PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( DistributedGridTest_3D ${TESTS_LIBRARIES} ) - target_link_options( DistributedGridTest_3D PRIVATE ${TESTS_LINKER_FLAGS} ) - -ADD_EXECUTABLE( CutDistributedGridTest CutDistributedGridTest.cpp ) - TARGET_COMPILE_OPTIONS( CutDistributedGridTest PRIVATE ${CXX_TESTS_FLAGS} ) - TARGET_LINK_LIBRARIES( CutDistributedGridTest ${TESTS_LIBRARIES} ) - target_link_options( CutDistributedGridTest PRIVATE ${TESTS_LINKER_FLAGS} ) +# ADD_EXECUTABLE( DistributedGridTest_1D DistributedGridTest_1D.cpp ) +# TARGET_COMPILE_OPTIONS( DistributedGridTest_1D PRIVATE ${CXX_TESTS_FLAGS} ) +# TARGET_LINK_LIBRARIES( DistributedGridTest_1D ${TESTS_LIBRARIES} ) +# target_link_options( DistributedGridTest_1D PRIVATE ${TESTS_LINKER_FLAGS} ) + +# ADD_EXECUTABLE( DistributedGridTest_2D DistributedGridTest_2D.cpp ) +# TARGET_COMPILE_OPTIONS( DistributedGridTest_2D PRIVATE ${CXX_TESTS_FLAGS} ) +# TARGET_LINK_LIBRARIES( DistributedGridTest_2D ${TESTS_LIBRARIES} ) +# target_link_options( DistributedGridTest_2D PRIVATE ${TESTS_LINKER_FLAGS} ) + +# ADD_EXECUTABLE( DistributedGridTest_3D DistributedGridTest_3D.cpp ) +# TARGET_COMPILE_OPTIONS( DistributedGridTest_3D PRIVATE ${CXX_TESTS_FLAGS} ) +# TARGET_LINK_LIBRARIES( DistributedGridTest_3D ${TESTS_LIBRARIES} ) +# target_link_options( DistributedGridTest_3D PRIVATE ${TESTS_LINKER_FLAGS} ) + +# ADD_EXECUTABLE( CutDistributedGridTest CutDistributedGridTest.cpp ) +# TARGET_COMPILE_OPTIONS( CutDistributedGridTest PRIVATE ${CXX_TESTS_FLAGS} ) +# TARGET_LINK_LIBRARIES( CutDistributedGridTest ${TESTS_LIBRARIES} ) +# target_link_options( CutDistributedGridTest PRIVATE ${TESTS_LINKER_FLAGS} ) #ADD_EXECUTABLE( CutDistributedMeshFunctionTest CutDistributedMeshFunctionTest.cpp ) # TARGET_COMPILE_OPTIONS( CutDistributedMeshFunctionTest PRIVATE ${CXX_TESTS_FLAGS} ) # TARGET_LINK_LIBRARIES( CutDistributedMeshFunctionTest ${TESTS_LIBRARIES} ) # target_link_options( CutDistributedMeshFunctionTest PRIVATE ${TESTS_LINKER_FLAGS} ) -if( BUILD_CUDA ) - cuda_add_executable( DistributedMeshTest DistributedMeshTest.cu OPTIONS ${CUDA_TESTS_FLAGS}) -else() - add_executable( DistributedMeshTest DistributedMeshTest.cpp ) - target_compile_options( DistributedMeshTest PRIVATE ${CXX_TESTS_FLAGS} ) -endif() -target_link_libraries( DistributedMeshTest ${TESTS_LIBRARIES} ) -target_link_options( DistributedMeshTest PRIVATE ${TESTS_LINKER_FLAGS} ) - +# if( BUILD_CUDA ) +# cuda_add_executable( DistributedMeshTest DistributedMeshTest.cu OPTIONS ${CUDA_TESTS_FLAGS}) +# else() +# add_executable( DistributedMeshTest DistributedMeshTest.cpp ) +# target_compile_options( DistributedMeshTest PRIVATE ${CXX_TESTS_FLAGS} ) +# endif() +# target_link_libraries( DistributedMeshTest ${TESTS_LIBRARIES} ) +# target_link_options( DistributedMeshTest PRIVATE ${TESTS_LINKER_FLAGS} ) # external libraries for tests which use mesh readers find_package( ZLIB ) find_package( tinyxml2 QUIET ) if( ZLIB_FOUND AND tinyxml2_FOUND ) - foreach( target IN ITEMS DistributedGridTest_1D DistributedGridTest_2D DistributedGridTest_3D DistributedMeshTest ) - target_compile_definitions(${target} PUBLIC "-DHAVE_ZLIB") - target_include_directories(${target} PUBLIC ${ZLIB_INCLUDE_DIRS}) - target_link_libraries(${target} ${ZLIB_LIBRARIES}) - - target_compile_definitions(${target} PUBLIC "-DHAVE_TINYXML2") - target_link_libraries(${target} tinyxml2::tinyxml2) - endforeach() + # foreach( target IN ITEMS DistributedGridTest_1D DistributedGridTest_2D DistributedGridTest_3D DistributedMeshTest ) + # target_compile_definitions(${target} PUBLIC "-DHAVE_ZLIB") + # target_include_directories(${target} PUBLIC ${ZLIB_INCLUDE_DIRS}) + # target_link_libraries(${target} ${ZLIB_LIBRARIES}) + + # target_compile_definitions(${target} PUBLIC "-DHAVE_TINYXML2") + # target_link_libraries(${target} tinyxml2::tinyxml2) + # endforeach() endif() -SET (mpi_test_parameters_1d -np 4 -H localhost:4 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedGridTest_1D${CMAKE_EXECUTABLE_SUFFIX}") -ADD_TEST( NAME DistributedGridTest_1D COMMAND "mpirun" ${mpi_test_parameters_1d}) +# SET (mpi_test_parameters_1d -np 4 -H localhost:4 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedGridTest_1D${CMAKE_EXECUTABLE_SUFFIX}") +# ADD_TEST( NAME DistributedGridTest_1D COMMAND "mpirun" ${mpi_test_parameters_1d}) -SET (mpi_test_parameters_2d -np 9 -H localhost:9 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedGridTest_2D${CMAKE_EXECUTABLE_SUFFIX}") -ADD_TEST( NAME DistributedGridTest_2D COMMAND "mpirun" ${mpi_test_parameters_2d}) +# SET (mpi_test_parameters_2d -np 9 -H localhost:9 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedGridTest_2D${CMAKE_EXECUTABLE_SUFFIX}") +# ADD_TEST( NAME DistributedGridTest_2D COMMAND "mpirun" ${mpi_test_parameters_2d}) -SET (mpi_test_parameters_3d -np 27 -H localhost:27 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedGridTest_3D${CMAKE_EXECUTABLE_SUFFIX}") -ADD_TEST( NAME DistributedGridTest_3D COMMAND "mpirun" ${mpi_test_parameters_3d}) +# SET (mpi_test_parameters_3d -np 27 -H localhost:27 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedGridTest_3D${CMAKE_EXECUTABLE_SUFFIX}") +# ADD_TEST( NAME DistributedGridTest_3D COMMAND "mpirun" ${mpi_test_parameters_3d}) -SET (mpi_test_parameters_CutDistributedGridTest -np 12 -H localhost:12 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CutDistributedGridTest${CMAKE_EXECUTABLE_SUFFIX}") -ADD_TEST( NAME CutDistributedGridTest COMMAND "mpirun" ${mpi_test_parameters_CutDistributedGridTest}) +# SET (mpi_test_parameters_CutDistributedGridTest -np 12 -H localhost:12 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CutDistributedGridTest${CMAKE_EXECUTABLE_SUFFIX}") +# ADD_TEST( NAME CutDistributedGridTest COMMAND "mpirun" ${mpi_test_parameters_CutDistributedGridTest}) # TODO: Fix #SET (mpi_test_parameters_CutDistributedMeshFunctionTest -np 12 -H localhost:12 "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CutDistributedMeshFunctionTest${CMAKE_EXECUTABLE_SUFFIX}") #ADD_TEST( NAME CutDistributedMeshFunctionTest COMMAND "mpirun" ${mpi_test_parameters_CutDistributedMeshFunctionTest}) -add_test( NAME DistributedMeshTest_2x2 COMMAND mpirun -np 4 -H localhost:4 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedMeshTest${CMAKE_EXECUTABLE_SUFFIX} ) -add_test( NAME DistributedMeshTest_3x3 COMMAND mpirun -np 9 -H localhost:9 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedMeshTest${CMAKE_EXECUTABLE_SUFFIX} ) -add_test( NAME DistributedMeshTest_4x4 COMMAND mpirun -np 16 -H localhost:16 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedMeshTest${CMAKE_EXECUTABLE_SUFFIX} ) +# add_test( NAME DistributedMeshTest_2x2 COMMAND mpirun -np 4 -H localhost:4 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedMeshTest${CMAKE_EXECUTABLE_SUFFIX} ) +# add_test( NAME DistributedMeshTest_3x3 COMMAND mpirun -np 9 -H localhost:9 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedMeshTest${CMAKE_EXECUTABLE_SUFFIX} ) +# add_test( NAME DistributedMeshTest_4x4 COMMAND mpirun -np 16 -H localhost:16 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/DistributedMeshTest${CMAKE_EXECUTABLE_SUFFIX} ) endif() diff --git a/src/UnitTests/Meshes/DistributedMeshes/CopyEntitiesTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CopyEntitiesTest.cpp index 740d5fa5f616687a1b3b6837c7beafc1bcd9a963..c6ad3137fab90816c39a9e92f202a8cf32850371 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/CopyEntitiesTest.cpp +++ b/src/UnitTests/Meshes/DistributedMeshes/CopyEntitiesTest.cpp @@ -2,7 +2,7 @@ #include -#ifdef HAVE_GTEST +#ifdef HAVE_GTEST #include #include "../../Functions/Functions.h" @@ -47,10 +47,10 @@ class TestMovedMeshfunction for(int i=0;i { entity.getCoordinates().x()=i; entity.getCoordinates().y()=j; - entity.getCoordinates().z()=k; + entity.getCoordinates().z()=k; entity.refresh(); EXPECT_EQ( meshFunction.getData()[entity.getIndex()], 100*(k+1)+10*(j+1)+(i+1)) << "Copy entities Failed for: "<< i; - } + } }; }; @@ -109,10 +109,10 @@ class EvalMeshFunction for(int i=0;i { entity.getCoordinates().x()=i; entity.getCoordinates().y()=j; - entity.getCoordinates().z()=k; + entity.getCoordinates().z()=k; entity.refresh(); meshFunction.getData()[entity.getIndex()]=100*k+10*j+i; - } + } }; }; @@ -150,7 +150,7 @@ class TestCopyEntities typedef MeshFunctionView MeshFunctionType; typedef Vector DofType; - typedef typename MeshType::PointType PointType; + typedef typename MeshType::PointType PointType; typedef typename MeshType::CoordinatesType CoordinatesType; typedef typename MeshType::Cell Cell; @@ -163,12 +163,12 @@ class TestCopyEntities gridptr->setDimensions(proportions); gridptr->setDomain(origin,proportions); - + DofType inputDof(gridptr-> template getEntitiesCount< Cell >()); MeshFunctionType inputMeshFunction; - inputMeshFunction.bind(gridptr,inputDof); - + inputMeshFunction.bind(gridptr,inputDof); + EvalMeshFunction :: Eval(inputMeshFunction); @@ -176,14 +176,14 @@ class TestCopyEntities PointType proportionsOut; Pointers::SharedPointer gridOutPtr; - originOut.setValue(0.5); - proportionsOut.setValue(8); + originOut.setValue(0.5); + proportionsOut.setValue(8); gridOutPtr->setDimensions(proportionsOut); gridOutPtr->setDomain(originOut,proportionsOut); DofType outDof(gridOutPtr-> template getEntitiesCount< Cell >()); MeshFunctionType outputMeshFunction; - outputMeshFunction.bind(gridOutPtr,outDof); + outputMeshFunction.bind(gridOutPtr,outDof); CoordinatesType zero; zero.setValue(0); diff --git a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp index a0f79550ea3a0461a5259091f4b8439eea50399d..408b019c72d90f06899ead2be14fb30ed4e821ea 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp +++ b/src/UnitTests/Meshes/DistributedMeshes/CutDistributedGridTest.cpp @@ -1,3 +1,4 @@ + #ifdef HAVE_GTEST #include diff --git a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp index d8225229e4d56d62c38a262c5bf3ca9946ef6edc..5672b868a4e243eea4281122a5962014c9503345 100644 --- a/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp +++ b/src/UnitTests/Meshes/DistributedMeshes/DistributedGridTest_3D.cpp @@ -1,3 +1,4 @@ + #ifdef HAVE_GTEST #include diff --git a/src/UnitTests/Meshes/GridTests/Accessors/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/Accessors/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7a840747a92dd4351f1279e2aff72019fd27bb32 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/CMakeLists.txt @@ -0,0 +1,7 @@ +include("../CMakeSupport.cmake") + +SET(SOME_ARGS "") + +generate_executables(Grid1DTest.h "Accessors" "../../../main.h" SOME_ARGS) +generate_executables(Grid2DTest.h "Accessors" "../../../main.h" SOME_ARGS) +generate_executables(Grid3DTest.h "Accessors" "../../../main.h" SOME_ARGS) diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.cpp b/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73c81a9543d24b2200a95b5328128f353eb6da2b --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid1DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.cu b/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..73c81a9543d24b2200a95b5328128f353eb6da2b --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid1DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.h b/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..a3f616a0442e0d09209da5e83f1d064053ef5ec8 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid1DTest.h @@ -0,0 +1,117 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "support.h" + +#ifdef HAVE_CUDA +using Implementations = ::testing::Types< + TNL::Meshes::NDimGrid<1, double, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<1, float, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<1, double, TNL::Devices::Cuda, int>, + TNL::Meshes::NDimGrid<1, float, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<1, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Cuda, int> +>; +#else +using Implementations = ::testing::Types< + TNL::Meshes::NDimGrid<1, double, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<1, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Host, int> +>; +#endif + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestMeshDimensionGetter) { + EXPECT_EQ(TypeParam::getMeshDimension(), 1) << "All grids must have dimension 1"; +} + +TYPED_TEST(GridTestSuite, TestSetWithParameterPack) { + testDimensionSetByIndex(this->grid, 0); + testDimensionSetByIndex(this->grid, 1); + testDimensionSetByIndex(this->grid, 2); + testDimensionSetByIndex(this->grid, 11211); + testDimensionSetByIndex(this->grid, 232121); + testDimensionSetByIndex(this->grid, 434343); +} + +TYPED_TEST(GridTestSuite, TestSetWithCoordinates) { + testDimensionSetByCoordinate(this -> grid, { 0 }); + testDimensionSetByCoordinate(this -> grid, { 1 }); + testDimensionSetByCoordinate(this -> grid, { 2 }); + testDimensionSetByCoordinate(this -> grid, { 10232 }); + testDimensionSetByCoordinate(this -> grid, { 45235423 }); + testDimensionSetByCoordinate(this -> grid, { 3231312 }); +} + +TYPED_TEST(GridTestSuite, TestEntitiesCount) { + // GridType, Edges, Vertices | Edges + testEntitiesCounts(this -> grid, { 0 }, { 0, 0 }); + testEntitiesCounts(this -> grid, { 1 }, { 2, 1 }); + testEntitiesCounts(this -> grid, { 2 }, { 3, 2 }); + + testEntitiesCounts(this -> grid, { 100 }, { 101, 100 }); +} + +TYPED_TEST(GridTestSuite, TestOriginSet) { + testOriginSetByCoordinate(this -> grid, { 0.6 }); + testOriginSetByCoordinate(this -> grid, { 1. }); + testOriginSetByCoordinate(this -> grid, { 2. }); + testOriginSetByCoordinate(this -> grid, { 0.4 }); + testOriginSetByCoordinate(this -> grid, { 3. }); + + testOriginSetByIndex(this -> grid, 0.6); + testOriginSetByIndex(this -> grid, 1.); + testOriginSetByIndex(this -> grid, 2.); + testOriginSetByIndex(this -> grid, 0.4); + testOriginSetByIndex(this -> grid, 3.); +} + +TYPED_TEST(GridTestSuite, TestSpaceStepsGetter) { + const int spaceStepsPowersSize = TypeParam::spaceStepsPowersSize; + + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 0.6 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 1 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 4 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 0.1 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 4 }); + + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 0.6); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 1); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 4); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 0.1); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 4); +} + +TYPED_TEST(GridTestSuite, TestSpaceStepsPowersValues) { + const int spaceStepsPowersSize = TypeParam::spaceStepsPowersSize; + + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 0. }); + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 1. }); + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 2. }); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.cpp b/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63738765a8730089d970d0ee219d88e68e8851bf --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid2DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.cu b/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..63738765a8730089d970d0ee219d88e68e8851bf --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid2DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.h b/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..b41f8eca79bbbb48a8868f698f81630386e2561e --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid2DTest.h @@ -0,0 +1,129 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "support.h" + +#ifdef HAVE_CUDA +using Implementations = ::testing::Types< + TNL::Meshes::NDimGrid<2, double, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<2, float, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<2, double, TNL::Devices::Cuda, int>, + TNL::Meshes::NDimGrid<2, float, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<2, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Cuda, int> +>; +#else +using Implementations = ::testing::Types< + TNL::Meshes::NDimGrid<2, double, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<2, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Host, int> +>; +#endif + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestMeshDimensionGetter) { + EXPECT_EQ(TypeParam::getMeshDimension(), 2) << "All grids must have dimension 2"; +} + +TYPED_TEST(GridTestSuite, TestSetWithParameterPack) { + testDimensionSetByIndex(this -> grid, 0, 0); + testDimensionSetByIndex(this -> grid, 0, 1); + testDimensionSetByIndex(this -> grid, 0, 2); + testDimensionSetByIndex(this -> grid, 1, 11211); + testDimensionSetByIndex(this -> grid, 232121, 21); + testDimensionSetByIndex(this -> grid, 54544, 434343); +} + +TYPED_TEST(GridTestSuite, TestSetWithCoordinates) { + testDimensionSetByCoordinate(this -> grid, { 0, 0 }); + testDimensionSetByCoordinate(this -> grid, { 0, 1 }); + testDimensionSetByCoordinate(this -> grid, { 0, 2 }); + testDimensionSetByCoordinate(this -> grid, { 1, 11211 }); + testDimensionSetByCoordinate(this -> grid, { 232121, 21 }); + testDimensionSetByCoordinate(this -> grid, { 54544, 434343 }); +} + +TYPED_TEST(GridTestSuite, TestEntitiesCount) { + // GridType, Edges, Vertices | Edges + testEntitiesCounts(this -> grid, { 0, 0 }, { 0, 0, 0 }); + + testEntitiesCounts(this -> grid, { 1, 0 }, { 0, 0, 0 }); + testEntitiesCounts(this -> grid, { 0, 1 }, { 0, 0, 0 }); + + testEntitiesCounts(this -> grid, { 1, 1 }, { 4, 4, 1 }); + + testEntitiesCounts(this -> grid, { 2, 1 }, { 6, 7, 2 }); + testEntitiesCounts(this -> grid, { 1, 2 }, { 6, 7, 2 }); + + testEntitiesCounts(this -> grid, { 2, 2 }, { 9, 12, 4 }); + + testEntitiesCounts(this -> grid, { 2, 3 }, { 12, 17, 6 }); + testEntitiesCounts(this -> grid, { 3, 2 }, { 12, 17, 6 }); + + testEntitiesCounts(this -> grid, { 50, 50 }, { 51 * 51, 51 * 50 + 50 * 51, 50 * 50 }); + testEntitiesCounts(this -> grid, { 50, 100 }, { 51 * 101, 51 * 100 + 50 * 101, 50 * 100 }); +} + +TYPED_TEST(GridTestSuite, TestOriginSet) { + testOriginSetByCoordinate(this -> grid, { 0.6, 1.2 }); + testOriginSetByCoordinate(this -> grid, { -1, 23232 }); + testOriginSetByCoordinate(this -> grid, { 100, -12132 }); + testOriginSetByCoordinate(this -> grid, { -100000, 32112 }); + testOriginSetByCoordinate(this -> grid, { 323121, -100312 }); + + testOriginSetByIndex(this -> grid, 0.6, 1.2); + testOriginSetByIndex(this -> grid, -1, 23232); + testOriginSetByIndex(this -> grid, 100, -12132); + testOriginSetByIndex(this -> grid, -100000, 32112); + testOriginSetByIndex(this -> grid, 323121, -100312); +} + +TYPED_TEST(GridTestSuite, TestSpaceStepsGetter) { + const int spaceStepsPowersSize = TypeParam::spaceStepsPowersSize; + + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 0.6, 1.2 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 1, 2 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 4, 3 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 0.1, 10 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 4, 5 }); + + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 0.6, 1.2); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 1, 2); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 4, 3); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 0.1, 10); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 4, 5); +} + +TYPED_TEST(GridTestSuite, TestSpaceStepsPowersValues) { + const int spaceStepsPowersSize = TypeParam::spaceStepsPowersSize; + + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 1., 1. }); + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 0., 2. }); + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 2., 3. }); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.cpp b/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f9bb7cd1339c087bc35ba2c189c0f57087f60e9 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid3DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.cu b/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..4f9bb7cd1339c087bc35ba2c189c0f57087f60e9 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid3DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.h b/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..8b614a21fc93cdd80ade528b3d078f68b134fcb6 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/Grid3DTest.h @@ -0,0 +1,156 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "support.h" + +#ifdef HAVE_CUDA +using Implementations = ::testing::Types< + TNL::Meshes::NDimGrid<3, double, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<3, float, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<3, double, TNL::Devices::Cuda, int>, + TNL::Meshes::NDimGrid<3, float, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<3, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Cuda, int> +>; +#else +using Implementations = ::testing::Types< + TNL::Meshes::NDimGrid<3, double, TNL::Devices::Host, int>, + TNL::Meshes::NDimGrid<3, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Host, int> +>; +#endif + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestMeshDimensionGetter) { + EXPECT_EQ(TypeParam::getMeshDimension(), 3) << "All grids must have dimension 3"; +} + +TYPED_TEST(GridTestSuite, TestSetWithParameterPack) { + testDimensionSetByIndex(this -> grid, 0, 0, 0); + + testDimensionSetByIndex(this -> grid, 0, 0, 1); + testDimensionSetByIndex(this -> grid, 0, 1, 0); + testDimensionSetByIndex(this -> grid, 1, 0, 0); + + testDimensionSetByIndex(this -> grid, 0, 2, 2); + testDimensionSetByIndex(this -> grid, 2, 0, 2); + testDimensionSetByIndex(this -> grid, 2, 2, 0); + + testDimensionSetByIndex(this -> grid, 3, 3, 3); + + testDimensionSetByIndex(this -> grid, 1, 1, 11211); + testDimensionSetByIndex(this -> grid, 232121, 21, 20); + testDimensionSetByIndex(this -> grid, 54544, 434343, 321341); +} + +TYPED_TEST(GridTestSuite, TestSetWithCoordinates) { + testDimensionSetByCoordinate(this -> grid, { 0, 0, 0 }); + + testDimensionSetByCoordinate(this -> grid, { 0, 0, 1 }); + testDimensionSetByCoordinate(this -> grid, { 0, 1, 0 }); + testDimensionSetByCoordinate(this -> grid, { 1, 0, 0 }); + + testDimensionSetByCoordinate(this -> grid, { 0, 2, 2 }); + testDimensionSetByCoordinate(this -> grid, { 2, 0, 2 }); + testDimensionSetByCoordinate(this -> grid, { 2, 2, 0 }); + + testDimensionSetByCoordinate(this -> grid, { 3, 3, 3 }); + + testDimensionSetByCoordinate(this -> grid, { 1, 1, 11211 }); + testDimensionSetByCoordinate(this -> grid, { 232121, 21, 20 }); + testDimensionSetByCoordinate(this -> grid, { 54544, 434343, 321343 }); +} + +TYPED_TEST(GridTestSuite, TestEntitiesCount) { + // GridType, Edges, Vertices | Edges + testEntitiesCounts(this -> grid, { 0, 0, 0 }, { 0, 0, 0, 0 }); + + testEntitiesCounts(this -> grid, { 1, 0, 0 }, { 0, 0, 0, 0 }); + testEntitiesCounts(this -> grid, { 0, 1, 0 }, { 0, 0, 0, 0 }); + testEntitiesCounts(this -> grid, { 0, 0, 1 }, { 0, 0, 0, 0 }); + + testEntitiesCounts(this -> grid, { 1, 1, 1 }, { 8, 12, 6, 1 }); + + testEntitiesCounts(this -> grid, { 2, 1, 1 }, { 12, 20, 11, 2 }); + testEntitiesCounts(this -> grid, { 1, 2, 1 }, { 12, 20, 11, 2 }); + testEntitiesCounts(this -> grid, { 1, 1, 2 }, { 12, 20, 11, 2 }); + + testEntitiesCounts(this -> grid, { 2, 2, 2 }, { 27, 54, 36, 8 }); + + testEntitiesCounts(this -> grid, { 2, 2, 3 }, { 36, 75, 52, 12 }); + testEntitiesCounts(this -> grid, { 2, 3, 2 }, { 36, 75, 52, 12 }); + testEntitiesCounts(this -> grid, { 3, 2, 2 }, { 36, 75, 52, 12 }); + + testEntitiesCounts(this -> grid, { 50, 50, 50 }, { 51 * 51 * 51, + 51 * 51 * 50 + 51 * 50 * 51 + 50 * 51 * 51, + 51 * 50 * 50 + 50 * 51 * 50 + 50 * 50 * 51, + 50 * 50 * 50 }); + testEntitiesCounts(this -> grid, { 50, 100, 150 }, { 51 * 101 * 151, + 51 * 101 * 150 + 51 * 100 * 151 + 50 * 101 * 151, + 51 * 100 * 150 + 50 * 101 * 150 + 50 * 100 * 151, + 50 * 100 * 150 }); +} + +TYPED_TEST(GridTestSuite, TestOriginSet) { + testOriginSetByCoordinate(this -> grid, { 0.6, 1.2, 1.8 }); + testOriginSetByCoordinate(this -> grid, { -1, 23232, -1 }); + testOriginSetByCoordinate(this -> grid, { 100, -12132, 1231 }); + testOriginSetByCoordinate(this -> grid, { -100000, 32112, 123 }); + testOriginSetByCoordinate(this -> grid, { 323121, -100312, 1341231 }); + + testOriginSetByIndex(this -> grid, 0.6, 1.2, 1.8); + testOriginSetByIndex(this -> grid, -1, 23232, -1); + testOriginSetByIndex(this -> grid, 100, -12132, 1231); + testOriginSetByIndex(this -> grid, -100000, 32112, 123); + testOriginSetByIndex(this -> grid, 323121, -100312, 1341231); +} + +TYPED_TEST(GridTestSuite, TestSpaceStepsGetter) { + const int spaceStepsPowersSize = TypeParam::spaceStepsPowersSize; + + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 0.6, 1.2, 1.8 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 1, 2, 1 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 0.5, 3, 2 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 5, 4, 3 }); + testSpaceStepsSetByCoordinate(this -> grid, spaceStepsPowersSize, { 3, 2, 1 }); + + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 0.6, 1.2, 1.8); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 1, 2, 1 ); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 0.5, 3, 2 ); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 5, 4, 3); + testSpaceStepsSetByIndex(this -> grid, spaceStepsPowersSize, 3, 2, 1); +} + +TYPED_TEST(GridTestSuite, TestSpaceStepsPowersValues) { + const int spaceStepsPowersSize = TypeParam::spaceStepsPowersSize; + + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 1., 1., 1.}); + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 0., 2., 4.}); + testSpaceStepsPowerValues(this -> grid, spaceStepsPowersSize, { 1., 2., 3.}); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Accessors/support.h b/src/UnitTests/Meshes/GridTests/Accessors/support.h new file mode 100644 index 0000000000000000000000000000000000000000..52fb7bf7adfe52b3dbdc74617b64cf2f3959ba6b --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Accessors/support.h @@ -0,0 +1,452 @@ +#pragma once + +#ifdef HAVE_GTEST +#include +#include + +#include "../CoordinateIterator.h" + +template +class GridAccessorsTestCaseInterface { + public: + template + void verifyDimensionGetters(const Grid& grid, const typename Grid::Coordinate& coordinates) const { FAIL() << "Expect to be specialized"; } + + template + void verifyEntitiesCountGetters(const Grid& grid, const typename Grid::Container& entitiesCount) const { FAIL() << "Expect to be specialized"; } + + template + void verifyOriginGetters(const Grid& grid, const typename Grid::Point& coordinates) const { FAIL() << "Expect to be specialized"; } + + template + void verifySpaceStepsGetter(const Grid& grid, const typename Grid::Point& spaceSteps) const { FAIL() << "Expect to be specialized"; } + + + template + void verifyDimensionByCoordinateGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { FAIL() << "Expect to be specialized"; } + + template + void verifyDimensionByIndexGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { FAIL() << "Expect to be specialized"; } + + template + void verifyDimensionByIndiciesGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { FAIL() << "Expect to be specialized"; } + + + template + void verifyEntitiesCountByContainerGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { FAIL() << "Expect to be specialized"; } + + template + void verifyEntitiesCountByIndexGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { FAIL() << "Expect to be specialized"; } + + template + void verifyEntitiesCountByIndiciesGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { FAIL() << "Expect to be specialized"; } + + + template + void verifySpaceStepsValues(const Grid& grid, const int spaceStepsSize, const typename Grid::Point& spaceSteps) { + using Real = typename Grid::RealType; + using Coordinate = typename Grid::Coordinate; + + Coordinate start, end; + + for (int i = 0; i < start.getSize(); i++) { + start[i] = -(spaceStepsSize >> 1); + end[i] = (spaceStepsSize >> 1); + } + + CoordinateIterator iterator(start, end); + + do { + auto coordinate = iterator.getCoordinate(); + Real product = 1.; + + for (typename Grid::IndexType i = 0; i < start.getSize(); i++) product *= pow(spaceSteps[i], coordinate[i]); + + if (std::is_same::value) { + EXPECT_FLOAT_EQ(grid.getSpaceStepsProducts(coordinate), product) << "Expect the step size products are the same"; + continue; + } + + if (std::is_same::value) { + EXPECT_DOUBLE_EQ(grid.getSpaceStepsProducts(coordinate), product) << "Expect the step size products are the same"; + continue; + } + + FAIL() << "Unknown type as real was provided for comparison: " << TNL::getType(); + } while (!iterator.next()); + } +}; + + +template +class GridAccessorsTestCase: public GridAccessorsTestCaseInterface {}; + +template<> +class GridAccessorsTestCase: public GridAccessorsTestCaseInterface { + public: + template + void verifyDimensionGetters(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + this->verifyDimensionByCoordinateGetter(grid, dimensions); + this->verifyDimensionByIndexGetter(grid, dimensions); + this->verifyDimensionByIndiciesGetter(grid, dimensions); + } + + template + void verifyEntitiesCountGetters(const Grid& grid, const typename Grid::Container& entitiesCounts) const { + this->verifyEntitiesCountByContainerGetter(grid, entitiesCounts); + this->verifyEntitiesCountByIndexGetter(grid, entitiesCounts); + this->verifyEntitiesCountByIndiciesGetter(grid, entitiesCounts); + } + + template + void verifyOriginGetter(const Grid& grid, const typename Grid::Point& coordinates) const { + auto result = grid.getOrigin(); + + EXPECT_EQ(coordinates, result) << "Verify, that the origin was correctly set"; + } + + template + void verifySpaceStepsGetter(const Grid& grid, const typename Grid::Point& spaceSteps) const { + auto result = grid.getSpaceSteps(); + + EXPECT_EQ(spaceSteps, result) << "Verify, that space steps were correctly set"; + } + + template + void verifyDimensionByCoordinateGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + auto result = grid.getDimensions(); + + EXPECT_EQ(dimensions, result) << "Verify, that dimension container accessor returns valid dimension"; + } + + template + void verifyDimensionByIndexGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + for (typename Grid::IndexType i = 0; i < dimensions.getSize(); i++) + EXPECT_EQ(grid.getDimension(i), dimensions[i]) << "Verify, that index access is correct"; + } + + template + void verifyDimensionByIndiciesGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + for (typename Grid::IndexType i = 0; i < dimensions.getSize(); i++) { + auto repeatedDimensions = grid.getDimensions(i, i, i, i, i, i, i, i, i, i); + + EXPECT_EQ(repeatedDimensions.getSize(), 10) << "Verify, that all dimension indices are returned"; + + for (typename Grid::IndexType j = 0; j < repeatedDimensions.getSize(); j++) + EXPECT_EQ(repeatedDimensions[j], dimensions[i]) << "Verify, that it is possible to request the same dimension multiple times"; + } + } + + template + void verifyEntitiesCountByContainerGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { + auto result = grid.getEntitiesCounts(); + + EXPECT_EQ(entitiesCounts, result) << "Verify, that returns expected entities counts"; + } + + template + void verifyEntitiesCountByIndexGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { + for (typename Grid::IndexType i = 0; i < entitiesCounts.getSize(); i++) + EXPECT_EQ(grid.getEntitiesCount(i), entitiesCounts[i]) << "Verify, that index access is correct"; + } + + template + void verifyEntitiesCountByIndiciesGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { + for (typename Grid::IndexType i = 0; i < entitiesCounts.getSize(); i++) { + auto repeated = grid.getEntitiesCounts(i, i, i, i, i, i, i, i, i, i); + + EXPECT_EQ(repeated.getSize(), 10) << "Verify, that all dimension indices are returned"; + + for (typename Grid::IndexType j = 0; j < repeated.getSize(); j++) + EXPECT_EQ(repeated[j], entitiesCounts[i]) << "Verify, that it is possible to request the same dimension multiple times"; + } + } +}; +#ifdef HAVE_CUDA + +template<> +class GridAccessorsTestCase: public GridAccessorsTestCaseInterface { + public: + template + void verifyDimensionGetters(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + this->verifyDimensionByCoordinateGetter(grid, dimensions); + this->verifyDimensionByIndexGetter(grid, dimensions); + this->verifyDimensionByIndiciesGetter(grid, dimensions); + } + + template + void verifyEntitiesCountGetters(const Grid& grid, const typename Grid::Container& entitiesCount) const { + this->verifyEntitiesCountByContainerGetter(grid, entitiesCount); + this->verifyEntitiesCountByIndexGetter(grid, entitiesCount); + this->verifyEntitiesCountByIndiciesGetter(grid, entitiesCount); + } + + template + void verifyOriginGetter(const Grid& grid, const typename Grid::Point& coordinates) const { + auto gridDimension = grid.getMeshDimension(); + + auto update = [=] __device__ (const int index, typename Grid::RealType& reference) mutable { + reference = grid.getOrigin()[index % gridDimension]; + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::RealType& reference) mutable { + EXPECT_EQ(reference, coordinates[index % gridDimension]); + }; + + this->executeFromDevice(update, verify); + } + + template + void verifySpaceStepsGetter(const Grid& grid, const typename Grid::Point& spaceSteps) const { + auto gridDimension = grid.getMeshDimension(); + + auto update = [=] __device__ (const int index, typename Grid::RealType& reference) mutable { + reference = grid.getSpaceSteps()[index % gridDimension]; + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::RealType& reference) mutable { + EXPECT_EQ(reference, spaceSteps[index % gridDimension]); + }; + + this->executeFromDevice(update, verify); + } + + template + void executeFromDevice(Updater&& updater, Verifier&& verifier) const { + TNL::Containers::Array container(100 * 100); + + container.forAllElements(updater); + + TNL::Containers::Array result(container); + + result.forAllElements(verifier); + } + + + template + void verifyDimensionByCoordinateGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + auto gridDimension = grid.getMeshDimension(); + + auto update = [=] __device__ (const int index, typename Grid::IndexType& reference) mutable { + reference = grid.getDimensions()[index % gridDimension]; + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::IndexType& reference) mutable { + EXPECT_EQ(reference, dimensions[index % gridDimension]); + }; + + this->executeFromDevice(update, verify); + } + + template + void verifyDimensionByIndexGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + auto gridDimension = grid.getMeshDimension(); + + auto update = [=] __device__ (const int index, typename Grid::IndexType& reference) mutable { + reference = grid.getDimension(index % gridDimension); + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::IndexType& reference) mutable { + EXPECT_EQ(reference, dimensions[index % gridDimension]); + }; + + this->executeFromDevice(update, verify); + } + + template + void verifyDimensionByIndiciesGetter(const Grid& grid, const typename Grid::Coordinate& dimensions) const { + auto gridDimension = grid.getMeshDimension(); + + auto update = [=] __device__ (const int index, typename Grid::IndexType& reference) mutable { + reference = grid.getDimensions(index % gridDimension)[0]; + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::IndexType& reference) mutable { + EXPECT_EQ(reference, dimensions[index % gridDimension]); + }; + + this -> executeFromDevice(update, verify); + } + + + template + void verifyEntitiesCountByContainerGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { + auto size = entitiesCounts.getSize(); + + auto update = [=] __device__ (const int index, typename Grid::IndexType& reference) mutable { + reference = grid.getEntitiesCounts()[index % size]; + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::IndexType& reference) mutable { + EXPECT_EQ(reference, entitiesCounts[index % size]); + }; + + this -> executeFromDevice(update, verify); + } + + template + void verifyEntitiesCountByIndexGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { + auto size = entitiesCounts.getSize(); + + auto update = [=] __device__ (const int index, typename Grid::IndexType& reference) mutable { + reference = grid.getEntitiesCount(index % size); + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::IndexType& reference) mutable { + EXPECT_EQ(reference, entitiesCounts[index % size]); + }; + + this -> executeFromDevice(update, verify); + } + + template + void verifyEntitiesCountByIndiciesGetter(const Grid& grid, const typename Grid::Container& entitiesCounts) const { + auto size = entitiesCounts.getSize(); + + auto update = [=] __device__ (const int index, typename Grid::IndexType& reference) mutable { + reference = grid.getEntitiesCounts(index % size)[0]; + }; + + auto verify = [=] __cuda_callable__ (const int index, const typename Grid::IndexType& reference) mutable { + EXPECT_EQ(reference, entitiesCounts[index % size]); + }; + + this -> executeFromDevice(update, verify); + } +}; + +#endif + +template +std::string makeString(Parameters... parameters) { + std::ostringstream s; + + for (const auto x: { parameters... }) + s << x << ", "; + + return s.str(); +} + +template +void testDimensionSetByIndex(Grid& grid, T... dimensions) { + auto paramString = makeString(dimensions...); + + EXPECT_NO_THROW(grid.setDimensions(dimensions...)) << "Verify, that the set of" << paramString << " doesn't cause assert"; + + SCOPED_TRACE("Test dimension set by index"); + SCOPED_TRACE("Dimension: " + TNL::convertToString(typename Grid::Coordinate(dimensions...))); + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(grid.getDimensions())); + + GridAccessorsTestCase support; + + support.template verifyDimensionGetters(grid, typename Grid::Coordinate(dimensions...)); +} + +template +void testDimensionSetByCoordinate(Grid& grid, const typename Grid::Coordinate& dimensions) { + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + + SCOPED_TRACE("Test dimension set by coordinate"); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(grid.getDimensions())); + + GridAccessorsTestCase support; + + support.template verifyDimensionGetters(grid, dimensions); +} + +template +void testEntitiesCounts(Grid& grid, + const typename Grid::Coordinate& dimensions, + const typename Grid::Container& entitiesCounts) { + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + + SCOPED_TRACE("Test entities count"); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Grid Entities Counts: " + TNL::convertToString(grid.getEntitiesCounts())); + SCOPED_TRACE("Expected Entities Counts:: " + TNL::convertToString(entitiesCounts)); + + GridAccessorsTestCase support; + + support.template verifyEntitiesCountGetters(grid, entitiesCounts); +} + +template...>, bool> = true> +void testOriginSetByIndex(Grid& grid, T... coordinates) { + auto paramString = makeString(coordinates...); + + EXPECT_NO_THROW(grid.setOrigin(coordinates...)) << "Verify, that the set of" << paramString << " doesn't cause assert"; + + SCOPED_TRACE("Test origin set by coordinate"); + SCOPED_TRACE("Coordinates: " + TNL::convertToString(typename Grid::Coordinate(coordinates...))); + SCOPED_TRACE("Grid origin: " + TNL::convertToString(grid.getOrigin())); + + GridAccessorsTestCase support; + + support.template verifyOriginGetter(grid, typename Grid::Point(coordinates...)); +} + +template +void testOriginSetByCoordinate(Grid& grid, const typename Grid::Point& coordinates) { + EXPECT_NO_THROW(grid.setOrigin(coordinates)) << "Verify, that the set of " << coordinates << " doesn't cause assert"; + + SCOPED_TRACE("Test origin set by index"); + SCOPED_TRACE("Coordinates: " + TNL::convertToString(coordinates)); + SCOPED_TRACE("Grid origin: " + TNL::convertToString(grid.getOrigin())); + + GridAccessorsTestCase support; + + support.template verifyOriginGetter(grid, coordinates); +} + +template +void testSpaceStepsSetByCoordinate(Grid& grid, const int spaceStepsSize, const typename Grid::Point& spaceSteps) { + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of " << spaceSteps << " doesn't cause assert"; + + SCOPED_TRACE("Test space steps set by coordinate"); + SCOPED_TRACE("Space steps: " + TNL::convertToString(spaceSteps)); + SCOPED_TRACE("Grid space steps: " + TNL::convertToString(grid.getSpaceSteps())); + + GridAccessorsTestCase support; + + support.template verifySpaceStepsGetter(grid, spaceSteps); + support.template verifySpaceStepsValues(grid, spaceStepsSize, spaceSteps); +} + +template...>, bool> = true> +void testSpaceStepsSetByIndex(Grid& grid, const int spaceStepsSize, T... spaceSteps) { + typename Grid::Point spaceStepsContainer(spaceSteps...); + + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps...)) << "Verify, that the set of " << spaceStepsContainer << " doesn't cause assert"; + + SCOPED_TRACE("Test space steps set by index"); + SCOPED_TRACE("Space steps: " + TNL::convertToString(spaceStepsContainer)); + SCOPED_TRACE("Grid space steps: " + TNL::convertToString(grid.getSpaceSteps())); + + GridAccessorsTestCase support; + + support.template verifySpaceStepsGetter(grid, spaceStepsContainer); + support.template verifySpaceStepsValues(grid, spaceStepsSize, spaceStepsContainer); +} + +template +void testSpaceStepsPowerValues(Grid& grid, const int spaceStepsSize, const typename Grid::Point& spaceSteps) { + if (spaceStepsSize <= 0) + GTEST_SKIP() << "Negative space steps sizes are not supported"; + + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of " << spaceSteps << " doesn't cause assert"; + + SCOPED_TRACE("Test space steps set by index"); + SCOPED_TRACE("Space steps: " + TNL::convertToString(spaceSteps)); + SCOPED_TRACE("Grid space steps: " + TNL::convertToString(grid.getSpaceSteps())); + + GridAccessorsTestCase support; + + support.template verifySpaceStepsValues(grid, spaceStepsSize, spaceSteps); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5759d699bb3150be70d2aad41cc423857eae1808 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/CMakeLists.txt @@ -0,0 +1,4 @@ +# add_subdirectory(Accessors) +add_subdirectory(Traverse) +# add_subdirectory(Neighbours) +# add_subdirectory(Utils) diff --git a/src/UnitTests/Meshes/GridTests/CMakeSupport.cmake b/src/UnitTests/Meshes/GridTests/CMakeSupport.cmake new file mode 100644 index 0000000000000000000000000000000000000000..182ac172d359d1c652a07c20dc312b5789344db0 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/CMakeSupport.cmake @@ -0,0 +1,31 @@ + +function(generate_executables HEADER SUFFIX MAIN_FILE_PATH ARGS) + get_filename_component(MODULE_NAME ${HEADER} NAME_WE) + + if (${BUILD_CUDA}) + SET(SUPPORT_FILENAME ${MODULE_NAME}.cu) + else() + SET(SUPPORT_FILENAME ${MODULE_NAME}.cpp) + endif() + + file(WRITE ${SUPPORT_FILENAME} +" +#include \"${HEADER}\" +#include \"${MAIN_FILE_PATH}\" +") + + # Targets are separated by suffix provided + set(MODULE_NAME ${MODULE_NAME}_${SUFFIX}) + + if (${BUILD_CUDA}) + CUDA_ADD_EXECUTABLE(${MODULE_NAME} ${HEADER} ${SUPPORT_FILENAME} OPTIONS ${CUDA_TESTS_FLAGS}) + TARGET_LINK_LIBRARIES(${MODULE_NAME} ${TESTS_LIBRARIES}) + else() + ADD_EXECUTABLE(${MODULE_NAME} ${HEADER} ${SUPPORT_FILENAME}) + TARGET_COMPILE_OPTIONS(${MODULE_NAME} PRIVATE ${CXX_TESTS_FLAGS}) + endif() + + TARGET_LINK_LIBRARIES(${MODULE_NAME} ${TESTS_LIBRARIES} ) + target_link_options(${MODULE_NAME} PRIVATE ${TESTS_LINKER_FLAGS}) + ADD_TEST(${MODULE_NAME} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${MODULE_NAME}${CMAKE_EXECUTABLE_SUFFIX} ) +endfunction() diff --git a/src/UnitTests/Meshes/GridTests/CoordinateIterator.h b/src/UnitTests/Meshes/GridTests/CoordinateIterator.h new file mode 100644 index 0000000000000000000000000000000000000000..9604518c9568a1f3fc497847afb5017fff2ac9a0 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/CoordinateIterator.h @@ -0,0 +1,47 @@ + +#pragma once + +#include + +template +class CoordinateIterator { + public: + using Coordinate = TNL::Containers::StaticVector; + + CoordinateIterator(const Coordinate& start, const Coordinate& end): start(start), current(start), end(end) {} + + Coordinate getCoordinate() const { return current; } + + bool next() { + current[0] += 1; + + Index carry = 0; + + bool isEnded = false; + + for (Index i = 0; i < current.getSize(); i++) { + current[i] += carry; + + if (current[i] == end[i]) { + carry = 1; + current[i] = start[i]; + + isEnded = i == current.getSize() - 1; + continue; + } + + break; + } + + return isEnded; + } + + bool canIterate() { + for (Index i = 0; i < current.getSize(); i++) + if (current[i] >= end[i]) return false; + + return true; + } + protected: + Coordinate start, current, end; +}; diff --git a/src/UnitTests/Meshes/GridTests/EntityDataStore.h b/src/UnitTests/Meshes/GridTests/EntityDataStore.h new file mode 100644 index 0000000000000000000000000000000000000000..6106e79c75dd5b07e2b5b45e327f2f6eb38415f6 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/EntityDataStore.h @@ -0,0 +1,203 @@ + +#pragma once + +#include +#include + +template +struct EntityPrototype { + public: + using Coordinate = TNL::Containers::StaticVector; + using Point = TNL::Containers::StaticVector; + + EntityPrototype(const Coordinate& coordinate, + const Coordinate& basis, + const Index index, + const Index calls, + const Index orientation, + const bool isBoundary, + const Point& center, + const Real& measure): coordinate(coordinate), basis(basis), index(index), calls(calls), orientation(orientation), isBoundary(isBoundary), center(center), measure(measure) {} + + const Coordinate coordinate; + const Coordinate basis; + const Index index; + const Index calls; + const Index orientation; + const bool isBoundary; + const Point center; + const Real measure; + + template + friend std::ostream & operator << (std::ostream & os, const EntityPrototype& entity); +}; + +template +std::ostream & operator << (std::ostream & os, const EntityPrototype& entity) { + os << "Coordinate: " << entity.coordinate << std::endl; + os << "Basis: " << entity.basis << std::endl; + os << "Index: " << entity.index << std::endl; + os << "Calls: " << entity.calls << std::endl; + os << "Orientation: " << entity.orientation << std::endl; + os << "Is boundary: " << entity.isBoundary << std::endl; + os << "Center: " << entity.center << std::endl; + os << "Measure: " << entity.measure << std::endl; + + return os; +} + +template +struct EntityDataStore { + public: + using Coordinate = TNL::Containers::StaticVector; + using Point = TNL::Containers::StaticVector; + + template + using Container = TNL::Containers::Array; + + struct View { + View(typename Container::ViewType calls, + typename Container::ViewType indices, + typename Container::ViewType coordinates, + typename Container::ViewType basis, + typename Container::ViewType orientations, + typename Container::ViewType isBoundary, + typename Container::ViewType center, + typename Container::ViewType measure): calls(calls), indices(indices), coordinates(coordinates), basis(basis), orientations(orientations), isBoundary(isBoundary), center(center), measure(measure) {} + + template + __cuda_callable__ void store(const Entity entity) { + this -> store(entity, entity.getIndex()); + } + + template + __cuda_callable__ void store(const Entity entity, const Index index) { + calls[index] += 1; + indices[index] = entity.getIndex(); + isBoundary[index] = entity.isBoundary(); + orientations[index] = entity.getOrientation(); + measure[index] = entity.getMeasure(); + + auto coordinates = entity.getCoordinates(); + auto basis = entity.getBasis(); + auto center = entity.getCenter(); + + for (Index i = 0; i < GridDimension; i++) { + Index containerIndex = index * GridDimension + i; + + this->coordinates[containerIndex] = coordinates[i]; + this->basis[containerIndex] = basis[i]; + this->center[containerIndex] = center[i]; + } + } + + template + __cuda_callable__ void clear(const Entity entity) { + auto index = entity.getIndex(); + + calls[index] = 0; + indices[index] = 0; + isBoundary[index] = 0; + orientations[index] = 0; + measure[index] = 0; + + for (Index i = 0; i < GridDimension; i++) { + Index containerIndex = index * GridDimension + i; + + coordinates[containerIndex] = 0; + basis[containerIndex] = 0; + center[containerIndex] = 0; + } + } + + EntityPrototype getEntity(const Index index) { + Coordinate coordinates, basis; + Point center; + + for (Index i = 0; i < GridDimension; i++) { + Index containerIndex = index * GridDimension + i; + + coordinates[i] = this -> coordinates[containerIndex]; + basis[i] = this -> basis[containerIndex]; + center[i] = this -> center[containerIndex]; + } + + return { coordinates, basis, indices[index], calls[index], orientations[index], isBoundary[index] > 0, center, measure[index] }; + } + + protected: + typename Container::ViewType calls, indices, coordinates, basis, orientations, isBoundary; + typename Container::ViewType center, measure; + }; + + EntityDataStore(const Index& entitiesCount): entitiesCount(entitiesCount) { + calls.resize(entitiesCount); + indices.resize(entitiesCount); + isBoundary.resize(entitiesCount); + orientations.resize(entitiesCount); + + measure.resize(entitiesCount); + + coordinates.resize(GridDimension * entitiesCount); + basis.resize(GridDimension * entitiesCount); + center.resize(GridDimension * entitiesCount); + + calls = 0; + indices = 0; + isBoundary = 0; + orientations = 0; + coordinates = 0; + basis = 0; + center = 0; + measure = 0; + } + + EntityDataStore(const Index& entitiesCount, + const Container& calls, + const Container& indices, + const Container& coordinates, + const Container& basis, + const Container& orientations, + const Container& isBoundary, + const Container& center, + const Container& measure) + : entitiesCount(entitiesCount), + calls(calls), + indices(indices), + coordinates(coordinates), + orientations(orientations), + basis(basis), + isBoundary(isBoundary), + center(center), + measure(measure) {} + + View getView() { + return { calls.getView(), indices.getView(), coordinates.getView(), basis.getView(), orientations.getView(), isBoundary.getView(), center.getView(), measure.getView() }; + } + + template + EntityDataStore move() const { + using NewIndexContainer = TNL::Containers::Array; + using NewRealContainer = TNL::Containers::Array; + + EntityDataStore newContainer(this -> entitiesCount, + NewIndexContainer(this -> calls), + NewIndexContainer(this -> indices), + NewIndexContainer(this -> coordinates), + NewIndexContainer(this -> basis), + NewIndexContainer(this -> orientations), + NewIndexContainer(this -> isBoundary), + NewRealContainer(this -> center), + NewRealContainer(this -> measure)); + + return newContainer; + }; + + typename Container::ViewType getCallsView() { return calls.getView(); } + private: + Index entitiesCount; + + Container calls, indices, coordinates, orientations, basis, isBoundary; + Container center, measure; + +}; diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/Neighbours/1D/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..12417750b74566e19d03d2051d04b3e68978a7f0 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/CMakeLists.txt @@ -0,0 +1,6 @@ +include("../../CMakeSupport.cmake") + +SET(SOME_ARGS "") + +generate_executables(Grid1D_0DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) +generate_executables(Grid1D_1DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1DTestSuite.h b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1DTestSuite.h new file mode 100644 index 0000000000000000000000000000000000000000..a550096c6ff23ca1cafb99cd886980fbbe30a492 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1DTestSuite.h @@ -0,0 +1,76 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "../support.h" + +using Implementations = ::testing::Types< + TNL::Meshes::Grid<1, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Cuda, int> +>; + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + + std::vector dimensions = { + { 1 }, + { 2 }, + { 4 }, + { 8 }, + { 9 } +#if defined(HAVE_CUDA) || defined(HAVE_OPENMP) + , + { 127 }, + { 1024 } +#endif + }; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +template +void testStaticNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension) { + auto loop = [&](const auto i){ + testStaticNeighbourEntityGetter(grid, dimension); + }; + + TNL::Meshes::Templates::DescendingFor<2>::exec(loop); +} + +template +void testStaticNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension) { + auto loop = [&](const auto i){ + testStaticNeighbourEntityGetter(grid, dimension); + }; + + TNL::Meshes::Templates::DescendingFor<2>::exec(loop); +} + +template +void testDynamicNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension, const int scale = 1) { + for (int i = -1 * scale; i < 1 * scale; i++) + testDynamicNeighbourEntityGetter(grid, dimension, typename Grid::Coordinate(i)); +} + +template +void testDynamicNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension, const int scale = 1) { + for (int i = -1 * scale; i < 1 * scale; i++) + testDynamicNeighbourEntityGetter(grid, dimension, typename Grid::Coordinate(i)); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6d0e49360c9891ba628cb6e2ea88c0e29ab653f0 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid1D_0DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..6d0e49360c9891ba628cb6e2ea88c0e29ab653f0 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid1D_0DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..074eed95a34641cc56caaa3cd6b9e28ac8f684fb --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_0DTest.h @@ -0,0 +1,47 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid1DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..42ff530d2f00976dcab98bad76d662194a2ecf2c --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid1D_1DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..42ff530d2f00976dcab98bad76d662194a2ecf2c --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid1D_1DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..46f049e78ab31e648300c06b342b02b203e64547 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/1D/Grid1D_1DTest.h @@ -0,0 +1,47 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid1DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/Neighbours/2D/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..698ae9e0c463f07c8abcdde0d623ffb57fad3be9 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/CMakeLists.txt @@ -0,0 +1,7 @@ +include("../../CMakeSupport.cmake") + +SET(SOME_ARGS "") + +generate_executables(Grid2D_0DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) +generate_executables(Grid2D_1DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) +generate_executables(Grid2D_2DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2DTestSuite.h b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2DTestSuite.h new file mode 100644 index 0000000000000000000000000000000000000000..b764dd50ee09ce6913776ed2aa41a75dae65f80b --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2DTestSuite.h @@ -0,0 +1,88 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "../support.h" + +using Implementations = ::testing::Types< + TNL::Meshes::Grid<2, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Cuda, int> +>; + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + + std::vector dimensions = { + { 1, 1 }, + { 2, 1 }, + { 1, 2 }, + { 2, 2 }, + { 3, 3 } +#if HAVE_CUDA || HAVE_OPENMP + , + { 100, 1 }, + { 1, 100 }, + { 100, 100 } +#endif + }; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + + +template +void testStaticNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension) { + auto firstLoop = [&](const auto i){ + auto secondLoop = [&](const auto i, const auto j) { + testStaticNeighbourEntityGetter(grid, dimension); + }; + + TNL::Meshes::Templates::DescendingFor<2>::exec(secondLoop, i); + }; + + TNL::Meshes::Templates::DescendingFor<2>::exec(firstLoop); +} + +template +void testStaticNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension) { + auto firstLoop = [&](const auto i){ + auto secondLoop = [&](const auto i, const auto j) { + testStaticNeighbourEntityGetter(grid, dimension); + }; + + TNL::Meshes::Templates::DescendingFor<2>::exec(secondLoop, i); + }; + + TNL::Meshes::Templates::DescendingFor<2>::exec(firstLoop); +} + +template +void testDynamicNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension, const int scale = 1) { + for (int i = -1 * scale; i < 1 * scale; i++) + for (int j = -1 * scale; j < 1 * scale; j++) + testDynamicNeighbourEntityGetter(grid, dimension, typename Grid::Coordinate(i, j)); +} + +template +void testDynamicNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension, const int scale = 1) { + for (int i = -1 * scale; i < 1 * scale; i++) + for (int j = -1 * scale; j < 1 * scale; j++) + testDynamicNeighbourEntityGetter(grid, dimension, typename Grid::Coordinate(i, j)); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f64459116d204572fcdc810a6e114a921fd2456f --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid2D_0DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..f64459116d204572fcdc810a6e114a921fd2456f --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid2D_0DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..c8b84ef376cc26a19a4eccfead3733cc27ad7f31 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_0DTest.h @@ -0,0 +1,66 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid2DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_2D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_2D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..26c1e25926679ccb7d6959ad501ad46dcba8f07f --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid2D_1DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..26c1e25926679ccb7d6959ad501ad46dcba8f07f --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid2D_1DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..ad179b32b87c6da97c12f37fcc037535945e5133 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_1DTest.h @@ -0,0 +1,66 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid2DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_2D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_2D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..230a808feb1bedc1bcd29fd87ddb17f0a7a16019 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid2D_2DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..230a808feb1bedc1bcd29fd87ddb17f0a7a16019 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid2D_2DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..850647df873ee35f1d7b5238d3957567e84ac280 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/2D/Grid2D_2DTest.h @@ -0,0 +1,66 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid2DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_2D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_2D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/Neighbours/3D/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f29499185eb1b4e59c643785691d7a29ee3f3408 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/CMakeLists.txt @@ -0,0 +1,8 @@ +include("../../CMakeSupport.cmake") + +SET(SOME_ARGS "") + +generate_executables(Grid3D_0DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) +generate_executables(Grid3D_1DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) +generate_executables(Grid3D_2DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) +generate_executables(Grid3D_3DTest.h "Neighbours" "../../../../main.h" SOME_ARGS) diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3DTestSuite.h b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3DTestSuite.h new file mode 100644 index 0000000000000000000000000000000000000000..c7688b5cb404fcbfebd48af18f3ad1bcd8bd0015 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3DTestSuite.h @@ -0,0 +1,110 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "../support.h" + +using Implementations = ::testing::Types< + TNL::Meshes::Grid<3, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Cuda, int> +>; + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + + std::vector dimensions = { + { 1, 1, 1 }, + { 2, 1, 1 }, + { 1, 2, 1 }, + { 1, 1, 2 }, + { 2, 2, 2 }, + { 3, 3, 3 }, + { 10, 1, 1 }, + { 1, 10, 1 }, + { 1, 1, 10 } +#if defined(HAVE_CUDA) || defined(HAVE_OPENMP) + , + { 10, 10, 1 }, + { 1, 10, 10 }, + { 10, 1, 10 }, + { 10, 10, 10 } +#endif + }; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +template +void testStaticNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension) { + testStaticNeighbourEntityGetter(grid, dimension); + + // Uncomment, if you want to test for all instances. Note, that it may take a lot of time to compile. + // + // auto firstLoop = [&](const auto i){ + // auto secondLoop = [&](const auto i, const auto j) { + // auto thirdLoop = [&](const auto i, const auto j, const auto k) { + // testStaticNeighbourEntityGetter(grid, dimension); + // }; + + // TNL::Meshes::Templates::DescendingFor<2>::exec(thirdLoop, i, j); + // }; + + // TNL::Meshes::Templates::DescendingFor<2>::exec(secondLoop, i); + // }; + + // TNL::Meshes::Templates::DescendingFor<2>::exec(firstLoop); +} + +template +void testStaticNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension) { + testStaticNeighbourEntityGetter(grid, dimension); + + // Uncomment, if you want to test for all instances. Note, that it may take a lot of time to compile. + // + // auto firstLoop = [&](const auto i){ + // auto secondLoop = [&](const auto i, const auto j) { + // auto thirdLoop = [&](const auto i, const auto j, const auto k) { + // testStaticNeighbourEntityGetter(grid, dimension); + // }; + + // TNL::Meshes::Templates::DescendingFor<2>::exec(thirdLoop, i, j); + // }; + + // TNL::Meshes::Templates::DescendingFor<2>::exec(secondLoop, i); + // }; + + // TNL::Meshes::Templates::DescendingFor<2>::exec(firstLoop); +} + +template +void testDynamicNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension, const int scale = 1) { + for (int i = -1 * scale; i < 1 * scale; i++) + for (int j = -1 * scale; j < 1 * scale; j++) + for (int k = -1 * scale; k < 1 * scale; k++) + testDynamicNeighbourEntityGetter(grid, dimension, typename Grid::Coordinate(i, j, k)); +} + +template +void testDynamicNeighbourEntityGetterForAllStencils(Grid& grid, const typename Grid::Coordinate& dimension, const int scale = 1) { + for (int i = -1 * scale; i < 1 * scale; i++) + for (int j = -1 * scale; j < 1 * scale; j++) + for (int k = -1 * scale; k < 1 * scale; k++) + testDynamicNeighbourEntityGetter(grid, dimension, typename Grid::Coordinate(i, j, k)); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7b9753a2246c6052c7f3f0a2a76643b30aa0fa7a --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid3D_0DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..7b9753a2246c6052c7f3f0a2a76643b30aa0fa7a --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid3D_0DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..27a722396b46fd2f41b70c5deb6362de4e5aced3 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_0DTest.h @@ -0,0 +1,87 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid3DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_2D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_3D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_2D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_0D_Entity_TO_3D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d5ac9984180cd9533c8ff470a6ab8e2cc839e08 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid3D_1DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..5d5ac9984180cd9533c8ff470a6ab8e2cc839e08 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid3D_1DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..d7a090d1273aca610ab3174703ec144514b831cc --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_1DTest.h @@ -0,0 +1,87 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid3DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_2D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_3D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_2D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_1D_Entity_TO_3D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ac02aaace95343d8019143a19018529be6c606ff --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid3D_2DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..ac02aaace95343d8019143a19018529be6c606ff --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid3D_2DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..bd244b19fbc5734ccae5c5defc07b2c5f51779bd --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_2DTest.h @@ -0,0 +1,88 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid3DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_2D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_3D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientationation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientationation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_2D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_2D_Entity_TO_3D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.cpp b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3cf7b3a449c4ce8c77c895c672267582444ab49d --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid3D_3DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.cu b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..3cf7b3a449c4ce8c77c895c672267582444ab49d --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid3D_3DTest.h" +#include "../../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.h b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..ef0719b336c2717d20521402de2a9b12285acf77 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/3D/Grid3D_3DTest.h @@ -0,0 +1,87 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include "Grid3DTestSuite.h" +#include + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_0D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Offseett + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_1D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_2D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_3D_By_StaticGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testStaticNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_0D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_1D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_2D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +TYPED_TEST(GridTestSuite, TestNeighbour_OF_3D_Entity_TO_3D_By_DynamicGetter) { + // EntityDimension | NeighbourEntityDimension | Orientation + for (const auto& dimension : this->dimensions) { + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + testDynamicNeighbourEntityGetterForAllStencils(this -> grid, dimension); + } +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/Neighbours/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..bb8f4c36de7f734c161b83be5289e53b57477aee --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory(1D) +add_subdirectory(2D) +add_subdirectory(3D) diff --git a/src/UnitTests/Meshes/GridTests/Neighbours/support.h b/src/UnitTests/Meshes/GridTests/Neighbours/support.h new file mode 100644 index 0000000000000000000000000000000000000000..75185371aaadf652f5550e422a814264bca53dc8 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Neighbours/support.h @@ -0,0 +1,286 @@ +#pragma once + +#ifdef HAVE_GTEST + +#include "../EntityDataStore.h" +#include "../CoordinateIterator.h" +#include + +template +class NeighbourGridEntityGetterTestCase { + public: + using Index = typename Grid::IndexType; + using Real = typename Grid::RealType; + using Coordinate = typename Grid::Coordinate; + using DataStore = EntityDataStore; + using HostDataStore = EntityDataStore; + + template + void storeByStaticAccessor(const Grid& grid, DataStore& store) { + SCOPED_TRACE("Store using static accessor without"); + + constexpr int neighbourOrientationsCount = Grid::getEntityOrientationsCount(NeighbourEntityDimension); + + auto view = store.getView(); + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + int neighbourEntityOrientation = TNL::min(entity.getOrientation(), neighbourOrientationsCount - 1); + Coordinate alignedCoordinate = entity.getCoordinates() + Coordinate(Steps...); + Coordinate boundary = grid.getDimensions() + grid.template getBasis(neighbourEntityOrientation); + + if (alignedCoordinate >= 0 && alignedCoordinate < boundary) { + auto neighbour = entity.template getNeighbourEntity(); + + neighbour.refresh(); + + view.store(neighbour, entity.getIndex()); + } + }; + + grid.template forAll(update); + } + + template + void storeByStaticAccessorWithOrientation(const Grid& grid, DataStore& store) { + SCOPED_TRACE("Store using static accessor with orientation"); + + auto view = store.getView(); + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + Coordinate alignedCoordinate = entity.getCoordinates() + Coordinate(Steps...); + Coordinate boundary = grid.getDimensions() + grid.template getBasis(NeighbourEntityOrientation); + + if ((alignedCoordinate >= 0 && alignedCoordinate < boundary)) { + auto neighbour = entity.template getNeighbourEntity(); + + neighbour.refresh(); + + view.store(neighbour, entity.getIndex()); + } + }; + + grid.template forAll(update); + } + + void storeByDynamicAccessor(const Grid& grid, DataStore& store, const Coordinate& offset) { + SCOPED_TRACE("Store using dynamic accessor without orientation"); + + constexpr int neighbourOrientationsCount = Grid::getEntityOrientationsCount(NeighbourEntityDimension); + + auto view = store.getView(); + auto update = [=] __cuda_callable__(const typename Grid::EntityType& entity) mutable { + int neighbourEntityOrientation = TNL::min(entity.getOrientation(), neighbourOrientationsCount - 1); + Coordinate alignedCoordinate = entity.getCoordinates() + offset; + Coordinate boundary = grid.getDimensions() + grid.template getBasis(neighbourEntityOrientation); + + if ((alignedCoordinate >= 0 && alignedCoordinate < boundary)) { + auto neighbour = entity.template getNeighbourEntity(offset); + + neighbour.refresh(); + + view.store(neighbour, entity.getIndex()); + } + }; + + grid.template forAll(update); + } + + template + void storeByDynamicAccessorWithOrientation(const Grid& grid, DataStore& store, const Coordinate& offset) { + SCOPED_TRACE("Store using dynamic accessor with orientation"); + + auto view = store.getView(); + auto update = [=] __cuda_callable__(const typename Grid::EntityType& entity) mutable { + Coordinate alignedCoordinate = entity.getCoordinates() + offset; + Coordinate boundary = grid.getDimensions() + grid.template getBasis(NeighbourEntityOrientation); + + if ((alignedCoordinate >= 0 && alignedCoordinate < boundary)) { + auto neighbour = entity.template getNeighbourEntity(offset); + + neighbour.refresh(); + + view.store(neighbour, entity.getIndex()); + } + }; + + grid.template forAll(update); + } + + void verify(const Grid& grid, DataStore& store, const Coordinate& offset, const int entityOrientation) { + auto hostStore = store.template move(); + auto hostStoreView = hostStore.getView(); + + constexpr int orientationsCount = Grid::getEntityOrientationsCount(EntityDimension); + constexpr int neighbourEntityOrientationsCount = Grid::getEntityOrientationsCount(NeighbourEntityDimension); + + auto verify = [&](const auto orientation) { + GridCoordinateIterator iterator(grid.getDimensions()); + + if (!iterator.canIterate()) { + SCOPED_TRACE("Skip iteration"); + EXPECT_EQ(hostStore.getCallsView().getSize(), 0) << "Expect, that we can't iterate, when grid is empty"; + return; + } + + int neighbourEntityOrientation = 0; + + if (entityOrientation == -1) { + int tmp = orientation; + neighbourEntityOrientation = TNL::min(tmp, neighbourEntityOrientationsCount - 1); + } else { + neighbourEntityOrientation = entityOrientation; + } + + const Coordinate neighbourEntityBasis = grid.template getBasis(neighbourEntityOrientation); + + do { + Index parentEntityIndex = iterator.getIndex(grid); + auto neighbourEntity = hostStoreView.getEntity(parentEntityIndex); + + Coordinate alignedCoordinate = iterator.getCoordinate() + offset; + + // Unable to get entity out of bounds + bool expectCall = alignedCoordinate >= Coordinate(0) && alignedCoordinate < grid.getDimensions() + neighbourEntityBasis; + + EXPECT_EQ(expectCall, neighbourEntity.calls == 1) << + "Expect, that the parent entity was called"; + EXPECT_EQ(expectCall ? alignedCoordinate : Coordinate(0), neighbourEntity.coordinate) << + "Expect, that the coordinate is updated"; + EXPECT_EQ(expectCall ? neighbourEntityBasis : Coordinate(0), neighbourEntity.basis) << + "Expect, that the basis is updated"; + EXPECT_EQ(expectCall ? neighbourEntityOrientation : 0, neighbourEntity.orientation) << + "Expect, that the parent entity was called"; + } while (!iterator.next()); + }; + + TNL::Meshes::Templates::DescendingFor::exec(verify); + } + protected: + template + class GridCoordinateIterator: public CoordinateIterator { + public: + using Base = CoordinateIterator; + using EntityBasis = TNL::Meshes::BasisGetter; + + GridCoordinateIterator(const Coordinate& end): Base(Coordinate(0), end + EntityBasis::template getBasis()) { + for (Index i = 0; i < this -> current.getSize(); i++) { + this -> start[i] = 0; + this -> current[i] = 0; + } + } + + Coordinate getCoordinate() const { + return this -> current; + } + + Index getIndex(const Grid& grid) const { + Index result = 0; + + for (Index i = 0; i < this->current.getSize(); i++) { + if (i == 0) { + result += this->current[i]; + } else { + Index offset = 1; + + for (Index j = 0; j < i; j++) offset *= this->end[j]; + + result += this->current[i] * offset; + } + } + + for (Index i = 0; i < Orientation; i++) result += grid.getOrientedEntitiesCount(EntityDimension, i); + + return result; + } + }; +}; + +template = true> +void testStaticNeighbourEntityGetter(Grid& grid, const typename Grid::Coordinate& dimensions) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Neighbour Entity Dimension: " + TNL::convertToString(NeighbourEntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + + using Test = NeighbourGridEntityGetterTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.template storeByStaticAccessor(grid, store); + test.verify(grid, store, typename Grid::Coordinate(Steps...), -1); +} + +template = true> +void testStaticNeighbourEntityGetter(Grid& grid, const typename Grid::Coordinate& dimensions) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Neighbour Entity Dimension: " + TNL::convertToString(NeighbourEntityDimension)); + SCOPED_TRACE("Neighbour Entity Orientation: " + TNL::convertToString(NeighbourEntityOrientation)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + + using Test = NeighbourGridEntityGetterTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.template storeByStaticAccessorWithOrientation(grid, store); + test.verify(grid, store, typename Grid::Coordinate(Steps...), NeighbourEntityOrientation); +} + + +template +void testDynamicNeighbourEntityGetter(Grid& grid, const typename Grid::Coordinate& dimensions, const typename Grid::Coordinate& offset) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Neighbour Entity Dimension: " + TNL::convertToString(NeighbourEntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + + using Test = NeighbourGridEntityGetterTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.storeByDynamicAccessor(grid, store, offset); + test.verify(grid, store, offset, -1); +} + +template +void testDynamicNeighbourEntityGetter(Grid& grid, const typename Grid::Coordinate& dimensions, const typename Grid::Coordinate& offset) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Neighbour Entity Dimension: " + TNL::convertToString(NeighbourEntityDimension)); + SCOPED_TRACE("Neighbour Entity Orientation: " + TNL::convertToString(NeighbourEntityOrientation)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + + using Test = NeighbourGridEntityGetterTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.template storeByDynamicAccessorWithOrientation(grid, store, offset); + test.verify(grid, store, offset, NeighbourEntityOrientation); +} + + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Traverse/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/Traverse/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..4dfb0deb5abcc4a9e154e6ba168ec16e92849b1c --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/CMakeLists.txt @@ -0,0 +1,7 @@ +include("../CMakeSupport.cmake") + +SET(SOME_ARGS "") + +generate_executables(Grid1DTest.h "Traversers" "../../../main.h" SOME_ARGS) +generate_executables(Grid2DTest.h "Traversers" "../../../main.h" SOME_ARGS) +generate_executables(Grid3DTest.h "Traversers" "../../../main.h" SOME_ARGS) diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.cpp b/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..73c81a9543d24b2200a95b5328128f353eb6da2b --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid1DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.cu b/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..73c81a9543d24b2200a95b5328128f353eb6da2b --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid1DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.h b/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1cd6aa7e6c5d025fe8783aec4d22412aad6e158f --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid1DTest.h @@ -0,0 +1,136 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "support.h" + +#ifdef HAVE_CUDA +using Implementations = ::testing::Types< + TNL::Meshes::Grid<1, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Cuda, int> +>; +#else +using Implementations = ::testing::Types< + TNL::Meshes::Grid<1, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<1, float, TNL::Devices::Host, int> +>; +#endif + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + + std::vector dimensions = { + { 1 }, + { 2 }, + { 4 }, + { 8 }, + { 9 } +#if defined(HAVE_CUDA) || defined(HAVE_OPENMP) + , + { 127 }, + { 1024 } +#endif + }; + + std::vector origins = { + { 1 }, + { -10 }, + { 0.1 }, + { 1 }, + { 1 }, + { -2 } + }; + + std::vector spaceSteps = { + { 0.1 }, + { 2 }, + { 0.1 }, + { 1 }, + { 12 } + }; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestForAllTraverse_0D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this->grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForAllTraverse_1D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this->grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testForInteriorTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testForInteriorTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testForBoundaryTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testForBoundaryTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInteriorEqualAllProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInteriorEqualAllProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.cpp b/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63738765a8730089d970d0ee219d88e68e8851bf --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid2DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.cu b/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..63738765a8730089d970d0ee219d88e68e8851bf --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid2DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.h b/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..964220a7ca9d3876291245744a52f1062dabb8bd --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid2DTest.h @@ -0,0 +1,169 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include + +#include "support.h" + +#ifdef HAVE_CUDA +using Implementations = ::testing::Types< + TNL::Meshes::Grid<2, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Cuda, int> +>; +#else +using Implementations = ::testing::Types< + TNL::Meshes::Grid<2, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<2, float, TNL::Devices::Host, int> +>; +#endif + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + + std::vector dimensions = { + { 1, 1 }, + { 2, 1 }, + { 1, 2 }, + { 2, 2 }, + { 3, 3 }, + { 100, 1 }, + { 1, 100 } +#if defined(HAVE_CUDA) || defined(HAVE_OPENMP) + , + { 100, 100 } +#endif + }; + + std::vector origins = { + { 1, 1 }, + { -10, -10 }, + { 0.1, 0.1 }, + { 1, 0.2 }, + { 1, -1 }, + { -2, -2 } + }; + + std::vector spaceSteps = { + { 0.1, 0.1 }, + { 2, 2.4 }, + { 0.1, 3.1 }, + { 1, 4 }, + { 12, 2 } + }; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestForAllTraverse_0D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this -> grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForAllTraverse_1D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this -> grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForAllTraverse_2D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this -> grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testForInteriorTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testForInteriorTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testForInteriorTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testForBoundaryTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testForBoundaryTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testForBoundaryTraverse(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInternalEqualAllProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInternalEqualAllProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInternalEqualAllProperty_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.cpp b/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f9bb7cd1339c087bc35ba2c189c0f57087f60e9 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.cpp @@ -0,0 +1,3 @@ + +#include "Grid3DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.cu b/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..4f9bb7cd1339c087bc35ba2c189c0f57087f60e9 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.cu @@ -0,0 +1,3 @@ + +#include "Grid3DTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.h b/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.h new file mode 100644 index 0000000000000000000000000000000000000000..138b30a770e5446a6c8f7e6828681f4f3a11cea2 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/Grid3DTest.h @@ -0,0 +1,205 @@ + +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include +#include "support.h" + +#ifdef HAVE_CUDA +using Implementations = ::testing::Types< + TNL::Meshes::Grid<3, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, double, TNL::Devices::Cuda, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Cuda, int> +>; +#else +using Implementations = ::testing::Types< + TNL::Meshes::Grid<3, double, TNL::Devices::Host, int>, + TNL::Meshes::Grid<3, float, TNL::Devices::Host, int> +>; +#endif + +template +class GridTestSuite: public ::testing::Test { + protected: + GridType grid; + + std::vector dimensions = { + { 1, 1, 1 }, + { 2, 1, 1 }, + { 1, 2, 1 }, + { 1, 1, 2 }, + { 2, 2, 2 }, + { 3, 3, 3 }, + { 10, 1, 1 }, + { 1, 10, 1 }, + { 1, 1, 10 } +#if defined(HAVE_CUDA) || defined(HAVE_OPENMP) + , + { 10, 10, 1 }, + { 1, 10, 10 }, + { 10, 1, 10 }, + { 10, 10, 10 } +#endif + }; + + std::vector origins = { + { 1, 1, 1 }, + { -10, -10, 2 }, + { 0.1, 0.1, 0.1 }, + { 1, 0.2, 1 }, + { 1, -1, 2 }, + { -2, -2, -2 } + }; + + std::vector spaceSteps = { + { 0.1, 0.1, 0.1 }, + { 2, 2.4, 2 }, + { 0.1, 3.1, 1 }, + { 1, 4, 2 }, + { 12, 2, 1 } + }; + +#ifndef HAVE_CUDA + void SetUp() override { + if (std::is_same::value) { + GTEST_SKIP() << "No CUDA available on host. Try to compile with CUDA instead"; + } + } +#endif +}; + +TYPED_TEST_SUITE(GridTestSuite, Implementations); + +TYPED_TEST(GridTestSuite, TestForAllTraverse_0D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this->grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForAllTraverse_1D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this->grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForAllTraverse_2D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this->grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForAllTraverse_3D_Entity) { + for (const auto& dimension: this->dimensions) + for (const auto& origin: this->origins) + for (const auto& spaceStep: this->spaceSteps) + testForAllTraverse(this->grid, dimension, origin, spaceStep); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_0D_Entity) { + for (const auto& dimension : this->dimensions) + testForInteriorTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_1D_Entity) { + for (const auto& dimension : this->dimensions) + testForInteriorTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_2D_Entity) { + for (const auto& dimension : this->dimensions) + testForInteriorTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForInteriorTraverse_3D_Entity) { + for (const auto& dimension : this->dimensions) + testForInteriorTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_0D_Entity) { + for (const auto& dimension : this->dimensions) + testForBoundaryTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_1D_Entity) { + for (const auto& dimension : this->dimensions) + testForBoundaryTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_2D_Entity) { + for (const auto& dimension : this->dimensions) + testForBoundaryTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestForBoundaryTraverse_3D_Entity) { + for (const auto& dimension : this->dimensions) + testForBoundaryTraverse(this->grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInternalEqualAllProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInternalEqualAllProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInternalEqualAllProperty_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestBoundaryUnionInternalEqualAllProperty_3D_Entity) { + for (const auto& dimension : this -> dimensions) + testBoundaryUnionInteriorEqualAllProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusBoundaryEqualInteriorProperty_3D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusBoundaryEqualInteriorProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_0D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_1D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_2D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +TYPED_TEST(GridTestSuite, TestAllMinusInteriorEqualBoundaryProperty_3D_Entity) { + for (const auto& dimension : this -> dimensions) + testAllMinusInteriorEqualBoundaryProperty(this -> grid, dimension); +} + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Traverse/support.h b/src/UnitTests/Meshes/GridTests/Traverse/support.h new file mode 100644 index 0000000000000000000000000000000000000000..5e4bfc1a23f89fe87af295f6fbe249e159050e8b --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Traverse/support.h @@ -0,0 +1,482 @@ +#pragma once + +#ifdef HAVE_GTEST + +#include +#include + +#include +#include + +#include "../CoordinateIterator.h" +#include "../EntityDataStore.h" + +namespace Templates { +/* + * A compiler-friendly implementation of the templated for-cycle, because + * the template specializations count is O(Value) bounded. + */ +template +struct DescendingFor; + +template +struct DescendingFor { + public: + template + static void exec(Func func, FuncArgs&&... args) { + static_assert(Value > 0, "Couldn't descend for negative values"); + + func(std::integral_constant(), std::forward(args)...); + + DescendingFor::exec(std::forward(func), std::forward(args)...); + } +}; + +template <> +struct DescendingFor<0> { + public: + template + static void exec(Func func, FuncArgs&&... args) { + func(std::integral_constant(), std::forward(args)...); + } +}; + +} // namespace Templates + +template +class GridTraverseTestCase { + public: + using Index = typename Grid::IndexType; + using Real = typename Grid::RealType; + using Coordinate = typename Grid::Coordinate; + using Point = typename Grid::Point; + using DataStore = EntityDataStore; + using HostDataStore = EntityDataStore; + + // NVCC is incapable of deducing generic lambda + using UpdateFunctionType = std::function&)>; + + void storeAll(const Grid& grid, DataStore& store) const { + SCOPED_TRACE("Store all"); + + auto view = store.getView(); + + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + view.store(entity); + }; + + grid.template forAll(update); + } + void storeBoundary(const Grid& grid, DataStore& store) const { + SCOPED_TRACE("Store boundary"); + + auto view = store.getView(); + + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + view.store(entity); + }; + + grid.template forBoundary(update); + } + void storeInterior(const Grid& grid, DataStore& store) const { + SCOPED_TRACE("Store interior"); + + auto view = store.getView(); + + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + view.store(entity); + }; + + grid.template forInterior(update); + } + void clearAll(const Grid& grid, DataStore& store) const { + SCOPED_TRACE("Clear all"); + + auto view = store.getView(); + + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + view.clear(entity); + }; + + grid.template forAll(update); + } + void clearBoundary(const Grid& grid, DataStore& store) const { + SCOPED_TRACE("Clear boundary"); + + auto view = store.getView(); + + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + view.clear(entity); + }; + + grid.template forBoundary(update); + } + void clearInterior(const Grid& grid, DataStore& store) const { + SCOPED_TRACE("Clear interior"); + + auto view = store.getView(); + + auto update = [=] __cuda_callable__ (const typename Grid::EntityType& entity) mutable { + view.clear(entity); + }; + + grid.template forInterior(update); + } + + void verifyAll(const Grid& grid, const DataStore& store) const { + auto hostStore = store.template move(); + auto hostStoreView = hostStore.getView(); + + constexpr int orientationsCount = Grid::getEntityOrientationsCount(EntityDimension); + + SCOPED_TRACE("Verifying forAll"); + SCOPED_TRACE("Orientations Count: " + TNL::convertToString(orientationsCount)); + + ASSERT_GT(orientationsCount, 0) << "Every entity must have at least one orientation"; + + auto callsView = hostStore.getCallsView(); + + for (Index i = 0; i < callsView.getSize(); i++) + EXPECT_EQ(callsView[i], 1) << "Expect each index to be called only once"; + + auto verify = [&](const auto orientation) { + GridCoordinateIterator iterator(grid.getDimensions()); + + if (!iterator.canIterate()) { + SCOPED_TRACE("Skip iteration"); + EXPECT_EQ(callsView.getSize(), 0) << "Expect, that we can't iterate, when grid is empty"; + return; + } + + do { + verifyEntity(grid, iterator, hostStoreView, true); + } while (!iterator.next()); + }; + + Templates::DescendingFor::exec(verify); + } + void verifyBoundary(const Grid& grid, const DataStore& store) const { + auto hostStore = store.template move(); + auto hostStoreView = hostStore.getView(); + + constexpr int orientationsCount = Grid::getEntityOrientationsCount(EntityDimension); + + SCOPED_TRACE("Verifying forBoundary"); + SCOPED_TRACE("Orientations Count: " + TNL::convertToString(orientationsCount)); + + ASSERT_GT(orientationsCount, 0) << "Every entity must have at least one orientation"; + + auto verify = [&](const auto orientation) { + GridCoordinateIterator iterator(grid.getDimensions()); + + if (!iterator.canIterate()) { + SCOPED_TRACE("Skip iteration"); + EXPECT_EQ(hostStore.getCallsView().getSize(), 0) << "Expect, that we can't iterate, when grid is empty"; + return; + } + + do { + verifyEntity(grid, iterator, hostStoreView, iterator.isBoundary(grid)); + } while (!iterator.next()); + }; + + Templates::DescendingFor::exec(verify); + } + void verifyInterior(const Grid& grid, const DataStore& store) const { + auto hostStore = store.template move(); + auto hostStoreView = hostStore.getView(); + + constexpr int orientationsCount = Grid::getEntityOrientationsCount(EntityDimension); + + SCOPED_TRACE("Verifying forInterior"); + SCOPED_TRACE("Orientations Count: " + TNL::convertToString(orientationsCount)); + + ASSERT_GT(orientationsCount, 0) << "Every entity must have at least one orientation"; + + auto verify = [&](const auto orientation) { + GridCoordinateIterator iterator(grid.getDimensions()); + + if (!iterator.canIterate()) { + SCOPED_TRACE("Skip iteration"); + EXPECT_EQ(hostStore.getCallsView().getSize(), 0) << "Expect, that we can't iterate, when grid is empty"; + return; + } + + do { + verifyEntity(grid, iterator, hostStoreView, !iterator.isBoundary(grid)); + } while (!iterator.next()); + }; + + Templates::DescendingFor::exec(verify); + } + private: + template + class GridCoordinateIterator: public CoordinateIterator { + public: + using Base = CoordinateIterator; + using EntityBasis = TNL::Meshes::BasisGetter; + + GridCoordinateIterator(const Coordinate& end): Base(Coordinate(0), end + EntityBasis::template getBasis()) { + for (Index i = 0; i < this -> current.getSize(); i++) { + this -> start[i] = 0; + this -> current[i] = 0; + } + } + + bool isBoundary(const Grid& grid) const { + switch (EntityDimension) { + case Grid::getMeshDimension(): + for (Index i = 0; i < this -> current.getSize(); i++) + if (this -> current[i] == 0 || this -> current[i] == grid.getDimension(i) - 1) + return true; + + break; + default: + for (Index i = 0; i < this -> current.getSize(); i++) + if (getBasis()[i] && (this -> current[i] == 0 || this -> current[i] == grid.getDimension(i))) + return true; + break; + } + + return false; + } + + Coordinate getCoordinate() const { + return this -> current; + } + + Index getIndex(const Grid& grid) const { + Index result = 0; + + for (Index i = 0; i < this -> current.getSize(); i++) { + if (i == 0) { + result += this -> current[i]; + } else { + Index offset = 1; + + for (Index j = 0; j < i; j++) + offset *= this -> end[j]; + + result += this -> current[i] * offset; + } + } + + for (Index i = 0; i < Orientation; i++) + result += grid.getOrientedEntitiesCount(EntityDimension, i); + + return result; + } + + Coordinate getBasis() const { + return EntityBasis::template getBasis(); + } + + Point getCenter(const Grid& grid) const { + Point origin = grid.getOrigin(), center, spaceSteps = grid.getSpaceSteps(); + + Coordinate basis = getBasis(); + + for (Index i = 0; i < this -> current.getSize(); i++) + center[i] = origin[i] + (this -> current[i] + (Real)(0.5 * !basis[i])) * spaceSteps[i]; + + return center; + } + + Real getMeasure(const Grid& grid) const { + if (EntityDimension == 0) { + return 0.0; + } + + Coordinate basis = getBasis(), powers; + + for (Index i = 0; i < this -> current.getSize(); i++) + powers[i] = !basis[i]; + + return grid.getSpaceStepsProducts(powers); + } + }; + + template + void verifyEntity(const Grid& grid, + const GridCoordinateIterator& iterator, + typename HostDataStore::View& dataStore, + bool expectCall) const { + static Real precision = 9e-5; + + auto index = iterator.getIndex(grid); + auto entity = dataStore.getEntity(index); + + SCOPED_TRACE("Entity: " + TNL::convertToString(entity)); + + EXPECT_EQ(entity.calls, expectCall ? 1 : 0) << "Expect the index to be called once"; + EXPECT_EQ(entity.index, expectCall ? index : 0) << "Expect the index was correctly set"; + EXPECT_EQ(entity.isBoundary, expectCall ? iterator.isBoundary(grid) : 0) << "Expect the index was correctly set" ; + + Coordinate coordinate = expectCall ? iterator.getCoordinate() : Coordinate(0); + Coordinate basis = expectCall ? iterator.getBasis() : Coordinate(0); + Point center = expectCall ? iterator.getCenter(grid) : Point(0); + + EXPECT_EQ(entity.coordinate, coordinate) + << "Expect the coordinates are the same on the same index. "; + EXPECT_EQ(entity.basis, basis) + << "Expect the bases are the same on the same index. "; + + // CUDA calculates floating points differently. + EXPECT_NEAR(expectCall ? iterator.getMeasure(grid) : 0.0, entity.measure, precision) + << "Expect the measure was correctly calculated. "; + + for (Index i = 0; i < Grid::getMeshDimension(); i++) + EXPECT_NEAR(entity.center[i], center[i], precision) + << "Expect the centers are the same on the same index. " << entity.center << " " << center; + } +}; + +template +void testForAllTraverse(Grid& grid, + const typename Grid::Coordinate& dimensions, + const typename Grid::Point& origin = typename Grid::Point(0), + const typename Grid::Point& spaceSteps = typename Grid::Point(1)) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Origin:" + TNL::convertToString(origin)); + SCOPED_TRACE("Space steps:" + TNL::convertToString(spaceSteps)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + EXPECT_NO_THROW(grid.setOrigin(origin)) << "Verify, that the set of" << origin << "doesn't cause assert"; + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of" << spaceSteps << "doesn't cause assert"; + + using Test = GridTraverseTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.storeAll(grid, store); + test.verifyAll(grid, store); +} + +template +void testForInteriorTraverse(Grid& grid, + const typename Grid::Coordinate& dimensions, + const typename Grid::Point& origin = typename Grid::Point(0), + const typename Grid::Point& spaceSteps = typename Grid::Point(1)) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Origin:" + TNL::convertToString(origin)); + SCOPED_TRACE("Space steps:" + TNL::convertToString(spaceSteps)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + EXPECT_NO_THROW(grid.setOrigin(origin)) << "Verify, that the set of" << origin << "doesn't cause assert"; + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of" << spaceSteps << "doesn't cause assert"; + + using Test = GridTraverseTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.storeInterior(grid, store); + test.verifyInterior(grid, store); +} + +template +void testForBoundaryTraverse(Grid& grid, + const typename Grid::Coordinate& dimensions, + const typename Grid::Point& origin = typename Grid::Point(0), + const typename Grid::Point& spaceSteps = typename Grid::Point(1)) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Origin:" + TNL::convertToString(origin)); + SCOPED_TRACE("Space steps:" + TNL::convertToString(spaceSteps)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + EXPECT_NO_THROW(grid.setOrigin(origin)) << "Verify, that the set of" << origin << "doesn't cause assert"; + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of" << spaceSteps << "doesn't cause assert"; + + using Test = GridTraverseTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.storeBoundary(grid, store); + test.verifyBoundary(grid, store); +} + +template +void testBoundaryUnionInteriorEqualAllProperty(Grid& grid, + const typename Grid::Coordinate& dimensions, + const typename Grid::Point& origin = typename Grid::Point(0), + const typename Grid::Point& spaceSteps = typename Grid::Point(1)) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Origin:" + TNL::convertToString(origin)); + SCOPED_TRACE("Space steps:" + TNL::convertToString(spaceSteps)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + EXPECT_NO_THROW(grid.setOrigin(origin)) << "Verify, that the set of" << origin << "doesn't cause assert"; + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of" << spaceSteps << "doesn't cause assert"; + + using Test = GridTraverseTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.storeBoundary(grid, store); + test.storeInterior(grid, store); + test.verifyAll(grid, store); +} + +template +void testAllMinusBoundaryEqualInteriorProperty(Grid& grid, + const typename Grid::Coordinate& dimensions, + const typename Grid::Point& origin = typename Grid::Point(0), + const typename Grid::Point& spaceSteps = typename Grid::Point(1)) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Origin:" + TNL::convertToString(origin)); + SCOPED_TRACE("Space steps:" + TNL::convertToString(spaceSteps)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + EXPECT_NO_THROW(grid.setOrigin(origin)) << "Verify, that the set of" << origin << "doesn't cause assert"; + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of" << spaceSteps << "doesn't cause assert"; + + using Test = GridTraverseTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.storeAll(grid, store); + test.clearBoundary(grid, store); + test.verifyInterior(grid, store); +} + +template +void testAllMinusInteriorEqualBoundaryProperty(Grid& grid, + const typename Grid::Coordinate& dimensions, + const typename Grid::Point& origin = typename Grid::Point(0), + const typename Grid::Point& spaceSteps = typename Grid::Point(1)) { + SCOPED_TRACE("Grid Dimension: " + TNL::convertToString(Grid::getMeshDimension())); + SCOPED_TRACE("Entity Dimension: " + TNL::convertToString(EntityDimension)); + SCOPED_TRACE("Dimension: " + TNL::convertToString(dimensions)); + SCOPED_TRACE("Origin:" + TNL::convertToString(origin)); + SCOPED_TRACE("Space steps:" + TNL::convertToString(spaceSteps)); + + EXPECT_NO_THROW(grid.setDimensions(dimensions)) << "Verify, that the set of" << dimensions << " doesn't cause assert"; + EXPECT_NO_THROW(grid.setOrigin(origin)) << "Verify, that the set of" << origin << "doesn't cause assert"; + EXPECT_NO_THROW(grid.setSpaceSteps(spaceSteps)) << "Verify, that the set of" << spaceSteps << "doesn't cause assert"; + + using Test = GridTraverseTestCase; + + Test test; + typename Test::DataStore store(grid.getEntitiesCount(EntityDimension)); + + test.storeAll(grid, store); + test.clearInterior(grid, store); + test.verifyBoundary(grid, store); +} + + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Utils/CMakeLists.txt b/src/UnitTests/Meshes/GridTests/Utils/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..cb7634f725f963326de45eb390ec7624f07a60f0 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Utils/CMakeLists.txt @@ -0,0 +1,6 @@ +include("../CMakeSupport.cmake") + +SET(SOME_ARGS "") + +generate_executables(GridBasisTest.h "Utils" "../../../main.h" SOME_ARGS) +generate_executables(GridTemplatesTest.h "Utils" "../../../main.h" SOME_ARGS) diff --git a/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.cpp b/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f8c12abefcef57d6b55af455ec82970c627d506d --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.cpp @@ -0,0 +1,3 @@ + +#include "GridBasisTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.cu b/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..f8c12abefcef57d6b55af455ec82970c627d506d --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.cu @@ -0,0 +1,3 @@ + +#include "GridBasisTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.h b/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.h new file mode 100644 index 0000000000000000000000000000000000000000..1e51178aa8d009109046263858974a6272ba6eb1 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Utils/GridBasisTest.h @@ -0,0 +1,75 @@ +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include +#include + +template +void compare(const TNL::Containers::StaticVector& expectation) { + auto basis = TNL::Meshes::BasisGetter::template getBasis(); + + EXPECT_EQ(basis, expectation) << "Grid Dimension: [" << GridDimension << "], " + << "Entity Orientation: [" << EntityOrientation << "], " + << "Entity Dimension: [" << EntityDimension << "]"; +} + +TEST(BasisTestSuite, Basis1DTest) { + // Grid Dimension, EntityOrientation, EntityDimension + compare<1, 0, 0>({ 1 }); + compare<1, 0, 1>({ 0 }); +} + +TEST(BasisTestSuite, Basis2DTest) { + // Grid Dimension, EntityOrientation, EntityDimension + compare<2, 0, 0>({ 1, 1 }); + + compare<2, 0, 1>({ 0, 1 }); + compare<2, 1, 1>({ 1, 0 }); + + compare<2, 0, 2>({ 0, 0 }); +} + +TEST(BasisTestSuite, Basis3DTest) { + // Grid Dimension, EntityOrientation, EntityDimension + compare<3, 0, 0>({ 1, 1, 1 }); + + compare<3, 0, 1>({ 0, 1, 1 }); + compare<3, 1, 1>({ 1, 0, 1 }); + compare<3, 2, 1>({ 1, 1, 0 }); + + compare<3, 0, 2>({ 0, 0, 1 }); + compare<3, 1, 2>({ 0, 1, 0 }); + compare<3, 2, 2>({ 1, 0, 0 }); + + compare<3, 0, 3>({ 0, 0, 0 }); +} + +TEST(BasisTestSuite, Basis4DTest) { + // Grid Dimension, EntityOrientation, EntityDimension + compare<4, 0, 0>({ 1, 1, 1, 1 }); + + compare<4, 0, 1>({ 0, 1, 1, 1 }); + compare<4, 1, 1>({ 1, 0, 1, 1 }); + compare<4, 2, 1>({ 1, 1, 0, 1 }); + compare<4, 3, 1>({ 1, 1, 1, 0 }); + + compare<4, 0, 2>({ 0, 0, 1, 1 }); + compare<4, 1, 2>({ 0, 1, 0, 1 }); + compare<4, 2, 2>({ 0, 1, 1, 0 }); + compare<4, 3, 2>({ 1, 0, 0, 1 }); + compare<4, 4, 2>({ 1, 0, 1, 0 }); + compare<4, 5, 2>({ 1, 1, 0, 0 }); + + compare<4, 0, 3>({ 0, 0, 0, 1 }); + compare<4, 1, 3>({ 0, 0, 1, 0 }); + compare<4, 2, 3>({ 0, 1, 0, 0 }); + compare<4, 3, 3>({ 1, 0, 0, 0 }); + + compare<4, 0, 4>({ 0, 0, 0, 0 }); +} + + +#endif diff --git a/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.cpp b/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..130914e228890a2ce95532c9083aed0d07810239 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.cpp @@ -0,0 +1,3 @@ + +#include "GridTemplatesTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.cu b/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.cu new file mode 100644 index 0000000000000000000000000000000000000000..130914e228890a2ce95532c9083aed0d07810239 --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.cu @@ -0,0 +1,3 @@ + +#include "GridTemplatesTest.h" +#include "../../../main.h" diff --git a/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.h b/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.h new file mode 100644 index 0000000000000000000000000000000000000000..3b99c9a07f90fd5c7714d80b77a1db846c39839f --- /dev/null +++ b/src/UnitTests/Meshes/GridTests/Utils/GridTemplatesTest.h @@ -0,0 +1,98 @@ +#pragma once + +#ifdef HAVE_GTEST + +#include + +#include +#include "../CoordinateIterator.h" + +void testCombination(const int k, const int n, const int expectation) { + EXPECT_EQ(TNL::Meshes::Templates::combination(k, n), expectation) << k << " " << n; +} + +TEST(TemplatesTestSuite, CombinationsTest) { + testCombination(0, 1, 1); + testCombination(1, 1, 1); + + testCombination(0, 2, 1); + testCombination(1, 2, 2); + testCombination(2, 2, 1); + + testCombination(0, 3, 1); + testCombination(1, 3, 3); + testCombination(2, 3, 3); + testCombination(3, 3, 1); + + testCombination(0, 4, 1); + testCombination(1, 4, 4); + testCombination(2, 4, 6); + testCombination(3, 4, 4); + testCombination(4, 4, 1); +} + +void testCombinationSum(const int k, const int n, const int expectation) { + EXPECT_EQ(TNL::Meshes::Templates::firstKCombinationSum(k, n), expectation) << k << " " << n; +} + +TEST(TemplatesTestSuite, FirstKCombinationsTest) { + testCombinationSum(0, 1, 0); + testCombinationSum(1, 1, 1); + + testCombinationSum(0, 2, 0); + testCombinationSum(1, 2, 1); + testCombinationSum(2, 2, 3); + + testCombinationSum(0, 3, 0); + testCombinationSum(1, 3, 1); + testCombinationSum(2, 3, 4); + testCombinationSum(3, 3, 7); + + testCombinationSum(0, 4, 0); + testCombinationSum(1, 4, 1); + testCombinationSum(2, 4, 5); + testCombinationSum(3, 4, 11); + testCombinationSum(4, 4, 15); +} + +template +using Coordinate = TNL::Containers::StaticVector; + +template +void testIndexCollapse(const int base) { + SCOPED_TRACE("Coordinate size: " + TNL::convertToString(Size)); + SCOPED_TRACE("Base: " + TNL::convertToString(base)); + + const int halfBase = base >> 1; + Coordinate start, end; + + for (int i = 0; i < Size; i++) { + start[i] = -halfBase; + // Want to traverse + end[i] = halfBase + 1; + } + + CoordinateIterator iterator(start, end); + + int index = 0; + + do { + EXPECT_EQ(TNL::Meshes::Templates::makeCollapsedIndex(base, iterator.getCoordinate()), index) + << base << " " << index << " " << iterator.getCoordinate(); + index++; + } while (!iterator.next()); +} + +TEST(TemplatesTestSuite, IndexCollapseTest) { + testIndexCollapse<1>(3); + testIndexCollapse<2>(3); + testIndexCollapse<3>(3); + testIndexCollapse<4>(3); + + testIndexCollapse<1>(5); + testIndexCollapse<2>(5); + testIndexCollapse<3>(5); + testIndexCollapse<4>(5); +} + +#endif diff --git a/src/UnitTests/Meshes/VTIReaderTest.cpp b/src/UnitTests/Meshes/VTIReaderTest.cpp index b0c6847ba48997ddd98b62135b52cb66ce59cafc..6daf8b82f24a000979a0709058b31e53b7281959 100644 --- a/src/UnitTests/Meshes/VTIReaderTest.cpp +++ b/src/UnitTests/Meshes/VTIReaderTest.cpp @@ -1,3 +1,4 @@ + #ifdef HAVE_GTEST #include