Commit ccd42739 authored by Jakub Klinkovský's avatar Jakub Klinkovský

Merge branch 'hamilton-jacobi-rebase' into 'develop'

Hamilton jacobi rebase

See merge request !43
parents 552e90c4 e162a57a
......@@ -36,6 +36,9 @@ class DirectEikonalSolverConfig
{
config.addDelimiter( "Direct eikonal equation solver settings:" );
config.addRequiredEntry< String >( "input-file", "Input file." );
config.addEntry< String >( "distributed-grid-io-type", "Choose Distributed Grid IO Type", "MpiIO");
config.addEntryEnum< String >( "LocalCopy" );
config.addEntryEnum< String >( "MpiIO" );
};
};
......
#!/bin/bash
device="host"
dimensions="2D 3D"
#dimensions="3D"
#dimensions="2D 3D"
dimensions="2D"
sizes1D="16 32 64 128 256 512 1024 2048 4096"
#sizes1D="256"
sizes2D="16 32 64 128 256 512 1024"
#sizes2D="8"
sizes3D="16 32 64 128 256"
sizes2D="16 32 64 128 256 512 1024 2048 4096"
#sizes2D="16"
sizes3D="8 16 32 64 128 256"
#sizes3D="128 256"
testFunctions="paraboloid"
#testFunctions="sin-wave-sdf"
#testFunctions="sin-bumps-sdf"
snapshotPeriod=0.1
finalTime=1.5
solverName="tnl-direct-eikonal-solver"
#solverName="gdb --args tnl-direct-eikonal-solver-dbg --catch-exceptions no"
#
realType="double"
#mpiRun="mpirun -np 4 -oversubscribe "
mpiRun=""
## CAREFULL: If you set LocalCopy of MPI, you have to start with mpiRun even tnl-init
## This isnt problem with MpiIO.
## CAREFULL: For smoothly calculated error, you have to choose the right output function which
## is for both MpiIO, LocalCopy different.
solverName=${mpiRun}"tnl-direct-eikonal-solver"
#solverName="gdb --args "${mpiRun}"tnl-direct-eikonal-solver-dbg --catch-exceptions no --mpi-gdb-debug false"
#scale=2.0
#finalSdf="aux-0.tnl aux-1.tnl"
finalSdf="aux-final.tnl"
setupTestFunction()
{
......@@ -22,16 +36,17 @@ setupTestFunction()
# then
origin=-1.0
proportions=2.0
# origin=-1.0
# proportions=2.0
amplitude=1.0
waveLength=0.2
waveLengthX=0.2
waveLengthY=0.2
waveLengthZ=0.2
wavesNumber=3.0
wavesNumberX=0.5
wavesNumberY=2.0
waveLength=0.4
waveLengthX=0.5
waveLengthY=0.5
waveLengthZ=0.5
wavesNumber=1.25
wavesNumberX=0.5 wavesNumberY=2.0
wavesNumberZ=3.0
phase=0.1
phase=-1.5
phaseX=0.0
phaseY=0.0
phaseZ=0.0
......@@ -44,6 +59,7 @@ setupGrid()
{
dimensions=$1
gridSize=$2
#scale=$3
tnl-grid-setup --dimensions ${dimensions} \
--origin-x ${origin} \
--origin-y ${origin} \
......@@ -53,13 +69,16 @@ setupGrid()
--proportions-z ${proportions} \
--size-x ${gridSize} \
--size-y ${gridSize} \
--real-type ${realType} \
--size-z ${gridSize}
#$((2*${gridSize}))
}
setInitialCondition()
{
testFunction=$1
tnl-init --test-function ${testFunction} \
--real-type ${realType} \
--output-file initial-u.tnl \
--amplitude ${amplitude} \
--wave-length ${waveLength} \
......@@ -78,6 +97,7 @@ setInitialCondition()
--radius ${radius}
tnl-init --test-function ${testFunction}-sdf \
--real-type ${realType} \
--output-file exact-u.tnl \
--amplitude ${amplitude} \
--wave-length ${waveLength} \
......@@ -89,11 +109,11 @@ setInitialCondition()
--waves-number-y ${wavesNumberY} \
--waves-number-z ${wavesNumberZ} \
--phase ${phase} \
--phase-x ${phaseX} \
--phase-y ${phaseY} \
--phase-x ${phaseZ} \
--phase-y ${phaseZ} \
--phase-z ${phaseZ} \
--sigma ${sigma} \
--radius ${radius}
--radius ${radius} \
}
......@@ -111,17 +131,22 @@ solve()
--min-iterations 20 \
--convergence-residue 1.0e-12 \
--snapshot-period ${snapshotPeriod} \
--real-type ${realType} \
--final-time ${finalTime}
}
computeError()
{
for sweep in ${finalSdf}
do
tnl-diff --mesh mesh.tnl \
--input-files aux-final.tnl exact-u.tnl \
--input-files exact-u.tnl u-00000.tnl \
--mode sequence \
--snapshot-period ${snapshotPeriod} \
--output-file errors.txt \
--write-difference yes
#aux-final.tnl \
done
}
runTest()
......
/*
* File: tnlDirectEikonalMethodBase1D_impl.h
* Author: Fencl
*
* Created on March 15, 2019
*/
#pragma once
template< typename Real,
typename Device,
typename Index >
void
tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > >::
initInterface( const MeshFunctionPointer& _input,
MeshFunctionPointer& _output,
InterfaceMapPointer& _interfaceMap )
{
if( std::is_same< Device, Devices::Cuda >::value )
{
#ifdef HAVE_CUDA
const MeshType& mesh = _input->getMesh();
const int cudaBlockSize( 16 );
int numBlocksX = Devices::Cuda::getNumberOfBlocks( mesh.getDimensions().x(), cudaBlockSize );
dim3 blockSize( cudaBlockSize );
dim3 gridSize( numBlocksX );
Devices::Cuda::synchronizeDevice();
CudaInitCaller<<< gridSize, blockSize >>>( _input.template getData< Device >(),
_output.template modifyData< Device >(),
_interfaceMap.template modifyData< Device >() );
cudaDeviceSynchronize();
TNL_CHECK_CUDA_DEVICE;
#endif
}
if( std::is_same< Device, Devices::Host >::value )
{
const MeshType& mesh = _input->getMesh();
typedef typename MeshType::Cell Cell;
const MeshFunctionType& input = _input.getData();
MeshFunctionType& output = _output.modifyData();
InterfaceMapType& interfaceMap = _interfaceMap.modifyData();
Cell cell( mesh );
for( cell.getCoordinates().x() = 0;
cell.getCoordinates().x() < mesh.getDimensions().x();
cell.getCoordinates().x() ++ )
{
cell.refresh();
output[ cell.getIndex() ] =
input( cell ) >= 0 ? std::numeric_limits< RealType >::max() :
-std::numeric_limits< RealType >::max();
interfaceMap[ cell.getIndex() ] = false;
}
const RealType& h = mesh.getSpaceSteps().x();
for( cell.getCoordinates().x() = 0;
cell.getCoordinates().x() < mesh.getDimensions().x() - 1;
cell.getCoordinates().x() ++ )
{
cell.refresh();
const RealType& c = input( cell );
if( ! cell.isBoundaryEntity() )
{
const auto& neighbors = cell.getNeighborEntities();
Real pom = 0;
//const IndexType& c = cell.getIndex();
const IndexType e = neighbors.template getEntityIndex< 1 >();
if( c * input[ e ] <= 0 )
{
pom = TNL::sign( c )*( h * c )/( c - input[ e ]);
if( TNL::abs( output[ cell.getIndex() ] ) > TNL::abs( pom ) )
output[ cell.getIndex() ] = pom;
pom = pom - TNL::sign( c )*h; //output[ e ] = (hx * c)/( c - input[ e ]) - hx;
if( TNL::abs( output[ e ] ) > TNL::abs( pom ) )
output[ e ] = pom;
interfaceMap[ cell.getIndex() ] = true;
interfaceMap[ e ] = true;
}
}
}
}
}
template< typename Real,
typename Device,
typename Index >
template< typename MeshEntity >
void
tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > >::
updateCell( MeshFunctionType& u,
const MeshEntity& cell,
const RealType v )
{
const auto& neighborEntities = cell.template getNeighborEntities< 1 >();
const MeshType& mesh = cell.getMesh();
const RealType& h = mesh.getSpaceSteps().x();
const RealType value = u( cell );
RealType a, tmp = std::numeric_limits< RealType >::max();
if( cell.getCoordinates().x() == 0 )
a = u[ neighborEntities.template getEntityIndex< 1 >() ];
else if( cell.getCoordinates().x() == mesh.getDimensions().x() - 1 )
a = u[ neighborEntities.template getEntityIndex< -1 >() ];
else
{
a = TNL::argAbsMin( u[ neighborEntities.template getEntityIndex< -1 >() ],
u[ neighborEntities.template getEntityIndex< 1 >() ] );
}
if( fabs( a ) == std::numeric_limits< RealType >::max() )
return;
tmp = a + TNL::sign( value ) * h/v;
u[ cell.getIndex() ] = argAbsMin( value, tmp );
}
template< typename Real,
typename Device,
typename Index >
__cuda_callable__
bool
tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > >::
updateCell( volatile Real sArray[18], int thri, const Real h, const Real v )
{
const RealType value = sArray[ thri ];
RealType a, tmp = std::numeric_limits< RealType >::max();
a = TNL::argAbsMin( sArray[ thri+1 ],
sArray[ thri-1 ] );
if( fabs( a ) == std::numeric_limits< RealType >::max() )
return false;
tmp = a + TNL::sign( value ) * h/v;
sArray[ thri ] = argAbsMin( value, tmp );
tmp = value - sArray[ thri ];
if ( fabs( tmp ) > 0.001*h )
return true;
else
return false;
}
#ifdef HAVE_CUDA
template < typename Real, typename Device, typename Index >
__global__ void CudaInitCaller( const Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& input,
Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index > >& output,
Functions::MeshFunction< Meshes::Grid< 1, Real, Device, Index >, 1, bool >& interfaceMap )
{
int i = threadIdx.x + blockDim.x*blockIdx.x;
const Meshes::Grid< 1, Real, Device, Index >& mesh = input.template getMesh< Devices::Cuda >();
if( i < mesh.getDimensions().x() )
{
typedef typename Meshes::Grid< 1, Real, Device, Index >::Cell Cell;
Cell cell( mesh );
cell.getCoordinates().x() = i;
cell.refresh();
const Index cind = cell.getIndex();
output[ cind ] =
input( cell ) >= 0 ? std::numeric_limits< Real >::max() :
- std::numeric_limits< Real >::max();
interfaceMap[ cind ] = false;
const Real& h = mesh.getSpaceSteps().x();
cell.refresh();
const Real& c = input( cell );
if( ! cell.isBoundaryEntity() )
{
auto neighbors = cell.getNeighborEntities();
Real pom = 0;
const Index e = neighbors.template getEntityIndex< 1 >();
const Index w = neighbors.template getEntityIndex< -1 >();
if( c * input[ e ] <= 0 )
{
pom = TNL::sign( c )*( h * c )/( c - input[ e ]);
if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) )
output[ cind ] = pom;
interfaceMap[ cind ] = true;
}
if( c * input[ w ] <= 0 )
{
pom = TNL::sign( c )*( h * c )/( c - input[ w ]);
if( TNL::abs( output[ cind ] ) > TNL::abs( pom ) )
output[ cind ] = pom;
interfaceMap[ cind ] = true;
}
}
}
}
#endif
......@@ -72,6 +72,8 @@ class tnlDirectEikonalProblem
bool setInitialCondition( const Config::ParameterContainer& parameters,
DofVectorPointer& dofs );
bool makeSnapshot( );
bool solve( DofVectorPointer& dosf );
......
......@@ -12,6 +12,9 @@
*/
#pragma once
#include <TNL/FileName.h>
#include "tnlDirectEikonalProblem.h"
template< typename Mesh,
typename Communicator,
......@@ -76,6 +79,11 @@ tnlDirectEikonalProblem< Mesh, Communicator, Anisotropy, Real, Index >::
setup( const Config::ParameterContainer& parameters,
const String& prefix )
{
String param=parameters.getParameter< String >( "distributed-grid-io-type" );
if(param=="MpiIO")
distributedIOType=Meshes::DistributedMeshes::MpiIO;
if(param=="LocalCopy")
distributedIOType=Meshes::DistributedMeshes::LocalCopy;
return true;
}
......@@ -116,15 +124,14 @@ setInitialCondition( const Config::ParameterContainer& parameters,
this->bindDofs( dofs );
String inputFile = parameters.getParameter< String >( "input-file" );
this->initialData->setMesh( this->getMesh() );
std::cout<<"setInitialCondition" <<std::endl;
if(CommunicatorType::isDistributed())
if( CommunicatorType::isDistributed() )
{
std::cout<<"Nodes Distribution: " << u->getMesh().getDistributedMesh()->printProcessDistr() << std::endl;
std::cout<<"Nodes Distribution: " << initialData->getMesh().getDistributedMesh()->printProcessDistr() << std::endl;
if(distributedIOType==Meshes::DistributedMeshes::MpiIO)
Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType,Meshes::DistributedMeshes::MpiIO> ::load(inputFile, *u );
Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType,Meshes::DistributedMeshes::MpiIO> ::load(inputFile, *initialData );
if(distributedIOType==Meshes::DistributedMeshes::LocalCopy)
Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType,Meshes::DistributedMeshes::LocalCopy> ::load(inputFile, *u );
u->template synchronize<CommunicatorType>();
Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType,Meshes::DistributedMeshes::LocalCopy> ::load(inputFile, *initialData );
initialData->template synchronize<CommunicatorType>();
}
else
{
......@@ -141,6 +148,35 @@ setInitialCondition( const Config::ParameterContainer& parameters,
return true;
}
template< typename Mesh,
typename Communicator,
typename Anisotropy,
typename Real,
typename Index >
bool
tnlDirectEikonalProblem< Mesh, Communicator, Anisotropy, Real, Index >::
makeSnapshot( )
{
std::cout << std::endl << "Writing output." << std::endl;
//this->bindDofs( dofs );
FileName fileName;
fileName.setFileNameBase( "u-" );
fileName.setExtension( "tnl" );
if(CommunicatorType::isDistributed())
{
if(distributedIOType==Meshes::DistributedMeshes::MpiIO)
Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType,Meshes::DistributedMeshes::MpiIO> ::save(fileName.getFileName(), *u );
if(distributedIOType==Meshes::DistributedMeshes::LocalCopy)
Meshes::DistributedMeshes::DistributedGridIO<MeshFunctionType,Meshes::DistributedMeshes::LocalCopy> ::save(fileName.getFileName(), *u );
}
else
this->u->save( fileName.getFileName() );
return true;
}
template< typename Mesh,
typename Communicator,
......@@ -151,7 +187,9 @@ bool
tnlDirectEikonalProblem< Mesh, Communicator, Anisotropy, Real, Index >::
solve( DofVectorPointer& dofs )
{
FastSweepingMethod< MeshType, AnisotropyType > fsm;
fsm.solve( this->getMesh(), anisotropy, initialData );
FastSweepingMethod< MeshType, Communicator,AnisotropyType > fsm;
fsm.solve( this->getMesh(), u, anisotropy, initialData );
makeSnapshot();
return true;
}
......@@ -10,13 +10,14 @@
#pragma once
#include <TNL/Meshes/Grid.h>
#include <TNL/Functions/Analytic/Constant.h>
#include <TNL/Pointers/SharedPointer.h>
//#include <TNL/Meshes/Grid.h>
//#include <TNL/Functions/Analytic/Constant.h>
//#include <TNL/Pointers/SharedPointer.h>
#include "tnlDirectEikonalMethodsBase.h"
template< typename Mesh,
typename Communicator,
typename Anisotropy = Functions::Analytic::Constant< Mesh::getMeshDimension(), typename Mesh::RealType > >
class FastSweepingMethod
{
......@@ -25,8 +26,9 @@ class FastSweepingMethod
template< typename Real,
typename Device,
typename Index,
typename Communicator,
typename Anisotropy >
class FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >
class FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Communicator, Anisotropy >
: public tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > >
{
//static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." );
......@@ -56,6 +58,7 @@ class FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >
void setMaxIterations( const IndexType& maxIterations );
void solve( const MeshPointer& mesh,
MeshFunctionPointer& Aux,
const AnisotropyPointer& anisotropy,
MeshFunctionPointer& u );
......@@ -68,8 +71,9 @@ class FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >
template< typename Real,
typename Device,
typename Index,
typename Communicator,
typename Anisotropy >
class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy >
class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Communicator, Anisotropy >
: public tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > >
{
//static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." );
......@@ -82,8 +86,12 @@ class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy >
typedef Index IndexType;
typedef Anisotropy AnisotropyType;
typedef tnlDirectEikonalMethodsBase< Meshes::Grid< 2, Real, Device, Index > > BaseType;
typedef Communicator CommunicatorType;
typedef Containers::StaticVector< 2, Index > StaticVector;
using MeshPointer = Pointers::SharedPointer< MeshType >;
using AnisotropyPointer = Pointers::SharedPointer< AnisotropyType, DeviceType >;
using MPI = Communicators::MpiCommunicator;
using typename BaseType::InterfaceMapType;
using typename BaseType::MeshFunctionType;
......@@ -98,19 +106,30 @@ class FastSweepingMethod< Meshes::Grid< 2, Real, Device, Index >, Anisotropy >
void setMaxIterations( const IndexType& maxIterations );
void solve( const MeshPointer& mesh,
MeshFunctionPointer& Aux,
const AnisotropyPointer& anisotropy,
MeshFunctionPointer& u );
const MeshFunctionPointer& u );
protected:
const IndexType maxIterations;
void setOverlaps( StaticVector& vecLowerOverlaps, StaticVector& vecUpperOverlaps,
const MeshPointer& mesh);
bool goThroughSweep( const StaticVector boundsFrom, const StaticVector boundsTo,
MeshFunctionType& aux, const InterfaceMapType& interfaceMap,
const AnisotropyPointer& anisotropy );
void getInfoFromNeighbours( int& calculated, int& calculateAgain, const MeshPointer& mesh );
};
template< typename Real,
typename Device,
typename Index,
typename Communicator,
typename Anisotropy >
class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy >
class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Communicator, Anisotropy >
: public tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > >
{
//static_assert( std::is_same< Device, TNL::Devices::Host >::value, "The fast sweeping method works only on CPU." );
......@@ -123,8 +142,12 @@ class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy >
typedef Index IndexType;
typedef Anisotropy AnisotropyType;
typedef tnlDirectEikonalMethodsBase< Meshes::Grid< 3, Real, Device, Index > > BaseType;
typedef Communicator CommunicatorType;
typedef Containers::StaticVector< 3, Index > StaticVector;
using MeshPointer = Pointers::SharedPointer< MeshType >;
using AnisotropyPointer = Pointers::SharedPointer< AnisotropyType, DeviceType >;
using MPI = Communicators::MpiCommunicator;
using typename BaseType::InterfaceMapType;
using typename BaseType::MeshFunctionType;
......@@ -140,6 +163,7 @@ class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy >
void setMaxIterations( const IndexType& maxIterations );
void solve( const MeshPointer& mesh,
MeshFunctionPointer& Aux,
const AnisotropyPointer& anisotropy,
MeshFunctionPointer& u );
......@@ -147,6 +171,15 @@ class FastSweepingMethod< Meshes::Grid< 3, Real, Device, Index >, Anisotropy >
protected:
const IndexType maxIterations;
void setOverlaps( StaticVector& vecLowerOverlaps, StaticVector& vecUpperOverlaps,
const MeshPointer& mesh);
bool goThroughSweep( const StaticVector boundsFrom, const StaticVector boundsTo,
MeshFunctionType& aux, const InterfaceMapType& interfaceMap,
const AnisotropyPointer& anisotropy );
void getInfoFromNeighbours( int& calculated, int& calculateAgain, const MeshPointer& mesh );
};
......
......@@ -18,8 +18,9 @@
template< typename Real,
typename Device,
typename Index,
typename Communicator,
typename Anisotropy >
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >::
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Communicator, Anisotropy >::
FastSweepingMethod()
: maxIterations( 1 )
{
......@@ -29,9 +30,10 @@ FastSweepingMethod()
template< typename Real,
typename Device,
typename Index,
typename Communicator,
typename Anisotropy >
const Index&
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >::
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Communicator, Anisotropy >::
getMaxIterations() const
{
......@@ -40,9 +42,10 @@ getMaxIterations() const
template< typename Real,
typename Device,
typename Index,
typename Communicator,
typename Anisotropy >
void
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >::
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Communicator, Anisotropy >::
setMaxIterations( const IndexType& maxIterations )
{
......@@ -51,10 +54,12 @@ setMaxIterations( const IndexType& maxIterations )
template< typename Real,
typename Device,
typename Index,
typename Communicator,
typename Anisotropy >
void
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Anisotropy >::
FastSweepingMethod< Meshes::Grid< 1, Real, Device, Index >, Communicator, Anisotropy >::
solve( const MeshPointer& mesh,
MeshFunctionPointer& Aux,
const AnisotropyPointer& anisotropy,
MeshFunctionPointer& u )
{
......@@ -104,7 +109,7 @@ solve( const MeshPointer& mesh,
dim3 blockSize( cudaBlockSize );
dim3 gridSize( numBlocksX );
tnlDirectEikonalMethodsBase< Meshes::Grid< 1, Real, Device, Index > > ptr;
BaseType ptr;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment