...
 
Commits (3)
......@@ -122,7 +122,7 @@ if( DEFINED ENV{CI_JOB_NAME} OR ${CMAKE_GENERATOR} STREQUAL "Ninja" )
endif()
#####
# Check for MPI -- poznej podle vraperu compileru -- da se testovat preklad bez MPI
# Check for MPI
#
get_filename_component( CXX_COMPILER_NAME ${CMAKE_CXX_COMPILER} NAME )
if( ${CXX_COMPILER_NAME} STREQUAL "mpicxx" )
......@@ -267,6 +267,17 @@ if( JPEG_FOUND )
include_directories( ${JPEG_INCLUDE_DIRS} )
endif()
####
# Adaptive grid - temporary
#
if( ${WITH_ADAPTIVE_GRID} )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_ADAPTIVE_GRID" )
if( NOT ${ADAPTIVE_GRID_PATH} EQUAL "" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I ${ADAPTIVE_GRID_PATH}" )
endif()
endif()
####
# Test for GMP
#
......
......@@ -28,6 +28,9 @@ WITH_EXAMPLES="yes"
WITH_PYTHON="yes"
WITH_TOOLS="yes"
WITH_BENCHMARKS="yes"
# This is temporary
WITH_ADAPTIVE_GRID="no"
ADAPTIVE_GRID_PATH=""
WITH_TEMPLATE_INSTANTIATION="no"
INSTANTIATE_LONG_INT="no"
......@@ -65,6 +68,8 @@ do
--with-benchmarks=* ) WITH_BENCHMARKS="${option#*=}" ;;
--with-python=* ) WITH_PYTHON="${option#*=}" ;;
--with-templates-instantiation=* ) WITH_TEMPLATE_INSTANTIATION="${option#*=}" ;;
--with-adaptive-grid=* ) WITH_ADAPTIVE_GRID="${option#*=}" ;;
--adaptive-grid-path=* ) ADAPTIVE_GRID_PATH="${option#*=}" ;;
--instantiate-long-int=* ) INSTANTIATE_LONG_INT="${option#*=}" ;;
--instantiate-int=* ) INSTANTIATE_INT="${option#*=}" ;;
--instantiate-long-double=* ) INSTANTIATE_LONG_DOUBLE="${option#*=}" ;;
......@@ -101,6 +106,7 @@ if [[ ${HELP} == "yes" ]]; then
echo " --with-coverage=yes/no Enables code coverage reports for unit tests. 'no' by default (lcov is required)."
echo " --with-examples=yes/no Compile the 'examples' directory. 'yes' by default."
echo " --with-tools=yes/no Compile the 'src/Tools' directory. 'yes' by default."
echo " --with-benchmarks=yes/no Compile the 'src/Benchmarks' directory. 'yes' by default."
echo " --with-python=yes/no Compile the Python bindings. 'yes' by default."
echo " --with-templates-instantiation=yes/no Precompiles some TNL templates during the build. 'no' by default."
echo " --cmake=CMAKE Path to cmake. 'cmake' by default."
......@@ -173,6 +179,8 @@ cmake_command=(
-DWITH_EXAMPLES=${WITH_EXAMPLES}
-DWITH_TOOLS=${WITH_TOOLS}
-DWITH_BENCHMARKS=${WITH_BENCHMARKS}
-DWITH_ADAPTIVE_GRID=${WITH_ADAPTIVE_GRID}
-DADAPTIVE_GRID_PATH=${ADAPTIVE_GRID_PATH}
-DWITH_PYTHON=${WITH_PYTHON}
-DDCMTK_DIR=${DCMTK_DIR}
-DWITH_TEMPLATE_INSTANTIATION=${WITH_TEMPLATE_INSTANTIATION}
......
......@@ -346,6 +346,13 @@ class MpiCommunicator
throw Exceptions::MPISupportMissing();
#endif
}
static void wait( Request& request )
{
#ifdef HAVE_MPI
MPI_Wait( &request, MPI_STATUS_IGNORE );
#endif
}
static void WaitAll(Request *reqs, int length)
{
......
......@@ -89,6 +89,10 @@ class NoDistrCommunicator
return 1;
}
static void wait( Request& request )
{
}
static void WaitAll(Request *reqs, int length)
{
}
......
......@@ -178,6 +178,22 @@ class MeshFunction :
void synchronize( bool withPeriodicBoundaryConditions = false,
const Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >& mask =
Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >( nullptr ) );
template< typename CommunicatorType,
typename PeriodicBoundariesMaskType = MeshFunction< Mesh, MeshEntityDimension, bool > >
void startSynchronization( std::list< typename CommunicatorType::Request >& requests,
bool withPeriodicBoundaryConditions = false,
const Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >& mask =
Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >( nullptr ) );
template< typename CommunicatorType,
typename PeriodicBoundariesMaskType = MeshFunction< Mesh, MeshEntityDimension, bool > >
void finishSynchronization( std::list< typename CommunicatorType::Request >& requests,
bool withPeriodicBoundaryConditions = false,
const Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >& mask =
Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >( nullptr ) );
protected:
......
......@@ -555,6 +555,42 @@ synchronize( bool periodicBoundaries,
}
}
template< typename Mesh,
int MeshEntityDimension,
typename Real >
template< typename CommunicatorType,
typename PeriodicBoundariesMaskType >
void
MeshFunction< Mesh, MeshEntityDimension, Real >::
startSynchronization( std::list< typename CommunicatorType::Request >& requests,
bool periodicBoundaries,
const Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >& mask )
{
auto distrMesh = this->getMesh().getDistributedMesh();
if(distrMesh != NULL && distrMesh->isDistributed())
{
this->synchronizer.template startSynchronization<CommunicatorType>( *this, requests, periodicBoundaries, mask );
}
}
template< typename Mesh,
int MeshEntityDimension,
typename Real >
template< typename CommunicatorType,
typename PeriodicBoundariesMaskType >
void
MeshFunction< Mesh, MeshEntityDimension, Real >::
finishSynchronization( std::list< typename CommunicatorType::Request >& requests,
bool periodicBoundaries,
const Pointers::SharedPointer< PeriodicBoundariesMaskType, DeviceType >& mask )
{
auto distrMesh = this->getMesh().getDistributedMesh();
if(distrMesh != NULL && distrMesh->isDistributed())
{
this->synchronizer.template finishSynchronization<CommunicatorType>( *this, requests, periodicBoundaries, mask );
}
}
template< typename Mesh,
int MeshEntityDimension,
typename Real >
......@@ -579,3 +615,4 @@ operator << ( std::ostream& str, const MeshFunction< Mesh, MeshEntityDimension,
} // namespace Functions
} // namespace TNL
......@@ -20,6 +20,10 @@
#include <TNL/Meshes/Topologies/Hexahedron.h>
#include <TNL/Meshes/Topologies/Simplex.h>
#ifdef HAVE_ADAPTIVE_GRID
#include <TNL/Meshes/GridAdaptive.h>
#endif
namespace TNL {
namespace Meshes {
namespace BuildConfigTags {
......@@ -60,6 +64,17 @@ struct GridTag< ConfigTag, Grid< Dimension, Real, Device, Index > >
};
};
#ifdef HAVE_ADAPTIVE_GRID
template< typename ConfigTag, int Dimension, typename Real, typename Device, typename Index >
struct GridTag< ConfigTag, GridA< Dimension, Real, Device, Index > >
{
enum { enabled = GridDimensionTag< ConfigTag, Dimension >::enabled &&
GridRealTag< ConfigTag, Real >::enabled &&
GridDeviceTag< ConfigTag, Device >::enabled &&
GridIndexTag< ConfigTag, Index >::enabled
};
};
#endif
/****
* Configuration for unstructured meshes
......
/***************************************************************************
DistributedAdaptiveGrid.h - part common for all Dimensionensions
-------------------
begin : Apr 04, 2019
copyright : (C) 2019 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/* See Copyright Notice in tnl/Copyright */
#pragma once
#include <iostream>
#include <TNL/Meshes/Grid.h>
#include <TNL/Logger.h>
#include <TNL/Meshes/DistributedMeshes/Directions.h>
#include <TNL/Meshes/DistributedMeshes/DistributedMesh.h>
#ifdef HAVE_ADAPTIVE_GRID
#include <TNL/Meshes/GridAdaptive.h>
#endif
namespace TNL {
namespace Meshes {
namespace DistributedMeshes {
#ifdef HAVE_ADAPTIVE_GRID
template< int Dimension,
typename Real,
typename Device,
typename Index >
class DistributedMesh< GridA< Dimension, Real, Device, Index > >
{
public:
typedef Real RealType;
typedef Device DeviceType;
typedef Index IndexType;
typedef Grid< Dimension, Real, Device, IndexType > GridType;
typedef typename GridType::PointType PointType;
typedef Containers::StaticVector< Dimension, IndexType > CoordinatesType;
typedef Containers::StaticVector< Dimension, IndexType > SubdomainOverlapsType;
static constexpr int getMeshDimension() { return Dimension; };
static constexpr int getNeighborsCount() { return DirectionCount<Dimension>::get(); } //c++14 may use Directions::pow3(Dimension)-1
DistributedMesh();
~DistributedMesh();
static void configSetup( Config::ConfigDescription& config );
bool setup( const Config::ParameterContainer& parameters,
const String& prefix );
void setDomainDecomposition( const CoordinatesType& domainDecomposition );
const CoordinatesType& getDomainDecomposition() const;
template< typename CommunicatorType >
void setGlobalGrid( const GridType& globalGrid );
const GridType& getGlobalGrid() const;
void setOverlaps( const SubdomainOverlapsType& lower,
const SubdomainOverlapsType& upper);
void setupGrid( GridType& grid);
bool isDistributed() const;
bool isBoundarySubdomain() const;
// TODO: replace it with getLowerOverlap() and getUpperOverlap()
// It is still being used in cuts set-up
const CoordinatesType& getOverlap() const { return this->overlap;};
//currently used overlaps at this subdomain
const SubdomainOverlapsType& getLowerOverlap() const;
const SubdomainOverlapsType& getUpperOverlap() const;
//number of elements of local sub domain WITHOUT overlap
// TODO: getSubdomainDimensions
const CoordinatesType& getLocalSize() const;
// TODO: delete
//Dimensions of global grid
const CoordinatesType& getGlobalSize() const;
//coordinates of begin of local subdomain without overlaps in global grid
const CoordinatesType& getGlobalBegin() const;
//number of elements of local sub domain WITH overlap
// TODO: replace with localGrid
const CoordinatesType& getLocalGridSize() const;
//coordinates of begin of local subdomain without overlaps in local grid
const CoordinatesType& getLocalBegin() const;
const CoordinatesType& getSubdomainCoordinates() const;
const PointType& getLocalOrigin() const;
const PointType& getSpaceSteps() const;
//aka MPI-communcicator
void setCommunicationGroup(void * group);
void * getCommunicationGroup() const;
template< int EntityDimension >
IndexType getEntitiesCount() const;
template< typename Entity >
IndexType getEntitiesCount() const;
const int* getNeighbors() const;
const int* getPeriodicNeighbors() const;
template<typename CommunicatorType, typename DistributedGridType>
bool SetupByCut(DistributedGridType &inputDistributedGrid,
Containers::StaticVector<Dimension, int> savedDimensions,
Containers::StaticVector<DistributedGridType::getMeshDimension()-Dimension,int> reducedDimensions,
Containers::StaticVector<DistributedGridType::getMeshDimension()-Dimension,IndexType> fixedIndexs);
int getRankOfProcCoord(const CoordinatesType &nodeCoordinates) const;
String printProcessCoords() const;
String printProcessDistr() const;
void writeProlog( Logger& logger );
public:
bool isThereNeighbor(const CoordinatesType &direction) const;
void setupNeighbors();
void print( std::ostream& str ) const;
GridType globalGrid;
PointType localOrigin;
CoordinatesType localBegin;
CoordinatesType localSize;
CoordinatesType localGridSize;
CoordinatesType overlap;
//CoordinatesType globalDimensions;
CoordinatesType globalBegin;
PointType spaceSteps;
SubdomainOverlapsType lowerOverlap, upperOverlap, globalLowerOverlap, globalUpperOverlap;
CoordinatesType domainDecomposition;
CoordinatesType subdomainCoordinates;
// TODO: static arrays
int neighbors[ getNeighborsCount() ];
int periodicNeighbors[ getNeighborsCount() ];
IndexType Dimensions;
bool distributed;
int rank;
int nproc;
bool isSet;
//aka MPI-communicator
void * communicationGroup;
};
#endif
} // namespace DistributedMeshes
} // namespace Meshes
} // namespace TNL
#include <TNL/Meshes/DistributedMeshes/DistributedAdaptiveGrid.hpp>
/***************************************************************************
DistributedAdaptiveGrid.hpp - description
-------------------
begin : July 07, 2018
copyright : (C) 2018 by Tomas Oberhuber
email : tomas.oberhuber@fjfi.cvut.cz
***************************************************************************/
/* See Copyright Notice in tnl/Copyright */
#pragma once
#include <cstdlib>
#include <TNL/Communicators/MpiCommunicator.h>
#include <TNL/Meshes/DistributedMeshes/DistributedGrid.h>
#ifdef HAVE_ADAPTIVE_GRID
#include <TNL/Meshes/GridAdaptive.h>
#endif
namespace TNL {
namespace Meshes {
namespace DistributedMeshes {
template<int Dimension, typename Real, typename Device, typename Index >
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
DistributedMesh()
: domainDecomposition( 0 ), isSet( false ) {}
template<int Dimension, typename Real, typename Device, typename Index >
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
~DistributedMesh()
{
}
template<int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
configSetup( Config::ConfigDescription& config )
{
}
template<int Dimension, typename Real, typename Device, typename Index >
bool
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
setup( const Config::ParameterContainer& parameters,
const String& prefix )
{
return true;
}
template< int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
setDomainDecomposition( const CoordinatesType& domainDecomposition )
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getDomainDecomposition() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
template< typename CommunicatorType >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
setGlobalGrid( const GridType &globalGrid )
{
}
template< int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
setOverlaps( const SubdomainOverlapsType& lower,
const SubdomainOverlapsType& upper)
{
}
template< int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
setupGrid( GridType& grid)
{
};
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getSubdomainCoordinates() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::PointType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getLocalOrigin() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::PointType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getSpaceSteps() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
bool
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
isDistributed() const
{
};
template< int Dimension, typename Real, typename Device, typename Index >
bool
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
isBoundarySubdomain() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getLowerOverlap() const
{
};
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getUpperOverlap() const
{
};
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getLocalSize() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getGlobalSize() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::GridType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getGlobalGrid() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getGlobalBegin() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getLocalGridSize() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const typename DistributedMesh< GridA< Dimension, Real, Device, Index > >::CoordinatesType&
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getLocalBegin() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
template< int EntityDimension >
Index
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getEntitiesCount() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
template< typename Entity >
Index
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getEntitiesCount() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
setCommunicationGroup(void * group)
{
}
template< int Dimension, typename Real, typename Device, typename Index >
void *
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getCommunicationGroup() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
int
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getRankOfProcCoord(const CoordinatesType &nodeCoordinates) const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
bool
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
isThereNeighbor(const CoordinatesType &direction) const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
setupNeighbors()
{
}
template< int Dimension, typename Real, typename Device, typename Index >
const int*
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getNeighbors() const
{
TNL_ASSERT_TRUE(this->isSet,"DistributedGrid is not set, but used by getNeighbors");
return this->neighbors;
}
template< int Dimension, typename Real, typename Device, typename Index >
const int*
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
getPeriodicNeighbors() const
{
TNL_ASSERT_TRUE(this->isSet,"DistributedGrid is not set, but used by getNeighbors");
return this->periodicNeighbors;
}
template< int Dimension, typename Real, typename Device, typename Index >
template<typename CommunicatorType, typename DistributedGridType >
bool
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
SetupByCut(DistributedGridType &inputDistributedGrid,
Containers::StaticVector<Dimension, int> savedDimensions,
Containers::StaticVector<DistributedGridType::getMeshDimension()-Dimension,int> reducedDimensions,
Containers::StaticVector<DistributedGridType::getMeshDimension()-Dimension,IndexType> fixedIndexs)
{
return false;
}
template< int Dimension, typename Real, typename Device, typename Index >
String
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
printProcessCoords() const
{
};
template< int Dimension, typename Real, typename Device, typename Index >
String
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
printProcessDistr() const
{
}
template< int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
writeProlog( Logger& logger )
{
}
template< int Dimension, typename Real, typename Device, typename Index >
void
DistributedMesh< GridA< Dimension, Real, Device, Index > >::
print( std::ostream& str ) const
{
}
} //namespace DistributedMeshes
} // namespace Meshes
} // namespace TNL
/***************************************************************************
DistributedGrid_Base.h - part common for all Dimensionensions
DistributedGrid.h - part common for all Dimensionensions
-------------------
begin : July 07, 2018
copyright : (C) 2018 by Tomas Oberhuber
......
/***************************************************************************
DistributedGrid_Base.hpp - description
DistributedGrid.hpp - description
-------------------
begin : July 07, 2018
copyright : (C) 2018 by Tomas Oberhuber
......
......@@ -17,8 +17,8 @@ namespace Meshes {
namespace DistributedMeshes {
/*
* This variant cerate copy of MeshFunction but smaller, reduced to local entities, without overlap.
/****
* This variant create copy of MeshFunction but smaller, reduced to local entities, without overlap.
* It is slow and has high RAM consumption
*/
template< int Dimension,
......@@ -140,6 +140,41 @@ class DistributedGridIO<
};
#ifdef HAVE_ADAPTIVE_GRID
template< int Dimension,
int MeshEntityDimension,
typename MeshReal,
typename Device,
typename Index,
typename Real >
class DistributedGridIO<
Functions::MeshFunction< Meshes::GridA< Dimension, MeshReal, Device, Index >,
MeshEntityDimension,
Real >,
LocalCopy >
{
public:
using MeshType = Meshes::GridA< Dimension, Real, Device, Index >;
using MeshFunctionType = Functions::MeshFunction< MeshType, MeshEntityDimension, Real >;
using CoordinatesType = typename MeshFunctionType::MeshType::CoordinatesType;
using PointType = typename MeshFunctionType::MeshType::PointType;
using VectorType = typename MeshFunctionType::VectorType;
//typedef DistributedGrid< MeshType,MeshFunctionType::getMeshDimension()> DistributedGridType;
static bool save(const String& fileName, MeshFunctionType &meshFunction)
{
return false;
};
static bool load(const String& fileName,MeshFunctionType &meshFunction)
{
return false;
};
};
#endif
/*
* Save distributed data into single file without overlaps using MPIIO and MPI datatypes,
* EXPLOSIVE: works with only Grids and MPI
......@@ -524,6 +559,43 @@ class DistributedGridIO<
};
};
#ifdef HAVE_ADAPTIVE_GRID
template< int Dimension,
int MeshEntityDimension,
typename MeshReal,
typename Device,
typename Index,
typename Real >
class DistributedGridIO<
Functions::MeshFunction< Meshes::GridA< Dimension, MeshReal, Device, Index >,
MeshEntityDimension,
Real >,
MpiIO >
{
public:
using MeshType = Meshes::GridA< Dimension, MeshReal, Device, Index >;
using MeshFunctionType = Functions::MeshFunction< MeshType, MeshEntityDimension, Real >;
using CoordinatesType = typename MeshFunctionType::MeshType::CoordinatesType;
using PointType = typename MeshFunctionType::MeshType::PointType;
using VectorType = typename MeshFunctionType::VectorType;
//typedef DistributedGrid< MeshType,MeshFunctionType::getMeshDimension()> DistributedGridType;
static bool save(const String& fileName, MeshFunctionType &meshFunction)
{
TNL_ASSERT( false, std::cerr << "Not implemented." << std::endl );
return false;
};
static bool load(const String& fileName,MeshFunctionType &meshFunction)
{
TNL_ASSERT( false, std::cerr << "Not implemented." << std::endl );
return false;
};
};
#endif
} //namespace DistributedMeshes
} //namespace Meshes
} //namespace TNL
......@@ -10,12 +10,17 @@
#pragma once
#include <list>
#include <TNL/Meshes/Grid.h>
#include <TNL/Containers/Array.h>
#include <TNL/Meshes/DistributedMeshes/BufferEntitiesHelper.h>
#include <TNL/Meshes/DistributedMeshes/Directions.h>
#include <TNL/Communicators/MPIPrint.h>
#ifdef HAVE_ADAPTIVE_GRID
#include <TNL/Meshes/GridAdaptive.h>
#endif
namespace TNL {
namespace Functions{
template< typename Mesh,
......@@ -123,8 +128,85 @@ class DistributedMeshSynchronizer< Functions::MeshFunction< Grid< MeshDimension,
neighbors[ i ] == -1 )
swap( sendBegin[i], recieveBegin[i] );
}
}
}
template< typename CommunicatorType,
typename MeshFunctionType,
typename PeriodicBoundariesMaskPointer = Pointers::SharedPointer< MeshFunctionType > >
void startSynchronization( MeshFunctionType &meshFunction,
std::list< typename CommunicatorType::Request >& requests,
bool periodicBoundaries = false,
const PeriodicBoundariesMaskPointer& mask = PeriodicBoundariesMaskPointer( nullptr ) )
{
TNL_ASSERT_TRUE( isSet, "Synchronizer is not set, but used to synchronize" );
if( !distributedGrid->isDistributed() ) return;
const int *neighbors = distributedGrid->getNeighbors();
const int *periodicNeighbors = distributedGrid->getPeriodicNeighbors();
//fill send buffers
copyBuffers( meshFunction,
sendBuffers, sendBegin,sendDimensions,
true,
neighbors,
periodicBoundaries,
PeriodicBoundariesMaskPointer( nullptr ) ); // the mask is used only when receiving data );
//async send and receive
//requests.setSize( 2 * this->getNeighborCount() );
typename CommunicatorType::CommunicationGroup group;
group=*((typename CommunicatorType::CommunicationGroup *)(distributedGrid->getCommunicationGroup()));
int requestsCount( 0 );
//send everything, receive everything
for( int i=0; i<this->getNeighborCount(); i++ )
{
/*TNL_MPI_PRINT( "Sending data... " << i << " sizes -> "
<< sendSizes[ i ] << "sendDimensions -> " << sendDimensions[ i ]
<< " upperOverlap -> " << this->distributedGrid->getUpperOverlap() );*/
if( neighbors[ i ] != -1 )
{
//TNL_MPI_PRINT( "Sending data to node " << neighbors[ i ] );
requests.push_back( CommunicatorType::ISend( sendBuffers[ i ].getData(), sendSizes[ i ], neighbors[ i ], 0, group ) );
//TNL_MPI_PRINT( "Receiving data from node " << neighbors[ i ] );
requests.push_back( CommunicatorType::IRecv( recieveBuffers[ i ].getData(), sendSizes[ i ], neighbors[ i ], 0, group ) );
}
else if( periodicBoundaries && sendSizes[ i ] !=0 )
{
//TNL_MPI_PRINT( "Sending data to node " << periodicNeighbors[ i ] );
requests.push_back( CommunicatorType::ISend( sendBuffers[ i ].getData(), sendSizes[ i ], periodicNeighbors[ i ], 1, group ) );
//TNL_MPI_PRINT( "Receiving data to node " << periodicNeighbors[ i ] );
requests.push_back( CommunicatorType::IRecv( recieveBuffers[ i ].getData(), sendSizes[ i ], periodicNeighbors[ i ], 1, group ) );
}
}
}
template< typename CommunicatorType,
typename MeshFunctionType,
typename PeriodicBoundariesMaskPointer = Pointers::SharedPointer< MeshFunctionType > >
void finishSynchronization( MeshFunctionType &meshFunction,
std::list< typename CommunicatorType::Request >& requests,
bool periodicBoundaries = false,
const PeriodicBoundariesMaskPointer& mask = PeriodicBoundariesMaskPointer( nullptr ) )
{
//wait until send is done
//TNL_MPI_PRINT( "Waiting for data ..." )
for( auto& request : requests )
CommunicatorType::wait( request );
//copy data from receive buffers
//TNL_MPI_PRINT( "Copying data ..." )
const int *neighbors = distributedGrid->getNeighbors();
copyBuffers(meshFunction,
recieveBuffers,recieveBegin,sendDimensions ,
false,
neighbors,
periodicBoundaries,
mask );
}
template< typename CommunicatorType,
typename MeshFunctionType,
typename PeriodicBoundariesMaskPointer = Pointers::SharedPointer< MeshFunctionType > >
......@@ -154,7 +236,7 @@ class DistributedMeshSynchronizer< Functions::MeshFunction< Grid< MeshDimension,
group=*((typename CommunicatorType::CommunicationGroup *)(distributedGrid->getCommunicationGroup()));
int requestsCount( 0 );
//send everything, recieve everything
//send everything, receive everything
for( int i=0; i<this->getNeighborCount(); i++ )
{
/*TNL_MPI_PRINT( "Sending data... " << i << " sizes -> "
......@@ -234,6 +316,82 @@ class DistributedMeshSynchronizer< Functions::MeshFunction< Grid< MeshDimension,
bool isSet;
};
#ifdef HAVE_ADAPTIVE_GRID
template <typename RealType,
int EntityDimension,
int MeshDimension,
typename Index,
typename Device,
typename GridReal>
class DistributedMeshSynchronizer< Functions::MeshFunction< GridA< MeshDimension, GridReal, Device, Index >,EntityDimension, RealType>>
{
public:
static constexpr int getMeshDimension() { return MeshDimension; };
static constexpr int getNeighborCount() {return DirectionCount<MeshDimension>::get();};
typedef typename GridA< MeshDimension, GridReal, Device, Index >::Cell Cell;
// FIXME: clang does not like this (incomplete type error)
typedef typename GridA< MeshDimension, GridReal, Device, Index >::DistributedMeshType DistributedGridType;
typedef typename DistributedGridType::CoordinatesType CoordinatesType;
using SubdomainOverlapsType = typename DistributedGridType::SubdomainOverlapsType;
enum PeriodicBoundariesCopyDirection
{
BoundaryToOverlap,
OverlapToBoundary
};
DistributedMeshSynchronizer()
{
};
DistributedMeshSynchronizer( DistributedGridType *distributedGrid )
{
};
void setPeriodicBoundariesCopyDirection( const PeriodicBoundariesCopyDirection dir )
{
}
void setDistributedGrid( DistributedGridType *distributedGrid )
{
}
template< typename CommunicatorType,
typename MeshFunctionType,
typename PeriodicBoundariesMaskPointer = Pointers::SharedPointer< MeshFunctionType > >
void startSynchronization( MeshFunctionType &meshFunction,
std::list< typename CommunicatorType::Request >& requests,
bool periodicBoundaries = false,
const PeriodicBoundariesMaskPointer& mask = PeriodicBoundariesMaskPointer( nullptr ) )
{
}
template< typename CommunicatorType,
typename MeshFunctionType,
typename PeriodicBoundariesMaskPointer = Pointers::SharedPointer< MeshFunctionType > >
void finishSynchronization( MeshFunctionType &meshFunction,
std::list< typename CommunicatorType::Request >& requests,
bool periodicBoundaries = false,
const PeriodicBoundariesMaskPointer& mask = PeriodicBoundariesMaskPointer( nullptr ) )
{
}
template< typename CommunicatorType,
typename MeshFunctionType,
typename PeriodicBoundariesMaskPointer = Pointers::SharedPointer< MeshFunctionType > >
void synchronize( MeshFunctionType &meshFunction,
bool periodicBoundaries = false,
const PeriodicBoundariesMaskPointer& mask = PeriodicBoundariesMaskPointer( nullptr ) )
{
}
};
#endif
} // namespace DistributedMeshes
} // namespace Meshes
......
......@@ -34,3 +34,4 @@ public:
} // namespace TNL
#include <TNL/Meshes/DistributedMeshes/DistributedGrid.h>
#include <TNL/Meshes/DistributedMeshes/DistributedAdaptiveGrid.h>
......@@ -53,6 +53,18 @@ public:
else if( meshDimension == 3 )
cellShape = EntityShape::Hexahedron;
}
else if( meshType == "Meshes::AdaptiveGrid" ) {
meshDimension = worldDimension = std::atoi( parsedMeshType[ 1 ].getString() );
realType = parsedMeshType[ 2 ];
globalIndexType = localIndexType = idType = parsedMeshType[ 4 ];
// populate entity types (not necessary for GridTypeResolver, but while we're at it...)
if( meshDimension == 1 )
cellShape = EntityShape::Line;
else if( meshDimension == 2 )
cellShape = EntityShape::Quad;
else if( meshDimension == 3 )
cellShape = EntityShape::Hexahedron;
}
else if( meshType == "Meshes::Mesh" ) {
const std::vector< String > parsedMeshConfig = parseObjectType( parsedMeshType[ 1 ] );
if( ! parsedMeshConfig.size() ) {
......@@ -153,7 +165,17 @@ public:
{
return idType;
}
void setAdaptivity( bool adaptive )
{
this->adaptivity = adaptive;
}
bool getAdaptivity() const
{
return this->adaptivity;
}
protected:
String fileName;
String meshType;
......@@ -164,6 +186,7 @@ protected:
String globalIndexType;
String localIndexType;
String idType;
bool adaptivity = false;
void reset()
{
......
......@@ -16,6 +16,11 @@
#include <TNL/Meshes/Grid.h>
#include <TNL/Meshes/TypeResolver/GridTypeResolver.h>
#ifdef HAVE_ADAPTIVE_GRID
#include <TNL/Meshes/GridAdaptive.h>
#endif
namespace TNL {
namespace Meshes {
......@@ -162,8 +167,21 @@ GridTypeResolver< Reader, ConfigTag, Device, ProblemSetter, ProblemSetterArgs...
resolveGridType( const Reader& reader,
ProblemSetterArgs&&... problemSetterArgs )
{
using GridType = Meshes::Grid< MeshDimension, Real, Device, Index >;
return resolveTerminate< GridType >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
if( reader.getAdaptivity() )
{
#ifdef HAVE_ADAPTIVE_GRID
using GridType = Meshes::GridA< MeshDimension, Real, Device, Index >;
return resolveTerminate< GridType >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
#else
std::cerr << "Adaptive grid is not supported." << std::endl;
return false;
#endif
}
else
{
using GridType = Meshes::Grid< MeshDimension, Real, Device, Index >;
return resolveTerminate< GridType >( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
}
}
template< typename Reader,
......
......@@ -20,6 +20,10 @@
#include <TNL/Meshes/TypeResolver/GridTypeResolver.h>
#include <TNL/Meshes/TypeResolver/MeshTypeResolver.h>
#ifdef HAVE_ADAPTIVE_GRID
#include <TNL/Meshes/GridAdaptive.h>
#endif
// TODO: implement this in TNL::String
inline bool ends_with( const std::string& value, const std::string& ending )
{
......@@ -66,6 +70,14 @@ bool resolveMeshType( const String& fileName_,
if( reader.getMeshType() == "Meshes::Grid" )
return GridTypeResolver< decltype(reader), ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
run( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
#ifdef HAVE_ADAPTIVE_GRID
else if( reader.getMeshType() == "Meshes::AdaptiveGrid" )
{
reader.setAdaptivity( true );
return GridTypeResolver< decltype(reader), ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
run( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
}
#endif
else if( reader.getMeshType() == "Meshes::Mesh" )
return MeshTypeResolver< decltype(reader), ConfigTag, Device, ProblemSetter, ProblemSetterArgs... >::
run( reader, std::forward<ProblemSetterArgs>(problemSetterArgs)... );
......@@ -155,6 +167,53 @@ loadMesh( const String& fileName,
return true;
}
#ifdef HAVE_ADAPTIVE_GRID
// Specializations for adaptive grid
template< typename CommunicatorType,
int Dimension,
typename Real,
typename Device,
typename Index >
bool
loadMesh( const String& fileName,
GridA< Dimension, Real, Device, Index >& mesh,
DistributedMeshes::DistributedMesh< GridA< Dimension, Real, Device, Index > > &distributedMesh )
{
if( CommunicatorType::isDistributed() )
{
/*std::cout << "Loading a global mesh from the file " << fileName << "...";
GridA< Dimension, Real, Device, Index > globalGrid;
if( ! globalGrid.load( fileName ) )
{
std::cerr << std::endl;
std::cerr << "I am not able to load the global mesh from the file " << fileName << "." << std::endl;
return false;
}
std::cout << " [ OK ] " << std::endl;
typename Meshes::DistributedMeshes::DistributedMesh<GridA< Dimension, Real, Device, Index >>::SubdomainOverlapsType overlap;
distributedMesh.template setGlobalGrid< CommunicatorType >( globalGrid );
distributedMesh.setupGrid(mesh);
return true;*/
}
else
{
std::cout << "Loading a mesh from the file " << fileName << "...";
if( ! mesh.load( fileName ) )
{
std::cerr << std::endl;
std::cerr << "I am not able to load the mesh from the file " << fileName << "." << std::endl;
std::cerr << " You may create it with tools like tnl-grid-setup or tnl-mesh-convert." << std::endl;
return false;
}
std::cout << " [ OK ] " << std::endl;
return true;
}
}
#endif
template< typename Problem,
typename MeshConfig,
typename Device >
......@@ -270,5 +329,33 @@ decomposeMesh( const Config::ParameterContainer& parameters,
return true;
}
#ifdef HAVE_ADAPTIVE_GRID
template< typename Problem,
int Dimension,
typename Real,
typename Device,
typename Index >
bool
decomposeMesh( const Config::ParameterContainer& parameters,
const String& prefix,
GridA< Dimension, Real, Device, Index >& mesh,
DistributedMeshes::DistributedMesh< GridA< Dimension, Real, Device, Index > > &distributedMesh,
Problem& problem )
{
using GridType = GridA< Dimension, Real, Device, Index >;
using DistributedGridType = DistributedMeshes::DistributedMesh< GridType >;
using SubdomainOverlapsType = typename DistributedGridType::SubdomainOverlapsType;
using CommunicatorType = typename Problem::CommunicatorType;
if( CommunicatorType::isDistributed() )
{
return false;
}
else
return true;
}
#endif
} // namespace Meshes
} // namespace TNL
......@@ -56,6 +56,42 @@ protected:
Real timeStepOrder = 0.0;
};
#ifdef HAVE_ADAPTIVE_GRID
template< int Dimension,
typename MeshReal,
typename Device,
typename MeshIndex,
typename Real >
class MeshDependentTimeSteps< TNL::Meshes::GridA< Dimension, MeshReal, Device, MeshIndex >, Real >
{
public:
using MeshType = TNL::Meshes::GridA< Dimension, MeshReal, Device, MeshIndex >;
bool setTimeStepOrder( const Real& timeStepOrder )
{
if( timeStepOrder < 0 ) {
std::cerr << "The time step order for PDESolver must be zero or positive value." << std::endl;
return false;
}
this->timeStepOrder = timeStepOrder;
return true;
}
const Real& getTimeStepOrder() const
{
return timeStepOrder;
}
Real getRefinedTimeStep( const MeshType& mesh, const Real& timeStep )
{
return timeStep * std::pow( mesh.getSmallestSpaceStep(), this->timeStepOrder );
}
protected:
Real timeStepOrder = 0.0;
};
#endif
template< typename MeshConfig,
typename Device,
typename Real >
......
......@@ -37,6 +37,7 @@ void configSetup( Config::ConfigDescription& config )
config.addEntry < int > ( "size-y", "Number of elements along the y axis." );
config.addEntry < int > ( "size-z", "Number of elements along the z axis." );
config.addEntry < bool > ( "equal-space-steps", "All space steps will be equivalent.", false );
config.addEntry < bool > ( "adaptive-grid", "Create adaptive grid.", false );
}
int main( int argc, char* argv[] )
......
......@@ -8,12 +8,14 @@
/* See Copyright Notice in tnl/Copyright */
#ifndef TNL_GRID_SETUP_H_
#define TNL_GRID_SETUP_H_
#pragma once
#include <TNL/Config/ParameterContainer.h>
#include <TNL/Meshes/Grid.h>
#ifdef HAVE_ADAPTIVE_GRID
#include <TNL/Meshes/GridAdaptive.h>
#endif
using namespace TNL;
template< typename RealType, typename IndexType >
......@@ -50,30 +52,67 @@ bool setupGrid( const Config::ParameterContainer& parameters )
RealType proportionsY = parameters.getParameter< double >( "proportions-y" );
IndexType sizeX = parameters.getParameter< int >( "size-x" );
IndexType sizeY = parameters.getParameter< int >( "size-y" );
typedef Meshes::Grid< 2, RealType, Devices::Host, IndexType > GridType;
typedef typename GridType::PointType PointType;
typedef typename GridType::CoordinatesType CoordinatesType;
GridType grid;
grid.setDomain( PointType( originX, originY ), PointType( proportionsX, proportionsY ) );
grid.setDimensions( CoordinatesType( sizeX, sizeY ) );
if( parameters.getParameter< bool >( "equal-space-steps" ) )
if( parameters.getParameter< bool >( "adaptive-grid" ) )
{
if( grid.getSpaceSteps().x() != grid.getSpaceSteps().y() )
#ifdef HAVE_ADAPTIVE_GRID
typedef Meshes::GridA< 2, RealType, Devices::Host, IndexType > AdaptiveGridType;
typedef typename AdaptiveGridType::PointType PointType;
typedef typename AdaptiveGridType::CoordinatesType CoordinatesType;
AdaptiveGridType grid;
grid.setDomain( PointType( originX, originY ), PointType( proportionsX, proportionsY ) );
grid.setDimensions( CoordinatesType( sizeX, sizeY ) );
if( parameters.getParameter< bool >( "equal-space-steps" ) )
{
double h = min( grid.getSpaceSteps().x(), grid.getSpaceSteps().y() );
grid.setSpaceSteps( PointType( h, h ) );
std::cout << "Adjusting grid space steps to " << grid.getSpaceSteps()
<< " and grid proportions to " << grid.getProportions() << "." << std::endl;
if( grid.getSpaceSteps().x() != grid.getSpaceSteps().y() )
{
double h = min( grid.getSpaceSteps().x(), grid.getSpaceSteps().y() );
grid.setSpaceSteps( PointType( h, h ) );
std::cout << "Adjusting grid space steps to " << grid.getSpaceSteps()
<< " and grid proportions to " << grid.getProportions() << "." << std::endl;
}
}
}
std::cout << "Setting dimensions to ... " << grid.getDimensions() << std::endl;
std::cout << "Writing the grid to the file " << outputFile << " .... ";
std::cout << "Setting dimensions to ... " << grid.getDimensions() << std::endl;
std::cout << "Writing the grid to the file " << outputFile << " .... ";
if( ! grid.save( outputFile ) )
if( ! grid.save( outputFile ) )
{
std::cerr << "[ FAILED ] " << std::endl;
return false;
}
#else
std::cerr << "Adaptive grid is not supported." << std::endl;
#endif
}
else
{
std::cerr << "[ FAILED ] " << std::endl;
return false;
typedef Meshes::Grid< 2, RealType, Devices::Host, IndexType > GridType;
typedef typename GridType::PointType PointType;
typedef typename GridType::CoordinatesType CoordinatesType;
GridType grid;
grid.setDomain( PointType( originX, originY ), PointType( proportionsX, proportionsY ) );
grid.setDimensions( CoordinatesType( sizeX, sizeY ) );
if( parameters.getParameter< bool >( "equal-space-steps" ) )
{
if( grid.getSpaceSteps().x() != grid.getSpaceSteps().y() )
{
double h = min( grid.getSpaceSteps().x(), grid.getSpaceSteps().y() );
grid.setSpaceSteps( PointType( h, h ) );
std::cout << "Adjusting grid space steps to " << grid.getSpaceSteps()
<< " and grid proportions to " << grid.getProportions() << "." << std::endl;
}
}
std::cout << "Setting dimensions to ... " << grid.getDimensions() << std::endl;
std::cout << "Writing the grid to the file " << outputFile << " .... ";
if( ! grid.save( outputFile ) )
{
std::cerr << "[ FAILED ] " << std::endl;
return false;
}
}
}
if( dimensions == 3 )
......@@ -144,5 +183,3 @@ bool resolveRealType( const Config::ParameterContainer& parameters )
std::cerr << "The real type '" << realType << "' is not supported. " << std::endl;
return false;
}
#endif /* TNL_GRID_SETUP_H_ */