From d87a946c1bb71e4f156a7691ecfd27eb8b634274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4fer?= <schafjan@fjfi.cvut.cz> Date: Sun, 2 Sep 2018 21:42:50 +0200 Subject: [PATCH] added steger-warming flow and upwind for transport equation --- examples/flow-sw/BoundaryConditionsBoiler.h | 137 ++ examples/flow-sw/BoundaryConditionsCavity.h | 137 ++ examples/flow-sw/CMakeLists.txt | 23 + .../CompressibleConservativeVariables.h | 147 ++ .../flow-sw/DensityBoundaryConditionBoiler.h | 542 +++++++ .../flow-sw/DensityBoundaryConditionCavity.h | 536 +++++++ .../flow-sw/EnergyBoundaryConditionBoiler.h | 854 ++++++++++ .../flow-sw/EnergyBoundaryConditionCavity.h | 673 ++++++++ examples/flow-sw/LaxFridrichs.h | 141 ++ examples/flow-sw/LaxFridrichsContinuity.h | 288 ++++ examples/flow-sw/LaxFridrichsEnergy.h | 309 ++++ examples/flow-sw/LaxFridrichsMomentumBase.h | 68 + examples/flow-sw/LaxFridrichsMomentumX.h | 276 ++++ examples/flow-sw/LaxFridrichsMomentumY.h | 260 +++ examples/flow-sw/LaxFridrichsMomentumZ.h | 240 +++ .../MomentumXBoundaryConditionBoiler.h | 594 +++++++ .../MomentumXBoundaryConditionCavity.h | 570 +++++++ .../MomentumYBoundaryConditionBoiler.h | 588 +++++++ .../MomentumYBoundaryConditionCavity.h | 564 +++++++ .../MomentumZBoundaryConditionBoiler.h | 563 +++++++ .../MomentumZBoundaryConditionCavity.h | 554 +++++++ examples/flow-sw/PhysicalVariablesGetter.h | 122 ++ .../flow-sw/RiemannProblemInitialCondition.h | 1417 +++++++++++++++++ examples/flow-sw/Upwind.h | 158 ++ examples/flow-sw/UpwindContinuity.h | 386 +++++ examples/flow-sw/UpwindEnergy.h | 717 +++++++++ examples/flow-sw/UpwindMomentumBase.h | 137 ++ examples/flow-sw/UpwindMomentumX.h | 433 +++++ examples/flow-sw/UpwindMomentumY.h | 403 +++++ examples/flow-sw/UpwindMomentumZ.h | 338 ++++ examples/flow-sw/navierStokes.cpp | 1 + examples/flow-sw/navierStokes.cu | 1 + examples/flow-sw/navierStokes.h | 107 ++ examples/flow-sw/navierStokesBuildConfigTag.h | 51 + examples/flow-sw/navierStokesProblem.h | 133 ++ examples/flow-sw/navierStokesProblem_impl.h | 456 ++++++ examples/flow-sw/navierStokesRhs.h | 35 + examples/flow-sw/run-euler | 25 + examples/flow-vl/UpwindMomentumBase.h | 8 +- examples/inviscid-flow-vl/UpwindContinuity.h | 2 +- examples/inviscid-flow-vl/UpwindEnergy.h | 7 +- .../inviscid-flow-vl/UpwindMomentumBase.h | 8 +- .../tnl-run-transport-equation-eoc | 500 +++++- src/TNL/Operators/Advection/Upwind.h | 328 ++++ 44 files changed, 13798 insertions(+), 39 deletions(-) create mode 100644 examples/flow-sw/BoundaryConditionsBoiler.h create mode 100644 examples/flow-sw/BoundaryConditionsCavity.h create mode 100644 examples/flow-sw/CMakeLists.txt create mode 100644 examples/flow-sw/CompressibleConservativeVariables.h create mode 100644 examples/flow-sw/DensityBoundaryConditionBoiler.h create mode 100644 examples/flow-sw/DensityBoundaryConditionCavity.h create mode 100644 examples/flow-sw/EnergyBoundaryConditionBoiler.h create mode 100644 examples/flow-sw/EnergyBoundaryConditionCavity.h create mode 100644 examples/flow-sw/LaxFridrichs.h create mode 100644 examples/flow-sw/LaxFridrichsContinuity.h create mode 100644 examples/flow-sw/LaxFridrichsEnergy.h create mode 100644 examples/flow-sw/LaxFridrichsMomentumBase.h create mode 100644 examples/flow-sw/LaxFridrichsMomentumX.h create mode 100644 examples/flow-sw/LaxFridrichsMomentumY.h create mode 100644 examples/flow-sw/LaxFridrichsMomentumZ.h create mode 100644 examples/flow-sw/MomentumXBoundaryConditionBoiler.h create mode 100644 examples/flow-sw/MomentumXBoundaryConditionCavity.h create mode 100644 examples/flow-sw/MomentumYBoundaryConditionBoiler.h create mode 100644 examples/flow-sw/MomentumYBoundaryConditionCavity.h create mode 100644 examples/flow-sw/MomentumZBoundaryConditionBoiler.h create mode 100644 examples/flow-sw/MomentumZBoundaryConditionCavity.h create mode 100644 examples/flow-sw/PhysicalVariablesGetter.h create mode 100644 examples/flow-sw/RiemannProblemInitialCondition.h create mode 100644 examples/flow-sw/Upwind.h create mode 100644 examples/flow-sw/UpwindContinuity.h create mode 100644 examples/flow-sw/UpwindEnergy.h create mode 100644 examples/flow-sw/UpwindMomentumBase.h create mode 100644 examples/flow-sw/UpwindMomentumX.h create mode 100644 examples/flow-sw/UpwindMomentumY.h create mode 100644 examples/flow-sw/UpwindMomentumZ.h create mode 100644 examples/flow-sw/navierStokes.cpp create mode 100644 examples/flow-sw/navierStokes.cu create mode 100644 examples/flow-sw/navierStokes.h create mode 100644 examples/flow-sw/navierStokesBuildConfigTag.h create mode 100644 examples/flow-sw/navierStokesProblem.h create mode 100644 examples/flow-sw/navierStokesProblem_impl.h create mode 100644 examples/flow-sw/navierStokesRhs.h create mode 100644 examples/flow-sw/run-euler create mode 100644 src/TNL/Operators/Advection/Upwind.h diff --git a/examples/flow-sw/BoundaryConditionsBoiler.h b/examples/flow-sw/BoundaryConditionsBoiler.h new file mode 100644 index 0000000000..0cba68d7fa --- /dev/null +++ b/examples/flow-sw/BoundaryConditionsBoiler.h @@ -0,0 +1,137 @@ +#include <TNL/Functions/FunctionAdapter.h> + +#include "DensityBoundaryConditionBoiler.h" +#include "MomentumXBoundaryConditionBoiler.h" +#include "MomentumYBoundaryConditionBoiler.h" +#include "MomentumZBoundaryConditionBoiler.h" +#include "EnergyBoundaryConditionBoiler.h" + +namespace TNL { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class BoundaryConditionsBoiler +{ + public: + typedef Mesh MeshType; + typedef Real RealType; + typedef Index IndexType; + typedef Function FunctionType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + typedef typename Mesh::DeviceType DeviceType; + + typedef TNL::Operators::DensityBoundaryConditionsBoiler< MeshType, FunctionType, RealType, IndexType > DensityBoundaryConditionsType; + typedef TNL::Operators::MomentumXBoundaryConditionsBoiler< MeshType, FunctionType, RealType, IndexType > MomentumXBoundaryConditionsType; + typedef TNL::Operators::MomentumYBoundaryConditionsBoiler< MeshType, FunctionType, RealType, IndexType > MomentumYBoundaryConditionsType; + typedef TNL::Operators::MomentumZBoundaryConditionsBoiler< MeshType, FunctionType, RealType, IndexType > MomentumZBoundaryConditionsType; + typedef TNL::Operators::EnergyBoundaryConditionsBoiler< MeshType, FunctionType, RealType, IndexType > EnergyBoundaryConditionsType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + + typedef SharedPointer< DensityBoundaryConditionsType > DensityBoundaryConditionsTypePointer; + typedef SharedPointer< MomentumXBoundaryConditionsType > MomentumXBoundaryConditionsTypePointer; + typedef SharedPointer< MomentumYBoundaryConditionsType > MomentumYBoundaryConditionsTypePointer; + typedef SharedPointer< MomentumZBoundaryConditionsType > MomentumZBoundaryConditionsTypePointer; + typedef SharedPointer< EnergyBoundaryConditionsType > EnergyBoundaryConditionsTypePointer; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshType > MeshPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + } + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->densityBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->momentumXBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->momentumYBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->momentumZBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->energyBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + return true; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->densityBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->momentumXBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->momentumYBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->momentumZBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->energyBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + } + + void setTimestep(const RealType timestep) + { + this->densityBoundaryConditionsPointer->setTimestep(timestep); + this->momentumXBoundaryConditionsPointer->setTimestep(timestep); + this->momentumYBoundaryConditionsPointer->setTimestep(timestep); + this->momentumZBoundaryConditionsPointer->setTimestep(timestep); + this->energyBoundaryConditionsPointer->setTimestep(timestep); + } + + void setGamma(const RealType gamma) + { + this->densityBoundaryConditionsPointer->setGamma(gamma); + this->momentumXBoundaryConditionsPointer->setGamma(gamma); + this->momentumYBoundaryConditionsPointer->setGamma(gamma); + this->momentumZBoundaryConditionsPointer->setGamma(gamma); + this->energyBoundaryConditionsPointer->setGamma(gamma); + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->densityBoundaryConditionsPointer->setPressure(pressure); + this->momentumXBoundaryConditionsPointer->setPressure(pressure); + this->momentumYBoundaryConditionsPointer->setPressure(pressure); + this->momentumZBoundaryConditionsPointer->setPressure(pressure); + this->energyBoundaryConditionsPointer->setPressure(pressure); + } + + void setSpeed(const RealType cavitySpeed) + { + this->momentumXBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + this->momentumYBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + this->momentumZBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + this->energyBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + } + + DensityBoundaryConditionsTypePointer& getDensityBoundaryCondition() + { + return this->densityBoundaryConditionsPointer; + } + + MomentumXBoundaryConditionsTypePointer& getMomentumXBoundaryCondition() + { + return this->momentumXBoundaryConditionsPointer; + } + + MomentumYBoundaryConditionsTypePointer& getMomentumYBoundaryCondition() + { + return this->momentumYBoundaryConditionsPointer; + } + + MomentumZBoundaryConditionsTypePointer& getMomentumZBoundaryCondition() + { + return this->momentumZBoundaryConditionsPointer; + } + + EnergyBoundaryConditionsTypePointer& getEnergyBoundaryCondition() + { + return this->energyBoundaryConditionsPointer; + } + + + protected: + DensityBoundaryConditionsTypePointer densityBoundaryConditionsPointer; + MomentumXBoundaryConditionsTypePointer momentumXBoundaryConditionsPointer; + MomentumYBoundaryConditionsTypePointer momentumYBoundaryConditionsPointer; + MomentumZBoundaryConditionsTypePointer momentumZBoundaryConditionsPointer; + EnergyBoundaryConditionsTypePointer energyBoundaryConditionsPointer; + +}; + +} //namespace TNL diff --git a/examples/flow-sw/BoundaryConditionsCavity.h b/examples/flow-sw/BoundaryConditionsCavity.h new file mode 100644 index 0000000000..8a42faea17 --- /dev/null +++ b/examples/flow-sw/BoundaryConditionsCavity.h @@ -0,0 +1,137 @@ +#include <TNL/Functions/FunctionAdapter.h> + +#include "DensityBoundaryConditionCavity.h" +#include "MomentumXBoundaryConditionCavity.h" +#include "MomentumYBoundaryConditionCavity.h" +#include "MomentumZBoundaryConditionCavity.h" +#include "EnergyBoundaryConditionCavity.h" + +namespace TNL { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class BoundaryConditionsCavity +{ + public: + typedef Mesh MeshType; + typedef Real RealType; + typedef Index IndexType; + typedef Function FunctionType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + typedef typename Mesh::DeviceType DeviceType; + + typedef TNL::Operators::DensityBoundaryConditionsCavity< MeshType, FunctionType, RealType, IndexType > DensityBoundaryConditionsType; + typedef TNL::Operators::MomentumXBoundaryConditionsCavity< MeshType, FunctionType, RealType, IndexType > MomentumXBoundaryConditionsType; + typedef TNL::Operators::MomentumYBoundaryConditionsCavity< MeshType, FunctionType, RealType, IndexType > MomentumYBoundaryConditionsType; + typedef TNL::Operators::MomentumZBoundaryConditionsCavity< MeshType, FunctionType, RealType, IndexType > MomentumZBoundaryConditionsType; + typedef TNL::Operators::EnergyBoundaryConditionsCavity< MeshType, FunctionType, RealType, IndexType > EnergyBoundaryConditionsType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + + typedef SharedPointer< DensityBoundaryConditionsType > DensityBoundaryConditionsTypePointer; + typedef SharedPointer< MomentumXBoundaryConditionsType > MomentumXBoundaryConditionsTypePointer; + typedef SharedPointer< MomentumYBoundaryConditionsType > MomentumYBoundaryConditionsTypePointer; + typedef SharedPointer< MomentumZBoundaryConditionsType > MomentumZBoundaryConditionsTypePointer; + typedef SharedPointer< EnergyBoundaryConditionsType > EnergyBoundaryConditionsTypePointer; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshType > MeshPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + } + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->densityBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->momentumXBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->momentumYBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->momentumZBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + this->energyBoundaryConditionsPointer->setup( meshPointer, parameters, prefix); + return true; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->densityBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->momentumXBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->momentumYBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->momentumZBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + this->energyBoundaryConditionsPointer->setCompressibleConservativeVariables(compressibleConservativeVariables); + } + + void setTimestep(const RealType timestep) + { + this->densityBoundaryConditionsPointer->setTimestep(timestep); + this->momentumXBoundaryConditionsPointer->setTimestep(timestep); + this->momentumYBoundaryConditionsPointer->setTimestep(timestep); + this->momentumZBoundaryConditionsPointer->setTimestep(timestep); + this->energyBoundaryConditionsPointer->setTimestep(timestep); + } + + void setGamma(const RealType gamma) + { + this->densityBoundaryConditionsPointer->setGamma(gamma); + this->momentumXBoundaryConditionsPointer->setGamma(gamma); + this->momentumYBoundaryConditionsPointer->setGamma(gamma); + this->momentumZBoundaryConditionsPointer->setGamma(gamma); + this->energyBoundaryConditionsPointer->setGamma(gamma); + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->densityBoundaryConditionsPointer->setPressure(pressure); + this->momentumXBoundaryConditionsPointer->setPressure(pressure); + this->momentumYBoundaryConditionsPointer->setPressure(pressure); + this->momentumZBoundaryConditionsPointer->setPressure(pressure); + this->energyBoundaryConditionsPointer->setPressure(pressure); + } + + void setSpeed(const RealType cavitySpeed) + { + this->momentumXBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + this->momentumYBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + this->momentumZBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + this->energyBoundaryConditionsPointer->setCavitySpeed(cavitySpeed); + } + + DensityBoundaryConditionsTypePointer& getDensityBoundaryCondition() + { + return this->densityBoundaryConditionsPointer; + } + + MomentumXBoundaryConditionsTypePointer& getMomentumXBoundaryCondition() + { + return this->momentumXBoundaryConditionsPointer; + } + + MomentumYBoundaryConditionsTypePointer& getMomentumYBoundaryCondition() + { + return this->momentumYBoundaryConditionsPointer; + } + + MomentumZBoundaryConditionsTypePointer& getMomentumZBoundaryCondition() + { + return this->momentumZBoundaryConditionsPointer; + } + + EnergyBoundaryConditionsTypePointer& getEnergyBoundaryCondition() + { + return this->energyBoundaryConditionsPointer; + } + + + protected: + DensityBoundaryConditionsTypePointer densityBoundaryConditionsPointer; + MomentumXBoundaryConditionsTypePointer momentumXBoundaryConditionsPointer; + MomentumYBoundaryConditionsTypePointer momentumYBoundaryConditionsPointer; + MomentumZBoundaryConditionsTypePointer momentumZBoundaryConditionsPointer; + EnergyBoundaryConditionsTypePointer energyBoundaryConditionsPointer; + +}; + +} //namespace TNL diff --git a/examples/flow-sw/CMakeLists.txt b/examples/flow-sw/CMakeLists.txt new file mode 100644 index 0000000000..5cd2372ffc --- /dev/null +++ b/examples/flow-sw/CMakeLists.txt @@ -0,0 +1,23 @@ +set( tnl_flow_sw_HEADERS + CompressibleConservativeVariables.h ) + +set( tnl_flow_sw_SOURCES + navierStokes.cpp + navierStokes.cu ) + +IF( BUILD_CUDA ) + CUDA_ADD_EXECUTABLE(tnl-navier-stokes-sw${debugExt} navierStokes.cu) + target_link_libraries (tnl-navier-stokes-sw${debugExt} tnl${debugExt}-${tnlVersion} ${CUSPARSE_LIBRARY} ) +ELSE( BUILD_CUDA ) + ADD_EXECUTABLE(tnl-navier-stokes-sw${debugExt} navierStokes.cpp) + target_link_libraries (tnl-navier-stokes-sw${debugExt} tnl${debugExt}-${tnlVersion} ) +ENDIF( BUILD_CUDA ) + + +INSTALL( TARGETS tnl-navier-stokes-sw${debugExt} + RUNTIME DESTINATION bin + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE ) + +INSTALL( FILES run-navier-stokes-sw + ${tnl_inviscid_flow_SOURCES} + DESTINATION share/tnl-${tnlVersion}/examples/navier-stokes-sw ) diff --git a/examples/flow-sw/CompressibleConservativeVariables.h b/examples/flow-sw/CompressibleConservativeVariables.h new file mode 100644 index 0000000000..a3afc84536 --- /dev/null +++ b/examples/flow-sw/CompressibleConservativeVariables.h @@ -0,0 +1,147 @@ +/*************************************************************************** + CompressibleConservativeVariables.h - description + ------------------- + begin : Feb 12, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/MeshFunction.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/SharedPointer.h> + +namespace TNL { + +template< typename Mesh > +class CompressibleConservativeVariables +{ + public: + typedef Mesh MeshType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshType > MeshPointer; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > MomentumFieldPointer; + + CompressibleConservativeVariables(){}; + + CompressibleConservativeVariables( const MeshPointer& meshPointer ) + : density( meshPointer ), + momentum( meshPointer ), + //pressure( meshPointer ), + energy( meshPointer ){}; + + void setMesh( const MeshPointer& meshPointer ) + { + this->density->setMesh( meshPointer ); + this->momentum->setMesh( meshPointer ); + //this->pressure.setMesh( meshPointer ); + this->energy->setMesh( meshPointer ); + } + + template< typename Vector > + void bind( const MeshPointer& meshPointer, + const Vector& data, + IndexType offset = 0 ) + { + IndexType currentOffset( offset ); + this->density->bind( meshPointer, data, currentOffset ); + currentOffset += this->density->getDofs( meshPointer ); + for( IndexType i = 0; i < Dimensions; i++ ) + { + ( *this->momentum )[ i ]->bind( meshPointer, data, currentOffset ); + currentOffset += ( *this->momentum )[ i ]->getDofs( meshPointer ); + } + this->energy->bind( meshPointer, data, currentOffset ); + } + + IndexType getDofs( const MeshPointer& meshPointer ) const + { + return this->density->getDofs( meshPointer ) + + this->momentum->getDofs( meshPointer ) + + this->energy->getDofs( meshPointer ); + } + + MeshFunctionPointer& getDensity() + { + return this->density; + } + + const MeshFunctionPointer& getDensity() const + { + return this->density; + } + + void setDensity( MeshFunctionPointer& density ) + { + this->density = density; + } + + MomentumFieldPointer& getMomentum() + { + return this->momentum; + } + + const MomentumFieldPointer& getMomentum() const + { + return this->momentum; + } + + void setMomentum( MomentumFieldPointer& momentum ) + { + this->momentum = momentum; + } + + /*MeshFunctionPointer& getPressure() + { + return this->pressure; + } + + const MeshFunctionPointer& getPressure() const + { + return this->pressure; + } + + void setPressure( MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }*/ + + MeshFunctionPointer& getEnergy() + { + return this->energy; + } + + const MeshFunctionPointer& getEnergy() const + { + return this->energy; + } + + void setEnergy( MeshFunctionPointer& energy ) + { + this->energy = energy; + } + + void getVelocityField( VelocityFieldType& velocityField ) + { + + } + + protected: + + MeshFunctionPointer density; + MomentumFieldPointer momentum; + MeshFunctionPointer energy; + +}; + +} // namespace TN \ No newline at end of file diff --git a/examples/flow-sw/DensityBoundaryConditionBoiler.h b/examples/flow-sw/DensityBoundaryConditionBoiler.h new file mode 100644 index 0000000000..c3bae7e3d9 --- /dev/null +++ b/examples/flow-sw/DensityBoundaryConditionBoiler.h @@ -0,0 +1,542 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class DensityBoundaryConditionsBoiler +{ + +}; + +/**** + * Base + */ +template< typename Function > +class DensityBoundaryConditionsBoilerBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class DensityBoundaryConditionsBoiler< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public DensityBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef DensityBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef DensityBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return u[ neighborEntities.template getEntityIndex< 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType gamma; + MeshFunctionPointer pressure; + +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class DensityBoundaryConditionsBoiler< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public DensityBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef DensityBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef DensityBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if (entity.getCoordinates().y() < 0.8 * ( entity.getMesh().getDimensions().y() - 1 ) && false) + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, -1 >() ]; + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType gamma; + MeshFunctionPointer pressure; + +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class DensityBoundaryConditionsBoiler< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public DensityBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef DensityBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef DensityBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if (entity.getCoordinates().z() < 0.8 * ( entity.getMesh().getDimensions().z() - 1 ) ) + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType gamma; + MeshFunctionPointer pressure; + +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const DensityBoundaryConditionsBoiler< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionBoilers: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/DensityBoundaryConditionCavity.h b/examples/flow-sw/DensityBoundaryConditionCavity.h new file mode 100644 index 0000000000..a2d34ce540 --- /dev/null +++ b/examples/flow-sw/DensityBoundaryConditionCavity.h @@ -0,0 +1,536 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class DensityBoundaryConditionsCavity +{ + +}; + +/**** + * Base + */ +template< typename Function > +class DensityBoundaryConditionsCavityBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class DensityBoundaryConditionsCavity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public DensityBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef DensityBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef DensityBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return u[ neighborEntities.template getEntityIndex< 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType gamma; + MeshFunctionPointer pressure; + +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class DensityBoundaryConditionsCavity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public DensityBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef DensityBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef DensityBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType gamma; + MeshFunctionPointer pressure; + +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class DensityBoundaryConditionsCavity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public DensityBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef DensityBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef DensityBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType gamma; + MeshFunctionPointer pressure; + +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const DensityBoundaryConditionsCavity< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsCavity: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/EnergyBoundaryConditionBoiler.h b/examples/flow-sw/EnergyBoundaryConditionBoiler.h new file mode 100644 index 0000000000..fe227d68f8 --- /dev/null +++ b/examples/flow-sw/EnergyBoundaryConditionBoiler.h @@ -0,0 +1,854 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> +#include "CompressibleConservativeVariables.h" + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class EnergyBoundaryConditionsBoiler +{ + +}; + +/**** + * Base + */ +template< typename Function> +class EnergyBoundaryConditionsBoilerBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class EnergyBoundaryConditionsBoiler< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public EnergyBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef EnergyBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef EnergyBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class EnergyBoundaryConditionsBoiler< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public EnergyBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef EnergyBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef EnergyBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + if( ( entity.getCoordinates().y() < 0.20 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.19 * ( entity.getMesh().getDimensions().y() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + this->cavitySpeed + * + this->cavitySpeed + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + ); + else + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 1, 0 >()] + + 0 + ) + * + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 1, 0 >()] + + 0 + ) + );*/ + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if( ( entity.getCoordinates().y() < 0.20 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.19 * ( entity.getMesh().getDimensions().y() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + this->cavitySpeed * ( -1 ) + * + this->cavitySpeed * ( -1 ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + ); + else if( entity.getCoordinates().y() > 0.8 * ( entity.getMesh().getDimensions().y() - 1 ) && false ) + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< -1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< -1, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< -1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< -1, 0 >()] + + 0 + ) + );*/ + } + if( entity.getCoordinates().y() == 0 ) + { + if( ( entity.getCoordinates().x() < 0.6 * ( entity.getMesh().getDimensions().x() - 1 ) ) && ( entity.getCoordinates().x() > 0.4 * ( entity.getMesh().getDimensions().x() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + + + this->cavitySpeed + * + this->cavitySpeed + ); + else + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 1 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 1 >()] + + 0 + ) + );*/ + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, -1 >() ]; + /*return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, -1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, -1 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, -1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, -1 >()] + + 0 + ) + );*/ + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class EnergyBoundaryConditionsBoiler< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public EnergyBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef EnergyBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef EnergyBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + if( ( entity.getCoordinates().y() < 0.59 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.39 * ( entity.getMesh().getDimensions().y() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed + * + this->cavitySpeed + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + ); + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if( ( entity.getCoordinates().y() < 0.59 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.39 * ( entity.getMesh().getDimensions().y() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed * ( -1 ) + * + this->cavitySpeed * ( -1 ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + ); + else if( entity.getCoordinates().y() >0.8 * ( entity.getMesh().getDimensions().y() - 1 ) ) + return u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + if( ( entity.getCoordinates().x() < 0.59 * ( entity.getMesh().getDimensions().x() - 1 ) ) && ( entity.getCoordinates().x() > 0.39 * ( entity.getMesh().getDimensions().x() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed + * + this->cavitySpeed + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + ); + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + if( ( entity.getCoordinates().x() < 0.59 * ( entity.getMesh().getDimensions().x() - 1 ) ) && ( entity.getCoordinates().x() > 0.39 * ( entity.getMesh().getDimensions().x() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed * ( -1 ) + * + this->cavitySpeed * ( -1 ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + ); + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) +{ + if( ( entity.getCoordinates().x() < 0.6 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.4 * ( entity.getMesh().getDimensions().y() - 1 ) ) + &&( entity.getCoordinates().y() < 0.6 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.4 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * + ( + ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + + + ( + this->cavitySpeed + * + this->cavitySpeed + ) + ); + + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const EnergyBoundaryConditionsBoiler< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsBoiler: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/EnergyBoundaryConditionCavity.h b/examples/flow-sw/EnergyBoundaryConditionCavity.h new file mode 100644 index 0000000000..ca3fbe01de --- /dev/null +++ b/examples/flow-sw/EnergyBoundaryConditionCavity.h @@ -0,0 +1,673 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> +#include "CompressibleConservativeVariables.h" + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class EnergyBoundaryConditionsCavity +{ + +}; + +/**** + * Base + */ +template< typename Function> +class EnergyBoundaryConditionsCavityBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class EnergyBoundaryConditionsCavity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public EnergyBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef EnergyBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef EnergyBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class EnergyBoundaryConditionsCavity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public EnergyBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef EnergyBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef EnergyBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /* ( (* this->pressure)[ neighborEntities.template getEntityIndex< 1, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 1, 0 >()] + * ( + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 1, 0 >()] + + 0 + ) + * + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 1, 0 >()] + + 0 + ) + )*/; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /* ( (* this->pressure)[ neighborEntities.template getEntityIndex< -1, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< -1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< -1, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< -1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< -1, 0 >()] + + 0 + ) + )*/; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /* ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 1 >() ] + / ( this->gamma - 1 ) + ) + + 0 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 1 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 1 >()] + + 0 + ) + )*/; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, -1 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, -1 >()] + * ( + this->cavitySpeed/* + * ( + entity.getMesh().getDimensions().x() / 2 - std::abs( (entity.getCoordinates().x() - entity.getMesh().getDimensions().x() / 2 ) ) + ) + / ( entity.getMesh().getDimensions().x() / 2 )*/ + * + this->cavitySpeed/* + * ( + entity.getMesh().getDimensions().x() / 2 - std::abs( (entity.getCoordinates().x() - entity.getMesh().getDimensions().x() / 2 ) ) + ) + / ( entity.getMesh().getDimensions().x() / 2 )*/ + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + + 0 + ) + ); + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class EnergyBoundaryConditionsCavity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public EnergyBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef EnergyBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef EnergyBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return ( (* this->pressure)[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ] + / ( this->gamma - 1 ) + ) + + 0.5 + * (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + ( this->cavitySpeed + * ( + entity.getMesh().getDimensions().x() / 2 - std::abs( (entity.getCoordinates().x() - entity.getMesh().getDimensions().x() / 2 ) ) + ) + / ( entity.getMesh().getDimensions().x() / 2 ) + ) + * + ( this->cavitySpeed + * ( + entity.getMesh().getDimensions().x() / 2 - std::abs( (entity.getCoordinates().x() - entity.getMesh().getDimensions().x() / 2 ) ) + ) + / ( entity.getMesh().getDimensions().x() / 2 ) + ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + + + ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 2 ])[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + + 0 + ) + ); + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const EnergyBoundaryConditionsCavity< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsCavity: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/LaxFridrichs.h b/examples/flow-sw/LaxFridrichs.h new file mode 100644 index 0000000000..cdf32899f6 --- /dev/null +++ b/examples/flow-sw/LaxFridrichs.h @@ -0,0 +1,141 @@ +/*************************************************************************** + LaxFridrichs.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> + +#include "LaxFridrichsContinuity.h" +#include "LaxFridrichsEnergy.h" +#include "LaxFridrichsMomentumX.h" +#include "LaxFridrichsMomentumY.h" +#include "LaxFridrichsMomentumZ.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichs +{ + public: + typedef Mesh MeshType; + typedef Real RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + static const int Dimensions = Mesh::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VectorFieldType; + + typedef LaxFridrichsContinuity< Mesh, Real, Index > ContinuityOperatorType; + typedef LaxFridrichsMomentumX< Mesh, Real, Index > MomentumXOperatorType; + typedef LaxFridrichsMomentumY< Mesh, Real, Index > MomentumYOperatorType; + typedef LaxFridrichsMomentumZ< Mesh, Real, Index > MomentumZOperatorType; + typedef LaxFridrichsEnergy< Mesh, Real, Index > EnergyOperatorType; + + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VectorFieldType > VectorFieldPointer; + typedef SharedPointer< MeshType > MeshPointer; + + typedef SharedPointer< ContinuityOperatorType > ContinuityOperatorPointer; + typedef SharedPointer< MomentumXOperatorType > MomentumXOperatorPointer; + typedef SharedPointer< MomentumYOperatorType > MomentumYOperatorPointer; + typedef SharedPointer< MomentumZOperatorType > MomentumZOperatorPointer; + typedef SharedPointer< EnergyOperatorType > EnergyOperatorPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + LaxFridrichs() + : artificialViscosity( 1.0 ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + this->continuityOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->momentumXOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->momentumYOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->momentumZOperatorPointer->setArtificialViscosity( artificialViscosity ); + this->energyOperatorPointer->setArtificialViscosity( artificialViscosity ); + + return true; + } + + void setTau( const RealType& tau ) + { + this->continuityOperatorPointer->setTau( tau ); + this->momentumXOperatorPointer->setTau( tau ); + this->momentumYOperatorPointer->setTau( tau ); + this->momentumZOperatorPointer->setTau( tau ); + this->energyOperatorPointer->setTau( tau ); + } + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->momentumXOperatorPointer->setPressure( pressure ); + this->momentumYOperatorPointer->setPressure( pressure ); + this->momentumZOperatorPointer->setPressure( pressure ); + this->energyOperatorPointer->setPressure( pressure ); + } + + void setVelocity( const VectorFieldPointer& velocity ) + { + this->continuityOperatorPointer->setVelocity( velocity ); + this->momentumXOperatorPointer->setVelocity( velocity ); + this->momentumYOperatorPointer->setVelocity( velocity ); + this->momentumZOperatorPointer->setVelocity( velocity ); + this->energyOperatorPointer->setVelocity( velocity ); + } + + const ContinuityOperatorPointer& getContinuityOperator() const + { + return this->continuityOperatorPointer; + } + + const MomentumXOperatorPointer& getMomentumXOperator() const + { + return this->momentumXOperatorPointer; + } + + const MomentumYOperatorPointer& getMomentumYOperator() const + { + return this->momentumYOperatorPointer; + } + + const MomentumZOperatorPointer& getMomentumZOperator() const + { + return this->momentumZOperatorPointer; + } + + const EnergyOperatorPointer& getEnergyOperator() const + { + return this->energyOperatorPointer; + } + + protected: + + ContinuityOperatorPointer continuityOperatorPointer; + MomentumXOperatorPointer momentumXOperatorPointer; + MomentumYOperatorPointer momentumYOperatorPointer; + MomentumZOperatorPointer momentumZOperatorPointer; + EnergyOperatorPointer energyOperatorPointer; + + RealType artificialViscosity; +}; + +} //namespace TNL diff --git a/examples/flow-sw/LaxFridrichsContinuity.h b/examples/flow-sw/LaxFridrichsContinuity.h new file mode 100644 index 0000000000..45ad4d52b1 --- /dev/null +++ b/examples/flow-sw/LaxFridrichsContinuity.h @@ -0,0 +1,288 @@ +/*************************************************************************** + LaxFridrichsContinuity.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/SharedPointer.h> + +namespace TNL { + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsContinuityBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + LaxFridrichsContinuityBase() + : artificialViscosity( 1.0 ){}; + + static String getType() + { + return String( "LaxFridrichsContinuity< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setArtificialViscosity( const RealType& artificialViscosity ) + { + this->artificialViscosity = artificialViscosity; + } + + + protected: + + RealType tau; + + VelocityFieldPointer velocity; + + RealType artificialViscosity; +}; + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsContinuity +{ +}; + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsContinuityBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + return 1.0 / ( 2.0 * this->tau ) * this->artificialViscosity * ( u[ west ] - 2.0 * u[ center ] + u[ east ] ) + - 0.5 * ( u[ east ] * velocity_x_east - u[ west ] * velocity_x_west ) * hxInverse; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsContinuity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsContinuityBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + //rho + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / ( 4.0 * this->tau ) * this->artificialViscosity * ( u[ west ] + u[ east ] + u[ south ] + u[ north ] - 4.0 * u[ center ] ) + - 0.5 * ( ( u[ east ] * velocity_x_east - u[ west ] * velocity_x_west ) * hxInverse + + ( u[ north ] * velocity_y_north - u[ south ] * velocity_y_south ) * hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsContinuity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsContinuityBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + //rho + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + + return 1.0 / ( 6.0 * this->tau ) * this->artificialViscosity * + ( u[ west ] + u[ east ] + u[ south ] + u[ north ] + u[ up ] + u[ down ]- 6.0 * u[ center ] ) + - 0.5 * ( ( u[ east ] * velocity_x_east - u[ west ] * velocity_x_west ) * hxInverse + + ( u[ north ] * velocity_y_north - u[ south ] * velocity_y_south ) * hyInverse + + ( u[ up ] * velocity_z_up - u[ down ] * velocity_z_down ) * hzInverse ); + + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} //namespace TNL diff --git a/examples/flow-sw/LaxFridrichsEnergy.h b/examples/flow-sw/LaxFridrichsEnergy.h new file mode 100644 index 0000000000..18c824762b --- /dev/null +++ b/examples/flow-sw/LaxFridrichsEnergy.h @@ -0,0 +1,309 @@ +/*************************************************************************** + LaxFridrichsEnergy.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsEnergyBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + LaxFridrichsEnergyBase() + : artificialViscosity( 1.0 ){}; + + static String getType() + { + return String( "LaxFridrichsEnergy< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }; + + void setArtificialViscosity( const RealType& artificialViscosity ) + { + this->artificialViscosity = artificialViscosity; + } + + protected: + + RealType tau; + + VelocityFieldPointer velocity; + + MeshFunctionPointer pressure; + + RealType artificialViscosity; +}; + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsEnergy +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsEnergyBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& e, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + return 1.0 / ( 2.0 * this->tau ) * this->artificialViscosity * ( e[ west ] - 2.0 * e[ center ] + e[ east ] ) + - 0.5 * ( ( e[ east ] + pressure_east ) * velocity_x_east + - ( e[ west ] + pressure_west ) * velocity_x_west ) * hxInverse; + + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsEnergyBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& e, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / ( 4.0 * this->tau ) * this->artificialViscosity * ( e[ west ] + e[ east ] + e[ south ] + e[ north ] - 4.0 * e[ center ] ) + - 0.5 * ( ( ( ( e[ east ] + pressure_east ) * velocity_x_east ) + -( ( e[ west ] + pressure_west ) * velocity_x_west ) ) * hxInverse + + ( ( ( e[ north ] + pressure_north ) * velocity_y_north ) + -( ( e[ south ] + pressure_south ) * velocity_y_south ) ) * hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsEnergyBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& e, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + + return 1.0 / ( 6.0 * this->tau ) * this->artificialViscosity * + ( e[ west ] + e[ east ] + e[ south ] + e[ north ] + e[ up ] + e[ down ] - 6.0 * e[ center ] ) + - 0.5 * ( ( ( ( e[ east ] + pressure_east ) * velocity_x_east ) + -( ( e[ west ] + pressure_west ) * velocity_x_west ) ) * hxInverse + + ( ( ( e[ north ] + pressure_north ) * velocity_y_north ) + -( ( e[ south ] + pressure_south ) * velocity_y_south ) ) * hyInverse + + ( ( ( e[ up ] + pressure_up ) * velocity_z_up ) + -( ( e[ down ] + pressure_down ) * velocity_z_down ) ) * hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +} //namespace TNL diff --git a/examples/flow-sw/LaxFridrichsMomentumBase.h b/examples/flow-sw/LaxFridrichsMomentumBase.h new file mode 100644 index 0000000000..67dae9fdf8 --- /dev/null +++ b/examples/flow-sw/LaxFridrichsMomentumBase.h @@ -0,0 +1,68 @@ +/*************************************************************************** + LaxFridrichsMomentumBase.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + LaxFridrichsMomentumBase() + : artificialViscosity( 1.0 ){}; + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }; + + void setArtificialViscosity( const RealType& artificialViscosity ) + { + this->artificialViscosity = artificialViscosity; + } + + protected: + + RealType tau; + + VelocityFieldPointer velocity; + + MeshFunctionPointer pressure; + + RealType artificialViscosity; +}; + +} //namespace TNL diff --git a/examples/flow-sw/LaxFridrichsMomentumX.h b/examples/flow-sw/LaxFridrichsMomentumX.h new file mode 100644 index 0000000000..63def12d31 --- /dev/null +++ b/examples/flow-sw/LaxFridrichsMomentumX.h @@ -0,0 +1,276 @@ +/*************************************************************************** + LaxFridrichsMomentumX.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "LaxFridrichsMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumX +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumX< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + + return 1.0 / ( 2.0 * this->tau ) * this->artificialViscosity * ( rho_u[ west ] + rho_u[ east ] - 2.0 * rho_u[ center ] ) + - 0.5 * ( ( rho_u[ east ] * velocity_x_east + pressure_east ) + -( rho_u[ west ] * velocity_x_west + pressure_west ) ) * hxInverse; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumX< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / ( 4.0 * this->tau ) * this->artificialViscosity * ( rho_u[ west ] + rho_u[ east ] + rho_u[ south ] + rho_u[ north ] - 4.0 * rho_u[ center ] ) + - 0.5 * ( ( ( rho_u[ east ] * velocity_x_east + pressure_east ) + - ( rho_u[ west ] * velocity_x_west + pressure_west ) ) * hxInverse + + ( ( rho_u[ north ] * velocity_y_north ) + - ( rho_u[ south ] * velocity_y_south ) ) * hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumX< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + //const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + //const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + //const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + //const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + return 1.0 / ( 6.0 * this->tau ) * this->artificialViscosity * + ( rho_u[ west ] + rho_u[ east ] + rho_u[ south ] + rho_u[ north ] + rho_u[ up ] + rho_u[ down ] - 6.0 * rho_u[ center ] ) + - 0.5 * ( ( ( rho_u[ east ] * velocity_x_east + pressure_east ) + - ( rho_u[ west ] * velocity_x_west + pressure_west ) )* hxInverse + + ( ( rho_u[ north ] * velocity_y_north ) + - ( rho_u[ south ] * velocity_y_south ) )* hyInverse + + ( ( rho_u[ up ] * velocity_z_up ) + - ( rho_u[ down ] * velocity_z_down ) )* hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} // namespace TNL + diff --git a/examples/flow-sw/LaxFridrichsMomentumY.h b/examples/flow-sw/LaxFridrichsMomentumY.h new file mode 100644 index 0000000000..8ce42282dd --- /dev/null +++ b/examples/flow-sw/LaxFridrichsMomentumY.h @@ -0,0 +1,260 @@ +/*************************************************************************** + LaxFridrichsMomentumY.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "LaxFridrichsMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumY +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumY< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_v, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + //const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumY< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_v, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return 1.0 / ( 4.0 * this->tau ) * this->artificialViscosity * ( rho_v[ west ] + rho_v[ east ] + rho_v[ south ] + rho_v[ north ] - 4.0 * rho_v[ center ] ) + - 0.5 * ( ( ( rho_v[ east ] * velocity_x_east ) + - ( rho_v[ west ] * velocity_x_west ) )* hxInverse + + ( ( rho_v[ north ] * velocity_y_north + pressure_north ) + - ( rho_v[ south ] * velocity_y_south + pressure_south ) )* hyInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumY< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_v, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + return 1.0 / ( 6.0 * this->tau ) * this->artificialViscosity * + ( rho_v[ west ] + rho_v[ east ] + rho_v[ south ] + rho_v[ north ] + rho_v[ up ] + rho_v[ down ] - 6.0 * rho_v[ center ] ) + - 0.5 * ( ( ( rho_v[ east ] * velocity_x_east ) + - ( rho_v[ west ] * velocity_x_west ) ) * hxInverse + + ( ( rho_v[ north ] * velocity_y_north + pressure_north ) + - ( rho_v[ south ] * velocity_y_south + pressure_south ) ) * hyInverse + + ( ( rho_v[ up ] * velocity_z_up ) + - ( rho_v[ down ] * velocity_z_down ) ) * hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} // namespace TNL + diff --git a/examples/flow-sw/LaxFridrichsMomentumZ.h b/examples/flow-sw/LaxFridrichsMomentumZ.h new file mode 100644 index 0000000000..a67e862cef --- /dev/null +++ b/examples/flow-sw/LaxFridrichsMomentumZ.h @@ -0,0 +1,240 @@ +/*************************************************************************** + LaxFridrichsMomentumZ.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "LaxFridrichsMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class LaxFridrichsMomentumZ +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumZ< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + //const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumZ< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + //const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class LaxFridrichsMomentumZ< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public LaxFridrichsMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef LaxFridrichsMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "LaxFridrichsMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + return 1.0 / ( 6.0 * this->tau ) * this->artificialViscosity * + ( rho_w[ west ] + rho_w[ east ] + rho_w[ south ] + rho_w[ north ] + rho_w[ up ] + rho_w[ down ] - 6.0 * rho_w[ center ] ) + -0.5 * ( ( ( rho_w[ east ] * velocity_x_east ) + - ( rho_w[ west ] * velocity_x_west ) )* hxInverse + + ( ( rho_w[ north ] * velocity_y_north ) + - ( rho_w[ south ] * velocity_y_south ) )* hyInverse + + ( ( rho_w[ up ] * velocity_z_up + pressure_up ) + - ( rho_w[ down ] * velocity_z_down + pressure_down ) )* hzInverse ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} // namespace TNL + diff --git a/examples/flow-sw/MomentumXBoundaryConditionBoiler.h b/examples/flow-sw/MomentumXBoundaryConditionBoiler.h new file mode 100644 index 0000000000..823ec475a5 --- /dev/null +++ b/examples/flow-sw/MomentumXBoundaryConditionBoiler.h @@ -0,0 +1,594 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class MomentumXBoundaryConditionsBoiler +{ + +}; + +/**** + * Base + */ +template< typename Function > +class MomentumXBoundaryConditionsBoilerBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumXBoundaryConditionsBoiler< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumXBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumXBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumXBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumXBoundaryConditionsBoiler< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumXBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumXBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumXBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + if( ( entity.getCoordinates().y() < 0.20 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.19 * ( entity.getMesh().getDimensions().y() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + this->cavitySpeed + ); + else + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if( ( entity.getCoordinates().y() < 0.20 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.19 * ( entity.getMesh().getDimensions().y() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + this->cavitySpeed * ( -1 ) + ); + else if( entity.getCoordinates().y() > 0.8 * ( entity.getMesh().getDimensions().y() - 1 ) && false ) + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*(* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 1 >()] + );*/ + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, -1 >() ]; + /*return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, -1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, -1 >()] + );*/ + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumXBoundaryConditionsBoiler< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumXBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumXBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumXBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + if( ( entity.getCoordinates().y() < 0.59 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.39 * ( entity.getMesh().getDimensions().y() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed + ); + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if( ( entity.getCoordinates().y() < 0.59 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.39 * ( entity.getMesh().getDimensions().y() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed * ( -1 ) + ); + else if( entity.getCoordinates().y() >0.8 * ( entity.getMesh().getDimensions().y() - 1 ) ) + return u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const MomentumXBoundaryConditionsBoiler< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsBoiler: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/MomentumXBoundaryConditionCavity.h b/examples/flow-sw/MomentumXBoundaryConditionCavity.h new file mode 100644 index 0000000000..b787313827 --- /dev/null +++ b/examples/flow-sw/MomentumXBoundaryConditionCavity.h @@ -0,0 +1,570 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class MomentumXBoundaryConditionsCavity +{ + +}; + +/**** + * Base + */ +template< typename Function > +class MomentumXBoundaryConditionsCavityBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumXBoundaryConditionsCavity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumXBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumXBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumXBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumXBoundaryConditionsCavity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumXBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumXBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumXBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*(* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0, 1 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 1 >()] + );*/ + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, -1 >()] + * ( + ( this->cavitySpeed/* + * ( + entity.getMesh().getDimensions().x() / 2 - std::abs( (entity.getCoordinates().x() - entity.getMesh().getDimensions().x() / 2 ) ) + ) + / ( entity.getMesh().getDimensions().x() / 2 )*/ + ) + ); + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumXBoundaryConditionsCavity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumXBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumXBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumXBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed + ); + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const MomentumXBoundaryConditionsCavity< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsCavity: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/MomentumYBoundaryConditionBoiler.h b/examples/flow-sw/MomentumYBoundaryConditionBoiler.h new file mode 100644 index 0000000000..76f3ff0573 --- /dev/null +++ b/examples/flow-sw/MomentumYBoundaryConditionBoiler.h @@ -0,0 +1,588 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class MomentumYBoundaryConditionsBoiler +{ + +}; + +/**** + * Base + */ +template< typename Function > +class MomentumYBoundaryConditionsBoilerBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumYBoundaryConditionsBoiler< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumYBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumYBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumYBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumYBoundaryConditionsBoiler< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumYBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumYBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumYBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*(* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 1, 0 >()] + );*/ + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if( entity.getCoordinates().y() > 0.8 * ( entity.getMesh().getDimensions().y() - 1 ) && false) + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*(* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< -1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< -1, 0 >()] + );*/ + } + if( entity.getCoordinates().y() == 0 ) + { + if( ( entity.getCoordinates().x() < 0.6 * ( entity.getMesh().getDimensions().x() - 1 ) ) && ( entity.getCoordinates().x() > 0.4 * ( entity.getMesh().getDimensions().x() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + this->cavitySpeed + ); + else return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, -1 >() ]; + /*return u[ neighborEntities.template getEntityIndex< 0, 0 >() ];*/ + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumYBoundaryConditionsBoiler< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumYBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumYBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumYBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if( entity.getCoordinates().y() >0.8 * ( entity.getMesh().getDimensions().y() - 1 ) ) + return u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + if( ( entity.getCoordinates().x() < 0.59 * ( entity.getMesh().getDimensions().x() - 1 ) ) && ( entity.getCoordinates().x() > 0.39 * ( entity.getMesh().getDimensions().x() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed + ); + else return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + if( ( entity.getCoordinates().x() < 0.59 * ( entity.getMesh().getDimensions().x() - 1 ) ) && ( entity.getCoordinates().x() > 0.39 * ( entity.getMesh().getDimensions().x() - 1 ) ) + &&( entity.getCoordinates().z() < 0.59 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.39 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed * ( -1 ) + ); + else return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const MomentumYBoundaryConditionsBoiler< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsBoiler: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/MomentumYBoundaryConditionCavity.h b/examples/flow-sw/MomentumYBoundaryConditionCavity.h new file mode 100644 index 0000000000..afce8239b7 --- /dev/null +++ b/examples/flow-sw/MomentumYBoundaryConditionCavity.h @@ -0,0 +1,564 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class MomentumYBoundaryConditionsCavity +{ + +}; + +/**** + * Base + */ +template< typename Function > +class MomentumYBoundaryConditionsCavityBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumYBoundaryConditionsCavity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumYBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumYBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumYBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumYBoundaryConditionsCavity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumYBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumYBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumYBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*(* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< 1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 1, 0 >()] + );*/ + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + /*(* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0 >()] + * ( + (* (* this->compressibleConservativeVariables->getMomentum())[ 1 ])[neighborEntities.template getEntityIndex< -1, 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< -1, 0 >()] + );*/ + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumYBoundaryConditionsCavity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumYBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumYBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumYBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const MomentumYBoundaryConditionsCavity< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsCavity: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/MomentumZBoundaryConditionBoiler.h b/examples/flow-sw/MomentumZBoundaryConditionBoiler.h new file mode 100644 index 0000000000..188aaa9851 --- /dev/null +++ b/examples/flow-sw/MomentumZBoundaryConditionBoiler.h @@ -0,0 +1,563 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class MomentumZBoundaryConditionsBoiler +{ + +}; + +/**** + * Base + */ +template< typename Function > +class MomentumZBoundaryConditionsBoilerBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumZBoundaryConditionsBoiler< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumZBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumZBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumZBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumZBoundaryConditionsBoiler< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumZBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumZBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumZBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< -0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumZBoundaryConditionsBoiler< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumZBoundaryConditionsBoilerBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumZBoundaryConditionsBoiler< MeshType, Function, Real, Index > ThisType; + typedef MomentumZBoundaryConditionsBoilerBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + if( entity.getCoordinates().y() >0.8 * ( entity.getMesh().getDimensions().y() - 1 ) ) + return u[ neighborEntities.template getEntityIndex< -1, 0, 0 >() ]; + else + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + if( ( entity.getCoordinates().x() < 0.6 * ( entity.getMesh().getDimensions().y() - 1 ) ) && ( entity.getCoordinates().y() > 0.4 * ( entity.getMesh().getDimensions().y() - 1 ) ) + &&( entity.getCoordinates().y() < 0.6 * ( entity.getMesh().getDimensions().z() - 1 ) ) && ( entity.getCoordinates().z() > 0.4 * ( entity.getMesh().getDimensions().z() - 1 ) ) ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0, 0, 0 >()] + * ( + this->cavitySpeed + ); + else return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const MomentumZBoundaryConditionsBoiler< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsBoiler: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/MomentumZBoundaryConditionCavity.h b/examples/flow-sw/MomentumZBoundaryConditionCavity.h new file mode 100644 index 0000000000..1942cd5893 --- /dev/null +++ b/examples/flow-sw/MomentumZBoundaryConditionCavity.h @@ -0,0 +1,554 @@ +/*************************************************************************** + IdentityOperator.h - description + ------------------- + begin : Nov 17, 2014 + copyright : (C) 2014 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Functions/FunctionAdapter.h> + +namespace TNL { +namespace Operators { + +template< typename Mesh, + typename Function, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::GlobalIndexType > +class MomentumZBoundaryConditionsCavity +{ + +}; + +/**** + * Base + */ +template< typename Function > +class MomentumZBoundaryConditionsCavityBase +{ + public: + + typedef Function FunctionType; + + static void configSetup( const Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + } + + template< typename MeshPointer > + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return Functions::FunctionAdapter< typename MeshPointer::ObjectType, FunctionType >::setup( this->function, meshPointer, parameters, prefix ); + } + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + Function::configSetup( config, prefix ); + }; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return this->function.setup( parameters, prefix ); + }; + + void setFunction( const FunctionType& function ) + { + this->function = function; + }; + + FunctionType& getFunction() + { + return this->function; + } + + const FunctionType& getFunction() const + { + return this->function; + }; + + protected: + + FunctionType function; + +}; + +/**** + * 1D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumZBoundaryConditionsCavity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumZBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 1, 1, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 1, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumZBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumZBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + return (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + * ( (* (* this->compressibleConservativeVariables->getMomentum())[ 0 ])[neighborEntities.template getEntityIndex< 0 >()] + / (* this->compressibleConservativeVariables->getDensity())[neighborEntities.template getEntityIndex< 0 >()] + + this->timestep + ); + else + return u[ neighborEntities.template getEntityIndex< -1 >() ]; + + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + else + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 2D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumZBoundaryConditionsCavity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumZBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 2, 2, + Real, + Index > + +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 2, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumZBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumZBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< -0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0 >() ]; + } + } + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +/**** + * 3D grid + */ +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Function, + typename Real, + typename Index > +class MomentumZBoundaryConditionsCavity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Function, Real, Index > + : public MomentumZBoundaryConditionsCavityBase< Function >, + public Operator< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, + Functions::MeshBoundaryDomain, + 3, 3, + Real, + Index > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + typedef Function FunctionType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef Containers::Vector< RealType, DeviceType, IndexType> DofVectorType; + typedef Containers::StaticVector< 3, RealType > PointType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef MomentumZBoundaryConditionsCavity< MeshType, Function, Real, Index > ThisType; + typedef MomentumZBoundaryConditionsCavityBase< Function > BaseType; + typedef CompressibleConservativeVariables< MeshType > CompressibleConservativeVariablesType; + typedef SharedPointer< CompressibleConservativeVariablesType > CompressibleConservativeVariablesPointer; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + + template< typename EntityType, + typename MeshFunction > + __cuda_callable__ + const RealType operator()( const MeshFunction& u, + const EntityType& entity, + const RealType& time = 0 ) const + { + const MeshType& mesh = entity.getMesh(); + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + if( entity.getCoordinates().x() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + if( entity.getCoordinates().z() == 0 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + // The following line is commented to avoid compiler warning + //if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + return u[ neighborEntities.template getEntityIndex< 0, 0, 0 >() ]; + } + } + + + template< typename EntityType > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const EntityType& entity ) const + { + return 2; + } + + template< typename PreimageFunction, + typename MeshEntity, + typename Matrix, + typename Vector > + __cuda_callable__ + void setMatrixElements( const PreimageFunction& u, + const MeshEntity& entity, + const RealType& time, + const RealType& tau, + Matrix& matrix, + Vector& b ) const + { + const auto& neighborEntities = entity.getNeighborEntities(); + const IndexType& index = entity.getIndex(); + typename Matrix::MatrixRow matrixRow = matrix.getRow( index ); + if( entity.getCoordinates().x() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 1, 0, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().x() == entity.getMesh().getDimensions().x() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< -1, 0, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().x() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 1, 0 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().y() == entity.getMesh().getDimensions().y() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, -1, 0 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().y() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == 0 ) + { + matrixRow.setElement( 0, index, 1.0 ); + matrixRow.setElement( 1, neighborEntities.template getEntityIndex< 0, 0, 1 >(), -1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + if( entity.getCoordinates().z() == entity.getMesh().getDimensions().z() - 1 ) + { + matrixRow.setElement( 0, neighborEntities.template getEntityIndex< 0, 0, -1 >(), -1.0 ); + matrixRow.setElement( 1, index, 1.0 ); + b[ index ] = entity.getMesh().getSpaceSteps().z() * + Functions::FunctionAdapter< MeshType, FunctionType >::getValue( this->function, entity, time ); + } + } + + void setTimestep(const RealType timestep ) + { + this->timestep = timestep; + } + + void setGamma(const RealType gamma ) + { + this->gamma = gamma; + } + + void setCompressibleConservativeVariables(const CompressibleConservativeVariablesPointer& compressibleConservativeVariables) + { + this->compressibleConservativeVariables = compressibleConservativeVariables; + } + + void setPressure(const MeshFunctionPointer& pressure) + { + this->pressure = pressure; + } + + void setCavitySpeed(const RealType cavitySpeed) + { + this->cavitySpeed = cavitySpeed; + } + + private: + CompressibleConservativeVariablesPointer compressibleConservativeVariables; + RealType timestep; + RealType cavitySpeed; + RealType gamma; + MeshFunctionPointer pressure; +}; + +template< typename Mesh, + typename Function, + typename Real, + typename Index > +std::ostream& operator << ( std::ostream& str, const MomentumZBoundaryConditionsCavity< Mesh, Function, Real, Index >& bc ) +{ + str << "Neumann boundary ConditionsCavity: function = " << bc.getFunction(); + return str; +} + +} // namespace Operators +} // namespace TNL + diff --git a/examples/flow-sw/PhysicalVariablesGetter.h b/examples/flow-sw/PhysicalVariablesGetter.h new file mode 100644 index 0000000000..f1ba6bd122 --- /dev/null +++ b/examples/flow-sw/PhysicalVariablesGetter.h @@ -0,0 +1,122 @@ +/*************************************************************************** + CompressibleConservativeVariables.h - description + ------------------- + begin : Feb 12, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/SharedPointer.h> +#include <TNL/Functions/MeshFunction.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/Functions/MeshFunctionEvaluator.h> +#include "CompressibleConservativeVariables.h" + +namespace TNL { + +template< typename Mesh > +class PhysicalVariablesGetter +{ + public: + + typedef Mesh MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + static const int Dimensions = MeshType::getMeshDimension(); + + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef CompressibleConservativeVariables< MeshType > ConservativeVariablesType; + typedef SharedPointer< ConservativeVariablesType > ConservativeVariablesPointer; + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + class VelocityGetter : public Functions::Domain< Dimensions, Functions::MeshDomain > + { + public: + typedef typename MeshType::RealType RealType; + + VelocityGetter( MeshFunctionPointer density, + MeshFunctionPointer momentum ) + : density( density ), momentum( momentum ) {} + + template< typename EntityType > + __cuda_callable__ + RealType operator()( const EntityType& meshEntity, + const RealType& time = 0.0 ) const + { + if( density.template getData< DeviceType >()( meshEntity ) == 0.0 ) + return 0; + else + return momentum.template getData< DeviceType >()( meshEntity ) / + density.template getData< DeviceType >()( meshEntity ); + } + + protected: + const MeshFunctionPointer density, momentum; + }; + + class PressureGetter : public Functions::Domain< Dimensions, Functions::MeshDomain > + { + public: + typedef typename MeshType::RealType RealType; + + PressureGetter( MeshFunctionPointer density, + MeshFunctionPointer energy, + VelocityFieldPointer momentum, + const RealType& gamma ) + : density( density ), energy( energy ), momentum( momentum ), gamma( gamma ) {} + + template< typename EntityType > + __cuda_callable__ + RealType operator()( const EntityType& meshEntity, + const RealType& time = 0.0 ) const + { + const RealType e = energy.template getData< DeviceType >()( meshEntity ); + const RealType rho = density.template getData< DeviceType >()( meshEntity ); + const RealType momentumNorm = momentum.template getData< DeviceType >().getVector( meshEntity ).lpNorm( 2.0 ); + if( rho == 0.0 ) + return 0; + else + return ( gamma - 1.0 ) * ( e - 0.5 * momentumNorm * momentumNorm / rho ); + } + + protected: + const MeshFunctionPointer density, energy; + const VelocityFieldPointer momentum; + const RealType gamma; + }; + + + void getVelocity( const ConservativeVariablesPointer& conservativeVariables, + VelocityFieldPointer& velocity ) + { + Functions::MeshFunctionEvaluator< MeshFunctionType, VelocityGetter > evaluator; + for( int i = 0; i < Dimensions; i++ ) + { + SharedPointer< VelocityGetter, DeviceType > velocityGetter( conservativeVariables->getDensity(), + ( *conservativeVariables->getMomentum() )[ i ] ); + evaluator.evaluate( ( *velocity )[ i ], velocityGetter ); + } + } + + void getPressure( const ConservativeVariablesPointer& conservativeVariables, + const RealType& gamma, + MeshFunctionPointer& pressure ) + { + Functions::MeshFunctionEvaluator< MeshFunctionType, PressureGetter > evaluator; + SharedPointer< PressureGetter, DeviceType > pressureGetter( conservativeVariables->getDensity(), + conservativeVariables->getEnergy(), + conservativeVariables->getMomentum(), + gamma ); + evaluator.evaluate( pressure, pressureGetter ); + } + +}; + +} //namespace TNL diff --git a/examples/flow-sw/RiemannProblemInitialCondition.h b/examples/flow-sw/RiemannProblemInitialCondition.h new file mode 100644 index 0000000000..640e4b6d1e --- /dev/null +++ b/examples/flow-sw/RiemannProblemInitialCondition.h @@ -0,0 +1,1417 @@ +/*************************************************************************** + RiemannProblemInitialCondition.h - description + ------------------- + begin : Feb 13, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Containers/StaticVector.h> +#include <TNL/Operators/Analytic/Sign.h> +#include <TNL/Functions/MeshFunctionEvaluator.h> +#include <TNL/Operators/Analytic/Sign.h> +#include <TNL/Meshes/Grid.h> +#include "CompressibleConservativeVariables.h" + +namespace TNL { +template <typename Mesh> +class RiemannProblemInitialConditionSetter +{ + +}; + +template <typename MeshReal, + typename Device, + typename MeshIndex> +class RiemannProblemInitialConditionSetter< Meshes::Grid< 1,MeshReal, Device, MeshIndex > > +{ + public: + + typedef Meshes::Grid< 1,MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Containers::StaticVector< Dimensions, RealType > PointType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef Functions::VectorField< Dimensions, MeshType > VectorFieldType; +// for cyklus i = 0 to mesh.getDimensions().x() j pro .y() a k pro .z() +// typedef typename MeshType::Cell CellType +// typedef typename MeshType::CoordinatesType CoordinatesType +// Celltype cell(mesh, CoordinatesType(i,j)) +// p59stup do density setElement(mesh.template getEntityIndex< CellType >(cell), hodnota, kterou budu zapisovat) +// pomocn8 t59da, kterou budu specialiyovat p5es r;zn0 dimenze gridu + + void setDiscontinuity(PointType discontinuityPlacement) + { + this->discontinuityPlacement = discontinuityPlacement; + }; + void setDensity(RealType NWUDensity, + RealType NEUDensity, + RealType SWUDensity, + RealType SEUDensity, + RealType NWDDensity, + RealType NEDDensity, + RealType SWDDensity, + RealType SEDDensity) + { + this->NWUDensity = NWUDensity; + this->NEUDensity = NEUDensity; + this->SWUDensity = SWUDensity; + this->SEUDensity = SEUDensity; + this->NWDDensity = NWDDensity; + this->NEDDensity = NEDDensity; + this->SWDDensity = SWDDensity; + this->SEDDensity = SEDDensity; + }; + + void setMomentum(PointType NWUMomentum, + PointType NEUMomentum, + PointType SWUMomentum, + PointType SEUMomentum, + PointType NWDMomentum, + PointType NEDMomentum, + PointType SWDMomentum, + PointType SEDMomentum) + { + this->NWUMomentum = NWUMomentum; + this->NEUMomentum = NEUMomentum; + this->SWUMomentum = SWUMomentum; + this->SEUMomentum = SEUMomentum; + this->NWDMomentum = NWDMomentum; + this->NEDMomentum = NEDMomentum; + this->SWDMomentum = SWDMomentum; + this->SEDMomentum = SEDMomentum; + }; + + void setEnergy(RealType NWUEnergy, + RealType NEUEnergy, + RealType SWUEnergy, + RealType SEUEnergy, + RealType NWDEnergy, + RealType NEDEnergy, + RealType SWDEnergy, + RealType SEDEnergy) + { + this->NWUEnergy = NWUEnergy; + this->NEUEnergy = NEUEnergy; + this->SWUEnergy = SWUEnergy; + this->SEUEnergy = SEUEnergy; + this->NWDEnergy = NWDEnergy; + this->NEDEnergy = NEDEnergy; + this->SWDEnergy = SWDEnergy; + this->SEDEnergy = SEDEnergy; + }; + + void setGamma(RealType gamma) + { + this->gamma = gamma; + }; + + void placeDensity(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + if ( i < this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + { + CellType cell(mesh, CoordinatesType(i)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SWDDensity); + } + else + { + CellType cell(mesh, CoordinatesType(i)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SEDDensity); + } + }; + + void placeMomentum(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + if ( i < this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + { + CellType cell(mesh, CoordinatesType(i)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SWDMomentum[ 0 ]); + } + else + { + CellType cell(mesh, CoordinatesType(i)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SEDMomentum[ 0 ]); + } + }; + + void placeEnergy(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + if ( i < this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + { + CellType cell(mesh, CoordinatesType(i)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SWDEnergy); + } + else + { + CellType cell(mesh, CoordinatesType(i)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SEDEnergy); + } + }; + + PointType discontinuityPlacement; + RealType NWUDensity, NEUDensity, SWUDensity, SEUDensity, NWDDensity, NEDDensity, SWDDensity, SEDDensity; + RealType NWUEnergy, NEUEnergy, SWUEnergy, SEUEnergy, NWDEnergy, NEDEnergy, SWDEnergy, SEDEnergy; + PointType NWUMomentum, NEUMomentum, SWUMomentum, SEUMomentum, NWDMomentum, NEDMomentum, SWDMomentum, SEDMomentum; + RealType gamma; +}; + + +template <typename MeshReal, + typename Device, + typename MeshIndex> +class RiemannProblemInitialConditionSetter< Meshes::Grid< 2, MeshReal, Device, MeshIndex > > +{ + public: + + typedef Meshes::Grid< 2,MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Containers::StaticVector< Dimensions, RealType > PointType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef Functions::VectorField< Dimensions, MeshType > VectorFieldType; +// for cyklus i = 0 to mesh.getDimensions().x() j pro .y() a k pro .z() +// typedef typename MeshType::Cell CellType +// typedef typename MeshType::CoordinatesType CoordinatesType +// Celltype cell(mesh, CoordinatesType(i,j)) +// p59stup do density setElement(mesh.template getEntityIndex< CellType >(cell), hodnota, kterou budu zapisovat) +// pomocn8 t59da, kterou budu specialiyovat p5es r;zn0 dimenze gridu + + void setDiscontinuity(PointType discontinuityPlacement) + { + this->discontinuityPlacement = discontinuityPlacement; + }; + void setDensity(RealType NWUDensity, + RealType NEUDensity, + RealType SWUDensity, + RealType SEUDensity, + RealType NWDDensity, + RealType NEDDensity, + RealType SWDDensity, + RealType SEDDensity) + { + this->NWUDensity = NWUDensity; + this->NEUDensity = NEUDensity; + this->SWUDensity = SWUDensity; + this->SEUDensity = SEUDensity; + this->NWDDensity = NWDDensity; + this->NEDDensity = NEDDensity; + this->SWDDensity = SWDDensity; + this->SEDDensity = SEDDensity; + }; + + void setMomentum(PointType NWUMomentum, + PointType NEUMomentum, + PointType SWUMomentum, + PointType SEUMomentum, + PointType NWDMomentum, + PointType NEDMomentum, + PointType SWDMomentum, + PointType SEDMomentum) + { + this->NWUMomentum = NWUMomentum; + this->NEUMomentum = NEUMomentum; + this->SWUMomentum = SWUMomentum; + this->SEUMomentum = SEUMomentum; + this->NWDMomentum = NWDMomentum; + this->NEDMomentum = NEDMomentum; + this->SWDMomentum = SWDMomentum; + this->SEDMomentum = SEDMomentum; + }; + + void setEnergy(RealType NWUEnergy, + RealType NEUEnergy, + RealType SWUEnergy, + RealType SEUEnergy, + RealType NWDEnergy, + RealType NEDEnergy, + RealType SWDEnergy, + RealType SEDEnergy) + { + this->NWUEnergy = NWUEnergy; + this->NEUEnergy = NEUEnergy; + this->SWUEnergy = SWUEnergy; + this->SEUEnergy = SEUEnergy; + this->NWDEnergy = NWDEnergy; + this->NEDEnergy = NEDEnergy; + this->SWDEnergy = SWDEnergy; + this->SEDEnergy = SEDEnergy; + }; + + void setGamma(RealType gamma) + { + this->gamma = gamma; + }; + + void placeDensity(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + for( int j = 0; j < mesh.getDimensions().y(); j++) + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SWDDensity); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SEDDensity); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->NWDDensity); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->NEDDensity); + } + }; + + void placeMomentum(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + for( int j = 0; j < mesh.getDimensions().y(); j++) + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SWDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SWDMomentum[ 1 ]); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SEDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SEDMomentum[ 1 ]); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->NWDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->NWDMomentum[ 1 ]); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->NEDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->NEDMomentum[ 1 ]); + } + }; + + void placeEnergy(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + for( int j = 0; j < mesh.getDimensions().y(); j++) + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SWDEnergy); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SEDEnergy); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->NWDEnergy); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) ) + { + CellType cell(mesh, CoordinatesType(i,j)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->NEDEnergy); + } + }; + + PointType discontinuityPlacement; + RealType NWUDensity, NEUDensity, SWUDensity, SEUDensity, NWDDensity, NEDDensity, SWDDensity, SEDDensity; + RealType NWUEnergy, NEUEnergy, SWUEnergy, SEUEnergy, NWDEnergy, NEDEnergy, SWDEnergy, SEDEnergy; + PointType NWUMomentum, NEUMomentum, SWUMomentum, SEUMomentum, NWDMomentum, NEDMomentum, SWDMomentum, SEDMomentum; + RealType gamma; +}; + +template <typename MeshReal, + typename Device, + typename MeshIndex> +class RiemannProblemInitialConditionSetter< Meshes::Grid< 3, MeshReal, Device, MeshIndex > > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Containers::StaticVector< Dimensions, RealType > PointType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef Functions::VectorField< Dimensions, MeshType > VectorFieldType; +// for cyklus i = 0 to mesh.getDimensions().x() j pro .y() a k pro .z() +// typedef typename MeshType::Cell CellType +// typedef typename MeshType::CoordinatesType CoordinatesType +// Celltype cell(mesh, CoordinatesType(i,j)) +// p59stup do density setElement(mesh.template getEntityIndex< CellType >(cell), hodnota, kterou budu zapisovat) +// pomocn8 t59da, kterou budu specialiyovat p5es r;zn0 dimenze gridu + + void setDiscontinuity(PointType discontinuityPlacement) + { + this->discontinuityPlacement = discontinuityPlacement; + }; + void setDensity(RealType NWUDensity, + RealType NEUDensity, + RealType SWUDensity, + RealType SEUDensity, + RealType NWDDensity, + RealType NEDDensity, + RealType SWDDensity, + RealType SEDDensity) + { + this->NWUDensity = NWUDensity; + this->NEUDensity = NEUDensity; + this->SWUDensity = SWUDensity; + this->SEUDensity = SEUDensity; + this->NWDDensity = NWDDensity; + this->NEDDensity = NEDDensity; + this->SWDDensity = SWDDensity; + this->SEDDensity = SEDDensity; + }; + + void setMomentum(PointType NWUMomentum, + PointType NEUMomentum, + PointType SWUMomentum, + PointType SEUMomentum, + PointType NWDMomentum, + PointType NEDMomentum, + PointType SWDMomentum, + PointType SEDMomentum) + { + this->NWUMomentum = NWUMomentum; + this->NEUMomentum = NEUMomentum; + this->SWUMomentum = SWUMomentum; + this->SEUMomentum = SEUMomentum; + this->NWDMomentum = NWDMomentum; + this->NEDMomentum = NEDMomentum; + this->SWDMomentum = SWDMomentum; + this->SEDMomentum = SEDMomentum; + }; + + void setEnergy(RealType NWUEnergy, + RealType NEUEnergy, + RealType SWUEnergy, + RealType SEUEnergy, + RealType NWDEnergy, + RealType NEDEnergy, + RealType SWDEnergy, + RealType SEDEnergy) + { + this->NWUEnergy = NWUEnergy; + this->NEUEnergy = NEUEnergy; + this->SWUEnergy = SWUEnergy; + this->SEUEnergy = SEUEnergy; + this->NWDEnergy = NWDEnergy; + this->NEDEnergy = NEDEnergy; + this->SWDEnergy = SWDEnergy; + this->SEDEnergy = SEDEnergy; + }; + + void setGamma(RealType gamma) + { + this->gamma = gamma; + }; + + void placeDensity(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + for( int j = 0; j < mesh.getDimensions().y(); j++) + for ( int k = 0; k < mesh.getDimensions().z(); k++) + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SWDDensity); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SEDDensity); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->NWDDensity); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->NEDDensity); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SWUDensity); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SEUDensity); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SWUDensity); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getDensity()).setValue(cell, this->SEUDensity); + } + }; + + void placeMomentum(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + for( int j = 0; j < mesh.getDimensions().y(); j++) + for ( int k = 0; k < mesh.getDimensions().z(); k++) + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SWDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SWDMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->SWDMomentum[ 2 ]); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SEDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SEDMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->SEDMomentum[ 2 ]); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->NWDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->NWDMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->NWDMomentum[ 2 ]); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->NEDMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->NEDMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->NEDMomentum[ 2 ]); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SWUMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SWUMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->SWUMomentum[ 2 ]); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SEUMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SEUMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->SEUMomentum[ 2 ]); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SWUMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SWUMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->SWUMomentum[ 2 ]); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* (* conservativeVariables.getMomentum())[ 0 ]).setValue(cell, this->SEUMomentum[ 0 ]); + (* (* conservativeVariables.getMomentum())[ 1 ]).setValue(cell, this->SEUMomentum[ 1 ]); + (* (* conservativeVariables.getMomentum())[ 2 ]).setValue(cell, this->SEUMomentum[ 2 ]); + } + }; + + void placeEnergy(CompressibleConservativeVariables< MeshType >& conservativeVariables) + { + typedef typename MeshType::Cell CellType; + typedef typename MeshType::CoordinatesType CoordinatesType; + MeshType mesh = (* conservativeVariables.getDensity()).getMesh(); + for( int i = 0; i < mesh.getDimensions().x(); i++) + for( int j = 0; j < mesh.getDimensions().y(); j++) + for ( int k = 0; k < mesh.getDimensions().z(); k++) + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SWDEnergy); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SEDEnergy); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->NWDEnergy); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k <= this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->NEDEnergy); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SWUEnergy); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j <= this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SEUEnergy); + } + else + if ( ( i <= this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SWUEnergy); + } + else + if ( ( i > this->discontinuityPlacement[ 0 ] * mesh.getDimensions().x() ) + && ( j > this->discontinuityPlacement[ 1 ] * mesh.getDimensions().y() ) + && ( k > this->discontinuityPlacement[ 2 ] * mesh.getDimensions().z() ) ) + { + CellType cell(mesh, CoordinatesType(i,j,k)); + cell.refresh(); + (* conservativeVariables.getEnergy()).setValue(cell, this->SEUEnergy); + } + }; + + PointType discontinuityPlacement; + RealType NWUDensity, NEUDensity, SWUDensity, SEUDensity, NWDDensity, NEDDensity, SWDDensity, SEDDensity; + RealType NWUEnergy, NEUEnergy, SWUEnergy, SEUEnergy, NWDEnergy, NEDEnergy, SWDEnergy, SEDEnergy; + PointType NWUMomentum, NEUMomentum, SWUMomentum, SEUMomentum, NWDMomentum, NEDMomentum, SWDMomentum, SEDMomentum; + RealType gamma; +}; + +template< typename Mesh > +class RiemannProblemInitialCondition +{ + public: + + typedef Mesh MeshType; + typedef typename MeshType::RealType RealType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::IndexType IndexType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Containers::StaticVector< Dimensions, RealType > PointType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef Functions::VectorField< Dimensions, MeshType > VectorFieldType; + + RiemannProblemInitialCondition() + : discontinuityPlacement( 0.5 ), + leftDensity( 1.0 ), rightDensity( 1.0 ), + leftVelocity( -2.0 ), rightVelocity( 2.0 ), + leftPressure( 0.4 ), rightPressure( 0.4 ), + gamma( 1.67 ){} + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "discontinuity-placement-0", "x-coordinate of the discontinuity placement.", 0.5 ); + config.addEntry< double >( prefix + "discontinuity-placement-1", "y-coordinate of the discontinuity placement.", 0.5 ); + config.addEntry< double >( prefix + "discontinuity-placement-2", "z-coordinate of the discontinuity placement.", 0.5 ); +/* + config.addEntry< double >( prefix + "left-density", "Density on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "right-density", "Density on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "left-velocity-0", "x-coordinate of the velocity on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "left-velocity-1", "y-coordinate of the velocity on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "left-velocity-2", "z-coordinate of the velocity on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "right-velocity-0", "x-coordinate of the velocity on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "right-velocity-1", "y-coordinate of the velocity on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "right-velocity-2", "z-coordinate of the velocity on the right side of the discontinuity.", 0.0 ); + config.addEntry< double >( prefix + "left-pressure", "Pressure on the left side of the discontinuity.", 1.0 ); + config.addEntry< double >( prefix + "right-pressure", "Pressure on the right side of the discontinuity.", 0.0 ); +*/ + config.addEntry< double >( prefix + "NWU-density", "This sets a value of northwest up density.", 1.0 ); + config.addEntry< double >( prefix + "NWU-velocity-0", "This sets a value of northwest up x velocity.", 1.0 ); + config.addEntry< double >( prefix + "NWU-velocity-1", "This sets a value of northwest up y velocity.", 1.0 ); + config.addEntry< double >( prefix + "NWU-velocity-2", "This sets a value of northwest up z velocity.", 1.0 ); + config.addEntry< double >( prefix + "NWU-pressure", "This sets a value of northwest up pressure.", 1.0 ); + config.addEntry< double >( prefix + "SWU-density", "This sets a value of southwest up density.", 1.0 ); + config.addEntry< double >( prefix + "SWU-velocity-0", "This sets a value of southwest up x velocity.", 1.0 ); + config.addEntry< double >( prefix + "SWU-velocity-1", "This sets a value of southwest up y velocity.", 1.0 ); + config.addEntry< double >( prefix + "SWU-velocity-2", "This sets a value of southwest up z velocity.", 1.0 ); + config.addEntry< double >( prefix + "SWU-pressure", "This sets a value of southwest up pressure.", 1.0 ); + config.addEntry< double >( prefix + "NWD-density", "This sets a value of northwest down density.", 1.0 ); + config.addEntry< double >( prefix + "NWD-velocity-0", "This sets a value of northwest down x velocity.", 1.0 ); + config.addEntry< double >( prefix + "NWD-velocity-1", "This sets a value of northwest down y velocity.", 1.0 ); + config.addEntry< double >( prefix + "NWD-velocity-2", "This sets a value of northwest down z velocity.", 1.0 ); + config.addEntry< double >( prefix + "NWD-pressure", "This sets a value of northwest down pressure.", 1.0 ); + config.addEntry< double >( prefix + "SWD-density", "This sets a value of southwest down density.", 1.0 ); + config.addEntry< double >( prefix + "SWD-velocity-0", "This sets a value of southwest down x velocity.", 1.0 ); + config.addEntry< double >( prefix + "SWD-velocity-1", "This sets a value of southwest down y velocity.", 1.0 ); + config.addEntry< double >( prefix + "SWD-velocity-2", "This sets a value of southwest down z velocity.", 1.0 ); + config.addEntry< double >( prefix + "SWD-pressure", "This sets a value of southwest down pressure.", 1.0 ); + config.addEntry< double >( prefix + "NEU-density", "This sets a value of northeast up density.", 1.0 ); + config.addEntry< double >( prefix + "NEU-velocity-0", "This sets a value of northeast up x velocity.", 1.0 ); + config.addEntry< double >( prefix + "NEU-velocity-1", "This sets a value of northeast up y velocity.", 1.0 ); + config.addEntry< double >( prefix + "NEU-velocity-2", "This sets a value of northeast up z velocity.", 1.0 ); + config.addEntry< double >( prefix + "NEU-pressure", "This sets a value of northeast up pressure.", 1.0 ); + config.addEntry< double >( prefix + "SEU-density", "This sets a value of southeast up density.", 1.0 ); + config.addEntry< double >( prefix + "SEU-velocity-0", "This sets a value of southeast up x velocity.", 1.0 ); + config.addEntry< double >( prefix + "SEU-velocity-1", "This sets a value of southeast up y velocity.", 1.0 ); + config.addEntry< double >( prefix + "SEU-velocity-2", "This sets a value of southeast up z velocity.", 1.0 ); + config.addEntry< double >( prefix + "SEU-pressure", "This sets a value of southeast up pressure.", 1.0 ); + config.addEntry< double >( prefix + "NED-density", "This sets a value of northeast down density.", 1.0 ); + config.addEntry< double >( prefix + "NED-velocity-0", "This sets a value of northeast down x velocity.", 1.0 ); + config.addEntry< double >( prefix + "NED-velocity-1", "This sets a value of northeast down y velocity.", 1.0 ); + config.addEntry< double >( prefix + "NED-velocity-2", "This sets a value of northeast down z velocity.", 1.0 ); + config.addEntry< double >( prefix + "NED-pressure", "This sets a value of northeast down pressure.", 1.0 ); + config.addEntry< double >( prefix + "SED-density", "This sets a value of southeast down density.", 1.0 ); + config.addEntry< double >( prefix + "SED-velocity-0", "This sets a value of southeast down x velocity.", 1.0 ); + config.addEntry< double >( prefix + "SED-velocity-1", "This sets a value of southeast down y velocity.", 1.0 ); + config.addEntry< double >( prefix + "SED-velocity-2", "This sets a value of southeast down z velocity.", 1.0 ); + config.addEntry< double >( prefix + "SED-pressure", "This sets a value of southeast down pressure.", 1.0 ); + config.addEntry< double >( prefix + "gamma", "Gamma in the ideal gas state equation.", 1.4 ); + + config.addEntry< String >( prefix + "initial", " One of predefined initial condition.", "none"); + config.addEntryEnum< String >( "none" ); + config.addEntryEnum< String >( "1D_2" ); + config.addEntryEnum< String >( "1D_3a" ); + config.addEntryEnum< String >( "1D_4" ); + config.addEntryEnum< String >( "1D_5" ); + config.addEntryEnum< String >( "1D_6" ); + config.addEntryEnum< String >( "1D_Noh" ); + config.addEntryEnum< String >( "1D_peak" ); + config.addEntryEnum< String >( "2D_3" ); + config.addEntryEnum< String >( "2D_4" ); + config.addEntryEnum< String >( "2D_6" ); + config.addEntryEnum< String >( "2D_12" ); + config.addEntryEnum< String >( "2D_15" ); + config.addEntryEnum< String >( "2D_17" ); + } + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + String initial = parameters.getParameter< String >( prefix + "initial" ); + if(initial == prefix + "none") + { + this->discontinuityPlacement.setup( parameters, prefix + "discontinuity-placement-" ); + this->gamma = parameters.getParameter< double >( prefix + "gamma" ); +/* + this->leftVelocity.setup( parameters, prefix + "left-velocity-" ); + this->rightVelocity.setup( parameters, prefix + "right-velocity-" ); + this->leftDensity = parameters.getParameter< double >( prefix + "left-density" ); + this->rightDensity = parameters.getParameter< double >( prefix + "right-density" ); + this->leftPressure = parameters.getParameter< double >( prefix + "left-pressure" ); + this->rightPressure = parameters.getParameter< double >( prefix + "right-pressure" ); +*/ + + this->NWUDensity = parameters.getParameter< RealType >( prefix + "NWU-density" ); + this->NWUVelocity.setup( parameters, prefix + "NWU-velocity-" ); + this->NWUPressure = parameters.getParameter< RealType >( prefix + "NWU-pressure" ); + this->NWUEnergy = Energy( NWUDensity, NWUPressure, gamma, NWUVelocity); + this->NWUMomentum = NWUVelocity * NWUDensity; + + this->SWUDensity = parameters.getParameter< RealType >( prefix + "SWU-density" ); + this->SWUVelocity.setup( parameters, prefix + "SWU-velocity-" ); + this->SWUPressure = parameters.getParameter< RealType >( prefix + "SWU-pressure" ); + this->SWUEnergy = Energy( SWUDensity, SWUPressure, gamma, SWUVelocity); + this->SWUMomentum = SWUVelocity * SWUDensity; + + this->NWDDensity = parameters.getParameter< RealType >( prefix + "NWD-density" ); + this->NWDVelocity.setup( parameters, prefix + "NWD-velocity-" ); + this->NWDPressure = parameters.getParameter< RealType >( prefix + "NWD-pressure" ); + this->NWDEnergy = Energy( NWDDensity, NWDPressure, gamma, NWDVelocity); + this->NWDMomentum = NWDVelocity * NWDDensity; + + this->SWDDensity = parameters.getParameter< RealType >( prefix + "SWD-density" ); + this->SWDVelocity.setup( parameters, prefix + "SWD-velocity-" ); + this->SWDPressure = parameters.getParameter< RealType >( prefix + "SWD-pressure" ); + this->SWDEnergy = Energy( SWDDensity, SWDPressure, gamma, SWDVelocity); + this->SWDMomentum = SWDVelocity * SWDDensity; + + this->NEUDensity = parameters.getParameter< RealType >( prefix + "NEU-density" ); + this->NEUVelocity.setup( parameters, prefix + "NEU-velocity-" ); + this->NEUPressure = parameters.getParameter< RealType >( prefix + "NEU-pressure" ); + this->NEUEnergy = Energy( NEUDensity, NEUPressure, gamma, NEUVelocity); + this->NEUMomentum = NEUVelocity * NEUDensity; + + this->SEUDensity = parameters.getParameter< RealType >( prefix + "SEU-density" ); + this->SEUVelocity.setup( parameters, prefix + "SEU-velocity-" ); + this->SEUPressure = parameters.getParameter< RealType >( prefix + "SEU-pressure" ); + this->SEUEnergy = Energy( SEUDensity, SEUPressure, gamma, SEUVelocity); + this->SEUMomentum = SEUVelocity * SEUDensity; + + this->NEDDensity = parameters.getParameter< RealType >( prefix + "NED-density" ); + this->NEDVelocity.setup(parameters, prefix + "NED-velocity-" ); + this->NEDPressure = parameters.getParameter< RealType >( prefix + "NED-pressure" ); + this->NEDEnergy = Energy( NEDDensity, NEDPressure, gamma, NEDVelocity); + this->NEDMomentum = NEDVelocity * NEDDensity; + + this->SEDDensity = parameters.getParameter< RealType >( prefix + "SED-density" ); + this->SEDVelocity.setup( parameters, prefix + "SED-velocity-" ); + this->SEDPressure = parameters.getParameter< RealType >( prefix + "SED-pressure" ); + this->SEDEnergy = Energy( SEDDensity, SEDPressure, gamma, SEDVelocity); + this->SEDMomentum = SEDVelocity * SEDDensity; + + } + if(initial == prefix + "1D_2") + predefinedInitialCondition( 1.4, 0.5, 0.0, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.0, 1.0, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.0, 1.0, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.0, 0.4, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.0, 0.4, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + -2.0, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 2.0, 0.0, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "1D_3a") + predefinedInitialCondition( 1.4, 0.8, 0.0, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.0, 1.0, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.0, 1.0, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.0, 1000.0, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.0, 0.01, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + -19.59745, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + -19.59745, 0.0, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "1D_4") + predefinedInitialCondition( 1.666, 0.4, 0.0, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.0, 5.99924, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.0, 5.99242, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.0, 460.894, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.0, 46.095, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 19.5975, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + -6.19633, 0.0, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "1D_5") + predefinedInitialCondition( 1.4, 0.5, 0.0, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.0, 1.4, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.0, 1.0, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.0, 1.0, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.0, 1.0, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 0.0, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 0.0, 0.0, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "1D_6") + predefinedInitialCondition( 1.4, 0.5, 0.0, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.0, 1.4, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.0, 1.0, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.0, 0.1, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.0, 0.1, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 0.1, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 0.1, 0.0, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "1D_Noh") + predefinedInitialCondition( 1.4, 0.5, 0.0, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.0, 1.0, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.0, 1.0, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.0, 0.000001, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.0, 0.000001, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 1.0, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + -1.0, 0.0, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "1D_peak") + predefinedInitialCondition( 1.4, 0.5, 0.0, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.0, 0.12612, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.0, 6.5915, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.0, 782.929, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.0, 3.15449, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 8.90470, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 2.26542, 0.0, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "2D_3") + predefinedInitialCondition( 1.666, 0.5, 0.5, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.5323, 0.138, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 1.5, 0.5323, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.3, 0.029, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 1.5, 0.3, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 1.206, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 1.206, 1.206, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 0.0, 1.206, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "2D_4") + predefinedInitialCondition( 1.666, 0.5, 0.5, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.5065, 1.1, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 1.1, 0.5065, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.35, 1.1, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 1.1, 0.35, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.8939, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 0.8939, 0.8939, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 0.0, 0.8939, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + + if(initial == prefix + "2D_6") + predefinedInitialCondition( 1.666, 0.5, 0.5, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 2.0, 1.0, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 1.0, 3.0, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 1.0, 1.0, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 1.0, 1.0, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.75, 0.5, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + -0.75, 0.5, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.75, -0.5, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + -0.75, -0.5, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "2D_12") + predefinedInitialCondition( 1.666, 0.5, 0.5, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 1.0, 0.8, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 0.5313, 1.0, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 1.0, 1.0, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 0.4, 1.0, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.7276, 0.0, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 0.0, 0.0, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, 0.0, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 0.0, 0.7276, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + + if(initial == prefix + "2D_15") + predefinedInitialCondition( 1.666, 0.5, 0.5, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 0.5197, 0.8, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 1.0, 0.5313, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 0.4, 0.4, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 1.0, 0.4, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + -0.6259, -0.3, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 0.1, -0.3, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.1, -0.3, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 0.1, 0.4276, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + if(initial == prefix + "2D_17") + predefinedInitialCondition( 1.666, 0.5, 0.5, 0.0, // double preGamma, double preDiscX, double preDiscY, double preDiscZ, + 0.0, 0.0, 2.0, 1.0625, //double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + 0.0, 0.0, 1.0, 0.5197, //double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + 0.0, 0.0, 1.0, 0.4, //double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + 0.0, 0.0, 1.0, 0.4, //double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + 0.0, 0.0, 0.0, //double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + 0.0, 0.0, 0.0, //double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + 0.0, -0.3, 0.0, //double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + 0.0, 0.2145, 0.0, //double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + 0.0, 0.0, 0.0, //double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + 0.0, 0.0, 0.0, //double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + 0.0, -0.4, 0.0, //double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + 0.0, 1.1259, 0.0 //double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ); + return true; + } + + void setDiscontinuityPlacement( const PointType& v ) + { + this->discontinuityPlacement = v; + } + + const PointType& getDiscontinuityPlasement() const + { + return this->discontinuityPlacement; + } + + void setLeftDensity( const RealType& leftDensity ) + { + this->leftDensity = leftDensity; + } + + const RealType& getLeftDensity() const + { + return this->leftDensity; + } + + void setRightDensity( const RealType& rightDensity ) + { + this->rightDensity = rightDensity; + } + + const RealType& getRightDensity() const + { + return this->rightDensity; + } + + void setLeftVelocity( const PointType& leftVelocity ) + { + this->leftVelocity = leftVelocity; + } + + const PointType& getLeftVelocity() const + { + return this->leftVelocity; + } + + void setRightVelocity( const RealType& rightVelocity ) + { + this->rightVelocity = rightVelocity; + } + + const PointType& getRightVelocity() const + { + return this->rightVelocity; + } + + void setLeftPressure( const RealType& leftPressure ) + { + this->leftPressure = leftPressure; + } + + const RealType& getLeftPressure() const + { + return this->leftPressure; + } + + void setRightPressure( const RealType& rightPressure ) + { + this->rightPressure = rightPressure; + } + + const RealType& getRightPressure() const + { + return this->rightPressure; + } + + + void predefinedInitialCondition( double preGamma, double preDiscX, double preDiscY, double preDiscZ, + double preNWUDensity, double preSWUDensity, double preNWDDensity, double preSWDDensity, + double preNEUDensity, double preSEUDensity, double preNEDDensity, double preSEDDensity, + double preNWUPressure, double preSWUPressure, double preNWDPressure, double preSWDPressure, + double preNEUPressure, double preSEUPressure, double preNEDPressure, double preSEDPressure, + double preNWUVelocityX, double preNWUVelocityY,double preNWUVelocityZ, + double preSWUVelocityX, double preSWUVelocityY,double preSWUVelocityZ, + double preNWDVelocityX, double preNWDVelocityY,double preNWDVelocityZ, + double preSWDVelocityX, double preSWDVelocityY,double preSWDVelocityZ, + double preNEUVelocityX, double preNEUVelocityY,double preNEUVelocityZ, + double preSEUVelocityX, double preSEUVelocityY,double preSEUVelocityZ, + double preNEDVelocityX, double preNEDVelocityY,double preNEDVelocityZ, + double preSEDVelocityX, double preSEDVelocityY,double preSEDVelocityZ + ) + + { + this->discontinuityPlacement = PointLoad(preDiscX, preDiscY, preDiscZ); + this->gamma = preGamma; + + this->NWUDensity = preNWUDensity; + this->NWUVelocity = PointLoad(preNWUVelocityX, preNWUVelocityY, preNWUVelocityZ); + this->NWUPressure = preNWUPressure; + this->NWUEnergy = Energy( NWUDensity, NWUPressure, gamma, NWUVelocity); + this->NWUMomentum = NWUVelocity * NWUDensity; + + this->SWUDensity = preNWUDensity; + this->SWUVelocity = PointLoad(preSWUVelocityX, preSWUVelocityY, preSWUVelocityZ); + this->SWUPressure = preSWUPressure; + this->SWUEnergy = Energy( SWUDensity, SWUPressure, gamma, SWUVelocity); + this->SWUMomentum = SWUVelocity * SWUDensity; + + this->NWDDensity = preNWDDensity; + this->NWDVelocity = PointLoad(preNWDVelocityX, preNWDVelocityY, preNWDVelocityZ); + this->NWDPressure = preNWDPressure; + this->NWDEnergy = Energy( NWDDensity, NWDPressure, gamma, NWDVelocity); + this->NWDMomentum = NWDVelocity * NWDDensity; + + this->SWDDensity = preSWDDensity; + this->SWDVelocity = PointLoad(preSWDVelocityX, preSWDVelocityY, preSWDVelocityZ); + this->SWDPressure = preSWDPressure; + this->SWDEnergy = Energy( SWDDensity, SWDPressure, gamma, SWDVelocity); + this->SWDMomentum = SWDVelocity * SWDDensity; + + this->NEUDensity = preNEUDensity; + this->NEUVelocity = PointLoad(preNEUVelocityX, preNEUVelocityY, preNEUVelocityZ); + this->NEUPressure = preNEUPressure; + this->NEUEnergy = Energy( NEUDensity, NEUPressure, gamma, NEUVelocity); + this->NEUMomentum = NEUVelocity * NEUDensity; + + this->SEUDensity = preSEUDensity; + this->SEUVelocity = PointLoad(preSEUVelocityX, preSEUVelocityY, preSEUVelocityZ); + this->SEUPressure = preSEUPressure; + this->SEUEnergy = Energy( SEUDensity, SEUPressure, gamma, SEUVelocity); + this->SEUMomentum = SEUVelocity * SEUDensity; + + this->NEDDensity = preNEDDensity; + this->NEDVelocity = PointLoad(preNEDVelocityX, preNEDVelocityY, preNEDVelocityZ); + this->NEDPressure = preNEDPressure; + this->NEDEnergy = Energy( NEDDensity, NEDPressure, gamma, NEDVelocity); + this->NEDMomentum = NEDVelocity * NEDDensity; + + this->SEDDensity = preSEDDensity; + this->SEDVelocity = PointLoad(preSEDVelocityX, preSEDVelocityY, preSEDVelocityZ); + this->SEDPressure = preSEDPressure; + this->SEDEnergy = Energy( SEDDensity, SEDPressure, gamma, SEDVelocity); + this->SEDMomentum = SEDVelocity * SEDDensity; + + std::cout << this->SEDEnergy; + std::cout << this->SWDEnergy; + + } + + PointType PointLoad( RealType ValueX, RealType ValueY, RealType ValueZ) + { + PointType point; + switch (Dimensions) + { + case 1: point[ 0 ] = ValueX; + break; + case 2: point[ 0 ] = ValueX; + point[ 1 ] = ValueY; + break; + case 3: point[ 0 ] = ValueX; + point[ 1 ] = ValueY; + point[ 2 ] = ValueZ; + break; + } + return point; + } + + RealType Energy( RealType Density, RealType Pressure, RealType gamma, PointType Velocity) + { + RealType energy; + switch (Dimensions) + { + case 1: energy = (Pressure / (gamma -1.0) + 0.5 * Density * (std::pow(Velocity[ 0 ], 2 ))); + break; + case 2: energy = (Pressure / (gamma -1.0) + 0.5 * Density * (std::pow(Velocity[ 0 ], 2 ) + std::pow(Velocity[ 1 ], 2 ))); + break; + case 3: energy = (Pressure / (gamma -1.0) + 0.5 * Density * (std::pow(Velocity[ 0 ], 2 ) + std::pow(Velocity[ 1 ], 2 ) + std::pow(Velocity[ 3 ], 2 ))); + break; // druhou mocninu ps8t jako sou4in + } + return energy; + } + + void setInitialCondition( CompressibleConservativeVariables< MeshType >& conservativeVariables, + const PointType& center = PointType( 0.0 ) ) + { + RiemannProblemInitialConditionSetter<MeshType>* variablesSetter = new RiemannProblemInitialConditionSetter<MeshType>; + variablesSetter->setGamma(this->gamma); + variablesSetter->setDensity(this->NWUDensity, + this->NEUDensity, + this->SWUDensity, + this->SEUDensity, + this->NWDDensity, + this->NEDDensity, + this->SWDDensity, + this->SEDDensity); + variablesSetter->setMomentum(this->NWUMomentum, + this->NEUMomentum, + this->SWUMomentum, + this->SEUMomentum, + this->NWDMomentum, + this->NEDMomentum, + this->SWDMomentum, + this->SEDMomentum); + variablesSetter->setEnergy(this->NWUEnergy, + this->NEUEnergy, + this->SWUEnergy, + this->SEUEnergy, + this->NWDEnergy, + this->NEDEnergy, + this->SWDEnergy, + this->SEDEnergy); + variablesSetter->setDiscontinuity(this->discontinuityPlacement); + variablesSetter->placeDensity(conservativeVariables); + variablesSetter->placeMomentum(conservativeVariables); + variablesSetter->placeEnergy(conservativeVariables); + +// for cyklus i = 0 to mesh.getDimensions().x() j pro .y() a k pro .z() +// typedef typename MeshType::Cell CellType +// typedef typename MeshType::CoordinatesType CoordinatesType +// Celltype cell(mesh, CoordinatesType(i,j)) +// p59stup do density setElement(mesh.template getEntityIndex< CellType >(cell), hodnota, kterou budu zapisovat) +// pomocn8 t59da, kterou budu specialiyovat p5es r;zn0 dimenze gridu + +/* + typedef Functions::Analytic::VectorNorm< Dimensions, RealType > VectorNormType; + typedef Operators::Analytic::Sign< Dimensions, RealType > SignType; + typedef Functions::OperatorFunction< SignType, VectorNormType > InitialConditionType; + typedef SharedPointer< InitialConditionType, DeviceType > InitialConditionPointer; + + InitialConditionPointer initialCondition; + initialCondition->getFunction().setCenter( center ); + initialCondition->getFunction().setMaxNorm( true ); + initialCondition->getFunction().setRadius( discontinuityPlacement[ 0 ] ); + discontinuityPlacement *= 1.0 / discontinuityPlacement[ 0 ]; + for( int i = 1; i < Dimensions; i++ ) + discontinuityPlacement[ i ] = 1.0 / discontinuityPlacement[ i ]; + initialCondition->getFunction().setAnisotropy( discontinuityPlacement ); + initialCondition->getFunction().setMultiplicator( -1.0 ); + + Functions::MeshFunctionEvaluator< MeshFunctionType, InitialConditionType > evaluator; +*/ + /**** + * Density + */ +/* + conservativeVariables.getDensity()->write( "density.gplt", "gnuplot" ); +*/ +/* + initialCondition->getOperator().setPositiveValue( leftDensity ); + initialCondition->getOperator().setNegativeValue( rightDensity ); + evaluator.evaluate( conservativeVariables.getDensity(), initialCondition ); + conservativeVariables.getDensity()->write( "density.gplt", "gnuplot" ); +*/ + /**** + * Momentum + */ + +/* + for( int i = 0; i < Dimensions; i++ ) + { + initialCondition->getOperator().setPositiveValue( leftDensity * leftVelocity[ i ] ); + initialCondition->getOperator().setNegativeValue( rightDensity * rightVelocity[ i ] ); + evaluator.evaluate( conservativeVariables.getMomentum()[ i ], initialCondition ); + } +*/ + /**** + * Energy + */ +/* + conservativeVariables.getEnergy()->write( "energy-init", "gnuplot" ); +*/ +/* + const RealType leftKineticEnergy = leftVelocity.lpNorm( 2.0 ); + const RealType rightKineticEnergy = rightVelocity.lpNorm( 2.0 ); + const RealType leftEnergy = leftPressure / ( gamma - 1.0 ) + 0.5 * leftDensity * leftKineticEnergy * leftKineticEnergy; + const RealType rightEnergy = rightPressure / ( gamma - 1.0 ) + 0.5 * rightDensity * rightKineticEnergy * rightKineticEnergy; + initialCondition->getOperator().setPositiveValue( leftEnergy ); + initialCondition->getOperator().setNegativeValue( rightEnergy ); + evaluator.evaluate( (* conservativeVariables.getEnergy()), initialCondition ); + (* conservativeVariables.getEnergy())->write( "energy-init", "gnuplot" ); +*/ + } + + + protected: + + PointType discontinuityPlacement; + PointType NWUVelocity, NEUVelocity, SWUVelocity, SEUVelocity, NWDVelocity, NEDVelocity, SWDVelocity, SEDVelocity; + RealType NWUDensity, NEUDensity, SWUDensity, SEUDensity, NWDDensity, NEDDensity, SWDDensity, SEDDensity; + RealType NWUPressure, NEUPressure, SWUPressure, SEUPressure, NWDPressure, NEDPressure, SWDPressure, SEDPressure; + RealType NWUEnergy, NEUEnergy, SWUEnergy, SEUEnergy, NWDEnergy, NEDEnergy, SWDEnergy, SEDEnergy; + PointType NWUMomentum, NEUMomentum, SWUMomentum, SEUMomentum, NWDMomentum, NEDMomentum, SWDMomentum, SEDMomentum; + RealType leftDensity, rightDensity; + PointType leftVelocity, rightVelocity; + RealType leftPressure, rightPressure; + + RealType gamma; // gamma in the ideal gas state equation +}; + +} //namespace TNL diff --git a/examples/flow-sw/Upwind.h b/examples/flow-sw/Upwind.h new file mode 100644 index 0000000000..cf337144b1 --- /dev/null +++ b/examples/flow-sw/Upwind.h @@ -0,0 +1,158 @@ +/*************************************************************************** + Upwind.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> + +#include "UpwindContinuity.h" +#include "UpwindEnergy.h" +#include "UpwindMomentumX.h" +#include "UpwindMomentumY.h" +#include "UpwindMomentumZ.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class Upwind +{ + public: + typedef Mesh MeshType; + typedef Real RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + static const int Dimensions = Mesh::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VectorFieldType; + + typedef UpwindContinuity< Mesh, Real, Index > ContinuityOperatorType; + typedef UpwindMomentumX< Mesh, Real, Index > MomentumXOperatorType; + typedef UpwindMomentumY< Mesh, Real, Index > MomentumYOperatorType; + typedef UpwindMomentumZ< Mesh, Real, Index > MomentumZOperatorType; + typedef UpwindEnergy< Mesh, Real, Index > EnergyOperatorType; + + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VectorFieldType > VectorFieldPointer; + typedef SharedPointer< MeshType > MeshPointer; + + typedef SharedPointer< ContinuityOperatorType > ContinuityOperatorPointer; + typedef SharedPointer< MomentumXOperatorType > MomentumXOperatorPointer; + typedef SharedPointer< MomentumYOperatorType > MomentumYOperatorPointer; + typedef SharedPointer< MomentumZOperatorType > MomentumZOperatorPointer; + typedef SharedPointer< EnergyOperatorType > EnergyOperatorPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "dynamical-viscosity", "Value of dynamical (real) viscosity in the Navier-Stokes equation", 1.0 ); + } + + Upwind() + :dynamicalViscosity( 1.0 ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->dynamicalViscosity = parameters.getParameter< double >( prefix + "dynamical-viscosity" ); + this->momentumXOperatorPointer->setDynamicalViscosity( dynamicalViscosity ); + this->momentumYOperatorPointer->setDynamicalViscosity( dynamicalViscosity ); + this->momentumZOperatorPointer->setDynamicalViscosity( dynamicalViscosity ); + this->energyOperatorPointer->setDynamicalViscosity( dynamicalViscosity ); + + return true; + } + + void setTau( const RealType& tau ) + { + this->continuityOperatorPointer->setTau( tau ); + this->momentumXOperatorPointer->setTau( tau ); + this->momentumYOperatorPointer->setTau( tau ); + this->momentumZOperatorPointer->setTau( tau ); + this->energyOperatorPointer->setTau( tau ); + } + + void setGamma( const RealType& gamma ) + { + this->continuityOperatorPointer->setGamma( gamma ); + this->momentumXOperatorPointer->setGamma( gamma ); + this->momentumYOperatorPointer->setGamma( gamma ); + this->momentumZOperatorPointer->setGamma( gamma ); + this->energyOperatorPointer->setGamma( gamma ); + } + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->continuityOperatorPointer->setPressure( pressure ); + this->momentumXOperatorPointer->setPressure( pressure ); + this->momentumYOperatorPointer->setPressure( pressure ); + this->momentumZOperatorPointer->setPressure( pressure ); + this->energyOperatorPointer->setPressure( pressure ); + } + + void setDensity( const MeshFunctionPointer& density ) + { + this->momentumXOperatorPointer->setDensity( density ); + this->momentumYOperatorPointer->setDensity( density ); + this->momentumZOperatorPointer->setDensity( density ); + this->energyOperatorPointer->setDensity( density ); + } + + void setVelocity( const VectorFieldPointer& velocity ) + { + this->continuityOperatorPointer->setVelocity( velocity ); + this->momentumXOperatorPointer->setVelocity( velocity ); + this->momentumYOperatorPointer->setVelocity( velocity ); + this->momentumZOperatorPointer->setVelocity( velocity ); + this->energyOperatorPointer->setVelocity( velocity ); + } + + const ContinuityOperatorPointer& getContinuityOperator() const + { + return this->continuityOperatorPointer; + } + + const MomentumXOperatorPointer& getMomentumXOperator() const + { + return this->momentumXOperatorPointer; + } + + const MomentumYOperatorPointer& getMomentumYOperator() const + { + return this->momentumYOperatorPointer; + } + + const MomentumZOperatorPointer& getMomentumZOperator() const + { + return this->momentumZOperatorPointer; + } + + const EnergyOperatorPointer& getEnergyOperator() const + { + return this->energyOperatorPointer; + } + + protected: + + ContinuityOperatorPointer continuityOperatorPointer; + MomentumXOperatorPointer momentumXOperatorPointer; + MomentumYOperatorPointer momentumYOperatorPointer; + MomentumZOperatorPointer momentumZOperatorPointer; + EnergyOperatorPointer energyOperatorPointer; + + RealType dynamicalViscosity; +}; + +} //namespace TNL diff --git a/examples/flow-sw/UpwindContinuity.h b/examples/flow-sw/UpwindContinuity.h new file mode 100644 index 0000000000..cc9b84aba0 --- /dev/null +++ b/examples/flow-sw/UpwindContinuity.h @@ -0,0 +1,386 @@ +/*************************************************************************** + UpwindContinuity.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/SharedPointer.h> + +namespace TNL { + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindContinuityBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + static String getType() + { + return String( "UpwindContinuity< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setGamma(const Real& gamma) + { + this->gamma = gamma; + }; + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + RealType positiveDensityFlux( const RealType& density, const RealType& velocity, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity / speedOfSound; + if ( machNumber <= -1.0 ) + return 0.0; + else if ( machNumber <= 0.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( machNumber + 1.0 ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( ( 2.0 * this->gamma - 1.0 ) * machNumber + 1.0 ); + else + return density * velocity; + }; + + RealType negativeDensityFlux( const RealType& density, const RealType& velocity, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity / speedOfSound; + if ( machNumber <= -1.0 ) + return density * velocity; + else if ( machNumber <= 0.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( ( 2.0 * this->gamma - 1.0 ) * machNumber - 1.0 ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( machNumber - 1.0 ); + else + return 0.0; + }; + + RealType multiply (const RealType& a, const RealType& b ) const + { + return a * b; + }; + + + protected: + + RealType tau; + + RealType gamma; + + VelocityFieldPointer velocity; + + MeshFunctionPointer pressure; + +}; + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindContinuity +{ +}; + + + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindContinuity< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindContinuityBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + + return -hxInverse * ( + this->positiveDensityFlux( u[ center ], velocity_x_center, pressure_center ) + - this->positiveDensityFlux( u[ west ], velocity_x_west , pressure_west ) + - this->negativeDensityFlux( u[ center ], velocity_x_center, pressure_center ) + + this->negativeDensityFlux( u[ east ], velocity_x_east , pressure_east ) + ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindContinuity< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindContinuityBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + //rho + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + return -hxInverse * ( + this->positiveDensityFlux( u[ center ], velocity_x_center, pressure_center ) + - this->positiveDensityFlux( u[ west ], velocity_x_west , pressure_west ) + - this->negativeDensityFlux( u[ center ], velocity_x_center, pressure_center ) + + this->negativeDensityFlux( u[ east ], velocity_x_east , pressure_east ) + ) + -hyInverse * ( + this->positiveDensityFlux( u[ center ], velocity_y_center, pressure_center ) + - this->positiveDensityFlux( u[ south ], velocity_y_south , pressure_south ) + - this->negativeDensityFlux( u[ center ], velocity_y_center, pressure_center ) + + this->negativeDensityFlux( u[ north ], velocity_y_north , pressure_north ) + ); + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindContinuity< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindContinuityBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindContinuityBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + //rho + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + + const RealType& velocity_z_center = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + + return -hxInverse * ( + this->positiveDensityFlux( u[ center ], velocity_x_center, pressure_center ) + - this->positiveDensityFlux( u[ west ], velocity_x_west , pressure_west ) + - this->negativeDensityFlux( u[ center ], velocity_x_center, pressure_center ) + + this->negativeDensityFlux( u[ east ], velocity_x_east , pressure_east ) + ) + -hyInverse * ( + this->positiveDensityFlux( u[ center ], velocity_y_center, pressure_center ) + - this->positiveDensityFlux( u[ south ], velocity_y_south , pressure_south ) + - this->negativeDensityFlux( u[ center ], velocity_y_center, pressure_center ) + + this->negativeDensityFlux( u[ north ], velocity_y_north , pressure_north ) + ) + -hzInverse * ( + this->positiveDensityFlux( u[ center ], velocity_z_center, pressure_center ) + - this->positiveDensityFlux( u[ down ], velocity_z_down , pressure_down ) + - this->negativeDensityFlux( u[ center ], velocity_z_center, pressure_center ) + + this->negativeDensityFlux( u[ up ], velocity_z_up , pressure_up ) + ); + + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} //namespace TNL diff --git a/examples/flow-sw/UpwindEnergy.h b/examples/flow-sw/UpwindEnergy.h new file mode 100644 index 0000000000..913178e4b0 --- /dev/null +++ b/examples/flow-sw/UpwindEnergy.h @@ -0,0 +1,717 @@ +/*************************************************************************** + UpwindEnergy.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindEnergyBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + UpwindEnergyBase() + : artificialViscosity( 1.0 ){}; + + static String getType() + { + return String( "UpwindEnergy< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setGamma(const Real& gamma) + { + this->gamma = gamma; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }; + + void setDensity( const MeshFunctionPointer& density ) + { + this->density = density; + }; + + void setArtificialViscosity( const RealType& artificialViscosity ) + { + this->artificialViscosity = artificialViscosity; + }; + + void setDynamicalViscosity( const RealType& dynamicalViscosity ) + { + this->dynamicalViscosity = dynamicalViscosity; + } + + protected: + + RealType tau; + + RealType gamma; + + VelocityFieldPointer velocity; + + MeshFunctionPointer pressure; + + RealType artificialViscosity, dynamicalViscosity; + + MeshFunctionPointer density; +}; + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindEnergy +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindEnergy< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindEnergyBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + RealType positiveEnergyFlux( const RealType& density, const RealType& velocity_main, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return 0.0; + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( machNumber + 1.0 ) * 0.5 * ( machNumber * machNumber / ( speedOfSound * speedOfSound ) ) ) + + ( machNumber * ( machNumber + 1.0 ) ) + + ( ( machNumber + 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( ( 2.0 * this->gamma - 1.0 ) * machNumber + 1.0 ) * 0.5 * ( machNumber * machNumber / ( speedOfSound * speedOfSound ) ) ) + + ( machNumber * ( machNumber + 1.0 ) ) + + ( ( machNumber + 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else + return velocity_main * ( pressure + pressure / ( this->gamma - 1.0 ) + 0.5 * density * ( velocity_main * velocity_main ) ); + }; + + RealType negativeEnergyFlux( const RealType& density, const RealType& velocity_main, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return velocity_main * ( pressure + pressure / ( this->gamma - 1.0 ) + 0.5 * density * ( velocity_main * velocity_main ) ); + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( ( 2.0 * this->gamma - 1.0 ) * machNumber - 1.0 ) * 0.5 * ( machNumber * machNumber / ( speedOfSound * speedOfSound ) ) ) + - ( machNumber * ( machNumber - 1.0 ) ) + + ( ( machNumber - 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( machNumber - 1.0 ) * 0.5 * ( machNumber * machNumber / ( speedOfSound * speedOfSound ) ) ) + - ( machNumber * ( machNumber - 1.0 ) ) + + ( ( machNumber - 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else + return 0.0; + }; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + + return -hxInverse * ( + this->positiveEnergyFlux( density_center, velocity_x_center, pressure_center) + - this->positiveEnergyFlux( density_west , velocity_x_west , pressure_west ) + - this->negativeEnergyFlux( density_center, velocity_x_center, pressure_center) + + this->negativeEnergyFlux( density_east , velocity_x_east , pressure_east ) + ) +// 1D uT_11_x + - 4.0 / 3.0 * ( velocity_x_east * velocity_x_center - velocity_x_center * velocity_x_west + - velocity_x_center * velocity_x_center + velocity_x_west * velocity_x_west + ) * hxSquareInverse / 4 + * this->dynamicalViscosity; + + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindEnergyBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + RealType positiveEnergyFlux( const RealType& density, const RealType& velocity_main, const RealType& velocity_other1, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return 0.0; + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( machNumber + 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 ) / ( speedOfSound * speedOfSound ) ) ) + + ( machNumber * ( machNumber + 1.0 ) ) + + ( ( machNumber + 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( ( 2.0 * this->gamma - 1.0 ) * machNumber + 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 ) / ( speedOfSound * speedOfSound ) ) ) + + ( machNumber * ( machNumber + 1.0 ) ) + + ( ( machNumber + 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else + return velocity_main * ( pressure + pressure / ( this->gamma - 1.0 ) + 0.5 * density * ( velocity_main * velocity_main + velocity_other1 * velocity_other1 ) ); + }; + + RealType negativeEnergyFlux( const RealType& density, const RealType& velocity_main, const RealType& velocity_other1, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return velocity_main * ( pressure + pressure / ( this->gamma - 1.0 ) + 0.5 * density * ( velocity_main * velocity_main + velocity_other1 * velocity_other1 ) ); + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( ( 2.0 * this->gamma - 1.0 ) * machNumber - 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 ) / ( speedOfSound * speedOfSound ) ) ) + - ( machNumber * ( machNumber - 1.0 ) ) + + ( ( machNumber - 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( machNumber - 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 ) / ( speedOfSound * speedOfSound ) ) ) + - ( machNumber * ( machNumber - 1.0 ) ) + + ( ( machNumber - 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else + return 0.0; + }; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + const IndexType& southEast = neighborEntities.template getEntityIndex< 1, -1 >(); + const IndexType& southWest = neighborEntities.template getEntityIndex< -1, -1 >(); + const IndexType& northEast = neighborEntities.template getEntityIndex< 1, 1 >(); + const IndexType& northWest = neighborEntities.template getEntityIndex< -1, 1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + const RealType& density_north = this->density.template getData< DeviceType >()[ north ]; + const RealType& density_south = this->density.template getData< DeviceType >()[ south ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_south = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_x_north = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_x_southEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_x_southWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_x_northEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_x_northWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northWest ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_east = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_west = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_y_southEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_y_southWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_y_northEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_y_northWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northWest ]; + + return -hxInverse * ( + this->positiveEnergyFlux( density_center, velocity_x_center, velocity_y_center, pressure_center) + - this->positiveEnergyFlux( density_west , velocity_x_west , velocity_y_west , pressure_west ) + - this->negativeEnergyFlux( density_center, velocity_x_center, velocity_y_center, pressure_center) + + this->negativeEnergyFlux( density_east , velocity_x_east , velocity_y_east , pressure_east ) + ) + -hyInverse * ( + this->positiveEnergyFlux( density_center, velocity_y_center, velocity_x_center, pressure_center) + - this->positiveEnergyFlux( density_south , velocity_y_south , velocity_x_south , pressure_south ) + - this->negativeEnergyFlux( density_center, velocity_y_center, velocity_x_center, pressure_center) + + this->negativeEnergyFlux( density_north , velocity_y_north , velocity_x_north , pressure_north ) + ) +// 2D uT_11_x + + ( 4.0 / 3.0 * ( velocity_x_east * velocity_x_center - velocity_x_center * velocity_x_west + - velocity_x_center * velocity_x_center + velocity_x_west * velocity_x_west + ) * hxSquareInverse + - 2.0 / 3.0 * ( velocity_y_northEast * velocity_x_east - velocity_y_southEast * velocity_x_east + - velocity_y_northWest * velocity_x_west + velocity_y_southWest * velocity_x_west + ) * hxInverse * hyInverse / 4 + ) * this->dynamicalViscosity +// vT_21_x + + ( ( velocity_y_northEast * velocity_y_east - velocity_y_southEast * velocity_y_east + - velocity_y_northWest * velocity_y_west + velocity_y_southWest * velocity_y_west + ) * hxInverse * hyInverse / 4 + + ( velocity_x_east * velocity_y_center - velocity_x_center * velocity_y_west + - velocity_x_center * velocity_y_center + velocity_x_west * velocity_y_west + ) * hxSquareInverse + ) * this->dynamicalViscosity +// uT_12_y + + ( ( velocity_x_northEast * velocity_x_north - velocity_x_southEast * velocity_x_south + - velocity_x_northWest * velocity_x_north + velocity_x_southWest * velocity_x_south + ) * hxInverse * hyInverse / 4 + + ( velocity_y_north * velocity_x_center - velocity_y_center * velocity_x_south + - velocity_y_center * velocity_x_center + velocity_y_south * velocity_x_south + ) * hySquareInverse + ) * this->dynamicalViscosity +// 2D vT_22_y + + ( 4.0 / 3.0 * ( velocity_y_north * velocity_y_center - velocity_y_center * velocity_y_south + - velocity_y_center * velocity_y_center + velocity_y_south * velocity_y_south + ) * hySquareInverse + - 2.0 / 3.0 * ( velocity_x_northEast * velocity_y_north - velocity_x_southEast * velocity_y_east + - velocity_x_northWest * velocity_y_north + velocity_x_southWest * velocity_y_west + ) * hxInverse * hyInverse / 4 + ) * this->dynamicalViscosity; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindEnergy< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindEnergyBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindEnergyBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + RealType positiveEnergyFlux( const RealType& density, const RealType& velocity_main, const RealType& velocity_other1, const RealType& velocity_other2, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return 0.0; + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( machNumber + 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 + velocity_other2 * velocity_other2 ) / ( speedOfSound * speedOfSound ) ) ) + + ( machNumber * ( machNumber + 1.0 ) ) + + ( ( machNumber + 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( ( 2.0 * this->gamma - 1.0 ) * machNumber + 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 + velocity_other2 * velocity_other2 ) / ( speedOfSound * speedOfSound ) ) ) + + ( machNumber * ( machNumber + 1.0 ) ) + + ( ( machNumber + 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else + return velocity_main * ( pressure + pressure / ( this->gamma - 1.0 ) + 0.5 * density * ( velocity_main * velocity_main + velocity_other1 * velocity_other1 + velocity_other2 * velocity_other2 ) ); + }; + + RealType negativeEnergyFlux( const RealType& density, const RealType& velocity_main, const RealType& velocity_other1, const RealType& velocity_other2, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return velocity_main * ( pressure + pressure / ( this->gamma - 1.0 ) + 0.5 * density * ( velocity_main * velocity_main + velocity_other1 * velocity_other1 + velocity_other2 * velocity_other2 ) ); + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( ( 2.0 * this->gamma - 1.0 ) * machNumber - 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 + velocity_other2 * velocity_other2 ) / ( speedOfSound * speedOfSound ) ) ) + - ( machNumber * ( machNumber - 1.0 ) ) + + ( ( machNumber - 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound * speedOfSound / ( 2.0 * this->gamma ) + * ( + ( ( machNumber - 1.0 ) * 0.5 * ( machNumber * machNumber + ( velocity_other1 * velocity_other1 + velocity_other2 * velocity_other2 ) / ( speedOfSound * speedOfSound ) ) ) + - ( machNumber * ( machNumber - 1.0 ) ) + + ( ( machNumber - 1.0 ) / ( this->gamma - 1.0 ) ) + ); + else + return 0.0; + }; + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + const IndexType& northWest = neighborEntities.template getEntityIndex< -1, 1, 0 >(); + const IndexType& northEast = neighborEntities.template getEntityIndex< 1, 1, 0 >(); + const IndexType& southWest = neighborEntities.template getEntityIndex< -1, -1, 0 >(); + const IndexType& southEast = neighborEntities.template getEntityIndex< 1, -1, 0 >(); + const IndexType& upWest = neighborEntities.template getEntityIndex< -1, 0, 1 >(); + const IndexType& upEast = neighborEntities.template getEntityIndex< 1, 0, 1 >(); + const IndexType& upSouth = neighborEntities.template getEntityIndex< 0, -1, 1 >(); + const IndexType& upNorth = neighborEntities.template getEntityIndex< 0, 1, 1 >(); + const IndexType& downWest = neighborEntities.template getEntityIndex< -1, 0, -1 >(); + const IndexType& downEast = neighborEntities.template getEntityIndex< 1, 0, -1 >(); + const IndexType& downSouth = neighborEntities.template getEntityIndex< 0, -1, -1 >(); + const IndexType& downNorth = neighborEntities.template getEntityIndex< 0, 1, -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + const RealType& density_north = this->density.template getData< DeviceType >()[ north ]; + const RealType& density_south = this->density.template getData< DeviceType >()[ south ]; + const RealType& density_up = this->density.template getData< DeviceType >()[ up ]; + const RealType& density_down = this->density.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_north = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_x_south = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_x_up = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_x_down = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_x_northWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_x_northEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_x_southWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_x_southEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_x_upWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_x_downWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_x_upEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_x_downEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downEast ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_east = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_west = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_y_up = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_y_down = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_y_northWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_y_northEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_y_southWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_y_southEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_y_upNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_y_upSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_y_downNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_y_downSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downSouth ]; + + const RealType& velocity_z_center = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_z_east = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_z_west = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_z_north = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_z_south = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_z_upWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_z_upEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_z_upNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_z_upSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_z_downWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_z_downEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downEast ]; + const RealType& velocity_z_downNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_z_downSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downSouth ]; + + return -hxInverse * ( + this->positiveEnergyFlux( density_center, velocity_x_center, velocity_y_center, velocity_z_center, pressure_center) + - this->positiveEnergyFlux( density_west , velocity_x_west , velocity_y_west , velocity_z_west , pressure_west ) + - this->negativeEnergyFlux( density_center, velocity_x_center, velocity_y_center, velocity_z_center, pressure_center) + + this->negativeEnergyFlux( density_east , velocity_x_east , velocity_y_east , velocity_z_east , pressure_east ) + ) + -hyInverse * ( + this->positiveEnergyFlux( density_center, velocity_y_center, velocity_x_center, velocity_z_center, pressure_center) + - this->positiveEnergyFlux( density_south , velocity_y_south , velocity_x_south , velocity_z_south , pressure_south ) + - this->negativeEnergyFlux( density_center, velocity_y_center, velocity_x_center, velocity_z_center, pressure_center) + + this->negativeEnergyFlux( density_north , velocity_y_north , velocity_x_north , velocity_z_north , pressure_north ) + ) + -hyInverse * ( + this->positiveEnergyFlux( density_center, velocity_y_center, velocity_x_center, velocity_z_center, pressure_center) + - this->positiveEnergyFlux( density_down , velocity_y_down , velocity_x_down , velocity_z_down , pressure_down ) + - this->negativeEnergyFlux( density_center, velocity_y_center, velocity_x_center, velocity_z_center, pressure_center) + + this->negativeEnergyFlux( density_up , velocity_y_up , velocity_x_up , velocity_z_up , pressure_up ) + ) +// 3D uT_11_x + + ( 4.0 / 3.0 * ( velocity_x_east * velocity_x_center - velocity_x_center * velocity_x_west + - velocity_x_center * velocity_x_center + velocity_x_west * velocity_x_west + ) * hxSquareInverse + - 2.0 / 3.0 * ( velocity_y_northEast * velocity_x_east - velocity_y_southEast * velocity_x_east + - velocity_y_northWest * velocity_x_west + velocity_y_southWest * velocity_x_west + ) * hxInverse * hyInverse / 4 + - 2.0 / 3.0 * ( velocity_z_upEast * velocity_x_east - velocity_z_downEast * velocity_x_east + - velocity_z_upWest * velocity_x_west + velocity_z_downWest * velocity_x_west + ) * hxInverse * hzInverse / 4 + ) * this->dynamicalViscosity +// vT_21_x + + ( ( velocity_y_northEast * velocity_y_east - velocity_y_southEast * velocity_y_east + - velocity_y_northWest * velocity_y_west + velocity_y_southWest * velocity_y_west + ) * hxInverse * hyInverse / 4 + + ( velocity_x_east * velocity_y_center - velocity_x_center * velocity_y_west + - velocity_x_center * velocity_y_center + velocity_x_west * velocity_y_west + ) * hxSquareInverse + ) * this->dynamicalViscosity +// wT_31_x + + ( ( velocity_z_upEast * velocity_z_east - velocity_z_downEast * velocity_z_east + - velocity_z_upWest * velocity_z_west + velocity_z_downWest * velocity_z_west + ) * hxInverse * hzInverse / 4 + + ( velocity_x_east * velocity_z_center - velocity_x_center * velocity_z_west + - velocity_x_center * velocity_z_center + velocity_x_west * velocity_z_west + ) * hxSquareInverse + ) * this->dynamicalViscosity +// uT_12_y + + ( ( velocity_x_northEast * velocity_x_north - velocity_x_southEast * velocity_x_south + - velocity_x_northWest * velocity_x_north + velocity_x_southWest * velocity_x_south + ) * hxInverse * hyInverse / 4 + + ( velocity_y_north * velocity_x_center - velocity_y_center * velocity_x_south + + velocity_y_center * velocity_x_center + velocity_y_south * velocity_x_south + ) * hySquareInverse + ) * this->dynamicalViscosity +// 3D vT_22_y + + ( 4.0 / 3.0 * ( velocity_y_north * velocity_y_center - velocity_y_center * velocity_y_south + - velocity_y_center * velocity_y_center + velocity_y_south * velocity_y_south + ) * hySquareInverse + - 2.0 / 3.0 * ( velocity_x_northEast * velocity_y_north - velocity_x_southEast * velocity_y_south + - velocity_x_northWest * velocity_y_north + velocity_x_southWest * velocity_y_south + ) * hxInverse * hyInverse / 4 + - 2.0 / 3.0 * ( velocity_z_upNorth * velocity_y_north - velocity_z_downNorth * velocity_y_north + - velocity_z_upSouth * velocity_y_south + velocity_z_downSouth * velocity_y_south + ) * hyInverse * hzInverse / 4 + ) * this->dynamicalViscosity +// wT_32_y + + ( ( velocity_z_upNorth * velocity_z_north - velocity_z_downNorth * velocity_y_north + - velocity_z_upSouth * velocity_z_south + velocity_z_downSouth * velocity_z_south + ) * hyInverse * hzInverse / 4 + + ( velocity_y_north * velocity_z_center - velocity_y_center * velocity_z_south + - velocity_y_center * velocity_z_center + velocity_y_south * velocity_z_south + ) * hySquareInverse + ) * this->dynamicalViscosity +// uT_13_z + + ( ( velocity_z_up * velocity_x_center - velocity_z_center * velocity_x_center + - velocity_z_center * velocity_x_down + velocity_z_down * velocity_x_down + ) * hzSquareInverse + + ( velocity_x_upEast * velocity_x_up - velocity_x_downEast * velocity_x_down + - velocity_x_upWest * velocity_x_up + velocity_x_downWest * velocity_x_down + ) * hxInverse * hzInverse / 4 + ) * this->dynamicalViscosity +// T_23_z + + ( ( velocity_y_upNorth * velocity_y_up - velocity_y_downNorth * velocity_y_down + - velocity_y_upSouth * velocity_y_up + velocity_y_downSouth * velocity_y_down + ) * hyInverse * hzInverse / 4 + + ( velocity_z_up * velocity_y_center - velocity_z_center * velocity_y_down + - velocity_z_center * velocity_y_center + velocity_z_down * velocity_y_down + ) * hzSquareInverse + ) * this->dynamicalViscosity +// 3D T_33_z + + ( 4.0 / 3.0 * ( velocity_z_up * velocity_z_center - velocity_z_center * velocity_z_down + - velocity_z_center * velocity_z_center + velocity_z_down * velocity_z_down + ) * hzSquareInverse + - 2.0 / 3.0 * ( velocity_y_upNorth * velocity_z_up - velocity_y_downNorth * velocity_z_down + - velocity_y_upSouth * velocity_z_up + velocity_y_downSouth * velocity_z_down + ) * hyInverse * hzInverse / 4 + - 2.0 / 3.0 * ( velocity_x_upEast * velocity_z_up - velocity_x_downEast * velocity_z_down + - velocity_x_upWest * velocity_z_up + velocity_x_downWest * velocity_z_down + ) * hxInverse * hzInverse / 4 + ) * this->dynamicalViscosity; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +} //namespace TNL diff --git a/examples/flow-sw/UpwindMomentumBase.h b/examples/flow-sw/UpwindMomentumBase.h new file mode 100644 index 0000000000..bd85458657 --- /dev/null +++ b/examples/flow-sw/UpwindMomentumBase.h @@ -0,0 +1,137 @@ +/*************************************************************************** + UpwindMomentumBase.h - description + ------------------- + begin : Feb 17, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindMomentumBase +{ + public: + + typedef Real RealType; + typedef Index IndexType; + typedef Mesh MeshType; + typedef typename MeshType::DeviceType DeviceType; + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + static const int Dimensions = MeshType::getMeshDimension(); + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType > MeshFunctionPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setGamma(const Real& gamma) + { + this->gamma = gamma; + }; + + void setVelocity( const VelocityFieldPointer& velocity ) + { + this->velocity = velocity; + }; + + void setDensity( const MeshFunctionPointer& density ) + { + this->density = density; + }; + + void setPressure( const MeshFunctionPointer& pressure ) + { + this->pressure = pressure; + }; + + void setDynamicalViscosity( const RealType& dynamicalViscosity ) + { + this->dynamicalViscosity = dynamicalViscosity; + } + + RealType positiveMainMomentumFlux( const RealType& density, const RealType& velocity, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity / speedOfSound; + if ( machNumber <= -1.0 ) + return 0; + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( ( machNumber + 1.0 ) * ( machNumber + 1.0 ) ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( 2.0 * ( this->gamma - 1.0 ) * machNumber * machNumber + (machNumber + 1.0 ) * (machNumber + 1.0 ) ); + else + return density * velocity * velocity + pressure; + }; + + RealType negativeMainMomentumFlux( const RealType& density, const RealType& velocity, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity / speedOfSound; + if ( machNumber <= -1.0 ) + return density * velocity * velocity + pressure; + else if ( machNumber <= 0.0 ) + return density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( 2.0 * ( this->gamma - 1.0 ) * machNumber * machNumber + (machNumber - 1.0 ) * (machNumber - 1.0 ) ); + else if ( machNumber <= 1.0 ) + return density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( ( machNumber - 1.0 ) * ( machNumber - 1.0 ) ); + else + return 0; + }; + + RealType positiveOtherMomentumFlux( const RealType& density, const RealType& velocity_main, const RealType& velocity_other, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return 0.0; + else if ( machNumber <= 0.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( machNumber + 1.0 ) * velocity_other; + else if ( machNumber <= 1.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( ( 2.0 * this->gamma - 1.0 ) * machNumber + 1.0 ) * velocity_other; + else + return density * velocity_main * velocity_other; + }; + + RealType negativeOtherMomentumFlux( const RealType& density, const RealType& velocity_main, const RealType& velocity_other, const RealType& pressure ) const + { + const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); + const RealType& machNumber = velocity_main / speedOfSound; + if ( machNumber <= -1.0 ) + return density * velocity_main * velocity_other; + else if ( machNumber <= 0.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( ( 2.0 * this->gamma - 1.0 ) * machNumber - 1.0 ) * velocity_other; + else if ( machNumber <= 1.0 ) + return density * speedOfSound / ( 2 * this->gamma ) * ( machNumber - 1.0 ) * velocity_other; + else + return 0.0; + }; + + protected: + + RealType tau; + + RealType gamma; + + VelocityFieldPointer velocity; + + MeshFunctionPointer pressure; + + RealType dynamicalViscosity; + + MeshFunctionPointer density; + +}; + +} //namespace TNL diff --git a/examples/flow-sw/UpwindMomentumX.h b/examples/flow-sw/UpwindMomentumX.h new file mode 100644 index 0000000000..edd3756208 --- /dev/null +++ b/examples/flow-sw/UpwindMomentumX.h @@ -0,0 +1,433 @@ +/*************************************************************************** + UpwindMomentumX.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "UpwindMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindMomentumX +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumX< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + + return -hxInverse * ( + this->positiveMainMomentumFlux( density_center, velocity_x_center, pressure_center ) + - this->positiveMainMomentumFlux( density_west, velocity_x_west , pressure_west ) + - this->negativeMainMomentumFlux( density_center, velocity_x_center, pressure_center ) + + this->negativeMainMomentumFlux( density_east, velocity_x_east , pressure_east ) + ) +// 1D T_11_x + - 4.0 / 3.0 *( velocity_x_east - 2 * velocity_x_center + velocity_x_west + ) * hxSquareInverse + * this->dynamicalViscosity; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumX< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + const IndexType& southEast = neighborEntities.template getEntityIndex< 1, -1 >(); + const IndexType& southWest = neighborEntities.template getEntityIndex< -1, -1 >(); + const IndexType& northEast = neighborEntities.template getEntityIndex< 1, 1 >(); + const IndexType& northWest = neighborEntities.template getEntityIndex< -1, 1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + const RealType& density_north = this->density.template getData< DeviceType >()[ north ]; + const RealType& density_south = this->density.template getData< DeviceType >()[ south ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_south = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_x_north = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_x_southEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_x_southWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_x_northEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_x_northWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northWest ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_y_southEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_y_southWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_y_northEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_y_northWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northWest ]; + + return -hxInverse * ( + this->positiveMainMomentumFlux( density_center, velocity_x_center, pressure_center ) + - this->positiveMainMomentumFlux( density_west , velocity_x_west , pressure_west ) + - this->negativeMainMomentumFlux( density_center, velocity_x_center, pressure_center ) + + this->negativeMainMomentumFlux( density_east , velocity_x_east , pressure_east ) + ) + -hyInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_x_center, velocity_y_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_south , velocity_x_south , velocity_y_south , pressure_south ) + - this->negativeOtherMomentumFlux( density_center, velocity_x_center, velocity_y_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_north , velocity_x_north , velocity_y_north , pressure_north ) + ) +// 2D T_11_x + + ( 4.0 / 3.0 * ( velocity_x_east - 2 * velocity_x_center + velocity_x_west + ) * hxSquareInverse + - 2.0 / 3.0 * ( velocity_y_northEast - velocity_y_southEast - velocity_y_northWest + velocity_y_southWest + ) * hxInverse * hyInverse / 4 + ) * this->dynamicalViscosity +// T_21_y + + ( ( velocity_y_northEast - velocity_y_southEast - velocity_y_northWest + velocity_y_southWest + ) * hxInverse * hyInverse / 4 + + ( velocity_x_north - 2 * velocity_x_center + velocity_x_south + ) * hxInverse * hyInverse + ) * this->dynamicalViscosity; + + + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumX< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumX< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + const IndexType& northWest = neighborEntities.template getEntityIndex< -1, 1, 0 >(); + const IndexType& northEast = neighborEntities.template getEntityIndex< 1, 1, 0 >(); + const IndexType& southWest = neighborEntities.template getEntityIndex< -1, -1, 0 >(); + const IndexType& southEast = neighborEntities.template getEntityIndex< 1, -1, 0 >(); + const IndexType& upWest = neighborEntities.template getEntityIndex< -1, 0, 1 >(); + const IndexType& upEast = neighborEntities.template getEntityIndex< 1, 0, 1 >(); + const IndexType& upSouth = neighborEntities.template getEntityIndex< 0, -1, 1 >(); + const IndexType& upNorth = neighborEntities.template getEntityIndex< 0, 1, 1 >(); + const IndexType& downWest = neighborEntities.template getEntityIndex< -1, 0, -1 >(); + const IndexType& downEast = neighborEntities.template getEntityIndex< 1, 0, -1 >(); + const IndexType& downSouth = neighborEntities.template getEntityIndex< 0, -1, -1 >(); + const IndexType& downNorth = neighborEntities.template getEntityIndex< 0, 1, -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + const RealType& density_north = this->density.template getData< DeviceType >()[ north ]; + const RealType& density_south = this->density.template getData< DeviceType >()[ south ]; + const RealType& density_up = this->density.template getData< DeviceType >()[ up ]; + const RealType& density_down = this->density.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_north = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_x_south = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_x_up = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_x_down = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_x_northWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_x_northEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_x_southWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_x_southEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_x_upWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_x_downWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_x_upEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_x_downEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downEast ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_y_northWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_y_northEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_y_southWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_y_southEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_y_upNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_y_upSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_y_downNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_y_downSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downSouth ]; + + const RealType& velocity_z_center = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_z_upWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_z_upEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_z_upNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_z_upSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_z_downWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_z_downEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downEast ]; + const RealType& velocity_z_downNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_z_downSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downSouth ]; + + return -hxInverse * ( + this->positiveMainMomentumFlux( density_center, velocity_x_center, pressure_center ) + - this->positiveMainMomentumFlux( density_west , velocity_x_west , pressure_west ) + - this->negativeMainMomentumFlux( density_center, velocity_x_center, pressure_center ) + + this->negativeMainMomentumFlux( density_east , velocity_x_east , pressure_east ) + ) + -hyInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_x_center, velocity_y_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_south , velocity_x_south , velocity_y_south , pressure_south ) + - this->negativeOtherMomentumFlux( density_center, velocity_x_center, velocity_y_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_north , velocity_x_north , velocity_y_north , pressure_north ) + ) + -hzInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_x_center, velocity_z_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_down , velocity_x_down , velocity_z_down , pressure_down ) + - this->negativeOtherMomentumFlux( density_center, velocity_x_center, velocity_z_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_up , velocity_x_up , velocity_z_up , pressure_up ) + ) +// 3D T_11_x + + ( 4.0 / 3.0 * ( velocity_x_east - 2 * velocity_x_center + velocity_x_west + ) * hxSquareInverse + - 2.0 / 3.0 * ( velocity_y_northEast - velocity_y_southEast - velocity_y_northWest + velocity_y_southWest + ) * hxInverse * hyInverse / 4 + - 2.0 / 3.0 * ( velocity_z_upEast - velocity_z_downEast - velocity_z_upWest + velocity_z_downWest + ) * hxInverse * hzInverse / 4 + ) * this->dynamicalViscosity +// T_21_x + + ( ( velocity_y_northEast - velocity_y_southEast - velocity_y_northWest + velocity_y_southWest + ) * hxInverse * hyInverse / 4 + + ( velocity_x_east - 2 * velocity_x_center + velocity_x_west + ) * hxSquareInverse + ) * this->dynamicalViscosity +// T_31_x + + ( ( velocity_z_upEast - velocity_z_downEast - velocity_z_upWest + velocity_z_downWest + ) * hxInverse * hzInverse / 4 + + ( velocity_x_east - 2 * velocity_x_center + velocity_x_west + ) * hxSquareInverse + ) * this->dynamicalViscosity; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} // namespace TNL + diff --git a/examples/flow-sw/UpwindMomentumY.h b/examples/flow-sw/UpwindMomentumY.h new file mode 100644 index 0000000000..4b5a7bcb26 --- /dev/null +++ b/examples/flow-sw/UpwindMomentumY.h @@ -0,0 +1,403 @@ +/*************************************************************************** + UpwindMomentumY.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "UpwindMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindMomentumY +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumY< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_v, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + //const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumY< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + const IndexType& southEast = neighborEntities.template getEntityIndex< 1, -1 >(); + const IndexType& southWest = neighborEntities.template getEntityIndex< -1, -1 >(); + const IndexType& northEast = neighborEntities.template getEntityIndex< 1, 1 >(); + const IndexType& northWest = neighborEntities.template getEntityIndex< -1, 1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + const RealType& density_north = this->density.template getData< DeviceType >()[ north ]; + const RealType& density_south = this->density.template getData< DeviceType >()[ south ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_southEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_x_southWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_x_northEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_x_northWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northWest ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_east = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_west = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_y_southEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_y_southWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_y_northEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_y_northWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northWest ]; + + return -hxInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_y_center, velocity_x_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_west , velocity_y_west , velocity_x_west , pressure_west ) + - this->negativeOtherMomentumFlux( density_center, velocity_y_center, velocity_x_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_east , velocity_y_east , velocity_x_east , pressure_east ) + ) + -hyInverse * ( + this->positiveMainMomentumFlux( density_center, velocity_y_center, pressure_center ) + - this->positiveMainMomentumFlux( density_south , velocity_y_south , pressure_south ) + - this->negativeMainMomentumFlux( density_center, velocity_y_center, pressure_center ) + + this->negativeMainMomentumFlux( density_north , velocity_y_north , pressure_north ) + ) +// 2D T_22_y + + ( 4.0 / 3.0 * ( velocity_y_north - 2 * velocity_y_center + velocity_y_south + ) * hySquareInverse + - 2.0 / 3.0 * ( velocity_x_northEast - velocity_x_southEast - velocity_x_northWest + velocity_x_southWest + ) * hxInverse * hyInverse / 4 + ) * this->dynamicalViscosity +// T_12_x + + ( ( velocity_x_northEast - velocity_x_southEast - velocity_x_northWest + velocity_x_southWest + ) * hxInverse * hyInverse / 4 + + ( velocity_y_west - 2 * velocity_y_center + velocity_y_east + ) * hxSquareInverse + ) * this->dynamicalViscosity; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumY< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumY< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + const IndexType& northWest = neighborEntities.template getEntityIndex< -1, 1, 0 >(); + const IndexType& northEast = neighborEntities.template getEntityIndex< 1, 1, 0 >(); + const IndexType& southWest = neighborEntities.template getEntityIndex< -1, -1, 0 >(); + const IndexType& southEast = neighborEntities.template getEntityIndex< 1, -1, 0 >(); + const IndexType& upWest = neighborEntities.template getEntityIndex< -1, 0, 1 >(); + const IndexType& upEast = neighborEntities.template getEntityIndex< 1, 0, 1 >(); + const IndexType& upSouth = neighborEntities.template getEntityIndex< 0, -1, 1 >(); + const IndexType& upNorth = neighborEntities.template getEntityIndex< 0, 1, 1 >(); + const IndexType& downWest = neighborEntities.template getEntityIndex< -1, 0, -1 >(); + const IndexType& downEast = neighborEntities.template getEntityIndex< 1, 0, -1 >(); + const IndexType& downSouth = neighborEntities.template getEntityIndex< 0, -1, -1 >(); + const IndexType& downNorth = neighborEntities.template getEntityIndex< 0, 1, -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + const RealType& density_north = this->density.template getData< DeviceType >()[ north ]; + const RealType& density_south = this->density.template getData< DeviceType >()[ south ]; + const RealType& density_up = this->density.template getData< DeviceType >()[ up ]; + const RealType& density_down = this->density.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_northWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_x_northEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_x_southWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_x_southEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_x_upWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_x_downWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_x_upEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_x_downEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downEast ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_east = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_y_west = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_y_up = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_y_down = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_y_northWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_y_northEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_y_southWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_y_southEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_y_upNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_y_upSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_y_downNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_y_downSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downSouth ]; + + const RealType& velocity_z_center = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_z_upWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_z_upEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_z_upNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_z_upSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_z_downWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_z_downEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downEast ]; + const RealType& velocity_z_downNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_z_downSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downSouth ]; + + return -hxInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_y_center, velocity_x_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_west , velocity_y_west , velocity_x_west , pressure_west ) + - this->negativeOtherMomentumFlux( density_center, velocity_y_center, velocity_x_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_east , velocity_y_east , velocity_x_east , pressure_east ) + ) + -hyInverse * ( + this->positiveMainMomentumFlux( density_center, velocity_y_center, pressure_center ) + - this->positiveMainMomentumFlux( density_south , velocity_y_south , pressure_south ) + - this->negativeMainMomentumFlux( density_center, velocity_y_center, pressure_center ) + + this->negativeMainMomentumFlux( density_north , velocity_y_north , pressure_north ) + ) + -hzInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_y_center, velocity_z_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_down , velocity_y_down , velocity_z_down , pressure_down ) + - this->negativeOtherMomentumFlux( density_center, velocity_y_center, velocity_z_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_up , velocity_y_up , velocity_z_up , pressure_up ) + ) +// T_12_y + + ( ( velocity_x_northEast - velocity_x_southEast - velocity_x_northWest + velocity_x_southWest + ) * hxInverse * hyInverse / 4 + + ( velocity_y_north - 2 * velocity_y_center + velocity_y_south + ) * hySquareInverse + ) * this->dynamicalViscosity +// 3D T_22_y + + ( 4.0 / 3.0 * ( velocity_y_north - 2 * velocity_y_center + velocity_y_south + ) * hySquareInverse + - 2.0 / 3.0 * ( velocity_x_northEast - velocity_x_southEast - velocity_x_northWest + velocity_x_southWest + ) * hxInverse * hyInverse / 4 + - 2.0 / 3.0 * ( velocity_z_upNorth - velocity_z_downNorth - velocity_z_upSouth + velocity_z_downSouth + ) * hyInverse * hzInverse / 4 + ) * this->dynamicalViscosity +// T_32_y + + ( ( velocity_z_upNorth - velocity_z_downNorth - velocity_z_upSouth + velocity_z_downSouth + ) * hyInverse * hzInverse / 4 + + ( velocity_y_north - 2 * velocity_y_center + velocity_y_south + ) * hySquareInverse + ) * this->dynamicalViscosity; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} // namespace TNL + diff --git a/examples/flow-sw/UpwindMomentumZ.h b/examples/flow-sw/UpwindMomentumZ.h new file mode 100644 index 0000000000..887eec9775 --- /dev/null +++ b/examples/flow-sw/UpwindMomentumZ.h @@ -0,0 +1,338 @@ +/*************************************************************************** + UpwindMomentumZ.h - description + ------------------- + begin : Feb 18, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + + +#pragma once + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include "UpwindMomentumBase.h" + +namespace TNL { + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType > +class UpwindMomentumZ +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumZ< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + //const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumZ< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& rho_w, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + //const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + return 0.0; + } + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index > +class UpwindMomentumZ< Meshes::Grid< 3,MeshReal, Device, MeshIndex >, Real, Index > + : public UpwindMomentumBase< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index > +{ + public: + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef UpwindMomentumBase< MeshType, Real, Index > BaseType; + + using typename BaseType::RealType; + using typename BaseType::IndexType; + using typename BaseType::DeviceType; + using typename BaseType::CoordinatesType; + using typename BaseType::MeshFunctionType; + using typename BaseType::MeshFunctionPointer; + using typename BaseType::VelocityFieldType; + using typename BaseType::VelocityFieldPointer; + using BaseType::Dimensions; + + static String getType() + { + return String( "UpwindMomentumZ< " ) + + MeshType::getType() + ", " + + TNL::getType< Real >() + ", " + + TNL::getType< Index >() + " >"; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const RealType& hxSquareInverse = entity.getMesh().template getSpaceStepsProducts< -2, 0, 0 >(); + const RealType& hySquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, -2, 0 >(); + const RealType& hzSquareInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -2 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + const IndexType& northWest = neighborEntities.template getEntityIndex< -1, 1, 0 >(); + const IndexType& northEast = neighborEntities.template getEntityIndex< 1, 1, 0 >(); + const IndexType& southWest = neighborEntities.template getEntityIndex< -1, -1, 0 >(); + const IndexType& southEast = neighborEntities.template getEntityIndex< 1, -1, 0 >(); + const IndexType& upWest = neighborEntities.template getEntityIndex< -1, 0, 1 >(); + const IndexType& upEast = neighborEntities.template getEntityIndex< 1, 0, 1 >(); + const IndexType& upSouth = neighborEntities.template getEntityIndex< 0, -1, 1 >(); + const IndexType& upNorth = neighborEntities.template getEntityIndex< 0, 1, 1 >(); + const IndexType& downWest = neighborEntities.template getEntityIndex< -1, 0, -1 >(); + const IndexType& downEast = neighborEntities.template getEntityIndex< 1, 0, -1 >(); + const IndexType& downSouth = neighborEntities.template getEntityIndex< 0, -1, -1 >(); + const IndexType& downNorth = neighborEntities.template getEntityIndex< 0, 1, -1 >(); + + const RealType& pressure_center = this->pressure.template getData< DeviceType >()[ center ]; + const RealType& pressure_west = this->pressure.template getData< DeviceType >()[ west ]; + const RealType& pressure_east = this->pressure.template getData< DeviceType >()[ east ]; + const RealType& pressure_north = this->pressure.template getData< DeviceType >()[ north ]; + const RealType& pressure_south = this->pressure.template getData< DeviceType >()[ south ]; + const RealType& pressure_up = this->pressure.template getData< DeviceType >()[ up ]; + const RealType& pressure_down = this->pressure.template getData< DeviceType >()[ down ]; + + const RealType& density_center = this->density.template getData< DeviceType >()[ center ]; + const RealType& density_west = this->density.template getData< DeviceType >()[ west ]; + const RealType& density_east = this->density.template getData< DeviceType >()[ east ]; + const RealType& density_north = this->density.template getData< DeviceType >()[ north ]; + const RealType& density_south = this->density.template getData< DeviceType >()[ south ]; + const RealType& density_up = this->density.template getData< DeviceType >()[ up ]; + const RealType& density_down = this->density.template getData< DeviceType >()[ down ]; + + const RealType& velocity_x_center = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_x_east = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_x_west = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_x_northWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_x_northEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_x_southWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_x_southEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_x_upWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_x_downWest = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_x_upEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_x_downEast = this->velocity.template getData< DeviceType >()[ 0 ].template getData< DeviceType >()[ downEast ]; + + const RealType& velocity_y_center = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_y_north = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_y_south = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_y_northWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northWest ]; + const RealType& velocity_y_northEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ northEast ]; + const RealType& velocity_y_southWest = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southWest ]; + const RealType& velocity_y_southEast = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ southEast ]; + const RealType& velocity_y_upNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_y_upSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_y_downNorth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_y_downSouth = this->velocity.template getData< DeviceType >()[ 1 ].template getData< DeviceType >()[ downSouth ]; + + const RealType& velocity_z_center = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ center ]; + const RealType& velocity_z_east = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ east ]; + const RealType& velocity_z_west = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ west ]; + const RealType& velocity_z_north = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ north ]; + const RealType& velocity_z_south = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ south ]; + const RealType& velocity_z_up = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ up ]; + const RealType& velocity_z_down = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ down ]; + const RealType& velocity_z_upWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upWest ]; + const RealType& velocity_z_upEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upEast ]; + const RealType& velocity_z_upNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upNorth ]; + const RealType& velocity_z_upSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ upSouth ]; + const RealType& velocity_z_downWest = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downWest ]; + const RealType& velocity_z_downEast = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downEast ]; + const RealType& velocity_z_downNorth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downNorth ]; + const RealType& velocity_z_downSouth = this->velocity.template getData< DeviceType >()[ 2 ].template getData< DeviceType >()[ downSouth ]; + + return -hxInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_z_center, velocity_x_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_west , velocity_z_west , velocity_x_west , pressure_west ) + - this->negativeOtherMomentumFlux( density_center, velocity_z_center, velocity_x_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_east , velocity_z_east , velocity_x_east , pressure_east ) + ) + -hyInverse * ( + this->positiveOtherMomentumFlux( density_center, velocity_z_center, velocity_y_center, pressure_center ) + - this->positiveOtherMomentumFlux( density_south , velocity_z_south , velocity_y_south , pressure_south ) + - this->negativeOtherMomentumFlux( density_center, velocity_z_center, velocity_y_center, pressure_center ) + + this->negativeOtherMomentumFlux( density_north , velocity_z_north , velocity_y_north , pressure_north ) + ) + -hzInverse * ( + this->positiveMainMomentumFlux( density_center, velocity_z_center, pressure_center ) + - this->positiveMainMomentumFlux( density_down , velocity_z_down , pressure_down ) + - this->negativeMainMomentumFlux( density_center, velocity_z_center, pressure_center ) + + this->negativeMainMomentumFlux( density_up , velocity_z_up , pressure_up ) + ) +// T_13_z + + ( ( velocity_z_up - 2 * velocity_z_center + velocity_z_down ) + * hzSquareInverse + + ( velocity_x_upEast - velocity_x_downEast - velocity_x_upWest + velocity_x_downWest ) + * hxInverse * hzInverse / 4 + ) + * this->dynamicalViscosity +// T_23_z + + ( ( velocity_y_upNorth - velocity_y_downNorth - velocity_y_upSouth + velocity_y_downSouth ) + * hyInverse * hzInverse / 4 + + ( velocity_z_up - 2 * velocity_z_center + velocity_z_down ) + * hzSquareInverse + ) + * this->dynamicalViscosity +// 3D T_33_z + + ( 4.0 / 3.0 * ( velocity_z_up - 2 * velocity_z_center + velocity_z_down ) + * hzSquareInverse + - 2.0 / 3.0 * ( velocity_y_upNorth - velocity_y_downNorth - velocity_y_upSouth + velocity_y_downSouth ) + * hyInverse * hzInverse / 4 + - 2.0 / 3.0 * ( velocity_x_upEast - velocity_x_downEast - velocity_x_upWest + velocity_x_downWest ) + * hxInverse * hzInverse / 4 + ) + * this->dynamicalViscosity; + } + + + /*template< typename MeshEntity > + __cuda_callable__ + Index getLinearSystemRowLength( const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity ) const; + + template< typename MeshEntity, typename Vector, typename MatrixRow > + __cuda_callable__ + void updateLinearSystem( const RealType& time, + const RealType& tau, + const MeshType& mesh, + const IndexType& index, + const MeshEntity& entity, + const MeshFunctionType& u, + Vector& b, + MatrixRow& matrixRow ) const;*/ +}; + + +} // namespace TNL + diff --git a/examples/flow-sw/navierStokes.cpp b/examples/flow-sw/navierStokes.cpp new file mode 100644 index 0000000000..7dffcb059f --- /dev/null +++ b/examples/flow-sw/navierStokes.cpp @@ -0,0 +1 @@ +#include "navierStokes.h" diff --git a/examples/flow-sw/navierStokes.cu b/examples/flow-sw/navierStokes.cu new file mode 100644 index 0000000000..7dffcb059f --- /dev/null +++ b/examples/flow-sw/navierStokes.cu @@ -0,0 +1 @@ +#include "navierStokes.h" diff --git a/examples/flow-sw/navierStokes.h b/examples/flow-sw/navierStokes.h new file mode 100644 index 0000000000..b4cf74bfee --- /dev/null +++ b/examples/flow-sw/navierStokes.h @@ -0,0 +1,107 @@ +#include <TNL/tnlConfig.h> +#include <TNL/Solvers/Solver.h> +#include <TNL/Solvers/BuildConfigTags.h> +#include <TNL/Operators/DirichletBoundaryConditions.h> +#include <TNL/Operators/NeumannBoundaryConditions.h> +#include <TNL/Functions/Analytic/Constant.h> +#include "navierStokesProblem.h" +#include "Upwind.h" +#include "navierStokesRhs.h" +#include "navierStokesBuildConfigTag.h" + +#include "RiemannProblemInitialCondition.h" +#include "BoundaryConditionsCavity.h" +#include "BoundaryConditionsBoiler.h" + +using namespace TNL; + +typedef navierStokesBuildConfigTag BuildConfig; + +/**** + * Uncomment the following (and comment the previous line) for the complete build. + * This will include support for all floating point precisions, all indexing types + * and more solvers. You may then choose between them from the command line. + * The compile time may, however, take tens of minutes or even several hours, + * especially if CUDA is enabled. Use this, if you want, only for the final build, + * not in the development phase. + */ +//typedef tnlDefaultConfigTag BuildConfig; + +template< typename ConfigTag >class navierStokesConfig +{ + public: + static void configSetup( Config::ConfigDescription & config ) + { + config.addDelimiter( "Inviscid flow settings:" ); + config.addEntry< String >( "boundary-conditions-type", "Choose the boundary conditions type.", "cavity"); + config.addEntryEnum< String >( "boiler" ); + config.addEntryEnum< String >( "cavity" ); + config.addEntry< double >( "boundary-conditions-constant", "This sets a value in case of the constant boundary conditions." ); + config.addEntry< double >( "speed-increment", "This sets increment of input speed.", 0.0 ); + config.addEntry< double >( "speed-increment-until", "This sets time until input speed will rose", -0.1 ); + config.addEntry< double >( "cavity-speed", "This sets speed parameter of cavity", 0.0 ); + typedef Meshes::Grid< 3 > Mesh; + Upwind< Mesh >::configSetup( config, "inviscid-operators-" ); + RiemannProblemInitialCondition< Mesh >::configSetup( config ); + + /**** + * Add definition of your solver command line arguments. + */ + + } +}; + +template< typename Real, + typename Device, + typename Index, + typename MeshType, + typename ConfigTag, + typename SolverStarter > +class navierStokesSetter +{ + public: + + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + + static bool run( const Config::ParameterContainer & parameters ) + { + enum { Dimension = MeshType::getMeshDimension() }; + typedef Upwind< MeshType, Real, Index > ApproximateOperator; + typedef navierStokesRhs< MeshType, Real > RightHandSide; + typedef Containers::StaticVector < MeshType::getMeshDimension(), Real > Point; + + /**** + * Resolve the template arguments of your solver here. + * The following code is for the Dirichlet and the Neumann boundary conditions. + * Both can be constant or defined as descrete values of Vector. + */ + typedef Functions::Analytic::Constant< Dimension, Real > Constant; + String boundaryConditionsType = parameters.getParameter< String >( "boundary-conditions-type" ); + if( boundaryConditionsType == "cavity" ) + { + typedef BoundaryConditionsCavity< MeshType, Constant, Real, Index > BoundaryConditions; + typedef navierStokesProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + if( boundaryConditionsType == "boiler" ) + { + typedef BoundaryConditionsBoiler< MeshType, Constant, Real, Index > BoundaryConditions; + typedef navierStokesProblem< MeshType, BoundaryConditions, RightHandSide, ApproximateOperator > Problem; + SolverStarter solverStarter; + return solverStarter.template run< Problem >( parameters ); + } + + return true;} + +}; + +int main( int argc, char* argv[] ) +{ + Solvers::Solver< navierStokesSetter, navierStokesConfig, BuildConfig > solver; + if( ! solver. run( argc, argv ) ) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/examples/flow-sw/navierStokesBuildConfigTag.h b/examples/flow-sw/navierStokesBuildConfigTag.h new file mode 100644 index 0000000000..f84233ade4 --- /dev/null +++ b/examples/flow-sw/navierStokesBuildConfigTag.h @@ -0,0 +1,51 @@ +#ifndef navierStokesBUILDCONFIGTAG_H_ +#define navierStokesBUILDCONFIGTAG_H_ + +#include <TNL/Solvers/BuildConfigTags.h> + +namespace TNL { + +class navierStokesBuildConfigTag{}; + +namespace Solvers { + +/**** + * Turn off support for float and long double. + */ +template<> struct ConfigTagReal< navierStokesBuildConfigTag, float > { enum { enabled = false }; }; +template<> struct ConfigTagReal< navierStokesBuildConfigTag, long double > { enum { enabled = false }; }; + +/**** + * Turn off support for short int and long int indexing. + */ +template<> struct ConfigTagIndex< navierStokesBuildConfigTag, short int >{ enum { enabled = false }; }; +template<> struct ConfigTagIndex< navierStokesBuildConfigTag, long int >{ enum { enabled = false }; }; + +//template< int Dimension > struct ConfigTagDimension< navierStokesBuildConfigTag, Dimension >{ enum { enabled = ( Dimension == 1 ) }; }; + +/**** + * Use of Grid is enabled for allowed dimensions and Real, Device and Index types. + */ +template< int Dimension, typename Real, typename Device, typename Index > + struct ConfigTagMesh< navierStokesBuildConfigTag, Meshes::Grid< Dimension, Real, Device, Index > > + { enum { enabled = ConfigTagDimension< navierStokesBuildConfigTag, Dimension >::enabled && + ConfigTagReal< navierStokesBuildConfigTag, Real >::enabled && + ConfigTagDevice< navierStokesBuildConfigTag, Device >::enabled && + ConfigTagIndex< navierStokesBuildConfigTag, Index >::enabled }; }; + +/**** + * Please, chose your preferred time discretisation here. + */ +template<> struct ConfigTagTimeDiscretisation< navierStokesBuildConfigTag, ExplicitTimeDiscretisationTag >{ enum { enabled = true }; }; +template<> struct ConfigTagTimeDiscretisation< navierStokesBuildConfigTag, SemiImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; +template<> struct ConfigTagTimeDiscretisation< navierStokesBuildConfigTag, ImplicitTimeDiscretisationTag >{ enum { enabled = false }; }; + +/**** + * Only the Runge-Kutta-Merson solver is enabled by default. + */ +template<> struct ConfigTagExplicitSolver< navierStokesBuildConfigTag, ExplicitEulerSolverTag >{ enum { enabled = true }; }; + +} // namespace Solvers +} // namespace TNL + +#endif /* navierStokesBUILDCONFIGTAG_H_ */ diff --git a/examples/flow-sw/navierStokesProblem.h b/examples/flow-sw/navierStokesProblem.h new file mode 100644 index 0000000000..2d8f4c2e1d --- /dev/null +++ b/examples/flow-sw/navierStokesProblem.h @@ -0,0 +1,133 @@ +/*************************************************************************** + navierStokesProblem.h - description + ------------------- + begin : Feb 13, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/Problems/PDEProblem.h> +#include <TNL/Functions/MeshFunction.h> +#include "CompressibleConservativeVariables.h" + + +using namespace TNL::Problems; + +namespace TNL { + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +class navierStokesProblem: + public PDEProblem< Mesh, + typename InviscidOperators::RealType, + typename Mesh::DeviceType, + typename InviscidOperators::IndexType > +{ + public: + + typedef typename InviscidOperators::RealType RealType; + typedef typename Mesh::DeviceType DeviceType; + typedef typename InviscidOperators::IndexType IndexType; + typedef PDEProblem< Mesh, RealType, DeviceType, IndexType > BaseType; + + using typename BaseType::MeshType; + using typename BaseType::MeshPointer; + using typename BaseType::DofVectorType; + using typename BaseType::DofVectorPointer; + using typename BaseType::MeshDependentDataType; + using typename BaseType::MeshDependentDataPointer; + + static const int Dimensions = Mesh::getMeshDimension(); + + typedef Functions::MeshFunction< Mesh > MeshFunctionType; + typedef CompressibleConservativeVariables< MeshType > ConservativeVariablesType; + typedef Functions::VectorField< Dimensions, MeshFunctionType > VelocityFieldType; + typedef SharedPointer< MeshFunctionType, DeviceType > MeshFunctionPointer; + typedef SharedPointer< ConservativeVariablesType > ConservativeVariablesPointer; + typedef SharedPointer< VelocityFieldType > VelocityFieldPointer; + typedef SharedPointer< InviscidOperators > InviscidOperatorsPointer; + typedef SharedPointer< BoundaryCondition > BoundaryConditionPointer; + typedef SharedPointer< RightHandSide, DeviceType > RightHandSidePointer; + + static String getTypeStatic(); + + String getPrologHeader() const; + + void writeProlog( Logger& logger, + const Config::ParameterContainer& parameters ) const; + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ); + + bool setInitialCondition( const Config::ParameterContainer& parameters, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ); + + template< typename Matrix > + bool setupLinearSystem( const MeshPointer& mesh, + Matrix& matrix ); + + bool makeSnapshot( const RealType& time, + const IndexType& step, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ); + + IndexType getDofs( const MeshPointer& mesh ) const; + + void bindDofs( const MeshPointer& mesh, + DofVectorPointer& dofs ); + + void getExplicitUpdate( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& _u, + DofVectorPointer& _fu, + MeshDependentDataPointer& meshDependentData ); + + template< typename Matrix > + void assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& dofs, + Matrix& matrix, + DofVectorPointer& rightHandSide, + MeshDependentDataPointer& meshDependentData ); + + bool postIterate( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ); + + protected: + + InviscidOperatorsPointer inviscidOperatorsPointer; + + BoundaryConditionPointer boundaryConditionPointer; + RightHandSidePointer rightHandSidePointer; + + ConservativeVariablesPointer conservativeVariables, + conservativeVariablesRHS; + + VelocityFieldPointer velocity; + MeshFunctionPointer pressure; + + RealType gamma; + RealType speedIncrement; + RealType cavitySpeed; + RealType speedIncrementUntil; +}; + +} // namespace TNL + +#include "navierStokesProblem_impl.h" + diff --git a/examples/flow-sw/navierStokesProblem_impl.h b/examples/flow-sw/navierStokesProblem_impl.h new file mode 100644 index 0000000000..b0b528dc89 --- /dev/null +++ b/examples/flow-sw/navierStokesProblem_impl.h @@ -0,0 +1,456 @@ +/*************************************************************************** + navierStokesProblem_impl.h - description + ------------------- + begin : Feb 13, 2017 + copyright : (C) 2017 by Tomas Oberhuber + email : tomas.oberhuber@fjfi.cvut.cz + ***************************************************************************/ + +/* See Copyright Notice in tnl/Copyright */ + +#pragma once + +#include <TNL/FileName.h> +#include <TNL/Matrices/MatrixSetter.h> +#include <TNL/Solvers/PDE/ExplicitUpdater.h> +#include <TNL/Solvers/PDE/LinearSystemAssembler.h> +#include <TNL/Solvers/PDE/BackwardTimeDiscretisation.h> +#include <TNL/Functions/Analytic/VectorNorm.h> + +#include "RiemannProblemInitialCondition.h" +#include "CompressibleConservativeVariables.h" +#include "PhysicalVariablesGetter.h" +#include "navierStokesProblem.h" + +#include "UpwindContinuity.h" +#include "UpwindEnergy.h" +#include "UpwindMomentumX.h" +#include "UpwindMomentumY.h" +#include "UpwindMomentumZ.h" + +namespace TNL { + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +String +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +getTypeStatic() +{ + return String( "navierStokesProblem< " ) + Mesh :: getTypeStatic() + " >"; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +String +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +getPrologHeader() const +{ + return String( "Inviscid flow solver" ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +void +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +writeProlog( Logger& logger, const Config::ParameterContainer& parameters ) const +{ + /**** + * Add data you want to have in the computation report (log) as follows: + * logger.writeParameter< double >( "Parameter description", parameter ); + */ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +bool +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix ) +{ + if( ! this->inviscidOperatorsPointer->setup( meshPointer, parameters, prefix + "inviscid-operators-" ) || + ! this->boundaryConditionPointer->setup( meshPointer, parameters, prefix + "boundary-conditions-" ) || + ! this->rightHandSidePointer->setup( parameters, prefix + "right-hand-side-" ) ) + return false; + this->gamma = parameters.getParameter< double >( "gamma" ); + velocity->setMesh( meshPointer ); + pressure->setMesh( meshPointer ); + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +typename navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >::IndexType +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +getDofs( const MeshPointer& mesh ) const +{ + /**** + * Return number of DOFs (degrees of freedom) i.e. number + * of unknowns to be resolved by the main solver. + */ + return this->conservativeVariables->getDofs( mesh ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +void +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +bindDofs( const MeshPointer& mesh, + DofVectorPointer& dofVector ) +{ + this->conservativeVariables->bind( mesh, dofVector ); +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +bool +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +setInitialCondition( const Config::ParameterContainer& parameters, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ) +{ + CompressibleConservativeVariables< MeshType > conservativeVariables; + conservativeVariables.bind( mesh, dofs ); + const String& initialConditionType = parameters.getParameter< String >( "initial-condition" ); + this->speedIncrementUntil = parameters.getParameter< RealType >( "speed-increment-until" ); + this->speedIncrement = parameters.getParameter< RealType >( "speed-increment" ); + this->cavitySpeed = parameters.getParameter< RealType >( "cavity-speed" ); + if( initialConditionType == "riemann-problem" ) + { + RiemannProblemInitialCondition< MeshType > initialCondition; + if( ! initialCondition.setup( parameters ) ) + return false; + initialCondition.setInitialCondition( conservativeVariables ); + return true; + } + std::cerr << "Unknown initial condition " << initialConditionType << std::endl; + return false; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > + template< typename Matrix > +bool +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +setupLinearSystem( const MeshPointer& mesh, + Matrix& matrix ) +{ +/* const IndexType dofs = this->getDofs( mesh ); + typedef typename Matrix::CompressedRowLengthsVector CompressedRowLengthsVectorType; + CompressedRowLengthsVectorType rowLengths; + if( ! rowLengths.setSize( dofs ) ) + return false; + MatrixSetter< MeshType, DifferentialOperator, BoundaryCondition, CompressedRowLengthsVectorType > matrixSetter; + matrixSetter.template getCompressedRowLengths< typename Mesh::Cell >( mesh, + differentialOperator, + boundaryCondition, + rowLengths ); + matrix.setDimensions( dofs, dofs ); + if( ! matrix.setCompressedRowLengths( rowLengths ) ) + return false;*/ + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +bool +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +makeSnapshot( const RealType& time, + const IndexType& step, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ) +{ + std::cout << std::endl << "Writing output at time " << time << " step " << step << "." << std::endl; + + this->bindDofs( mesh, dofs ); + PhysicalVariablesGetter< MeshType > physicalVariablesGetter; + physicalVariablesGetter.getVelocity( this->conservativeVariables, this->velocity ); + physicalVariablesGetter.getPressure( this->conservativeVariables, this->gamma, this->pressure ); + + FileName fileName; + fileName.setExtension( "tnl" ); + fileName.setIndex( step ); + fileName.setFileNameBase( "density-" ); + if( ! this->conservativeVariables->getDensity()->save( fileName.getFileName() ) ) + return false; + + fileName.setFileNameBase( "velocity-" ); + if( ! this->velocity->save( fileName.getFileName() ) ) + return false; + + fileName.setFileNameBase( "pressure-" ); + if( ! this->pressure->save( fileName.getFileName() ) ) + return false; + + /*fileName.setFileNameBase( "energy-" ); + if( ! this->conservativeVariables->getEnergy()->save( fileName.getFileName() ) ) + return false; + + fileName.setFileNameBase( "momentum-" ); + if( ! this->conservativeVariables->getMomentum()->save( fileName.getFileName() ) ) + return false;*/ + + return true; +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +void +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +getExplicitUpdate( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& _u, + DofVectorPointer& _fu, + MeshDependentDataPointer& meshDependentData ) +{ + typedef typename MeshType::Cell Cell; + + /**** + * Bind DOFs + */ + this->conservativeVariables->bind( mesh, _u ); + this->conservativeVariablesRHS->bind( mesh, _fu ); + this->velocity->setMesh( mesh ); + this->pressure->setMesh( mesh ); + +// this->pressure->write( "pressure1", "gnuplot" ); +// getchar(); + /**** + * Resolve the physical variables + */ + PhysicalVariablesGetter< typename MeshPointer::ObjectType > physicalVariables; + physicalVariables.getVelocity( this->conservativeVariables, this->velocity ); + physicalVariables.getPressure( this->conservativeVariables, this->gamma, this->pressure ); + + /**** + * Set-up operators + */ + typedef typename InviscidOperators::ContinuityOperatorType ContinuityOperatorType; + typedef typename InviscidOperators::MomentumXOperatorType MomentumXOperatorType; + typedef typename InviscidOperators::MomentumYOperatorType MomentumYOperatorType; + typedef typename InviscidOperators::MomentumZOperatorType MomentumZOperatorType; + typedef typename InviscidOperators::EnergyOperatorType EnergyOperatorType; + + this->inviscidOperatorsPointer->setTau( tau ); + this->inviscidOperatorsPointer->setVelocity( this->velocity ); + this->inviscidOperatorsPointer->setPressure( this->pressure ); + this->inviscidOperatorsPointer->setDensity( this->conservativeVariables->getDensity() ); + this->inviscidOperatorsPointer->setGamma( this->gamma ); + + /**** + * Set Up Boundary Conditions + */ + + typedef typename BoundaryCondition::DensityBoundaryConditionsType DensityBoundaryConditionsType; + typedef typename BoundaryCondition::MomentumXBoundaryConditionsType MomentumXBoundaryConditionsType; + typedef typename BoundaryCondition::MomentumYBoundaryConditionsType MomentumYBoundaryConditionsType; + typedef typename BoundaryCondition::MomentumZBoundaryConditionsType MomentumZBoundaryConditionsType; + typedef typename BoundaryCondition::EnergyBoundaryConditionsType EnergyBoundaryConditionsType; + + /**** + * Update Boundary Conditions + */ + if(this->speedIncrementUntil > time ) + { + this->boundaryConditionPointer->setTimestep(this->speedIncrement); + } + else + { + this->boundaryConditionPointer->setTimestep(0); + } + this->boundaryConditionPointer->setSpeed(this->cavitySpeed); + this->boundaryConditionPointer->setCompressibleConservativeVariables(this->conservativeVariables); + this->boundaryConditionPointer->setGamma(this->gamma); + this->boundaryConditionPointer->setPressure(this->pressure); + + + /**** + * Continuity equation + */ + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, ContinuityOperatorType, DensityBoundaryConditionsType, RightHandSide > explicitUpdaterContinuity; + explicitUpdaterContinuity.setDifferentialOperator( this->inviscidOperatorsPointer->getContinuityOperator() ); + explicitUpdaterContinuity.setBoundaryConditions( this->boundaryConditionPointer->getDensityBoundaryCondition() ); + explicitUpdaterContinuity.setRightHandSide( this->rightHandSidePointer ); + explicitUpdaterContinuity.template update< typename Mesh::Cell >( time, tau, mesh, + this->conservativeVariables->getDensity(), + this->conservativeVariablesRHS->getDensity() ); + + /**** + * Momentum equations + */ + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumXOperatorType, MomentumXBoundaryConditionsType, RightHandSide > explicitUpdaterMomentumX; + explicitUpdaterMomentumX.setDifferentialOperator( this->inviscidOperatorsPointer->getMomentumXOperator() ); + explicitUpdaterMomentumX.setBoundaryConditions( this->boundaryConditionPointer->getMomentumXBoundaryCondition() ); + explicitUpdaterMomentumX.setRightHandSide( this->rightHandSidePointer ); + explicitUpdaterMomentumX.template update< typename Mesh::Cell >( time, tau, mesh, + ( *this->conservativeVariables->getMomentum() )[ 0 ], // uRhoVelocityX, + ( *this->conservativeVariablesRHS->getMomentum() )[ 0 ] ); //, fuRhoVelocityX ); + + if( Dimensions > 1 ) + { + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumYOperatorType, MomentumYBoundaryConditionsType, RightHandSide > explicitUpdaterMomentumY; + explicitUpdaterMomentumY.setDifferentialOperator( this->inviscidOperatorsPointer->getMomentumYOperator() ); + explicitUpdaterMomentumY.setBoundaryConditions( this->boundaryConditionPointer->getMomentumYBoundaryCondition() ); + explicitUpdaterMomentumY.setRightHandSide( this->rightHandSidePointer ); + explicitUpdaterMomentumY.template update< typename Mesh::Cell >( time, tau, mesh, + ( *this->conservativeVariables->getMomentum() )[ 1 ], // uRhoVelocityX, + ( *this->conservativeVariablesRHS->getMomentum() )[ 1 ] ); //, fuRhoVelocityX ); + } + + if( Dimensions > 2 ) + { + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, MomentumZOperatorType, MomentumZBoundaryConditionsType, RightHandSide > explicitUpdaterMomentumZ; + explicitUpdaterMomentumZ.setDifferentialOperator( this->inviscidOperatorsPointer->getMomentumZOperator() ); + explicitUpdaterMomentumZ.setBoundaryConditions( this->boundaryConditionPointer->getMomentumZBoundaryCondition() ); + explicitUpdaterMomentumZ.setRightHandSide( this->rightHandSidePointer ); + explicitUpdaterMomentumZ.template update< typename Mesh::Cell >( time, tau, mesh, + ( *this->conservativeVariables->getMomentum() )[ 2 ], // uRhoVelocityX, + ( *this->conservativeVariablesRHS->getMomentum() )[ 2 ] ); //, fuRhoVelocityX ); + } + + + /**** + * Energy equation + */ + Solvers::PDE::ExplicitUpdater< Mesh, MeshFunctionType, EnergyOperatorType, EnergyBoundaryConditionsType, RightHandSide > explicitUpdaterEnergy; + explicitUpdaterEnergy.setDifferentialOperator( this->inviscidOperatorsPointer->getEnergyOperator() ); + explicitUpdaterEnergy.setBoundaryConditions( this->boundaryConditionPointer->getEnergyBoundaryCondition() ); + explicitUpdaterEnergy.setRightHandSide( this->rightHandSidePointer ); + explicitUpdaterEnergy.template update< typename Mesh::Cell >( time, tau, mesh, + this->conservativeVariablesRHS->getEnergy(), // uRhoVelocityX, + this->conservativeVariablesRHS->getEnergy() ); //, fuRhoVelocityX ); + +/* this->pressure->write( "pressure3", "gnuplot" ); + getchar(); + this->conservativeVariablesRHS->getDensity()->write( "density", "gnuplot" ); + this->conservativeVariablesRHS->getEnergy()->write( "energy", "gnuplot" ); + this->conservativeVariablesRHS->getMomentum()->write( "momentum", "gnuplot", 0.05 ); + getchar();*/ + +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > + template< typename Matrix > +void +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +assemblyLinearSystem( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& _u, + Matrix& matrix, + DofVectorPointer& b, + MeshDependentDataPointer& meshDependentData ) +{ +/* LinearSystemAssembler< Mesh, + MeshFunctionType, + InviscidOperators, + BoundaryCondition, + RightHandSide, + BackwardTimeDiscretisation, + Matrix, + DofVectorType > systemAssembler; + + MeshFunction< Mesh > u( mesh, _u ); + systemAssembler.template assembly< typename Mesh::Cell >( time, + tau, + mesh, + this->differentialOperator, + this->boundaryCondition, + this->rightHandSide, + u, + matrix, + b );*/ +} + +template< typename Mesh, + typename BoundaryCondition, + typename RightHandSide, + typename InviscidOperators > +bool +navierStokesProblem< Mesh, BoundaryCondition, RightHandSide, InviscidOperators >:: +postIterate( const RealType& time, + const RealType& tau, + const MeshPointer& mesh, + DofVectorPointer& dofs, + MeshDependentDataPointer& meshDependentData ) +{ + /* + typedef typename MeshType::Cell Cell; + int count = mesh->template getEntitiesCount< Cell >()/4; + //bind _u + this->_uRho.bind( *dofs, 0, count); + this->_uRhoVelocityX.bind( *dofs, count, count); + this->_uRhoVelocityY.bind( *dofs, 2 * count, count); + this->_uEnergy.bind( *dofs, 3 * count, count); + + MeshFunctionType velocity( mesh, this->velocity ); + MeshFunctionType velocityX( mesh, this->velocityX ); + MeshFunctionType velocityY( mesh, this->velocityY ); + MeshFunctionType pressure( mesh, this->pressure ); + MeshFunctionType uRho( mesh, _uRho ); + MeshFunctionType uRhoVelocityX( mesh, _uRhoVelocityX ); + MeshFunctionType uRhoVelocityY( mesh, _uRhoVelocityY ); + MeshFunctionType uEnergy( mesh, _uEnergy ); + //Generating differential operators + Velocity navierStokes2DVelocity; + VelocityX navierStokes2DVelocityX; + VelocityY navierStokes2DVelocityY; + Pressure navierStokes2DPressure; + + //velocityX + navierStokes2DVelocityX.setRhoVelX(uRhoVelocityX); + navierStokes2DVelocityX.setRho(uRho); +// OperatorFunction< VelocityX, MeshFunction, void, true > OFVelocityX; +// velocityX = OFVelocityX; + + //velocityY + navierStokes2DVelocityY.setRhoVelY(uRhoVelocityY); + navierStokes2DVelocityY.setRho(uRho); +// OperatorFunction< VelocityY, MeshFunction, void, time > OFVelocityY; +// velocityY = OFVelocityY; + + //velocity + navierStokes2DVelocity.setVelX(velocityX); + navierStokes2DVelocity.setVelY(velocityY); +// OperatorFunction< Velocity, MeshFunction, void, time > OFVelocity; +// velocity = OFVelocity; + + //pressure + navierStokes2DPressure.setGamma(gamma); + navierStokes2DPressure.setVelocity(velocity); + navierStokes2DPressure.setEnergy(uEnergy); + navierStokes2DPressure.setRho(uRho); +// OperatorFunction< navierStokes2DPressure, MeshFunction, void, time > OFPressure; +// pressure = OFPressure; + */ + return true; +} + +} // namespace TNL + diff --git a/examples/flow-sw/navierStokesRhs.h b/examples/flow-sw/navierStokesRhs.h new file mode 100644 index 0000000000..3c82ad4539 --- /dev/null +++ b/examples/flow-sw/navierStokesRhs.h @@ -0,0 +1,35 @@ +#ifndef navierStokesRHS_H_ +#define navierStokesRHS_H_ + +#include <TNL/Functions/Domain.h> + +namespace TNL { + +template< typename Mesh, typename Real >class navierStokesRhs + : public Functions::Domain< Mesh::getMeshDimension(), Functions::MeshDomain > + { + public: + + typedef Mesh MeshType; + typedef Real RealType; + + bool setup( const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + return true; + } + + template< typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshEntity& entity, + const Real& time = 0.0 ) const + { + typedef typename MeshEntity::MeshType::PointType PointType; + PointType v = entity.getCenter(); + return 0.0; + } +}; + +} //namespace TNL + +#endif /* navierStokesRHS_H_ */ diff --git a/examples/flow-sw/run-euler b/examples/flow-sw/run-euler new file mode 100644 index 0000000000..9ebf9cbb55 --- /dev/null +++ b/examples/flow-sw/run-euler @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-y 0.0 \ + --proportions-x 1.0 \ + --proportions-y 1.0 \ + --size-x 100 \ + --size-y 100 + +tnl-init --test-function sin-wave \ + --output-file init.tnl +tnl-euler-2d --initial-condition riemann-problem \ + --discontinuity-placement-0 0.3 \ + --discontinuity-placement-1 0.3 \ + --discontinuity-placement-2 0.3 \ + --time-discretisation explicit \ + --boundary-conditions-type neumann \ + --boundary-conditions-constant 0 \ + --discrete-solver euler \ + --time-step 0.0001 \ + --snapshot-period 0.01 \ + --final-time 1.0 + +tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/examples/flow-vl/UpwindMomentumBase.h b/examples/flow-vl/UpwindMomentumBase.h index b9aed78e6c..db59383dd1 100644 --- a/examples/flow-vl/UpwindMomentumBase.h +++ b/examples/flow-vl/UpwindMomentumBase.h @@ -69,7 +69,9 @@ class UpwindMomentumBase if ( machNumber <= -1.0 ) return 0; else if ( machNumber <= 1.0 ) - return density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( machNumber + 1.0 ) * ( machNumber + 1.0 ) * ( 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); + return density * speedOfSound / 4.0 * ( machNumber + 1.0 ) * ( machNumber + 1.0 ) + * ( ( 2.0 * speedOfSound ) / this->gamma ) + * ( 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); else return density * velocity * velocity + pressure; }; @@ -81,7 +83,9 @@ class UpwindMomentumBase if ( machNumber <= -1.0 ) return density * velocity * velocity + pressure; else if ( machNumber <= 1.0 ) - return - density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( machNumber - 1.0 ) * ( machNumber - 1.0 ) * ( - 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); + return - density * speedOfSound / 4.0 * ( machNumber - 1.0 ) * ( machNumber - 1.0 ) + * ( ( 2.0 * speedOfSound ) / this->gamma ) + * ( - 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); else return 0; }; diff --git a/examples/inviscid-flow-vl/UpwindContinuity.h b/examples/inviscid-flow-vl/UpwindContinuity.h index 32ff1f88ec..113d0bd8f4 100644 --- a/examples/inviscid-flow-vl/UpwindContinuity.h +++ b/examples/inviscid-flow-vl/UpwindContinuity.h @@ -84,7 +84,7 @@ class UpwindContinuityBase if ( machNumber <= -1.0 ) return density * velocity; else if ( machNumber <= 1.0 ) - return - density * speedOfSound / 4 * ( machNumber - 1.0 ) * ( machNumber - 1.0 ); + return - density * speedOfSound / 4.0 * ( machNumber - 1.0 ) * ( machNumber - 1.0 ); else return 0.0; }; diff --git a/examples/inviscid-flow-vl/UpwindEnergy.h b/examples/inviscid-flow-vl/UpwindEnergy.h index 4abc7e00b8..ce68c182d0 100644 --- a/examples/inviscid-flow-vl/UpwindEnergy.h +++ b/examples/inviscid-flow-vl/UpwindEnergy.h @@ -230,6 +230,7 @@ class UpwindEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index using typename BaseType::VelocityFieldPointer; using BaseType::Dimensions; + RealType positiveEnergyFlux( const RealType& density, const RealType& velocity_main, const RealType& velocity_other1, const RealType& pressure ) const { const RealType& speedOfSound = std::sqrt( this->gamma * pressure / density ); @@ -242,7 +243,7 @@ class UpwindEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index velocity_other1 * velocity_other1 / 2.0 + 2.0 * speedOfSound * speedOfSound / ( this->gamma * this->gamma - 1.0 ) * ( 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ) - * ( 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ) + * ( 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ) ); else return velocity_main * ( pressure + pressure / ( this->gamma - 1.0 ) + 0.5 * density * ( velocity_main * velocity_main + velocity_other1 * velocity_other1 ) ); @@ -260,11 +261,11 @@ class UpwindEnergy< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index velocity_other1 * velocity_other1 / 2.0 + 2.0 * speedOfSound * speedOfSound / ( this->gamma * this->gamma - 1.0 ) * ( 1.0 - ( this->gamma - 1.0 ) * machNumber / 2.0 ) - * ( 1.0 - ( this->gamma - 1.0 ) * machNumber / 2.0 ) + * ( 1.0 - ( this->gamma - 1.0 ) * machNumber / 2.0 ) ); else return 0.0; - }; + }; template< typename MeshFunction, typename MeshEntity > __cuda_callable__ diff --git a/examples/inviscid-flow-vl/UpwindMomentumBase.h b/examples/inviscid-flow-vl/UpwindMomentumBase.h index 82d7ae48ae..5b390029f1 100644 --- a/examples/inviscid-flow-vl/UpwindMomentumBase.h +++ b/examples/inviscid-flow-vl/UpwindMomentumBase.h @@ -64,7 +64,9 @@ class UpwindMomentumBase if ( machNumber <= -1.0 ) return 0; else if ( machNumber <= 1.0 ) - return density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( machNumber + 1.0 ) * ( machNumber + 1.0 ) * ( 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); + return density * speedOfSound / 4.0 * ( machNumber + 1.0 ) * ( machNumber + 1.0 ) + * ( ( 2.0 * speedOfSound ) / this->gamma ) + * ( 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); else return density * velocity * velocity + pressure; }; @@ -76,7 +78,9 @@ class UpwindMomentumBase if ( machNumber <= -1.0 ) return density * velocity * velocity + pressure; else if ( machNumber <= 1.0 ) - return - density * speedOfSound * speedOfSound / ( 2 * this->gamma ) * ( machNumber - 1.0 ) * ( machNumber - 1.0 ) * ( - 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); + return - density * speedOfSound / 4.0 * ( machNumber - 1.0 ) * ( machNumber - 1.0 ) + * ( ( 2.0 * speedOfSound ) / this->gamma ) + * ( - 1.0 + ( this->gamma - 1.0 ) * machNumber / 2.0 ); else return 0; }; diff --git a/examples/transport-equation/tnl-run-transport-equation-eoc b/examples/transport-equation/tnl-run-transport-equation-eoc index ec08d44172..81d647c375 100755 --- a/examples/transport-equation/tnl-run-transport-equation-eoc +++ b/examples/transport-equation/tnl-run-transport-equation-eoc @@ -1,32 +1,470 @@ -#!/usr/bin/env bash - -tnl-grid-setup --dimensions 2 \ - --origin-x 0.0 \ - --origin-x 0.0 \ - --proportions-x 1.0 \ - --proportions-y 1.0 \ - --size-x 100 \ - --size-y 100 +#!/bin/bash + +dimensions="1D 2D" +initial_conditions="square circle" +viscosities="0.25 0.5 1.0" +entities_counts="50 100 200 400 800 1600" + +setupGrid() +{ + if test $dimension = 1D; + then + tnl-grid-setup --dimensions 1 \ + --origin-x 0.0 \ + --proportions-x 1.0 \ + --size-x ${entities_count} + fi + + if test $dimension = 2D; + then + tnl-grid-setup --dimensions 2 \ + --origin-x 0.0 \ + --origin-y 0.0 \ + --proportions-x 1.0 \ + --proportions-y 1.0 \ + --size-x ${entities_count} \ + --size-y ${entities_count} + fi + + if test $dimension = 3D; + then + tnl-grid-setup --dimensions 3 \ + --origin-x 0.0 \ + --origin-y 0.0 \ + --origin-z 0.0 \ + --proportions-x 1.0 \ + --proportions-y 1.0 \ + --proportions-z 1.0 \ + --size-x ${entities_count} \ + --size-y ${entities_count} \ + --size-z ${entities_count} + fi +} + +tnlViewTest() +{ + tnl-view --mesh mesh.tnl --input-files *tnl +} + +setInitialCondition() +{ +if test $dimension = 1D; + then + if test $initial_condition = square; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file init.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + fi + + if test $initial_condition = circle; + then + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file init.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + fi +fi + +if test $dimension = 2D; +then + if test $initial_condition = square; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file init.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + fi + + if test $initial_condition = circle; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file init.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + fi +fi + +if test $dimension = 3D; +then + if test $initial_condition = square; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file init.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-center-2 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + fi + + if test $initial_condition = circle; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file init.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-center-2 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + fi +fi +} + +setAnalyticSolution() +{ +if test $dimension = 1D; + then + if test $initial_condition = square; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00000.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00001.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.55 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00002.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.65 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + fi + + if test $initial_condition = circle; + then + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00000.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00001.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.55 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00002.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.65 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + fi +fi + +if test $dimension = 2D; +then + if test $initial_condition = square; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00000.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00001.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.55 \ + --vector-norm-center-1 0.55 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00002.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.65 \ + --vector-norm-center-1 0.65 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + fi + + if test $initial_condition = circle; + then + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00000.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00001.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.55 \ + --vector-norm-center-1 0.55 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00002.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.65 \ + --vector-norm-center-1 0.65 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + fi +fi + +if test $dimension = 3D; +then + if test $initial_condition = square; + then + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00000.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-center-2 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00001.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.55 \ + --vector-norm-center-1 0.55 \ + --vector-norm-center-2 0.55 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + tnl-init --test-function heaviside-of-vector-norm \ + --output-file a-00002.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.65 \ + --vector-norm-center-1 0.65 \ + --vector-norm-center-2 0.65 \ + --vector-norm-radius 0.2 \ + --vector-norm-power 0.6 \ + --vector-norm-max-norm true \ + --vector-norm-multiplicator -1.0 + + fi + + if test $initial_condition = circle; + then + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00000.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.45 \ + --vector-norm-center-1 0.45 \ + --vector-norm-center-2 0.45 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00001.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.55 \ + --vector-norm-center-1 0.55 \ + --vector-norm-center-2 0.55 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + tnl-init --test-function smooth-heaviside-of-vector-norm \ + --output-file a-00002.tnl \ + --coefficient -1.0 \ + --vector-norm-center-0 0.65 \ + --vector-norm-center-1 0.65 \ + --vector-norm-center-2 0.65 \ + --vector-norm-radius 0.1 \ + --vector-norm-power 2.0 \ + --vector-norm-max-norm false \ + --vector-norm-multiplicator -1.0 \ + --smooth-heaviside-sharpness 10.0 + + fi +fi +} + +compute() + +{ +timestep=$(echo "scale=8;(1/${entities_count})" |bc -l) +tnl-transport-equation --device host \ + --initial-condition init.tnl \ + --time-discretisation explicit \ + --time-step $timestep \ + --boundary-conditions-constant 0.0 \ + --discrete-solver euler \ + --snapshot-period 1.0 \ + --final-time 2.0 \ + --numerical-viscosity ${viscosity} \ + --velocity-field-0-constant 0.1 \ + --velocity-field-1-constant 0.1 \ + --velocity-field-2-constant 0.1 +} + +computeError() +{ + tnl-diff --mesh mesh.tnl \ + --input-files a-*.tnl u-*.tnl \ + --mode halves \ + --snapshot-period 1.0 \ + --output-file errors.txt \ + --write-difference yes +} + +runTest() +{ + mv computation-in-progress computation-done + for dimension in ${dimensions}; + do + mkdir -p ${dimension} + cd ${dimension} + + for initial_condition in ${initial_conditions}; + do + mkdir -p ${initial_condition} + cd ${initial_condition} + + for viscosity in ${viscosities}; + do + mkdir -p ${viscosity} + cd ${viscosity} + + for entities_count in ${entities_counts}; + do + lastSize="" + mkdir -p ${entities_count} + cd ${entities_count} + + echo "" + echo "" + echo "" + if test ! -f computation-done; + then + touch computation-in-progress + echo "=========================================================================" + echo "=== SETTING UP THE GRID ===" + echo "=========================================================================" + setupGrid + echo "=========================================================================" + echo "=== WRITING THE EXACT SOLUTION ===" + echo "=========================================================================" + setInitialCondition + echo "=========================================================================" + echo "=== STARTING THE SOLVER ===" + echo "=========================================================================" + compute + setAnalyticSolution + mv computation-in-progress computation-done + fi + echo "=========================================================================" + echo "=== COMPUTING THE ERROR ===" + echo "=========================================================================" + computeError + echo "=========================================================================" + echo "=== COMPUTING THE EOC ===" + echo "=========================================================================" + if test ! $lastSize = $entities_count; + then + tnl-err2eoc ../$lastSize/errors.txt errors.txt + fi + echo "=========================================================================" + echo "=== COMPUTATION DONE ===" + echo "=========================================================================" + + cd .. + lastSize=$entities_count + done + cd .. + + done + cd .. + + done + cd .. + + done +} + +runTest -tnl-transport-equation-eoc --device host \ - --initial-condition heaviside-vector-norm \ - --heaviside-multiplicator 1.0 \ - --vector-norm-multiplicator -1.0 \ - --vector-norm-center-0 0.5 \ - --vector-norm-center-1 0.5 \ - --vector-norm-center-2 0.5 \ - --vector-norm-radius 0.2 \ - --vector-norm-power 0.6 \ - --vector-norm-max-norm false \ - --time-discretisation explicit \ - --time-step 1.0e-5 \ - --boundary-conditions-constant 0.0 \ - --discrete-solver euler \ - --snapshot-period 0.005 \ - --final-time 0.1 \ - --numerical-viscosity 1.0 \ - --velocity-field-0-constant 1.0 \ - --velocity-field-1-constant 1.0 \ - --velocity-field-2-constant 1.0 - -tnl-view --mesh mesh.tnl --input-files *tnl diff --git a/src/TNL/Operators/Advection/Upwind.h b/src/TNL/Operators/Advection/Upwind.h new file mode 100644 index 0000000000..a5e19ac109 --- /dev/null +++ b/src/TNL/Operators/Advection/Upwind.h @@ -0,0 +1,328 @@ +#ifndef Upwind_H +#define Upwind_H + +#include <TNL/Containers/Vector.h> +#include <TNL/Meshes/Grid.h> +#include <TNL/Functions/VectorField.h> +#include <TNL/SharedPointer.h> + +namespace TNL { + namespace Operators { + namespace Advection { + + +template< typename Mesh, + typename Real = typename Mesh::RealType, + typename Index = typename Mesh::IndexType, + typename VelocityFunction = Functions::MeshFunction< Mesh > > +class Upwind +{ +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename VelocityFunction > +class Upwind< Meshes::Grid< 1, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction > +{ + public: + + typedef Meshes::Grid< 1, MeshReal, Device, MeshIndex > MeshType; + typedef SharedPointer< MeshType > MeshPointer; + static const int Dimensions = MeshType::getMeshDimension(); + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef VelocityFunction VelocityFunctionType; + typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + Upwind() + : artificialViscosity( 1.0 ) {} + + Upwind( const VelocityFieldPointer& velocityField ) + : artificialViscosity( 1.0 ), velocityField( velocityField ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + return true; + } + + static String getType(); + + void setViscosity(const Real& artificalViscosity) + { + this->artificialViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocityField( const VelocityFieldPointer& velocityField ) + { + this->velocityField = velocityField; + } + + const VelocityFieldPointer& getVelocityField() const + { + return this->velocityField; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 1, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 1, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 1 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1 >(); + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + const RealType& speedX = FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ], entity, time ); + return ( - 0.5 * ( speedX + std::abs(speedX) ) * ( u[ center ] - u[ west ] ) * hxInverse ) + - ( 0.5 * ( speedX - std::abs(speedX) ) * ( u[ east ] - u[ center ] ) * hxInverse ) ; + } + + protected: + + RealType tau; + + RealType artificialViscosity; + + VelocityFieldPointer velocityField; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename VelocityFunction > +class Upwind< Meshes::Grid< 2, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction > +{ + public: + + typedef Meshes::Grid< 2, MeshReal, Device, MeshIndex > MeshType; + typedef SharedPointer< MeshType > MeshPointer; + static const int Dimensions = MeshType::getMeshDimension(); + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef VelocityFunction VelocityFunctionType; + typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + Upwind() + : artificialViscosity( 1.0 ) {} + + Upwind( const VelocityFieldPointer& velocityField ) + : artificialViscosity( 1.0 ), velocityField( velocityField ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + return true; + } + + static String getType(); + + void setViscosity(const Real& artificalViscosity) + { + this->artificialViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocityField( const VelocityFieldPointer& velocityField ) + { + this->velocityField = velocityField; + } + + const VelocityFieldPointer& getVelocityField() const + { + return this->velocityField; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 2, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 2, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 2 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1 >(); + + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1 >(); + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + const RealType& speedX = FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ]); + const RealType& speedY = FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 1 ]); + + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + return ( - 0.5 * ( speedX + std::abs(speedX) ) * ( u[ center ] - u[ west ] ) * hxInverse ) + - ( 0.5 * ( speedX - std::abs(speedX) ) * ( u[ east ] - u[ center ] ) * hxInverse ) + - ( 0.5 * ( speedY + std::abs(speedY) ) * ( u[ center ] - u[ south ] ) * hyInverse ) + - ( 0.5 * ( speedY - std::abs(speedY) ) * ( u[ north ] - u[ center ] ) * hyInverse ); + } + + protected: + + RealType tau; + + RealType artificialViscosity; + + VelocityFieldPointer velocityField; +}; + +template< typename MeshReal, + typename Device, + typename MeshIndex, + typename Real, + typename Index, + typename VelocityFunction > +class Upwind< Meshes::Grid< 3, MeshReal, Device, MeshIndex >, Real, Index, VelocityFunction > +{ + public: + + typedef Meshes::Grid< 3, MeshReal, Device, MeshIndex > MeshType; + typedef SharedPointer< MeshType > MeshPointer; + static const int Dimensions = MeshType::getMeshDimension(); + typedef typename MeshType::CoordinatesType CoordinatesType; + typedef Real RealType; + typedef Device DeviceType; + typedef Index IndexType; + typedef Functions::MeshFunction< MeshType > MeshFunctionType; + typedef VelocityFunction VelocityFunctionType; + typedef Functions::VectorField< Dimensions, VelocityFunctionType > VelocityFieldType; + typedef SharedPointer< VelocityFieldType, DeviceType > VelocityFieldPointer; + + static void configSetup( Config::ConfigDescription& config, + const String& prefix = "" ) + { + config.addEntry< double >( prefix + "numerical-viscosity", "Value of artificial (numerical) viscosity in the Lax-Fridrichs scheme", 1.0 ); + } + + Upwind() + : artificialViscosity( 1.0 ) {} + + Upwind( const VelocityFieldPointer& velocityField ) + : artificialViscosity( 1.0 ), velocityField( velocityField ) {} + + bool setup( const MeshPointer& meshPointer, + const Config::ParameterContainer& parameters, + const String& prefix = "" ) + { + this->artificialViscosity = parameters.getParameter< double >( prefix + "numerical-viscosity" ); + return true; + } + + static String getType(); + + void setViscosity(const Real& artificalViscosity) + { + this->artificialViscosity = artificalViscosity; + } + + void setTau(const Real& tau) + { + this->tau = tau; + }; + + void setVelocityField( const VelocityFieldPointer& velocityField ) + { + this->velocityField = velocityField; + } + + const VelocityFieldPointer& getVelocityField() const + { + return this->velocityField; + } + + template< typename MeshFunction, typename MeshEntity > + __cuda_callable__ + Real operator()( const MeshFunction& u, + const MeshEntity& entity, + const RealType& time = 0.0 ) const + { + static_assert( MeshEntity::getEntityDimension() == 3, "Wrong mesh entity dimensions." ); + static_assert( MeshFunction::getEntitiesDimension() == 3, "Wrong preimage function" ); + const typename MeshEntity::template NeighborEntities< 3 >& neighborEntities = entity.getNeighborEntities(); + + const RealType& hxInverse = entity.getMesh().template getSpaceStepsProducts< -1, 0, 0 >(); + const RealType& hyInverse = entity.getMesh().template getSpaceStepsProducts< 0, -1, 0 >(); + const RealType& hzInverse = entity.getMesh().template getSpaceStepsProducts< 0, 0, -1 >(); + const IndexType& center = entity.getIndex(); + const IndexType& east = neighborEntities.template getEntityIndex< 1, 0, 0 >(); + const IndexType& west = neighborEntities.template getEntityIndex< -1, 0, 0 >(); + const IndexType& north = neighborEntities.template getEntityIndex< 0, 1, 0 >(); + const IndexType& south = neighborEntities.template getEntityIndex< 0, -1, 0 >(); + const IndexType& up = neighborEntities.template getEntityIndex< 0, 0, 1 >(); + const IndexType& down = neighborEntities.template getEntityIndex< 0, 0, -1 >(); + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + const RealType& speedX = FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 0 ]); + const RealType& speedY = FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 1 ]); + const RealType& speedZ = FunctionAdapter::getValue( this->velocityField.template getData< DeviceType >()[ 2 ]); + + typedef Functions::FunctionAdapter< MeshType, VelocityFunctionType > FunctionAdapter; + return ( - 0.5 * ( speedX + std::abs(speedX) ) * ( u[ center ] - u[ west ] ) * hxInverse ) + - ( 0.5 * ( speedX - std::abs(speedX) ) * ( u[ east ] - u[ center ] ) * hxInverse ) + - ( 0.5 * ( speedY + std::abs(speedY) ) * ( u[ center ] - u[ south ] ) * hyInverse ) + - ( 0.5 * ( speedY - std::abs(speedY) ) * ( u[ north ] - u[ center ] ) * hyInverse ) + - ( 0.5 * ( speedZ + std::abs(speedZ) ) * ( u[ center ] - u[ down ] ) * hyInverse ) + - ( 0.5 * ( speedZ - std::abs(speedZ) ) * ( u[ up ] - u[ center ] ) * hyInverse ); + } + + protected: + + RealType tau; + + RealType artificialViscosity; + + VelocityFieldPointer velocityField; +}; + + }// namespace Advection + } // namepsace Operators +} // namespace TNL + +#endif /* Upwind_H */ -- GitLab