From a0069db33399a382e2ebe714b9ab2dc526caf804 Mon Sep 17 00:00:00 2001 From: Tomas Sobotik <sobotto4@fjfi.cvut.cz> Date: Tue, 2 Dec 2014 08:01:09 +0100 Subject: [PATCH] Alpha version of parallel solver. --- examples/CMakeLists.txt | 1 + .../hamilton-jacobi-parallel/CMakeLists.txt | 17 + .../MainBuildConfig.h | 64 +++ examples/hamilton-jacobi-parallel/Makefile | 41 ++ examples/hamilton-jacobi-parallel/main.cpp | 53 ++ .../parallelEikonalConfig.h | 45 ++ .../tnlParallelEikonalSolver.h | 84 ++++ .../tnlParallelEikonalSolver_impl.h | 469 ++++++++++++++++++ .../operators/godunov-eikonal/CMakeLists.txt | 5 +- .../parallelGodunovEikonal1D_impl.h | 170 +++++++ .../parallelGodunovEikonal2D_impl.h | 224 +++++++++ .../parallelGodunovEikonal3D_impl.h | 197 ++++++++ .../solvers/ode/tnlEulerSolver_impl.h | 4 +- src/operators/godunov-eikonal/CMakeLists.txt | 1 + .../godunov-eikonal/parallelGodunovEikonal.h | 212 ++++++++ 15 files changed, 1584 insertions(+), 3 deletions(-) create mode 100755 examples/hamilton-jacobi-parallel/CMakeLists.txt create mode 100644 examples/hamilton-jacobi-parallel/MainBuildConfig.h create mode 100644 examples/hamilton-jacobi-parallel/Makefile create mode 100644 examples/hamilton-jacobi-parallel/main.cpp create mode 100644 examples/hamilton-jacobi-parallel/parallelEikonalConfig.h create mode 100644 examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h create mode 100644 examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver_impl.h create mode 100644 src/implementation/operators/godunov-eikonal/parallelGodunovEikonal1D_impl.h create mode 100644 src/implementation/operators/godunov-eikonal/parallelGodunovEikonal2D_impl.h create mode 100644 src/implementation/operators/godunov-eikonal/parallelGodunovEikonal3D_impl.h create mode 100644 src/operators/godunov-eikonal/parallelGodunovEikonal.h diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 09c7d2cf34..b5fa429c12 100755 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory( simple-solver ) add_subdirectory( heat-equation ) add_subdirectory( navier-stokes ) add_subdirectory( hamilton-jacobi ) +add_subdirectory( hamilton-jacobi-parallel ) diff --git a/examples/hamilton-jacobi-parallel/CMakeLists.txt b/examples/hamilton-jacobi-parallel/CMakeLists.txt new file mode 100755 index 0000000000..31bc1cfca6 --- /dev/null +++ b/examples/hamilton-jacobi-parallel/CMakeLists.txt @@ -0,0 +1,17 @@ +set( tnl_hamilton_jacobi_parallel_SOURCES + MainBuildConfig.h + tnlParallelEikonalSolver_impl.h + tnlParallelEikonalSolver.h + main.cpp + parallelEikonalConfig.h ) + +ADD_EXECUTABLE(hamilton-jacobi-parallel${debugExt} main.cpp) +target_link_libraries (hamilton-jacobi-parallel${debugExt} tnl${debugExt}-${tnlVersion} ) + +INSTALL( TARGETS hamilton-jacobi-parallel${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +INSTALL( FILES ${tnl_hamilton_jacobi_parallel_SOURCES} + Makefile + DESTINATION share/tnl-${tnlVersion}/examples/hamilton-jacobi-parallel ) diff --git a/examples/hamilton-jacobi-parallel/MainBuildConfig.h b/examples/hamilton-jacobi-parallel/MainBuildConfig.h new file mode 100644 index 0000000000..8ece05b9dc --- /dev/null +++ b/examples/hamilton-jacobi-parallel/MainBuildConfig.h @@ -0,0 +1,64 @@ +/*************************************************************************** + MainBuildConfig.h - description + ------------------- + begin : Jul 7, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MAINBUILDCONFIG_H_ +#define MAINBUILDCONFIG_H_ + +#include <solvers/tnlConfigTags.h> + +class MainBuildConfig +{ + public: + + static void print() { cerr << "MainBuildConfig" << endl; } +}; + +/**** + * Turn off support for float and long double. + */ +template<> struct tnlConfigTagReal< MainBuildConfig, float > { enum { enabled = false }; }; +template<> struct tnlConfigTagReal< MainBuildConfig, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct tnlConfigTagIndex< MainBuildConfig, short int >{ enum { enabled = false }; }; +template<> struct tnlConfigTagIndex< MainBuildConfig, long int >{ enum { enabled = false }; }; + +/**** + * Use of tnlGrid is enabled for allowed dimensions and Real, Device and Index types. + */ +template< int Dimensions, typename Real, typename Device, typename Index > + struct tnlConfigTagMesh< MainBuildConfig, tnlGrid< Dimensions, Real, Device, Index > > + { enum { enabled = tnlConfigTagDimensions< MainBuildConfig, Dimensions >::enabled && + tnlConfigTagReal< MainBuildConfig, Real >::enabled && + tnlConfigTagDevice< MainBuildConfig, Device >::enabled && + tnlConfigTagIndex< MainBuildConfig, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlSemiImplicitTimeDiscretisationTag >{ enum { enabled = false}; }; +template<> struct tnlConfigTagTimeDiscretisation< MainBuildConfig, tnlImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct tnlConfigTagExplicitSolver< MainBuildConfig, tnlExplicitEulerSolverTag >{ enum { enabled = false }; }; + +#endif /* MAINBUILDCONFIG_H_ */ diff --git a/examples/hamilton-jacobi-parallel/Makefile b/examples/hamilton-jacobi-parallel/Makefile new file mode 100644 index 0000000000..6b0e04e313 --- /dev/null +++ b/examples/hamilton-jacobi-parallel/Makefile @@ -0,0 +1,41 @@ +TNL_VERSION=0.1 +TNL_INSTALL_DIR=${HOME}/local/lib +TNL_INCLUDE_DIR=${HOME}/local/include/tnl-${TNL_VERSION} + +TARGET = hamiltonJacobiParallelSolver +#CONFIG_FILE = $(TARGET).cfg.desc +INSTALL_DIR = ${HOME}/local +CXX = g++ +CUDA_CXX = nvcc +OMP_FLAGS = -DHAVE_OPENMP -fopenmp +CXX_FLAGS = -std=gnu++0x -I$(TNL_INCLUDE_DIR) -O3 $(OMP_FLAGS) +LD_FLAGS = -L$(TNL_INSTALL_DIR) -ltnl-0.1 -lgomp + +SOURCES = main.cpp +HEADERS = +OBJECTS = main.o +DIST = $(SOURCES) Makefile + +all: $(TARGET) +clean: + rm -f $(OBJECTS) + rm -f $(TARGET)-conf.h + +dist: $(DIST) + tar zcvf $(TARGET).tgz $(DIST) + +install: $(TARGET) + cp $(TARGET) $(INSTALL_DIR)/bin + cp $(CONFIG_FILE) $(INSTALL_DIR)/share + +uninstall: $(TARGET) + rm -f $(INSTALL_DIR)/bin/$(TARGET) + rm -f $(CONFIG_FILE) $(INSTALL_DIR)/share + +$(TARGET): $(OBJECTS) + $(CXX) -o $(TARGET) $(OBJECTS) $(LD_FLAGS) + +%.o: %.cpp $(HEADERS) + $(CXX) -c -o $@ $(CXX_FLAGS) $< + + diff --git a/examples/hamilton-jacobi-parallel/main.cpp b/examples/hamilton-jacobi-parallel/main.cpp new file mode 100644 index 0000000000..1561662b30 --- /dev/null +++ b/examples/hamilton-jacobi-parallel/main.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + main.cpp - description + ------------------- + begin : Jul 8 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "tnlParallelEikonalSolver.h" +#include "parallelEikonalConfig.h" +#include "MainBuildConfig.h" +#include <solvers/tnlConfigTags.h> +#include <operators/godunov-eikonal/parallelGodunovEikonal.h> +#include <mesh/tnlGrid.h> + +typedef MainBuildConfig BuildConfig; + +int main( int argc, char* argv[] ) +{ + tnlParameterContainer parameters; + tnlConfigDescription configDescription; + parallelEikonalConfig< BuildConfig >::configSetup( configDescription ); + + if( ! ParseCommandLine( argc, argv, configDescription, parameters ) ) + return false; + + //if (parameters.GetParameter <tnlString>("scheme") == "godunov") + //{ + typedef parallelGodunovEikonalScheme< tnlGrid<2,double,tnlHost, int>, double, int > SchemeType; + tnlParallelEikonalSolver<SchemeType> solver; + if(!solver.init(parameters)) + { + cerr << "Solver failed to initialize." << endl; + return EXIT_FAILURE; + } + cout << "-------------------------------------------------------------" << endl; + cout << "Starting solver loop..." << endl; + solver.run(); + cout << "a" <<endl; + // } + + return EXIT_SUCCESS; +} + + diff --git a/examples/hamilton-jacobi-parallel/parallelEikonalConfig.h b/examples/hamilton-jacobi-parallel/parallelEikonalConfig.h new file mode 100644 index 0000000000..76784f7a38 --- /dev/null +++ b/examples/hamilton-jacobi-parallel/parallelEikonalConfig.h @@ -0,0 +1,45 @@ +/*************************************************************************** + hamiltonJacobiProblemConfig.h - description + ------------------- + begin : Oct 5, 2014 + copyright : (C) 2014 by Tomas Sobotik + email : + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef HAMILTONJACOBIPROBLEMCONFIG_H_ +#define HAMILTONJACOBIPROBLEMCONFIG_H_ + +#include <config/tnlConfigDescription.h> + +template< typename ConfigTag > +class parallelEikonalConfig +{ + public: + static void configSetup( tnlConfigDescription& config ) + { + config.addDelimiter( "Parallel Eikonal solver settings:" ); + config.addEntry < tnlString > ( "problem-name", "This defines particular problem.", "hamilton-jacobi-parallel" ); + config.addEntry < tnlString > ( "scheme", "This defines scheme used for discretization.", "godunov" ); + config.addEntryEnum( "godunov" ); + config.addEntryEnum( "upwind" ); + config.addRequiredEntry < tnlString > ( "initial-condition", "Initial condition for solver"); + config.addEntry < tnlString > ( "mesh", "Name of mesh.", "mesh.tnl" ); + config.addEntry < double > ( "epsilon", "This defines epsilon for smoothening of sign().", 0.0 ); + config.addEntry < double > ( "delta", " Allowed difference on subgrid boundaries", 0.0 ); + config.addRequiredEntry < double > ( "stop-time", " Final time for solver"); + config.addRequiredEntry < double > ( "initial-tau", " initial tau for solver" ); + config.addEntry < double > ( "cfl-condition", " CFL condition", 0.0 ); + config.addEntry < int > ( "subgrid-size", "Subgrid size.", 16 ); + } +}; + +#endif /* HAMILTONJACOBIPROBLEMCONFIG_H_ */ diff --git a/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h b/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h new file mode 100644 index 0000000000..5278e8e800 --- /dev/null +++ b/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver.h @@ -0,0 +1,84 @@ +/*************************************************************************** + tnlParallelEikonalSolver.h - description + ------------------- + begin : Nov 28 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLPARALLELEIKONALSOLVER_H_ +#define TNLPARALLELEIKONALSOLVER_H_ + +#include <config/tnlParameterContainer.h> +#include <core/vectors/tnlVector.h> +#include <core/vectors/tnlStaticVector.h> +#include <core/tnlHost.h> +#include <mesh/tnlGrid.h> +#include <limits.h> + + +template< typename Scheme, + typename RealType = double, + typename Device = tnlHost, + typename IndexType = int > +class tnlParallelEikonalSolver +{}; + +template< typename Scheme> +class tnlParallelEikonalSolver<Scheme, double, tnlHost, int > +{ +public: + + typedef tnlVector< double, tnlHost, int > VectorType; + typedef tnlVector< int, tnlHost, int > IntVectorType; + typedef tnlGrid< 2, double, tnlHost, int > MeshType; + + tnlParallelEikonalSolver(); + bool init( const tnlParameterContainer& parameters ); + void run(); + +private: + + void synchronize(); + + int getOwner( int i) const; + + int getSubgridValue( int i ) const; + + void setSubgridValue( int i, int value ); + + int getBoundaryCondition( int i ) const; + + void setBoundaryCondition( int i, int value ); + + void stretchGrid(); + + void contractGrid(); + + VectorType getSubgrid( const int i ) const; + + void insertSubgrid( VectorType u, const int i ); + + VectorType runSubgrid( int boundaryCondition, VectorType u); + + + VectorType u0, work_u; + IntVectorType subgridValues, boundaryConditions; + MeshType mesh, subMesh; + Scheme scheme; + double delta, tau0, stopTime,cflCondition; + int gridRows, gridCols, currentStep, n; + +}; + +#include "tnlParallelEikonalSolver_impl.h" + +#endif /* TNLPARALLELEIKONALSOLVER_H_ */ diff --git a/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver_impl.h b/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver_impl.h new file mode 100644 index 0000000000..f6e0b4a1a7 --- /dev/null +++ b/examples/hamilton-jacobi-parallel/tnlParallelEikonalSolver_impl.h @@ -0,0 +1,469 @@ +/*************************************************************************** + tnlParallelEikonalSolver_impl.h - description + ------------------- + begin : Nov 28 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TNLPARALLELEIKONALSOLVER_IMPL_H_ +#define TNLPARALLELEIKONALSOLVER_IMPL_H_ + + +#include "tnlParallelEikonalSolver.h" + +template< typename Scheme> +tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::tnlParallelEikonalSolver() +{ +} + +template< typename Scheme> +bool tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::init( const tnlParameterContainer& parameters ) +{ + cout << "Initializating solver..." << endl; + const tnlString& meshLocation = parameters.GetParameter <tnlString>("mesh"); + this->mesh.load( meshLocation ); + + this->n = parameters.GetParameter <int>("subgrid-size"); + + this->subMesh.setDimensions( this->n, this->n ); + this->subMesh.setDomain( tnlStaticVector<2,double>(0.0, 0.0), + tnlStaticVector<2,double>(this->mesh.getHx()*(double)(this->n), this->mesh.getHy()*(double)(this->n)) ); + + + const tnlString& initialCondition = parameters.GetParameter <tnlString>("initial-condition"); + this->u0.load( initialCondition ); + + this->delta = parameters.GetParameter <double>("delta"); + this->delta *= sqrt(this->mesh.getHx()*this->mesh.getHx() + this->mesh.getHy()*this->mesh.getHy()); + + this->tau0 = parameters.GetParameter <double>("initial-tau"); + this->stopTime = parameters.GetParameter <double>("stop-time"); + + this->cflCondition = parameters.GetParameter <double>("cfl-condition"); + + stretchGrid(); + this->stopTime /= (double)(this->gridCols); + + cout << "Initializating scheme..." << endl; + if(!this->scheme.init(parameters)) + { + cerr << "Scheme failed to initialize." << endl; + return false; + } + cout << "Scheme initialized." << endl; + + + VectorType* tmp = new VectorType[subgridValues.getSize()]; + bool containsCurve = false; + + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + + if(! tmp[i].setSize(this->n * this->n)) + cout << "Could not allocate tmp["<< i <<"] array." << endl; + tmp[i] = getSubgrid(i); + containsCurve = false; + + for(int j = 0; j < tmp[i].getSize(); j++) + { + if(tmp[i][0]*tmp[i][j] <= 0.0) + { + containsCurve = true; + //cout << tmp[i][0] << ":" << tmp[i][j] << endl; + j=tmp[i].getSize(); + } + + } + if(containsCurve) + { + //cout << "Computing initial SDF on subgrid " << i << "." << endl; + insertSubgrid(runSubgrid(0, tmp[i]), i); + setSubgridValue(i, 4); + //cout << "Computed initial SDF on subgrid " << i << "." << endl; + } + containsCurve = false; + + } + + this->currentStep = 1; + synchronize(); + cout << "Solver initialized." << endl; + return true; +} + +template< typename Scheme > +void tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::run() +{ + while (this->subgridValues.max() > 0) + { + + for(int i = 0; i < this->subgridValues.getSize(); i++) + { + if(getSubgridValue(i) != INT_MAX && getSubgridValue(i) > 0) + { + if(getBoundaryCondition(i) & 1) + { + insertSubgrid( runSubgrid(1, getSubgrid(i)), i); + setBoundaryCondition(i, getBoundaryCondition(i) - 1); + } + if(getBoundaryCondition(i) & 2) + { + insertSubgrid( runSubgrid(2, getSubgrid(i)), i); + setBoundaryCondition(i, getBoundaryCondition(i) - 2); + } + if(getBoundaryCondition(i) & 4) + { + insertSubgrid( runSubgrid(4, getSubgrid(i)), i); + setBoundaryCondition(i, getBoundaryCondition(i) - 4); + } + if(getBoundaryCondition(i) & 8) + { + insertSubgrid( runSubgrid(8, getSubgrid(i)), i); + setBoundaryCondition(i, getBoundaryCondition(i) - 8); + } + + setSubgridValue(i, getSubgridValue(i)-1); + } + } + + synchronize(); + } + + contractGrid(); + this->u0.save("u-00001.tnl"); + cout << "Solver finished" << endl; + +} +//north - 1, east - 2, west - 4, south - 8 +template< typename Scheme > +void tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::synchronize() +{ + cout << "Synchronizig..." << endl; + int tmp1, tmp2; + int grid1, grid2; + + for(int j = 0; j < this->gridRows - 1; j++) + { + for (int i = 0; i < this->gridCols*this->n; i++) + { + tmp1 = this->gridCols*this->n*((this->n-1)+j*this->n) + i; + tmp2 = this->gridCols*this->n*((this->n)+j*this->n) + i; + grid1 = getSubgridValue(getOwner(tmp1)); + grid2 = getSubgridValue(getOwner(tmp2)); + if ((this->work_u[tmp1] < this->work_u[tmp2] - this->delta || grid2 == INT_MAX|| grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + if(getSubgridValue(getOwner(tmp2)) == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+1); + } + else if ((this->work_u[tmp1] > this->work_u[tmp2] + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + if(getSubgridValue(getOwner(tmp1)) == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+8); + } + /*else if ( (grid1 != INT_MAX && grid1 != -INT_MAX) || (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + if(getSubgridValue(getOwner(tmp2)) == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + else if(getSubgridValue(getOwner(tmp1)) == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + }*/ + } + + } + + + for(int i = 1; i < this->gridCols; i++) + { + for (int j = 0; j < this->gridRows*this->n; j++) + { + tmp1 = this->gridCols*this->n*j + i*this->n; + tmp2 = this->gridCols*this->n*j + i*this->n + 1; + if ((this->work_u[tmp1] < this->work_u[tmp2] - this->delta || grid2 == INT_MAX|| grid2 == -INT_MAX) && (grid1 != INT_MAX && grid1 != -INT_MAX)) + { + this->work_u[tmp2] = this->work_u[tmp1]; + if(getSubgridValue(getOwner(tmp2)) == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + setBoundaryCondition(getOwner(tmp2), getBoundaryCondition(getOwner(tmp2))+2); + } + else if ((this->work_u[tmp1] > this->work_u[tmp2] + this->delta || grid1 == INT_MAX || grid1 == -INT_MAX) && (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + this->work_u[tmp1] = this->work_u[tmp2]; + if(getSubgridValue(getOwner(tmp1)) == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + setBoundaryCondition(getOwner(tmp1), getBoundaryCondition(getOwner(tmp1))+4); + } + /*else if ( (grid1 != INT_MAX && grid1 != -INT_MAX) || (grid2 != INT_MAX && grid2 != -INT_MAX)) + { + if(getSubgridValue(getOwner(tmp2)) == INT_MAX) + { + setSubgridValue(getOwner(tmp2), -INT_MAX); + } + else if(getSubgridValue(getOwner(tmp1)) == INT_MAX) + { + setSubgridValue(getOwner(tmp1), -INT_MAX); + } + }*/ + } + + } + + int stepValue = this->currentStep + 3; + this->currentStep++; + for (int i = 0; i < this->subgridValues.getSize(); i++) + { + if( getSubgridValue(i) == -INT_MAX ) + setSubgridValue(i, stepValue); + } + + cout << "Grid synchronized at step " << (this->currentStep - 1 ) << endl; + +} + + +template< typename Scheme > +int tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::getOwner(int i) const +{ + + return (i / (this->gridCols*this->n*this->n))*this->gridCols + (i % (this->gridCols*this->n))/this->n; +} + +template< typename Scheme > +int tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::getSubgridValue( int i ) const +{ + return this->subgridValues[i]; +} + +template< typename Scheme > +void tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::setSubgridValue(int i, int value) +{ + this->subgridValues[i] = value; +} + +template< typename Scheme > +int tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::getBoundaryCondition( int i ) const +{ + return this->boundaryConditions[i]; +} + +template< typename Scheme > +void tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::setBoundaryCondition(int i, int value) +{ + this->boundaryConditions[i] = value; +} + +template< typename Scheme > +void tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::stretchGrid() +{ + cout << "Stretching grid..." << endl; + + + this->gridCols = ceil((double)(this->mesh.getDimensions().x())/(double)(this->n)); + this->gridRows = ceil((double)(this->mesh.getDimensions().y())/(double)(this->n)); + + this->subgridValues.setSize(this->gridCols*this->gridRows); + this->boundaryConditions.setSize(this->gridCols*this->gridRows); + + for(int i = 0; i < this->subgridValues.getSize(); i++ ) + { + this->subgridValues[i] = INT_MAX; + this->boundaryConditions[i] = 0; + } + + int stretchedSize = this->n*this->n*this->gridCols*this->gridRows; + + if(!this->work_u.setSize(stretchedSize)) + cerr << "Could not allocate memory for stretched grid." << endl; + + + for(int i = 0; i < stretchedSize; i++) + { + int k = i/this->n - i/(this->n*this->gridCols) + this->n*this->gridCols*(i/(this->n*this->n*this->gridCols)); + int j=(i % (this->n*this->gridCols)) - ( (this->mesh.getDimensions().x() - this->n)/(this->n - 1) + this->mesh.getDimensions().x()); + + if(j > 0) + k += j; + + this->work_u[i] = this->u0[i-k]; + } + + cout << "Grid stretched." << endl; +} + +template< typename Scheme > +void tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::contractGrid() +{ + cout << "Contracting grid..." << endl; + int stretchedSize = this->n*this->n*this->gridCols*this->gridRows; + + for(int i = 0; i < stretchedSize; i++) + { + int k = i/this->n - i/(this->n*this->gridCols) + this->n*this->gridCols*(i/(this->n*this->n*this->gridCols)); + int j=(i % (this->n*this->gridCols)) - ((this->mesh.getDimensions().x() - this->n)/(this->n - 1) + this->mesh.getDimensions().x()); + + if(!(j > 0)) + this->u0[i-k] = this->work_u[i]; + } + + //MISSING FILL FOR BOTTOM + cout << "Grid contracted" << endl; +} + +template< typename Scheme > +typename tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::VectorType +tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::getSubgrid( const int i ) const +{ + VectorType u; + u.setSize(this->n*this->n); + + for( int j = 0; j < this->n*this->n; j++) + { + u[j] = this->work_u[(i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n)]; + } + return u; +} + +template< typename Scheme > +void tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::insertSubgrid( VectorType u, const int i ) +{ + for( int j = 0; j < this->n*this->n; j++) + { + int index = (i / this->gridCols)*this->n*this->n*this->gridCols + (i % this->gridCols)*this->n + (j/this->n)*this->n*this->gridCols + (j % this->n); + //OMP LOCK index + if(this->work_u[index] > u[j]) + this->work_u[index] = u[j]; + //OMP UNLOCK index + } +} + +template< typename Scheme > +typename tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::VectorType +tnlParallelEikonalSolver<Scheme, double, tnlHost, int>::runSubgrid( int boundaryCondition, VectorType u) +{ + VectorType fu; + + fu.setLike(u); + fu.setValue( 0.0 ); + +/* + * Insert Euler-Solver Here + */ + + double time = 0.0; + double currentTau = this->tau0; + if( time + currentTau > this -> stopTime ) currentTau = this -> stopTime - time; + /*this->resetIterations(); + this->setResidue( this->getConvergenceResidue() + 1.0 ); + + this -> refreshSolverMonitor();*/ + + /**** + * Start the main loop + */ + while( time < this->stopTime ) + { + /**** + * Compute the RHS + */ + //this->problem->getExplicitRHS( time, currentTau, u, fu ); + + for( int i = 0; i < fu.getSize(); i ++ ) + { + fu[ i ] = scheme.getValue( this->subMesh, i, this->subMesh.getCellCoordinates(i), u, time, boundaryCondition ); + } + + + //RealType lastResidue = this->getResidue(); + double maxResidue( 0.0 ); + //cout << fu. absMax() << endl; + if( this -> cflCondition != 0.0 ) + { + maxResidue = fu. absMax(); + if( currentTau * maxResidue > this -> cflCondition ) + { + currentTau *= 0.9; + continue; + } + } + //RealType newResidue( 0.0 ); + //computeNewTimeLevel( u, currentTau, newResidue ); + for( int i = 0; i < fu.getSize(); i ++ ) + { + double add = currentTau * fu[ i ]; + u[ i ] += add; + //localResidue += fabs( add ); + } + //this->setResidue( newResidue ); + + /**** + * When time is close to stopTime the new residue + * may be inaccurate significantly. + */ + //if( currentTau + time == this -> stopTime ) this->setResidue( lastResidue ); + time += currentTau; + + /*if( ! this->nextIteration() ) + return false;*/ + + /**** + * Compute the new time step. + */ + if( this -> cflCondition != 0.0 ) + currentTau /= 0.95; + + if( time + currentTau > this -> stopTime ) + currentTau = this -> stopTime - time; //we don't want to keep such tau + //else this -> tau = currentTau; + + //this -> refreshSolverMonitor(); + + /**** + * Check stop conditions. + */ + /*if( time >= this->getStopTime() || + ( this -> getConvergenceResidue() != 0.0 && this->getResidue() < this -> getConvergenceResidue() ) ) + { + //this -> refreshSolverMonitor(); + return true; + }*/ + + + } + + + VectorType solution; + solution.setLike(u); + for( int i = 0; i < u.getSize(); i ++ ) + { + solution[i]=u[i]; + } + + return solution; +} + + +#endif /* TNLPARALLELEIKONALSOLVER_IMPL_H_ */ diff --git a/src/implementation/operators/godunov-eikonal/CMakeLists.txt b/src/implementation/operators/godunov-eikonal/CMakeLists.txt index 6dfff4c79a..6e0c100777 100755 --- a/src/implementation/operators/godunov-eikonal/CMakeLists.txt +++ b/src/implementation/operators/godunov-eikonal/CMakeLists.txt @@ -1,6 +1,9 @@ set( headers godunovEikonal1D_impl.h godunovEikonal2D_impl.h - godunovEikonal3D_impl.h) + godunovEikonal3D_impl.h + parallelGodunovEikonal1D_impl.h + parallelGodunovEikonal2D_impl.h + parallelGodunovEikonal3D_impl.h) SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/implementation/operators/godunov-eikonal ) diff --git a/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal1D_impl.h b/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal1D_impl.h new file mode 100644 index 0000000000..899549178b --- /dev/null +++ b/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal1D_impl.h @@ -0,0 +1,170 @@ +/*************************************************************************** + parallelGodunovEikonal1D_impl.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOVEIKONAL1D_IMPL_H_ +#define GODUNOVEIKONAL1D_IMPL_H_ + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if(eps == 0.0) + return 0.0; + + return sin( ( M_PI * x ) / (2 * eps) ); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > :: init( const tnlParameterContainer& parameters ) +{ + + + const tnlString& meshFile = parameters.GetParameter< tnlString >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + h = originalMesh.getHx(); + cout << "h = " << h << endl; + + epsilon = parameters. GetParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=h; + + /*dofVector. setSize( this->mesh.getDofs() );*/ + + return true; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString parallelGodunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return tnlString( "parallelGodunovEikonalScheme< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 1, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time, + const IndexType boundaryCondition ) const +{ + + RealType nabla, xb, xf, signui; + + signui = sign(u[cellIndex],epsilon); + + if(signui > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return signui*(1.0 - nabla); + } + else if (signui < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/h); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/h); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + nabla = sqrt (xf*xf + xb*xb ); + + return signui*(1.0 - nabla); + } + else + { + return 0.0; + } + +} + + +#endif /* GODUNOVEIKONAL1D_IMPL_H_ */ diff --git a/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal2D_impl.h b/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal2D_impl.h new file mode 100644 index 0000000000..ba64ea36fb --- /dev/null +++ b/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal2D_impl.h @@ -0,0 +1,224 @@ +/*************************************************************************** + parallelGodunovEikonal2D_impl.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOVEIKONAL2D_IMPL_H_ +#define GODUNOVEIKONAL2D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index >:: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if ( eps == 0.0) + return 0.0; + + return sin((M_PI*x)/(2.0*eps)); +} + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > :: init( const tnlParameterContainer& parameters ) +{ + + const tnlString& meshFile = parameters.GetParameter< tnlString >( "mesh" ); + MeshType originalMesh; + if( ! originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + + + hx = originalMesh.getHx(); + hy = originalMesh.getHy(); + + epsilon = parameters. GetParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=sqrt( hx*hx + hy*hy ); + +// dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return tnlString( "tnlLinearDiffusion< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 2, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time, + const IndexType boundaryCondition ) const +{ + + if ( (coordinates.x() == 0 && boundaryCondition == 4) || + (coordinates.x() == mesh.getDimensions().x() - 1 && boundaryCondition == 2) || + (coordinates.y() == 0 && boundaryCondition == 1) || + (coordinates.y() == mesh.getDimensions().y() - 1 && boundaryCondition == 8) ) + return 0.0; + + RealType nabla, xb, xf, yb, yf, signui; + + signui = sign(u[cellIndex],epsilon); + + if(signui > 0.0) + { + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf = negativePart((u[mesh.getCellXPredecessor( cellIndex )] - u[cellIndex])/hx); + else + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + + if(coordinates.x() == 0) + xb = positivePart((u[cellIndex] - u[mesh.getCellXSuccessor( cellIndex )])/hx); + else + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf = negativePart((u[mesh.getCellYPredecessor( cellIndex )] - u[cellIndex])/hy); + else + yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + + if(coordinates.y() == 0) + yb = positivePart((u[cellIndex] - u[mesh.getCellYSuccessor( cellIndex )])/hy); + else + yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + if(yb + yf > 0.0) + yf = 0.0; + else + yb = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); + + return signui*(1.0 - nabla); + } + else if (signui < 0.0) + { + if(coordinates.x() == mesh.getDimensions().x() - 1) + xf = positivePart((u[mesh.getCellXPredecessor( cellIndex )] - u[cellIndex])/hx); + else + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + + if(coordinates.x() == 0) + xb = negativePart((u[cellIndex] - u[mesh.getCellXSuccessor( cellIndex )])/hx); + else + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + + if(coordinates.y() == mesh.getDimensions().y() - 1) + yf = positivePart((u[mesh.getCellYPredecessor( cellIndex )] - u[cellIndex])/hy); + else + yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + + if(coordinates.y() == 0) + yb = negativePart((u[cellIndex] - u[mesh.getCellYSuccessor( cellIndex )])/hy); + else + yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + if(yb + yf > 0.0) + yb = 0.0; + else + yf = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb ); + + return signui*(1.0 - nabla); + } + else + { + return 0.0; + } + +} + + +#endif /* GODUNOVEIKONAL2D_IMPL_H_ */ diff --git a/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal3D_impl.h b/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal3D_impl.h new file mode 100644 index 0000000000..f160223ad1 --- /dev/null +++ b/src/implementation/operators/godunov-eikonal/parallelGodunovEikonal3D_impl.h @@ -0,0 +1,197 @@ +/*************************************************************************** + parallelGodunovEikonal3D_impl.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOVEIKONAL3D_IMPL_H_ +#define GODUNOVEIKONAL3D_IMPL_H_ + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: positivePart(const Real arg) const +{ + if(arg > 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: negativePart(const Real arg) const +{ + if(arg < 0.0) + return arg; + return 0.0; +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +Real parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: sign(const Real x, const Real eps) const +{ + if(x > eps) + return 1.0; + else if (x < -eps) + return (-1.0); + + if ( eps == 0.0) + return 0.0; + + return sin((M_PI*x)/(2.0*eps)); +} + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +bool parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > :: init( const tnlParameterContainer& parameters ) +{ + const tnlString& meshFile = parameters.GetParameter< tnlString >( "mesh" ); + if( ! this->originalMesh.load( meshFile ) ) + { + cerr << "I am not able to load the mesh from the file " << meshFile << "." << endl; + return false; + } + + + hx = originalMesh.getHx(); + hy = originalMesh.getHy(); + hz = originalMesh.getHz(); + + epsilon = parameters. GetParameter< double >( "epsilon" ); + + if(epsilon != 0.0) + epsilon *=sqrt( hx*hx + hy*hy +hz*hz ); + + // dofVector. setSize( this->mesh.getDofs() ); + + return true; + +} + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +tnlString parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index > :: getType() +{ + return tnlString( "tnlLinearDiffusion< " ) + + MeshType::getType() + ", " + + ::getType< Real >() + ", " + + ::getType< Index >() + " >"; +} + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +template< typename Vector > +#ifdef HAVE_CUDA +__device__ __host__ +#endif +Real parallelGodunovEikonalScheme< tnlGrid< 3, MeshReal, Device, MeshIndex >, Real, Index >:: getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const Real& time, + const IndexType boundaryCondition ) const +{ + + RealType nabla, xb, xf, yb, yf, zb, zf, signui; + + signui = sign(u[cellIndex],epsilon); + + if(signui > 0.0) + { + xf = negativePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = positivePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = negativePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = positivePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + zf = negativePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz); + zb = positivePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz); + + if(xb + xf > 0.0) + xf = 0.0; + else + xb = 0.0; + + if(yb + yf > 0.0) + yf = 0.0; + else + yb = 0.0; + + if(zb + zf > 0.0) + zf = 0.0; + else + zb = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb ); + + return signui*(1.0 - nabla); + } + else if (signui < 0.0) + { + xf = positivePart((u[mesh.getCellXSuccessor( cellIndex )] - u[cellIndex])/hx); + xb = negativePart((u[cellIndex] - u[mesh.getCellXPredecessor( cellIndex )])/hx); + yf = positivePart((u[mesh.getCellYSuccessor( cellIndex )] - u[cellIndex])/hy); + yb = negativePart((u[cellIndex] - u[mesh.getCellYPredecessor( cellIndex )])/hy); + zf = positivePart((u[mesh.getCellZSuccessor( cellIndex )] - u[cellIndex])/hz); + zb = negativePart((u[cellIndex] - u[mesh.getCellZPredecessor( cellIndex )])/hz); + + if(xb + xf > 0.0) + xb = 0.0; + else + xf = 0.0; + + if(yb + yf > 0.0) + yb = 0.0; + else + yf = 0.0; + + if(zb + zf > 0.0) + zb = 0.0; + else + zf = 0.0; + + nabla = sqrt (xf*xf + xb*xb + yf*yf + yb*yb + zf*zf + zb*zb ); + + return signui*(1.0 - nabla); + } + else + { + return 0.0; + } + +} + + +#endif /* GODUNOVEIKONAL3D_IMPL_H_ */ diff --git a/src/implementation/solvers/ode/tnlEulerSolver_impl.h b/src/implementation/solvers/ode/tnlEulerSolver_impl.h index 3fb5f16170..eb2fdb28b1 100644 --- a/src/implementation/solvers/ode/tnlEulerSolver_impl.h +++ b/src/implementation/solvers/ode/tnlEulerSolver_impl.h @@ -81,8 +81,8 @@ bool tnlEulerSolver< Problem > :: solve( DofVectorType& u ) /**** * Set necessary parameters */ - RealType& time = this->time; - RealType currentTau = this->tau; + double time = 0.0; + double currentTau = this->tau0; if( time + currentTau > this -> getStopTime() ) currentTau = this -> getStopTime() - time; if( currentTau == 0.0 ) return true; this->resetIterations(); diff --git a/src/operators/godunov-eikonal/CMakeLists.txt b/src/operators/godunov-eikonal/CMakeLists.txt index 79145e6fe7..554890c93e 100755 --- a/src/operators/godunov-eikonal/CMakeLists.txt +++ b/src/operators/godunov-eikonal/CMakeLists.txt @@ -1,4 +1,5 @@ SET( headers godunovEikonal.h + parallelGodunovEikonal.h ) INSTALL( FILES ${headers} DESTINATION include/tnl-${tnlVersion}/operators/godunov-eikonal ) diff --git a/src/operators/godunov-eikonal/parallelGodunovEikonal.h b/src/operators/godunov-eikonal/parallelGodunovEikonal.h new file mode 100644 index 0000000000..0834e22080 --- /dev/null +++ b/src/operators/godunov-eikonal/parallelGodunovEikonal.h @@ -0,0 +1,212 @@ +/*************************************************************************** + godunov.h - description + ------------------- + begin : Dec 1 , 2014 + copyright : (C) 2014 by Tomas Sobotik + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GODUNOVEIKONAL_H_ +#define GODUNOVEIKONAL_H_ + +#include <matrices/tnlCSRMatrix.h> +#include <solvers/preconditioners/tnlDummyPreconditioner.h> +#include <solvers/tnlSolverMonitor.h> +#include <core/tnlLogger.h> +#include <core/vectors/tnlVector.h> +#include <core/vectors/tnlSharedVector.h> +#include <core/mfilename.h> +#include <mesh/tnlGrid.h> + + +template< typename Mesh, + typename Real, + typename Index > +class parallelGodunovEikonalScheme +{ +}; + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovEikonalScheme< tnlGrid< 1,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 1, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + + static tnlString getType(); + + RealType positivePart(const RealType arg) const; + + RealType negativePart(const RealType arg) const; + + RealType sign(const RealType x, const RealType eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition) const; + + bool init( const tnlParameterContainer& parameters ); + + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType h; + + RealType epsilon; + + +}; + + + + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovEikonalScheme< tnlGrid< 2,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 2, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + static tnlString getType(); + + RealType positivePart(const RealType arg) const; + + RealType negativePart(const RealType arg) const; + + RealType sign(const RealType x, const Real eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition ) const; + + bool init( const tnlParameterContainer& parameters ); + + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx; + RealType hy; + + RealType epsilon; + + +}; + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class parallelGodunovEikonalScheme< tnlGrid< 3,MeshReal, Device, MeshIndex >, Real, Index > +{ + +public: + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef tnlGrid< 3, Real, Device, Index > MeshType; + typedef tnlVector< RealType, DeviceType, IndexType> DofVectorType; + typedef typename MeshType::CoordinatesType CoordinatesType; + + + static tnlString getType(); + + RealType positivePart(const RealType arg) const; + + RealType negativePart(const RealType arg) const; + + RealType sign(const RealType x, const Real eps) const; + + template< typename Vector > + #ifdef HAVE_CUDA + __device__ __host__ + #endif + Real getValue( const MeshType& mesh, + const IndexType cellIndex, + const CoordinatesType& coordinates, + const Vector& u, + const RealType& time, + const IndexType boundaryCondition ) const; + + bool init( const tnlParameterContainer& parameters ); + + +protected: + + MeshType originalMesh; + + DofVectorType dofVector; + + RealType hx; + RealType hy; + RealType hz; + + RealType epsilon; + + +}; + + + +#include <implementation/operators/godunov-eikonal/parallelGodunovEikonal1D_impl.h> +#include <implementation/operators/godunov-eikonal/parallelGodunovEikonal2D_impl.h> +#include <implementation/operators/godunov-eikonal/parallelGodunovEikonal3D_impl.h> + + +#endif /* GODUNOVEIKONAL_H_ */ -- GitLab