]> SALOME platform Git repositories - tools/solverlab.git/commitdiff
Salome HOME
Restructured example folder
authormichael <michael@is242589.intra.cea.fr>
Mon, 13 Sep 2021 11:47:45 +0000 (13:47 +0200)
committermichael <michael@is242589.intra.cea.fr>
Mon, 13 Sep 2021 11:47:45 +0000 (13:47 +0200)
216 files changed:
CDMATH/tests/CMakeLists.txt
CDMATH/tests/examples/BurgersEquation1D/CMakeLists.txt
CDMATH/tests/examples/EulerEquations/CMakeLists.txt [new file with mode: 0644]
CDMATH/tests/examples/EulerEquations/FullEulerSystem/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_HeatedChannel/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_HeatedChannel/Euler_complet_HeatedChanel.py [new file with mode: 0644]
CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_RiemannProblem/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_RiemannProblem/Euler_complet_RP.py [new file with mode: 0644]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DConservativeStaggered/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DConservativeStaggered/EulerSystem1DConservativeStaggered.py [new file with mode: 0644]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwind/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwind/EulerSystem1DUpwind.py [new file with mode: 0644]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwindEntrCorr/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwindEntrCorr/EulerSystem1DUpwindEntrCorr.py [new file with mode: 0644]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemStaggered/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemStaggered/EulerIsothermal_2DConservativeStaggered.py [new file with mode: 0644]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemUpwind/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemUpwind/EulerSystemUpwind.py [new file with mode: 0755]
CDMATH/tests/examples/EulerSystem1D/EulerSystem1DConservativeStaggered/CMakeLists.txt [deleted file]
CDMATH/tests/examples/EulerSystem1D/EulerSystem1DConservativeStaggered/EulerSystem1DConservativeStaggered.py [deleted file]
CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwind/CMakeLists.txt [deleted file]
CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwind/EulerSystem1DUpwind.py [deleted file]
CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwindEntrCorr/CMakeLists.txt [deleted file]
CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwindEntrCorr/EulerSystem1DUpwindEntrCorr.py [deleted file]
CDMATH/tests/examples/EulerSystem_Shock/EulerSystemStaggered/CMakeLists.txt [deleted file]
CDMATH/tests/examples/EulerSystem_Shock/EulerSystemStaggered/EulerIsothermal_2DConservativeStaggered.py [deleted file]
CDMATH/tests/examples/EulerSystem_Shock/EulerSystemUpwind/CMakeLists.txt [deleted file]
CDMATH/tests/examples/EulerSystem_Shock/EulerSystemUpwind/EulerSystemUpwind.py [deleted file]
CDMATH/tests/examples/HeatEquation/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/HeatEquation/HeatEquation1DExplicit/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/HeatEquation/HeatEquation1DExplicit/HeatEquation1DExplicit.py [new file with mode: 0755]
CDMATH/tests/examples/HeatEquation/HeatEquation1DImplicit/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/HeatEquation/HeatEquation1DImplicit/HeatEquation1DImplicit.py [new file with mode: 0755]
CDMATH/tests/examples/HeatEquation1DExplicit/CMakeLists.txt [deleted file]
CDMATH/tests/examples/HeatEquation1DExplicit/HeatEquation1DExplicit.py [deleted file]
CDMATH/tests/examples/HeatEquation1DImplicit/CMakeLists.txt [deleted file]
CDMATH/tests/examples/HeatEquation1DImplicit/HeatEquation1DImplicit.py [deleted file]
CDMATH/tests/examples/Poisson1DEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson1DEF/FiniteElements1DPoisson.py [deleted file]
CDMATH/tests/examples/Poisson1DVF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson1DVF/FiniteVolumes1DPoisson.py [deleted file]
CDMATH/tests/examples/Poisson2DEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson2DEF/FiniteElements2DPoisson_SQUARE.py [deleted file]
CDMATH/tests/examples/Poisson2DEF_DISK/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson2DEF_DISK/FiniteElements2DPoisson_DISK.py [deleted file]
CDMATH/tests/examples/Poisson2DEF_DISK_StiffBC/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson2DEF_DISK_StiffBC/FiniteElements2DPoisson_DISK_StiffBC.py [deleted file]
CDMATH/tests/examples/Poisson2DEF_SQUARE_StiffBC/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson2DEF_SQUARE_StiffBC/FiniteElements2DPoisson_SQUARE_StiffBC.py [deleted file]
CDMATH/tests/examples/Poisson2DVF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson2DVF/FiniteVolumes2DPoisson_SQUARE.py [deleted file]
CDMATH/tests/examples/Poisson2DVF_DISK/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson2DVF_DISK/FiniteVolumes2DPoisson_DISK.py [deleted file]
CDMATH/tests/examples/Poisson2DVF_DISK_StiffBC/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson2DVF_DISK_StiffBC/FiniteVolumes2DPoisson_DISK_StiffBC.py [deleted file]
CDMATH/tests/examples/Poisson3DCubeSkinEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DCubeSkinEF/FiniteElements3DPoissonCubeSkin.py [deleted file]
CDMATH/tests/examples/Poisson3DEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DEF/FiniteElements3DPoisson_CUBE.py [deleted file]
CDMATH/tests/examples/Poisson3DEF_BALL/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DEF_BALL/FiniteElements3DPoisson_BALL.py [deleted file]
CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py [deleted file]
CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med [deleted file]
CDMATH/tests/examples/Poisson3DSphereEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DSphereEF/FiniteElements3DPoissonSphere.py [deleted file]
CDMATH/tests/examples/Poisson3DTorusEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DTorusEF/FiniteElements3DPoissonTorus.py [deleted file]
CDMATH/tests/examples/Poisson3DVF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DVF/FiniteVolumes3DPoisson_CUBE.py [deleted file]
CDMATH/tests/examples/Poisson3DVF_BALL/CMakeLists.txt [deleted file]
CDMATH/tests/examples/Poisson3DVF_BALL/FiniteVolumes3DPoisson_BALL.py [deleted file]
CDMATH/tests/examples/PoissonEquation/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson1DEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson1DEF/FiniteElements1DPoisson.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson1DVF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson1DVF/FiniteVolumes1DPoisson.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF/FiniteElements2DPoisson_SQUARE.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK/FiniteElements2DPoisson_DISK.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK_StiffBC/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK_StiffBC/FiniteElements2DPoisson_DISK_StiffBC.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF_SQUARE_StiffBC/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DEF_SQUARE_StiffBC/FiniteElements2DPoisson_SQUARE_StiffBC.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DVF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DVF/FiniteVolumes2DPoisson_SQUARE.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK/FiniteVolumes2DPoisson_DISK.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK_StiffBC/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK_StiffBC/FiniteVolumes2DPoisson_DISK_StiffBC.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DCubeSkinEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DCubeSkinEF/FiniteElements3DPoissonCubeSkin.py [new file with mode: 0644]
CDMATH/tests/examples/PoissonEquation/Poisson3DEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DEF/FiniteElements3DPoisson_CUBE.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DEF_BALL/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DEF_BALL/FiniteElements3DPoisson_BALL.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DSphereEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DSphereEF/FiniteElements3DPoissonSphere.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DTorusEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DTorusEF/FiniteElements3DPoissonTorus.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DVF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DVF/FiniteVolumes3DPoisson_CUBE.py [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DVF_BALL/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/PoissonEquation/Poisson3DVF_BALL/FiniteVolumes3DPoisson_BALL.py [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DEF/SpectrumLaplace2DEF_SQUARE.py [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DVF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DVF/SpectrumLaplace2DVF_SQUARE.py [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplaceBeltrami3DEF/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplaceBeltrami3DEF/SpectrumFiniteElements3DLaplace-Beltrami.py [new file with mode: 0755]
CDMATH/tests/examples/SpectrumLaplace2DEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/SpectrumLaplace2DEF/SpectrumLaplace2DEF_SQUARE.py [deleted file]
CDMATH/tests/examples/SpectrumLaplace2DVF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/SpectrumLaplace2DVF/SpectrumLaplace2DVF_SQUARE.py [deleted file]
CDMATH/tests/examples/SpectrumLaplaceBeltrami3DEF/CMakeLists.txt [deleted file]
CDMATH/tests/examples/SpectrumLaplaceBeltrami3DEF/SpectrumFiniteElements3DLaplace-Beltrami.py [deleted file]
CDMATH/tests/examples/TransportEquation/CMakeLists.txt
CDMATH/tests/examples/TransportEquation/TransportEquation/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation/TransportEquationUpwind.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredExplicit/1DTransportEquationCenteredExplicit.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredExplicit/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredImplicit/1DTransportEquationCenteredImplicit.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredImplicit/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindExplicit/1DTransportEquationUpwindExplicit.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindExplicit/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindImplicit/1DTransportEquationUpwindImplicit.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindImplicit/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/TransportEquationUpwind.py [deleted file]
CDMATH/tests/examples/TransportEquation/thermique1d/main.cxx [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/thermique1d/makefile [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport1d/main.cxx [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport1d/main.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport1d/makefile [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport2d_ns/main.cxx [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport2d_ns/main.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport2d_ns/main2.cxx [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport2d_ns/makefile [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport2d_s/main.cxx [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport2d_s/main.py [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation/transport2d_s/makefile [new file with mode: 0755]
CDMATH/tests/examples/TransportEquation1DCenteredExplicit/1DTransportEquationCenteredExplicit.py [deleted file]
CDMATH/tests/examples/TransportEquation1DCenteredExplicit/CMakeLists.txt [deleted file]
CDMATH/tests/examples/TransportEquation1DCenteredImplicit/1DTransportEquationCenteredImplicit.py [deleted file]
CDMATH/tests/examples/TransportEquation1DCenteredImplicit/CMakeLists.txt [deleted file]
CDMATH/tests/examples/TransportEquation1DUpwindExplicit/1DTransportEquationUpwindExplicit.py [deleted file]
CDMATH/tests/examples/TransportEquation1DUpwindExplicit/CMakeLists.txt [deleted file]
CDMATH/tests/examples/TransportEquation1DUpwindImplicit/1DTransportEquationUpwindImplicit.py [deleted file]
CDMATH/tests/examples/TransportEquation1DUpwindImplicit/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem1DStaggered_RiemannProblem/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem1DStaggered_RiemannProblem/WaveSystem1DStaggered_RiemannProblem.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind/WaveSystem1DUpwind.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind_RiemannProblem/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind_RiemannProblem/WaveSystem1DUpwind_RiemannProblem.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem2DUpwind_RiemannProblem/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem2DUpwind_RiemannProblem/WaveSystemUpwind.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemCentered/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemCentered/WaveSystemCentered.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemPStag/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemPStag/WaveSystemPStag.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemStaggered/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemStaggered/WaveSystemStaggered.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemUpwind/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemUpwind/WaveSystemUpwind.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemCentered/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemCentered/WaveSystemCentered.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemPStag/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemPStag/WaveSystemPStag.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemStaggered/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemStaggered/WaveSystemStaggered.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemUpwind/CMakeLists.txt [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemUpwind/WaveSystemUpwind.py [new file with mode: 0755]
CDMATH/tests/examples/WaveSystem1DStaggered_RiemannProblem/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem1DStaggered_RiemannProblem/WaveSystem1DStaggered_RiemannProblem.py [deleted file]
CDMATH/tests/examples/WaveSystem1DUpwind/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem1DUpwind/WaveSystem1DUpwind.py [deleted file]
CDMATH/tests/examples/WaveSystem1DUpwind_RiemannProblem/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem1DUpwind_RiemannProblem/WaveSystem1DUpwind_RiemannProblem.py [deleted file]
CDMATH/tests/examples/WaveSystem2DUpwind_RiemannProblem/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem2DUpwind_RiemannProblem/WaveSystemUpwind.py [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemCentered/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemCentered/WaveSystemCentered.py [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemPStag/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemPStag/WaveSystemPStag.py [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemStaggered/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemStaggered/WaveSystemStaggered.py [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemUpwind/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Shock/WaveSystemUpwind/WaveSystemUpwind.py [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemCentered/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemCentered/WaveSystemCentered.py [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemPStag/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemPStag/WaveSystemPStag.py [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemStaggered/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemStaggered/WaveSystemStaggered.py [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemUpwind/CMakeLists.txt [deleted file]
CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemUpwind/WaveSystemUpwind.py [deleted file]
CDMATH/tests/examples/thermique1d/main.cxx [deleted file]
CDMATH/tests/examples/thermique1d/makefile [deleted file]
CDMATH/tests/examples/transport1d/main.cxx [deleted file]
CDMATH/tests/examples/transport1d/main.py [deleted file]
CDMATH/tests/examples/transport1d/makefile [deleted file]
CDMATH/tests/examples/transport2d_ns/main.cxx [deleted file]
CDMATH/tests/examples/transport2d_ns/main.py [deleted file]
CDMATH/tests/examples/transport2d_ns/main2.cxx [deleted file]
CDMATH/tests/examples/transport2d_ns/makefile [deleted file]
CDMATH/tests/examples/transport2d_s/main.cxx [deleted file]
CDMATH/tests/examples/transport2d_s/main.py [deleted file]
CDMATH/tests/examples/transport2d_s/makefile [deleted file]
CDMATH/tests/ressources/CMakeLists.txt

index 8a98ca685af79bddf1aee91003d592362f8715e6..dc2db804ba7de35589f14a077e1aaffa92444354 100755 (executable)
@@ -52,14 +52,14 @@ IF (CDMATH_WITH_TESTS)
 ENDIF (CDMATH_WITH_TESTS)
 
 ADD_SUBDIRECTORY(ressources)
+SET(MED_MESHES  ${CMAKE_CURRENT_SOURCE_DIR}/ressources  )
 
 FILE(COPY doc/ DESTINATION share/doc/)
 
 if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-  # Examples tests
-  set (examples_dir ${CDMATH_SOURCE_DIR}/tests/examples)
-  add_subdirectory (${examples_dir})
-  add_subdirectory (validation)
+
+  add_subdirectory (examples) #basic test that run a single calculation
+  add_subdirectory (validation) # convergence studies (several runs)
 
   add_custom_target (tests_CDMATH COMMAND ctest -O testsCDMATH.log)
   add_custom_target (check COMMAND ctest -E 'validation|Example')# may be replace ctest -E with ctest -LE
index 69df6ba4a1e54ce238be0bdcea1771f7c3f09614..f20907b4b6c8f85239d0bd576994ea5e218b8734 100755 (executable)
@@ -1,3 +1,8 @@
+file(GLOB BurgersEquation_EXAMPLES_TO_INSTALL 
+  BurgersEquation1D # 1D Burgers' equation
+)
+
+install(DIRECTORY ${BurgersEquation_EXAMPLES_TO_INSTALL} DESTINATION share/examples/BurgersEquation)
 
 if (CDMATH_WITH_PYTHON )
 
diff --git a/CDMATH/tests/examples/EulerEquations/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6e94c5f
--- /dev/null
@@ -0,0 +1,3 @@
+  
+  ADD_SUBDIRECTORY(IsentropicEulerSystem)
+  ADD_SUBDIRECTORY(      FullEulerSystem)
diff --git a/CDMATH/tests/examples/EulerEquations/FullEulerSystem/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/FullEulerSystem/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..cb95639
--- /dev/null
@@ -0,0 +1,12 @@
+file(GLOB FullEulerEquations_EXAMPLES_TO_INSTALL 
+EulerSystem1D/EulerSystem1DUpwind EulerSystem1D/EulerSystem1DUpwindEntrCorr EulerSystem1D/EulerSystem1DConservativeStaggered EulerSystem_Shock/EulerSystemStaggered EulerSystem_Shock/EulerSystemUpwind
+)
+
+install(DIRECTORY ${FullEulerEquations_EXAMPLES_TO_INSTALL} DESTINATION share/examples/EulerEquations/FullEulerEquations)
+
+IF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+    ADD_SUBDIRECTORY(EulerSystem1D_RiemannProblem)
+    ADD_SUBDIRECTORY(EulerSystem1D_HeatedChannel)
+ENDIF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_HeatedChannel/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_HeatedChannel/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..8415053
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleFullEulerSystem_1DHeatedChannel_Roe ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Euler_complet_HeatedChanel.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_HeatedChannel/Euler_complet_HeatedChanel.py b/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_HeatedChannel/Euler_complet_HeatedChanel.py
new file mode 100644 (file)
index 0000000..e63c38c
--- /dev/null
@@ -0,0 +1,981 @@
+#!/usr/bin/env python3\r
+# -*-coding:utf-8 -*\r
+\r
+"""\r
+Created on Mon Aug 30 2021\r
+@author: Michael NDJINGA, Katia Ait Ameur, Coraline Mounier\r
+\r
+Euler system with heating source term (phi) in one dimension on regular domain [a,b]\r
+Riemann problemn with ghost cell boundary condition\r
+Left : Inlet boundary condition (velocity and temperature imposed)\r
+Right : Outlet boundary condition (pressure imposed)\r
+Roe scheme\r
+Regular square mesh\r
+\r
+State law Stiffened gaz : p = (gamma - 1) * rho * (e - q) - gamma * p0\r
+4 choices of parameters gamma and p0 are available : \r
+  - Lagrange interpolation (with q=0)\r
+  - Hermite interpolation with reference point at 575K (with q=0)\r
+  - Hermite interpolation with reference point at 590K (with q=0)\r
+  - Hermite interpolation with reference point at 617.94K (saturation at 155 bar)  with q=0\r
+  \r
+Linearized enthalpy : h = h_sat + cp * (T - T_sat)\r
+Values for cp and T_sat parameters are taken at the reference point chosen for the state law\r
+\r
+To do correct the computation of the time step : lambda_max (maximum eigenvalue) should be computed first)\r
+"""\r
+\r
+import cdmath\r
+import numpy as np\r
+import matplotlib\r
+\r
+matplotlib.use("Agg")\r
+import matplotlib.pyplot as plt\r
+import matplotlib.animation as manimation\r
+import sys\r
+from math import sqrt, atan, pi\r
+from numpy import sign\r
+\r
+\r
+#### Initial and boundary condition (T in K, v in m/s, p in Pa)\r
+T_inlet  = 565.\r
+v_inlet  = 5.\r
+p_outlet = 155.0 * 10**5\r
+\r
+#initial parameters are determined from boundary conditions\r
+p_0   = p_outlet       #initial pressure\r
+v_0   = v_inlet        #initial velocity\r
+T_0   = T_inlet        #initial temperature\r
+### Heating source term\r
+phi=1.e8\r
+\r
+## Numerical parameter\r
+precision = 1e-6\r
+\r
+#state law parameter : can be 'Lagrange', 'Hermite590K', 'Hermite617K', or 'FLICA'\r
+state_law = "Hermite575K"\r
+\r
+def state_law_parameters(state_law):\r
+       #state law Stiffened Gaz : p = (gamma - 1) * rho * e - gamma * p0\r
+       global gamma\r
+       global p0\r
+       global q\r
+       global c0\r
+       global cp\r
+       global h_sat\r
+       global T_sat\r
+       \r
+       if state_law == "Lagrange":\r
+               # reference values for Lagrange interpolation\r
+               p_ref = 155. * 10**5     #Reference pressure in a REP 900 nuclear power plant     \r
+               p1    = 153. * 10**5     # value of pressure at inlet of a 900 MWe PWR vessel\r
+               rho_ref = 594.38        #density of water at saturation temperature of 617.94K and 155 bars\r
+               rho1 = 742.36           # value of density at inlet of a 900 MWe PWR vessel (T1 = 565K)\r
+               e_ref = 1603.8 * 10**3  #internal energy of water at saturation temperature of 617.94K and 155 bars\r
+               e1 = 1273.6 * 10**3     # value of internal energy at inlet of a 900 MWe PWR vessel\r
+               \r
+               gamma = (p1 - p_ref) / (rho1 * e1 - rho_ref *e_ref) + 1.\r
+               p0 = - 1. / gamma * ( - (gamma - 1) * rho_ref * e_ref + p_ref)\r
+               q=0.\r
+               c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))\r
+               \r
+               cp = 8950.\r
+               h_sat = 1.63 * 10 ** 6     # saturation enthalpy of water at 155 bars\r
+               T_sat = 617.94 \r
+\r
+       elif state_law == "Hermite617K":\r
+               # reference values for Hermite interpolation\r
+               p_ref = 155. * 10**5     #Reference pressure in a REP 900 nuclear power plant\r
+               T_ref = 617.94          #Reference temperature for interpolation at 617.94K\r
+               rho_ref = 594.38        #density of water at saturation temperature of 617.94K and 155 bars\r
+               e_ref = 1603.8 * 10**3  #internal energy of water at saturation temperature of 617.94K and 155 bars\r
+               h_ref   = e_ref + p_ref / rho_ref\r
+               c_ref = 621.43          #sound speed for water at 155 bars and 617.94K\r
+\r
+               gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref)           # From the sound speed formula\r
+               p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)       \r
+               q=0.\r
+               c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))\r
+               \r
+               cp = 8950.                  # value at 155 bar and 617.94K\r
+               h_sat = 1.63 * 10 ** 6     # saturation enthalpy of water at 155 bars\r
+               T_sat = 617.94  \r
+       \r
+       elif state_law == 'Hermite590K':\r
+               # reference values for Hermite interpolation\r
+               p_ref = 155. * 10**5     #Reference pressure  in a REP 900 nuclear power plant\r
+               T_ref = 590.             #Reference temperature for interpolation at 590K\r
+               rho_ref = 688.3         #density of water at 590K and 155 bars\r
+               e_ref = 1411.4 * 10**3  #internal energy of water at 590K and 155 bars\r
+               h_ref   = e_ref + p_ref / rho_ref\r
+               c_ref = 866.29          #sound speed for water at 155 bars and 590K\r
+               \r
+               gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref)           # From the sound speed formula\r
+               p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)       \r
+               q=0.\r
+               c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))\r
+               \r
+               cp = 5996.8                  # value at 155 bar and 590K\r
+               h_sat = 1433.9 * 10 ** 3     # saturation enthalpy of water at 155 bars\r
+               T_sat = 590.  \r
+\r
+       elif state_law == 'Hermite575K':\r
+               # reference values for Hermite interpolation\r
+               p_ref = 155 * 10**5     #Reference pressure  in a REP 900 nuclear power plant\r
+               T_ref = 575             #Reference temperature at inlet in a REP 900 nuclear power plant\r
+               #Remaining values determined using iapws python package\r
+               rho_ref = 722.66        #density of water at 575K and 155 bars\r
+               e_ref = 1326552.66  #internal energy of water at 575K and 155 bars\r
+               h_ref   = e_ref + p_ref / rho_ref\r
+               c_ref = 959.28          #sound speed for water at 155 bars and 575K\r
+               \r
+               gamma = 1 + c_ref * c_ref / (e_ref + p_ref / rho_ref)           # From the sound speed formula\r
+               p0 = 1 / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)       \r
+               q=0.\r
+               c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))#This is actually c_ref\r
+               \r
+               cp = 5504.05                 # value at 155 bar and 590K\r
+               h_sat = h_ref     # saturation enthalpy of water at 155 bars\r
+               T_sat = T_ref\r
+       else:\r
+               raise ValueError("Incorrect value for parameter state_law")\r
+               \r
+def initial_conditions_Riemann_problem(a, b, nx):\r
+       print("Initial data Riemann problem")\r
+       dx = (b - a) / nx  # space step\r
+       x = [a + 0.5 * dx + i * dx for i in range(nx)]  # array of cell center (1D mesh)\r
+\r
+       p_initial = np.array([ p_0 for xi in x])\r
+       v_initial = np.array([ v_0 for xi in x])\r
+       T_initial = np.array([ T_0 for xi in x])\r
+\r
+       rho_initial = p_to_rho_StiffenedGaz(p_initial, T_initial)\r
+       q_initial = rho_initial * v_initial\r
+       rho_E_initial = T_to_rhoE_StiffenedGaz(T_initial, rho_initial, q_initial)\r
+\r
+       return rho_initial, q_initial, rho_E_initial, p_initial, v_initial, T_initial\r
+\r
+def p_to_rho_StiffenedGaz(p_field, T_field):\r
+       rho_field = (p_field + p0) * gamma / (gamma - 1) * 1. / (h_sat + cp * (T_field - T_sat))\r
+       return rho_field\r
+       \r
+def T_to_rhoE_StiffenedGaz(T_field, rho_field, q_field):\r
+       rho_E_field = 1. / 2. * (q_field) ** 2 / rho_field + p0 + rho_field / gamma * (h_sat + cp * (T_field- T_sat))\r
+       return rho_E_field\r
+\r
+def rhoE_to_T_StiffenedGaz(rho_field, q_field, rho_E_field):\r
+       T_field = T_sat + 1 / cp * (gamma * (rho_E_field / rho_field - 1 / 2 * (q_field / rho_field) ** 2) - gamma * p0 / rho_field - h_sat)\r
+       return T_field\r
+\r
+def rho_to_p_StiffenedGaz(rho_field, q_field, rho_E_field):\r
+       p_field = (gamma - 1) * (rho_E_field - 1. / 2 * q_field ** 2 / rho_field) - gamma * p0\r
+       return p_field\r
+\r
+def T_to_E_StiffenedGaz(p_field, T_field, v_field):\r
+       rho_field = p_to_rho_StiffenedGaz(p_field, T_field)\r
+       E_field = (p_field + gamma * p0) / ((gamma-1) * rho_field) + 0.5 * v_field **2\r
+       return E_field\r
+               \r
+def dp_drho_e_const_StiffenedGaz( e ):\r
+       return (gamma-1)*(e-q)\r
+\r
+def dp_de_rho_const_StiffenedGaz( rho ):\r
+       return (gamma-1)*rho\r
+\r
+def sound_speed_StiffenedGaz( h ):\r
+       return np.sqrt((gamma-1)*(h-q))\r
+\r
+def rho_h_to_p_StiffenedGaz( rho, h ):\r
+       return (gamma - 1) * rho * ( h - q ) / gamma - p0\r
+\r
+def MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+       RoeMat = cdmath.Matrix(3, 3)\r
+\r
+       u_l = q_l / rho_l\r
+       u_r = q_r / rho_r\r
+       p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)\r
+       p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)\r
+       H_l = rho_E_l / rho_l + p_l / rho_l\r
+       H_r = rho_E_r / rho_r + p_r / rho_r\r
+\r
+       # Roe averages\r
+       rho = np.sqrt(rho_l * rho_r)\r
+       u   = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+       H   = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+\r
+       p = rho_h_to_p_StiffenedGaz( rho, H - u**2/2. )\r
+       e = H - p / rho - 1./2 * u**2\r
+       dp_drho = dp_drho_e_const_StiffenedGaz( e )\r
+       dp_de   = dp_de_rho_const_StiffenedGaz( rho )\r
+\r
+       RoeMat[0, 0] = 0\r
+       RoeMat[0, 1] = 1\r
+       RoeMat[0, 2] = 0\r
+       RoeMat[1, 0] = dp_drho - u ** 2 + dp_de / rho * (u**2/2 - e)\r
+       RoeMat[1, 1] = 2 * u - u * dp_de / rho\r
+       RoeMat[1, 2] = dp_de / rho\r
+       RoeMat[2, 0] = -u * ( -dp_drho + H - dp_de / rho * (u**2/2 - e) )\r
+       RoeMat[2, 1] = H - dp_de / rho * u ** 2\r
+       RoeMat[2, 2] = (dp_de / rho +1) * u\r
+       \r
+       return(RoeMat)\r
+\r
+       \r
+def Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+    Droe   = cdmath.Matrix(3, 3)\r
+\r
+    u_l = q_l / rho_l\r
+    u_r = q_r / rho_r\r
+    p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)\r
+    p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)\r
+    H_l = rho_E_l / rho_l + p_l / rho_l\r
+    H_r = rho_E_r / rho_r + p_r / rho_r\r
+\r
+    # Roe averages\r
+    rho = np.sqrt(rho_l * rho_r)\r
+    u = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+    H = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+\r
+    c = sound_speed_StiffenedGaz( H - u**2/2. )\r
+    \r
+    lamb  = cdmath.Vector(3)\r
+    lamb[0] = u-c\r
+    lamb[1] = u\r
+    lamb[2] = u+c    \r
+\r
+    r   = cdmath.Matrix(3, 3)\r
+    r[0,0] = 1.\r
+    r[1,0] = u-c\r
+    r[2,0] = H-u*c    \r
+    r[0,1] = 1.\r
+    r[1,1] = u   \r
+    r[2,1] = H-c**2/(gamma-1)    \r
+    r[0,2] = 1.\r
+    r[1,2] = u+c\r
+    r[2,2] = H+u*c         \r
+\r
+    l   = cdmath.Matrix(3, 3)\r
+    l[0,0] = (1./(2*c**2))*(0.5*(gamma-1)*u**2+u*c)\r
+    l[1,0] = (1./(2*c**2))*(-u*(gamma-1)-c)\r
+    l[2,0] = (1./(2*c**2))*(gamma-1)\r
+    l[0,1] = ((gamma-1)/c**2)*(H-u**2)\r
+    l[1,1] = ((gamma-1)/c**2)*u   \r
+    l[2,1] = -((gamma-1)/c**2)    \r
+    l[0,2] = (1./(2*c**2))*(0.5*(gamma-1)*u**2-u*c)\r
+    l[1,2] = (1./(2*c**2))*(c-u*(gamma-1))\r
+    l[2,2] = (1./(2*c**2))*(gamma-1)\r
+\r
+    M1 = cdmath.Matrix(3, 3) #abs(lamb[0])*r[:,0].tensProduct(l[:,0])\r
+    M2 = cdmath.Matrix(3, 3) #abs(lamb[1])*r[:,1].tensProduct(l[:,1])   \r
+    M3 = cdmath.Matrix(3, 3) #abs(lamb[2])*r[:,2].tensProduct(l[:,2])\r
+    for i in range(3):\r
+        for j in range(3):\r
+            M1[i,j] = abs(lamb[0])*r[i,0]*l[j,0]\r
+            M2[i,j] = abs(lamb[1])*r[i,1]*l[j,1]            \r
+            M3[i,j] = abs(lamb[2])*r[i,2]*l[j,2]\r
+            \r
+    Droe = M1+M2+M3 \r
+    \r
+    return(Droe)    \r
+\r
+\r
+def jacobianMatricesm(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+\r
+       if rho_l < 0 or rho_r < 0:\r
+               print("rho_l=", rho_l, " rho_r= ", rho_r)\r
+               raise ValueError("Negative density")\r
+       if rho_E_l < 0 or rho_E_r < 0:\r
+               print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)\r
+               raise ValueError("Negative total energy")\r
+\r
+       RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       \r
+       Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)    \r
+       return (RoeMat - Droe) * coeff * 0.5\r
+\r
+\r
+def jacobianMatricesp(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+       if rho_l < 0 or rho_r < 0:\r
+               print("rho_l=", rho_l, " rho_r= ", rho_r)\r
+               raise ValueError("Negative density")\r
+       if rho_E_l < 0 or rho_E_r < 0:\r
+               print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)\r
+               raise ValueError("Negative total energy")\r
+\r
+       RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)    \r
+\r
+       return (RoeMat + Droe) * coeff * 0.5\r
+\r
+\r
+def FillEdges(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):\r
+       dUi1 = cdmath.Vector(3)\r
+       dUi2 = cdmath.Vector(3)\r
+       temp1 = cdmath.Vector(3)\r
+       temp2 = cdmath.Vector(3)\r
+\r
+       if (j == 0):\r
+               rho_l   = Uk[j * nbComp + 0]\r
+               q_l     = Uk[j * nbComp + 1]\r
+               rho_E_l = Uk[j * nbComp + 2]\r
+               rho_r   = Uk[(j + 1) * nbComp + 0]\r
+               q_r     = Uk[(j + 1) * nbComp + 1]\r
+               rho_E_r = Uk[(j + 1) * nbComp + 2]      \r
+\r
+               Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)\r
+               divMat.addValue(j * nbComp,       j * nbComp, Am * (-1.))\r
+\r
+               p_inlet = rho_to_p_StiffenedGaz(Uk[j * nbComp + 0], Uk[j * nbComp + 1], Uk[j * nbComp + 2])# We take p from inside the domain\r
+               rho_l=p_to_rho_StiffenedGaz(p_inlet, T_inlet) # rho is computed from the temperature BC and the inner pressure\r
+               #rho_l   = Uk[j * nbComp + 0]                            # We take rho from inside the domain\r
+               q_l     = rho_l * v_inlet                               # q is imposed by the boundary condition v_inlet\r
+               rho_E_l = T_to_rhoE_StiffenedGaz(T_inlet, rho_l, q_l)   #rhoE is obtained  using the two boundary conditions v_inlet and e_inlet\r
+               rho_r   = Uk[j * nbComp + 0]\r
+               q_r     = Uk[j * nbComp + 1]\r
+               rho_E_r = Uk[j * nbComp + 2]\r
+\r
+               Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+       \r
+               if(isImplicit):\r
+                       dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+                       dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+                       dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+                       temp1 = Am * dUi1\r
+               \r
+                       dUi2[0] = rho_l   -  Uk[(j ) * nbComp + 0]\r
+                       dUi2[1] = q_l     -  Uk[(j ) * nbComp + 1]\r
+                       dUi2[2] = rho_E_l -  Uk[(j ) * nbComp + 2]\r
+                       temp2 = Ap * dUi2\r
+               else:\r
+                       dUi2[0] = rho_l   \r
+                       dUi2[1] = q_l     \r
+                       dUi2[2] = rho_E_l \r
+                       temp2 = Ap * dUi2\r
+\r
+       elif (j == nx - 1):\r
+               rho_l   = Uk[(j - 1) * nbComp + 0]\r
+               q_l     = Uk[(j - 1) * nbComp + 1]\r
+               rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+               rho_r   = Uk[j * nbComp + 0]\r
+               q_r     = Uk[j * nbComp + 1]\r
+               rho_E_r = Uk[j * nbComp + 2]\r
+\r
+               Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+               divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))\r
+\r
+               rho_l   = Uk[j * nbComp + 0]\r
+               q_l     = Uk[j * nbComp + 1]\r
+               rho_E_l = Uk[j * nbComp + 2]\r
+               rho_r   = Uk[(j ) * nbComp + 0]                               # We take rho inside the domain\r
+               q_r     = Uk[(j ) * nbComp + 1]                               # We take q from inside the domain\r
+               rho_E_r = (p_outlet+gamma*p0)/(gamma-1) + 0.5*q_r**2/rho_r    # rhoE is obtained using the boundary condition p_outlet\r
+\r
+               Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)       \r
+               divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))\r
+\r
+               if(isImplicit):\r
+                       dUi1[0] = rho_r   - Uk[j * nbComp + 0]\r
+                       dUi1[1] = q_r     - Uk[j * nbComp + 1]\r
+                       dUi1[2] = rho_E_r - Uk[j * nbComp + 2]\r
+                       temp1 = Am * dUi1\r
+\r
+                       dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+                       dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+                       dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+                       temp2 = Ap * dUi2\r
+               else:\r
+                       dUi1[0] = rho_r   \r
+                       dUi1[1] = q_r     \r
+                       dUi1[2] = rho_E_r \r
+                       temp1 = Am * dUi1\r
+       \r
+       if(isImplicit):#implicit scheme, contribution from the Newton scheme residual\r
+               Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])\r
+               Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])\r
+               Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])\r
+       else:#explicit scheme, contribution from the boundary data the right hand side\r
+               Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] \r
+               Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] \r
+               Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] \r
+\r
+def FillInnerCell(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):\r
+\r
+       rho_l   = Uk[(j - 1) * nbComp + 0]\r
+       q_l     = Uk[(j - 1) * nbComp + 1]\r
+       rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+       rho_r   = Uk[j * nbComp + 0]\r
+       q_r     = Uk[j * nbComp + 1]\r
+       rho_E_r = Uk[j * nbComp + 2]\r
+       Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       \r
+       rho_l   = Uk[j * nbComp + 0]\r
+       q_l     = Uk[j * nbComp + 1]\r
+       rho_E_l = Uk[j * nbComp + 2]\r
+       rho_r   = Uk[(j + 1) * nbComp + 0]\r
+       q_r     = Uk[(j + 1) * nbComp + 1]\r
+       rho_E_r = Uk[(j + 1) * nbComp + 2]\r
+       Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+\r
+       divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)\r
+       divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))\r
+       divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+       divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))\r
+\r
+       if(isImplicit):\r
+               dUi1 = cdmath.Vector(3)\r
+               dUi2 = cdmath.Vector(3)\r
+               \r
+               dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+               dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+               dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+       \r
+               dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+               dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+               dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+               \r
+               temp1 = Am * dUi1\r
+               temp2 = Ap * dUi2\r
+\r
+               Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])\r
+               Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])\r
+               Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])\r
+       else:\r
+               Rhs[j * nbComp + 0] = 0\r
+               Rhs[j * nbComp + 1] = 0\r
+               Rhs[j * nbComp + 2] = 0\r
+\r
+def SetPicture(rho_field_Roe, q_field_Roe, h_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe, dx):\r
+       max_initial_rho = max(rho_field_Roe)\r
+       min_initial_rho = min(rho_field_Roe)\r
+       max_initial_q = max(q_field_Roe)\r
+       min_initial_q = min(q_field_Roe)\r
+       min_initial_h = min(h_field_Roe)\r
+       max_initial_h = max(h_field_Roe)\r
+       max_initial_p = max(p_field_Roe)\r
+       min_initial_p = min(p_field_Roe)\r
+       max_initial_v = max(v_field_Roe)\r
+       min_initial_v = min(v_field_Roe)\r
+       max_initial_T = max(T_field_Roe)\r
+       min_initial_T = min(T_field_Roe)\r
+\r
+       fig, ([axDensity, axMomentum, axh],[axPressure, axVitesse, axTemperature]) = plt.subplots(2, 3,sharex=True, figsize=(14,10))\r
+       plt.gcf().subplots_adjust(wspace = 0.5)\r
+\r
+       lineDensity_Roe, = axDensity.plot([a+0.5*dx + i*dx for i in range(nx)], rho_field_Roe, label='Roe')\r
+       axDensity.set(xlabel='x (m)', ylabel='Densité (kg/m3)')\r
+       axDensity.set_xlim(a,b)\r
+       axDensity.set_ylim(680, 800)\r
+       axDensity.legend()\r
+\r
+       lineMomentum_Roe, = axMomentum.plot([a+0.5*dx + i*dx for i in range(nx)], q_field_Roe, label='Roe')\r
+       axMomentum.set(xlabel='x (m)', ylabel='Momentum (kg/(m2.s))')\r
+       axMomentum.set_xlim(a,b)\r
+       axMomentum.set_ylim(3500,       4000)\r
+       axMomentum.legend()\r
+\r
+       lineh_Roe, = axh.plot([a+0.5*dx + i*dx for i in range(nx)], h_field_Roe, label='Roe')\r
+       axh.set(xlabel='x (m)', ylabel='h (J/m3)')\r
+       axh.set_xlim(a,b)\r
+       axh.set_ylim(1.2 * 10**6, 1.5*10**6)\r
+       axh.legend()\r
+       \r
+       linePressure_Roe, = axPressure.plot([a+0.5*dx + i*dx for i in range(nx)], p_field_Roe, label='Roe')\r
+       axPressure.set(xlabel='x (m)', ylabel='Pression (bar)')\r
+       axPressure.set_xlim(a,b)\r
+       axPressure.set_ylim(155, 155.5)\r
+       axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))\r
+       axPressure.legend()\r
+\r
+       lineVitesse_Roe, = axVitesse.plot([a+0.5*dx + i*dx for i in range(nx)], v_field_Roe, label='Roe')\r
+       axVitesse.set(xlabel='x (m)', ylabel='Vitesse (m/s)')\r
+       axVitesse.set_xlim(a,b)\r
+       axVitesse.set_ylim(v_0-1, v_0+1)\r
+       axVitesse.ticklabel_format(axis='y', style='sci', scilimits=(0,0))\r
+       axVitesse.legend()\r
+\r
+       lineTemperature_Roe, = axTemperature.plot([a+0.5*dx + i*dx for i in range(nx)], T_field_Roe, label='Roe')\r
+       axTemperature.set(xlabel='x (m)', ylabel='Température (K)')\r
+       axTemperature.set_xlim(a,b)\r
+       axTemperature.set_ylim(T_0-10, T_0+30)\r
+       axTemperature.ticklabel_format(axis='y', style='sci', scilimits=(0,0))\r
+       axTemperature.legend()\r
+       \r
+       return(fig, lineDensity_Roe, lineMomentum_Roe, lineh_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe)\r
+\r
+\r
+def EulerSystemRoe(ntmax, tmax, cfl, a, b, nbCells, output_freq, meshName, state_law, isImplicit):\r
+       state_law_parameters(state_law)\r
+       dim = 1\r
+       nbComp = 3\r
+       dt = 0.\r
+       time = 0.\r
+       it = 0\r
+       isStationary = False\r
+       dx = (b - a) / nx\r
+       dt = cfl * dx / c0\r
+       #dt = 5*10**(-6)\r
+       nbVoisinsMax = 2\r
+\r
+       # iteration vectors\r
+       Un_Roe  = cdmath.Vector(nbCells * (nbComp))\r
+       dUn_Roe = cdmath.Vector(nbCells * (nbComp))\r
+       dUk_Roe = cdmath.Vector(nbCells * (nbComp))\r
+       Rhs_Roe = cdmath.Vector(nbCells * (nbComp))\r
+\r
+       # Initial conditions\r
+       print("Construction of the initial condition …")\r
+\r
+       rho_field_Roe, q_field_Roe, rho_E_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe = initial_conditions_Riemann_problem(a, b, nx)\r
+       h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2\r
+       p_field_Roe = p_field_Roe * 10 ** (-5)\r
+       \r
+\r
+       for k in range(nbCells):\r
+               Un_Roe[k * nbComp + 0] = rho_field_Roe[k]\r
+               Un_Roe[k * nbComp + 1] = q_field_Roe[k]\r
+               Un_Roe[k * nbComp + 2] = rho_E_field_Roe[k]\r
+\r
+       divMat_Roe = cdmath.SparseMatrixPetsc(nbCells * nbComp, nbCells * nbComp, (nbVoisinsMax + 1) * nbComp)\r
+       \r
+       # Picture settings\r
+       fig, lineDensity_Roe, lineMomentum_Roe, lineRhoE_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe = SetPicture( rho_field_Roe, q_field_Roe, h_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe, dx)\r
+\r
+       plt.savefig("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "0" + ".png")\r
+       iterGMRESMax = 50\r
+       newton_max = 100\r
+\r
+       print("Starting computation of the non linear Euler non isentropic system with Roe scheme …")\r
+       # STARTING TIME LOOP\r
+       while (it < ntmax and time <= tmax and not isStationary):\r
+               dUn_Roe = Un_Roe.deepCopy()\r
+               Uk_Roe  = Un_Roe.deepCopy()\r
+               residu_Roe = 1.\r
+               \r
+               k_Roe = 0\r
+               while (k_Roe < newton_max and residu_Roe > precision):\r
+                       # STARTING NEWTON LOOP\r
+                       divMat_Roe.zeroEntries()  #sets the matrix coefficients to zero\r
+                       for j in range(nbCells):\r
+                               \r
+                               # traitements des bords\r
+                               if (j == 0):\r
+                                       FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)\r
+                               elif (j == nbCells - 1):\r
+                                       FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)\r
+\r
+                               # traitement des cellules internes\r
+                               else:\r
+                                       FillInnerCell(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)\r
+                                       \r
+                               Rhs_Roe[j * nbComp + 2] += phi*dt\r
+                       \r
+                       if(isImplicit):\r
+                               #solving the linear system divMat * dUk = Rhs\r
+                               divMat_Roe.diagonalShift(1.)\r
+                               LS_Roe = cdmath.LinearSolver(divMat_Roe, Rhs_Roe, iterGMRESMax, precision, "GMRES", "LU")\r
+                               dUk_Roe = LS_Roe.solve()\r
+                               vector_residu_Roe = dUk_Roe.maxVector(nbComp)\r
+                               residu_Roe = max(abs(vector_residu_Roe[0])/rho0, abs(vector_residu_Roe[1])/(rho0*v_0), abs(vector_residu_Roe[2])/rhoE0 )\r
+                       else:\r
+                               dUk_Roe=Rhs_Roe - divMat_Roe*Un_Roe\r
+                               residu_Roe = 0.#Convergence schéma Newton\r
+                       \r
+                       if (isImplicit and (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax)):\r
+                               print("Residu Newton at iteration ",k_Roe, " :   ", residu_Roe)\r
+                               print("Linear system converged in ", LS_Roe.getNumberOfIter(), " GMRES iterations")\r
+\r
+                       #updates for Newton loop\r
+                       Uk_Roe += dUk_Roe\r
+                       k_Roe = k_Roe + 1\r
+                       if (isImplicit and not LS_Roe.getStatus()):\r
+                               print("Linear system did not converge ", LS_Roe.getNumberOfIter(), " GMRES iterations")\r
+                               raise ValueError("No convergence of the linear system")\r
+                       \r
+                       if k_Roe == newton_max:\r
+                               raise ValueError("No convergence of Newton Roe Scheme")\r
+\r
+               #updating fields\r
+               Un_Roe = Uk_Roe.deepCopy()\r
+               dUn_Roe -= Un_Roe\r
+\r
+               #Testing stationarity\r
+               residu_stat = dUn_Roe.maxVector(nbComp)#On prend le max de chaque composante\r
+               if (it % output_freq == 0 ):\r
+                       print("Test de stationarité : Un+1-Un= ", max(abs(residu_stat[0])/rho0, abs(residu_stat[1])/(rho0*v_0), abs(residu_stat[2])/rhoE0 ))\r
+\r
+               if ( it>1 and abs(residu_stat[0])/rho0<precision  and abs(residu_stat[1])/(rho0*v_0)<precision and abs(residu_stat[2])/rhoE0<precision):\r
+                               isStationary = True\r
+               \r
+               for k in range(nbCells):\r
+                       rho_field_Roe[k]   = Un_Roe[k * nbComp + 0]\r
+                       q_field_Roe[k]     = Un_Roe[k * nbComp + 1]\r
+                       rho_E_field_Roe[k] = Un_Roe[k * nbComp + 2]\r
+\r
+               v_field_Roe = q_field_Roe / rho_field_Roe\r
+               p_field_Roe = rho_to_p_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)\r
+               T_field_Roe = rhoE_to_T_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)\r
+               h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2\r
+               p_field_Roe = p_field_Roe * 10 ** (-5)\r
+               \r
+               if( min(p_field_Roe)<0) :\r
+                       raise ValueError("Negative pressure, stopping calculation")\r
+\r
+               #picture and video updates\r
+               lineDensity_Roe.set_ydata(rho_field_Roe)\r
+               lineMomentum_Roe.set_ydata(q_field_Roe)\r
+               lineRhoE_Roe.set_ydata(h_field_Roe)\r
+               linePressure_Roe.set_ydata(p_field_Roe)\r
+               lineVitesse_Roe.set_ydata(v_field_Roe)\r
+               lineTemperature_Roe.set_ydata(T_field_Roe)\r
+               \r
+               time = time + dt\r
+               it = it + 1\r
+\r
+               # Savings\r
+               if (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax):\r
+       \r
+                       print("-- Time step : " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))\r
+\r
+                       print("Temperature gain between inlet and outlet is ", T_field_Roe[nbCells-1]-T_field_Roe[0],"\n")\r
+\r
+                       plt.savefig("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "Implicit"+str(isImplicit)+ str(it) + '_time' + str(time) + ".png")\r
+\r
+       print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt)+"\n")\r
+       \r
+       if (it >= ntmax):\r
+               print("Maximum number of time steps ntmax= ", ntmax, " reached")\r
+               return\r
+\r
+       elif (isStationary):\r
+               print("Stationary regime reached at time step ", it, ", t= ", time)\r
+               print("------------------------------------------------------------------------------------")\r
+               np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_rho_Stat.txt", rho_field_Roe, delimiter="\n")\r
+               np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_q_Stat.txt", q_field_Roe, delimiter="\n")\r
+               np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_rhoE_Stat.txt", rho_E_field_Roe, delimiter="\n")\r
+               np.savetxt("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "_p_Stat.txt", p_field_Roe, delimiter="\n")\r
+               plt.savefig("EulerComplet_HeatedChannel_" + str(dim) + "D_Roe" + meshName + "Implicit"+str(isImplicit)+"_Stat.png")\r
+               return\r
+       else:\r
+               print("Maximum time Tmax= ", tmax, " reached")\r
+               return\r
+\r
+\r
+def solve(a, b, nx, meshName, meshType, cfl, state_law, isImplicit):\r
+       print("Simulation of a heated channel in dimension 1 on " + str(nx) + " cells")\r
+       print("State Law Stiffened Gaz, " + state_law)\r
+       print("Initial data : ", "constant fields")\r
+       print("Boundary conditions : ", "Inlet (Left), Outlet (Right)")\r
+       print("Mesh name : ", meshName, ", ", nx, " cells")\r
+       # Problem data\r
+       tmax = 10.\r
+       ntmax = 100000\r
+       output_freq = 1000\r
+       EulerSystemRoe(ntmax, tmax, cfl, a, b, nx, output_freq, meshName, state_law, isImplicit)\r
+       return\r
+\r
+def FillMatrixFromEdges(j, Uk, nbComp, divMat, dt, dx):\r
+\r
+       if (j == 0):\r
+               rho_l   = Uk[j * nbComp + 0]\r
+               q_l     = Uk[j * nbComp + 1]\r
+               rho_E_l = Uk[j * nbComp + 2]\r
+               rho_r   = Uk[(j + 1) * nbComp + 0]\r
+               q_r     = Uk[(j + 1) * nbComp + 1]\r
+               rho_E_r = Uk[(j + 1) * nbComp + 2]      \r
+\r
+               Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)\r
+               divMat.addValue(j * nbComp,       j * nbComp, Am * (-1.))\r
+       \r
+               p_inlet = rho_to_p_StiffenedGaz(Uk[j * nbComp + 0], Uk[j * nbComp + 1], Uk[j * nbComp + 2])# We take p from inside the domain\r
+               rho_l=p_to_rho_StiffenedGaz(p_inlet, T_inlet) # rho is computed from the temperature BC and the inner pressure\r
+               #rho_l   = Uk[j * nbComp + 0]                            # We take rho from inside the domain\r
+               q_l     = rho_l * v_inlet                               # q is imposed by the boundary condition v_inlet\r
+               rho_E_l = T_to_rhoE_StiffenedGaz(T_inlet, rho_l, q_l)   #rhoE is obtained  using the two boundary conditions v_inlet and e_inlet\r
+               rho_r   = Uk[j * nbComp + 0]\r
+               q_r     = Uk[j * nbComp + 1]\r
+               rho_E_r = Uk[j * nbComp + 2]\r
+\r
+               Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+\r
+       elif (j == nx - 1):\r
+               rho_l   = Uk[j * nbComp + 0]\r
+               q_l     = Uk[j * nbComp + 1]\r
+               rho_E_l = Uk[j * nbComp + 2]\r
+               rho_r   = Uk[(j ) * nbComp + 0]                               # We take rho inside the domain\r
+               q_r     = Uk[(j ) * nbComp + 1]                               # We take q from inside the domain\r
+               rho_E_r = (p_outlet+gamma*p0)/(gamma-1) + 0.5*q_r**2/rho_r    # rhoE is obtained using the boundary condition p_outlet\r
+\r
+               Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)       \r
+               divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))\r
+       \r
+               rho_l   = Uk[(j - 1) * nbComp + 0]\r
+               q_l     = Uk[(j - 1) * nbComp + 1]\r
+               rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+               rho_r   = Uk[j * nbComp + 0]\r
+               q_r     = Uk[j * nbComp + 1]\r
+               rho_E_r = Uk[j * nbComp + 2]\r
+\r
+               Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+               divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))\r
+\r
+\r
+def FillMatrixFromInnerCell(j, Uk, nbComp, divMat, dt, dx):\r
+\r
+       rho_l   = Uk[(j - 1) * nbComp + 0]\r
+       q_l     = Uk[(j - 1) * nbComp + 1]\r
+       rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+       rho_r   = Uk[j * nbComp + 0]\r
+       q_r     = Uk[j * nbComp + 1]\r
+       rho_E_r = Uk[j * nbComp + 2]\r
+       Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       \r
+       rho_l   = Uk[j * nbComp + 0]\r
+       q_l     = Uk[j * nbComp + 1]\r
+       rho_E_l = Uk[j * nbComp + 2]\r
+       rho_r   = Uk[(j + 1) * nbComp + 0]\r
+       q_r     = Uk[(j + 1) * nbComp + 1]\r
+       rho_E_r = Uk[(j + 1) * nbComp + 2]\r
+       Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+\r
+       divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)\r
+       divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))\r
+       divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+       divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))\r
+                       \r
+def FillRHSFromEdges(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit):\r
+       dUi1 = cdmath.Vector(3)\r
+       dUi2 = cdmath.Vector(3)\r
+       temp1 = cdmath.Vector(3)\r
+       temp2 = cdmath.Vector(3)\r
+\r
+       if (j == 0):\r
+               rho_l   = Uk[j * nbComp + 0]\r
+               q_l     = Uk[j * nbComp + 1]\r
+               rho_E_l = Uk[j * nbComp + 2]\r
+               rho_r   = Uk[(j + 1) * nbComp + 0]\r
+               q_r     = Uk[(j + 1) * nbComp + 1]\r
+               rho_E_r = Uk[(j + 1) * nbComp + 2]      \r
+\r
+               Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+\r
+               p_inlet = rho_to_p_StiffenedGaz(Uk[j * nbComp + 0], Uk[j * nbComp + 1], Uk[j * nbComp + 2])# We take p from inside the domain\r
+               rho_l=p_to_rho_StiffenedGaz(p_inlet, T_inlet) # rho is computed from the temperature BC and the inner pressure\r
+               #rho_l   = Uk[j * nbComp + 0]                            # We take rho from inside the domain\r
+               q_l     = rho_l * v_inlet                               # q is imposed by the boundary condition v_inlet\r
+               rho_E_l = T_to_rhoE_StiffenedGaz(T_inlet, rho_l, q_l)   #rhoE is obtained  using the two boundary conditions v_inlet and e_inlet\r
+               rho_r   = Uk[j * nbComp + 0]\r
+               q_r     = Uk[j * nbComp + 1]\r
+               rho_E_r = Uk[j * nbComp + 2]\r
+\r
+               Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       \r
+               if(isImplicit):\r
+                       dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+                       dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+                       dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+                       temp1 = Am * dUi1\r
+               \r
+                       dUi2[0] = rho_l   -  Uk[(j ) * nbComp + 0]\r
+                       dUi2[1] = q_l     -  Uk[(j ) * nbComp + 1]\r
+                       dUi2[2] = rho_E_l -  Uk[(j ) * nbComp + 2]\r
+                       temp2 = Ap * dUi2\r
+               else:\r
+                       dUi2[0] = rho_l   \r
+                       dUi2[1] = q_l     \r
+                       dUi2[2] = rho_E_l \r
+                       temp2 = Ap * dUi2\r
+\r
+       elif (j == nx - 1):\r
+               rho_l   = Uk[(j - 1) * nbComp + 0]\r
+               q_l     = Uk[(j - 1) * nbComp + 1]\r
+               rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+               rho_r   = Uk[j * nbComp + 0]\r
+               q_r     = Uk[j * nbComp + 1]\r
+               rho_E_r = Uk[j * nbComp + 2]\r
+\r
+               Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+\r
+               rho_l   = Uk[j * nbComp + 0]\r
+               q_l     = Uk[j * nbComp + 1]\r
+               rho_E_l = Uk[j * nbComp + 2]\r
+               rho_r   = Uk[(j ) * nbComp + 0]                               # We take rho inside the domain\r
+               q_r     = Uk[(j ) * nbComp + 1]                               # We take q from inside the domain\r
+               rho_E_r = (p_outlet+gamma*p0)/(gamma-1) + 0.5*q_r**2/rho_r    # rhoE is obtained using the boundary condition p_outlet\r
+\r
+               Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)       \r
+\r
+               if(isImplicit):\r
+                       dUi1[0] = rho_r   - Uk[j * nbComp + 0]\r
+                       dUi1[1] = q_r     - Uk[j * nbComp + 1]\r
+                       dUi1[2] = rho_E_r - Uk[j * nbComp + 2]\r
+                       temp1 = Am * dUi1\r
+       \r
+                       dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+                       dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+                       dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+                       temp2 = Ap * dUi2\r
+               else:\r
+                       dUi1[0] = rho_r   \r
+                       dUi1[1] = q_r     \r
+                       dUi1[2] = rho_E_r \r
+                       temp1 = Am * dUi1\r
+       \r
+       if(isImplicit):\r
+               Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])\r
+               Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])\r
+               Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])\r
+       else:#explicit scheme, contribution from the boundary data the right hand side\r
+               Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] \r
+               Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] \r
+               Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] \r
+\r
+def FillRHSFromInnerCell(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit):\r
+\r
+       rho_l   = Uk[(j - 1) * nbComp + 0]\r
+       q_l     = Uk[(j - 1) * nbComp + 1]\r
+       rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+       rho_r   = Uk[j * nbComp + 0]\r
+       q_r     = Uk[j * nbComp + 1]\r
+       rho_E_r = Uk[j * nbComp + 2]\r
+       Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       \r
+       rho_l   = Uk[j * nbComp + 0]\r
+       q_l     = Uk[j * nbComp + 1]\r
+       rho_E_l = Uk[j * nbComp + 2]\r
+       rho_r   = Uk[(j + 1) * nbComp + 0]\r
+       q_r     = Uk[(j + 1) * nbComp + 1]\r
+       rho_E_r = Uk[(j + 1) * nbComp + 2]\r
+       Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+\r
+       if(isImplicit):#Contribution to the right hand side if te scheme is implicit\r
+               dUi1 = cdmath.Vector(3)\r
+               dUi2 = cdmath.Vector(3)\r
+               \r
+               dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+               dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+               dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+       \r
+               dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+               dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+               dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+\r
+               temp1 = Am * dUi1\r
+               temp2 = Ap * dUi2\r
+\r
+               Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])\r
+               Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])\r
+               Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])\r
+       else:\r
+               Rhs[j * nbComp + 0] = 0\r
+               Rhs[j * nbComp + 1] = 0\r
+               Rhs[j * nbComp + 2] = 0\r
+\r
+\r
+def computeSystemMatrix(a,b,nx, cfl, Uk, isImplicit):\r
+       dim = 1\r
+       nbComp = 3\r
+       dx = (b - a) / nx\r
+       dt = cfl * dx / c0\r
+       nbVoisinsMax = 2\r
+\r
+       nbCells = nx\r
+       divMat = cdmath.SparseMatrixPetsc(nbCells * nbComp, nbCells * nbComp, (nbVoisinsMax + 1) * nbComp)\r
+\r
+       divMat.zeroEntries()  #sets the matrix coefficients to zero\r
+       for j in range(nbCells):\r
+               \r
+               # traitements des bords\r
+               if (j == 0):\r
+                       FillMatrixFromEdges(j, Uk, nbComp, divMat, dt, dx)\r
+               elif (j == nbCells - 1):\r
+                       FillMatrixFromEdges(j, Uk, nbComp, divMat, dt, dx)\r
+               # traitement des cellules internes\r
+               else:\r
+                       FillMatrixFromInnerCell(j, Uk, nbComp, divMat, dt, dx)\r
+       \r
+       if(isImplicit):         \r
+               divMat.diagonalShift(1.)  # add one on the diagonal\r
+       else:\r
+               divMat*=-1.\r
+               divMat.diagonalShift(1.)  # add one on the diagonal\r
+\r
+       return divMat\r
+\r
+def computeRHSVector(a,b,nx, cfl, Uk, Un, isImplicit):\r
+       dim = 1\r
+       nbComp = 3\r
+       dx = (b - a) / nx\r
+       dt = cfl * dx / c0\r
+       nbVoisinsMax = 2\r
+\r
+       nbCells = nx\r
+       Rhs = cdmath.Vector(nbCells * (nbComp))\r
+\r
+       for j in range(nbCells):\r
+               \r
+               # traitements des bords\r
+               if (j == 0):\r
+                       FillRHSFromEdges(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit)\r
+               elif (j == nbCells - 1):\r
+                       FillRHSFromEdges(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit)\r
+               # traitement des cellules internes\r
+               else:\r
+                       FillRHSFromInnerCell(j, Uk, nbComp, Rhs, Un, dt, dx, isImplicit)\r
+                       \r
+       return Rhs\r
+\r
+\r
+if __name__ == """__main__""":\r
+       nbComp=3 # number of equations \r
+       a = 0.# domain is interval [a,b]\r
+       b = 4.2# domain is interval [a,b]\r
+       nx = 10# number of cells\r
+       dx = (b - a) / nx  # space step\r
+       x = [a + 0.5 * dx + i * dx for i in range(nx)]  # array of cell center (1D mesh)\r
+       state_law = "Hermite575K"\r
+       state_law_parameters(state_law)\r
+       rho0=p_to_rho_StiffenedGaz(p_0, T_0)\r
+       rhoE0=T_to_rhoE_StiffenedGaz(T_0, rho0, rho0*v_0)\r
+\r
+\r
+#### initial condition (T in K, v in m/s, p in Pa)\r
+       p_initial   = np.array([ p_outlet      for xi in x])\r
+       v_initial   = np.array([ v_inlet       for xi in x])\r
+       T_initial   = np.array([ T_inlet       for xi in x])\r
+       \r
+       rho_field = p_to_rho_StiffenedGaz(p_initial, T_initial)\r
+       q_field = rho_field * v_initial\r
+       rho_E_field = rho_field * T_to_E_StiffenedGaz(p_initial, T_initial, v_initial)\r
+\r
+       U = cdmath.Vector(nx * (nbComp))#Inutile à terme mais nécessaire pour le moment\r
+\r
+       for k in range(nx):\r
+               U[k * nbComp + 0] = rho_field[k]\r
+               U[k * nbComp + 1] = q_field[k]\r
+               U[k * nbComp + 2] = rho_E_field[k]\r
+       print("\n Testing function computeSystemMatrix \n")\r
+       cfl = 0.5\r
+       computeSystemMatrix(a, b, nx, cfl, U,True)  #Implicit matrix\r
+       computeSystemMatrix(a, b, nx, cfl, U,False) #Explicit matrix\r
+\r
+       print("\n Testing function computeRHSVector \n")\r
+       cfl = 0.5\r
+       computeRHSVector(a, b, nx, cfl, U, U,True)  #Implicit RHS\r
+       computeRHSVector(a, b, nx, cfl, U, U,False) #Explicit RHS\r
+\r
+       print("\n Testing function solve (Implicit scheme) \n")\r
+       isImplicit=True\r
+       cfl = 1000.\r
+       solve(a, b, nx, "RegularSquares", "", cfl, state_law, isImplicit)\r
+       \r
+       print("\n Testing function solve (Explicit scheme) \n")\r
+       isImplicit=False\r
+       cfl = 0.5\r
+       solve(a, b, nx, "RegularSquares", "", cfl, state_law, isImplicit)\r
+\r
diff --git a/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_RiemannProblem/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_RiemannProblem/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..895c803
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleFullEulerSystem_1DRiemammProblem_Roe ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Euler_complet_RP.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_RiemannProblem/Euler_complet_RP.py b/CDMATH/tests/examples/EulerEquations/FullEulerSystem/EulerSystem1D_RiemannProblem/Euler_complet_RP.py
new file mode 100644 (file)
index 0000000..8785225
--- /dev/null
@@ -0,0 +1,642 @@
+#!/usr/bin/env python3\r
+# -*-coding:utf-8 -*\r
+\r
+"""\r
+Created on Mon Aug 30 2021\r
+@author: Michael NDJINGA, Katia Ait Ameur, Coraline Mounier\r
+\r
+Euler system without source term in one dimension on regular domain [a,b]\r
+Riemann problemn with ghost cell boundary condition\r
+Left and right: Neumann boundary condition \r
+Roe scheme\r
+Regular square mesh\r
+\r
+State law Stiffened gaz : p = (gamma - 1) * rho * (e - q) - gamma * p0\r
+4 choices of parameters gamma and p0 are available : \r
+  - Lagrange interpolation (with q=0)\r
+  - Hermite interpolation with reference point at 575K (with q=0)\r
+  - Hermite interpolation with reference point at 590K (with q=0)\r
+  - Hermite interpolation with reference point at 617.94K (saturation at 155 bar)  with q=0\r
+  \r
+Linearized enthalpy : h = h_sat + cp * (T - T_sat)\r
+Values for cp and T_sat parameters are taken at the reference point chosen for the state law\r
+\r
+To do correct the computation of the time step : lambda_max (maximum eigenvalue) should be computed first)\r
+"""\r
+\r
+import cdmath\r
+import numpy as np\r
+import matplotlib\r
+\r
+matplotlib.use("Agg")\r
+import matplotlib.pyplot as plt\r
+import matplotlib.animation as manimation\r
+import sys\r
+from math import sqrt, atan, pi\r
+from numpy import sign\r
+\r
+\r
+## Numerical parameter\r
+precision = 1e-5\r
+\r
+#state law parameter : can be 'Lagrange', 'Hermite590K', 'Hermite617K', or 'FLICA'\r
+state_law = "Hermite590K"\r
+\r
+#indicates with test case is simulated to compare with FLICA5 results\r
+#num_test = 0 means there are no FLICA5 results given here\r
+num_test = 0\r
+\r
+#def state_law_parameters(state_law):\r
+#state law Stiffened Gaz : p = (gamma - 1) * rho * e - gamma * p0\r
+global gamma\r
+global p0\r
+global q\r
+global c0\r
+global cp\r
+global h_sat\r
+global T_sat\r
+\r
+if state_law == "Lagrange":\r
+       # reference values for Lagrange interpolation\r
+       p_ref = 155. * 10**5     #Reference pressure in a REP 900 nuclear power plant     \r
+       p1    = 153. * 10**5     # value of pressure at inlet of a 900 MWe PWR vessel\r
+       rho_ref = 594.38        #density of water at saturation temperature of 617.94K and 155 bars\r
+       rho1 = 742.36           # value of density at inlet of a 900 MWe PWR vessel (T1 = 565K)\r
+       e_ref = 1603.8 * 10**3  #internal energy of water at saturation temperature of 617.94K and 155 bars\r
+       e1 = 1273.6 * 10**3     # value of internal energy at inlet of a 900 MWe PWR vessel\r
+       \r
+       gamma = (p1 - p_ref) / (rho1 * e1 - rho_ref *e_ref) + 1.\r
+       p0 = - 1. / gamma * ( - (gamma - 1) * rho_ref * e_ref + p_ref)\r
+       q=0.\r
+       c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))\r
+       \r
+       cp = 8950.\r
+       h_sat = 1.63 * 10 ** 6     # saturation enthalpy of water at 155 bars\r
+       T_sat = 617.94 \r
+\r
+elif state_law == "Hermite617K":\r
+       # reference values for Hermite interpolation\r
+       p_ref = 155. * 10**5     #Reference pressure in a REP 900 nuclear power plant\r
+       T_ref = 617.94          #Reference temperature for interpolation at 617.94K\r
+       rho_ref = 594.38        #density of water at saturation temperature of 617.94K and 155 bars\r
+       e_ref = 1603.8 * 10**3  #internal energy of water at saturation temperature of 617.94K and 155 bars\r
+       h_ref   = e_ref + p_ref / rho_ref\r
+       c_ref = 621.43          #sound speed for water at 155 bars and 617.94K\r
+\r
+       gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref)           # From the sound speed formula\r
+       p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)       \r
+       q=0.\r
+       c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))\r
+       \r
+       cp = 8950.                  # value at 155 bar and 617.94K\r
+       h_sat = 1.63 * 10 ** 6     # saturation enthalpy of water at 155 bars\r
+       T_sat = 617.94  \r
+\r
+elif state_law == 'Hermite590K':\r
+       # reference values for Hermite interpolation\r
+       p_ref = 155. * 10**5     #Reference pressure  in a REP 900 nuclear power plant\r
+       T_ref = 590.             #Reference temperature for interpolation at 590K\r
+       rho_ref = 688.3         #density of water at 590K and 155 bars\r
+       e_ref = 1411.4 * 10**3  #internal energy of water at 590K and 155 bars\r
+       h_ref   = e_ref + p_ref / rho_ref\r
+       c_ref = 866.29          #sound speed for water at 155 bars and 590K\r
+       \r
+       gamma = 1. + c_ref * c_ref / (e_ref + p_ref / rho_ref)           # From the sound speed formula\r
+       p0 = 1. / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)       \r
+       q=0.\r
+       c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))\r
+       \r
+       cp = 5996.8                  # value at 155 bar and 590K\r
+       h_sat = 1433.9 * 10 ** 3     # saturation enthalpy of water at 155 bars\r
+       T_sat = 590.  \r
+\r
+elif state_law == 'Hermite575K':\r
+       # reference values for Hermite interpolation\r
+       p_ref = 155 * 10**5     #Reference pressure  in a REP 900 nuclear power plant\r
+       T_ref = 575             #Reference temperature at inlet in a REP 900 nuclear power plant\r
+       #Remaining values determined using iapws python package\r
+       rho_ref = 722.66        #density of water at 575K and 155 bars\r
+       e_ref = 1326552.66  #internal energy of water at 575K and 155 bars\r
+       h_ref   = e_ref + p_ref / rho_ref\r
+       c_ref = 959.28          #sound speed for water at 155 bars and 575K\r
+       \r
+       gamma = 1 + c_ref * c_ref / (e_ref + p_ref / rho_ref)           # From the sound speed formula\r
+       p0 = 1 / gamma * ( (gamma - 1) * rho_ref * e_ref - p_ref)       \r
+       q=0.\r
+       c0 = sqrt((gamma - 1) * (e_ref + p_ref / rho_ref))#This is actually c_ref\r
+       \r
+       cp = 5504.05                 # value at 155 bar and 590K\r
+       h_sat = h_ref     # saturation enthalpy of water at 155 bars\r
+       T_sat = T_ref\r
+else:\r
+       raise ValueError("Incorrect value for parameter state_law")\r
+\r
+\r
+#initial parameters for Riemann problem (p in Pa, v in m/s, T in K)\r
+p_L = 155. * 10**5  \r
+p_R = 150. * 10**5\r
+v_L = 0.\r
+v_R = 0.\r
+h_L = 1.4963*10**6\r
+h_R = 1.4963*10**6\r
+\r
+T_L = (h_L - h_sat ) / cp + T_sat\r
+T_R = (h_R - h_sat ) / cp + T_sat\r
+\r
+def initial_conditions_Riemann_problem(a, b, nx):\r
+       print("Initial data Riemann problem")\r
+       dx = (b - a) / nx  # space step\r
+       x = [a + 0.5 * dx + i * dx for i in range(nx)]  # array of cell center (1D mesh)        \r
+\r
+       p_initial = np.array([ (xi < (a + b) / 2) * p_L + (xi >= (a + b) / 2) * p_R for xi in x])\r
+       v_initial = np.array([ (xi < (a + b) / 2) * v_L + (xi >= (a + b) / 2) * v_R for xi in x])\r
+       T_initial = np.array([ (xi < (a + b) / 2) * T_L + (xi >= (a + b) / 2) * T_R for xi in x])\r
+\r
+       rho_initial = p_to_rho_StiffenedGaz(p_initial, T_initial)\r
+       q_initial = rho_initial * v_initial\r
+       rho_E_initial = T_to_rhoE_StiffenedGaz(T_initial, rho_initial, q_initial)\r
+\r
+       return rho_initial, q_initial, rho_E_initial, p_initial, v_initial, T_initial\r
+\r
+def rho_to_p_StiffenedGaz(rho_field, q_field, rho_E_field):\r
+       p_field = (gamma - 1) * ( rho_E_field - 1. / 2 * q_field ** 2 / rho_field - rho_field * q) - gamma * p0\r
+       return p_field\r
+       \r
+\r
+def p_to_rho_StiffenedGaz(p_field, T_field):\r
+       rho_field = (p_field + p0) * gamma / (gamma - 1) * 1 / (h_sat + cp * (T_field - T_sat) - q)\r
+       return rho_field\r
+       \r
+\r
+def T_to_rhoE_StiffenedGaz(T_field, rho_field, q_field):\r
+       rho_E_field = 1 / 2 * (q_field) ** 2 / rho_field + p0 + rho_field / gamma * (h_sat + cp * (T_field- T_sat) + (gamma - 1) * q)\r
+       return rho_E_field\r
+\r
+               \r
+def rhoE_to_T_StiffenedGaz(rho_field, q_field, rho_E_field):\r
+       T_field = T_sat + 1 / cp * (gamma * (rho_E_field / rho_field - 1 / 2 * (q_field / rho_field) ** 2) - gamma * p0 / rho_field -  (gamma - 1) * q - h_sat)\r
+       return T_field\r
+\r
+def dp_drho_e_const_StiffenedGaz( e ):\r
+       return (gamma-1)*(e-q)\r
+\r
+def dp_de_rho_const_StiffenedGaz( rho ):\r
+       return (gamma-1)*rho\r
+\r
+def sound_speed_StiffenedGaz( h ):\r
+       return np.sqrt((gamma-1)*(h-q))\r
+\r
+def rho_h_to_p_StiffenedGaz( rho, h ):\r
+       return (gamma - 1) * rho * ( h - q ) / gamma - p0\r
+\r
+def MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+       RoeMat = cdmath.Matrix(3, 3)\r
+\r
+       u_l = q_l / rho_l\r
+       u_r = q_r / rho_r\r
+       p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)\r
+       p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)\r
+       H_l = rho_E_l / rho_l + p_l / rho_l\r
+       H_r = rho_E_r / rho_r + p_r / rho_r\r
+\r
+       # Roe averages\r
+       rho = np.sqrt(rho_l * rho_r)\r
+       u   = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+       H   = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+\r
+       p = rho_h_to_p_StiffenedGaz( rho, H - u**2/2. )\r
+       e = H - p / rho - 1./2 * u**2\r
+       dp_drho = dp_drho_e_const_StiffenedGaz( e )\r
+       dp_de   = dp_de_rho_const_StiffenedGaz( rho )\r
+\r
+       RoeMat[0, 0] = 0\r
+       RoeMat[0, 1] = 1\r
+       RoeMat[0, 2] = 0\r
+       RoeMat[1, 0] = dp_drho - u ** 2 + dp_de / rho * (u**2/2 - e)\r
+       RoeMat[1, 1] = 2 * u - u * dp_de / rho\r
+       RoeMat[1, 2] = dp_de / rho\r
+       RoeMat[2, 0] = -u * ( -dp_drho + H - dp_de / rho * (u**2/2 - e) )\r
+       RoeMat[2, 1] = H - dp_de / rho * u ** 2\r
+       RoeMat[2, 2] = (dp_de / rho +1) * u\r
+       \r
+       return(RoeMat)\r
+\r
+       \r
+def Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+    Droe   = cdmath.Matrix(3, 3)\r
+\r
+    u_l = q_l / rho_l\r
+    u_r = q_r / rho_r\r
+    p_l = rho_to_p_StiffenedGaz(rho_l, q_l, rho_E_l)\r
+    p_r = rho_to_p_StiffenedGaz(rho_r, q_r, rho_E_r)\r
+    H_l = rho_E_l / rho_l + p_l / rho_l\r
+    H_r = rho_E_r / rho_r + p_r / rho_r\r
+\r
+    # Roe averages\r
+    rho = np.sqrt(rho_l * rho_r)\r
+    u = (u_l * sqrt(rho_l) + u_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+    H = (H_l * sqrt(rho_l) + H_r * sqrt(rho_r)) / (sqrt(rho_l) + sqrt(rho_r))\r
+\r
+    c = sound_speed_StiffenedGaz( H - u**2/2. )\r
+    \r
+    lamb  = cdmath.Vector(3)\r
+    lamb[0] = u-c\r
+    lamb[1] = u\r
+    lamb[2] = u+c    \r
+\r
+    r   = cdmath.Matrix(3, 3)\r
+    r[0,0] = 1.\r
+    r[1,0] = u-c\r
+    r[2,0] = H-u*c    \r
+    r[0,1] = 1.\r
+    r[1,1] = u   \r
+    r[2,1] = H-c**2/(gamma-1)    \r
+    r[0,2] = 1.\r
+    r[1,2] = u+c\r
+    r[2,2] = H+u*c         \r
+\r
+    l   = cdmath.Matrix(3, 3)\r
+    l[0,0] = (1./(2*c**2))*(0.5*(gamma-1)*u**2+u*c)\r
+    l[1,0] = (1./(2*c**2))*(-u*(gamma-1)-c)\r
+    l[2,0] = (1./(2*c**2))*(gamma-1)\r
+    l[0,1] = ((gamma-1)/c**2)*(H-u**2)\r
+    l[1,1] = ((gamma-1)/c**2)*u   \r
+    l[2,1] = -((gamma-1)/c**2)    \r
+    l[0,2] = (1./(2*c**2))*(0.5*(gamma-1)*u**2-u*c)\r
+    l[1,2] = (1./(2*c**2))*(c-u*(gamma-1))\r
+    l[2,2] = (1./(2*c**2))*(gamma-1)\r
+\r
+    M1 = cdmath.Matrix(3, 3) #abs(lamb[0])*r[:,0].tensProduct(l[:,0])\r
+    M2 = cdmath.Matrix(3, 3) #abs(lamb[1])*r[:,1].tensProduct(l[:,1])   \r
+    M3 = cdmath.Matrix(3, 3) #abs(lamb[2])*r[:,2].tensProduct(l[:,2])\r
+    for i in range(3):\r
+        for j in range(3):\r
+            M1[i,j] = abs(lamb[0])*r[i,0]*l[j,0]\r
+            M2[i,j] = abs(lamb[1])*r[i,1]*l[j,1]            \r
+            M3[i,j] = abs(lamb[2])*r[i,2]*l[j,2]\r
+            \r
+    Droe = M1+M2+M3 \r
+    \r
+    return(Droe)    \r
+\r
+\r
+def jacobianMatricesm(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+\r
+       if rho_l < 0 or rho_r < 0:\r
+               print("rho_l=", rho_l, " rho_r= ", rho_r)\r
+               raise ValueError("Negative density")\r
+       if rho_E_l < 0 or rho_E_r < 0:\r
+               print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)\r
+               raise ValueError("Negative total energy")\r
+\r
+       RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       \r
+       Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)    \r
+       return (RoeMat - Droe) * coeff * 0.5\r
+\r
+\r
+def jacobianMatricesp(coeff, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r):\r
+       if rho_l < 0 or rho_r < 0:\r
+               print("rho_l=", rho_l, " rho_r= ", rho_r)\r
+               raise ValueError("Negative density")\r
+       if rho_E_l < 0 or rho_E_r < 0:\r
+               print("rho_E_l=", rho_E_l, " rho_E_r= ", rho_E_r)\r
+               raise ValueError("Negative total energy")\r
+\r
+       RoeMat = MatRoe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       Droe = Droe_StiffenedGaz( rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)    \r
+\r
+       return (RoeMat + Droe) * coeff * 0.5\r
+\r
+\r
+def FillEdges(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):\r
+       dUi = cdmath.Vector(3)\r
+\r
+       if (j == 0):\r
+               rho_l   = Uk[j * nbComp + 0]\r
+               q_l     = Uk[j * nbComp + 1]\r
+               rho_E_l = Uk[j * nbComp + 2]\r
+               rho_r   = Uk[(j + 1) * nbComp + 0]\r
+               q_r     = Uk[(j + 1) * nbComp + 1]\r
+               rho_E_r = Uk[(j + 1) * nbComp + 2]\r
+               \r
+               Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)\r
+               divMat.addValue(j * nbComp,       j * nbComp, Am * (-1.))\r
+\r
+               dUi[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+               dUi[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+               dUi[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+               temp = Am * dUi\r
+\r
+               if(isImplicit):\r
+                       Rhs[j * nbComp + 0] = -temp[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])\r
+                       Rhs[j * nbComp + 1] = -temp[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])\r
+                       Rhs[j * nbComp + 2] = -temp[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])\r
+\r
+       elif (j == nx - 1):\r
+               rho_l   = Uk[(j - 1) * nbComp + 0]\r
+               q_l     = Uk[(j - 1) * nbComp + 1]\r
+               rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+               rho_r   = Uk[j * nbComp + 0]\r
+               q_r     = Uk[j * nbComp + 1]\r
+               rho_E_r = Uk[j * nbComp + 2]\r
+\r
+               Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+               divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+               divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))\r
+\r
+               dUi[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+               dUi[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+               dUi[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+\r
+               temp = Ap * dUi\r
+\r
+               if(isImplicit):\r
+                       Rhs[j * nbComp + 0] = temp[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])\r
+                       Rhs[j * nbComp + 1] = temp[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])\r
+                       Rhs[j * nbComp + 2] = temp[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])\r
+\r
+def FillInnerCell(j, Uk, nbComp, divMat, Rhs, Un, dt, dx, isImplicit):\r
+\r
+       rho_l   = Uk[(j - 1) * nbComp + 0]\r
+       q_l     = Uk[(j - 1) * nbComp + 1]\r
+       rho_E_l = Uk[(j - 1) * nbComp + 2]\r
+       rho_r   = Uk[j * nbComp + 0]\r
+       q_r     = Uk[j * nbComp + 1]\r
+       rho_E_r = Uk[j * nbComp + 2]\r
+       Ap = jacobianMatricesp(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+       \r
+       rho_l   = Uk[j * nbComp + 0]\r
+       q_l     = Uk[j * nbComp + 1]\r
+       rho_E_l = Uk[j * nbComp + 2]\r
+       rho_r   = Uk[(j + 1) * nbComp + 0]\r
+       q_r     = Uk[(j + 1) * nbComp + 1]\r
+       rho_E_r = Uk[(j + 1) * nbComp + 2]\r
+       Am = jacobianMatricesm(dt / dx, rho_l, q_l, rho_E_l, rho_r, q_r, rho_E_r)\r
+\r
+       divMat.addValue(j * nbComp, (j + 1) * nbComp, Am)\r
+       divMat.addValue(j * nbComp, j * nbComp, Am * (-1.))\r
+       divMat.addValue(j * nbComp, j * nbComp, Ap)\r
+       divMat.addValue(j * nbComp, (j - 1) * nbComp, Ap * (-1.))\r
+       dUi1 = cdmath.Vector(3)\r
+       dUi2 = cdmath.Vector(3)\r
+       dUi1[0] = Uk[(j + 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+       dUi1[1] = Uk[(j + 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+       dUi1[2] = Uk[(j + 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+\r
+       dUi2[0] = Uk[(j - 1) * nbComp + 0] - Uk[j * nbComp + 0]\r
+       dUi2[1] = Uk[(j - 1) * nbComp + 1] - Uk[j * nbComp + 1]\r
+       dUi2[2] = Uk[(j - 1) * nbComp + 2] - Uk[j * nbComp + 2]\r
+       temp1 = Am * dUi1\r
+       temp2 = Ap * dUi2\r
+\r
+       if(isImplicit):\r
+               Rhs[j * nbComp + 0] = -temp1[0] + temp2[0] - (Uk[j * nbComp + 0] - Un[j * nbComp + 0])\r
+               Rhs[j * nbComp + 1] = -temp1[1] + temp2[1] - (Uk[j * nbComp + 1] - Un[j * nbComp + 1])\r
+               Rhs[j * nbComp + 2] = -temp1[2] + temp2[2] - (Uk[j * nbComp + 2] - Un[j * nbComp + 2])\r
+\r
+def SetPicture(rho_field_Roe, q_field_Roe, h_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe, dx):\r
+       max_initial_rho = max(rho_field_Roe)\r
+       min_initial_rho = min(rho_field_Roe)\r
+       max_initial_q = max(q_field_Roe)\r
+       min_initial_q = min(q_field_Roe)\r
+       min_initial_h = min(h_field_Roe)\r
+       max_initial_h = max(h_field_Roe)\r
+       max_initial_p = max(p_field_Roe)\r
+       min_initial_p = min(p_field_Roe)\r
+       max_initial_v = max(v_field_Roe)\r
+       min_initial_v = min(v_field_Roe)\r
+       max_initial_T = max(T_field_Roe)\r
+       min_initial_T = min(T_field_Roe)\r
+\r
+       fig, ([axDensity, axMomentum, axRhoE],[axPressure, axVitesse, axTemperature]) = plt.subplots(2, 3,sharex=True, figsize=(14,10))\r
+       plt.gcf().subplots_adjust(wspace = 0.5)\r
+\r
+       lineDensity_Roe, = axDensity.plot([a+0.5*dx + i*dx for i in range(nx)], rho_field_Roe, label='Roe')\r
+       axDensity.set(xlabel='x (m)', ylabel='Densité (kg/m3)')\r
+       axDensity.set_xlim(a,b)\r
+       #axDensity.set_ylim(min_initial_rho - 0.1 * (max_initial_rho - min_initial_rho), 700.)\r
+       axDensity.set_ylim(657, 660.5)\r
+       axDensity.legend()\r
+\r
+       lineMomentum_Roe, = axMomentum.plot([a+0.5*dx + i*dx for i in range(nx)], q_field_Roe, label='Roe')\r
+       axMomentum.set(xlabel='x (m)', ylabel='Momentum (kg/(m2.s))')\r
+       axMomentum.set_xlim(a,b)\r
+       #axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q * 2.5)\r
+       axMomentum.set_ylim(-50, 500)\r
+       axMomentum.legend()\r
+       \r
+       lineRhoE_Roe, = axRhoE.plot([a+0.5*dx + i*dx for i in range(nx)], h_field_Roe, label='Roe')\r
+       axRhoE.set(xlabel='x (m)', ylabel='h (J/m3)')\r
+       axRhoE.set_xlim(a,b)\r
+       #axRhoE.set_ylim(min_initial_h - 0.05*abs(min_initial_h), max_initial_h +  0.5*(max_initial_h-min_initial_h))\r
+       axRhoE.set_ylim(1.495 * 10**6, 1.5*10**6)\r
+       axRhoE.legend()\r
+       \r
+       linePressure_Roe, = axPressure.plot([a+0.5*dx + i*dx for i in range(nx)], p_field_Roe, label='Roe')\r
+       axPressure.set(xlabel='x (m)', ylabel='Pression (bar)')\r
+       axPressure.set_xlim(a,b)\r
+       #axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p +  0.5*(max_initial_p-min_initial_p))\r
+       axPressure.set_ylim(149, 156)\r
+       axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))\r
+       axPressure.legend()\r
+\r
+       lineVitesse_Roe, = axVitesse.plot([a+0.5*dx + i*dx for i in range(nx)], v_field_Roe, label='Roe')\r
+       axVitesse.set(xlabel='x (m)', ylabel='Vitesse (m/s)')\r
+       axVitesse.set_xlim(a,b)\r
+       #axVitesse.set_ylim(min_initial_v - 0.05*abs(min_initial_v), 15)\r
+       axVitesse.set_ylim(-0.5, 1)\r
+       axVitesse.ticklabel_format(axis='y', style='sci', scilimits=(0,0))\r
+       axVitesse.legend()\r
+\r
+       lineTemperature_Roe, = axTemperature.plot([a+0.5*dx + i*dx for i in range(nx)], T_field_Roe, label='Roe')\r
+       axTemperature.set(xlabel='x (m)', ylabel='Température (K)')\r
+       axTemperature.set_xlim(a,b)\r
+       #axTemperature.set_ylim(min_initial_T - 0.005*abs(min_initial_T), 604)\r
+       axTemperature.set_ylim(600, 601)\r
+       axTemperature.ticklabel_format(axis='y', style='sci', scilimits=(0,0))\r
+       axTemperature.legend()\r
+       \r
+       return(fig, lineDensity_Roe, lineMomentum_Roe, lineRhoE_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe, lineDensity_Roe, lineMomentum_Roe, lineRhoE_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe)\r
+\r
+\r
+def EulerSystemRoe(ntmax, tmax, cfl, a, b, nbCells, output_freq, meshName, state_law):\r
+       #state_law_parameters(state_law)\r
+       dim = 1\r
+       nbComp = 3\r
+       dt = 0.\r
+       time = 0.\r
+       it = 0\r
+       isStationary = False\r
+       isImplicit = False\r
+       dx = (b - a) / nx\r
+       dt = cfl * dx / c0\r
+       #dt = 5*10**(-6)\r
+       nbVoisinsMax = 2\r
+\r
+       # iteration vectors\r
+       Un_Roe  = cdmath.Vector(nbCells * (nbComp))\r
+       dUn_Roe = cdmath.Vector(nbCells * (nbComp))\r
+       dUk_Roe = cdmath.Vector(nbCells * (nbComp))\r
+       Rhs_Roe = cdmath.Vector(nbCells * (nbComp))\r
+\r
+       # Initial conditions\r
+       print("Construction of the initial condition …")\r
+\r
+       rho_field_Roe, q_field_Roe, rho_E_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe = initial_conditions_Riemann_problem(a, b, nx)\r
+       h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2\r
+       p_field_Roe = p_field_Roe * 10 ** (-5)\r
+       \r
+\r
+       for k in range(nbCells):\r
+               Un_Roe[k * nbComp + 0] = rho_field_Roe[k]\r
+               Un_Roe[k * nbComp + 1] = q_field_Roe[k]\r
+               Un_Roe[k * nbComp + 2] = rho_E_field_Roe[k]\r
+\r
+       divMat_Roe = cdmath.SparseMatrixPetsc(nbCells * nbComp, nbCells * nbComp, (nbVoisinsMax + 1) * nbComp)\r
+       \r
+       # Picture settings\r
+       fig, lineDensity, lineMomentum, lineRhoE, linePressure, lineVitesse, lineTemperature, lineDensity_Roe, lineMomentum_Roe, lineRhoE_Roe, linePressure_Roe, lineVitesse_Roe, lineTemperature_Roe  = SetPicture( rho_field_Roe, q_field_Roe, h_field_Roe, p_field_Roe, v_field_Roe, T_field_Roe, dx)\r
+\r
+       # Video settings\r
+       FFMpegWriter = manimation.writers['ffmpeg']\r
+       metadata = dict(title="Roe scheme for the 1D Euler system", artist="CEA Saclay", comment="Shock tube")\r
+       writer = FFMpegWriter(fps=10, metadata=metadata, codec='h264')\r
+       with writer.saving(fig, "1DEuler_complet_RP_Roe" + ".mp4", ntmax):\r
+               writer.grab_frame()\r
+               plt.savefig("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "0" + ".png")\r
+               np.savetxt( "EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_rho" + "0" + ".txt", rho_field_Roe, delimiter="\n")\r
+               np.savetxt( "EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_q" + "0" + ".txt", q_field_Roe,  delimiter="\n")\r
+               iterGMRESMax = 50\r
+               newton_max = 100\r
+       \r
+               print("Starting computation of the non linear Euler non isentropic system with Roe scheme …")\r
+               # STARTING TIME LOOP\r
+               while (it < ntmax and time <= tmax and not isStationary):\r
+                       dUn_Roe = Un_Roe.deepCopy()\r
+                       Uk_Roe  = Un_Roe.deepCopy()\r
+                       residu_Roe = 1.\r
+                       \r
+                       k_Roe = 0\r
+                       while (k_Roe < newton_max and residu_Roe > precision):\r
+                               # STARTING NEWTON LOOP\r
+                               divMat_Roe.zeroEntries()  #sets the matrix coefficients to zero\r
+                               for j in range(nbCells):\r
+                                       \r
+                                       # traitements des bords\r
+                                       if (j == 0):\r
+                                               FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)\r
+                                       elif (j == nbCells - 1):\r
+                                               FillEdges(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)\r
+       \r
+                                       # traitement des cellules internes\r
+                                       else:\r
+                                               FillInnerCell(j, Uk_Roe, nbComp, divMat_Roe, Rhs_Roe, Un_Roe, dt, dx, isImplicit)\r
+                                               \r
+                               #solving the linear system divMat * dUk = Rhs\r
+                               \r
+                               if(isImplicit):\r
+                                       divMat_Roe.diagonalShift(1.)\r
+                                       LS_Roe = cdmath.LinearSolver(divMat_Roe, Rhs_Roe, iterGMRESMax, precision, "GMRES", "LU")\r
+                                       dUk_Roe = LS_Roe.solve()\r
+                                       residu_Roe = dUk_Roe.norm()\r
+                               else:\r
+                                       dUk_Roe=Rhs_Roe - divMat_Roe*Un_Roe\r
+                                       residu_Roe = 0.#Convergence schéma Newton\r
+                               \r
+                               if (isImplicit and (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax)):\r
+                                       print("Residu Newton :   ", residu_Roe)\r
+                                       print("Linear system converged in ", LS_Roe.getNumberOfIter(), " GMRES iterations")\r
+       \r
+                               #updates for Newton loop\r
+                               Uk_Roe += dUk_Roe\r
+                               k_Roe = k_Roe + 1\r
+                               if (isImplicit and not LS_Roe.getStatus()):\r
+                                       print("Linear system did not converge ", LS_Roe.getNumberOfIter(), " GMRES iterations")\r
+                                       raise ValueError("No convergence of the linear system")\r
+                               \r
+                               if k_Roe == newton_max:\r
+                                       raise ValueError("No convergence of Newton Roe Scheme")\r
+       \r
+                       #updating fields\r
+                       Un_Roe = Uk_Roe.deepCopy()\r
+                       dUn_Roe -= Un_Roe\r
+                       if (dUn_Roe.norm()<precision):\r
+                                       isStationary = True\r
+                       \r
+                       for k in range(nbCells):\r
+                               rho_field_Roe[k]   = Un_Roe[k * nbComp + 0]\r
+                               q_field_Roe[k]     = Un_Roe[k * nbComp + 1]\r
+                               rho_E_field_Roe[k] = Un_Roe[k * nbComp + 2]\r
+       \r
+                       v_field_Roe = q_field_Roe / rho_field_Roe\r
+                       p_field_Roe = rho_to_p_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)\r
+                       T_field_Roe = rhoE_to_T_StiffenedGaz(rho_field_Roe, q_field_Roe, rho_E_field_Roe)\r
+                       h_field_Roe = (rho_E_field_Roe + p_field_Roe) / rho_field_Roe - 0.5 * (q_field_Roe / rho_field_Roe) **2\r
+                       p_field_Roe = p_field_Roe * 10 ** (-5)\r
+                       \r
+                       if( min(p_field_Roe)<0) :\r
+                               raise ValueError("Negative pressure, stopping calculation")\r
+       \r
+                       #picture and video updates\r
+                       lineDensity_Roe.set_ydata(rho_field_Roe)\r
+                       lineMomentum_Roe.set_ydata(q_field_Roe)\r
+                       lineRhoE_Roe.set_ydata(h_field_Roe)\r
+                       linePressure_Roe.set_ydata(p_field_Roe)\r
+                       lineVitesse_Roe.set_ydata(v_field_Roe)\r
+                       lineTemperature_Roe.set_ydata(T_field_Roe)\r
+                       \r
+                       writer.grab_frame()\r
+       \r
+                       time = time + dt\r
+                       it = it + 1\r
+       \r
+                       # Savings\r
+                       if (it == 1 or it % output_freq == 0 or it >= ntmax or isStationary or time >= tmax):\r
+               \r
+                               print("-- Time step : " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))\r
+       \r
+                               plt.savefig("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + str(it) + '_time' + str(time) + ".png")\r
+\r
+       print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))\r
+       if (it >= ntmax):\r
+               print("Maximum number of time steps ntmax= ", ntmax, " reached")\r
+               return\r
+\r
+       elif (isStationary):\r
+               print("Stationary regime reached at time step ", it, ", t= ", time)\r
+               print("------------------------------------------------------------------------------------")\r
+               np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_rho_Stat.txt", rho_field_Roe, delimiter="\n")\r
+               np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_q_Stat.txt", q_field_Roe, delimiter="\n")\r
+               np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_rhoE_Stat.txt", rho_E_field_Roe, delimiter="\n")\r
+               np.savetxt("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_p_Stat.txt", p_field_Roe, delimiter="\n")\r
+               plt.savefig("EulerComplet_RP_" + str(dim) + "D_Roe" + meshName + "_Stat.png")\r
+               return\r
+       else:\r
+               print("Maximum time Tmax= ", tmax, " reached")\r
+               return\r
+\r
+\r
+def solve(a, b, nx, meshName, meshType, cfl, state_law):\r
+       print("Resolution of the Euler System in dimension 1 on " + str(nx) + " cells")\r
+       print("State Law Stiffened Gaz, " + state_law)\r
+       print("Initial data : ", "Riemann problem")\r
+       print("Boundary conditions : ", "Neumann")\r
+       print("Mesh name : ", meshName, ", ", nx, " cells")\r
+       # Problem data\r
+       tmax = 10.\r
+       ntmax = 25\r
+       output_freq = 1\r
+       EulerSystemRoe(ntmax, tmax, cfl, a, b, nx, output_freq, meshName, state_law)\r
+       return\r
+\r
+\r
+if __name__ == """__main__""":\r
+       a = 0.\r
+       b = 1.\r
+       nx = 50\r
+       cfl = 0.5\r
+       #state_law = "Hermite590K"\r
+       #state_law_parameters(state_law)\r
+       solve(a, b, nx, "RegularSquares", "", cfl, state_law)\r
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..0dfd1ee
--- /dev/null
@@ -0,0 +1,15 @@
+file(GLOB IsentropicEulerEquations_EXAMPLES_TO_INSTALL 
+EulerSystem1D/EulerSystem1DUpwind EulerSystem1D/EulerSystem1DUpwindEntrCorr EulerSystem1D/EulerSystem1DConservativeStaggered EulerSystem_Shock/EulerSystemStaggered EulerSystem_Shock/EulerSystemUpwind
+)
+
+install(DIRECTORY ${IsentropicEulerEquations_EXAMPLES_TO_INSTALL} DESTINATION share/examples/EulerEquations/IsentropicEulerEquations)
+
+IF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+    ADD_SUBDIRECTORY(EulerSystem1D/EulerSystem1DUpwind)
+    ADD_SUBDIRECTORY(EulerSystem1D/EulerSystem1DUpwindEntrCorr)
+    ADD_SUBDIRECTORY(EulerSystem1D/EulerSystem1DConservativeStaggered)
+    ADD_SUBDIRECTORY(EulerSystem_Shock/EulerSystemUpwind)
+    ADD_SUBDIRECTORY(EulerSystem_Shock/EulerSystemStaggered)
+ENDIF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DConservativeStaggered/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DConservativeStaggered/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..04ce58c
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleIsentropicEulerSystem_1DShock_ConservativeStaggered ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystem1DConservativeStaggered.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DConservativeStaggered/EulerSystem1DConservativeStaggered.py b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DConservativeStaggered/EulerSystem1DConservativeStaggered.py
new file mode 100644 (file)
index 0000000..c1158ac
--- /dev/null
@@ -0,0 +1,291 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+# Isothermal Euler system
+# d rho/d t + d q/d x =0
+# d q/d t + d (q^2/rho+p)/d x = 0, where q = rho*u and p = c^2*rho
+# UU = (rho,q) : conservative variable
+# Scheme : Conservative stagerred scheme (Ait Ameur et al)
+# Author :  Katia Ait Ameur
+# Date : November 2020
+
+import cdmath
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+from math import sqrt
+
+c0=330.#reference sound speed for water at 15 bars
+precision=1e-5
+rho0=1
+
+def initial_conditions_Riemann_problem(a,b,nx):
+    print("Initial data Riemann problem")
+    dx = (b - a) / nx #space step
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+    rho_initial = [ (xi<(a+b)/2)*rho0        + (xi>=(a+b)/2)*rho0*2       for xi in x]
+    q_initial   = [ (xi<(a+b)/2)*rho0*(-300) + (xi>=(a+b)/2)*rho0*2*(-300)  for xi in x]
+
+    return rho_initial, q_initial
+
+def matrix_coef(rho_l,q_l,rho_r,q_r):
+    m_coef = -0.5*(q_l-q_r)/rho_r
+    return m_coef
+
+def jacobianMatricesm(coeff,rho_l,q_l,rho_r,q_r):
+    RoeMat   = cdmath.Matrix(2,2);
+    Dmac     = cdmath.Matrix(2,2);   
+    
+    u_l=q_l/rho_l  
+    u_r=q_r/rho_r
+    Dmac_coef = matrix_coef(rho_l,q_l,rho_r,q_r)
+    if rho_l<0 or rho_r<0 :
+        print( "rho_l=",rho_l, " rho_r= ",rho_r)
+        raise ValueError("Negative density")
+    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
+    RoeMat[0,0]   = 0
+    RoeMat[0,1]   = 1
+    RoeMat[1,0]   = c0*c0 - u*u
+    RoeMat[1,1]   = 2*u
+    
+    Dmac[0,0]= abs(u)-u;
+    Dmac[0,1]= 1;
+    Dmac[1,0]= -c0*c0-u*u;
+    Dmac[1,1]= abs(u)+u; 
+
+    return (RoeMat-Dmac)*coeff*0.5
+def jacobianMatricesp(coeff,rho_l,q_l,rho_r,q_r):
+    RoeMat   = cdmath.Matrix(2,2);
+    Dmac = cdmath.Matrix(2,2);   
+    
+    u_l=q_l/rho_l 
+    u_r=q_r/rho_r
+    Dmac_coef = matrix_coef(rho_l,q_l,rho_r,q_r)
+    if rho_l<0 or rho_r<0 :
+        print( "rho_l=",rho_l, " rho_r= ",rho_r)
+        raise ValueError("Negative density")
+    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
+    RoeMat[0,0]   = 0
+    RoeMat[0,1]   = 1
+    RoeMat[1,0]   = c0*c0 - u*u
+    RoeMat[1,1]   = 2*u
+    
+    Dmac[0,0]= abs(u)-u;
+    Dmac[0,1]= 1;
+    Dmac[1,0]= -c0*c0-u*u;
+    Dmac[1,1]= abs(u)+u; 
+
+    return (RoeMat+Dmac)*coeff*0.5
+
+def EulerSystemStaggered(ntmax, tmax, cfl, a,b,nx, output_freq, meshName):
+    dim=1
+    nbComp=dim+1
+    nbCells = nx
+    dt = 0.
+    dx=(b-a)/nx
+    dt = cfl * dx / c0
+    nbVoisinsMax=2
+
+    time = 0.
+    it=0;
+    iterGMRESMax=50
+    newton_max = 50
+    isStationary=False
+
+    #iteration vectors
+    Un =cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    dUk=cdmath.Vector(nbCells*(dim+1))
+    Rhs=cdmath.Vector(nbCells*(dim+1))
+
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    rho_field, q_field = initial_conditions_Riemann_problem(a,b,nx)
+    v_field   = [   q_field[i]/rho_field[i]  for i in range(nx)]
+    p_field   = [ rho_field[i]*(c0*c0)       for i in range(nx)]
+
+    max_initial_rho=max(rho_field)
+    min_initial_rho=min(rho_field)
+    max_initial_q=max(q_field)
+    min_initial_q=min(q_field)
+    max_initial_p=max(p_field)
+    min_initial_p=min(p_field)
+    max_initial_v=max(v_field)
+    min_initial_v=min(v_field)
+
+    for k in range(nbCells):
+        Un[k*nbComp+0] = rho_field[k]
+        Un[k*nbComp+1] =   q_field[k]
+
+    print("Starting computation of the non linear Euler system with staggered scheme …")
+    divMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    # Picture settings
+    fig, ([axDensity, axMomentum],[axVelocity, axPressure]) = plt.subplots(2, 2,sharex=True, figsize=(10,10))
+    fig.suptitle('Conservative staggered scheme')
+    lineDensity, = axDensity.plot([a+0.5*dx + i*dx for i in range(nx)], rho_field, label='Density') #new picture for video # Returns a tuple of line objects, thus the comma
+    axDensity.set(xlabel='x (m)', ylabel='Density')
+    axDensity.set_xlim(a,b)
+    axDensity.set_ylim(min_initial_rho - 0.1*(max_initial_rho-min_initial_rho), max_initial_rho +  0.1*(max_initial_rho-min_initial_rho) )
+    axDensity.legend()
+    lineMomentum, = axMomentum.plot([a+0.5*dx + i*dx for i in range(nx)], q_field, label='Momentum')
+    axMomentum.set(xlabel='x (m)', ylabel='Momentum')
+    axMomentum.set_xlim(a,b)
+    axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q +  0.1*(max_initial_q-min_initial_q) )
+    axMomentum.legend()
+    lineVelocity, = axVelocity.plot([a+0.5*dx + i*dx for i in range(nx)], v_field, label='Velocity')
+    axVelocity.set(xlabel='x (m)', ylabel='Velocity')
+    axVelocity.set_xlim(a,b)
+    axVelocity.set_ylim(min_initial_v - 0.4*abs(min_initial_v), max_initial_v +  0.05*abs(max_initial_v) )
+    axVelocity.legend()
+    linePressure, = axPressure.plot([a+0.5*dx + i*dx for i in range(nx)], p_field, label='Pressure')
+    axPressure.set(xlabel='x (m)', ylabel='Pressure')
+    axPressure.set_xlim(a,b)
+    axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p +  0.05*abs(max_initial_p) )
+    axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
+    axPressure.legend()
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Conservative staggered scheme for the 1D isothermal Euler System", artist = "CEA Saclay", comment="Shock tube")
+    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
+    with writer.saving(fig, "1DEuler_System_ConservativeStaggered"+".mp4", ntmax):
+        writer.grab_frame()
+        plt.savefig("EulerSystem"+str(dim)+"D_ConservativeStaggered"+meshName+"_0"+".png")
+
+        # Starting time loop
+        while (it<ntmax and time <= tmax and not isStationary):
+            dUn = Un.deepCopy()
+            Uk  = Un.deepCopy()
+            residu = 1.
+            k=0
+            while (k<newton_max and residu > precision ):
+                #DEBUT BOUCLE NEWTON
+                divMat.zeroEntries()#sets the matrix coefficients to zero
+                for j in range(nbCells):# 
+                    if ( j==0) : 
+                        rho_r = Uk[j*nbComp+0]
+                        q_r   = Uk[j*nbComp+1]
+                        rho_l = rho_r # Conditions de Neumann
+                        q_l   =   q_r
+                        Am= jacobianMatricesm(dt/dx,rho_l,q_l,rho_r,q_r)
+                        divMat.addValue(j*nbComp,(j+1)*nbComp,Am)
+                        divMat.addValue(j*nbComp,    j*nbComp,Am*(-1.))
+                        dUi=cdmath.Vector(2)
+                        dUi[0] = Uk[(j+1)*nbComp+0]-Uk[j*nbComp+0]
+                        dUi[1] = Uk[(j+1)*nbComp+1]-Uk[j*nbComp+1]
+                        temp=cdmath.Vector(2)
+                        temp = Am*dUi
+                        #print("Bloc 0 matrix  :   ", Am)
+                        Rhs[j*nbComp+0] = -temp[0]-(Uk[j*nbComp+0]-Un[j*nbComp+0]) 
+                        Rhs[j*nbComp+1] = -temp[1]-(Uk[j*nbComp+1]-Un[j*nbComp+1]) 
+                    elif ( j==nbCells-1) :
+                        rho_l = Uk[j*nbComp+0]
+                        q_l   = Uk[j*nbComp+1]
+                        rho_r = rho_l # Conditions de Neumann
+                        q_r   =   q_l
+                        Ap= jacobianMatricesp(dt/dx,rho_l,q_l,rho_r,q_r)
+                        divMat.addValue(j*nbComp,    j*nbComp,Ap)
+                        divMat.addValue(j*nbComp,(j-1)*nbComp,Ap*(-1.))
+                        dUi=cdmath.Vector(2)
+                        dUi[0] = Uk[(j-1)*nbComp+0]-Uk[j*nbComp+0]
+                        dUi[1] = Uk[(j-1)*nbComp+1]-Uk[j*nbComp+1]
+                        temp=cdmath.Vector(2)
+                        temp = Ap*dUi
+                        Rhs[j*nbComp+0] = temp[0]-(Uk[j*nbComp+0]-Un[j*nbComp+0]) 
+                        Rhs[j*nbComp+1] = temp[1]-(Uk[j*nbComp+1]-Un[j*nbComp+1]) 
+                    else :
+                        rho_l = Uk[(j-1)*nbComp+0]
+                        q_l   = Uk[(j-1)*nbComp+1]
+                        rho_r = Uk[j*nbComp+0]
+                        q_r   = Uk[j*nbComp+1]
+                        Ap = jacobianMatricesp(dt/dx,rho_l,q_l,rho_r,q_r)
+                        ###############################################################
+                        rho_l = Uk[j*nbComp+0]
+                        q_l   = Uk[j*nbComp+1]
+                        rho_r = Uk[(j+1)*nbComp+0]
+                        q_r   = Uk[(j+1)*nbComp+1]
+                        Am = jacobianMatricesm(dt/dx,rho_l,q_l,rho_r,q_r)
+                        divMat.addValue(j*nbComp,(j+1)*nbComp,Am)
+                        divMat.addValue(j*nbComp,    j*nbComp,Am*(-1.))
+                        divMat.addValue(j*nbComp,    j*nbComp,Ap)
+                        divMat.addValue(j*nbComp,(j-1)*nbComp,Ap*(-1.))
+                        dUi1=cdmath.Vector(2)
+                        dUi2=cdmath.Vector(2)
+                        dUi1[0] = Uk[(j+1)*nbComp+0]-Uk[j*nbComp+0]
+                        dUi1[1] = Uk[(j+1)*nbComp+1]-Uk[j*nbComp+1]
+                        dUi2[0] = Uk[(j-1)*nbComp+0]-Uk[j*nbComp+0]
+                        dUi2[1] = Uk[(j-1)*nbComp+1]-Uk[j*nbComp+1] 
+                        temp1 = cdmath.Vector(2)
+                        temp2 = cdmath.Vector(2)
+                        temp1 = Am*dUi1
+                        temp2 = Ap*dUi2
+                        Rhs[j*nbComp+0] = -temp1[0] + temp2[0] -(Uk[j*nbComp+0]-Un[j*nbComp+0]) 
+                        Rhs[j*nbComp+1] = -temp1[1] + temp2[1] -(Uk[j*nbComp+1]-Un[j*nbComp+1]) 
+                divMat.diagonalShift(1)#only after  filling all coefficients
+                LS=cdmath.LinearSolver(divMat,Rhs,iterGMRESMax, precision, "GMRES","LU")
+                dUk=LS.solve(); 
+                residu = dUk.norm()
+                #stop
+                Uk+=dUk
+                if(not LS.getStatus()):
+                    print("Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
+                    raise ValueError("Pas de convergence du système linéaire");
+                k=k+1
+            Un = Uk.deepCopy()
+            dUn-=Un
+            for k in range(nbCells):
+                rho_field[k] = Un[k*(dim+1)+0]
+                q_field[k]   = Un[k*(dim+1)+1] 
+            v_field   = [   q_field[i]/rho_field[i]  for i in range(nx)]
+            p_field   = [ rho_field[i]*(c0*c0)       for i in range(nx)]
+
+            lineDensity.set_ydata(rho_field)
+            lineMomentum.set_ydata(q_field)
+            lineVelocity.set_ydata(v_field)
+            linePressure.set_ydata(p_field)
+            writer.grab_frame()
+
+            time=time+dt;
+            it=it+1;
+            #Sauvegardes
+            if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+                #print("Last linear system converged in ", LS.getNumberOfIter(), " GMRES iterations", ", residu final:   ",residu)
+
+                plt.savefig("EulerSystem"+str(dim)+"D_ConservativeStaggered"+meshName+"_"+str(it)+".png")
+                print
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+    if(it>=ntmax):
+        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+        return
+    elif(isStationary):
+        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print("------------------------------------------------------------------------------------")
+        plt.savefig("EulerSystem"+str(dim)+"Staggered"+meshName+"_Stat.png")
+        return
+    else:
+        print("Temps maximum Tmax= ", tmax, " atteint")
+        return
+
+def solve( a,b,nx, meshName, meshType, cfl):
+    print("Resolution of the Euler system in dimension 1 on "+str(nx)+ " cells")
+    print("Initial data : ", "Riemann problem")
+    print("Boundary conditions : ", "Neumann")
+    print("Mesh name : ",meshName , ", ", nx, " cells")
+    # Problem data
+    tmax = 10.
+    ntmax = 50
+    output_freq = 10
+    EulerSystemStaggered(ntmax, tmax, cfl, a,b,nx, output_freq, meshName)
+    return
+
+if __name__ == """__main__""":
+    a=0.
+    b=1.
+    nx=100
+    cfl=0.99
+    solve( a,b,nx,"SquareRegularSquares","RegularSquares",cfl)
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwind/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwind/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..990582d
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleIsentropicEulerSystem_1DShock_UpwindExplicit ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystem1DUpwind.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwind/EulerSystem1DUpwind.py b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwind/EulerSystem1DUpwind.py
new file mode 100644 (file)
index 0000000..ee66cd1
--- /dev/null
@@ -0,0 +1,199 @@
+# Isothermal Euler system
+# d rho/d t + d q/d x =0
+# d q/d t + d (q^2/rho+p)/d x = 0, where q = rho*u and p = c^2*rho
+# UU = (rho,q) : conservative variable
+# Scheme : Roe scheme (without any entropy correction)
+# Comment : the solution displays a non entropic (non physical) shock instead of a rarefaction wave
+# Date : November 2020
+
+from cdmath import *
+import numpy as np
+from math import sqrt
+
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+
+c0=330.#reference sound speed for water at 15 bars
+precision=1e-5
+
+def flux(rho,q):
+    fl = Vector(2);
+    fl[0] = q;
+    fl[1] = q*q/rho + c0*c0*rho;    
+    return fl
+
+def compTimeStep(UU,dx,CFL):
+    M = UU.getMesh();
+    maxAbsEigVa = 0;
+    for i in range(M.getNumberOfCells()):
+        maxAbsEigVa = max(maxAbsEigVa,abs(UU[i,1]/UU[i,0]+c0),abs(UU[i,1]/UU[i,0]-c0));
+        pass
+    dt = CFL*dx/maxAbsEigVa;
+    return dt
+
+def AbsRoeMatrix(rho_l,q_l,rho_r,q_r):
+    AbsRoeMa = Matrix(2,2);
+    u_l = q_l/rho_l;
+    u_r = q_r/rho_r;
+    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
+    AbsRoeMa[0,0]=(abs(u-c0)*(u+c0)+abs(u+c0)*(c0-u))/(2*c0);
+    AbsRoeMa[0,1]= (abs(u+c0)-abs(u-c0))/(2*c0);
+    AbsRoeMa[1,0]=(abs(u-c0)*(u*u-c0*c0)+abs(u+c0)*(c0*c0-u*u))/(2*c0);
+    AbsRoeMa[1,1]=((u+c0)*abs(u+c0)-(u-c0)*abs(u-c0))/(2*c0);
+    return AbsRoeMa;
+    
+def main(meshName):
+    # mesh definition    
+    xmin=.0;
+    xmax= 1;
+    nx=100#1000;
+    ntmax=50;
+    dx = (xmax-xmin)/nx;
+    M=Mesh(xmin,xmax,nx);
+    dim=1
+    
+    # initial time
+    time=0.;
+    # maximum time T
+    tmax=0.01;
+    it=0;
+    freqSortie=10;
+    # CFL condition
+    CFL=0.99;
+    # conservative variable (unknown)
+    UU=Field("Conservative variables",CELLS,M,2);
+
+    # initial condition for Riemann problem
+    print("Construction of the initial condition …")
+    rhoL=1
+    vL=-300
+    rhoR=1.45
+    vR=-300
+    for i in range(M.getNumberOfCells()):
+        x=M.getCell(i).x();
+        if x < (xmax-xmin)/2:
+            UU[i,0] = rhoL;
+            UU[i,1] = rhoL*vL;
+        else:
+            UU[i,0] = rhoR;
+            UU[i,1] = rhoR*vR;
+        pass
+
+    rho_field = [ UU[i,0]          for i in range(nx)]
+    q_field   = [ UU[i,1]          for i in range(nx)]
+    v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
+    p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
+
+    max_initial_rho=max(rhoL,rhoR)
+    min_initial_rho=min(rhoL,rhoR)
+    max_initial_p=max_initial_rho*c0*c0
+    min_initial_p=min_initial_rho*c0*c0
+    max_initial_v=max(vL,vR)
+    min_initial_v=min(vL,vR)
+    max_initial_q=max(vL*rhoL,vR*rhoR)
+    min_initial_q=min(vL*rhoL,vR*rhoR)
+
+    print( "Numerical solution of the 1D Euler equation")
+
+    # prepare some memory
+    UU_limL = Vector(2);
+    UU_limR = Vector(2);
+    Del_UU_RL = Vector(2);
+    UU_new = UU;
+    
+    # Picture settings
+    fig, ([axDensity, axMomentum],[axVelocity, axPressure]) = plt.subplots(2, 2,sharex=True, figsize=(10,10))
+    fig.suptitle('Explicit Upwind scheme')
+    lineDensity, = axDensity.plot([xmin+0.5*dx + i*dx for i in range(nx)], rho_field, label='Density') #new picture for video # Returns a tuple of line objects, thus the comma
+    axDensity.set(xlabel='x (m)', ylabel='Density')
+    axDensity.set_xlim(xmin,xmax)
+    axDensity.set_ylim(min_initial_rho - 0.1*(max_initial_rho-min_initial_rho), max_initial_rho +  0.1*(max_initial_rho-min_initial_rho) )
+    axDensity.legend()
+    lineMomentum, = axMomentum.plot([xmin+0.5*dx + i*dx for i in range(nx)], q_field, label='Momentum')
+    axMomentum.set(xlabel='x (m)', ylabel='Momentum')
+    axMomentum.set_xlim(xmin,xmax)
+    axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q +  0.1*(max_initial_q-min_initial_q) )
+    axMomentum.legend()
+    lineVelocity, = axVelocity.plot([xmin+0.5*dx + i*dx for i in range(nx)], v_field, label='Velocity')
+    axVelocity.set(xlabel='x (m)', ylabel='Velocity')
+    axVelocity.set_xlim(xmin,xmax)
+    axVelocity.set_ylim(min_initial_v - 0.25*abs(min_initial_v), max_initial_v +  0.05*abs(max_initial_v) )
+    axVelocity.legend()
+    linePressure, = axPressure.plot([xmin+0.5*dx + i*dx for i in range(nx)], p_field, label='Pressure')
+    axPressure.set(xlabel='x (m)', ylabel='Pressure')
+    axPressure.set_xlim(xmin,xmax)
+    axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p +  0.05*abs(max_initial_p) )
+    axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
+    axPressure.legend()
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Upwind (Roe) scheme for the 1D isothermal Euler System", artist = "CEA Saclay", comment="Shock tube")
+    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
+    with writer.saving(fig, "1DEuler_System_Upwind"+".mp4", ntmax):
+        writer.grab_frame()
+        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_0"+".png")
+
+        # loop in time
+        while (it<ntmax and time <= tmax ):
+            # time step
+            dt=compTimeStep(UU,dx,CFL);
+            # Neumann boundary condition
+            UU_limL[0] = UU[0,0];
+            UU_limL[1] = UU[0,1];
+            UU_limR[0] = UU[M.getNumberOfCells()-1,0];
+            UU_limR[1] = UU[M.getNumberOfCells()-1,1];
+            flux_iminus = flux(UU_limL[0],UU_limL[1]);
+            #Main loop on cells
+            for i in range(0,M.getNumberOfCells()):
+                if (i<M.getNumberOfCells()-1):
+                    Del_UU_RL[0]=UU[i+1,0]-UU[i,0];
+                    Del_UU_RL[1]=UU[i+1,1]-UU[i,1];
+                    AbsRoeMa = AbsRoeMatrix(UU[i,0],UU[i,1],UU[i+1,0],UU[i+1,1]);
+                    flux_iplus = (flux(UU[i,0],UU[i,1])+flux(UU[i+1,0],UU[i+1,1]))-AbsRoeMa*Del_UU_RL;
+                    flux_iplus[0]*=0.5;
+                    flux_iplus[1]*=0.5;
+                else:
+                    flux_iplus= flux(UU_limR[0],UU_limR[1]);
+                UU_new[i,0] = UU[i,0] - dt/dx*(flux_iplus[0]-flux_iminus[0]);
+                UU_new[i,1] = UU[i,1] - dt/dx*(flux_iplus[1]-flux_iminus[1]);
+                flux_iminus = flux_iplus;
+                pass
+            UU = UU_new;
+            time+=dt;
+            it+=1;
+
+            rho_field = [ UU[i,0]  for i in range(nx)]
+            q_field   = [ UU[i,1]  for i in range(nx)]
+            v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
+            p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
+
+            lineDensity.set_ydata(rho_field)
+            lineMomentum.set_ydata(q_field)
+            lineVelocity.set_ydata(v_field)
+            linePressure.set_ydata(p_field)
+            writer.grab_frame()
+
+            if (it%freqSortie==0):
+                print( "-- Iter : ", it," Time : ",time," dt : ",dt)
+                plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_"+str(it)+".png")
+            pass
+
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+    if(it>=ntmax):
+        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+        return
+    elif(isStationary):
+        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print("------------------------------------------------------------------------------------")
+        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_Stat.png")
+        return
+    else:
+        print("Temps maximum Tmax= ", tmax, " atteint")
+
+    return
+
+if __name__ == '__main__':
+    main("SquareRegularSquares")
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwindEntrCorr/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwindEntrCorr/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..62fde1b
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleIsentropicEulerSystem_1DShock_UpwindExplicit_EntrCorr ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystem1DUpwindEntrCorr.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwindEntrCorr/EulerSystem1DUpwindEntrCorr.py b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem1D/EulerSystem1DUpwindEntrCorr/EulerSystem1DUpwindEntrCorr.py
new file mode 100644 (file)
index 0000000..e1ae7f0
--- /dev/null
@@ -0,0 +1,199 @@
+# Isothermal Euler system
+# d rho/d t + d q/d x =0
+# d q/d t + d (q^2/rho+p)/d x = 0, where q = rho*u and p = c^2*rho
+# UU = (rho,q) : conservative variable
+# Scheme : Roe scheme with entropy correction 
+# Comment : If one removes the entropic correction the result displays a non entropic (non physical) shock instead of a rarefaction wave
+# Date : November 2020
+
+from cdmath import *
+import numpy as np
+from math import sqrt
+
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+
+c0=330.#reference sound speed for water at 15 bars
+precision=1e-5
+
+def flux(rho,q):
+    fl = Vector(2);
+    fl[0] = q;
+    fl[1] = q*q/rho + c0*c0*rho;    
+    return fl
+
+def compTimeStep(UU,dx,CFL):
+    M = UU.getMesh();
+    maxAbsEigVa = 0;
+    for i in range(M.getNumberOfCells()):
+        maxAbsEigVa = max(maxAbsEigVa,abs(UU[i,1]/UU[i,0]+c0),abs(UU[i,1]/UU[i,0]-c0));
+        pass
+    dt = CFL*dx/maxAbsEigVa;
+    return dt
+
+def AbsRoeMatrix(rho_l,q_l,rho_r,q_r):
+    AbsRoeMa = Matrix(2,2);
+    u_l = q_l/rho_l;
+    u_r = q_r/rho_r;
+    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
+    AbsRoeMa[0,0]=(abs(u-c0)*(u+c0)+abs(u+c0)*(c0-u))/(2*c0);
+    AbsRoeMa[0,1]= (abs(u+c0)-abs(u-c0))/(2*c0);
+    AbsRoeMa[1,0]=(abs(u-c0)*(u*u-c0*c0)+abs(u+c0)*(c0*c0-u*u))/(2*c0);
+    AbsRoeMa[1,1]=((u+c0)*abs(u+c0)-(u-c0)*abs(u-c0))/(2*c0);
+    return AbsRoeMa;
+    
+def main(meshName):
+    # mesh definition    
+    xmin=.0;
+    xmax= 1;
+    nx=200#1000;
+    ntmax=100;
+    dx = (xmax-xmin)/nx;
+    M=Mesh(xmin,xmax,nx);
+    dim=1
+    
+    # initial time
+    time=0.;
+    # maximum time T
+    tmax=0.01;
+    it=0;
+    freqSortie=10;
+    # CFL condition
+    CFL=0.9;
+    # conservative variable (unknown)
+    UU=Field("Conservative variables",CELLS,M,2);
+
+    # initial condition for Riemann problem
+    print("Construction of the initial condition …")
+    rhoL=1
+    vL=-300
+    rhoR=2
+    vR=-300
+    for i in range(M.getNumberOfCells()):
+        x=M.getCell(i).x();
+        if x < (xmax-xmin)/2:
+            UU[i,0] = rhoL;
+            UU[i,1] = rhoL*vL;
+        else:
+            UU[i,0] = rhoR;
+            UU[i,1] = rhoR*vR;
+        pass
+
+    rho_field = [ UU[i,0]          for i in range(nx)]
+    q_field   = [ UU[i,1]          for i in range(nx)]
+    v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
+    p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
+
+    max_initial_rho=max(rhoL,rhoR)
+    min_initial_rho=min(rhoL,rhoR)
+    max_initial_p=max_initial_rho*c0*c0
+    min_initial_p=min_initial_rho*c0*c0
+    max_initial_v=max(vL,vR)
+    min_initial_v=min(vL,vR)
+    max_initial_q=max(vL*rhoL,vR*rhoR)
+    min_initial_q=min(vL*rhoL,vR*rhoR)
+
+    print( "Numerical solution of the 1D Euler equation")
+
+    # prepare some memory
+    UU_limL = Vector(2);
+    UU_limR = Vector(2);
+    Del_UU_RL = Vector(2);
+    UU_new = UU;
+    
+    # Picture settings
+    fig, ([axDensity, axMomentum],[axVelocity, axPressure]) = plt.subplots(2, 2,sharex=True, figsize=(10,10))
+    fig.suptitle('Explicit Upwind scheme')
+    lineDensity, = axDensity.plot([xmin+0.5*dx + i*dx for i in range(nx)], rho_field, label='Density') #new picture for video # Returns a tuple of line objects, thus the comma
+    axDensity.set(xlabel='x (m)', ylabel='Density')
+    axDensity.set_xlim(xmin,xmax)
+    axDensity.set_ylim(min_initial_rho - 0.1*(max_initial_rho-min_initial_rho), max_initial_rho +  0.1*(max_initial_rho-min_initial_rho) )
+    axDensity.legend()
+    lineMomentum, = axMomentum.plot([xmin+0.5*dx + i*dx for i in range(nx)], q_field, label='Momentum')
+    axMomentum.set(xlabel='x (m)', ylabel='Momentum')
+    axMomentum.set_xlim(xmin,xmax)
+    axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q +  0.1*(max_initial_q-min_initial_q) )
+    axMomentum.legend()
+    lineVelocity, = axVelocity.plot([xmin+0.5*dx + i*dx for i in range(nx)], v_field, label='Velocity')
+    axVelocity.set(xlabel='x (m)', ylabel='Velocity')
+    axVelocity.set_xlim(xmin,xmax)
+    axVelocity.set_ylim(min_initial_v - 0.4*abs(min_initial_v), max_initial_v +  0.05*abs(max_initial_v) )
+    axVelocity.legend()
+    linePressure, = axPressure.plot([xmin+0.5*dx + i*dx for i in range(nx)], p_field, label='Pressure')
+    axPressure.set(xlabel='x (m)', ylabel='Pressure')
+    axPressure.set_xlim(xmin,xmax)
+    axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p +  0.05*abs(max_initial_p) )
+    axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
+    axPressure.legend()
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Upwind (Roe) scheme with entropic correction for the 1D isothermal Euler System", artist = "CEA Saclay", comment="Shock tube")
+    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
+    with writer.saving(fig, "1DEuler_System_Upwind"+".mp4", ntmax):
+        writer.grab_frame()
+        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_0"+".png")
+
+        # loop in time
+        while (it<ntmax and time <= tmax ):
+            # time step
+            dt=compTimeStep(UU,dx,CFL);
+            # Neumann boundary condition
+            UU_limL[0] = UU[0,0];
+            UU_limL[1] = UU[0,1];
+            UU_limR[0] = UU[M.getNumberOfCells()-1,0];
+            UU_limR[1] = UU[M.getNumberOfCells()-1,1];
+            flux_iminus = flux(UU_limL[0],UU_limL[1]);
+            #Main loop on cells
+            for i in range(0,M.getNumberOfCells()):
+                if (i<M.getNumberOfCells()-1):
+                    Del_UU_RL[0]=UU[i+1,0]-UU[i,0];
+                    Del_UU_RL[1]=UU[i+1,1]-UU[i,1];
+                    AbsRoeMa = AbsRoeMatrix(UU[i,0],UU[i,1],UU[i+1,0],UU[i+1,1]);
+                    flux_iplus = (flux(UU[i,0],UU[i,1])+flux(UU[i+1,0],UU[i+1,1]))-AbsRoeMa*Del_UU_RL - Del_UU_RL*abs(UU[i+1,1]/UU[i+1,0]-UU[i,1]/UU[i,0])#The last term is the entropic correction
+                    flux_iplus[0]*=0.5;
+                    flux_iplus[1]*=0.5;
+                else:
+                    flux_iplus= flux(UU_limR[0],UU_limR[1]);
+                UU_new[i,0] = UU[i,0] - dt/dx*(flux_iplus[0]-flux_iminus[0]);
+                UU_new[i,1] = UU[i,1] - dt/dx*(flux_iplus[1]-flux_iminus[1]);
+                flux_iminus = flux_iplus;
+                pass
+            UU = UU_new;
+            time+=dt;
+            it+=1;
+
+            rho_field = [ UU[i,0]  for i in range(nx)]
+            q_field   = [ UU[i,1]  for i in range(nx)]
+            v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
+            p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
+
+            lineDensity.set_ydata(rho_field)
+            lineMomentum.set_ydata(q_field)
+            lineVelocity.set_ydata(v_field)
+            linePressure.set_ydata(p_field)
+            writer.grab_frame()
+
+            if (it%freqSortie==0):
+                print( "-- Iter : ", it," Time : ",time," dt : ",dt)
+                plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_"+str(it)+".png")
+            pass
+
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+    if(it>=ntmax):
+        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+        return
+    elif(isStationary):
+        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print("------------------------------------------------------------------------------------")
+        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_Stat.png")
+        return
+    else:
+        print("Temps maximum Tmax= ", tmax, " atteint")
+
+    return
+
+if __name__ == '__main__':
+    main("SquareRegularSquares")
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemStaggered/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemStaggered/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..211c08d
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleEulerSystem_2DShock_ConservativeStaggered ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerIsothermal_2DConservativeStaggered.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemStaggered/EulerIsothermal_2DConservativeStaggered.py b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemStaggered/EulerIsothermal_2DConservativeStaggered.py
new file mode 100644 (file)
index 0000000..5480b7e
--- /dev/null
@@ -0,0 +1,798 @@
+#!/usr/bin/env python3\r
+# -*-coding:utf-8 -*\r
+\r
+#===============================================================================================================================\r
+# Name        : Résolution VF des équations d'Euler isotherme 2D sans terme source\r
+#                \partial_t rho + \div q = 0\r
+#                \partial_t q   + \div q \otimes q/rho   \grad p = 0\r
+# Author      : Michaël Ndjinga, Coraline Mounier\r
+# Copyright   : CEA Saclay 2020\r
+# Description : Propagation d'une onde de choc droite\r
+#               Utilisation du schéma upwind explicite ou implicite sur un maillage général\r
+#               Initialisation par une discontinuité verticale\r
+#               Conditions aux limites de Neumann\r
+#                Création et sauvegarde du champ résultant et des figures\r
+#================================================================================================================================\r
+\r
+\r
+import cdmath\r
+import numpy as np\r
+import matplotlib\r
+matplotlib.use("Agg")\r
+import matplotlib.pyplot as plt\r
+import matplotlib.animation as manimation\r
+from math import sqrt\r
+import sys\r
+import PV_routines\r
+\r
+p0=155.e5 #reference pressure in a pressurised nuclear vessel\r
+c0=700.   #reference sound speed for water at 155 bars\r
+rho0=p0/(c0*c0)   #reference density\r
+precision=1e-5\r
+\r
+def initial_conditions_Riemann_problem(my_mesh):\r
+    print( "Initial data : Riemann problem" )\r
+    dim     = my_mesh.getMeshDimension()\r
+    nbCells = my_mesh.getNumberOfCells()\r
+\r
+    xcentre = 0.5\r
+\r
+    density_field = cdmath.Field("Density",    cdmath.CELLS, my_mesh, 1)\r
+    q_x_field     = cdmath.Field("Momentum x", cdmath.CELLS, my_mesh, 1)\r
+    q_y_field     = cdmath.Field("Momentum y", cdmath.CELLS, my_mesh, 1)\r
+    #Velocity field with 3 components should be created for streamlines to be drawn\r
+    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)\r
+\r
+    for i in range(nbCells):\r
+        x = my_mesh.getCell(i).x()\r
+\r
+        # Initial momentum is zero\r
+        q_x_field[i] = 0\r
+        q_y_field[i] = 0\r
+\r
+        # Initial velocity is zero\r
+        velocity_field[i,0] = 0\r
+        velocity_field[i,1] = 0\r
+        velocity_field[i,2] = 0\r
+\r
+        if x < xcentre:\r
+            density_field[i] = rho0\r
+            pass\r
+        else:\r
+            density_field[i] = rho0/2\r
+            pass\r
+        pass\r
+\r
+    return density_field, q_x_field, q_y_field, velocity_field\r
+\r
+\r
+def jacobianMatricesm_x(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
+    RoeMatx = cdmath.Matrix(3,3);\r
+    Dmacx = cdmath.Matrix(3,3);\r
+\r
+    u_lx=q_lx/rho_l\r
+    u_rx=q_rx/rho_r\r
+    u_ly=q_ly/rho_l\r
+    u_ry=q_ry/rho_r\r
+    if rho_l<0 or rho_r<0:\r
+        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
+        raise ValueError("Negative density")\r
+    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+\r
+    RoeMatx[0,0] = 0\r
+    RoeMatx[0,1] = 1\r
+    RoeMatx[0,2] = 0\r
+    RoeMatx[1,0] = c0*c0 - ux*ux\r
+    RoeMatx[1,1] = 2*ux\r
+    RoeMatx[1,2] = 0\r
+    RoeMatx[2,0] = -ux*uy\r
+    RoeMatx[2,1] = uy\r
+    RoeMatx[2,2] = ux\r
+\r
+    Dmacx[0,0] = abs(ux)-ux\r
+    Dmacx[0,1] = 1\r
+    Dmacx[0,2] = 0\r
+    Dmacx[1,0] = -c0*c0-ux*ux\r
+    Dmacx[1,1] = abs(ux)+ux\r
+    Dmacx[1,2] = 0\r
+    Dmacx[2,0] = -ux*uy\r
+    Dmacx[2,1] = uy\r
+    Dmacx[2,2] = abs(ux)\r
+\r
+    return (RoeMatx-Dmacx)*coeff*0.5\r
+\r
+def jacobianMatricesp_x(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
+    RoeMatx   = cdmath.Matrix(3,3)\r
+    Dmacx = cdmath.Matrix(3,3)\r
+\r
+    u_lx=q_lx/rho_l\r
+    u_rx=q_rx/rho_r\r
+    u_ly=q_ly/rho_l\r
+    u_ry=q_ry/rho_r\r
+    if rho_l<0 or rho_r<0:\r
+        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
+        raise ValueError("Negative density")\r
+    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+\r
+    RoeMatx[0,0] = 0\r
+    RoeMatx[0,1] = 1\r
+    RoeMatx[0,2] = 0\r
+    RoeMatx[1,0] = c0*c0 - ux*ux\r
+    RoeMatx[1,1] = 2*ux\r
+    RoeMatx[1,2] = 0\r
+    RoeMatx[2,0] = -ux*uy\r
+    RoeMatx[2,1] = uy\r
+    RoeMatx[2,2] = ux\r
+\r
+    Dmacx[0,0] = abs(ux)-ux\r
+    Dmacx[0,1] = 1\r
+    Dmacx[0,2] = 0\r
+    Dmacx[1,0] = -c0*c0-ux*ux\r
+    Dmacx[1,1] = abs(ux)+ux\r
+    Dmacx[1,2] = 0\r
+    Dmacx[2,0] = -ux*uy\r
+    Dmacx[2,1] = uy\r
+    Dmacx[2,2] = abs(ux)\r
+\r
+    return (RoeMatx+Dmacx)*coeff*0.5\r
+\r
+def jacobianMatricesm_y(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
+    RoeMaty   = cdmath.Matrix(3,3);\r
+    Dmacy = cdmath.Matrix(3,3);\r
+\r
+    u_lx=q_lx/rho_l\r
+    u_rx=q_rx/rho_r\r
+    u_ly=q_ly/rho_l\r
+    u_ry=q_ry/rho_r\r
+    if rho_l<0 or rho_r<0:\r
+        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
+        raise ValueError("Negative density")\r
+    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+\r
+    RoeMaty[0,0] = 0\r
+    RoeMaty[0,1] = 0\r
+    RoeMaty[0,2] = 1\r
+    RoeMaty[1,0] = -ux*uy\r
+    RoeMaty[1,1] = uy\r
+    RoeMaty[1,2] = ux\r
+    RoeMaty[2,0] = c0*c0-uy*uy\r
+    RoeMaty[2,1] = 0\r
+    RoeMaty[2,2] = 2*uy\r
+\r
+    Dmacy[0,0] = abs(uy)-uy\r
+    Dmacy[0,1] = 0\r
+    Dmacy[0,2] = 1\r
+    Dmacy[1,0] = -ux*uy\r
+    Dmacy[1,1] = abs(uy)\r
+    Dmacy[1,2] = ux\r
+    Dmacy[2,0] = -c0*c0-uy*uy\r
+    Dmacy[2,1] = 0\r
+    Dmacy[2,2] = abs(uy)+uy\r
+\r
+    return (RoeMaty-Dmacy)*coeff*0.5\r
+\r
+def jacobianMatricesp_y(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
+    RoeMaty   = cdmath.Matrix(3,3);\r
+    Dmacy = cdmath.Matrix(3,3);\r
+\r
+    u_lx=q_lx/rho_l\r
+    u_rx=q_rx/rho_r\r
+    u_ly=q_ly/rho_l\r
+    u_ry=q_ry/rho_r\r
+    if rho_l<0 or rho_r<0:\r
+        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
+        raise ValueError("Negative density")\r
+    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
+\r
+    RoeMaty[0,0] = 0\r
+    RoeMaty[0,1] = 0\r
+    RoeMaty[0,2] = 1\r
+    RoeMaty[1,0] = -ux*uy\r
+    RoeMaty[1,1] = uy\r
+    RoeMaty[1,2] = ux\r
+    RoeMaty[2,0] = c0*c0-uy*uy\r
+    RoeMaty[2,1] = 0\r
+    RoeMaty[2,2] = 2*uy\r
+\r
+    Dmacy[0,0] = abs(uy)-uy\r
+    Dmacy[0,1] = 0\r
+    Dmacy[0,2] = 1\r
+    Dmacy[1,0] = -ux*uy\r
+    Dmacy[1,1] = abs(uy)\r
+    Dmacy[1,2] = ux\r
+    Dmacy[2,0] = -c0*c0-uy*uy\r
+    Dmacy[2,1] = 0\r
+    Dmacy[2,2] = abs(uy)+uy\r
+\r
+    return (RoeMaty+Dmacy)*coeff*0.5\r
+\r
+def EulerSystemStaggered(ntmax, tmax, cfl,output_freq, my_mesh, meshName):\r
+\r
+    if not my_mesh.isStructured() :\r
+        raise ValueError("Euler_ConservativeStaggered2D_RiemannProblem.py expects a structured mesh")\r
+\r
+    dim=my_mesh.getMeshDimension()\r
+    if dim != 2 :\r
+        raise ValueError("Euler_ConservativeStaggered2D_RiemannProblem.py expects a 2D mesh")\r
+\r
+    nbComp=dim+1\r
+    # Mesh parameters\r
+    nbCells = my_mesh.getNumberOfCells()\r
+    nbCells_x = my_mesh.getNx()\r
+    nbCells_y = my_mesh.getNy()\r
+    dx,dy = my_mesh.getDXYZ()\r
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)\r
+    dx_min=my_mesh.minRatioVolSurf()\r
+    \r
+    # Time evolution parameters\r
+    time = 0.\r
+    it=0;\r
+    isStationary=False\r
+    iterGMRESMax = 50\r
+    newton_max   = 50\r
+\r
+    #iteration vectors\r
+    Un =cdmath.Vector(nbCells*nbComp)\r
+    dUn=cdmath.Vector(nbCells*nbComp)\r
+    dUk=cdmath.Vector(nbCells*nbComp)\r
+    Rhs=cdmath.Vector(nbCells*nbComp)\r
+\r
+    dUi_x=cdmath.Vector(nbComp)\r
+    dUi_y=cdmath.Vector(nbComp)\r
+    dUi1_x=cdmath.Vector(nbComp)\r
+    dUi2_x=cdmath.Vector(nbComp)\r
+    dUi1_y=cdmath.Vector(nbComp)\r
+    dUi2_y=cdmath.Vector(nbComp)\r
+\r
+    # Initial conditions #\r
+    print("Construction of the initial condition …")\r
+    rho_field, q_x_field, q_y_field, velocity_field= initial_conditions_Riemann_problem(my_mesh)\r
+\r
+    for i in range(nbCells):\r
+        Un[nbComp*i]   = rho_field[i]\r
+        Un[nbComp*i+1] = q_x_field[i]\r
+        Un[nbComp*i+2] = q_y_field[i]\r
+\r
+    #Sauvegarde de la donnée initiale\r
+    rho_field.setTime(time,it);\r
+    rho_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density");\r
+    q_x_field.setTime(time,it);\r
+    q_x_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX");\r
+    q_y_field.setTime(time,it);\r
+    q_y_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY");\r
+    velocity_field.setTime(time,it);\r
+    velocity_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_velocity");\r
+\r
+    print("Starting computation of the isothermal Euler system with a conservative staggered scheme …")\r
+    divMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)\r
+\r
+    # Starting time loop\r
+    while (it<ntmax and time <= tmax and not isStationary):\r
+        dUn = Un.deepCopy()\r
+        Uk  = Un.deepCopy()\r
+        residu = 1e10\r
+        k=0\r
+        while (k<newton_max and residu > 1/precision ):\r
+\r
+            dt = cfl * dx_min / c0# This choice should be improved when possible by using the actual eigenvalue abs(u)+c0, that is the time step should be determined avec the computation of the jacobian matrices\r
+            #DEBUT BOUCLE NEWTON\r
+            for j in range(nbCells_y):\r
+                for i in range(nbCells_x):\r
+                    #Traitement des coins\r
+                    if ( j==0 and i==0) :\r
+                        #Calcul de Am_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
+                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
+                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Am_y\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
+                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
+                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Am_x*(-1.)-Am_y)\r
+\r
+                        dUi_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
+                        dUi_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
+\r
+                        temp_x = Am_x*dUi_x\r
+                        temp_y = Am_y*dUi_y\r
+                        #print("Bloc 0 matrix  :   ", Am)\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0] - temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1] - temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2] - temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    elif(i==0 and j==nbCells_y-1):\r
+                        #Calcul de Am_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
+                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
+                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Ap_y\r
+                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
+                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Am_x*(-1.)+Ap_y)\r
+\r
+                        dUi_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
+                        dUi_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
+                        dUi_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        dUi_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
+\r
+                        temp_x = Am_x*dUi_x\r
+                        temp_y = Ap_y*dUi_y\r
+                        #print("Bloc 0 matrix  :   ", Am)\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]- temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]- temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]- temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    elif(i==nbCells_x-1 and j==0):\r
+\r
+                        #Calcul de Ap_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
+                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Am_y\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
+                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
+                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x-Am_y)\r
+\r
+                        dUi_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
+                        dUi_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        dUi_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        dUi_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
+\r
+                        temp_x = Ap_x*dUi_x\r
+                        temp_y= Am_y*dUi_y\r
+                        #print("Bloc 0 matrix  :   ", Am)\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]- temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]- temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]- temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    elif ( j==nbCells_y-1 and i==nbCells_x-1) :\r
+\r
+                        #Calcul de Ap_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
+                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Ap_y\r
+                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
+                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x+Ap_y)\r
+\r
+                        dUi_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
+                        dUi_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        dUi_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        dUi_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
+                        dUi_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        dUi_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
+\r
+                        temp_x = Ap_x*dUi_x\r
+                        temp_y = Ap_y*dUi_y\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]-temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]-temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]-temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    #Traitement des bords restants\r
+                    elif i==0 :\r
+\r
+                        #Calcul de Am_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
+                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
+                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Am_y\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
+                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
+                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Ap_y\r
+                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
+                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #remplissage de la divMat\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_y-Am_x-Am_y)\r
+\r
+                        #remplissage du membre de droite\r
+                        dUi_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
+                        dUi1_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi1_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi1_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
+                        dUi2_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
+                        dUi2_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        dUi2_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
+\r
+                        temp_x  = Am_x*dUi_x\r
+                        temp1_y = Am_y*dUi1_y\r
+                        temp2_y = Ap_y*dUi2_y\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]-temp1_y[0]-temp2_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]-temp1_y[1]-temp2_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]-temp1_y[2]-temp2_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    elif i==nbCells_x-1:\r
+\r
+                        #Calcul de Ap_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
+                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Am_y\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
+                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
+                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Ap_y\r
+                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
+                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #remplissage de la divMat\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_y+Ap_x-Am_y)\r
+\r
+                        #remplissage du membre de droite\r
+                        dUi_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
+                        dUi_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        dUi_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        dUi1_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi1_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi1_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
+                        dUi2_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
+                        dUi2_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        dUi2_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
+\r
+                        temp_x  = Ap_x*dUi_x\r
+                        temp1_y = Am_y*dUi1_y\r
+                        temp2_y = Ap_y*dUi2_y\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]-temp1_y[0]-temp2_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]-temp1_y[1]-temp2_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]-temp1_y[2]-temp2_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    elif j==0:\r
+\r
+                        #Calcul de Am_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
+                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
+                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #Calcul de Ap_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
+                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Am_y\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
+                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
+                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #remplissage de la divMat\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x-Am_x-Am_y)\r
+\r
+                        #remplissage du membre de droite\r
+                        dUi1_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi1_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi1_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
+                        dUi2_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
+                        dUi2_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        dUi2_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        dUi_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
+\r
+                        temp1_x = Am_x*dUi1_x\r
+                        temp2_x = Ap_x*dUi2_x\r
+                        temp_y = Am_y*dUi_y\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp1_x[0]-temp2_x[0]-temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp1_x[1]-temp2_x[1]-temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp1_x[2]-temp2_x[2]-temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    elif j==nbCells_y-1:\r
+\r
+                        #Calcul de Am_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
+                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
+                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #Calcul de Ap_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
+                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Ap_y\r
+                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
+                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #remplissage de la divMat\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x+Ap_y-Am_x)\r
+\r
+                        #remplissage du membre de droite\r
+                        dUi1_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi1_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi1_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
+                        dUi2_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
+                        dUi2_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        dUi2_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        dUi_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
+                        dUi_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        dUi_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
+\r
+                        temp1_x = Am_x*dUi1_x\r
+                        temp2_x = Ap_x*dUi2_x\r
+                        temp_y = Ap_y*dUi_y\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp1_x[0]-temp2_x[0]-temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp1_x[1]-temp2_x[1]-temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp1_x[2]-temp2_x[2]-temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+                    #Traitement des autres cellules\r
+                    else:\r
+\r
+                        #Calcul de Am_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
+                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
+                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #Calcul de Ap_x\r
+                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
+                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Am_y\r
+                        rho_l=Uk[3*nbCells_x*j+3*i]\r
+                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
+                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
+                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #calcul de Ap_y\r
+                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
+                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
+                        rho_r=Uk[3*nbCells_x*j+3*i]\r
+                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
+                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
+                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
+\r
+                        #remplissage de la divMat\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
+                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x+Ap_y-Am_x-Am_y)\r
+\r
+                        #remplissage du membre de droite\r
+\r
+                        dUi1_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi1_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi1_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
+\r
+                        dUi2_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
+                        dUi2_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
+                        dUi2_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
+\r
+                        dUi1_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
+                        dUi1_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
+                        dUi1_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
+\r
+                        dUi2_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
+                        dUi2_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
+                        dUi2_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
+\r
+                        temp1_x = Am_x*dUi1_x\r
+                        temp2_x = Ap_x*dUi2_x\r
+                        temp1_y = Am_y*dUi1_y\r
+                        temp2_y = Ap_y*dUi2_y\r
+                        Rhs[3*nbCells_x*j+3*i+0] = -temp1_x[0]-temp2_x[0]-temp1_y[0]-temp2_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
+                        Rhs[3*nbCells_x*j+3*i+1] = -temp1_x[1]-temp2_x[1]-temp1_y[1]-temp2_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
+                        Rhs[3*nbCells_x*j+3*i+2] = -temp1_x[2]-temp2_x[2]-temp1_y[2]-temp2_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
+\r
+            divMat.diagonalShift(1)  #only after  filling all coefficients\r
+            LS=cdmath.LinearSolver(divMat,Rhs,iterGMRESMax, precision, "GMRES","LU")\r
+            dUk=LS.solve();\r
+            residu = dUk.norm()\r
+            Uk+=dUk\r
+            #print("Newton iteration number ",k, "residu = ",residu)\r
+            if(not LS.getStatus()):\r
+                print("Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")\r
+                raise ValueError("Pas de convergence du système linéaire");\r
+            k=k+1\r
+        Un = Uk.deepCopy()\r
+        dUn-=Un\r
+        isStationary = dUn.norm()<precision\r
+        \r
+        for i in range(nbCells):\r
+            rho_field[i] = Un[nbComp*i]\r
+            q_x_field[i] = Un[nbComp*i+1]\r
+            q_y_field[i] = Un[nbComp*i+2]\r
+\r
+        time=time+dt;\r
+        it=it+1;\r
+        #Sauvegardes\r
+        if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):\r
+            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) + ", Newton iterations: "+str(k)+", ||dUn|| = "+str(dUn.norm()))\r
+            print("Linear system converged in ", LS.getNumberOfIter(), " GMRES iterations, résidu = ", residu)\r
+            for k in range(nbCells):\r
+                rho  =rho_field[k]\r
+                velocity_field[k,0]=q_x_field[i]/rho\r
+                if(dim>1):\r
+                    velocity_field[k,1]=q_y_field[k]/rho\r
+            print\r
+            rho_field.setTime(time,it);\r
+            rho_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density",False);\r
+            q_x_field.setTime(time,it);\r
+            q_x_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX",False);\r
+            q_y_field.setTime(time,it);\r
+            q_y_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY",False);\r
+            velocity_field.setTime(time,it);\r
+            velocity_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_velocity",False);\r
+            #Postprocessing : save 2D picture\r
+            PV_routines.Save_PV_data_to_picture_file("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density_"  +str(it)+'.vtu',"Density",   'CELLS',"EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density"  +str(it))\r
+            PV_routines.Save_PV_data_to_picture_file("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX_"+str(it)+'.vtu',"Momentum x",'CELLS',"EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX"+str(it))\r
+            PV_routines.Save_PV_data_to_picture_file("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY_"+str(it)+'.vtu',"Momentum y",'CELLS',"EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY"+str(it))\r
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))\r
+    if(it>=ntmax):\r
+        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")\r
+        return\r
+    elif(isStationary):\r
+        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)\r
+        print("------------------------------------------------------------------------------------")\r
+        return\r
+    else:\r
+        print("Temps maximum Tmax= ", tmax, " atteint")\r
+        return\r
+\r
+def solve( my_mesh,filename, resolution):\r
+    print("Resolution of the Isothermal Euler system in dimension 2 on "+str(my_mesh.getNumberOfCells())+ " cells")\r
+    print("Initial data : ", "Riemann problem")\r
+    print("Boundary conditions : ", "Neumann")\r
+    print("Mesh name : ",filename )\r
+    # Problem data\r
+    tmax = 10.\r
+    ntmax = 10\r
+    cfl=1\r
+    output_freq = 1\r
+    EulerSystemStaggered(ntmax, tmax, cfl, output_freq, my_mesh, filename)\r
+    return\r
+\r
+if __name__ == """__main__""":\r
+    if len(sys.argv) >1 :\r
+        filename=sys.argv[1]\r
+        my_mesh = cdmath.Mesh(filename)\r
+    else :\r
+        filename = "CartesianGrid"\r
+        ax=0;bx=1;nx=20;\r
+        ay=0;by=1;ny=10;        \r
+        my_mesh = cdmath.Mesh(ax,bx,nx,ay,by,ny)\r
+\r
+    solve(my_mesh,filename,100)\r
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemUpwind/CMakeLists.txt b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemUpwind/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..0e9b410
--- /dev/null
@@ -0,0 +1,81 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/EulerSystemUpwind)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(IMPLICIT_SCHEME  0 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindExplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindExplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshHexagonWithTriangles.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(IMPLICIT_SCHEME  1 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindImplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindImplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemUpwind/EulerSystemUpwind.py b/CDMATH/tests/examples/EulerEquations/IsentropicEulerSystem/EulerSystem_Shock/EulerSystemUpwind/EulerSystemUpwind.py
new file mode 100755 (executable)
index 0000000..0b3dff2
--- /dev/null
@@ -0,0 +1,337 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système Euler 2D barotrope sans terme source
+#                \partial_t rho + \div q = 0
+#                \partial_t q   + \div q\otimes q/rho  +  \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Propagation d'une onde de choc sphérique
+#               Utilisation du schéma de Roe upwind explicite ou implicite sur un maillage général
+#               Initialisation par une surpression sphérique
+#               Conditions aux limites parois
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sqrt
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel (used for initial data)
+c0=700.#reference sound speed for water at 155 bars, 600K (used for eox p= rho c0**2
+precision=1e-5
+
+def initial_conditions_shock(my_mesh, isCircle):
+    print( "Initial data : Spherical wave" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    rayon = 0.15
+    if(not isCircle):
+        xcentre = 0.5
+        ycentre = 0.5
+        zcentre = 0.5
+    else:
+        xcentre = 0.
+        ycentre = 0.
+        zcentre = 0.
+
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        velocity_field[i,0] = 0
+        velocity_field[i,1] = 0
+        velocity_field[i,2] = 0
+
+        x = my_mesh.getCell(i).x()
+        valX = (x - xcentre) * (x - xcentre)
+
+        if(dim==1):
+            val =  sqrt(valX)
+        if(dim==2):
+            y = my_mesh.getCell(i).y()
+            valY = (y - ycentre) * (y - ycentre)
+            val =  sqrt(valX + valY)
+        if(dim==3):
+            y = my_mesh.getCell(i).y()
+            z = my_mesh.getCell(i).z()
+            valY = (y - ycentre) * (y - ycentre)
+            valZ = (z - zcentre) * (z - zcentre)
+            val =  sqrt(valX + valY + valZ)
+
+        if val < rayon:
+            pressure_field[i] = p0
+            pass
+        else:
+            pressure_field[i] = p0
+            pass
+        pass
+
+    return pressure_field, velocity_field
+
+    
+def jacobianMatrices(normale,coeff,rho_l,q_l,rho_r,q_r):
+    RoeMat   = cdmath.Matrix(3,3);
+    AbsRoeMa = cdmath.Matrix(3,3);
+
+    tangent=cdmath.Vector(2);
+    tangent[0]= normale[1];
+    tangent[1]=-normale[0];
+
+    u_l = cdmath.Vector(2); u_l[0]*=q_l[0]/rho_l; u_l[1]*=q_l[1]/rho_l;
+    u_r = cdmath.Vector(2); u_r[0]*=q_r[0]/rho_r; u_r[1]*=q_r[1]/rho_r;
+    if rho_l<0 or rho_r<0 :
+        print( "rho_l=",rho_l, " rho_r= ",rho_r )
+        raise ValueError("Negative density")
+    u=cdmath.Vector(2);
+    u[0] = (u_l[0]*sqrt(rho_l)+u_r[0]*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
+    u[1] = (u_l[1]*sqrt(rho_l)+u_r[1]*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
+    un=u*normale;
+
+    RoeMat[0,0]   = 0
+    RoeMat[0,1]   =     normale[0]
+    RoeMat[0,2]   =     normale[1]
+    RoeMat[1,0]   = c0*c0*normale[0] - un*u[0]
+    RoeMat[2,0]   = c0*c0*normale[1] - un*u[1]
+    RoeMat[1,1]   = un + normale[0]*u[0]
+    RoeMat[1,2]   =      normale[1]*u[0]
+    RoeMat[2,2]   = un + normale[1]*u[1]
+    RoeMat[2,1]   =      normale[0]*u[1]
+
+    AbsRoeMa[0,0]=(abs(un-c0)*(un+c0)+abs(un+c0)*(c0-un))/(2*c0);
+    AbsRoeMa[0,1]= (abs(un+c0)-abs(un-c0))/(2*c0)*normale[0];
+    AbsRoeMa[0,2]= (abs(un+c0)-abs(un-c0))/(2*c0)*normale[1];
+    AbsRoeMa[1,0]=(abs(un-c0)*(un+c0)*(u[0]-c0*normale[0])-abs(un+c0)*(un-c0)*(u[0]+c0*normale[0]))/(2*c0)-abs(un)*(u*tangent)*tangent[0];
+    AbsRoeMa[2,0]=(abs(un-c0)*(un+c0)*(u[1]-c0*normale[1])-abs(un+c0)*(un-c0)*(u[1]+c0*normale[1]))/(2*c0)-abs(un)*(u*tangent)*tangent[1];
+    #subMatrix=(abs(un+c0)*((u-c0*normale)^normale)-abs(un-c0)*((u-c0*normale)^normale))/(2*c0)+abs(un)*(tangent^tangent);
+    AbsRoeMa[1,1]=(abs(un+c0)*((u[0]-c0*normale[0])*normale[0])-abs(un-c0)*((u[0]-c0*normale[0])*normale[0]))/(2*c0)+abs(un)*(tangent[0]*tangent[0]);#subMatrix[0,0];
+    AbsRoeMa[1,2]=(abs(un+c0)*((u[0]-c0*normale[0])*normale[1])-abs(un-c0)*((u[0]-c0*normale[0])*normale[1]))/(2*c0)+abs(un)*(tangent[0]*tangent[1]);#subMatrix[0,1];
+    AbsRoeMa[2,1]=(abs(un+c0)*((u[1]-c0*normale[1])*normale[0])-abs(un-c0)*((u[1]-c0*normale[1])*normale[0]))/(2*c0)+abs(un)*(tangent[1]*tangent[0]);
+    AbsRoeMa[2,2]=(abs(un+c0)*((u[1]-c0*normale[1])*normale[1])-abs(un-c0)*((u[1]-c0*normale[1])*normale[1]))/(2*c0)+abs(un)*(tangent[1]*tangent[1]);
+
+    return (RoeMat-AbsRoeMa)*coeff*0.5,un;
+
+def computeDivergenceMatrix(my_mesh,implMat,Un):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+    maxAbsEigVa = 0
+    q_l=cdmath.Vector(2);
+    q_r=cdmath.Vector(2);
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+    
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
+                    
+                q_l[0]=Un[j*nbComp+1]
+                q_l[1]=Un[j*nbComp+2]
+                q_r[0]=Un[cellAutre*nbComp+1]
+                q_r[1]=Un[cellAutre*nbComp+2]
+                Am, un=jacobianMatrices( normal,Fk.getMeasure()/Cj.getMeasure(),Un[j*nbComp],q_l,Un[cellAutre*nbComp],q_r);
+            
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
+                    q_l[0]=Un[j*nbComp+1]
+                    q_l[1]=Un[j*nbComp+2]
+                    q_r=q_l-normal*2*(q_l*normal)
+                    Am, un=jacobianMatrices( normal,Fk.getMeasure()/Cj.getMeasure(),Un[j*nbComp],q_l,Un[j*nbComp],q_r);
+            
+                    v=cdmath.Vector(dim+1)
+                    for i in range(dim) :
+                        v[i+1]=normal[i]
+                    idMoinsJacCL=v.tensProduct(v)*2
+                    
+                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
+                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
+                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    q_l[0]=Un[j*nbComp+1]
+                    q_l[1]=Un[j*nbComp+2]
+                    q_r[0]=Un[cellAutre*nbComp+1]
+                    q_r[1]=Un[cellAutre*nbComp+2]
+                    Am, un=jacobianMatrices( normal,Fk.getMeasure()/Cj.getMeasure(),Un[j*nbComp],q_l,Un[cellAutre*nbComp],q_r);
+            
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif( Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+            
+            maxAbsEigVa = max(maxAbsEigVa,abs(un+c0),abs(un-c0));
+    
+    return maxAbsEigVa
+
+def EulerSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
+    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1 or filename.find("HEXAON")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
+    else:
+        print( "Mesh name : ", filename )
+        raise ValueError("Mesh name should contain substring square, cube, disk or hexagon")
+
+    #iteration vectors
+    Un =cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =                pressure_field[k]/(c0*c0)
+        Un[k*(dim+1)+1] =Un[k*(dim+1)+0]*velocity_field[k,0]
+        if(dim>=2):
+            Un[k*(dim+1)+2] = Un[k*(dim+1)+0]*velocity_field[k,1]
+            if(dim==3):
+                Un[k*(dim+1)+3] = Un[k*(dim+1)+0]*velocity_field[k,2]
+        print(Un[k*(dim+1)+0],Un[k*(dim+1)+1],Un[k*(dim+1)+2])
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity");
+
+    dx_min=my_mesh.minRatioVolSurf()
+
+    divMat=cdmath.SparseMatrixPetsc(nbCells*(1+dim),nbCells*(1+dim),(nbVoisinsMax+1)*(1+dim))
+    if( isImplicit):
+        iterGMRESMax=50
+        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
+
+    print("Starting computation of the linear wave system with an explicit UPWIND scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        divMat.zeroEntries()#sets the matrix coefficients to zero
+        vp_max=computeDivergenceMatrix(my_mesh,divMat,Un)#To update at each time step
+        dt = cfl * dx_min / vp_max#To update at each time step
+            
+        if(isImplicit):
+            #Adding the identity matrix on the diagonal
+            divMat.diagonalShift(1)#only after  filling all coefficients
+            dUn=Un.deepCopy()
+            LS.setSndMember(Un)
+            Un=LS.solve();
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
+                raise ValueError("Pas de convergence du système linéaire");
+            dUn-=Un
+
+        else:
+            dUn=divMat*Un
+#            print(Un)
+            Un-=dUn
+        
+        time=time+dt;
+        it=it+1;
+         #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+
+            for k in range(nbCells):
+                pressure_field[k]  =Un[k*(dim+1)+0]*c0*c0
+                velocity_field[k,0]=Un[k*(dim+1)+1]/Un[k*(dim+1)+0]
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/Un[k*(dim+1)+0]
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/Un[k*(dim+1)+0]
+#                print(Un[k*(dim+1)+0],Un[k*(dim+1)+1],Un[k*(dim+1)+2])
+
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity",False);
+
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat");
+
+        #Postprocessing : Extraction of the diagonal data
+        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
+        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"EulerSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"EulerSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+
+
+def solve(my_mesh,filename,resolution, isImplicit):
+    print( "Resolution of the Euler system in dimension ", my_mesh.getSpaceDimension())
+    if( my_mesh.getSpaceDimension()!=2):
+        raise ValueError("Only dimension 2 simulations allowed")
+    print( "Numerical method : upwind")
+    print( "Initial data : spherical wave")
+    print( "Wall boundary conditions")
+    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells")
+
+    # Problem data
+    tmax = 1.
+    ntmax = 1
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 1
+
+    EulerSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
+
+def solve_file( filename,resolution, isImplicit):
+    my_mesh = cdmath.Mesh(filename+".med")
+    solve(my_mesh, filename,resolution, isImplicit)
+    
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        filename=sys.argv[1]
+        isImplicit=bool(int(sys.argv[2]))
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100, isImplicit)
+    else :
+        raise ValueError("EulerSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DConservativeStaggered/CMakeLists.txt b/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DConservativeStaggered/CMakeLists.txt
deleted file mode 100755 (executable)
index a4899a3..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleEulerSystem_1DShock_ConservativeStaggered ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystem1DConservativeStaggered.py )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DConservativeStaggered/EulerSystem1DConservativeStaggered.py b/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DConservativeStaggered/EulerSystem1DConservativeStaggered.py
deleted file mode 100644 (file)
index c1158ac..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-# Isothermal Euler system
-# d rho/d t + d q/d x =0
-# d q/d t + d (q^2/rho+p)/d x = 0, where q = rho*u and p = c^2*rho
-# UU = (rho,q) : conservative variable
-# Scheme : Conservative stagerred scheme (Ait Ameur et al)
-# Author :  Katia Ait Ameur
-# Date : November 2020
-
-import cdmath
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-from math import sqrt
-
-c0=330.#reference sound speed for water at 15 bars
-precision=1e-5
-rho0=1
-
-def initial_conditions_Riemann_problem(a,b,nx):
-    print("Initial data Riemann problem")
-    dx = (b - a) / nx #space step
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-    rho_initial = [ (xi<(a+b)/2)*rho0        + (xi>=(a+b)/2)*rho0*2       for xi in x]
-    q_initial   = [ (xi<(a+b)/2)*rho0*(-300) + (xi>=(a+b)/2)*rho0*2*(-300)  for xi in x]
-
-    return rho_initial, q_initial
-
-def matrix_coef(rho_l,q_l,rho_r,q_r):
-    m_coef = -0.5*(q_l-q_r)/rho_r
-    return m_coef
-
-def jacobianMatricesm(coeff,rho_l,q_l,rho_r,q_r):
-    RoeMat   = cdmath.Matrix(2,2);
-    Dmac     = cdmath.Matrix(2,2);   
-    
-    u_l=q_l/rho_l  
-    u_r=q_r/rho_r
-    Dmac_coef = matrix_coef(rho_l,q_l,rho_r,q_r)
-    if rho_l<0 or rho_r<0 :
-        print( "rho_l=",rho_l, " rho_r= ",rho_r)
-        raise ValueError("Negative density")
-    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
-    RoeMat[0,0]   = 0
-    RoeMat[0,1]   = 1
-    RoeMat[1,0]   = c0*c0 - u*u
-    RoeMat[1,1]   = 2*u
-    
-    Dmac[0,0]= abs(u)-u;
-    Dmac[0,1]= 1;
-    Dmac[1,0]= -c0*c0-u*u;
-    Dmac[1,1]= abs(u)+u; 
-
-    return (RoeMat-Dmac)*coeff*0.5
-def jacobianMatricesp(coeff,rho_l,q_l,rho_r,q_r):
-    RoeMat   = cdmath.Matrix(2,2);
-    Dmac = cdmath.Matrix(2,2);   
-    
-    u_l=q_l/rho_l 
-    u_r=q_r/rho_r
-    Dmac_coef = matrix_coef(rho_l,q_l,rho_r,q_r)
-    if rho_l<0 or rho_r<0 :
-        print( "rho_l=",rho_l, " rho_r= ",rho_r)
-        raise ValueError("Negative density")
-    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
-    RoeMat[0,0]   = 0
-    RoeMat[0,1]   = 1
-    RoeMat[1,0]   = c0*c0 - u*u
-    RoeMat[1,1]   = 2*u
-    
-    Dmac[0,0]= abs(u)-u;
-    Dmac[0,1]= 1;
-    Dmac[1,0]= -c0*c0-u*u;
-    Dmac[1,1]= abs(u)+u; 
-
-    return (RoeMat+Dmac)*coeff*0.5
-
-def EulerSystemStaggered(ntmax, tmax, cfl, a,b,nx, output_freq, meshName):
-    dim=1
-    nbComp=dim+1
-    nbCells = nx
-    dt = 0.
-    dx=(b-a)/nx
-    dt = cfl * dx / c0
-    nbVoisinsMax=2
-
-    time = 0.
-    it=0;
-    iterGMRESMax=50
-    newton_max = 50
-    isStationary=False
-
-    #iteration vectors
-    Un =cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    dUk=cdmath.Vector(nbCells*(dim+1))
-    Rhs=cdmath.Vector(nbCells*(dim+1))
-
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    rho_field, q_field = initial_conditions_Riemann_problem(a,b,nx)
-    v_field   = [   q_field[i]/rho_field[i]  for i in range(nx)]
-    p_field   = [ rho_field[i]*(c0*c0)       for i in range(nx)]
-
-    max_initial_rho=max(rho_field)
-    min_initial_rho=min(rho_field)
-    max_initial_q=max(q_field)
-    min_initial_q=min(q_field)
-    max_initial_p=max(p_field)
-    min_initial_p=min(p_field)
-    max_initial_v=max(v_field)
-    min_initial_v=min(v_field)
-
-    for k in range(nbCells):
-        Un[k*nbComp+0] = rho_field[k]
-        Un[k*nbComp+1] =   q_field[k]
-
-    print("Starting computation of the non linear Euler system with staggered scheme …")
-    divMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    # Picture settings
-    fig, ([axDensity, axMomentum],[axVelocity, axPressure]) = plt.subplots(2, 2,sharex=True, figsize=(10,10))
-    fig.suptitle('Conservative staggered scheme')
-    lineDensity, = axDensity.plot([a+0.5*dx + i*dx for i in range(nx)], rho_field, label='Density') #new picture for video # Returns a tuple of line objects, thus the comma
-    axDensity.set(xlabel='x (m)', ylabel='Density')
-    axDensity.set_xlim(a,b)
-    axDensity.set_ylim(min_initial_rho - 0.1*(max_initial_rho-min_initial_rho), max_initial_rho +  0.1*(max_initial_rho-min_initial_rho) )
-    axDensity.legend()
-    lineMomentum, = axMomentum.plot([a+0.5*dx + i*dx for i in range(nx)], q_field, label='Momentum')
-    axMomentum.set(xlabel='x (m)', ylabel='Momentum')
-    axMomentum.set_xlim(a,b)
-    axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q +  0.1*(max_initial_q-min_initial_q) )
-    axMomentum.legend()
-    lineVelocity, = axVelocity.plot([a+0.5*dx + i*dx for i in range(nx)], v_field, label='Velocity')
-    axVelocity.set(xlabel='x (m)', ylabel='Velocity')
-    axVelocity.set_xlim(a,b)
-    axVelocity.set_ylim(min_initial_v - 0.4*abs(min_initial_v), max_initial_v +  0.05*abs(max_initial_v) )
-    axVelocity.legend()
-    linePressure, = axPressure.plot([a+0.5*dx + i*dx for i in range(nx)], p_field, label='Pressure')
-    axPressure.set(xlabel='x (m)', ylabel='Pressure')
-    axPressure.set_xlim(a,b)
-    axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p +  0.05*abs(max_initial_p) )
-    axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
-    axPressure.legend()
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Conservative staggered scheme for the 1D isothermal Euler System", artist = "CEA Saclay", comment="Shock tube")
-    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
-    with writer.saving(fig, "1DEuler_System_ConservativeStaggered"+".mp4", ntmax):
-        writer.grab_frame()
-        plt.savefig("EulerSystem"+str(dim)+"D_ConservativeStaggered"+meshName+"_0"+".png")
-
-        # Starting time loop
-        while (it<ntmax and time <= tmax and not isStationary):
-            dUn = Un.deepCopy()
-            Uk  = Un.deepCopy()
-            residu = 1.
-            k=0
-            while (k<newton_max and residu > precision ):
-                #DEBUT BOUCLE NEWTON
-                divMat.zeroEntries()#sets the matrix coefficients to zero
-                for j in range(nbCells):# 
-                    if ( j==0) : 
-                        rho_r = Uk[j*nbComp+0]
-                        q_r   = Uk[j*nbComp+1]
-                        rho_l = rho_r # Conditions de Neumann
-                        q_l   =   q_r
-                        Am= jacobianMatricesm(dt/dx,rho_l,q_l,rho_r,q_r)
-                        divMat.addValue(j*nbComp,(j+1)*nbComp,Am)
-                        divMat.addValue(j*nbComp,    j*nbComp,Am*(-1.))
-                        dUi=cdmath.Vector(2)
-                        dUi[0] = Uk[(j+1)*nbComp+0]-Uk[j*nbComp+0]
-                        dUi[1] = Uk[(j+1)*nbComp+1]-Uk[j*nbComp+1]
-                        temp=cdmath.Vector(2)
-                        temp = Am*dUi
-                        #print("Bloc 0 matrix  :   ", Am)
-                        Rhs[j*nbComp+0] = -temp[0]-(Uk[j*nbComp+0]-Un[j*nbComp+0]) 
-                        Rhs[j*nbComp+1] = -temp[1]-(Uk[j*nbComp+1]-Un[j*nbComp+1]) 
-                    elif ( j==nbCells-1) :
-                        rho_l = Uk[j*nbComp+0]
-                        q_l   = Uk[j*nbComp+1]
-                        rho_r = rho_l # Conditions de Neumann
-                        q_r   =   q_l
-                        Ap= jacobianMatricesp(dt/dx,rho_l,q_l,rho_r,q_r)
-                        divMat.addValue(j*nbComp,    j*nbComp,Ap)
-                        divMat.addValue(j*nbComp,(j-1)*nbComp,Ap*(-1.))
-                        dUi=cdmath.Vector(2)
-                        dUi[0] = Uk[(j-1)*nbComp+0]-Uk[j*nbComp+0]
-                        dUi[1] = Uk[(j-1)*nbComp+1]-Uk[j*nbComp+1]
-                        temp=cdmath.Vector(2)
-                        temp = Ap*dUi
-                        Rhs[j*nbComp+0] = temp[0]-(Uk[j*nbComp+0]-Un[j*nbComp+0]) 
-                        Rhs[j*nbComp+1] = temp[1]-(Uk[j*nbComp+1]-Un[j*nbComp+1]) 
-                    else :
-                        rho_l = Uk[(j-1)*nbComp+0]
-                        q_l   = Uk[(j-1)*nbComp+1]
-                        rho_r = Uk[j*nbComp+0]
-                        q_r   = Uk[j*nbComp+1]
-                        Ap = jacobianMatricesp(dt/dx,rho_l,q_l,rho_r,q_r)
-                        ###############################################################
-                        rho_l = Uk[j*nbComp+0]
-                        q_l   = Uk[j*nbComp+1]
-                        rho_r = Uk[(j+1)*nbComp+0]
-                        q_r   = Uk[(j+1)*nbComp+1]
-                        Am = jacobianMatricesm(dt/dx,rho_l,q_l,rho_r,q_r)
-                        divMat.addValue(j*nbComp,(j+1)*nbComp,Am)
-                        divMat.addValue(j*nbComp,    j*nbComp,Am*(-1.))
-                        divMat.addValue(j*nbComp,    j*nbComp,Ap)
-                        divMat.addValue(j*nbComp,(j-1)*nbComp,Ap*(-1.))
-                        dUi1=cdmath.Vector(2)
-                        dUi2=cdmath.Vector(2)
-                        dUi1[0] = Uk[(j+1)*nbComp+0]-Uk[j*nbComp+0]
-                        dUi1[1] = Uk[(j+1)*nbComp+1]-Uk[j*nbComp+1]
-                        dUi2[0] = Uk[(j-1)*nbComp+0]-Uk[j*nbComp+0]
-                        dUi2[1] = Uk[(j-1)*nbComp+1]-Uk[j*nbComp+1] 
-                        temp1 = cdmath.Vector(2)
-                        temp2 = cdmath.Vector(2)
-                        temp1 = Am*dUi1
-                        temp2 = Ap*dUi2
-                        Rhs[j*nbComp+0] = -temp1[0] + temp2[0] -(Uk[j*nbComp+0]-Un[j*nbComp+0]) 
-                        Rhs[j*nbComp+1] = -temp1[1] + temp2[1] -(Uk[j*nbComp+1]-Un[j*nbComp+1]) 
-                divMat.diagonalShift(1)#only after  filling all coefficients
-                LS=cdmath.LinearSolver(divMat,Rhs,iterGMRESMax, precision, "GMRES","LU")
-                dUk=LS.solve(); 
-                residu = dUk.norm()
-                #stop
-                Uk+=dUk
-                if(not LS.getStatus()):
-                    print("Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
-                    raise ValueError("Pas de convergence du système linéaire");
-                k=k+1
-            Un = Uk.deepCopy()
-            dUn-=Un
-            for k in range(nbCells):
-                rho_field[k] = Un[k*(dim+1)+0]
-                q_field[k]   = Un[k*(dim+1)+1] 
-            v_field   = [   q_field[i]/rho_field[i]  for i in range(nx)]
-            p_field   = [ rho_field[i]*(c0*c0)       for i in range(nx)]
-
-            lineDensity.set_ydata(rho_field)
-            lineMomentum.set_ydata(q_field)
-            lineVelocity.set_ydata(v_field)
-            linePressure.set_ydata(p_field)
-            writer.grab_frame()
-
-            time=time+dt;
-            it=it+1;
-            #Sauvegardes
-            if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-                #print("Last linear system converged in ", LS.getNumberOfIter(), " GMRES iterations", ", residu final:   ",residu)
-
-                plt.savefig("EulerSystem"+str(dim)+"D_ConservativeStaggered"+meshName+"_"+str(it)+".png")
-                print
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-    if(it>=ntmax):
-        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-        return
-    elif(isStationary):
-        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print("------------------------------------------------------------------------------------")
-        plt.savefig("EulerSystem"+str(dim)+"Staggered"+meshName+"_Stat.png")
-        return
-    else:
-        print("Temps maximum Tmax= ", tmax, " atteint")
-        return
-
-def solve( a,b,nx, meshName, meshType, cfl):
-    print("Resolution of the Euler system in dimension 1 on "+str(nx)+ " cells")
-    print("Initial data : ", "Riemann problem")
-    print("Boundary conditions : ", "Neumann")
-    print("Mesh name : ",meshName , ", ", nx, " cells")
-    # Problem data
-    tmax = 10.
-    ntmax = 50
-    output_freq = 10
-    EulerSystemStaggered(ntmax, tmax, cfl, a,b,nx, output_freq, meshName)
-    return
-
-if __name__ == """__main__""":
-    a=0.
-    b=1.
-    nx=100
-    cfl=0.99
-    solve( a,b,nx,"SquareRegularSquares","RegularSquares",cfl)
diff --git a/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwind/CMakeLists.txt b/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwind/CMakeLists.txt
deleted file mode 100755 (executable)
index 8b41b92..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleEulerSystem_1DShock_UpwindExplicit ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystem1DUpwind.py )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwind/EulerSystem1DUpwind.py b/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwind/EulerSystem1DUpwind.py
deleted file mode 100644 (file)
index ee66cd1..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-# Isothermal Euler system
-# d rho/d t + d q/d x =0
-# d q/d t + d (q^2/rho+p)/d x = 0, where q = rho*u and p = c^2*rho
-# UU = (rho,q) : conservative variable
-# Scheme : Roe scheme (without any entropy correction)
-# Comment : the solution displays a non entropic (non physical) shock instead of a rarefaction wave
-# Date : November 2020
-
-from cdmath import *
-import numpy as np
-from math import sqrt
-
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-
-c0=330.#reference sound speed for water at 15 bars
-precision=1e-5
-
-def flux(rho,q):
-    fl = Vector(2);
-    fl[0] = q;
-    fl[1] = q*q/rho + c0*c0*rho;    
-    return fl
-
-def compTimeStep(UU,dx,CFL):
-    M = UU.getMesh();
-    maxAbsEigVa = 0;
-    for i in range(M.getNumberOfCells()):
-        maxAbsEigVa = max(maxAbsEigVa,abs(UU[i,1]/UU[i,0]+c0),abs(UU[i,1]/UU[i,0]-c0));
-        pass
-    dt = CFL*dx/maxAbsEigVa;
-    return dt
-
-def AbsRoeMatrix(rho_l,q_l,rho_r,q_r):
-    AbsRoeMa = Matrix(2,2);
-    u_l = q_l/rho_l;
-    u_r = q_r/rho_r;
-    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
-    AbsRoeMa[0,0]=(abs(u-c0)*(u+c0)+abs(u+c0)*(c0-u))/(2*c0);
-    AbsRoeMa[0,1]= (abs(u+c0)-abs(u-c0))/(2*c0);
-    AbsRoeMa[1,0]=(abs(u-c0)*(u*u-c0*c0)+abs(u+c0)*(c0*c0-u*u))/(2*c0);
-    AbsRoeMa[1,1]=((u+c0)*abs(u+c0)-(u-c0)*abs(u-c0))/(2*c0);
-    return AbsRoeMa;
-    
-def main(meshName):
-    # mesh definition    
-    xmin=.0;
-    xmax= 1;
-    nx=100#1000;
-    ntmax=50;
-    dx = (xmax-xmin)/nx;
-    M=Mesh(xmin,xmax,nx);
-    dim=1
-    
-    # initial time
-    time=0.;
-    # maximum time T
-    tmax=0.01;
-    it=0;
-    freqSortie=10;
-    # CFL condition
-    CFL=0.99;
-    # conservative variable (unknown)
-    UU=Field("Conservative variables",CELLS,M,2);
-
-    # initial condition for Riemann problem
-    print("Construction of the initial condition …")
-    rhoL=1
-    vL=-300
-    rhoR=1.45
-    vR=-300
-    for i in range(M.getNumberOfCells()):
-        x=M.getCell(i).x();
-        if x < (xmax-xmin)/2:
-            UU[i,0] = rhoL;
-            UU[i,1] = rhoL*vL;
-        else:
-            UU[i,0] = rhoR;
-            UU[i,1] = rhoR*vR;
-        pass
-
-    rho_field = [ UU[i,0]          for i in range(nx)]
-    q_field   = [ UU[i,1]          for i in range(nx)]
-    v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
-    p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
-
-    max_initial_rho=max(rhoL,rhoR)
-    min_initial_rho=min(rhoL,rhoR)
-    max_initial_p=max_initial_rho*c0*c0
-    min_initial_p=min_initial_rho*c0*c0
-    max_initial_v=max(vL,vR)
-    min_initial_v=min(vL,vR)
-    max_initial_q=max(vL*rhoL,vR*rhoR)
-    min_initial_q=min(vL*rhoL,vR*rhoR)
-
-    print( "Numerical solution of the 1D Euler equation")
-
-    # prepare some memory
-    UU_limL = Vector(2);
-    UU_limR = Vector(2);
-    Del_UU_RL = Vector(2);
-    UU_new = UU;
-    
-    # Picture settings
-    fig, ([axDensity, axMomentum],[axVelocity, axPressure]) = plt.subplots(2, 2,sharex=True, figsize=(10,10))
-    fig.suptitle('Explicit Upwind scheme')
-    lineDensity, = axDensity.plot([xmin+0.5*dx + i*dx for i in range(nx)], rho_field, label='Density') #new picture for video # Returns a tuple of line objects, thus the comma
-    axDensity.set(xlabel='x (m)', ylabel='Density')
-    axDensity.set_xlim(xmin,xmax)
-    axDensity.set_ylim(min_initial_rho - 0.1*(max_initial_rho-min_initial_rho), max_initial_rho +  0.1*(max_initial_rho-min_initial_rho) )
-    axDensity.legend()
-    lineMomentum, = axMomentum.plot([xmin+0.5*dx + i*dx for i in range(nx)], q_field, label='Momentum')
-    axMomentum.set(xlabel='x (m)', ylabel='Momentum')
-    axMomentum.set_xlim(xmin,xmax)
-    axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q +  0.1*(max_initial_q-min_initial_q) )
-    axMomentum.legend()
-    lineVelocity, = axVelocity.plot([xmin+0.5*dx + i*dx for i in range(nx)], v_field, label='Velocity')
-    axVelocity.set(xlabel='x (m)', ylabel='Velocity')
-    axVelocity.set_xlim(xmin,xmax)
-    axVelocity.set_ylim(min_initial_v - 0.25*abs(min_initial_v), max_initial_v +  0.05*abs(max_initial_v) )
-    axVelocity.legend()
-    linePressure, = axPressure.plot([xmin+0.5*dx + i*dx for i in range(nx)], p_field, label='Pressure')
-    axPressure.set(xlabel='x (m)', ylabel='Pressure')
-    axPressure.set_xlim(xmin,xmax)
-    axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p +  0.05*abs(max_initial_p) )
-    axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
-    axPressure.legend()
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Upwind (Roe) scheme for the 1D isothermal Euler System", artist = "CEA Saclay", comment="Shock tube")
-    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
-    with writer.saving(fig, "1DEuler_System_Upwind"+".mp4", ntmax):
-        writer.grab_frame()
-        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_0"+".png")
-
-        # loop in time
-        while (it<ntmax and time <= tmax ):
-            # time step
-            dt=compTimeStep(UU,dx,CFL);
-            # Neumann boundary condition
-            UU_limL[0] = UU[0,0];
-            UU_limL[1] = UU[0,1];
-            UU_limR[0] = UU[M.getNumberOfCells()-1,0];
-            UU_limR[1] = UU[M.getNumberOfCells()-1,1];
-            flux_iminus = flux(UU_limL[0],UU_limL[1]);
-            #Main loop on cells
-            for i in range(0,M.getNumberOfCells()):
-                if (i<M.getNumberOfCells()-1):
-                    Del_UU_RL[0]=UU[i+1,0]-UU[i,0];
-                    Del_UU_RL[1]=UU[i+1,1]-UU[i,1];
-                    AbsRoeMa = AbsRoeMatrix(UU[i,0],UU[i,1],UU[i+1,0],UU[i+1,1]);
-                    flux_iplus = (flux(UU[i,0],UU[i,1])+flux(UU[i+1,0],UU[i+1,1]))-AbsRoeMa*Del_UU_RL;
-                    flux_iplus[0]*=0.5;
-                    flux_iplus[1]*=0.5;
-                else:
-                    flux_iplus= flux(UU_limR[0],UU_limR[1]);
-                UU_new[i,0] = UU[i,0] - dt/dx*(flux_iplus[0]-flux_iminus[0]);
-                UU_new[i,1] = UU[i,1] - dt/dx*(flux_iplus[1]-flux_iminus[1]);
-                flux_iminus = flux_iplus;
-                pass
-            UU = UU_new;
-            time+=dt;
-            it+=1;
-
-            rho_field = [ UU[i,0]  for i in range(nx)]
-            q_field   = [ UU[i,1]  for i in range(nx)]
-            v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
-            p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
-
-            lineDensity.set_ydata(rho_field)
-            lineMomentum.set_ydata(q_field)
-            lineVelocity.set_ydata(v_field)
-            linePressure.set_ydata(p_field)
-            writer.grab_frame()
-
-            if (it%freqSortie==0):
-                print( "-- Iter : ", it," Time : ",time," dt : ",dt)
-                plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_"+str(it)+".png")
-            pass
-
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-    if(it>=ntmax):
-        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-        return
-    elif(isStationary):
-        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print("------------------------------------------------------------------------------------")
-        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_Stat.png")
-        return
-    else:
-        print("Temps maximum Tmax= ", tmax, " atteint")
-
-    return
-
-if __name__ == '__main__':
-    main("SquareRegularSquares")
diff --git a/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwindEntrCorr/CMakeLists.txt b/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwindEntrCorr/CMakeLists.txt
deleted file mode 100755 (executable)
index 655c40f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleEulerSystem_1DShock_UpwindExplicit_EntrCorr ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystem1DUpwindEntrCorr.py )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwindEntrCorr/EulerSystem1DUpwindEntrCorr.py b/CDMATH/tests/examples/EulerSystem1D/EulerSystem1DUpwindEntrCorr/EulerSystem1DUpwindEntrCorr.py
deleted file mode 100644 (file)
index e1ae7f0..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-# Isothermal Euler system
-# d rho/d t + d q/d x =0
-# d q/d t + d (q^2/rho+p)/d x = 0, where q = rho*u and p = c^2*rho
-# UU = (rho,q) : conservative variable
-# Scheme : Roe scheme with entropy correction 
-# Comment : If one removes the entropic correction the result displays a non entropic (non physical) shock instead of a rarefaction wave
-# Date : November 2020
-
-from cdmath import *
-import numpy as np
-from math import sqrt
-
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-
-c0=330.#reference sound speed for water at 15 bars
-precision=1e-5
-
-def flux(rho,q):
-    fl = Vector(2);
-    fl[0] = q;
-    fl[1] = q*q/rho + c0*c0*rho;    
-    return fl
-
-def compTimeStep(UU,dx,CFL):
-    M = UU.getMesh();
-    maxAbsEigVa = 0;
-    for i in range(M.getNumberOfCells()):
-        maxAbsEigVa = max(maxAbsEigVa,abs(UU[i,1]/UU[i,0]+c0),abs(UU[i,1]/UU[i,0]-c0));
-        pass
-    dt = CFL*dx/maxAbsEigVa;
-    return dt
-
-def AbsRoeMatrix(rho_l,q_l,rho_r,q_r):
-    AbsRoeMa = Matrix(2,2);
-    u_l = q_l/rho_l;
-    u_r = q_r/rho_r;
-    u = (u_l*sqrt(rho_l)+u_r*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
-    AbsRoeMa[0,0]=(abs(u-c0)*(u+c0)+abs(u+c0)*(c0-u))/(2*c0);
-    AbsRoeMa[0,1]= (abs(u+c0)-abs(u-c0))/(2*c0);
-    AbsRoeMa[1,0]=(abs(u-c0)*(u*u-c0*c0)+abs(u+c0)*(c0*c0-u*u))/(2*c0);
-    AbsRoeMa[1,1]=((u+c0)*abs(u+c0)-(u-c0)*abs(u-c0))/(2*c0);
-    return AbsRoeMa;
-    
-def main(meshName):
-    # mesh definition    
-    xmin=.0;
-    xmax= 1;
-    nx=200#1000;
-    ntmax=100;
-    dx = (xmax-xmin)/nx;
-    M=Mesh(xmin,xmax,nx);
-    dim=1
-    
-    # initial time
-    time=0.;
-    # maximum time T
-    tmax=0.01;
-    it=0;
-    freqSortie=10;
-    # CFL condition
-    CFL=0.9;
-    # conservative variable (unknown)
-    UU=Field("Conservative variables",CELLS,M,2);
-
-    # initial condition for Riemann problem
-    print("Construction of the initial condition …")
-    rhoL=1
-    vL=-300
-    rhoR=2
-    vR=-300
-    for i in range(M.getNumberOfCells()):
-        x=M.getCell(i).x();
-        if x < (xmax-xmin)/2:
-            UU[i,0] = rhoL;
-            UU[i,1] = rhoL*vL;
-        else:
-            UU[i,0] = rhoR;
-            UU[i,1] = rhoR*vR;
-        pass
-
-    rho_field = [ UU[i,0]          for i in range(nx)]
-    q_field   = [ UU[i,1]          for i in range(nx)]
-    v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
-    p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
-
-    max_initial_rho=max(rhoL,rhoR)
-    min_initial_rho=min(rhoL,rhoR)
-    max_initial_p=max_initial_rho*c0*c0
-    min_initial_p=min_initial_rho*c0*c0
-    max_initial_v=max(vL,vR)
-    min_initial_v=min(vL,vR)
-    max_initial_q=max(vL*rhoL,vR*rhoR)
-    min_initial_q=min(vL*rhoL,vR*rhoR)
-
-    print( "Numerical solution of the 1D Euler equation")
-
-    # prepare some memory
-    UU_limL = Vector(2);
-    UU_limR = Vector(2);
-    Del_UU_RL = Vector(2);
-    UU_new = UU;
-    
-    # Picture settings
-    fig, ([axDensity, axMomentum],[axVelocity, axPressure]) = plt.subplots(2, 2,sharex=True, figsize=(10,10))
-    fig.suptitle('Explicit Upwind scheme')
-    lineDensity, = axDensity.plot([xmin+0.5*dx + i*dx for i in range(nx)], rho_field, label='Density') #new picture for video # Returns a tuple of line objects, thus the comma
-    axDensity.set(xlabel='x (m)', ylabel='Density')
-    axDensity.set_xlim(xmin,xmax)
-    axDensity.set_ylim(min_initial_rho - 0.1*(max_initial_rho-min_initial_rho), max_initial_rho +  0.1*(max_initial_rho-min_initial_rho) )
-    axDensity.legend()
-    lineMomentum, = axMomentum.plot([xmin+0.5*dx + i*dx for i in range(nx)], q_field, label='Momentum')
-    axMomentum.set(xlabel='x (m)', ylabel='Momentum')
-    axMomentum.set_xlim(xmin,xmax)
-    axMomentum.set_ylim(min_initial_q - 0.1*(max_initial_q-min_initial_q), max_initial_q +  0.1*(max_initial_q-min_initial_q) )
-    axMomentum.legend()
-    lineVelocity, = axVelocity.plot([xmin+0.5*dx + i*dx for i in range(nx)], v_field, label='Velocity')
-    axVelocity.set(xlabel='x (m)', ylabel='Velocity')
-    axVelocity.set_xlim(xmin,xmax)
-    axVelocity.set_ylim(min_initial_v - 0.4*abs(min_initial_v), max_initial_v +  0.05*abs(max_initial_v) )
-    axVelocity.legend()
-    linePressure, = axPressure.plot([xmin+0.5*dx + i*dx for i in range(nx)], p_field, label='Pressure')
-    axPressure.set(xlabel='x (m)', ylabel='Pressure')
-    axPressure.set_xlim(xmin,xmax)
-    axPressure.set_ylim(min_initial_p - 0.05*abs(min_initial_p), max_initial_p +  0.05*abs(max_initial_p) )
-    axPressure.ticklabel_format(axis='y', style='sci', scilimits=(0,0))
-    axPressure.legend()
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Upwind (Roe) scheme with entropic correction for the 1D isothermal Euler System", artist = "CEA Saclay", comment="Shock tube")
-    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
-    with writer.saving(fig, "1DEuler_System_Upwind"+".mp4", ntmax):
-        writer.grab_frame()
-        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_0"+".png")
-
-        # loop in time
-        while (it<ntmax and time <= tmax ):
-            # time step
-            dt=compTimeStep(UU,dx,CFL);
-            # Neumann boundary condition
-            UU_limL[0] = UU[0,0];
-            UU_limL[1] = UU[0,1];
-            UU_limR[0] = UU[M.getNumberOfCells()-1,0];
-            UU_limR[1] = UU[M.getNumberOfCells()-1,1];
-            flux_iminus = flux(UU_limL[0],UU_limL[1]);
-            #Main loop on cells
-            for i in range(0,M.getNumberOfCells()):
-                if (i<M.getNumberOfCells()-1):
-                    Del_UU_RL[0]=UU[i+1,0]-UU[i,0];
-                    Del_UU_RL[1]=UU[i+1,1]-UU[i,1];
-                    AbsRoeMa = AbsRoeMatrix(UU[i,0],UU[i,1],UU[i+1,0],UU[i+1,1]);
-                    flux_iplus = (flux(UU[i,0],UU[i,1])+flux(UU[i+1,0],UU[i+1,1]))-AbsRoeMa*Del_UU_RL - Del_UU_RL*abs(UU[i+1,1]/UU[i+1,0]-UU[i,1]/UU[i,0])#The last term is the entropic correction
-                    flux_iplus[0]*=0.5;
-                    flux_iplus[1]*=0.5;
-                else:
-                    flux_iplus= flux(UU_limR[0],UU_limR[1]);
-                UU_new[i,0] = UU[i,0] - dt/dx*(flux_iplus[0]-flux_iminus[0]);
-                UU_new[i,1] = UU[i,1] - dt/dx*(flux_iplus[1]-flux_iminus[1]);
-                flux_iminus = flux_iplus;
-                pass
-            UU = UU_new;
-            time+=dt;
-            it+=1;
-
-            rho_field = [ UU[i,0]  for i in range(nx)]
-            q_field   = [ UU[i,1]  for i in range(nx)]
-            v_field   = [ UU[i,1]/UU[i,0]  for i in range(nx)]
-            p_field   = [ UU[i,0]*(c0*c0)  for i in range(nx)]
-
-            lineDensity.set_ydata(rho_field)
-            lineMomentum.set_ydata(q_field)
-            lineVelocity.set_ydata(v_field)
-            linePressure.set_ydata(p_field)
-            writer.grab_frame()
-
-            if (it%freqSortie==0):
-                print( "-- Iter : ", it," Time : ",time," dt : ",dt)
-                plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_"+str(it)+".png")
-            pass
-
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-    if(it>=ntmax):
-        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-        return
-    elif(isStationary):
-        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print("------------------------------------------------------------------------------------")
-        plt.savefig("EulerSystem"+str(dim)+"UpwindExplicit"+meshName+"_Stat.png")
-        return
-    else:
-        print("Temps maximum Tmax= ", tmax, " atteint")
-
-    return
-
-if __name__ == '__main__':
-    main("SquareRegularSquares")
diff --git a/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemStaggered/CMakeLists.txt b/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemStaggered/CMakeLists.txt
deleted file mode 100755 (executable)
index 211c08d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleEulerSystem_2DShock_ConservativeStaggered ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerIsothermal_2DConservativeStaggered.py )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemStaggered/EulerIsothermal_2DConservativeStaggered.py b/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemStaggered/EulerIsothermal_2DConservativeStaggered.py
deleted file mode 100644 (file)
index 5480b7e..0000000
+++ /dev/null
@@ -1,798 +0,0 @@
-#!/usr/bin/env python3\r
-# -*-coding:utf-8 -*\r
-\r
-#===============================================================================================================================\r
-# Name        : Résolution VF des équations d'Euler isotherme 2D sans terme source\r
-#                \partial_t rho + \div q = 0\r
-#                \partial_t q   + \div q \otimes q/rho   \grad p = 0\r
-# Author      : Michaël Ndjinga, Coraline Mounier\r
-# Copyright   : CEA Saclay 2020\r
-# Description : Propagation d'une onde de choc droite\r
-#               Utilisation du schéma upwind explicite ou implicite sur un maillage général\r
-#               Initialisation par une discontinuité verticale\r
-#               Conditions aux limites de Neumann\r
-#                Création et sauvegarde du champ résultant et des figures\r
-#================================================================================================================================\r
-\r
-\r
-import cdmath\r
-import numpy as np\r
-import matplotlib\r
-matplotlib.use("Agg")\r
-import matplotlib.pyplot as plt\r
-import matplotlib.animation as manimation\r
-from math import sqrt\r
-import sys\r
-import PV_routines\r
-\r
-p0=155.e5 #reference pressure in a pressurised nuclear vessel\r
-c0=700.   #reference sound speed for water at 155 bars\r
-rho0=p0/(c0*c0)   #reference density\r
-precision=1e-5\r
-\r
-def initial_conditions_Riemann_problem(my_mesh):\r
-    print( "Initial data : Riemann problem" )\r
-    dim     = my_mesh.getMeshDimension()\r
-    nbCells = my_mesh.getNumberOfCells()\r
-\r
-    xcentre = 0.5\r
-\r
-    density_field = cdmath.Field("Density",    cdmath.CELLS, my_mesh, 1)\r
-    q_x_field     = cdmath.Field("Momentum x", cdmath.CELLS, my_mesh, 1)\r
-    q_y_field     = cdmath.Field("Momentum y", cdmath.CELLS, my_mesh, 1)\r
-    #Velocity field with 3 components should be created for streamlines to be drawn\r
-    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)\r
-\r
-    for i in range(nbCells):\r
-        x = my_mesh.getCell(i).x()\r
-\r
-        # Initial momentum is zero\r
-        q_x_field[i] = 0\r
-        q_y_field[i] = 0\r
-\r
-        # Initial velocity is zero\r
-        velocity_field[i,0] = 0\r
-        velocity_field[i,1] = 0\r
-        velocity_field[i,2] = 0\r
-\r
-        if x < xcentre:\r
-            density_field[i] = rho0\r
-            pass\r
-        else:\r
-            density_field[i] = rho0/2\r
-            pass\r
-        pass\r
-\r
-    return density_field, q_x_field, q_y_field, velocity_field\r
-\r
-\r
-def jacobianMatricesm_x(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
-    RoeMatx = cdmath.Matrix(3,3);\r
-    Dmacx = cdmath.Matrix(3,3);\r
-\r
-    u_lx=q_lx/rho_l\r
-    u_rx=q_rx/rho_r\r
-    u_ly=q_ly/rho_l\r
-    u_ry=q_ry/rho_r\r
-    if rho_l<0 or rho_r<0:\r
-        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
-        raise ValueError("Negative density")\r
-    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-\r
-    RoeMatx[0,0] = 0\r
-    RoeMatx[0,1] = 1\r
-    RoeMatx[0,2] = 0\r
-    RoeMatx[1,0] = c0*c0 - ux*ux\r
-    RoeMatx[1,1] = 2*ux\r
-    RoeMatx[1,2] = 0\r
-    RoeMatx[2,0] = -ux*uy\r
-    RoeMatx[2,1] = uy\r
-    RoeMatx[2,2] = ux\r
-\r
-    Dmacx[0,0] = abs(ux)-ux\r
-    Dmacx[0,1] = 1\r
-    Dmacx[0,2] = 0\r
-    Dmacx[1,0] = -c0*c0-ux*ux\r
-    Dmacx[1,1] = abs(ux)+ux\r
-    Dmacx[1,2] = 0\r
-    Dmacx[2,0] = -ux*uy\r
-    Dmacx[2,1] = uy\r
-    Dmacx[2,2] = abs(ux)\r
-\r
-    return (RoeMatx-Dmacx)*coeff*0.5\r
-\r
-def jacobianMatricesp_x(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
-    RoeMatx   = cdmath.Matrix(3,3)\r
-    Dmacx = cdmath.Matrix(3,3)\r
-\r
-    u_lx=q_lx/rho_l\r
-    u_rx=q_rx/rho_r\r
-    u_ly=q_ly/rho_l\r
-    u_ry=q_ry/rho_r\r
-    if rho_l<0 or rho_r<0:\r
-        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
-        raise ValueError("Negative density")\r
-    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-\r
-    RoeMatx[0,0] = 0\r
-    RoeMatx[0,1] = 1\r
-    RoeMatx[0,2] = 0\r
-    RoeMatx[1,0] = c0*c0 - ux*ux\r
-    RoeMatx[1,1] = 2*ux\r
-    RoeMatx[1,2] = 0\r
-    RoeMatx[2,0] = -ux*uy\r
-    RoeMatx[2,1] = uy\r
-    RoeMatx[2,2] = ux\r
-\r
-    Dmacx[0,0] = abs(ux)-ux\r
-    Dmacx[0,1] = 1\r
-    Dmacx[0,2] = 0\r
-    Dmacx[1,0] = -c0*c0-ux*ux\r
-    Dmacx[1,1] = abs(ux)+ux\r
-    Dmacx[1,2] = 0\r
-    Dmacx[2,0] = -ux*uy\r
-    Dmacx[2,1] = uy\r
-    Dmacx[2,2] = abs(ux)\r
-\r
-    return (RoeMatx+Dmacx)*coeff*0.5\r
-\r
-def jacobianMatricesm_y(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
-    RoeMaty   = cdmath.Matrix(3,3);\r
-    Dmacy = cdmath.Matrix(3,3);\r
-\r
-    u_lx=q_lx/rho_l\r
-    u_rx=q_rx/rho_r\r
-    u_ly=q_ly/rho_l\r
-    u_ry=q_ry/rho_r\r
-    if rho_l<0 or rho_r<0:\r
-        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
-        raise ValueError("Negative density")\r
-    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-\r
-    RoeMaty[0,0] = 0\r
-    RoeMaty[0,1] = 0\r
-    RoeMaty[0,2] = 1\r
-    RoeMaty[1,0] = -ux*uy\r
-    RoeMaty[1,1] = uy\r
-    RoeMaty[1,2] = ux\r
-    RoeMaty[2,0] = c0*c0-uy*uy\r
-    RoeMaty[2,1] = 0\r
-    RoeMaty[2,2] = 2*uy\r
-\r
-    Dmacy[0,0] = abs(uy)-uy\r
-    Dmacy[0,1] = 0\r
-    Dmacy[0,2] = 1\r
-    Dmacy[1,0] = -ux*uy\r
-    Dmacy[1,1] = abs(uy)\r
-    Dmacy[1,2] = ux\r
-    Dmacy[2,0] = -c0*c0-uy*uy\r
-    Dmacy[2,1] = 0\r
-    Dmacy[2,2] = abs(uy)+uy\r
-\r
-    return (RoeMaty-Dmacy)*coeff*0.5\r
-\r
-def jacobianMatricesp_y(coeff,rho_l,q_lx,q_ly,rho_r,q_rx,q_ry):\r
-    RoeMaty   = cdmath.Matrix(3,3);\r
-    Dmacy = cdmath.Matrix(3,3);\r
-\r
-    u_lx=q_lx/rho_l\r
-    u_rx=q_rx/rho_r\r
-    u_ly=q_ly/rho_l\r
-    u_ry=q_ry/rho_r\r
-    if rho_l<0 or rho_r<0:\r
-        print("rho_l=",rho_l, " rho_r= ",rho_r)\r
-        raise ValueError("Negative density")\r
-    ux = (u_lx*sqrt(rho_l)+u_rx*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-    uy = (u_ly*sqrt(rho_l)+u_ry*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));\r
-\r
-    RoeMaty[0,0] = 0\r
-    RoeMaty[0,1] = 0\r
-    RoeMaty[0,2] = 1\r
-    RoeMaty[1,0] = -ux*uy\r
-    RoeMaty[1,1] = uy\r
-    RoeMaty[1,2] = ux\r
-    RoeMaty[2,0] = c0*c0-uy*uy\r
-    RoeMaty[2,1] = 0\r
-    RoeMaty[2,2] = 2*uy\r
-\r
-    Dmacy[0,0] = abs(uy)-uy\r
-    Dmacy[0,1] = 0\r
-    Dmacy[0,2] = 1\r
-    Dmacy[1,0] = -ux*uy\r
-    Dmacy[1,1] = abs(uy)\r
-    Dmacy[1,2] = ux\r
-    Dmacy[2,0] = -c0*c0-uy*uy\r
-    Dmacy[2,1] = 0\r
-    Dmacy[2,2] = abs(uy)+uy\r
-\r
-    return (RoeMaty+Dmacy)*coeff*0.5\r
-\r
-def EulerSystemStaggered(ntmax, tmax, cfl,output_freq, my_mesh, meshName):\r
-\r
-    if not my_mesh.isStructured() :\r
-        raise ValueError("Euler_ConservativeStaggered2D_RiemannProblem.py expects a structured mesh")\r
-\r
-    dim=my_mesh.getMeshDimension()\r
-    if dim != 2 :\r
-        raise ValueError("Euler_ConservativeStaggered2D_RiemannProblem.py expects a 2D mesh")\r
-\r
-    nbComp=dim+1\r
-    # Mesh parameters\r
-    nbCells = my_mesh.getNumberOfCells()\r
-    nbCells_x = my_mesh.getNx()\r
-    nbCells_y = my_mesh.getNy()\r
-    dx,dy = my_mesh.getDXYZ()\r
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)\r
-    dx_min=my_mesh.minRatioVolSurf()\r
-    \r
-    # Time evolution parameters\r
-    time = 0.\r
-    it=0;\r
-    isStationary=False\r
-    iterGMRESMax = 50\r
-    newton_max   = 50\r
-\r
-    #iteration vectors\r
-    Un =cdmath.Vector(nbCells*nbComp)\r
-    dUn=cdmath.Vector(nbCells*nbComp)\r
-    dUk=cdmath.Vector(nbCells*nbComp)\r
-    Rhs=cdmath.Vector(nbCells*nbComp)\r
-\r
-    dUi_x=cdmath.Vector(nbComp)\r
-    dUi_y=cdmath.Vector(nbComp)\r
-    dUi1_x=cdmath.Vector(nbComp)\r
-    dUi2_x=cdmath.Vector(nbComp)\r
-    dUi1_y=cdmath.Vector(nbComp)\r
-    dUi2_y=cdmath.Vector(nbComp)\r
-\r
-    # Initial conditions #\r
-    print("Construction of the initial condition …")\r
-    rho_field, q_x_field, q_y_field, velocity_field= initial_conditions_Riemann_problem(my_mesh)\r
-\r
-    for i in range(nbCells):\r
-        Un[nbComp*i]   = rho_field[i]\r
-        Un[nbComp*i+1] = q_x_field[i]\r
-        Un[nbComp*i+2] = q_y_field[i]\r
-\r
-    #Sauvegarde de la donnée initiale\r
-    rho_field.setTime(time,it);\r
-    rho_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density");\r
-    q_x_field.setTime(time,it);\r
-    q_x_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX");\r
-    q_y_field.setTime(time,it);\r
-    q_y_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY");\r
-    velocity_field.setTime(time,it);\r
-    velocity_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_velocity");\r
-\r
-    print("Starting computation of the isothermal Euler system with a conservative staggered scheme …")\r
-    divMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)\r
-\r
-    # Starting time loop\r
-    while (it<ntmax and time <= tmax and not isStationary):\r
-        dUn = Un.deepCopy()\r
-        Uk  = Un.deepCopy()\r
-        residu = 1e10\r
-        k=0\r
-        while (k<newton_max and residu > 1/precision ):\r
-\r
-            dt = cfl * dx_min / c0# This choice should be improved when possible by using the actual eigenvalue abs(u)+c0, that is the time step should be determined avec the computation of the jacobian matrices\r
-            #DEBUT BOUCLE NEWTON\r
-            for j in range(nbCells_y):\r
-                for i in range(nbCells_x):\r
-                    #Traitement des coins\r
-                    if ( j==0 and i==0) :\r
-                        #Calcul de Am_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
-                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
-                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Am_y\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
-                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
-                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Am_x*(-1.)-Am_y)\r
-\r
-                        dUi_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
-                        dUi_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
-\r
-                        temp_x = Am_x*dUi_x\r
-                        temp_y = Am_y*dUi_y\r
-                        #print("Bloc 0 matrix  :   ", Am)\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0] - temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1] - temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2] - temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    elif(i==0 and j==nbCells_y-1):\r
-                        #Calcul de Am_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
-                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
-                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Ap_y\r
-                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
-                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Am_x*(-1.)+Ap_y)\r
-\r
-                        dUi_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
-                        dUi_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
-                        dUi_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        dUi_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
-\r
-                        temp_x = Am_x*dUi_x\r
-                        temp_y = Ap_y*dUi_y\r
-                        #print("Bloc 0 matrix  :   ", Am)\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]- temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]- temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]- temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    elif(i==nbCells_x-1 and j==0):\r
-\r
-                        #Calcul de Ap_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
-                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Am_y\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
-                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
-                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x-Am_y)\r
-\r
-                        dUi_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
-                        dUi_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        dUi_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        dUi_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
-\r
-                        temp_x = Ap_x*dUi_x\r
-                        temp_y= Am_y*dUi_y\r
-                        #print("Bloc 0 matrix  :   ", Am)\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]- temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]- temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]- temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    elif ( j==nbCells_y-1 and i==nbCells_x-1) :\r
-\r
-                        #Calcul de Ap_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
-                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Ap_y\r
-                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
-                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x+Ap_y)\r
-\r
-                        dUi_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
-                        dUi_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        dUi_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        dUi_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
-                        dUi_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        dUi_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
-\r
-                        temp_x = Ap_x*dUi_x\r
-                        temp_y = Ap_y*dUi_y\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]-temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]-temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]-temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    #Traitement des bords restants\r
-                    elif i==0 :\r
-\r
-                        #Calcul de Am_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
-                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
-                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Am_y\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
-                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
-                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Ap_y\r
-                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
-                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #remplissage de la divMat\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_y-Am_x-Am_y)\r
-\r
-                        #remplissage du membre de droite\r
-                        dUi_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
-                        dUi1_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi1_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi1_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
-                        dUi2_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
-                        dUi2_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        dUi2_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
-\r
-                        temp_x  = Am_x*dUi_x\r
-                        temp1_y = Am_y*dUi1_y\r
-                        temp2_y = Ap_y*dUi2_y\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]-temp1_y[0]-temp2_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]-temp1_y[1]-temp2_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]-temp1_y[2]-temp2_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    elif i==nbCells_x-1:\r
-\r
-                        #Calcul de Ap_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
-                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Am_y\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
-                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
-                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Ap_y\r
-                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
-                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #remplissage de la divMat\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_y+Ap_x-Am_y)\r
-\r
-                        #remplissage du membre de droite\r
-                        dUi_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
-                        dUi_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        dUi_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        dUi1_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi1_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi1_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
-                        dUi2_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
-                        dUi2_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        dUi2_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
-\r
-                        temp_x  = Ap_x*dUi_x\r
-                        temp1_y = Am_y*dUi1_y\r
-                        temp2_y = Ap_y*dUi2_y\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp_x[0]-temp1_y[0]-temp2_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp_x[1]-temp1_y[1]-temp2_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp_x[2]-temp1_y[2]-temp2_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    elif j==0:\r
-\r
-                        #Calcul de Am_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
-                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
-                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #Calcul de Ap_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
-                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Am_y\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
-                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
-                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #remplissage de la divMat\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x-Am_x-Am_y)\r
-\r
-                        #remplissage du membre de droite\r
-                        dUi1_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi1_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi1_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
-                        dUi2_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
-                        dUi2_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        dUi2_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        dUi_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
-\r
-                        temp1_x = Am_x*dUi1_x\r
-                        temp2_x = Ap_x*dUi2_x\r
-                        temp_y = Am_y*dUi_y\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp1_x[0]-temp2_x[0]-temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp1_x[1]-temp2_x[1]-temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp1_x[2]-temp2_x[2]-temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    elif j==nbCells_y-1:\r
-\r
-                        #Calcul de Am_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
-                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
-                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #Calcul de Ap_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
-                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Ap_y\r
-                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
-                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #remplissage de la divMat\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x+Ap_y-Am_x)\r
-\r
-                        #remplissage du membre de droite\r
-                        dUi1_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi1_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi1_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
-                        dUi2_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
-                        dUi2_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        dUi2_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        dUi_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
-                        dUi_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        dUi_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
-\r
-                        temp1_x = Am_x*dUi1_x\r
-                        temp2_x = Ap_x*dUi2_x\r
-                        temp_y = Ap_y*dUi_y\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp1_x[0]-temp2_x[0]-temp_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp1_x[1]-temp2_x[1]-temp_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp1_x[2]-temp2_x[2]-temp_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-                    #Traitement des autres cellules\r
-                    else:\r
-\r
-                        #Calcul de Am_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*(i+1)]\r
-                        qx_r =Uk[3*nbCells_x*j+3*(i+1)+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*(i+1)+2]\r
-                        Am_x= jacobianMatricesm_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #Calcul de Ap_x\r
-                        rho_l=Uk[3*nbCells_x*j+3*(i-1)]\r
-                        qx_l =Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*(i-1)+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_x= jacobianMatricesp_x(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Am_y\r
-                        rho_l=Uk[3*nbCells_x*j+3*i]\r
-                        qx_l =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*j+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*(j+1)+3*i]\r
-                        qx_r =Uk[3*nbCells_x*(j+1)+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*(j+1)+3*i+2]\r
-                        Am_y= jacobianMatricesm_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #calcul de Ap_y\r
-                        rho_l=Uk[3*nbCells_x*(j-1)+3*i]\r
-                        qx_l =Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        qy_l =Uk[3*nbCells_x*(j-1)+3*i+2]\r
-                        rho_r=Uk[3*nbCells_x*j+3*i]\r
-                        qx_r =Uk[3*nbCells_x*j+3*i+1]\r
-                        qy_r =Uk[3*nbCells_x*j+3*i+2]\r
-                        Ap_y= jacobianMatricesp_y(dt/dx,rho_l,qx_l,qy_l,rho_r,qx_r,qy_r)\r
-\r
-                        #remplissage de la divMat\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i-1),Ap_x*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j-1)+3*i,Ap_y*(-1.))\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*(i+1),Am_x)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*(j+1)+3*i,Am_y)\r
-                        divMat.addValue(3*nbCells_x*j+3*i,3*nbCells_x*j+3*i,Ap_x+Ap_y-Am_x-Am_y)\r
-\r
-                        #remplissage du membre de droite\r
-\r
-                        dUi1_x[0] = Uk[3*nbCells_x*j+3*(i+1)]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi1_x[1] = Uk[3*nbCells_x*j+3*(i+1)+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi1_x[2] = Uk[3*nbCells_x*j+3*(i+1)+2]-Uk[3*nbCells_x*j+3*i+2]\r
-\r
-                        dUi2_x[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*j+3*(i-1)]\r
-                        dUi2_x[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*j+3*(i-1)+1]\r
-                        dUi2_x[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*j+3*(i-1)+2]\r
-\r
-                        dUi1_y[0] = Uk[3*nbCells_x*(j+1)+3*i]-Uk[3*nbCells_x*j+3*i]\r
-                        dUi1_y[1] = Uk[3*nbCells_x*(j+1)+3*i+1]-Uk[3*nbCells_x*j+3*i+1]\r
-                        dUi1_y[2] = Uk[3*nbCells_x*(j+1)+3*i+2]-Uk[3*nbCells_x*j+3*i+2]\r
-\r
-                        dUi2_y[0] = Uk[3*nbCells_x*j+3*i]-Uk[3*nbCells_x*(j-1)+3*i]\r
-                        dUi2_y[1] = Uk[3*nbCells_x*j+3*i+1]-Uk[3*nbCells_x*(j-1)+3*i+1]\r
-                        dUi2_y[2] = Uk[3*nbCells_x*j+3*i+2]-Uk[3*nbCells_x*(j-1)+3*i+2]\r
-\r
-                        temp1_x = Am_x*dUi1_x\r
-                        temp2_x = Ap_x*dUi2_x\r
-                        temp1_y = Am_y*dUi1_y\r
-                        temp2_y = Ap_y*dUi2_y\r
-                        Rhs[3*nbCells_x*j+3*i+0] = -temp1_x[0]-temp2_x[0]-temp1_y[0]-temp2_y[0]-(Uk[3*nbCells_x*j+3*i+0]-Un[3*nbCells_x*j+3*i+0])\r
-                        Rhs[3*nbCells_x*j+3*i+1] = -temp1_x[1]-temp2_x[1]-temp1_y[1]-temp2_y[1]-(Uk[3*nbCells_x*j+3*i+1]-Un[3*nbCells_x*j+3*i+1])\r
-                        Rhs[3*nbCells_x*j+3*i+2] = -temp1_x[2]-temp2_x[2]-temp1_y[2]-temp2_y[2]-(Uk[3*nbCells_x*j+3*i+2]-Un[3*nbCells_x*j+3*i+2])\r
-\r
-            divMat.diagonalShift(1)  #only after  filling all coefficients\r
-            LS=cdmath.LinearSolver(divMat,Rhs,iterGMRESMax, precision, "GMRES","LU")\r
-            dUk=LS.solve();\r
-            residu = dUk.norm()\r
-            Uk+=dUk\r
-            #print("Newton iteration number ",k, "residu = ",residu)\r
-            if(not LS.getStatus()):\r
-                print("Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")\r
-                raise ValueError("Pas de convergence du système linéaire");\r
-            k=k+1\r
-        Un = Uk.deepCopy()\r
-        dUn-=Un\r
-        isStationary = dUn.norm()<precision\r
-        \r
-        for i in range(nbCells):\r
-            rho_field[i] = Un[nbComp*i]\r
-            q_x_field[i] = Un[nbComp*i+1]\r
-            q_y_field[i] = Un[nbComp*i+2]\r
-\r
-        time=time+dt;\r
-        it=it+1;\r
-        #Sauvegardes\r
-        if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):\r
-            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) + ", Newton iterations: "+str(k)+", ||dUn|| = "+str(dUn.norm()))\r
-            print("Linear system converged in ", LS.getNumberOfIter(), " GMRES iterations, résidu = ", residu)\r
-            for k in range(nbCells):\r
-                rho  =rho_field[k]\r
-                velocity_field[k,0]=q_x_field[i]/rho\r
-                if(dim>1):\r
-                    velocity_field[k,1]=q_y_field[k]/rho\r
-            print\r
-            rho_field.setTime(time,it);\r
-            rho_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density",False);\r
-            q_x_field.setTime(time,it);\r
-            q_x_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX",False);\r
-            q_y_field.setTime(time,it);\r
-            q_y_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY",False);\r
-            velocity_field.setTime(time,it);\r
-            velocity_field.writeVTK("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_velocity",False);\r
-            #Postprocessing : save 2D picture\r
-            PV_routines.Save_PV_data_to_picture_file("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density_"  +str(it)+'.vtu',"Density",   'CELLS',"EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_density"  +str(it))\r
-            PV_routines.Save_PV_data_to_picture_file("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX_"+str(it)+'.vtu',"Momentum x",'CELLS',"EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumX"+str(it))\r
-            PV_routines.Save_PV_data_to_picture_file("EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY_"+str(it)+'.vtu',"Momentum y",'CELLS',"EulerIsothermal_"+str(dim)+"DConservativeStaggered_"+meshName+"_momentumY"+str(it))\r
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))\r
-    if(it>=ntmax):\r
-        print("Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")\r
-        return\r
-    elif(isStationary):\r
-        print("Régime stationnaire atteint au pas de temps ", it, ", t= ", time)\r
-        print("------------------------------------------------------------------------------------")\r
-        return\r
-    else:\r
-        print("Temps maximum Tmax= ", tmax, " atteint")\r
-        return\r
-\r
-def solve( my_mesh,filename, resolution):\r
-    print("Resolution of the Isothermal Euler system in dimension 2 on "+str(my_mesh.getNumberOfCells())+ " cells")\r
-    print("Initial data : ", "Riemann problem")\r
-    print("Boundary conditions : ", "Neumann")\r
-    print("Mesh name : ",filename )\r
-    # Problem data\r
-    tmax = 10.\r
-    ntmax = 10\r
-    cfl=1\r
-    output_freq = 1\r
-    EulerSystemStaggered(ntmax, tmax, cfl, output_freq, my_mesh, filename)\r
-    return\r
-\r
-if __name__ == """__main__""":\r
-    if len(sys.argv) >1 :\r
-        filename=sys.argv[1]\r
-        my_mesh = cdmath.Mesh(filename)\r
-    else :\r
-        filename = "CartesianGrid"\r
-        ax=0;bx=1;nx=20;\r
-        ay=0;by=1;ny=10;        \r
-        my_mesh = cdmath.Mesh(ax,bx,nx,ay,by,ny)\r
-\r
-    solve(my_mesh,filename,100)\r
diff --git a/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemUpwind/CMakeLists.txt b/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemUpwind/CMakeLists.txt
deleted file mode 100755 (executable)
index 857c261..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-
-SET(MESH_MED
-  ../../../ressources/squareWithTriangles.med
-  ../../../ressources/meshCube.med
-  ../../../ressources/squareWithSquares.med
-  ../../../ressources/cubeWithCubes.med
-  ../../../ressources/diskWithTriangles.med
-  ../../../ressources/diskWithSquares.med
-  ../../../ressources/diskWithSpiderWeb.med
-  ../../../ressources/diskWithHexagons.med
-  ../../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/EulerSystemUpwind)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(IMPLICIT_SCHEME  0 )
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindExplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindExplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshHexagonWithTriangles.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindExplicit_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(IMPLICIT_SCHEME  1 )
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindImplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    #ADD_TEST(ExampleEulerSystem_3DShock_UpwindImplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleEulerSystem_2DShock_UpwindImplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/EulerSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemUpwind/EulerSystemUpwind.py b/CDMATH/tests/examples/EulerSystem_Shock/EulerSystemUpwind/EulerSystemUpwind.py
deleted file mode 100755 (executable)
index b969762..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système Euler 2D barotrope sans terme source
-#                \partial_t rho + \div q = 0
-#                \partial_t q   + \div q\otimes q/rho  +  \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Propagation d'une onde de choc sphérique
-#               Utilisation du schéma de Roe upwind explicite ou implicite sur un maillage général
-#               Initialisation par une surpression sphérique
-#               Conditions aux limites parois
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sqrt
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_shock(my_mesh, isCircle):
-    print( "Initial data : Spherical wave" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    rayon = 0.15
-    if(not isCircle):
-        xcentre = 0.5
-        ycentre = 0.5
-        zcentre = 0.5
-    else:
-        xcentre = 0.
-        ycentre = 0.
-        zcentre = 0.
-
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        velocity_field[i,0] = 0
-        velocity_field[i,1] = 0
-        velocity_field[i,2] = 0
-
-        x = my_mesh.getCell(i).x()
-        valX = (x - xcentre) * (x - xcentre)
-
-        if(dim==1):
-            val =  sqrt(valX)
-        if(dim==2):
-            y = my_mesh.getCell(i).y()
-            valY = (y - ycentre) * (y - ycentre)
-            val =  sqrt(valX + valY)
-        if(dim==3):
-            y = my_mesh.getCell(i).y()
-            z = my_mesh.getCell(i).z()
-            valY = (y - ycentre) * (y - ycentre)
-            valZ = (z - zcentre) * (z - zcentre)
-            val =  sqrt(valX + valY + valZ)
-
-        if val < rayon:
-            pressure_field[i] = p0
-            pass
-        else:
-            pressure_field[i] = p0/2
-            pass
-        pass
-
-    return pressure_field, velocity_field
-
-    
-def jacobianMatrices(normale,coeff,rho_l,q_l,rho_r,q_r):
-    RoeMat   = cdmath.Matrix(3,3);
-    AbsRoeMa = cdmath.Matrix(3,3);
-
-    tangent=cdmath.Vector(2);
-    tangent[0]= normale[1];
-    tangent[1]=-normale[0];
-
-    u_l = cdmath.Vector(2); u_l[0]*=q_l[0]/rho_l; u_l[1]*=q_l[1]/rho_l;
-    u_r = cdmath.Vector(2); u_r[0]*=q_r[0]/rho_r; u_r[1]*=q_r[1]/rho_r;
-    if rho_l<0 or rho_r<0 :
-        print( "rho_l=",rho_l, " rho_r= ",rho_r )
-        raise ValueError("Negative density")
-    u=cdmath.Vector(2);
-    u[0] = (u_l[0]*sqrt(rho_l)+u_r[0]*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
-    u[1] = (u_l[1]*sqrt(rho_l)+u_r[1]*sqrt(rho_r))/(sqrt(rho_l)+sqrt(rho_r));   
-    un=u*normale;
-
-    RoeMat[0,0]   = 0
-    RoeMat[0,1]   =     normale[0]
-    RoeMat[0,2]   =     normale[1]
-    RoeMat[1,0]   = c0*c0*normale[0] - un*u[0]
-    RoeMat[2,0]   = c0*c0*normale[1] - un*u[1]
-    RoeMat[1,1]   = un + normale[0]*u[0]
-    RoeMat[1,2]   =      normale[1]*u[0]
-    RoeMat[2,2]   = un + normale[1]*u[1]
-    RoeMat[2,1]   =      normale[0]*u[1]
-
-    AbsRoeMa[0,0]=(abs(un-c0)*(un+c0)+abs(un+c0)*(c0-un))/(2*c0);
-    AbsRoeMa[0,1]= (abs(un+c0)-abs(un-c0))/(2*c0)*normale[0];
-    AbsRoeMa[0,2]= (abs(un+c0)-abs(un-c0))/(2*c0)*normale[1];
-    AbsRoeMa[1,0]=(abs(un-c0)*(un+c0)*(u[0]-c0*normale[0])-abs(un+c0)*(un-c0)*(u[0]+c0*normale[0]))/(2*c0)-abs(un)*(u*tangent)*tangent[0];
-    AbsRoeMa[2,0]=(abs(un-c0)*(un+c0)*(u[1]-c0*normale[1])-abs(un+c0)*(un-c0)*(u[1]+c0*normale[1]))/(2*c0)-abs(un)*(u*tangent)*tangent[1];
-    #subMatrix=(abs(un+c0)*((u-c0*normale)^normale)-abs(un-c0)*((u-c0*normale)^normale))/(2*c0)+abs(un)*(tangent^tangent);
-    AbsRoeMa[1,1]=(abs(un+c0)*((u[0]-c0*normale[0])*normale[0])-abs(un-c0)*((u[0]-c0*normale[0])*normale[0]))/(2*c0)+abs(un)*(tangent[0]*tangent[0]);#subMatrix[0,0];
-    AbsRoeMa[1,2]=(abs(un+c0)*((u[0]-c0*normale[0])*normale[1])-abs(un-c0)*((u[0]-c0*normale[0])*normale[1]))/(2*c0)+abs(un)*(tangent[0]*tangent[1]);#subMatrix[0,1];
-    AbsRoeMa[2,1]=(abs(un+c0)*((u[1]-c0*normale[1])*normale[0])-abs(un-c0)*((u[1]-c0*normale[1])*normale[0]))/(2*c0)+abs(un)*(tangent[1]*tangent[0]);
-    AbsRoeMa[2,2]=(abs(un+c0)*((u[1]-c0*normale[1])*normale[1])-abs(un-c0)*((u[1]-c0*normale[1])*normale[1]))/(2*c0)+abs(un)*(tangent[1]*tangent[1]);
-
-    return (RoeMat-AbsRoeMa)*coeff*0.5,un;
-
-def computeDivergenceMatrix(my_mesh,implMat,Un):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-    maxAbsEigVa = 0
-    q_l=cdmath.Vector(2);
-    q_r=cdmath.Vector(2);
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-    
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
-                    
-                q_l[0]=Un[j*nbComp+1]
-                q_l[1]=Un[j*nbComp+2]
-                q_r[0]=Un[cellAutre*nbComp+1]
-                q_r[1]=Un[cellAutre*nbComp+2]
-                Am, un=jacobianMatrices( normal,Fk.getMeasure()/Cj.getMeasure(),Un[j*nbComp],q_l,Un[cellAutre*nbComp],q_r);
-            
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
-                    q_l[0]=Un[j*nbComp+1]
-                    q_l[1]=Un[j*nbComp+2]
-                    q_r=q_l-normal*2*(q_l*normal)
-                    Am, un=jacobianMatrices( normal,Fk.getMeasure()/Cj.getMeasure(),Un[j*nbComp],q_l,Un[j*nbComp],q_r);
-            
-                    v=cdmath.Vector(dim+1)
-                    for i in range(dim) :
-                        v[i+1]=normal[i]
-                    idMoinsJacCL=v.tensProduct(v)*2
-                    
-                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
-                    
-                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
-                    q_l[0]=Un[j*nbComp+1]
-                    q_l[1]=Un[j*nbComp+2]
-                    q_r[0]=Un[cellAutre*nbComp+1]
-                    q_r[1]=Un[cellAutre*nbComp+2]
-                    Am, un=jacobianMatrices( normal,Fk.getMeasure()/Cj.getMeasure(),Un[j*nbComp],Un[j*nbComp+1],Un[j*nbComp+2],Un[cellAutre*nbComp],Un[cellAutre*nbComp+1],Un[cellAutre*nbComp+2]);
-            
-                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-            
-            maxAbsEigVa = max(maxAbsEigVa,abs(un+c0),abs(un-c0));
-    
-    return maxAbsEigVa
-
-def EulerSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
-    elif(filename.find("disk")>-1 or filename.find("Disk")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
-    else:
-        print( "Mesh name : ", filename )
-        raise ValueError("Mesh name should contain substring square, cube or disk")
-
-    #iteration vectors
-    Un =cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =     pressure_field[k]/(c0*c0)
-        Un[k*(dim+1)+1] =rho0*velocity_field[k,0]
-        if(dim>=2):
-            Un[k*(dim+1)+2] = rho0*velocity_field[k,1] # value on the bottom face
-            if(dim==3):
-                Un[k*(dim+1)+3] = rho0*initial_velocity[k,2]
-
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity");
-
-    dx_min=my_mesh.minRatioVolSurf()
-
-    divMat=cdmath.SparseMatrixPetsc(nbCells*(1+dim),nbCells*(1+dim),(nbVoisinsMax+1)*(1+dim))
-    if( isImplicit):
-        iterGMRESMax=50
-        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
-
-    print("Starting computation of the linear wave system with an explicit UPWIND scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        divMat.zeroEntries()#sets the matrix coefficients to zero
-        vp_max=computeDivergenceMatrix(my_mesh,divMat,Un)#To update at each time step
-        dt = cfl * dx_min / vp_max#To update at each time step
-            
-        if(isImplicit):
-            #Adding the identity matrix on the diagonal
-            divMat.diagonalShift(1)#only after  filling all coefficients
-            dUn=Un.deepCopy()
-            LS.setSndMember(Un)
-            Un=LS.solve();
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
-                raise ValueError("Pas de convergence du système linéaire");
-            dUn-=Un
-
-        else:
-            dUn=divMat*Un
-            Un-=dUn
-        
-        time=time+dt;
-        it=it+1;
-         #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-
-            for k in range(nbCells):
-                pressure_field[k]  =Un[k*(dim+1)+0]*c0*c0
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity",False);
-
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat");
-
-        #Postprocessing : Extraction of the diagonal data
-        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
-        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"EulerSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("EulerSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"EulerSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-
-
-def solve(my_mesh,filename,resolution, isImplicit):
-    print( "Resolution of the Euler system in dimension ", my_mesh.getSpaceDimension())
-    if( my_mesh.getSpaceDimension()!=2):
-        raise ValueError("Only dimension 2 simulations allowed")
-    print( "Numerical method : upwind")
-    print( "Initial data : spherical wave")
-    print( "Wall boundary conditions")
-    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells")
-
-    # Problem data
-    tmax = 1.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 1
-
-    EulerSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
-
-def solve_file( filename,resolution, isImplicit):
-    my_mesh = cdmath.Mesh(filename+".med")
-    solve(my_mesh, filename,resolution, isImplicit)
-    
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        filename=sys.argv[1]
-        isImplicit=bool(int(sys.argv[2]))
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100, isImplicit)
-    else :
-        raise ValueError("EulerSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/HeatEquation/CMakeLists.txt b/CDMATH/tests/examples/HeatEquation/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..d023248
--- /dev/null
@@ -0,0 +1,14 @@
+file(GLOB HeatEquation_EXAMPLES_TO_INSTALL 
+  HeatEquation1DExplicit HeatEquation1DImplicit# 1D Heat equation
+)
+
+install(DIRECTORY ${HeatEquation_EXAMPLES_TO_INSTALL} DESTINATION share/examples/HeatEquation)
+
+IF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_SUBDIRECTORY(HeatEquation1DExplicit)
+    ADD_SUBDIRECTORY(HeatEquation1DImplicit)
+
+ENDIF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/HeatEquation/HeatEquation1DExplicit/CMakeLists.txt b/CDMATH/tests/examples/HeatEquation/HeatEquation1DExplicit/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..117a131
--- /dev/null
@@ -0,0 +1,16 @@
+
+if (CDMATH_WITH_PYTHON )
+
+    SET(NX 100 )#Number of cells
+
+    SET(CFL  0.99  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleHeatEquation_1DFV_Explicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DExplicit.py ${NX} ${CFL})
+
+    SET(CFL  2  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleHeatEquation_1DFV_Explicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DExplicit.py ${NX} ${CFL})
+
+endif (CDMATH_WITH_PYTHON )
+
+
diff --git a/CDMATH/tests/examples/HeatEquation/HeatEquation1DExplicit/HeatEquation1DExplicit.py b/CDMATH/tests/examples/HeatEquation/HeatEquation1DExplicit/HeatEquation1DExplicit.py
new file mode 100755 (executable)
index 0000000..658941e
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation de la chaleur 1D \partial_t u = d \partial_xx u avec conditions aux limites périodiques
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Maillage 1D régulier
+#                      Création et sauvegarde du champ résultant et des figures
+#               Génération d'une video sauvegardée dans un fichier .mp4
+#================================================================================================================================
+
+
+from math import sin, pi, ceil
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+from copy import deepcopy
+
+def HeatEquation1DExplicit(nx,cfl):
+    print( "Simulation of 1D heat equation with an explicit scheme")
+
+    ##################### Simulation parameters
+    a = 0.0 # space domain :  a <= x <= b
+    b = 1.0
+    dx = (b - a) / nx #space step
+
+    d = 1. # thermal diffusivity
+    tmax = (b-a)/d # runs the simulation for 0 <= t <= tMax
+    dt = cfl * dx *dx/ (2*d)
+    ntmax = 100
+
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+    
+    ########################## Initial data
+    
+    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+
+    max_initial=max(u_initial)
+    min_initial=min(u_initial)
+    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
+
+    time = 0.
+    it = 0
+    output_freq = 10
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Explicit scheme for heat equation", artist = "CEA Saclay", comment="CFL="+str(cfl)+", Stable if CFL<1")
+    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
+        ########################### Postprocessing initialisation
+        # Picture frame
+        plt.legend()
+        plt.xlabel('x')
+        plt.ylabel('u')
+        plt.xlim(a,b)
+        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
+        plt.title("Explicit scheme for the heat equation, CFL="+str(cfl))
+        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
+    
+        print("Starting time loop")
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+        np.savetxt( "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
+        writer.grab_frame()
+        plt.savefig("HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
+
+        ############################# Time loop
+        while (it < ntmax and time <= tmax):
+            un=deepcopy(u)
+            for i in range(nx):
+                u[i] = un[i] + d * dt / (dx*dx) * (un[(i+1)%nx] -2*un[i] + un[(i-1)%nx])/2
+    
+            time += dt
+            it += 1
+
+            if cfl<1 :
+                assert max(u) <= max_initial
+                assert min(u) >= min_initial
+                assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial
+
+            # Postprocessing
+            line1.set_ydata(u)
+            writer.grab_frame()
+            if (it % output_freq == 0):
+                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+                np.savetxt( "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
+                plt.savefig("HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
+                #plt.show()
+
+    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
+    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
+    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
+    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])        )
+    
+    print("Simulation of heat equation with explicit scheme done.")
+    
+    #return min, max, total variation and l1 error
+    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
+
+
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        nx = int(sys.argv[1])
+        cfl = float(sys.argv[2])
+        HeatEquation1DExplicit(nx,cfl)
+    else :
+        nx = 50 # number of cells
+        cfl = 1 # c*dt/(2*dx) <= CFL
+        HeatEquation1DExplicit(nx,cfl)
+    
diff --git a/CDMATH/tests/examples/HeatEquation/HeatEquation1DImplicit/CMakeLists.txt b/CDMATH/tests/examples/HeatEquation/HeatEquation1DImplicit/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..623bb85
--- /dev/null
@@ -0,0 +1,16 @@
+
+if (CDMATH_WITH_PYTHON )
+
+    SET(NX 100 )#Number of cells
+
+    SET(CFL  1  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleHeatEquation_1DFV_Implicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DImplicit.py ${NX} ${CFL})
+
+    SET(CFL  2  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleHeatEquation_1DFV_Implicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DImplicit.py ${NX} ${CFL})
+
+endif (CDMATH_WITH_PYTHON )
+
+
diff --git a/CDMATH/tests/examples/HeatEquation/HeatEquation1DImplicit/HeatEquation1DImplicit.py b/CDMATH/tests/examples/HeatEquation/HeatEquation1DImplicit/HeatEquation1DImplicit.py
new file mode 100755 (executable)
index 0000000..0090e51
--- /dev/null
@@ -0,0 +1,140 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF implicite de l'équation de la chaleur 1D \partial_t u = d \partial_xx u avec conditions aux limites périodiques
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Maillage 1D régulier
+#                      Création et sauvegarde du champ résultant et des figures
+#               Génération d'une video sauvegardée dans un fichier .mp4
+#================================================================================================================================
+
+
+from math import sin, pi, ceil
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+import cdmath
+
+def implicitSchemeMatrix(nx,cfl):
+    implMat=cdmath.SparseMatrixPetsc(nx,nx,3)
+    for i in range(nx):
+        implMat.setValue(i,(i+1)%nx,-cfl)
+        implMat.setValue(i,i,1.+2*cfl)
+        implMat.setValue(i,(i-1)%nx,-cfl)
+
+    return implMat
+
+def HeatEquation1DImplicit(nx,cfl):
+    print( "Simulation of 1D heat equation with an implicit scheme")
+
+    ##################### Simulation parameters
+    a = 0.0 # space domain :  a <= x <= b
+    b = 1.0
+    dx = (b - a) / nx #space step
+
+    d = 1. # thermal diffusivity
+    tmax = (b-a)/d # runs the simulation for 0 <= t <= tMax
+    dt = cfl * dx *dx/ (2*d)
+    ntmax = 100
+
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+    
+    ########################## Initial data
+    
+    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+
+    max_initial=max(u_initial)
+    min_initial=min(u_initial)
+    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
+
+    time = 0.
+    it = 0
+    output_freq = 10
+
+    #Initialisation of the linear system 
+    systemMat=implicitSchemeMatrix(nx,cfl)
+    iterGMRESMax=50
+    precision=1.e-5
+    Un =cdmath.Vector(nx)
+    for i in range(nx):
+        Un[i]=u[i]
+    LS=cdmath.LinearSolver(systemMat,Un,iterGMRESMax, precision, "GMRES","ILU")
+    LS.setComputeConditionNumber()
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Implicit scheme for heat equation, "+"CFL="+str(cfl), artist = "CEA Saclay", comment="Stable for any CFL number")
+    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
+        ########################### Postprocessing initialisation
+        # Picture frame
+        plt.legend()
+        plt.xlabel('x')
+        plt.ylabel('u')
+        plt.xlim(a,b)
+        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
+        plt.title("Implicit scheme for heat equation, "+"CFL="+str(cfl))
+        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
+    
+        print("Starting time loop")
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+        np.savetxt( "HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
+        writer.grab_frame()
+        plt.savefig("HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
+
+        ############################# Time loop
+        while (it < ntmax and time <= tmax):
+            # Solve linear system
+            for i in range(nx):
+                Un[i]=u[i]
+            LS.setSndMember(Un)
+            Un=LS.solve()
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
+                raise ValueError("Pas de convergence du système linéaire");
+            for i in range(nx):
+                u[i]=Un[i]
+
+            assert max(u) <= max_initial
+            assert min(u) >= min_initial
+            assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial
+
+            time += dt
+            it += 1
+
+            # Postprocessing
+            line1.set_ydata(u)
+            writer.grab_frame()
+            if (it % output_freq == 0):
+                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+                np.savetxt( "HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
+                plt.savefig("HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
+                #plt.show()
+
+    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
+    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
+    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
+    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) ) 
+    
+    print("Simulation of heat equation with implicit scheme done.")
+    
+    #return min, max, total variation and l1 error
+    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
+
+
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        nx = int(sys.argv[1])
+        cfl = float(sys.argv[2])
+        HeatEquation1DImplicit(nx,cfl)
+    else :
+        nx = 50 # number of cells
+        cfl = 1 # c*dt/(2*dx) <= CFL
+        HeatEquation1DImplicit(nx,cfl)
+    
diff --git a/CDMATH/tests/examples/HeatEquation1DExplicit/CMakeLists.txt b/CDMATH/tests/examples/HeatEquation1DExplicit/CMakeLists.txt
deleted file mode 100755 (executable)
index 117a131..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-
-if (CDMATH_WITH_PYTHON )
-
-    SET(NX 100 )#Number of cells
-
-    SET(CFL  0.99  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleHeatEquation_1DFV_Explicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DExplicit.py ${NX} ${CFL})
-
-    SET(CFL  2  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleHeatEquation_1DFV_Explicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DExplicit.py ${NX} ${CFL})
-
-endif (CDMATH_WITH_PYTHON )
-
-
diff --git a/CDMATH/tests/examples/HeatEquation1DExplicit/HeatEquation1DExplicit.py b/CDMATH/tests/examples/HeatEquation1DExplicit/HeatEquation1DExplicit.py
deleted file mode 100755 (executable)
index 658941e..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation de la chaleur 1D \partial_t u = d \partial_xx u avec conditions aux limites périodiques
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Maillage 1D régulier
-#                      Création et sauvegarde du champ résultant et des figures
-#               Génération d'une video sauvegardée dans un fichier .mp4
-#================================================================================================================================
-
-
-from math import sin, pi, ceil
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-from copy import deepcopy
-
-def HeatEquation1DExplicit(nx,cfl):
-    print( "Simulation of 1D heat equation with an explicit scheme")
-
-    ##################### Simulation parameters
-    a = 0.0 # space domain :  a <= x <= b
-    b = 1.0
-    dx = (b - a) / nx #space step
-
-    d = 1. # thermal diffusivity
-    tmax = (b-a)/d # runs the simulation for 0 <= t <= tMax
-    dt = cfl * dx *dx/ (2*d)
-    ntmax = 100
-
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-    
-    ########################## Initial data
-    
-    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-
-    max_initial=max(u_initial)
-    min_initial=min(u_initial)
-    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
-
-    time = 0.
-    it = 0
-    output_freq = 10
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Explicit scheme for heat equation", artist = "CEA Saclay", comment="CFL="+str(cfl)+", Stable if CFL<1")
-    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
-        ########################### Postprocessing initialisation
-        # Picture frame
-        plt.legend()
-        plt.xlabel('x')
-        plt.ylabel('u')
-        plt.xlim(a,b)
-        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
-        plt.title("Explicit scheme for the heat equation, CFL="+str(cfl))
-        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
-    
-        print("Starting time loop")
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-        np.savetxt( "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
-        writer.grab_frame()
-        plt.savefig("HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
-
-        ############################# Time loop
-        while (it < ntmax and time <= tmax):
-            un=deepcopy(u)
-            for i in range(nx):
-                u[i] = un[i] + d * dt / (dx*dx) * (un[(i+1)%nx] -2*un[i] + un[(i-1)%nx])/2
-    
-            time += dt
-            it += 1
-
-            if cfl<1 :
-                assert max(u) <= max_initial
-                assert min(u) >= min_initial
-                assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial
-
-            # Postprocessing
-            line1.set_ydata(u)
-            writer.grab_frame()
-            if (it % output_freq == 0):
-                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-                np.savetxt( "HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
-                plt.savefig("HeatEquation1D_Explicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
-                #plt.show()
-
-    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
-    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
-    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
-    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])        )
-    
-    print("Simulation of heat equation with explicit scheme done.")
-    
-    #return min, max, total variation and l1 error
-    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
-
-
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        nx = int(sys.argv[1])
-        cfl = float(sys.argv[2])
-        HeatEquation1DExplicit(nx,cfl)
-    else :
-        nx = 50 # number of cells
-        cfl = 1 # c*dt/(2*dx) <= CFL
-        HeatEquation1DExplicit(nx,cfl)
-    
diff --git a/CDMATH/tests/examples/HeatEquation1DImplicit/CMakeLists.txt b/CDMATH/tests/examples/HeatEquation1DImplicit/CMakeLists.txt
deleted file mode 100755 (executable)
index 623bb85..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-
-if (CDMATH_WITH_PYTHON )
-
-    SET(NX 100 )#Number of cells
-
-    SET(CFL  1  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleHeatEquation_1DFV_Implicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DImplicit.py ${NX} ${CFL})
-
-    SET(CFL  2  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleHeatEquation_1DFV_Implicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/HeatEquation1DImplicit.py ${NX} ${CFL})
-
-endif (CDMATH_WITH_PYTHON )
-
-
diff --git a/CDMATH/tests/examples/HeatEquation1DImplicit/HeatEquation1DImplicit.py b/CDMATH/tests/examples/HeatEquation1DImplicit/HeatEquation1DImplicit.py
deleted file mode 100755 (executable)
index 0090e51..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF implicite de l'équation de la chaleur 1D \partial_t u = d \partial_xx u avec conditions aux limites périodiques
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Maillage 1D régulier
-#                      Création et sauvegarde du champ résultant et des figures
-#               Génération d'une video sauvegardée dans un fichier .mp4
-#================================================================================================================================
-
-
-from math import sin, pi, ceil
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-import cdmath
-
-def implicitSchemeMatrix(nx,cfl):
-    implMat=cdmath.SparseMatrixPetsc(nx,nx,3)
-    for i in range(nx):
-        implMat.setValue(i,(i+1)%nx,-cfl)
-        implMat.setValue(i,i,1.+2*cfl)
-        implMat.setValue(i,(i-1)%nx,-cfl)
-
-    return implMat
-
-def HeatEquation1DImplicit(nx,cfl):
-    print( "Simulation of 1D heat equation with an implicit scheme")
-
-    ##################### Simulation parameters
-    a = 0.0 # space domain :  a <= x <= b
-    b = 1.0
-    dx = (b - a) / nx #space step
-
-    d = 1. # thermal diffusivity
-    tmax = (b-a)/d # runs the simulation for 0 <= t <= tMax
-    dt = cfl * dx *dx/ (2*d)
-    ntmax = 100
-
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-    
-    ########################## Initial data
-    
-    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-
-    max_initial=max(u_initial)
-    min_initial=min(u_initial)
-    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
-
-    time = 0.
-    it = 0
-    output_freq = 10
-
-    #Initialisation of the linear system 
-    systemMat=implicitSchemeMatrix(nx,cfl)
-    iterGMRESMax=50
-    precision=1.e-5
-    Un =cdmath.Vector(nx)
-    for i in range(nx):
-        Un[i]=u[i]
-    LS=cdmath.LinearSolver(systemMat,Un,iterGMRESMax, precision, "GMRES","ILU")
-    LS.setComputeConditionNumber()
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Implicit scheme for heat equation, "+"CFL="+str(cfl), artist = "CEA Saclay", comment="Stable for any CFL number")
-    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
-        ########################### Postprocessing initialisation
-        # Picture frame
-        plt.legend()
-        plt.xlabel('x')
-        plt.ylabel('u')
-        plt.xlim(a,b)
-        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
-        plt.title("Implicit scheme for heat equation, "+"CFL="+str(cfl))
-        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
-    
-        print("Starting time loop")
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-        np.savetxt( "HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
-        writer.grab_frame()
-        plt.savefig("HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
-
-        ############################# Time loop
-        while (it < ntmax and time <= tmax):
-            # Solve linear system
-            for i in range(nx):
-                Un[i]=u[i]
-            LS.setSndMember(Un)
-            Un=LS.solve()
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
-                raise ValueError("Pas de convergence du système linéaire");
-            for i in range(nx):
-                u[i]=Un[i]
-
-            assert max(u) <= max_initial
-            assert min(u) >= min_initial
-            assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial
-
-            time += dt
-            it += 1
-
-            # Postprocessing
-            line1.set_ydata(u)
-            writer.grab_frame()
-            if (it % output_freq == 0):
-                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-                np.savetxt( "HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
-                plt.savefig("HeatEquation1D_Implicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
-                #plt.show()
-
-    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
-    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
-    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
-    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) ) 
-    
-    print("Simulation of heat equation with implicit scheme done.")
-    
-    #return min, max, total variation and l1 error
-    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
-
-
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        nx = int(sys.argv[1])
-        cfl = float(sys.argv[2])
-        HeatEquation1DImplicit(nx,cfl)
-    else :
-        nx = 50 # number of cells
-        cfl = 1 # c*dt/(2*dx) <= CFL
-        HeatEquation1DImplicit(nx,cfl)
-    
diff --git a/CDMATH/tests/examples/Poisson1DEF/CMakeLists.txt b/CDMATH/tests/examples/Poisson1DEF/CMakeLists.txt
deleted file mode 100755 (executable)
index 5be4ec4..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson1DEF)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_1DEF ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements1DPoisson.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson1DEF/FiniteElements1DPoisson.py b/CDMATH/tests/examples/Poisson1DEF/FiniteElements1DPoisson.py
deleted file mode 100755 (executable)
index 712b614..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Poisson 1D -\triangle u = f avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage 1D quelconque
-#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=-sin(pi*x)
-#================================================================================================================================
-
-import cdmath
-from math import sin, pi, sqrt
-from numpy import linspace
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-#Création d'un maillage uniforme du segment [0,1], définition des bords
-#======================================================================
-nx=100
-my_mesh = cdmath.Mesh(0,1,nx)
-if( my_mesh.getSpaceDimension()!=1 or my_mesh.getMeshDimension()!=1) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 1")
-
-eps=1e-6
-my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
-my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading/building done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Discrétisation du second membre et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-
-       my_RHSfield[i]=pi*pi*sin(pi*x)#mettre la fonction definie au second membre de l'edp
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               boundaryNodes.append(i)
-               nbBoundaryNodes=nbBoundaryNodes+1
-       else: # Détection des noeuds intérieurs
-               interiorNodes.append(i)
-               nbInteriorNodes=nbInteriorNodes+1
-               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print("nb of interior nodes=", nbInteriorNodes)
-print("nb of boundary nodes=", nbBoundaryNodes)
-print("Max nb of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbInteriorNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un segment (hypothèse 1D)
-GradShapeFunc0=cdmath.Vector(1)
-GradShapeFunc1=cdmath.Vector(1)
-
-#On parcourt les segments du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= 1
-       GradShapeFunc1[0]=-1
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1] :
-               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-                       #Ajout de la contribution de la cellule i au second membre du noeud j 
-                       RHS[j_int]=Ci.getMeasure()/2*my_RHSfield[j]+RHS[j_int] # intégrale sur le segment du produit f x fonction de base
-                       #Contribution de la cellule i à la ligne j_int du système linéaire
-                       for k in [nodeId0,nodeId1] : 
-                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-for j in range(nbBoundaryNodes):
-    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElements1DPoisson_ResultField")
-
-# Postprocessing :
-#=================
-# save 1D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElements1DPoisson_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements1DPoisson_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=linspace(0,1,resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,0,0],[1,0,0], resolution)
-plt.plot(curv_abs, diag_data, label= '1D mesh with '+str(nbNodes) + ' nodes')
-plt.legend()
-plt.xlabel('Position')
-plt.ylabel('Value')
-plt.title('1D finite elements \n for Laplace operator')
-plt.savefig("FiniteElements1DPoisson_ResultField_"+str(nbNodes) + '_nodes'+".png")
-
-print("Numerical solution of the 1D Poisson equation using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal the right hand side divided by pi*pi
-max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(pi*pi)
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbNodes) :
-    if erreur_abs < abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i]) :
-        erreur_abs = abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_RHSfield.max()/(pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(pi*pi))
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson1DVF/CMakeLists.txt b/CDMATH/tests/examples/Poisson1DVF/CMakeLists.txt
deleted file mode 100755 (executable)
index 2bde45f..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_1DVF_uniform ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes1DPoisson.py )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson1DVF/FiniteVolumes1DPoisson.py b/CDMATH/tests/examples/Poisson1DVF/FiniteVolumes1DPoisson.py
deleted file mode 100755 (executable)
index 0f18320..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation de Poisson 1D -\triangle u = f avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage 1D quelconque
-#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=-sin(pi*x)
-#================================================================================================================================
-
-import cdmath
-from math import sin, pi
-from numpy import linspace
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-import sys
-
-if len(sys.argv) >1 :#non uniform mesh
-    my_mesh = cdmath.Mesh(sys.argv[1])
-else :   #rectangular mesh
-#Création d'un maillage uniforme du segment [0,1], définition des bords
-#======================================================================
-       nx=100
-       my_mesh = cdmath.Mesh(0,1,nx)
-
-if( my_mesh.getSpaceDimension()!=1 or my_mesh.getMeshDimension()!=1) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 1")
-
-eps=1e-6
-my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
-my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
-
-nbCells = my_mesh.getNumberOfCells()
-
-print( "Mesh loading/building done")
-print( "Number of cells  = ", nbCells)
-
-#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
-#================================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
-maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
-for i in range(nbCells): 
-       Ci = my_mesh.getCell(i)
-       x = Ci.x()
-
-       my_RHSfield[i]=pi*pi*sin(pi*x)#mettre la fonction definie au second membre de l edp
-       # compute maximum number of neighbours
-       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print( "Max nb of neighbours = ", maxNbNeighbours )
-
-# Construction de la matrice et du vecteur second membre du système linéaire
-#===========================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbCells)
-#Parcours des cellules du domaine
-for i in range(nbCells):
-       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
-       Ci=my_mesh.getCell(i)
-       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
-               Fj=my_mesh.getFace(Ci.getFaceId(j))
-               if not Fj.isBorder():
-                       k=Fj.getCellId(0)
-                       if k==i :
-                               k=Fj.getCellId(1)
-                       Ck=my_mesh.getCell(k)
-                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
-                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
-               else:
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
-                       #For the particular case where the mesh boundary does not coincide with the domain boundary
-                       x=Fj.getBarryCenter().x()
-                       RHS[i]+=coeff*sin(pi*x)#mettre ici  la solution exacte de l'edp
-               Rigidite.addValue(i,i,coeff) # terme diagonal
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print( "Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
-for i in range(nbCells):
-    my_ResultField[i]=SolSyst[i];
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteVolumes1DPoisson_ResultField")
-
-#Postprocessing : 
-#===============
-# save 1D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteVolumes1DPoisson_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes1DPoisson_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=linspace(0,1,resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,0,0],[1,0,0], resolution)
-plt.legend()
-plt.xlabel('Position')
-plt.ylabel('Value')
-if len(sys.argv) >1 :
-    plt.title('Finite Volumes \n for Laplace operator in 1D'+my_mesh.getName())
-    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
-    plt.savefig("FiniteVolumes1DPoisson_ResultField_"+str(nbCells)+ '_cells'+".png")
-else :   
-    plt.title('Finite Volumes \n for Laplace operator on a 1D regular grid')
-    plt.plot(curv_abs, diag_data, label= str(nx) + ' cells mesh')
-    plt.savefig("FiniteVolumes1DPoisson_ResultField_"+str(nx) + '_cells'+".png")
-
-print("Numerical solution of 1D Poisson equation using finite volumes done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal the right hand side divided by pi*pi
-max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(pi*pi)
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbCells) :
-    if erreur_abs <  abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i]) :
-        erreur_abs = abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_RHSfield.max()/(pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(pi*pi))
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson2DEF/CMakeLists.txt b/CDMATH/tests/examples/Poisson2DEF/CMakeLists.txt
deleted file mode 100755 (executable)
index 47bd375..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/squareWithTriangles.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_2DEF_SQUARE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_SQUARE.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson2DEF/FiniteElements2DPoisson_SQUARE.py b/CDMATH/tests/examples/Poisson2DEF/FiniteElements2DPoisson_SQUARE.py
deleted file mode 100755 (executable)
index eb28762..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = f avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2016
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
-#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)
-#================================================================================================================================
-
-import cdmath
-from math import sin, pi, sqrt
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-#Chargement du maillage triangulaire du domaine carré [0,1]x[0,1], définition des bords
-#=======================================================================================
-my_mesh = cdmath.Mesh("squareWithTriangles.med")
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-if(not my_mesh.isTriangular()) :
-       raise ValueError("Wrong cell types : mesh is not made of triangles")
-eps=1e-6
-my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
-my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
-my_mesh.setGroupAtPlan(0.,1,eps,"DirichletBorder")#Bord BAS
-my_mesh.setGroupAtPlan(1.,1,eps,"DirichletBorder")#Bord HAUT
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Discrétisation du second membre et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-       y = Ni.y()
-
-       my_RHSfield[i]=2*pi*pi*sin(pi*x)*sin(pi*y)#mettre la fonction definie au second membre de l'edp
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               boundaryNodes.append(i)
-               nbBoundaryNodes=nbBoundaryNodes+1
-       else: # Détection des noeuds intérieurs
-               interiorNodes.append(i)
-               nbInteriorNodes=nbInteriorNodes+1
-               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
-
-print("Right hand side discretisation done")
-print("nb of interior nodes=", nbInteriorNodes)
-print("nb of boundary nodes=", nbBoundaryNodes)
-print("Max nb of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbInteriorNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
-GradShapeFunc0=cdmath.Vector(2)
-GradShapeFunc1=cdmath.Vector(2)
-GradShapeFunc2=cdmath.Vector(2)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= (N1.y()-N2.y())/2
-       GradShapeFunc0[1]=-(N1.x()-N2.x())/2
-       GradShapeFunc1[0]=-(N0.y()-N2.y())/2
-       GradShapeFunc1[1]= (N0.x()-N2.x())/2
-       GradShapeFunc2[0]= (N0.y()-N1.y())/2
-       GradShapeFunc2[1]=-(N0.x()-N1.x())/2
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2] :
-               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
-                       RHS[j_int]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
-                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
-                       for k in [nodeId0,nodeId1,nodeId2] : 
-                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
-
-print("Linear system matrix building done")
-
-# Conditionnement de la matrice de rigidité
-#=================================
-cond = Rigidite.getConditionNumber()
-print("Condition number is ",cond)
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
-SolSyst=LS.solve()
-
-print("Preconditioner used : ", LS.getNameOfPc())
-print("Number of iterations used : ", LS.getNumberOfIter())
-print("Final residual : ", LS.getResidu())
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-for j in range(nbBoundaryNodes):
-    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElements2DPoisson_SQUARE_ResultField")
-
-# Postprocessing :
-#=================
-# save 2D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoisson_SQUARE_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoisson_SQUARE_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=np.linspace(0,sqrt(2),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
-plt.plot(curv_abs, diag_data, label= '2D mesh with '+str(nbNodes) + ' nodes')
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D square with triangular mesh')
-plt.savefig("FiniteElements2DPoisson_SQUARE_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 2D Poisson equation on a square using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal the right hand side divided by 2*pi*pi
-max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(2*pi*pi)
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbNodes) :
-    if erreur_abs < abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i]) :
-        erreur_abs = abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_RHSfield.max()/(2*pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(2*pi*pi) )
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson2DEF_DISK/CMakeLists.txt b/CDMATH/tests/examples/Poisson2DEF_DISK/CMakeLists.txt
deleted file mode 100755 (executable)
index cfaa27b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/diskWithTriangles.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF_DISK)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_2DEF_DISK ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_DISK.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson2DEF_DISK/FiniteElements2DPoisson_DISK.py b/CDMATH/tests/examples/Poisson2DEF_DISK/FiniteElements2DPoisson_DISK.py
deleted file mode 100755 (executable)
index d133bdf..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = f sur le disque unité avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
-#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)
-#================================================================================================================================
-
-import cdmath
-from math import sin, sqrt, atan2
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-#Chargement du maillage triangulaire du disque unité
-#=======================================================================================
-my_mesh = cdmath.Mesh("diskWithTriangles.med")
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-if(not my_mesh.isTriangular()) :
-       raise ValueError("Wrong cell types : mesh is not made of triangles")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Discrétisation du second membre et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
-my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1)
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-       y = Ni.y()
-
-       r=sqrt(x*x+y*y)
-       theta=atan2(y,x)
-
-       my_RHSfield[i]=(8*r-3)*sin(theta)#mettre la fonction definie au second membre de l'edp
-       my_ExactSol[i]=-(r-1)*r*r*sin(theta)#mettre la solution exacte de l'edp
-    
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               boundaryNodes.append(i)
-               nbBoundaryNodes=nbBoundaryNodes+1
-       else: # Détection des noeuds intérieurs
-               interiorNodes.append(i)
-               nbInteriorNodes=nbInteriorNodes+1
-               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
-
-print("Right hand side discretisation done")
-print("Number of interior nodes=", nbInteriorNodes)
-print("Number of boundary nodes=", nbBoundaryNodes)
-print("Maximum number of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbInteriorNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
-GradShapeFunc0=cdmath.Vector(2)
-GradShapeFunc1=cdmath.Vector(2)
-GradShapeFunc2=cdmath.Vector(2)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= (N1.y()-N2.y())/2
-       GradShapeFunc0[1]=-(N1.x()-N2.x())/2
-       GradShapeFunc1[0]=-(N0.y()-N2.y())/2
-       GradShapeFunc1[1]= (N0.x()-N2.x())/2
-       GradShapeFunc2[0]= (N0.y()-N1.y())/2
-       GradShapeFunc2[1]=-(N0.x()-N1.x())/2
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2] :
-               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
-                       RHS[j_int]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
-                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
-                       for k in [nodeId0,nodeId1,nodeId2] : 
-                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-for j in range(nbBoundaryNodes):
-    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElements2DPoisson_DISK_ResultField")
-
-# Postprocessing :
-#=================
-# save 2D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoisson_DISK_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoisson_DISK_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=np.linspace(-1,1,resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[-0.5,-0.5,0],[0.5,0.5,0], resolution)
-plt.plot(curv_abs, diag_data, label= '2D disk mesh with '+str(nbNodes) + ' nodes')
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D disk triangular mesh')
-plt.savefig("FiniteElements2DPoisson_DISK_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 2D Poisson equation on a disk using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbNodes) :
-    if  erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
-        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min() )
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson2DEF_DISK_StiffBC/CMakeLists.txt b/CDMATH/tests/examples/Poisson2DEF_DISK_StiffBC/CMakeLists.txt
deleted file mode 100755 (executable)
index fb390a0..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/diskWithTriangles.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF_DISK_StiffBC)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_2DEF_DISK_StiffBC ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_DISK_StiffBC.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson2DEF_DISK_StiffBC/FiniteElements2DPoisson_DISK_StiffBC.py b/CDMATH/tests/examples/Poisson2DEF_DISK_StiffBC/FiniteElements2DPoisson_DISK_StiffBC.py
deleted file mode 100755 (executable)
index f160ce6..0000000
+++ /dev/null
@@ -1,224 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = 0 sur le disque unité avec conditions aux limites de Dirichlet discontinues
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
-#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=atan(2*x/(x**2+y**2-1))=atan(2 r cos(theta)/(r*2-1))
-#================================================================================================================================
-
-import cdmath
-from math import atan, pi
-from numpy import sign, linspace
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-# Fonction qui remplace successivement les colonnes d'une matrices par un vecteur donné et retourne la liste des déterminants
-def gradientNodal(M, values):
-    matrices=[0]*(len(values)-1)
-    for i in range(len(values)-1):
-        matrices[i] = M.deepCopy()        
-        for j in range(len(values)):
-            matrices[i][j,i] = values[j]
-
-    result = cdmath.Vector(len(values)-1)    
-    for i in range(len(values)-1):
-        result[i] = matrices[i].determinant()
-
-    return result
-
-
-#Chargement du maillage triangulaire du disque unité
-#=======================================================================================
-meshName="diskWithTriangles"
-my_mesh = cdmath.Mesh(meshName+".med")
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-if(not my_mesh.isTriangular()) :
-    raise ValueError("Wrong cell types : mesh is not made of triangles")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Détermination des noeuds intérieurs
-#======================================================================
-my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1)
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-eps=1e-10
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-    Ni=my_mesh.getNode(i)
-    x = Ni.x()
-    y = Ni.y()
-
-    #Robust calculation of atan(2x/(x**2+y**2-1)
-    #my_ExactSol[i]=atan2(2*x*sign(x**2+y**2-1),abs(x**2+y**2-1))#mettre la solution exacte de l'edp
-    if x**2+y**2-1 > eps :
-        print("!!! Warning Mesh ", meshName," !!! Node is not in the unit disk.",", eps=",eps, ", x**2+y**2-1=",x**2+y**2 - 1)
-        #raise ValueError("x**2+y**2 > 1 !!! Domain should be the unit disk.")
-    if x**2+y**2-1 < -eps :
-        my_ExactSol[i] = atan(2*x/(x**2+y**2-1))
-    elif x>0 : #x**2+y**2-1>=0
-        my_ExactSol[i] = -pi/2
-    elif x<0 : #x**2+y**2-1>=0
-        my_ExactSol[i] =  pi/2
-    else : #x=0
-        my_ExactSol[i] = 0
-        
-    if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-        boundaryNodes.append(i)
-        nbBoundaryNodes=nbBoundaryNodes+1
-    else: # Détection des noeuds intérieurs
-        interiorNodes.append(i)
-        nbInteriorNodes=nbInteriorNodes+1
-        maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
-
-print("Right hand side discretisation done")
-print("Number of interior nodes=", nbInteriorNodes)
-print("Number of boundary nodes=", nbBoundaryNodes)
-print("Maximum number of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbInteriorNodes)
-
-M=cdmath.Matrix(3,3)
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
-GradShapeFunc0=cdmath.Vector(2)
-GradShapeFunc1=cdmath.Vector(2)
-GradShapeFunc2=cdmath.Vector(2)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-    Ci=my_mesh.getCell(i)
-
-    #Contribution à la matrice de rigidité
-    nodeId0=Ci.getNodeId(0)
-    nodeId1=Ci.getNodeId(1)
-    nodeId2=Ci.getNodeId(2)
-
-    N0=my_mesh.getNode(nodeId0)
-    N1=my_mesh.getNode(nodeId1)
-    N2=my_mesh.getNode(nodeId2)
-
-    M[0,0]=N0.x()
-    M[0,1]=N0.y()
-    M[0,2]=1
-    M[1,0]=N1.x()
-    M[1,1]=N1.y()
-    M[1,2]=1
-    M[2,0]=N2.x()
-    M[2,1]=N2.y()
-    M[2,2]=1
-
-    #Values of each shape function at each node
-    values0=[1,0,0]
-    values1=[0,1,0]
-    values2=[0,0,1]
-
-    GradShapeFunc0 = gradientNodal(M,values0)*0.5
-    GradShapeFunc1 = gradientNodal(M,values1)*0.5
-    GradShapeFunc2 = gradientNodal(M,values2)*0.5
-
-    #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-    GradShapeFuncs={nodeId0 : GradShapeFunc0}
-    GradShapeFuncs[nodeId1]=GradShapeFunc1
-    GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-
-    # Remplissage de  la matrice de rigidité et du second membre
-    for j in [nodeId0,nodeId1,nodeId2] :
-        if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-            j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-            #Pas de contribution au second membre car pas de terme source
-            boundaryContributionAdded=False#Needed in case j is a border cell
-            #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
-            for k in [nodeId0,nodeId1,nodeId2] : 
-                if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                    k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                    Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                elif boundaryContributionAdded == False: #si condition limite non nulle au bord (ou maillage non recouvrant), ajouter la contribution du bord au second membre de la cellule j
-                    if boundaryNodes.count(nodeId0)!=0 :
-                        u0=my_ExactSol[nodeId0]
-                    else:
-                        u0=0
-                    if boundaryNodes.count(nodeId1)!=0 :
-                        u1=my_ExactSol[nodeId1]
-                    else:
-                        u1=0
-                    if boundaryNodes.count(nodeId2)!=0 :
-                        u2=my_ExactSol[nodeId2]
-                    else:
-                        u2=0
-                    boundaryContributionAdded=True#Contribution from the boundary to matrix line j is done in one step
-                    GradGh = gradientNodal(M,[u0,u1,u2])*0.5
-                    RHS[j_int] += -(GradGh*GradShapeFuncs[j])/Ci.getMeasure()
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print( "Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-for j in range(nbBoundaryNodes):
-    my_ResultField[boundaryNodes[j]]=my_ExactSol[boundaryNodes[j]];#remplissage des valeurs pour les noeuds frontière (condition limite)
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElements2DPoissonStiffBC_DISK_ResultField")
-my_ExactSol.writeVTK("ExactSol2DPoissonStiffBC_DISK")
-
-# Postprocessing :
-#=================
-# save 2D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoissonStiffBC_DISK_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoissonStiffBC_DISK_ResultField")
-PV_routines.Save_PV_data_to_picture_file("ExactSol2DPoissonStiffBC_DISK"+'_0.vtu',"Exact_field",'NODES',"ExactSol2DPoissonStiffBC_DISK")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=linspace(-1,1,resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,-1,0],[0,1,0], resolution)
-plt.plot(curv_abs, diag_data, label= '2D disk mesh with '+str(nbNodes) + ' nodes')
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D disk triangular mesh')
-plt.savefig("FiniteElements2DPoissonStiffBC_DISK_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 2D Poisson equation on a disk using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-l2_norm_sol_exacte=my_ExactSol.normL2()[0]
-l2_error = (my_ExactSol - my_ResultField).normL2()[0]
-
-print("L2 absolute error = norm( exact solution - numerical solution ) = ",l2_error )
-print("L2 relative error = norm( exact solution - numerical solution )/norm( exact solution ) = ",l2_error/l2_norm_sol_exacte)
-print("Maximum numerical solution = ", my_ResultField.max(), " Minimum numerical solution = ", my_ResultField.min())
-print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min())
-
-assert l2_error/l2_norm_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson2DEF_SQUARE_StiffBC/CMakeLists.txt b/CDMATH/tests/examples/Poisson2DEF_SQUARE_StiffBC/CMakeLists.txt
deleted file mode 100755 (executable)
index 99f13a4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/squareWithTriangles.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF_SQUARE_StiffBC)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_2DEF_SQUARE_StiffBC ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_SQUARE_StiffBC.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson2DEF_SQUARE_StiffBC/FiniteElements2DPoisson_SQUARE_StiffBC.py b/CDMATH/tests/examples/Poisson2DEF_SQUARE_StiffBC/FiniteElements2DPoisson_SQUARE_StiffBC.py
deleted file mode 100755 (executable)
index 1f2a44f..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = 0 sur le carré unité avec conditions aux limites de Dirichlet discontinues
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
-#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=atan((x*x-y*y)/(2*x*y))
-#================================================================================================================================
-
-import cdmath
-from math import atan, pi
-from numpy import linspace
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-# Fonction qui remplace successivement les colonnes d'une matrices par un vecteur donné et retourne la liste des déterminants
-def gradientNodal(M, values):
-    matrices=[0]*(len(values)-1)
-    for i in range(len(values)-1):
-        matrices[i] = M.deepCopy()        
-        for j in range(len(values)):
-            matrices[i][j,i] = values[j]
-
-    result = cdmath.Vector(len(values)-1)    
-    for i in range(len(values)-1):
-        result[i] = matrices[i].determinant()
-
-    return result
-
-
-#Chargement du maillage triangulaire du carré unité
-#=======================================================================================
-meshName="squareWithTriangles"
-my_mesh = cdmath.Mesh(meshName+".med")
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-if(not my_mesh.isTriangular()) :
-    raise ValueError("Wrong cell types : mesh is not made of triangles")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Détermination des noeuds intérieurs
-#======================================================================
-my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1)
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-eps=1e-10
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-    Ni=my_mesh.getNode(i)
-    x = Ni.x()
-    y = Ni.y()
-
-    #Robust calculation of atan((x*x-y*y)/(2*x*y))
-    if x<-eps or x>1+eps or y<-eps or y>1+eps :
-        print("!!! Warning Mesh ", meshName," !!! Node is not in the unit square.",", eps=",eps, ", x= ",x, ", y= ",y)
-        #raise ValueError("!!! Domain should be the unit square.")
-    if abs(x*y) > eps :
-        my_ExactSol[i] = atan((x*x-y*y)/(2*x*y))
-    elif x**2-y**2>0 :
-        my_ExactSol[i] = pi/2
-    elif x**2-y**2<0 :
-        my_ExactSol[i] = -pi/2
-    else : #x=0
-        my_ExactSol[i] = 0
-        
-    if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-        boundaryNodes.append(i)
-        nbBoundaryNodes=nbBoundaryNodes+1
-    else: # Détection des noeuds intérieurs
-        interiorNodes.append(i)
-        nbInteriorNodes=nbInteriorNodes+1
-        maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
-
-print("Right hand side discretisation done")
-print("Number of interior nodes=", nbInteriorNodes)
-print("Number of boundary nodes=", nbBoundaryNodes)
-print("Maximum number of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbInteriorNodes)
-
-M=cdmath.Matrix(3,3)
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
-GradShapeFunc0=cdmath.Vector(2)
-GradShapeFunc1=cdmath.Vector(2)
-GradShapeFunc2=cdmath.Vector(2)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-    Ci=my_mesh.getCell(i)
-
-    #Contribution à la matrice de rigidité
-    nodeId0=Ci.getNodeId(0)
-    nodeId1=Ci.getNodeId(1)
-    nodeId2=Ci.getNodeId(2)
-
-    N0=my_mesh.getNode(nodeId0)
-    N1=my_mesh.getNode(nodeId1)
-    N2=my_mesh.getNode(nodeId2)
-
-    M[0,0]=N0.x()
-    M[0,1]=N0.y()
-    M[0,2]=1
-    M[1,0]=N1.x()
-    M[1,1]=N1.y()
-    M[1,2]=1
-    M[2,0]=N2.x()
-    M[2,1]=N2.y()
-    M[2,2]=1
-
-    #Values of each shape function at each node
-    values0=[1,0,0]
-    values1=[0,1,0]
-    values2=[0,0,1]
-
-    GradShapeFunc0 = gradientNodal(M,values0)*0.5
-    GradShapeFunc1 = gradientNodal(M,values1)*0.5
-    GradShapeFunc2 = gradientNodal(M,values2)*0.5
-
-    #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-    GradShapeFuncs={nodeId0 : GradShapeFunc0}
-    GradShapeFuncs[nodeId1]=GradShapeFunc1
-    GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-
-    # Remplissage de  la matrice de rigidité et du second membre
-    for j in [nodeId0,nodeId1,nodeId2] :
-        if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-            j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-            #Pas de contribution au second membre car pas de terme source
-            boundaryContributionAdded=False#Needed in case j is a border cell
-            #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
-            for k in [nodeId0,nodeId1,nodeId2] : 
-                if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                    k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                    Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                elif boundaryContributionAdded == False: #si condition limite non nulle au bord (ou maillage non recouvrant), ajouter la contribution du bord au second membre de la cellule j
-                    if boundaryNodes.count(nodeId0)!=0 :
-                        u0=my_ExactSol[nodeId0]
-                    else:
-                        u0=0
-                    if boundaryNodes.count(nodeId1)!=0 :
-                        u1=my_ExactSol[nodeId1]
-                    else:
-                        u1=0
-                    if boundaryNodes.count(nodeId2)!=0 :
-                        u2=my_ExactSol[nodeId2]
-                    else:
-                        u2=0
-                    boundaryContributionAdded=True#Contribution from the boundary to matrix line j is done in one step
-                    GradGh = gradientNodal(M,[u0,u1,u2])*0.5
-                    RHS[j_int] += -(GradGh*GradShapeFuncs[j])/Ci.getMeasure()
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print( "Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-for j in range(nbBoundaryNodes):
-    my_ResultField[boundaryNodes[j]]=my_ExactSol[boundaryNodes[j]];#remplissage des valeurs pour les noeuds frontière (condition limite)
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElements2DPoissonStiffBC_SQUARE_ResultField")
-my_ExactSol.writeVTK("ExactSol2DPoissonStiffBC_SQUARE")
-
-# Postprocessing :
-#=================
-# save 2D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoissonStiffBC_SQUARE_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoissonStiffBC_SQUARE_ResultField")
-PV_routines.Save_PV_data_to_picture_file("ExactSol2DPoissonStiffBC_SQUARE"+'_0.vtu',"Exact_field",'NODES',"ExactSol2DPoissonStiffBC_SQUARE")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=linspace(-1,1,resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,-1,0],[0,1,0], resolution)
-plt.plot(curv_abs, diag_data, label= '2D square mesh with '+str(nbNodes) + ' nodes')
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D square triangular mesh')
-plt.savefig("FiniteElements2DPoissonStiffBC_SQUARE_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 2D Poisson equation on a square using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-l2_norm_sol_exacte=my_ExactSol.normL2()[0]
-l2_error = (my_ExactSol - my_ResultField).normL2()[0]
-
-print("L2 absolute error = norm( exact solution - numerical solution ) = ",l2_error )
-print("L2 relative error = norm( exact solution - numerical solution )/norm( exact solution ) = ",l2_error/l2_norm_sol_exacte)
-print("Maximum numerical solution = ", my_ResultField.max(), " Minimum numerical solution = ", my_ResultField.min())
-print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min())
-
-assert l2_error/l2_norm_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson2DVF/CMakeLists.txt b/CDMATH/tests/examples/Poisson2DVF/CMakeLists.txt
deleted file mode 100755 (executable)
index e302ceb..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_2DVF_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py)
-
-    SET(MESH_FILE  ../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/squareWithLocRefSquares.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_SQUARE_loc_ref ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/squareWithCheckerboardSquares.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/squareWithHexagons.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_SQUARE_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/squareWithBrickWall.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_SQUARE_brickwall ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/squareWithDeformedQuadrangles.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_SQUARE_deformed_quadrangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson2DVF/FiniteVolumes2DPoisson_SQUARE.py b/CDMATH/tests/examples/Poisson2DVF/FiniteVolumes2DPoisson_SQUARE.py
deleted file mode 100755 (executable)
index 877628c..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur un carré avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2016
-# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
-#                Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)
-#================================================================================================================================
-
-import cdmath
-from math import sin, pi, sqrt
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-import sys
-
-if len(sys.argv) >1 :#non rectangular mesh
-    my_mesh = cdmath.Mesh(sys.argv[1])
-else :   #rectangular mesh
-# Création d'un maillage cartésien du domaine carré [0,1]x[0,1], définition des bords
-#====================================================================================
-    xmin=0
-    xmax=1
-    ymin=0
-    ymax=1
-    
-    nx=15
-    ny=15
-    
-    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny)
-
-    eps=1e-6
-    my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
-    my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
-    my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
-    my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
-
-nbCells = my_mesh.getNumberOfCells()
-
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-
-print("Mesh loading done")
-print("Number of cells  = ", nbCells)
-
-#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
-#================================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
-maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
-for i in range(nbCells): 
-    Ci = my_mesh.getCell(i)
-    x = Ci.x()
-    y = Ci.y()
-
-    my_RHSfield[i]=2*pi*pi*sin(pi*x)*sin(pi*y)#mettre la fonction definie au second membre de l edp
-    # compute maximum number of neighbours
-    maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print("Max nb of neighbours = ", maxNbNeighbours)
-
-# Construction de la matrice et du vecteur second membre du système linéaire
-#===========================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbCells)
-#Parcours des cellules du domaine
-for i in range(nbCells):
-    RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
-    Ci=my_mesh.getCell(i)
-    for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
-        Fj=my_mesh.getFace(Ci.getFaceId(j))
-        if not Fj.isBorder():
-            k=Fj.getCellId(0)
-            if k==i :
-                k=Fj.getCellId(1)
-            Ck=my_mesh.getCell(k)
-            distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
-            coeff=Fj.getMeasure()/Ci.getMeasure()/distance
-            Rigidite.addValue(i,k,-coeff) # terme extradiagonal
-        else:
-            coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
-            #For the particular case where the mesh boundary does not coincide with the domain boundary
-            x=Fj.getBarryCenter().x()
-            y=Fj.getBarryCenter().y()
-            RHS[i]+=coeff*sin(pi*x)*sin(pi*y)#mettre ici  la solution exacte de l'edp
-        Rigidite.addValue(i,i,coeff) # terme diagonal
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
-SolSyst=LS.solve()
-
-print("Preconditioner used : ", LS.getNameOfPc())
-print("Number of iterations used : ", LS.getNumberOfIter())
-print("Final residual : ", LS.getResidu())
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
-for i in range(nbCells):
-    my_ResultField[i]=SolSyst[i];
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteVolumes2DPoisson_SQUARE_ResultField")
-
-#Postprocessing : 
-#===============
-# save 2D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteVolumes2DPoisson_SQUARE_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes2DPoisson_SQUARE_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=np.linspace(0,sqrt(2),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-if len(sys.argv) >1 :
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D square '+my_mesh.getName())
-    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
-    plt.savefig("FiniteVolumes2DPoisson_SQUARE_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
-else :   
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D square with a rectangular grid')
-    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
-    plt.savefig("FiniteVolumes2DPoisson_SQUARE_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 2D Poisson equation on a square using finite volumes done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal the right hand side divided by 2*pi*pi
-max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(2*pi*pi)
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbCells) :
-    if erreur_abs < abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i]) :
-        erreur_abs = abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_RHSfield.max()/(2*pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(2*pi*pi) )
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson2DVF_DISK/CMakeLists.txt b/CDMATH/tests/examples/Poisson2DVF_DISK/CMakeLists.txt
deleted file mode 100755 (executable)
index 546f57e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(MESH_FILE  ../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_spiderweb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson2DVF_DISK/FiniteVolumes2DPoisson_DISK.py b/CDMATH/tests/examples/Poisson2DVF_DISK/FiniteVolumes2DPoisson_DISK.py
deleted file mode 100755 (executable)
index 9e13ad3..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur un disque avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
-#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)
-#================================================================================================================================
-
-import cdmath
-from math import sin, sqrt, atan2
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-import sys
-
-if len(sys.argv) >1 :#non rectangular mesh
-    my_mesh = cdmath.Mesh(sys.argv[1])
-else :   
-    raise ValueError("Give an input mesh of the disk")
-
-nbCells = my_mesh.getNumberOfCells()
-
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-
-print( "Mesh loading done" )
-print( "Number of cells  = ", nbCells )
-
-#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
-#================================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
-my_ExactSol = cdmath.Field("Exact_field", cdmath.CELLS, my_mesh, 1)
-
-maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
-for i in range(nbCells): 
-       Ci = my_mesh.getCell(i)
-       x = Ci.x()
-       y = Ci.y()
-
-       r=sqrt(x*x+y*y)
-       theta=atan2(y,x)
-
-       my_RHSfield[i]=(8*r-3)*sin(theta)#mettre la fonction definie au second membre de l'edp
-       my_ExactSol[i]=-(r-1)*r*r*sin(theta)#mettre la solution exacte de l'edp
-       # compute maximum number of neighbours
-       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print("Maximum number of neighbours = ", maxNbNeighbours )
-
-# Construction de la matrice et du vecteur second membre du système linéaire
-#===========================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbCells)
-#Parcours des cellules du domaine
-for i in range(nbCells):
-       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
-       Ci=my_mesh.getCell(i)
-       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
-               Fj=my_mesh.getFace(Ci.getFaceId(j))
-               if not Fj.isBorder():
-                       k=Fj.getCellId(0)
-                       if k==i :
-                               k=Fj.getCellId(1)
-                       Ck=my_mesh.getCell(k)
-                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
-                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
-               else:
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
-                       #For the particular case where the mesh boundary does not coincide with the domain boundary
-                       x=Fj.getBarryCenter().x()
-                       y=Fj.getBarryCenter().y()
-                       r=sqrt(x*x+y*y)
-                       theta=atan2(y,x)
-                       RHS[i]+=coeff*(-(r-1)*r*r*sin(theta))#mettre ici la solution exacte de l'edp
-               Rigidite.addValue(i,i,coeff) # terme diagonal
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print( "Linear system solved" )
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
-for i in range(nbCells):
-    my_ResultField[i]=SolSyst[i];
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteVolumes2DPoisson_DISK_square_ResultField")
-
-#Postprocessing : 
-#===============
-# save 2D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteVolumes2DPoisson_DISK_square_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes2DPoisson_DISK_square_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=np.linspace(0,sqrt(2),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-if len(sys.argv) >1 :
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk mesh '+my_mesh.getName())
-    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
-    plt.savefig("FiniteVolumes2DPoisson_DISK_square_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
-else :   
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk with a rectangular grid')
-    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
-    plt.savefig("FiniteVolumes2DPoisson_DISK_square_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 2D Poisson equation on a disk using finite volumes done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbCells) :
-    if erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
-        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min() )
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson2DVF_DISK_StiffBC/CMakeLists.txt b/CDMATH/tests/examples/Poisson2DVF_DISK_StiffBC/CMakeLists.txt
deleted file mode 100755 (executable)
index f580a63..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(MESH_FILE  ../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
-
-    SET(MESH_FILE  ../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_spiderweb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson2DVF_DISK_StiffBC/FiniteVolumes2DPoisson_DISK_StiffBC.py b/CDMATH/tests/examples/Poisson2DVF_DISK_StiffBC/FiniteVolumes2DPoisson_DISK_StiffBC.py
deleted file mode 100755 (executable)
index 56355bd..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation de Poisson -\triangle u = 0 sur un disque avec conditions aux limites de Dirichlet discontinues
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
-#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=atan(2*x/(x**2+y**2-1))=atan(2 r cos(theta)/(r*2-1))
-#================================================================================================================================
-
-import cdmath
-from math import atan, pi, sqrt
-from numpy import linspace
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-import sys
-
-if len(sys.argv) >1 :#non rectangular mesh
-    meshName=sys.argv[1]
-    my_mesh = cdmath.Mesh(sys.argv[1])
-else :
-    raise ValueError("Give an input mesh of the disk")
-    
-nbCells = my_mesh.getNumberOfCells()
-
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-
-print( "Mesh loading done" )
-print( "Number of cells  = ", nbCells )
-
-#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
-#================================================================================
-my_ExactSol = cdmath.Field("Exact_field", cdmath.CELLS, my_mesh, 1)
-eps=1e-6#For coarse meshes
-
-maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
-for i in range(nbCells): 
-    Ci = my_mesh.getCell(i)
-    x = Ci.x()
-    y = Ci.y()
-
-    #Robust calculation of atan(2x/(x**2+y**2-1)
-    if x**2+y**2-1 > eps :
-        print("!!! Warning Mesh ", meshName," !!! Cell is not in the unit disk."," eps=",eps, ", x**2+y**2-1=",x**2+y**2 - 1)
-        #raise ValueError("x**2+y**2 > 1 !!! Domain should be the unit disk.")
-    if x**2+y**2-1 < -eps :
-        my_ExactSol[i] = atan(2*x/(x**2+y**2-1))
-    elif x>0 : #x**2+y**2-1>=0
-        my_ExactSol[i] = -pi/2
-    elif x<0 : #x**2+y**2-1>=0
-        my_ExactSol[i] =  pi/2
-    else : #x=0
-        my_ExactSol[i] = 0
-        
-    # compute maximum number of neighbours
-    maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print( "Maximum number of neighbours = ", maxNbNeighbours)
-
-# Construction de la matrice et du vecteur second membre du système linéaire
-#===========================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbCells)
-
-#Parcours des cellules du domaine
-for i in range(nbCells):
-    Ci=my_mesh.getCell(i)
-    for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
-        Fj=my_mesh.getFace(Ci.getFaceId(j))
-        if not Fj.isBorder():
-            k=Fj.getCellId(0)
-            if k==i :
-                k=Fj.getCellId(1)
-            Ck=my_mesh.getCell(k)
-            distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
-            coeff=Fj.getMeasure()/Ci.getMeasure()/distance
-            Rigidite.addValue(i,k,-coeff) # terme extradiagonal
-        else:
-            coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
-            #For the particular case where the mesh boundary does not coincide with the domain boundary
-            x=Fj.getBarryCenter().x()
-            y=Fj.getBarryCenter().y()
-            if x**2+y**2-1 > eps :
-                print("!!! Warning Mesh ", meshName," !!! Face is not in the unit disk.",", eps=",eps, ", x**2+y**2-1=",x**2+y**2 - 1)
-                #raise ValueError("!!! Domain should be the unit disk.")
-            if x**2+y**2-1 < -eps :
-                RHS[i]+= coeff*atan(2*x/(x**2+y**2-1))
-            elif x>0 : #x**2+y**2-1>=0
-                RHS[i]+= coeff*(-pi/2)
-            elif x<0 : #x**2+y**2-1>=0
-                RHS[i]+= coeff*pi/2
-            else : #x=0
-                RHS[i]+=  0
-        Rigidite.addValue(i,i,coeff) # terme diagonal
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print( "Linear system solved" )
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
-for i in range(nbCells):
-    my_ResultField[i]=SolSyst[i];
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteVolumes2DPoisson_DISK_ResultField")
-
-#Postprocessing : 
-#===============
-# save 2D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteVolumes2DPoisson_DISK_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes2DPoisson_DISK_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=linspace(0,sqrt(2),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,-1,0],[0,1,0], resolution)
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-if len(sys.argv) >1 :
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk mesh '+my_mesh.getName())
-    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
-    plt.savefig("FiniteVolumes2DPoisson_DISK_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
-else :   
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk with a rectangular grid')
-    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
-    plt.savefig("FiniteVolumes2DPoisson_DISK_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 2D Poisson equation on a disk using finite volumes done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-l2_norm_sol_exacte=my_ExactSol.normL2()[0]
-l2_error = (my_ExactSol - my_ResultField).normL2()[0]
-
-print("L2 absolute error = norm( exact solution - numerical solution ) = ",l2_error )
-print("L2 relative error = norm( exact solution - numerical solution )/norm( exact solution ) = ",l2_error/l2_norm_sol_exacte ) 
-print("Maximum numerical solution = ", my_ResultField.max(), " Minimum numerical solution = ", my_ResultField.min() )
-print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min() )
-
-assert l2_error/l2_norm_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson3DCubeSkinEF/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DCubeSkinEF/CMakeLists.txt
deleted file mode 100755 (executable)
index 3765230..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/meshCubeSkin.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DCubeSkinEF)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoissonBeltrami_3DFE_CUBESKIN ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoissonCubeSkin.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DCubeSkinEF/FiniteElements3DPoissonCubeSkin.py b/CDMATH/tests/examples/Poisson3DCubeSkinEF/FiniteElements3DPoissonCubeSkin.py
deleted file mode 100644 (file)
index e167456..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Laplace-Beltrami -\triangle u = f sur la frontière d'un cube
-# Author      : Michael Ndjinga
-# Copyright   : CEA Saclay 2021
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
-#               Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Résolution d'un système linéaire à matrice singulière : les vecteurs constants sont dans le noyau
-#               Comparaison de la solution numérique avec la solution exacte définie face par face : u(x,y,z)= cos(2*pi*x)*cos(2*pi*y)*cos(2*pi*z)
-#================================================================================================================================
-
-import cdmath
-from math import cos, pi
-import numpy as np
-import PV_routines
-import VTK_routines
-import paraview.simple as pvs
-
-#Chargement du maillage triangulaire de la frontière du cube unité [0,1]x[0,1]x[0,1]
-#=======================================================================================
-my_mesh = cdmath.Mesh("meshCubeSkin.med")
-if(not my_mesh.isTriangular()) :
-       raise ValueError("Wrong cell types : mesh is not made of triangles")
-if(my_mesh.getMeshDimension()!=2) :
-       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
-if(my_mesh.getSpaceDimension()!=3) :
-       raise ValueError("Wrong space dimension : expected a space of dimension 3")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh building/loading done")
-print("nb of nodes=", nbNodes)
-print("nb of cells=", nbCells)
-
-#Discrétisation du second membre et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS field", cdmath.NODES, my_mesh, 1)
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-
-eps=1e-6
-#parcours des noeuds pour discrétisation du second membre et extraction du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-       y = Ni.y()
-       z = Ni.z()
-
-       my_RHSfield[i]= 8*pi*pi*cos(2*pi*x)*cos(2*pi*y)*cos(2*pi*z)
-
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               raise ValueError("Mesh should not contain borders")
-       else:
-               maxNbNeighbours = max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only for planar cells, otherwise use function Ni.getNumberOfEdges()
-
-print("Right hand side discretisation done")
-print("Max nb of neighbours=", maxNbNeighbours)
-print("Integral of the RHS", my_RHSfield.integral(0))
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)# warning : third argument is number of non zero coefficients per line
-RHS=cdmath.Vector(nbNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
-GradShapeFunc0=cdmath.Vector(3)
-GradShapeFunc1=cdmath.Vector(3)
-GradShapeFunc2=cdmath.Vector(3)
-
-normalFace0=cdmath.Vector(3)
-normalFace1=cdmath.Vector(3)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-
-       #Build normal to cell Ci
-       normalFace0[0]=Ci.getNormalVector(0,0)
-       normalFace0[1]=Ci.getNormalVector(0,1)
-       normalFace0[2]=Ci.getNormalVector(0,2)
-       normalFace1[0]=Ci.getNormalVector(1,0)
-       normalFace1[1]=Ci.getNormalVector(1,1)
-       normalFace1[2]=Ci.getNormalVector(1,2)
-
-       normalCell = normalFace0.crossProduct(normalFace1)
-       normalCell = normalCell*(1/normalCell.norm())
-
-       cellMat=cdmath.Matrix(4)
-       cellMat[0,0]=N0.x()
-       cellMat[0,1]=N0.y()
-       cellMat[0,2]=N0.z()
-       cellMat[1,0]=N1.x()
-       cellMat[1,1]=N1.y()
-       cellMat[1,2]=N1.z()
-       cellMat[2,0]=N2.x()
-       cellMat[2,1]=N2.y()
-       cellMat[2,2]=N2.z()
-       cellMat[3,0]=normalCell[0]
-       cellMat[3,1]=normalCell[1]
-       cellMat[3,2]=normalCell[2]
-       cellMat[0,3]=1
-       cellMat[1,3]=1
-       cellMat[2,3]=1
-       cellMat[3,3]=0
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
-       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
-       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
-       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
-       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
-       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
-       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
-       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
-       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2] : 
-               #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
-               RHS[j]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j] # intégrale dans le triangle du produit f x fonction de base
-               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
-               for k in [nodeId0,nodeId1,nodeId2] : 
-                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-
-print("Linear system matrix building done")
-
-# Conditionnement de la matrice de rigidité
-#=================================
-cond = Rigidite.getConditionNumber(True)
-print("Condition number is ",cond)
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")
-LS.setMatrixIsSingular()#En raison de l'absence de bord
-SolSyst=LS.solve()
-print("Preconditioner used : ", LS.getNameOfPc() )
-print("Number of iterations used : ", LS.getNumberOfIter() )
-print("Final residual : ", LS.getResidu() )
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbNodes):
-    my_ResultField[j]=SolSyst[j];#remplissage des valeurs issues du système linéaire dans le champs résultat
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElementsOnCubeSkinPoisson")
-my_RHSfield.writeVTK("RHS_CubeSkinPoisson")
-
-print("Integral of the numerical solution", my_ResultField.integral(0))
-print("Numerical solution of Poisson equation on a cube skin using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal the right hand side divided by 8*pi*pi
-max_abs_sol_exacte=0
-erreur_abs=0
-max_sol_num=0
-min_sol_num=0
-for i in range(nbNodes) :
-    if max_abs_sol_exacte < abs(my_RHSfield[i]) :
-        max_abs_sol_exacte = abs(my_RHSfield[i])
-    if erreur_abs  < abs(my_RHSfield[i]/(8*pi*pi) - my_ResultField[i]) :
-        erreur_abs = abs(my_RHSfield[i]/(8*pi*pi) - my_ResultField[i])
-    if max_sol_num  < my_ResultField[i] :
-        max_sol_num = my_ResultField[i]
-    if min_sol_num  > my_ResultField[i] :
-        min_sol_num = my_ResultField[i]
-max_abs_sol_exacte = max_abs_sol_exacte/(8*pi*pi)
-
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_RHSfield.max()/(8*pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(8*pi*pi) )
-
-#Postprocessing :
-#================
-# save 3D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElementsOnCubeSkinPoisson"+'_0.vtu',"ResultField",'NODES',"FiniteElementsOnCubeSkinPoisson")
-resolution=100
-VTK_routines.Clip_VTK_data_to_VTK("FiniteElementsOnCubeSkinPoisson"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElementsOnCubeSkinPoisson"+'_0.vtu',[0.75,0.75,0.75], [0.,0.5,-0.5],resolution )
-PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElementsOnCubeSkinPoisson"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElementsOnCubeSkinPoisson")
-
-# Plot  over slice circle
-finiteElementsOnCubeSkin_0vtu = pvs.XMLUnstructuredGridReader(FileName=["FiniteElementsOnCubeSkinPoisson"+'_0.vtu'])
-slice1 = pvs.Slice(Input=finiteElementsOnCubeSkin_0vtu)
-slice1.SliceType.Normal = [0, 1, 0]
-renderView1 = pvs.GetActiveViewOrCreate('RenderView')
-finiteElementsOnCubeSkin_0vtuDisplay = pvs.Show(finiteElementsOnCubeSkin_0vtu, renderView1)
-pvs.ColorBy(finiteElementsOnCubeSkin_0vtuDisplay, ('POINTS', 'ResultField'))
-slice1Display = pvs.Show(slice1, renderView1)
-pvs.SaveScreenshot("./FiniteElementsOnCubeSkinPoisson"+"_Slice"+'.png', magnification=1, quality=100, view=renderView1)
-plotOnSortedLines1 = pvs.PlotOnSortedLines(Input=slice1)
-lineChartView2 = pvs.CreateView('XYChartView')
-plotOnSortedLines1Display = pvs.Show(plotOnSortedLines1, lineChartView2)
-plotOnSortedLines1Display.UseIndexForXAxis = 0
-plotOnSortedLines1Display.XArrayName = 'arc_length'
-plotOnSortedLines1Display.SeriesVisibility = ['ResultField (1)']
-pvs.SaveScreenshot("./FiniteElementsOnCubeSkinPoisson"+"_PlotOnSortedLine_"+'.png', magnification=1, quality=100, view=lineChartView2)
-pvs.Delete(lineChartView2)
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson3DEF/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DEF/CMakeLists.txt
deleted file mode 100755 (executable)
index 286cc1a..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/meshCube.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DEF)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_3DEF_CUBE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoisson_CUBE.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DEF/FiniteElements3DPoisson_CUBE.py b/CDMATH/tests/examples/Poisson3DEF/FiniteElements3DPoisson_CUBE.py
deleted file mode 100755 (executable)
index 6043a1e..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Poisson 3D -\triangle u = f sur le cube avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga, Sédrick Kameni
-# Copyright   : CEA Saclay 2017
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage tétraédrique
-#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)*sin(pi*z)
-#================================================================================================================================
-
-import cdmath
-from math import sin, pi, sqrt
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-#Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
-#==============================================================================================
-my_mesh = cdmath.Mesh("meshCube.med")
-if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
-if(not my_mesh.isTetrahedral()) :
-       raise ValueError("Wrong cell types : mesh is not made of tetrahedra")
-eps=1e-6
-my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
-my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
-my_mesh.setGroupAtPlan(0.,1,eps,"DirichletBorder")#Bord BAS
-my_mesh.setGroupAtPlan(1.,1,eps,"DirichletBorder")#Bord HAUT
-my_mesh.setGroupAtPlan(0.,2,eps,"DirichletBorder")#Bord AVANT
-my_mesh.setGroupAtPlan(1.,2,eps,"DirichletBorder")#Bord ARRIERE
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Discrétisation du second membre et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
-
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-       y = Ni.y()
-       z = Ni.z()
-
-       my_RHSfield[i]=3*pi*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)#mettre la fonction definie au second membre de l'edp
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               boundaryNodes.append(i)
-               nbBoundaryNodes=nbBoundaryNodes+1
-       else: # Détection des noeuds intérieurs
-               interiorNodes.append(i)
-               nbInteriorNodes=nbInteriorNodes+1
-               maxNbNeighbours= max(1+Ni.getNumberOfEdges(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print("Number of interior nodes=", nbInteriorNodes)
-print("Number of boundary nodes=", nbBoundaryNodes)
-print("Maximum number of neighbours per node=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours) # warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbInteriorNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un tétraèdre
-GradShapeFunc0=cdmath.Vector(3)
-GradShapeFunc1=cdmath.Vector(3)
-GradShapeFunc2=cdmath.Vector(3)
-GradShapeFunc3=cdmath.Vector(3)
-
-#On parcourt les tétraèdres du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Extraction des noeuds de la cellule
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-       nodeId3=Ci.getNodeId(3)
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-       N3=my_mesh.getNode(nodeId3)
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= (N2.y()*N3.z()-N2.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
-       GradShapeFunc0[1]=-(N2.x()*N3.z()-N2.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
-       GradShapeFunc0[2]=(N2.x()*N3.y()-N2.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
-       GradShapeFunc1[0]=- (N2.y()*N3.z()-N2.z()*N3.y()-N0.y()*N3.z()+N3.y()*N0.z()+N0.y()*N2.z()-N2.y()*N0.z())/6
-       GradShapeFunc1[1]=(N2.x()*N3.z()-N2.z()*N3.x()-N0.x()*N3.z()+N3.x()*N0.z()+N0.x()*N2.z()-N2.x()*N0.z())/6
-       GradShapeFunc1[2]=-(N2.x()*N3.y()-N2.y()*N3.x()-N0.x()*N3.y()+N3.x()*N0.y()+N0.x()*N2.y()-N2.x()*N0.y())/6
-       GradShapeFunc2[0]= -(N0.y()*N3.z()-N0.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N0.z()-N0.y()*N1.z())/6
-       GradShapeFunc2[1]=(N0.x()*N3.z()-N0.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N0.z()-N0.x()*N1.z())/6
-       GradShapeFunc2[2]= -(N0.x()*N3.y()-N0.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N0.y()-N0.x()*N1.y())/6
-       GradShapeFunc3[0]=-(N2.y()*N0.z()-N2.z()*N0.y()-N1.y()*N0.z()+N0.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
-       GradShapeFunc3[1]=(N2.x()*N0.z()-N2.z()*N0.x()-N1.x()*N0.z()+N0.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
-       GradShapeFunc3[2]=-(N2.x()*N0.y()-N2.y()*N0.x()-N1.x()*N0.y()+N0.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
-       
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme)
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-       GradShapeFuncs[nodeId3]=GradShapeFunc3
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2,nodeId3] :
-               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
-                       RHS[j_int]=Ci.getMeasure()/4*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
-                       #Contribution de la cellule tétraédrique i à la ligne j_int du système linéaire
-                       for k in [nodeId0,nodeId1,nodeId2,nodeId3] :
-                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#,"ILU" Remplacer CG par CHOLESKY pour solveur direct
-SolSyst=LS.solve()
-print( "Preconditioner used : ", LS.getNameOfPc())
-print( "Number of iterations used : ", LS.getNumberOfIter())
-print( "Final residual : ", LS.getResidu())
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-       my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-
-for j in range(nbBoundaryNodes):
-    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElements3DPoisson_CUBE_ResultField")
-
-#Postprocessing :
-#================
-# save 3D picture
-resolution=100
-VTK_routines.Clip_VTK_data_to_VTK("FiniteElements3DPoisson_CUBE_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElements3DPoisson_CUBE_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
-PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_CUBE_ResultField"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_CUBE_ResultField")
-
-# extract and plot diagonal values
-curv_abs=np.linspace(0,sqrt(3),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,0,0],[1,1,1], resolution)
-plt.plot(curv_abs, diag_data, label= str(nbNodes) + ' nodes 3D mesh')
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 3D tetrahedral mesh')
-plt.savefig("FiniteElements3DPoisson_CUBE_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 3D Poisson equation on a cube using finite elements done")
-
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal the right hand side divided by 3*pi*pi
-max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(3*pi*pi)
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbNodes) :
-    if erreur_abs < abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i]) :
-        erreur_abs = abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson3DEF_BALL/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DEF_BALL/CMakeLists.txt
deleted file mode 100755 (executable)
index 1a05b09..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DEF_BALL)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_3DEF_BALL ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoisson_BALL.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DEF_BALL/FiniteElements3DPoisson_BALL.py b/CDMATH/tests/examples/Poisson3DEF_BALL/FiniteElements3DPoisson_BALL.py
deleted file mode 100755 (executable)
index 82fa4e8..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Poisson 3D -\triangle u = f sur la boule unité avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage tétraédrique
-#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)**2*cos(phi)
-#================================================================================================================================
-
-import cdmath
-from math import sin, cos, atan2, sqrt
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-#Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
-#==============================================================================================
-my_mesh = cdmath.Mesh("ballWithTetrahedra.med")
-if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
-if(not my_mesh.isTetrahedral()) :
-       raise ValueError("Wrong cell types : mesh is not made of tetrahedra")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Discrétisation du second membre et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
-my_ExactSol = cdmath.Field("EXACT_SOL", cdmath.NODES, my_mesh, 1)
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-       y = Ni.y()
-       z = Ni.z()
-
-       r=sqrt(x*x+y*y+z*z)
-       phi=atan2(y,x)
-       theta=atan2(y,z*sin(phi))
-
-       my_RHSfield[i]=6*r*sin(theta)**2*cos(phi)+3*(r-1)*cos(phi)#mettre la fonction definie au second membre de l'edp
-       my_ExactSol[i]=-(r-1)*r**2*sin(theta)**2*cos(phi)
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               boundaryNodes.append(i)
-               nbBoundaryNodes=nbBoundaryNodes+1
-       else: # Détection des noeuds intérieurs
-               interiorNodes.append(i)
-               nbInteriorNodes=nbInteriorNodes+1
-               maxNbNeighbours= max(1+Ni.getNumberOfEdges(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print("Number of interior nodes=", nbInteriorNodes)
-print("Number of boundary nodes=", nbBoundaryNodes)
-print("Maximum number of neighbours per node=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours) # warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbInteriorNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un hexaèdre
-GradShapeFunc0=cdmath.Vector(3)
-GradShapeFunc1=cdmath.Vector(3)
-GradShapeFunc2=cdmath.Vector(3)
-GradShapeFunc3=cdmath.Vector(3)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-       nodeId3=Ci.getNodeId(3)
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-       N3=my_mesh.getNode(nodeId3)
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= (N2.y()*N3.z()-N2.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
-       GradShapeFunc0[1]=-(N2.x()*N3.z()-N2.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
-       GradShapeFunc0[2]=(N2.x()*N3.y()-N2.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
-       GradShapeFunc1[0]=- (N2.y()*N3.z()-N2.z()*N3.y()-N0.y()*N3.z()+N3.y()*N0.z()+N0.y()*N2.z()-N2.y()*N0.z())/6
-       GradShapeFunc1[1]=(N2.x()*N3.z()-N2.z()*N3.x()-N0.x()*N3.z()+N3.x()*N0.z()+N0.x()*N2.z()-N2.x()*N0.z())/6
-       GradShapeFunc1[2]=-(N2.x()*N3.y()-N2.y()*N3.x()-N0.x()*N3.y()+N3.x()*N0.y()+N0.x()*N2.y()-N2.x()*N0.y())/6
-       GradShapeFunc2[0]= -(N0.y()*N3.z()-N0.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N0.z()-N0.y()*N1.z())/6
-       GradShapeFunc2[1]=(N0.x()*N3.z()-N0.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N0.z()-N0.x()*N1.z())/6
-       GradShapeFunc2[2]= -(N0.x()*N3.y()-N0.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N0.y()-N0.x()*N1.y())/6
-       GradShapeFunc3[0]=-(N2.y()*N0.z()-N2.z()*N0.y()-N1.y()*N0.z()+N0.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
-       GradShapeFunc3[1]=(N2.x()*N0.z()-N2.z()*N0.x()-N1.x()*N0.z()+N0.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
-       GradShapeFunc3[2]=-(N2.x()*N0.y()-N2.y()*N0.x()-N1.x()*N0.y()+N0.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
-       
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme)
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-       GradShapeFuncs[nodeId3]=GradShapeFunc3
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2,nodeId3] :
-               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
-                       RHS[j_int]=Ci.getMeasure()/4*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
-                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
-                       for k in [nodeId0,nodeId1,nodeId2,nodeId3] :
-                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#,"ILU" Remplacer CG par CHOLESKY pour solveur direct
-SolSyst=LS.solve()
-print("Preconditioner used : ", LS.getNameOfPc() )
-print("Number of iterations used : ", LS.getNumberOfIter() )
-print("Final residual : ", LS.getResidu() )
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-       my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-
-for j in range(nbBoundaryNodes):
-    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElements3DPoisson_BALL_ResultField")
-
-#Postprocessing :
-#================
-# save 3D picture
-resolution=100
-VTK_routines.Clip_VTK_data_to_VTK("FiniteElements3DPoisson_BALL_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElements3DPoisson_BALL_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
-PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_BALL_ResultField"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_BALL_ResultField")
-
-# extract and plot diagonal values
-curv_abs=np.linspace(0,sqrt(3),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[-0.577,-0.577,-0.577],[0.577,0.577,0.577], resolution)
-plt.plot(curv_abs, diag_data, label= str(nbNodes) + ' nodes 3D mesh')
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 3D ball tetrahedral mesh')
-plt.savefig("FiniteElements3DPoisson_BALL_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 3D Poisson equation on a 3D ball using finite elements done")
-
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbNodes) :
-    if erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
-        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/CMakeLists.txt
deleted file mode 100755 (executable)
index f628489..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ./Mesh_RadiatorAndWindow.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DEF_RadiatorAndWindow)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_3DEF_CUBE_RadiatorAndWindow ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py b/CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py
deleted file mode 100755 (executable)
index f58010b..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Laplace 3D -\Delta T = 0 avec conditions aux limites de Dirichlet u non nulle
-# Authors     : Michaël Ndjinga, Sédrick Kameni Ngwamou
-# Copyright   : CEA Saclay 2019
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u discrétisés aux noeuds d'un maillage tétraédrique
-#               Condition limites correspondant au refroidissement dû à une fenêtre et au chauffage dû à un radiateur
-#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#================================================================================================================================
-
-import cdmath
-import numpy as np
-
-# Fonction qui remplace successivement les colonnes d'une matrices par un vecteur donné et retourne la liste des déterminants
-def gradientNodal(M, values):
-       matrices=[0]*(len(values)-1)
-       for i in range(len(values)-1):
-               matrices[i] = M.deepCopy()        
-               for j in range(len(values)):
-                       matrices[i][j,i] = values[j]
-
-       result = cdmath.Vector(len(values)-1)    
-       for i in range(len(values)-1):
-               result[i] = matrices[i].determinant()
-
-       return result
-
-# Fonction qui calcule la valeur de la condition limite en un noeud donné
-def boundaryValue(nodeId): 
-       Ni=my_mesh.getNode(nodeId)
-
-       # 4 groupes sont considérés sur le bord
-       if boundaryNodes.count(nodeId)==0:
-               return 0
-       elif Ni.getGroupName()=='Fenetre':
-               return Tfenetre;
-       elif Ni.getGroupName()=='Radiateur_sous-fenetre':
-               return Tradiateur
-       #elif Ni.getGroupName()=='Radiateur_Devant':
-               #return Tradiateur;
-       #elif Ni.getGroupName()=='Radiateur_droit':
-               #return Tradiateur
-       else:   
-               return Tmur;
-
-#Chargement du maillage tétraédrique du domaine
-#==============================================
-my_mesh = cdmath.Mesh("Mesh_RadiatorAndWindow.med")
-if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
-if(not my_mesh.isTetrahedral()) :
-       raise ValueError("Wrong cell types : mesh is not made of tetrahedra")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("nb of nodes=", nbNodes)
-print("nb of cells=", nbCells)
-
-#Conditions limites
-Tmur=20
-Tfenetre=0
-Tradiateur=40
-
-#Détermination des noeuds intérieurs
-#======================================================================
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes = []
-boundaryNodes = []
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-    
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière getGroupName my_mesh.getNode(i)
-               boundaryNodes.append(i)
-       else: # Détection des noeuds intérieurs
-               interiorNodes.append(i)
-               maxNbNeighbours= max(1+Ni.getNumberOfEdges(),maxNbNeighbours) 
-
-nbInteriorNodes=len(interiorNodes)
-nbBoundaryNodes=len(boundaryNodes)
-
-
-print("nb of interior nodes=", nbInteriorNodes)
-print("nb of Boundary nodes=", nbBoundaryNodes)
-print("Max nb of neighbours=", maxNbNeighbours)
-
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)
-RHS=cdmath.Vector(nbInteriorNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un tétrèdre (hypothèse 3D)
-M=cdmath.Matrix(4,4)
-GradShapeFunc0=cdmath.Vector(3)
-GradShapeFunc1=cdmath.Vector(3)
-GradShapeFunc2=cdmath.Vector(3)
-GradShapeFunc3=cdmath.Vector(3)
-
-#On parcourt les tétraèdres du domaine pour remplir la matrice
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Extraction des noeuds de la cellule
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-       nodeId3=Ci.getNodeId(3)
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-       N3=my_mesh.getNode(nodeId3)
-
-       M[0,0]=N0.x()
-       M[0,1]=N0.y()
-       M[0,2]=N0.z()
-       M[0,3]=1
-       M[1,0]=N1.x()
-       M[1,1]=N1.y()
-       M[1,2]=N1.z()
-       M[1,3]=1
-       M[2,0]=N2.x()
-       M[2,1]=N2.y()
-       M[2,2]=N2.z()
-       M[2,3]=1
-       M[3,0]=N3.x()
-       M[3,1]=N3.y()
-       M[3,2]=N3.z()
-       M[3,3]=1
-
-       #Values of each shape function at each node
-       values0=[1,0,0,0]
-       values1=[0,1,0,0]
-       values2=[0,0,1,0]
-       values3=[0,0,0,1]
-
-       GradShapeFunc0 = gradientNodal(M,values0)*(1./6)
-       GradShapeFunc1 = gradientNodal(M,values1)*(1./6)
-       GradShapeFunc2 = gradientNodal(M,values2)*(1./6)
-       GradShapeFunc3 = gradientNodal(M,values3)*(1./6)
-       
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme)
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-       GradShapeFuncs[nodeId3]=GradShapeFunc3
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2,nodeId3] : 
-               if boundaryNodes.count(j)==0: #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-                       boundaryContributionAdded=False#Needed in case j is a border cell
-                       #Ajout de la contribution de la cellule ttétraédrique i au second membre du noeud j 
-                       for k in [nodeId0,nodeId1,nodeId2,nodeId3] : 
-                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                                       k_int = interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                               elif boundaryContributionAdded == False: #si condition limite non nulle au bord (ou maillage non recouvrant), ajouter la contribution du bord au second membre de la cellule j
-                                       # Valeurs de g_h aux noeuds du tétraèdre
-                                       T0 = boundaryValue(nodeId0)
-                                       T1 = boundaryValue(nodeId1)
-                                       T2 = boundaryValue(nodeId2)
-                                       T3 = boundaryValue(nodeId3)
-                                       boundaryContributionAdded=True#Contribution from the boundary to matrix line j is done in one step
-                                       GradGh = gradientNodal(M,[T0,T1,T2,T3])*(1./6)
-                                       RHS[j_int] += -(GradGh*GradShapeFuncs[j])/Ci.getMeasure()
-            
-
-    
-print("Linear system matrix building done")
-
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#,"ILU" Remplacer CG par CHOLESKY pour solveur direct
-
-SolSyst=LS.solve()
-
-# Création du champ résultat
-#===========================
-my_Temperature = cdmath.Field("Temperature", cdmath.NODES, my_mesh, 1)
-for j in range(nbInteriorNodes):
-       my_Temperature[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs SolSyst[j]
-#Remplissage des valeurs pour les noeuds frontière (condition limite)
-for j in boundaryNodes:
-    my_Temperature[j]=boundaryValue(j)
-
-
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_Temperature.writeVTK("FiniteElements3DTemperature")
-
-print( "Minimum temperature= ", my_Temperature.min(), ", maximum temperature= ", my_Temperature.max() )
-assert my_Temperature.min()>= min(Tmur,Tfenetre,Tradiateur) and my_Temperature.max()<= max(Tmur,Tfenetre,Tradiateur)
-
-print( "Numerical solution of 3D Laplace equation using finite elements done" )
-
diff --git a/CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med b/CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med
deleted file mode 100644 (file)
index c22aec1..0000000
Binary files a/CDMATH/tests/examples/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med and /dev/null differ
diff --git a/CDMATH/tests/examples/Poisson3DSphereEF/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DSphereEF/CMakeLists.txt
deleted file mode 100755 (executable)
index 1d8b478..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/meshSphere.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DSphereEF)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoissonBeltrami_3DFE_SPHERE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoissonSphere.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DSphereEF/FiniteElements3DPoissonSphere.py b/CDMATH/tests/examples/Poisson3DSphereEF/FiniteElements3DPoissonSphere.py
deleted file mode 100755 (executable)
index 9d07572..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Laplace-Beltrami -\triangle u = f sur une sphere 
-# Author      : Michael Ndjinga
-# Copyright   : CEA Saclay 2017
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
-#               Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Référence : M. A. Olshanskii, A. Reusken, and J. Grande. A finite element method for elliptic equations
-#                           on surfaces. SIAM J. Num. Anal., 47, p. 3355
-#               Solution exacte = f/12 : il s'agit d'un vecteur propre du laplacien sur la sphère
-#               Résolution d'un système linéaire à matrice singulière : les vecteurs constants sont dans le noyau
-#================================================================================================================================
-
-import cdmath
-from math import pow
-import numpy as np
-import PV_routines
-import VTK_routines
-import paraview.simple as pvs
-
-#Chargement du maillage triangulaire de la sphère
-#=======================================================================================
-my_mesh = cdmath.Mesh("meshSphere.med")
-if(not my_mesh.isTriangular()) :
-       raise ValueError("Wrong cell types : mesh is not made of triangles")
-if(my_mesh.getMeshDimension()!=2) :
-       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
-if(my_mesh.getSpaceDimension()!=3) :
-       raise ValueError("Wrong space dimension : expected a space of dimension 3")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh building/loading done")
-print("nb of nodes=", nbNodes)
-print("nb of cells=", nbCells)
-
-#Discrétisation du second membre et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS field", cdmath.NODES, my_mesh, 1)
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-
-#parcours des noeuds pour discrétisation du second membre et extraction du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-       y = Ni.y()
-       z = Ni.z()
-
-       my_RHSfield[i]=12*y*(3*x*x-y*y)/pow(x*x+y*y+z*z,3/2)#vecteur propre du laplacien sur la sphère
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               raise ValueError("Mesh should not contain borders")
-       else:
-               maxNbNeighbours = max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only for planar cells, otherwise use function Ni.getNumberOfEdges()
-
-print("Right hand side discretisation done")
-print("Max nb of neighbours=", maxNbNeighbours)
-print("Integral of the RHS", my_RHSfield.integral(0))
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)# warning : third argument is number of non zero coefficients per line
-RHS=cdmath.Vector(nbNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
-GradShapeFunc0=cdmath.Vector(3)
-GradShapeFunc1=cdmath.Vector(3)
-GradShapeFunc2=cdmath.Vector(3)
-
-normalFace0=cdmath.Vector(3)
-normalFace1=cdmath.Vector(3)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-
-       #Build normal to cell Ci
-       normalFace0[0]=Ci.getNormalVector(0,0)
-       normalFace0[1]=Ci.getNormalVector(0,1)
-       normalFace0[2]=Ci.getNormalVector(0,2)
-       normalFace1[0]=Ci.getNormalVector(1,0)
-       normalFace1[1]=Ci.getNormalVector(1,1)
-       normalFace1[2]=Ci.getNormalVector(1,2)
-
-       normalCell = normalFace0.crossProduct(normalFace1)
-       normalCell = normalCell*(1/normalCell.norm())
-
-       cellMat=cdmath.Matrix(4)
-       cellMat[0,0]=N0.x()
-       cellMat[0,1]=N0.y()
-       cellMat[0,2]=N0.z()
-       cellMat[1,0]=N1.x()
-       cellMat[1,1]=N1.y()
-       cellMat[1,2]=N1.z()
-       cellMat[2,0]=N2.x()
-       cellMat[2,1]=N2.y()
-       cellMat[2,2]=N2.z()
-       cellMat[3,0]=normalCell[0]
-       cellMat[3,1]=normalCell[1]
-       cellMat[3,2]=normalCell[2]
-       cellMat[0,3]=1
-       cellMat[1,3]=1
-       cellMat[2,3]=1
-       cellMat[3,3]=0
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
-       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
-       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
-       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
-       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
-       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
-       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
-       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
-       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2] : 
-               #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
-               RHS[j]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j] # intégrale dans le triangle du produit f x fonction de base
-               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
-               for k in [nodeId0,nodeId1,nodeId2] : 
-                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-
-print("Linear system matrix building done")
-
-# Conditionnement de la matrice de rigidité
-#=================================
-cond = Rigidite.getConditionNumber(True)
-print("Condition number is ",cond)
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")
-LS.setMatrixIsSingular()#En raison de l'absence de bord
-SolSyst=LS.solve()
-print("Preconditioner used : ", LS.getNameOfPc() )
-print("Number of iterations used : ", LS.getNumberOfIter() )
-print("Final residual : ", LS.getResidu() )
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
-for j in range(nbNodes):
-    my_ResultField[j]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElementsOnSpherePoisson")
-
-print("Integral of the numerical solution", my_ResultField.integral(0))
-print("Numerical solution of Poisson equation on a sphere using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal the right hand side divided by 12
-max_abs_sol_exacte=0
-erreur_abs=0
-max_sol_num=0
-min_sol_num=0
-for i in range(nbNodes) :
-    if max_abs_sol_exacte < abs(my_RHSfield[i]) :
-        max_abs_sol_exacte = abs(my_RHSfield[i])
-    if erreur_abs < abs(my_RHSfield[i]/12 - my_ResultField[i]) :
-        erreur_abs = abs(my_RHSfield[i]/12 - my_ResultField[i])
-    if max_sol_num < my_ResultField[i] :
-        max_sol_num = my_ResultField[i]
-    if min_sol_num > my_ResultField[i] :
-        min_sol_num = my_ResultField[i]
-max_abs_sol_exacte = max_abs_sol_exacte/12
-
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", my_RHSfield.max()/12, " Minimum exact solution = ", my_RHSfield.min()/12 )
-
-#Postprocessing :
-#================
-# save 3D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElementsOnSpherePoisson"+'_0.vtu',"ResultField",'NODES',"FiniteElementsOnSpherePoisson")
-resolution=100
-VTK_routines.Clip_VTK_data_to_VTK("FiniteElementsOnSpherePoisson"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElementsOnSpherePoisson"+'_0.vtu',[0.25,0.25,0.25], [-0.5,-0.5,-0.5],resolution )
-PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElementsOnSpherePoisson"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElementsOnSpherePoisson")
-
-# Plot  over slice circle
-finiteElementsOnSphere_0vtu = pvs.XMLUnstructuredGridReader(FileName=["FiniteElementsOnSpherePoisson"+'_0.vtu'])
-slice1 = pvs.Slice(Input=finiteElementsOnSphere_0vtu)
-slice1.SliceType.Normal = [0.5, 0.5, 0.5]
-renderView1 = pvs.GetActiveViewOrCreate('RenderView')
-finiteElementsOnSphere_0vtuDisplay = pvs.Show(finiteElementsOnSphere_0vtu, renderView1)
-pvs.ColorBy(finiteElementsOnSphere_0vtuDisplay, ('POINTS', 'ResultField'))
-slice1Display = pvs.Show(slice1, renderView1)
-pvs.SaveScreenshot("./FiniteElementsOnSpherePoisson"+"_Slice"+'.png', magnification=1, quality=100, view=renderView1)
-plotOnSortedLines1 = pvs.PlotOnSortedLines(Input=slice1)
-lineChartView2 = pvs.CreateView('XYChartView')
-plotOnSortedLines1Display = pvs.Show(plotOnSortedLines1, lineChartView2)
-plotOnSortedLines1Display.UseIndexForXAxis = 0
-plotOnSortedLines1Display.XArrayName = 'arc_length'
-plotOnSortedLines1Display.SeriesVisibility = ['ResultField (1)']
-pvs.SaveScreenshot("./FiniteElementsOnSpherePoisson"+"_PlotOnSortedLine_"+'.png', magnification=1, quality=100, view=lineChartView2)
-pvs.Delete(lineChartView2)
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson3DTorusEF/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DTorusEF/CMakeLists.txt
deleted file mode 100755 (executable)
index 7da0838..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/meshTorus.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DTorusEF)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoissonBeltrami_3DFE_TORUS ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoissonTorus.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DTorusEF/FiniteElements3DPoissonTorus.py b/CDMATH/tests/examples/Poisson3DTorusEF/FiniteElements3DPoissonTorus.py
deleted file mode 100755 (executable)
index 6de976e..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution EF de l'équation de Laplace-Beltrami -\triangle u = f sur un tore
-# Author      : Michael Ndjinga
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
-#               Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
-#               Référence : M. A. Olshanskii, A. Reusken, and J. Grande. A finite element method for elliptic equations
-#                           on surfaces. SIAM J. Num. Anal., 47, p. 3355
-#               Résolution d'un système linéaire à matrice singulière : les vecteurs constants sont dans le noyau
-#================================================================================================================================
-
-import cdmath
-from math import sin, cos, atan2, sqrt
-import PV_routines
-import VTK_routines
-import paraview.simple as pvs
-
-#Chargement du maillage triangulaire du tore
-#=======================================================================================
-my_mesh = cdmath.Mesh("meshTorus.med")
-if(not my_mesh.isTriangular()) :
-       raise ValueError("Wrong cell types : mesh is not made of triangles")
-if(my_mesh.getMeshDimension()!=2) :
-       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
-if(my_mesh.getSpaceDimension()!=3) :
-       raise ValueError("Wrong space dimension : expected a space of dimension 3")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh building/loading done")
-print("nb of nodes=", nbNodes)
-print("nb of cells=", nbCells)
-
-# Torus radii (calculation  will fail if the mesh is not correct)
-R=1 #Grand rayon
-r=0.6 #Petit rayon
-
-#Discrétisation du second membre, de la solution exacte et détermination des noeuds intérieurs
-#======================================================================
-my_RHSfield = cdmath.Field("RHS field", cdmath.NODES, my_mesh, 1)
-exactSolField = cdmath.Field("Exact solution field", cdmath.NODES, my_mesh, 1)
-
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-
-#parcours des noeuds pour discrétisation du second membre et extraction du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       x = Ni.x()
-       y = Ni.y()
-       z = Ni.z()
-      
-       theta=atan2(z,sqrt(x*x+y*y)-R)
-       phi=atan2(y,x)
-
-       exactSolField[i] = sin(3*phi)*cos(3*theta+ phi) # for the exact solution we use the funtion given in the article of Olshanskii, Reusken 2009, page 19
-       my_RHSfield[i] = 9*sin(3*phi)*cos(3*theta+ phi)/(r*r) + (10*sin(3*phi)*cos(3*theta+ phi) + 6*cos(3*phi)*sin(3*theta+ phi))/((R+r*cos(theta))*(R+r*cos(theta))) - 3*sin(theta)*sin(3*phi)*sin(3*theta+ phi)/(r*(R+r*cos(theta))) #for the right hand side we use the function given in the article of Olshanskii, Reusken 2009, page 19
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               raise ValueError("Mesh should not contain borders")
-       else:
-               maxNbNeighbours = max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only for planar cells, otherwise use function Ni.getNumberOfEdges()
-
-print("Right hand side discretisation done")
-print("Max nb of neighbours=", maxNbNeighbours)
-print("Integral of the RHS", my_RHSfield.integral(0))
-
-# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
-#=======================================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)
-RHS=cdmath.Vector(nbNodes)
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
-GradShapeFunc0=cdmath.Vector(3)
-GradShapeFunc1=cdmath.Vector(3)
-GradShapeFunc2=cdmath.Vector(3)
-
-normalFace0=cdmath.Vector(3)
-normalFace1=cdmath.Vector(3)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-
-       #Build normal to cell Ci
-       normalFace0[0]=Ci.getNormalVector(0,0)
-       normalFace0[1]=Ci.getNormalVector(0,1)
-       normalFace0[2]=Ci.getNormalVector(0,2)
-       normalFace1[0]=Ci.getNormalVector(1,0)
-       normalFace1[1]=Ci.getNormalVector(1,1)
-       normalFace1[2]=Ci.getNormalVector(1,2)
-
-       normalCell = normalFace0.crossProduct(normalFace1)
-       normalCell = normalCell*(1/normalCell.norm())
-
-       cellMat=cdmath.Matrix(4)
-       cellMat[0,0]=N0.x()
-       cellMat[0,1]=N0.y()
-       cellMat[0,2]=N0.z()
-       cellMat[1,0]=N1.x()
-       cellMat[1,1]=N1.y()
-       cellMat[1,2]=N1.z()
-       cellMat[2,0]=N2.x()
-       cellMat[2,1]=N2.y()
-       cellMat[2,2]=N2.z()
-       cellMat[3,0]=normalCell[0]
-       cellMat[3,1]=normalCell[1]
-       cellMat[3,2]=normalCell[2]
-       cellMat[0,3]=1
-       cellMat[1,3]=1
-       cellMat[2,3]=1
-       cellMat[3,3]=0
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
-       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
-       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
-       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
-       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
-       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
-       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
-       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
-       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2] : 
-               #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
-               RHS[j]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j] # intégrale dans le triangle du produit f x fonction de base
-               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
-               for k in [nodeId0,nodeId1,nodeId2] : 
-                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-
-print("Linear system matrix building done")
-
-# Conditionnement de la matrice de rigidité
-#=================================
-cond = Rigidite.getConditionNumber(True)
-print("Condition number is ",cond)
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")#Remplacer CG par CHOLESKY pour solveur direct
-LS.setMatrixIsSingular()#En raison de l'absence de bord
-SolSyst=LS.solve()
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("Numerical result field", cdmath.NODES, my_mesh, 1)
-for j in range(nbNodes):
-    my_ResultField[j]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteElementsOnTorusPoisson")
-
-print("Integral of the numerical solution", my_ResultField.integral(0))
-print("Numerical solution of Poisson equation on a torus using finite elements done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-max_sol_exacte=exactSolField.normMax()[0]
-erreur_max=(exactSolField - my_ResultField).normMax()[0]
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-
-print("Relative error =  max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_max/max_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-print("Maximum exact solution = ", exactSolField.max(), " Minimum exact solution = ", exactSolField.min())
-
-#Postprocessing : 
-#================
-# Save 3D picture
-PV_routines.Save_PV_data_to_picture_file("FiniteElementsOnTorusPoisson"+'_0.vtu',"Numerical result field",'NODES',"FiniteElementsOnTorusPoisson")
-resolution=100
-VTK_routines.Clip_VTK_data_to_VTK("FiniteElementsOnTorusPoisson"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElementsOnTorusPoisson"+'_0.vtu',[0.25,0.25,0.25], [-0.5,-0.5,-0.5],resolution )
-PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElementsOnTorusPoisson"+'_0.vtu',"Numerical result field",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElementsOnTorusPoisson")
-
-# Plot  over slice circle
-finiteElementsOnTorus_0vtu = pvs.XMLUnstructuredGridReader(FileName=["FiniteElementsOnTorusPoisson"+'_0.vtu'])
-slice1 = pvs.Slice(Input=finiteElementsOnTorus_0vtu)
-slice1.SliceType.Normal = [0.5, 0.5, 0.5]
-renderView1 = pvs.GetActiveViewOrCreate('RenderView')
-finiteElementsOnTorus_0vtuDisplay = pvs.Show(finiteElementsOnTorus_0vtu, renderView1)
-pvs.ColorBy(finiteElementsOnTorus_0vtuDisplay, ('POINTS', 'Numerical result field'))
-slice1Display = pvs.Show(slice1, renderView1)
-pvs.SaveScreenshot("./FiniteElementsOnTorusPoisson"+"_Slice"+'.png', magnification=1, quality=100, view=renderView1)
-plotOnSortedLines1 = pvs.PlotOnSortedLines(Input=slice1)
-lineChartView2 = pvs.CreateView('XYChartView')
-plotOnSortedLines1Display = pvs.Show(plotOnSortedLines1, lineChartView2)
-plotOnSortedLines1Display.UseIndexForXAxis = 0
-plotOnSortedLines1Display.XArrayName = 'arc_length'
-plotOnSortedLines1Display.SeriesVisibility = ['Numerical result field (1)']
-pvs.SaveScreenshot("./FiniteElementsOnTorusPoisson"+"_PlotOnSortedLine_"+'.png', magnification=1, quality=100, view=lineChartView2)
-pvs.Delete(lineChartView2)
-
-assert erreur_max/max_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson3DVF/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DVF/CMakeLists.txt
deleted file mode 100755 (executable)
index 25bb884..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_3DVF_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
-
-    SET(MESH_FILE  ../../ressources/meshCube.med  )
-
-    ADD_TEST(ExamplePoisson_3DVF_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
-
-    SET(MESH_FILE  ../../ressources/cubeWithLocRefCubes.med  )
-
-    ADD_TEST(ExamplePoisson_3DVF_CUBE_loc_ref ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
-
-    SET(MESH_FILE  ../../ressources/3DCheckerboard/checkerboard_4x4x4.med  )
-
-    ADD_TEST(ExamplePoisson_3DVF_CUBE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DVF/FiniteVolumes3DPoisson_CUBE.py b/CDMATH/tests/examples/Poisson3DVF/FiniteVolumes3DPoisson_CUBE.py
deleted file mode 100755 (executable)
index 066d1ff..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur unu cube avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2016
-# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
-#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)*sin(pi*z)
-#================================================================================================================================
-
-import cdmath
-from math import sin, pi, sqrt
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-import sys
-
-if len(sys.argv) >1 :#non rectangular mesh
-    my_mesh = cdmath.Mesh(sys.argv[1])
-else :   #rectangular mesh
-# Maillage du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
-#====================================================================================
-    xmin=0
-    xmax=1
-    ymin=0
-    ymax=1
-    zmin=0 
-    zmax=1
-    
-    nx=21
-    ny=21
-    nz=21
-    
-    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny,zmin,zmax,nz)
-
-if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
-
-eps=1e-6
-my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
-my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
-my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
-my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
-my_mesh.setGroupAtPlan(0,2,eps,"DirichletBorder")#Bord AVANT 
-my_mesh.setGroupAtPlan(1,2,eps,"DirichletBorder")#Bord ARRIERE 
-
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of cells ", nbCells)
-
-#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
-#================================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
-maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
-for i in range(nbCells): 
-       Ci = my_mesh.getCell(i)
-       x = Ci.x()
-       y = Ci.y()
-       z = Ci.z() 
-       my_RHSfield[i]=3*pi*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)#mettre la fonction definie au second membre de l edp
-       # compute maximum number of neighbours
-       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print("Maximum number of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice et du vecteur second membre du système linéaire
-#===========================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbCells)
-#Parcours des cellules du domaine
-for i in range(nbCells):
-       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
-       Ci=my_mesh.getCell(i)
-       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
-               Fj=my_mesh.getFace(Ci.getFaceId(j))
-               if not Fj.isBorder():
-                       k=Fj.getCellId(0)
-                       if k==i :
-                               k=Fj.getCellId(1)
-                       Ck=my_mesh.getCell(k)
-                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
-                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
-               else:
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
-               Rigidite.addValue(i,i,coeff) # terme diagonal
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
-SolSyst=LS.solve()
-
-print("Preconditioner used : ", LS.getNameOfPc())
-print("Number of iterations used : ", LS.getNumberOfIter())
-print("Final residual : ", LS.getResidu())
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
-for i in range(nbCells):
-    my_ResultField[i]=SolSyst[i];
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteVolumes3DPoisson_CUBE_ResultField")
-
-#Postprocessing 
-#==============
-# save 3D picture
-resolution=100
-VTK_routines.Clip_VTK_data_to_VTK("FiniteVolumes3DPoisson_CUBE_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteVolumes3DPoisson_CUBE_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
-PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_CUBE_ResultField"+'_0.vtu',"ResultField",'CELLS',"Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_CUBE_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=np.linspace(0,sqrt(3),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-if len(sys.argv) >1 :
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 3D cube with  mesh '+my_mesh.getName())
-    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
-    plt.savefig("FiniteVolumes3DPoisson_CUBE_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
-else :   
-    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 3D cube with a rectangular grid')
-    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
-    plt.savefig("FiniteVolumes3DPoisson_CUBE_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 3D poisson equation using finite volumes done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-#The following formulas use the fact that the exact solution is equal to the right hand side divided by 3*pi*pi
-max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(3*pi*pi)
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbCells) :
-       if erreur_abs < abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i]) :
-               erreur_abs = abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/Poisson3DVF_BALL/CMakeLists.txt b/CDMATH/tests/examples/Poisson3DVF_BALL/CMakeLists.txt
deleted file mode 100755 (executable)
index e89f81e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-SET(MESH_FILE  ../../ressources/ballWithTetrahedra.med  )
-
-file(COPY ${MESH_FILE} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExamplePoisson_3DVF_BALL_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_BALL.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/Poisson3DVF_BALL/FiniteVolumes3DPoisson_BALL.py b/CDMATH/tests/examples/Poisson3DVF_BALL/FiniteVolumes3DPoisson_BALL.py
deleted file mode 100755 (executable)
index 2c32135..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur la boule unité  avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
-#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
-#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)**2*cos(phi)
-#================================================================================================================================
-
-import cdmath
-from math import sin, cos, pi, sqrt, atan2
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import PV_routines
-import VTK_routines
-
-import sys
-
-#Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
-#==============================================================================================
-my_mesh = cdmath.Mesh("ballWithTetrahedra.med")
-if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
-
-eps=1e-6
-my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
-my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
-my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
-my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
-my_mesh.setGroupAtPlan(0,2,eps,"DirichletBorder")#Bord AVANT 
-my_mesh.setGroupAtPlan(1,2,eps,"DirichletBorder")#Bord ARRIERE 
-
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of cells ", nbCells)
-
-#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
-#================================================================================
-my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
-my_ExactSol = cdmath.Field("EXACT_SOL", cdmath.CELLS, my_mesh, 1)
-
-maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
-for i in range(nbCells): 
-       Ci = my_mesh.getCell(i)
-       x = Ci.x()
-       y = Ci.y()
-       z = Ci.z() 
-
-       r=sqrt(x*x+y*y+z*z)
-       phi=atan2(y,x)
-       theta=atan2(y,z*sin(phi))
-
-       my_RHSfield[i]=6*r*sin(theta)**2*cos(phi)+3*(r-1)*cos(phi)#mettre la fonction definie au second membre de l'edp
-       my_ExactSol[i]=-(r-1)*r**2*sin(theta)**2*cos(phi)
-       # compute maximum number of neighbours
-       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
-
-print("Right hand side discretisation done")
-print("Maximum number of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice et du vecteur second membre du système linéaire
-#===========================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-RHS=cdmath.Vector(nbCells)
-#Parcours des cellules du domaine
-for i in range(nbCells):
-       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
-       Ci=my_mesh.getCell(i)
-       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
-               Fj=my_mesh.getFace(Ci.getFaceId(j))
-               if not Fj.isBorder():
-                       k=Fj.getCellId(0)
-                       if k==i :
-                               k=Fj.getCellId(1)
-                       Ck=my_mesh.getCell(k)
-                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
-                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
-               else:
-                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
-               Rigidite.addValue(i,i,coeff) # terme diagonal
-
-print("Linear system matrix building done")
-
-# Résolution du système linéaire
-#=================================
-LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
-SolSyst=LS.solve()
-
-print( "Preconditioner used : ", LS.getNameOfPc() )
-print( "Number of iterations used : ", LS.getNumberOfIter() )
-print( "Final residual : ", LS.getResidu() )
-print("Linear system solved")
-
-# Création du champ résultat
-#===========================
-my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
-for i in range(nbCells):
-    my_ResultField[i]=SolSyst[i];
-#sauvegarde sur le disque dur du résultat dans un fichier paraview
-my_ResultField.writeVTK("FiniteVolumes3DPoisson_BALL_ResultField")
-
-#Postprocessing 
-#==============
-# save 3D picture
-resolution=100
-VTK_routines.Clip_VTK_data_to_VTK("FiniteVolumes3DPoisson_BALL_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteVolumes3DPoisson_BALL_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
-PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_BALL_ResultField"+'_0.vtu',"ResultField",'CELLS',"Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_BALL_ResultField")
-
-# extract and plot diagonal values
-resolution=100
-curv_abs=np.linspace(0,sqrt(3),resolution+1)
-diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
-plt.legend()
-plt.xlabel('Position on diagonal line')
-plt.ylabel('Value on diagonal line')
-if len(sys.argv) >1 :
-    plt.title('Plot over diagonal line for finite volumes \n for Laplace operator on a 3D BALL with  mesh '+my_mesh.getName())
-    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
-    plt.savefig("FiniteVolumes3DPoisson_BALL_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
-else :   
-    plt.title('Plot over diagonal line for finite volumes \n for Laplace operator on a 3D BALL with a rectangular grid')
-    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
-    plt.savefig("FiniteVolumes3DPoisson_BALL_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
-
-print("Numerical solution of 3D poisson equation on a 3D ball using finite volumes done")
-
-#Calcul de l'erreur commise par rapport à la solution exacte
-#===========================================================
-max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
-max_sol_num=my_ResultField.max()
-min_sol_num=my_ResultField.min()
-erreur_abs=0
-for i in range(nbCells) :
-    if erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
-        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
-
-print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
-print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
-print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
-
-assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..21334e7
--- /dev/null
@@ -0,0 +1,30 @@
+file(GLOB PoissonEquation_EXAMPLES_TO_INSTALL 
+  Poisson1DEF Poisson2DEF Poisson2DEF_DISK Poisson2DEF_DISK_StiffBC Poisson2DEF_SQUARE_StiffBC Poisson1DVF Poisson2DVF Poisson2DVF_DISK Poisson2DVF_DISK_StiffBC Poisson3DEF Poisson3DEF_BALL Poisson3DVF Poisson3DVF_BALL Poisson3DEF_RadiatorAndWindow
+  Poisson3DSphereEF Poisson3DTorusEF Poisson3DCubeSkinEF # Laplace-Beltrami on surface
+)
+
+install(DIRECTORY ${PoissonEquation_EXAMPLES_TO_INSTALL} DESTINATION share/examples/PoissonEquation)
+
+IF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_SUBDIRECTORY(Poisson1DVF)
+    ADD_SUBDIRECTORY(Poisson1DEF)
+    ADD_SUBDIRECTORY(Poisson2DVF)
+    ADD_SUBDIRECTORY(Poisson2DVF_DISK)
+    ADD_SUBDIRECTORY(Poisson2DVF_DISK_StiffBC)
+    ADD_SUBDIRECTORY(Poisson2DEF)
+    ADD_SUBDIRECTORY(Poisson2DEF_DISK)
+    ADD_SUBDIRECTORY(Poisson2DEF_DISK_StiffBC)
+    ADD_SUBDIRECTORY(Poisson2DEF_SQUARE_StiffBC)
+    ADD_SUBDIRECTORY(Poisson3DSphereEF)
+    ADD_SUBDIRECTORY(Poisson3DTorusEF)
+    ADD_SUBDIRECTORY(Poisson3DCubeSkinEF)
+    ADD_SUBDIRECTORY(Poisson3DEF)
+    ADD_SUBDIRECTORY(Poisson3DEF_RadiatorAndWindow)
+    ADD_SUBDIRECTORY(Poisson3DEF_BALL)
+    ADD_SUBDIRECTORY(Poisson3DVF)
+    ADD_SUBDIRECTORY(Poisson3DVF_BALL)
+
+ENDIF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson1DEF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson1DEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..5be4ec4
--- /dev/null
@@ -0,0 +1,10 @@
+
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson1DEF)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_1DEF ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements1DPoisson.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson1DEF/FiniteElements1DPoisson.py b/CDMATH/tests/examples/PoissonEquation/Poisson1DEF/FiniteElements1DPoisson.py
new file mode 100755 (executable)
index 0000000..712b614
--- /dev/null
@@ -0,0 +1,164 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Poisson 1D -\triangle u = f avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage 1D quelconque
+#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=-sin(pi*x)
+#================================================================================================================================
+
+import cdmath
+from math import sin, pi, sqrt
+from numpy import linspace
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+#Création d'un maillage uniforme du segment [0,1], définition des bords
+#======================================================================
+nx=100
+my_mesh = cdmath.Mesh(0,1,nx)
+if( my_mesh.getSpaceDimension()!=1 or my_mesh.getMeshDimension()!=1) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 1")
+
+eps=1e-6
+my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
+my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading/building done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Discrétisation du second membre et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+
+       my_RHSfield[i]=pi*pi*sin(pi*x)#mettre la fonction definie au second membre de l'edp
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               boundaryNodes.append(i)
+               nbBoundaryNodes=nbBoundaryNodes+1
+       else: # Détection des noeuds intérieurs
+               interiorNodes.append(i)
+               nbInteriorNodes=nbInteriorNodes+1
+               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print("nb of interior nodes=", nbInteriorNodes)
+print("nb of boundary nodes=", nbBoundaryNodes)
+print("Max nb of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbInteriorNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un segment (hypothèse 1D)
+GradShapeFunc0=cdmath.Vector(1)
+GradShapeFunc1=cdmath.Vector(1)
+
+#On parcourt les segments du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= 1
+       GradShapeFunc1[0]=-1
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1] :
+               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+                       #Ajout de la contribution de la cellule i au second membre du noeud j 
+                       RHS[j_int]=Ci.getMeasure()/2*my_RHSfield[j]+RHS[j_int] # intégrale sur le segment du produit f x fonction de base
+                       #Contribution de la cellule i à la ligne j_int du système linéaire
+                       for k in [nodeId0,nodeId1] : 
+                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+for j in range(nbBoundaryNodes):
+    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElements1DPoisson_ResultField")
+
+# Postprocessing :
+#=================
+# save 1D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElements1DPoisson_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements1DPoisson_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=linspace(0,1,resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,0,0],[1,0,0], resolution)
+plt.plot(curv_abs, diag_data, label= '1D mesh with '+str(nbNodes) + ' nodes')
+plt.legend()
+plt.xlabel('Position')
+plt.ylabel('Value')
+plt.title('1D finite elements \n for Laplace operator')
+plt.savefig("FiniteElements1DPoisson_ResultField_"+str(nbNodes) + '_nodes'+".png")
+
+print("Numerical solution of the 1D Poisson equation using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal the right hand side divided by pi*pi
+max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(pi*pi)
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbNodes) :
+    if erreur_abs < abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i]) :
+        erreur_abs = abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_RHSfield.max()/(pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(pi*pi))
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson1DVF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson1DVF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..2bde45f
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_1DVF_uniform ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes1DPoisson.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson1DVF/FiniteVolumes1DPoisson.py b/CDMATH/tests/examples/PoissonEquation/Poisson1DVF/FiniteVolumes1DPoisson.py
new file mode 100755 (executable)
index 0000000..0f18320
--- /dev/null
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation de Poisson 1D -\triangle u = f avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage 1D quelconque
+#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=-sin(pi*x)
+#================================================================================================================================
+
+import cdmath
+from math import sin, pi
+from numpy import linspace
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+import sys
+
+if len(sys.argv) >1 :#non uniform mesh
+    my_mesh = cdmath.Mesh(sys.argv[1])
+else :   #rectangular mesh
+#Création d'un maillage uniforme du segment [0,1], définition des bords
+#======================================================================
+       nx=100
+       my_mesh = cdmath.Mesh(0,1,nx)
+
+if( my_mesh.getSpaceDimension()!=1 or my_mesh.getMeshDimension()!=1) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 1")
+
+eps=1e-6
+my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
+my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
+
+nbCells = my_mesh.getNumberOfCells()
+
+print( "Mesh loading/building done")
+print( "Number of cells  = ", nbCells)
+
+#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
+#================================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
+maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
+for i in range(nbCells): 
+       Ci = my_mesh.getCell(i)
+       x = Ci.x()
+
+       my_RHSfield[i]=pi*pi*sin(pi*x)#mettre la fonction definie au second membre de l edp
+       # compute maximum number of neighbours
+       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print( "Max nb of neighbours = ", maxNbNeighbours )
+
+# Construction de la matrice et du vecteur second membre du système linéaire
+#===========================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbCells)
+#Parcours des cellules du domaine
+for i in range(nbCells):
+       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
+       Ci=my_mesh.getCell(i)
+       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
+               Fj=my_mesh.getFace(Ci.getFaceId(j))
+               if not Fj.isBorder():
+                       k=Fj.getCellId(0)
+                       if k==i :
+                               k=Fj.getCellId(1)
+                       Ck=my_mesh.getCell(k)
+                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
+                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
+               else:
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
+                       #For the particular case where the mesh boundary does not coincide with the domain boundary
+                       x=Fj.getBarryCenter().x()
+                       RHS[i]+=coeff*sin(pi*x)#mettre ici  la solution exacte de l'edp
+               Rigidite.addValue(i,i,coeff) # terme diagonal
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print( "Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
+for i in range(nbCells):
+    my_ResultField[i]=SolSyst[i];
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteVolumes1DPoisson_ResultField")
+
+#Postprocessing : 
+#===============
+# save 1D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteVolumes1DPoisson_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes1DPoisson_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=linspace(0,1,resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,0,0],[1,0,0], resolution)
+plt.legend()
+plt.xlabel('Position')
+plt.ylabel('Value')
+if len(sys.argv) >1 :
+    plt.title('Finite Volumes \n for Laplace operator in 1D'+my_mesh.getName())
+    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
+    plt.savefig("FiniteVolumes1DPoisson_ResultField_"+str(nbCells)+ '_cells'+".png")
+else :   
+    plt.title('Finite Volumes \n for Laplace operator on a 1D regular grid')
+    plt.plot(curv_abs, diag_data, label= str(nx) + ' cells mesh')
+    plt.savefig("FiniteVolumes1DPoisson_ResultField_"+str(nx) + '_cells'+".png")
+
+print("Numerical solution of 1D Poisson equation using finite volumes done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal the right hand side divided by pi*pi
+max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(pi*pi)
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbCells) :
+    if erreur_abs <  abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i]) :
+        erreur_abs = abs(my_RHSfield[i]/(pi*pi) - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_RHSfield.max()/(pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(pi*pi))
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..4948b54
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/squareWithTriangles.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_2DEF_SQUARE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_SQUARE.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF/FiniteElements2DPoisson_SQUARE.py b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF/FiniteElements2DPoisson_SQUARE.py
new file mode 100755 (executable)
index 0000000..eb28762
--- /dev/null
@@ -0,0 +1,181 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = f avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2016
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
+#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)
+#================================================================================================================================
+
+import cdmath
+from math import sin, pi, sqrt
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+#Chargement du maillage triangulaire du domaine carré [0,1]x[0,1], définition des bords
+#=======================================================================================
+my_mesh = cdmath.Mesh("squareWithTriangles.med")
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+if(not my_mesh.isTriangular()) :
+       raise ValueError("Wrong cell types : mesh is not made of triangles")
+eps=1e-6
+my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
+my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
+my_mesh.setGroupAtPlan(0.,1,eps,"DirichletBorder")#Bord BAS
+my_mesh.setGroupAtPlan(1.,1,eps,"DirichletBorder")#Bord HAUT
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Discrétisation du second membre et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+       y = Ni.y()
+
+       my_RHSfield[i]=2*pi*pi*sin(pi*x)*sin(pi*y)#mettre la fonction definie au second membre de l'edp
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               boundaryNodes.append(i)
+               nbBoundaryNodes=nbBoundaryNodes+1
+       else: # Détection des noeuds intérieurs
+               interiorNodes.append(i)
+               nbInteriorNodes=nbInteriorNodes+1
+               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
+
+print("Right hand side discretisation done")
+print("nb of interior nodes=", nbInteriorNodes)
+print("nb of boundary nodes=", nbBoundaryNodes)
+print("Max nb of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbInteriorNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
+GradShapeFunc0=cdmath.Vector(2)
+GradShapeFunc1=cdmath.Vector(2)
+GradShapeFunc2=cdmath.Vector(2)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= (N1.y()-N2.y())/2
+       GradShapeFunc0[1]=-(N1.x()-N2.x())/2
+       GradShapeFunc1[0]=-(N0.y()-N2.y())/2
+       GradShapeFunc1[1]= (N0.x()-N2.x())/2
+       GradShapeFunc2[0]= (N0.y()-N1.y())/2
+       GradShapeFunc2[1]=-(N0.x()-N1.x())/2
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2] :
+               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
+                       RHS[j_int]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
+                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
+                       for k in [nodeId0,nodeId1,nodeId2] : 
+                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
+
+print("Linear system matrix building done")
+
+# Conditionnement de la matrice de rigidité
+#=================================
+cond = Rigidite.getConditionNumber()
+print("Condition number is ",cond)
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
+SolSyst=LS.solve()
+
+print("Preconditioner used : ", LS.getNameOfPc())
+print("Number of iterations used : ", LS.getNumberOfIter())
+print("Final residual : ", LS.getResidu())
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+for j in range(nbBoundaryNodes):
+    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElements2DPoisson_SQUARE_ResultField")
+
+# Postprocessing :
+#=================
+# save 2D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoisson_SQUARE_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoisson_SQUARE_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=np.linspace(0,sqrt(2),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
+plt.plot(curv_abs, diag_data, label= '2D mesh with '+str(nbNodes) + ' nodes')
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D square with triangular mesh')
+plt.savefig("FiniteElements2DPoisson_SQUARE_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 2D Poisson equation on a square using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal the right hand side divided by 2*pi*pi
+max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(2*pi*pi)
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbNodes) :
+    if erreur_abs < abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i]) :
+        erreur_abs = abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_RHSfield.max()/(2*pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(2*pi*pi) )
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..e9da83e
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/diskWithTriangles.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF_DISK)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_2DEF_DISK ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_DISK.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK/FiniteElements2DPoisson_DISK.py b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK/FiniteElements2DPoisson_DISK.py
new file mode 100755 (executable)
index 0000000..d133bdf
--- /dev/null
@@ -0,0 +1,176 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = f sur le disque unité avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
+#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)
+#================================================================================================================================
+
+import cdmath
+from math import sin, sqrt, atan2
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+#Chargement du maillage triangulaire du disque unité
+#=======================================================================================
+my_mesh = cdmath.Mesh("diskWithTriangles.med")
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+if(not my_mesh.isTriangular()) :
+       raise ValueError("Wrong cell types : mesh is not made of triangles")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Discrétisation du second membre et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
+my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1)
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+       y = Ni.y()
+
+       r=sqrt(x*x+y*y)
+       theta=atan2(y,x)
+
+       my_RHSfield[i]=(8*r-3)*sin(theta)#mettre la fonction definie au second membre de l'edp
+       my_ExactSol[i]=-(r-1)*r*r*sin(theta)#mettre la solution exacte de l'edp
+    
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               boundaryNodes.append(i)
+               nbBoundaryNodes=nbBoundaryNodes+1
+       else: # Détection des noeuds intérieurs
+               interiorNodes.append(i)
+               nbInteriorNodes=nbInteriorNodes+1
+               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
+
+print("Right hand side discretisation done")
+print("Number of interior nodes=", nbInteriorNodes)
+print("Number of boundary nodes=", nbBoundaryNodes)
+print("Maximum number of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbInteriorNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
+GradShapeFunc0=cdmath.Vector(2)
+GradShapeFunc1=cdmath.Vector(2)
+GradShapeFunc2=cdmath.Vector(2)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= (N1.y()-N2.y())/2
+       GradShapeFunc0[1]=-(N1.x()-N2.x())/2
+       GradShapeFunc1[0]=-(N0.y()-N2.y())/2
+       GradShapeFunc1[1]= (N0.x()-N2.x())/2
+       GradShapeFunc2[0]= (N0.y()-N1.y())/2
+       GradShapeFunc2[1]=-(N0.x()-N1.x())/2
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2] :
+               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
+                       RHS[j_int]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
+                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
+                       for k in [nodeId0,nodeId1,nodeId2] : 
+                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+for j in range(nbBoundaryNodes):
+    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElements2DPoisson_DISK_ResultField")
+
+# Postprocessing :
+#=================
+# save 2D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoisson_DISK_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoisson_DISK_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=np.linspace(-1,1,resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[-0.5,-0.5,0],[0.5,0.5,0], resolution)
+plt.plot(curv_abs, diag_data, label= '2D disk mesh with '+str(nbNodes) + ' nodes')
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D disk triangular mesh')
+plt.savefig("FiniteElements2DPoisson_DISK_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 2D Poisson equation on a disk using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbNodes) :
+    if  erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
+        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min() )
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK_StiffBC/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK_StiffBC/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..b9ca72d
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/diskWithTriangles.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF_DISK_StiffBC)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_2DEF_DISK_StiffBC ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_DISK_StiffBC.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK_StiffBC/FiniteElements2DPoisson_DISK_StiffBC.py b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_DISK_StiffBC/FiniteElements2DPoisson_DISK_StiffBC.py
new file mode 100755 (executable)
index 0000000..f160ce6
--- /dev/null
@@ -0,0 +1,224 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = 0 sur le disque unité avec conditions aux limites de Dirichlet discontinues
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
+#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=atan(2*x/(x**2+y**2-1))=atan(2 r cos(theta)/(r*2-1))
+#================================================================================================================================
+
+import cdmath
+from math import atan, pi
+from numpy import sign, linspace
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+# Fonction qui remplace successivement les colonnes d'une matrices par un vecteur donné et retourne la liste des déterminants
+def gradientNodal(M, values):
+    matrices=[0]*(len(values)-1)
+    for i in range(len(values)-1):
+        matrices[i] = M.deepCopy()        
+        for j in range(len(values)):
+            matrices[i][j,i] = values[j]
+
+    result = cdmath.Vector(len(values)-1)    
+    for i in range(len(values)-1):
+        result[i] = matrices[i].determinant()
+
+    return result
+
+
+#Chargement du maillage triangulaire du disque unité
+#=======================================================================================
+meshName="diskWithTriangles"
+my_mesh = cdmath.Mesh(meshName+".med")
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+if(not my_mesh.isTriangular()) :
+    raise ValueError("Wrong cell types : mesh is not made of triangles")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Détermination des noeuds intérieurs
+#======================================================================
+my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1)
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+eps=1e-10
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+    Ni=my_mesh.getNode(i)
+    x = Ni.x()
+    y = Ni.y()
+
+    #Robust calculation of atan(2x/(x**2+y**2-1)
+    #my_ExactSol[i]=atan2(2*x*sign(x**2+y**2-1),abs(x**2+y**2-1))#mettre la solution exacte de l'edp
+    if x**2+y**2-1 > eps :
+        print("!!! Warning Mesh ", meshName," !!! Node is not in the unit disk.",", eps=",eps, ", x**2+y**2-1=",x**2+y**2 - 1)
+        #raise ValueError("x**2+y**2 > 1 !!! Domain should be the unit disk.")
+    if x**2+y**2-1 < -eps :
+        my_ExactSol[i] = atan(2*x/(x**2+y**2-1))
+    elif x>0 : #x**2+y**2-1>=0
+        my_ExactSol[i] = -pi/2
+    elif x<0 : #x**2+y**2-1>=0
+        my_ExactSol[i] =  pi/2
+    else : #x=0
+        my_ExactSol[i] = 0
+        
+    if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+        boundaryNodes.append(i)
+        nbBoundaryNodes=nbBoundaryNodes+1
+    else: # Détection des noeuds intérieurs
+        interiorNodes.append(i)
+        nbInteriorNodes=nbInteriorNodes+1
+        maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
+
+print("Right hand side discretisation done")
+print("Number of interior nodes=", nbInteriorNodes)
+print("Number of boundary nodes=", nbBoundaryNodes)
+print("Maximum number of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbInteriorNodes)
+
+M=cdmath.Matrix(3,3)
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
+GradShapeFunc0=cdmath.Vector(2)
+GradShapeFunc1=cdmath.Vector(2)
+GradShapeFunc2=cdmath.Vector(2)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+    Ci=my_mesh.getCell(i)
+
+    #Contribution à la matrice de rigidité
+    nodeId0=Ci.getNodeId(0)
+    nodeId1=Ci.getNodeId(1)
+    nodeId2=Ci.getNodeId(2)
+
+    N0=my_mesh.getNode(nodeId0)
+    N1=my_mesh.getNode(nodeId1)
+    N2=my_mesh.getNode(nodeId2)
+
+    M[0,0]=N0.x()
+    M[0,1]=N0.y()
+    M[0,2]=1
+    M[1,0]=N1.x()
+    M[1,1]=N1.y()
+    M[1,2]=1
+    M[2,0]=N2.x()
+    M[2,1]=N2.y()
+    M[2,2]=1
+
+    #Values of each shape function at each node
+    values0=[1,0,0]
+    values1=[0,1,0]
+    values2=[0,0,1]
+
+    GradShapeFunc0 = gradientNodal(M,values0)*0.5
+    GradShapeFunc1 = gradientNodal(M,values1)*0.5
+    GradShapeFunc2 = gradientNodal(M,values2)*0.5
+
+    #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+    GradShapeFuncs={nodeId0 : GradShapeFunc0}
+    GradShapeFuncs[nodeId1]=GradShapeFunc1
+    GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+
+    # Remplissage de  la matrice de rigidité et du second membre
+    for j in [nodeId0,nodeId1,nodeId2] :
+        if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+            j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+            #Pas de contribution au second membre car pas de terme source
+            boundaryContributionAdded=False#Needed in case j is a border cell
+            #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
+            for k in [nodeId0,nodeId1,nodeId2] : 
+                if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                    k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                    Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                elif boundaryContributionAdded == False: #si condition limite non nulle au bord (ou maillage non recouvrant), ajouter la contribution du bord au second membre de la cellule j
+                    if boundaryNodes.count(nodeId0)!=0 :
+                        u0=my_ExactSol[nodeId0]
+                    else:
+                        u0=0
+                    if boundaryNodes.count(nodeId1)!=0 :
+                        u1=my_ExactSol[nodeId1]
+                    else:
+                        u1=0
+                    if boundaryNodes.count(nodeId2)!=0 :
+                        u2=my_ExactSol[nodeId2]
+                    else:
+                        u2=0
+                    boundaryContributionAdded=True#Contribution from the boundary to matrix line j is done in one step
+                    GradGh = gradientNodal(M,[u0,u1,u2])*0.5
+                    RHS[j_int] += -(GradGh*GradShapeFuncs[j])/Ci.getMeasure()
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print( "Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+for j in range(nbBoundaryNodes):
+    my_ResultField[boundaryNodes[j]]=my_ExactSol[boundaryNodes[j]];#remplissage des valeurs pour les noeuds frontière (condition limite)
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElements2DPoissonStiffBC_DISK_ResultField")
+my_ExactSol.writeVTK("ExactSol2DPoissonStiffBC_DISK")
+
+# Postprocessing :
+#=================
+# save 2D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoissonStiffBC_DISK_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoissonStiffBC_DISK_ResultField")
+PV_routines.Save_PV_data_to_picture_file("ExactSol2DPoissonStiffBC_DISK"+'_0.vtu',"Exact_field",'NODES',"ExactSol2DPoissonStiffBC_DISK")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=linspace(-1,1,resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,-1,0],[0,1,0], resolution)
+plt.plot(curv_abs, diag_data, label= '2D disk mesh with '+str(nbNodes) + ' nodes')
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D disk triangular mesh')
+plt.savefig("FiniteElements2DPoissonStiffBC_DISK_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 2D Poisson equation on a disk using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+l2_norm_sol_exacte=my_ExactSol.normL2()[0]
+l2_error = (my_ExactSol - my_ResultField).normL2()[0]
+
+print("L2 absolute error = norm( exact solution - numerical solution ) = ",l2_error )
+print("L2 relative error = norm( exact solution - numerical solution )/norm( exact solution ) = ",l2_error/l2_norm_sol_exacte)
+print("Maximum numerical solution = ", my_ResultField.max(), " Minimum numerical solution = ", my_ResultField.min())
+print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min())
+
+assert l2_error/l2_norm_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_SQUARE_StiffBC/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_SQUARE_StiffBC/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..2c176f8
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/squareWithTriangles.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson2DEF_SQUARE_StiffBC)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_2DEF_SQUARE_StiffBC ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements2DPoisson_SQUARE_StiffBC.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_SQUARE_StiffBC/FiniteElements2DPoisson_SQUARE_StiffBC.py b/CDMATH/tests/examples/PoissonEquation/Poisson2DEF_SQUARE_StiffBC/FiniteElements2DPoisson_SQUARE_StiffBC.py
new file mode 100755 (executable)
index 0000000..1f2a44f
--- /dev/null
@@ -0,0 +1,223 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Poisson 2D -\triangle u = 0 sur le carré unité avec conditions aux limites de Dirichlet discontinues
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
+#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=atan((x*x-y*y)/(2*x*y))
+#================================================================================================================================
+
+import cdmath
+from math import atan, pi
+from numpy import linspace
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+# Fonction qui remplace successivement les colonnes d'une matrices par un vecteur donné et retourne la liste des déterminants
+def gradientNodal(M, values):
+    matrices=[0]*(len(values)-1)
+    for i in range(len(values)-1):
+        matrices[i] = M.deepCopy()        
+        for j in range(len(values)):
+            matrices[i][j,i] = values[j]
+
+    result = cdmath.Vector(len(values)-1)    
+    for i in range(len(values)-1):
+        result[i] = matrices[i].determinant()
+
+    return result
+
+
+#Chargement du maillage triangulaire du carré unité
+#=======================================================================================
+meshName="squareWithTriangles"
+my_mesh = cdmath.Mesh(meshName+".med")
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+if(not my_mesh.isTriangular()) :
+    raise ValueError("Wrong cell types : mesh is not made of triangles")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Détermination des noeuds intérieurs
+#======================================================================
+my_ExactSol = cdmath.Field("Exact_field", cdmath.NODES, my_mesh, 1)
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+eps=1e-10
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+    Ni=my_mesh.getNode(i)
+    x = Ni.x()
+    y = Ni.y()
+
+    #Robust calculation of atan((x*x-y*y)/(2*x*y))
+    if x<-eps or x>1+eps or y<-eps or y>1+eps :
+        print("!!! Warning Mesh ", meshName," !!! Node is not in the unit square.",", eps=",eps, ", x= ",x, ", y= ",y)
+        #raise ValueError("!!! Domain should be the unit square.")
+    if abs(x*y) > eps :
+        my_ExactSol[i] = atan((x*x-y*y)/(2*x*y))
+    elif x**2-y**2>0 :
+        my_ExactSol[i] = pi/2
+    elif x**2-y**2<0 :
+        my_ExactSol[i] = -pi/2
+    else : #x=0
+        my_ExactSol[i] = 0
+        
+    if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+        boundaryNodes.append(i)
+        nbBoundaryNodes=nbBoundaryNodes+1
+    else: # Détection des noeuds intérieurs
+        interiorNodes.append(i)
+        nbInteriorNodes=nbInteriorNodes+1
+        maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
+
+print("Right hand side discretisation done")
+print("Number of interior nodes=", nbInteriorNodes)
+print("Number of boundary nodes=", nbBoundaryNodes)
+print("Maximum number of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbInteriorNodes)
+
+M=cdmath.Matrix(3,3)
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
+GradShapeFunc0=cdmath.Vector(2)
+GradShapeFunc1=cdmath.Vector(2)
+GradShapeFunc2=cdmath.Vector(2)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+    Ci=my_mesh.getCell(i)
+
+    #Contribution à la matrice de rigidité
+    nodeId0=Ci.getNodeId(0)
+    nodeId1=Ci.getNodeId(1)
+    nodeId2=Ci.getNodeId(2)
+
+    N0=my_mesh.getNode(nodeId0)
+    N1=my_mesh.getNode(nodeId1)
+    N2=my_mesh.getNode(nodeId2)
+
+    M[0,0]=N0.x()
+    M[0,1]=N0.y()
+    M[0,2]=1
+    M[1,0]=N1.x()
+    M[1,1]=N1.y()
+    M[1,2]=1
+    M[2,0]=N2.x()
+    M[2,1]=N2.y()
+    M[2,2]=1
+
+    #Values of each shape function at each node
+    values0=[1,0,0]
+    values1=[0,1,0]
+    values2=[0,0,1]
+
+    GradShapeFunc0 = gradientNodal(M,values0)*0.5
+    GradShapeFunc1 = gradientNodal(M,values1)*0.5
+    GradShapeFunc2 = gradientNodal(M,values2)*0.5
+
+    #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+    GradShapeFuncs={nodeId0 : GradShapeFunc0}
+    GradShapeFuncs[nodeId1]=GradShapeFunc1
+    GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+
+    # Remplissage de  la matrice de rigidité et du second membre
+    for j in [nodeId0,nodeId1,nodeId2] :
+        if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+            j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+            #Pas de contribution au second membre car pas de terme source
+            boundaryContributionAdded=False#Needed in case j is a border cell
+            #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
+            for k in [nodeId0,nodeId1,nodeId2] : 
+                if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                    k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                    Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                elif boundaryContributionAdded == False: #si condition limite non nulle au bord (ou maillage non recouvrant), ajouter la contribution du bord au second membre de la cellule j
+                    if boundaryNodes.count(nodeId0)!=0 :
+                        u0=my_ExactSol[nodeId0]
+                    else:
+                        u0=0
+                    if boundaryNodes.count(nodeId1)!=0 :
+                        u1=my_ExactSol[nodeId1]
+                    else:
+                        u1=0
+                    if boundaryNodes.count(nodeId2)!=0 :
+                        u2=my_ExactSol[nodeId2]
+                    else:
+                        u2=0
+                    boundaryContributionAdded=True#Contribution from the boundary to matrix line j is done in one step
+                    GradGh = gradientNodal(M,[u0,u1,u2])*0.5
+                    RHS[j_int] += -(GradGh*GradShapeFuncs[j])/Ci.getMeasure()
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#Remplacer CG par CHOLESKY pour solveur direct
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print( "Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+    my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+for j in range(nbBoundaryNodes):
+    my_ResultField[boundaryNodes[j]]=my_ExactSol[boundaryNodes[j]];#remplissage des valeurs pour les noeuds frontière (condition limite)
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElements2DPoissonStiffBC_SQUARE_ResultField")
+my_ExactSol.writeVTK("ExactSol2DPoissonStiffBC_SQUARE")
+
+# Postprocessing :
+#=================
+# save 2D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElements2DPoissonStiffBC_SQUARE_ResultField"+'_0.vtu',"ResultField",'NODES',"FiniteElements2DPoissonStiffBC_SQUARE_ResultField")
+PV_routines.Save_PV_data_to_picture_file("ExactSol2DPoissonStiffBC_SQUARE"+'_0.vtu',"Exact_field",'NODES',"ExactSol2DPoissonStiffBC_SQUARE")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=linspace(-1,1,resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,-1,0],[0,1,0], resolution)
+plt.plot(curv_abs, diag_data, label= '2D square mesh with '+str(nbNodes) + ' nodes')
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 2D square triangular mesh')
+plt.savefig("FiniteElements2DPoissonStiffBC_SQUARE_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 2D Poisson equation on a square using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+l2_norm_sol_exacte=my_ExactSol.normL2()[0]
+l2_error = (my_ExactSol - my_ResultField).normL2()[0]
+
+print("L2 absolute error = norm( exact solution - numerical solution ) = ",l2_error )
+print("L2 relative error = norm( exact solution - numerical solution )/norm( exact solution ) = ",l2_error/l2_norm_sol_exacte)
+print("Maximum numerical solution = ", my_ResultField.max(), " Minimum numerical solution = ", my_ResultField.min())
+print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min())
+
+assert l2_error/l2_norm_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DVF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson2DVF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..750392c
--- /dev/null
@@ -0,0 +1,32 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_2DVF_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithLocRefSquares.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_SQUARE_loc_ref ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithCheckerboardSquares.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithHexagons.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_SQUARE_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithBrickWall.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_SQUARE_brickwall ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithDeformedQuadrangles.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_SQUARE_deformed_quadrangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_SQUARE.py ${MESH_FILE})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DVF/FiniteVolumes2DPoisson_SQUARE.py b/CDMATH/tests/examples/PoissonEquation/Poisson2DVF/FiniteVolumes2DPoisson_SQUARE.py
new file mode 100755 (executable)
index 0000000..877628c
--- /dev/null
@@ -0,0 +1,152 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur un carré avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2016
+# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
+#                Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)
+#================================================================================================================================
+
+import cdmath
+from math import sin, pi, sqrt
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+import sys
+
+if len(sys.argv) >1 :#non rectangular mesh
+    my_mesh = cdmath.Mesh(sys.argv[1])
+else :   #rectangular mesh
+# Création d'un maillage cartésien du domaine carré [0,1]x[0,1], définition des bords
+#====================================================================================
+    xmin=0
+    xmax=1
+    ymin=0
+    ymax=1
+    
+    nx=15
+    ny=15
+    
+    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny)
+
+    eps=1e-6
+    my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
+    my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
+    my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
+    my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
+
+nbCells = my_mesh.getNumberOfCells()
+
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+
+print("Mesh loading done")
+print("Number of cells  = ", nbCells)
+
+#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
+#================================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
+maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
+for i in range(nbCells): 
+    Ci = my_mesh.getCell(i)
+    x = Ci.x()
+    y = Ci.y()
+
+    my_RHSfield[i]=2*pi*pi*sin(pi*x)*sin(pi*y)#mettre la fonction definie au second membre de l edp
+    # compute maximum number of neighbours
+    maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print("Max nb of neighbours = ", maxNbNeighbours)
+
+# Construction de la matrice et du vecteur second membre du système linéaire
+#===========================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbCells)
+#Parcours des cellules du domaine
+for i in range(nbCells):
+    RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
+    Ci=my_mesh.getCell(i)
+    for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
+        Fj=my_mesh.getFace(Ci.getFaceId(j))
+        if not Fj.isBorder():
+            k=Fj.getCellId(0)
+            if k==i :
+                k=Fj.getCellId(1)
+            Ck=my_mesh.getCell(k)
+            distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
+            coeff=Fj.getMeasure()/Ci.getMeasure()/distance
+            Rigidite.addValue(i,k,-coeff) # terme extradiagonal
+        else:
+            coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
+            #For the particular case where the mesh boundary does not coincide with the domain boundary
+            x=Fj.getBarryCenter().x()
+            y=Fj.getBarryCenter().y()
+            RHS[i]+=coeff*sin(pi*x)*sin(pi*y)#mettre ici  la solution exacte de l'edp
+        Rigidite.addValue(i,i,coeff) # terme diagonal
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
+SolSyst=LS.solve()
+
+print("Preconditioner used : ", LS.getNameOfPc())
+print("Number of iterations used : ", LS.getNumberOfIter())
+print("Final residual : ", LS.getResidu())
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
+for i in range(nbCells):
+    my_ResultField[i]=SolSyst[i];
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteVolumes2DPoisson_SQUARE_ResultField")
+
+#Postprocessing : 
+#===============
+# save 2D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteVolumes2DPoisson_SQUARE_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes2DPoisson_SQUARE_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=np.linspace(0,sqrt(2),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+if len(sys.argv) >1 :
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D square '+my_mesh.getName())
+    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
+    plt.savefig("FiniteVolumes2DPoisson_SQUARE_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
+else :   
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D square with a rectangular grid')
+    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
+    plt.savefig("FiniteVolumes2DPoisson_SQUARE_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 2D Poisson equation on a square using finite volumes done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal the right hand side divided by 2*pi*pi
+max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(2*pi*pi)
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbCells) :
+    if erreur_abs < abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i]) :
+        erreur_abs = abs(my_RHSfield[i]/(2*pi*pi) - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_RHSfield.max()/(2*pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(2*pi*pi) )
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..25d1467
--- /dev/null
@@ -0,0 +1,22 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_spiderweb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK.py ${MESH_FILE})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK/FiniteVolumes2DPoisson_DISK.py b/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK/FiniteVolumes2DPoisson_DISK.py
new file mode 100755 (executable)
index 0000000..9e13ad3
--- /dev/null
@@ -0,0 +1,143 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur un disque avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
+#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)
+#================================================================================================================================
+
+import cdmath
+from math import sin, sqrt, atan2
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+import sys
+
+if len(sys.argv) >1 :#non rectangular mesh
+    my_mesh = cdmath.Mesh(sys.argv[1])
+else :   
+    raise ValueError("Give an input mesh of the disk")
+
+nbCells = my_mesh.getNumberOfCells()
+
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+
+print( "Mesh loading done" )
+print( "Number of cells  = ", nbCells )
+
+#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
+#================================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
+my_ExactSol = cdmath.Field("Exact_field", cdmath.CELLS, my_mesh, 1)
+
+maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
+for i in range(nbCells): 
+       Ci = my_mesh.getCell(i)
+       x = Ci.x()
+       y = Ci.y()
+
+       r=sqrt(x*x+y*y)
+       theta=atan2(y,x)
+
+       my_RHSfield[i]=(8*r-3)*sin(theta)#mettre la fonction definie au second membre de l'edp
+       my_ExactSol[i]=-(r-1)*r*r*sin(theta)#mettre la solution exacte de l'edp
+       # compute maximum number of neighbours
+       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print("Maximum number of neighbours = ", maxNbNeighbours )
+
+# Construction de la matrice et du vecteur second membre du système linéaire
+#===========================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbCells)
+#Parcours des cellules du domaine
+for i in range(nbCells):
+       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
+       Ci=my_mesh.getCell(i)
+       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
+               Fj=my_mesh.getFace(Ci.getFaceId(j))
+               if not Fj.isBorder():
+                       k=Fj.getCellId(0)
+                       if k==i :
+                               k=Fj.getCellId(1)
+                       Ck=my_mesh.getCell(k)
+                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
+                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
+               else:
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
+                       #For the particular case where the mesh boundary does not coincide with the domain boundary
+                       x=Fj.getBarryCenter().x()
+                       y=Fj.getBarryCenter().y()
+                       r=sqrt(x*x+y*y)
+                       theta=atan2(y,x)
+                       RHS[i]+=coeff*(-(r-1)*r*r*sin(theta))#mettre ici la solution exacte de l'edp
+               Rigidite.addValue(i,i,coeff) # terme diagonal
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print( "Linear system solved" )
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
+for i in range(nbCells):
+    my_ResultField[i]=SolSyst[i];
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteVolumes2DPoisson_DISK_square_ResultField")
+
+#Postprocessing : 
+#===============
+# save 2D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteVolumes2DPoisson_DISK_square_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes2DPoisson_DISK_square_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=np.linspace(0,sqrt(2),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+if len(sys.argv) >1 :
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk mesh '+my_mesh.getName())
+    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
+    plt.savefig("FiniteVolumes2DPoisson_DISK_square_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
+else :   
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk with a rectangular grid')
+    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
+    plt.savefig("FiniteVolumes2DPoisson_DISK_square_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 2D Poisson equation on a disk using finite volumes done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbCells) :
+    if erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
+        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min() )
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK_StiffBC/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK_StiffBC/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..0762aca
--- /dev/null
@@ -0,0 +1,22 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExamplePoisson_2DVF_DISK_StiffBC_spiderweb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes2DPoisson_DISK_StiffBC.py ${MESH_FILE})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK_StiffBC/FiniteVolumes2DPoisson_DISK_StiffBC.py b/CDMATH/tests/examples/PoissonEquation/Poisson2DVF_DISK_StiffBC/FiniteVolumes2DPoisson_DISK_StiffBC.py
new file mode 100755 (executable)
index 0000000..56355bd
--- /dev/null
@@ -0,0 +1,155 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation de Poisson -\triangle u = 0 sur un disque avec conditions aux limites de Dirichlet discontinues
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
+#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=atan(2*x/(x**2+y**2-1))=atan(2 r cos(theta)/(r*2-1))
+#================================================================================================================================
+
+import cdmath
+from math import atan, pi, sqrt
+from numpy import linspace
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+import sys
+
+if len(sys.argv) >1 :#non rectangular mesh
+    meshName=sys.argv[1]
+    my_mesh = cdmath.Mesh(sys.argv[1])
+else :
+    raise ValueError("Give an input mesh of the disk")
+    
+nbCells = my_mesh.getNumberOfCells()
+
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+
+print( "Mesh loading done" )
+print( "Number of cells  = ", nbCells )
+
+#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
+#================================================================================
+my_ExactSol = cdmath.Field("Exact_field", cdmath.CELLS, my_mesh, 1)
+eps=1e-6#For coarse meshes
+
+maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
+for i in range(nbCells): 
+    Ci = my_mesh.getCell(i)
+    x = Ci.x()
+    y = Ci.y()
+
+    #Robust calculation of atan(2x/(x**2+y**2-1)
+    if x**2+y**2-1 > eps :
+        print("!!! Warning Mesh ", meshName," !!! Cell is not in the unit disk."," eps=",eps, ", x**2+y**2-1=",x**2+y**2 - 1)
+        #raise ValueError("x**2+y**2 > 1 !!! Domain should be the unit disk.")
+    if x**2+y**2-1 < -eps :
+        my_ExactSol[i] = atan(2*x/(x**2+y**2-1))
+    elif x>0 : #x**2+y**2-1>=0
+        my_ExactSol[i] = -pi/2
+    elif x<0 : #x**2+y**2-1>=0
+        my_ExactSol[i] =  pi/2
+    else : #x=0
+        my_ExactSol[i] = 0
+        
+    # compute maximum number of neighbours
+    maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print( "Maximum number of neighbours = ", maxNbNeighbours)
+
+# Construction de la matrice et du vecteur second membre du système linéaire
+#===========================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbCells)
+
+#Parcours des cellules du domaine
+for i in range(nbCells):
+    Ci=my_mesh.getCell(i)
+    for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
+        Fj=my_mesh.getFace(Ci.getFaceId(j))
+        if not Fj.isBorder():
+            k=Fj.getCellId(0)
+            if k==i :
+                k=Fj.getCellId(1)
+            Ck=my_mesh.getCell(k)
+            distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
+            coeff=Fj.getMeasure()/Ci.getMeasure()/distance
+            Rigidite.addValue(i,k,-coeff) # terme extradiagonal
+        else:
+            coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
+            #For the particular case where the mesh boundary does not coincide with the domain boundary
+            x=Fj.getBarryCenter().x()
+            y=Fj.getBarryCenter().y()
+            if x**2+y**2-1 > eps :
+                print("!!! Warning Mesh ", meshName," !!! Face is not in the unit disk.",", eps=",eps, ", x**2+y**2-1=",x**2+y**2 - 1)
+                #raise ValueError("!!! Domain should be the unit disk.")
+            if x**2+y**2-1 < -eps :
+                RHS[i]+= coeff*atan(2*x/(x**2+y**2-1))
+            elif x>0 : #x**2+y**2-1>=0
+                RHS[i]+= coeff*(-pi/2)
+            elif x<0 : #x**2+y**2-1>=0
+                RHS[i]+= coeff*pi/2
+            else : #x=0
+                RHS[i]+=  0
+        Rigidite.addValue(i,i,coeff) # terme diagonal
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print( "Linear system solved" )
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
+for i in range(nbCells):
+    my_ResultField[i]=SolSyst[i];
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteVolumes2DPoisson_DISK_ResultField")
+
+#Postprocessing : 
+#===============
+# save 2D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteVolumes2DPoisson_DISK_ResultField"+'_0.vtu',"ResultField",'CELLS',"FiniteVolumes2DPoisson_DISK_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=linspace(0,sqrt(2),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,-1,0],[0,1,0], resolution)
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+if len(sys.argv) >1 :
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk mesh '+my_mesh.getName())
+    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
+    plt.savefig("FiniteVolumes2DPoisson_DISK_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
+else :   
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 2D disk with a rectangular grid')
+    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
+    plt.savefig("FiniteVolumes2DPoisson_DISK_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 2D Poisson equation on a disk using finite volumes done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+l2_norm_sol_exacte=my_ExactSol.normL2()[0]
+l2_error = (my_ExactSol - my_ResultField).normL2()[0]
+
+print("L2 absolute error = norm( exact solution - numerical solution ) = ",l2_error )
+print("L2 relative error = norm( exact solution - numerical solution )/norm( exact solution ) = ",l2_error/l2_norm_sol_exacte ) 
+print("Maximum numerical solution = ", my_ResultField.max(), " Minimum numerical solution = ", my_ResultField.min() )
+print("Maximum exact solution = ", my_ExactSol.max(), " Minimum exact solution = ", my_ExactSol.min() )
+
+assert l2_error/l2_norm_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DCubeSkinEF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DCubeSkinEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..3720053
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/meshCubeSkin.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DCubeSkinEF)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoissonBeltrami_3DFE_CUBESKIN ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoissonCubeSkin.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DCubeSkinEF/FiniteElements3DPoissonCubeSkin.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DCubeSkinEF/FiniteElements3DPoissonCubeSkin.py
new file mode 100644 (file)
index 0000000..e167456
--- /dev/null
@@ -0,0 +1,216 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Laplace-Beltrami -\triangle u = f sur la frontière d'un cube
+# Author      : Michael Ndjinga
+# Copyright   : CEA Saclay 2021
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
+#               Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Résolution d'un système linéaire à matrice singulière : les vecteurs constants sont dans le noyau
+#               Comparaison de la solution numérique avec la solution exacte définie face par face : u(x,y,z)= cos(2*pi*x)*cos(2*pi*y)*cos(2*pi*z)
+#================================================================================================================================
+
+import cdmath
+from math import cos, pi
+import numpy as np
+import PV_routines
+import VTK_routines
+import paraview.simple as pvs
+
+#Chargement du maillage triangulaire de la frontière du cube unité [0,1]x[0,1]x[0,1]
+#=======================================================================================
+my_mesh = cdmath.Mesh("meshCubeSkin.med")
+if(not my_mesh.isTriangular()) :
+       raise ValueError("Wrong cell types : mesh is not made of triangles")
+if(my_mesh.getMeshDimension()!=2) :
+       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
+if(my_mesh.getSpaceDimension()!=3) :
+       raise ValueError("Wrong space dimension : expected a space of dimension 3")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh building/loading done")
+print("nb of nodes=", nbNodes)
+print("nb of cells=", nbCells)
+
+#Discrétisation du second membre et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS field", cdmath.NODES, my_mesh, 1)
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+
+eps=1e-6
+#parcours des noeuds pour discrétisation du second membre et extraction du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+       y = Ni.y()
+       z = Ni.z()
+
+       my_RHSfield[i]= 8*pi*pi*cos(2*pi*x)*cos(2*pi*y)*cos(2*pi*z)
+
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               raise ValueError("Mesh should not contain borders")
+       else:
+               maxNbNeighbours = max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only for planar cells, otherwise use function Ni.getNumberOfEdges()
+
+print("Right hand side discretisation done")
+print("Max nb of neighbours=", maxNbNeighbours)
+print("Integral of the RHS", my_RHSfield.integral(0))
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)# warning : third argument is number of non zero coefficients per line
+RHS=cdmath.Vector(nbNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
+GradShapeFunc0=cdmath.Vector(3)
+GradShapeFunc1=cdmath.Vector(3)
+GradShapeFunc2=cdmath.Vector(3)
+
+normalFace0=cdmath.Vector(3)
+normalFace1=cdmath.Vector(3)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+
+       #Build normal to cell Ci
+       normalFace0[0]=Ci.getNormalVector(0,0)
+       normalFace0[1]=Ci.getNormalVector(0,1)
+       normalFace0[2]=Ci.getNormalVector(0,2)
+       normalFace1[0]=Ci.getNormalVector(1,0)
+       normalFace1[1]=Ci.getNormalVector(1,1)
+       normalFace1[2]=Ci.getNormalVector(1,2)
+
+       normalCell = normalFace0.crossProduct(normalFace1)
+       normalCell = normalCell*(1/normalCell.norm())
+
+       cellMat=cdmath.Matrix(4)
+       cellMat[0,0]=N0.x()
+       cellMat[0,1]=N0.y()
+       cellMat[0,2]=N0.z()
+       cellMat[1,0]=N1.x()
+       cellMat[1,1]=N1.y()
+       cellMat[1,2]=N1.z()
+       cellMat[2,0]=N2.x()
+       cellMat[2,1]=N2.y()
+       cellMat[2,2]=N2.z()
+       cellMat[3,0]=normalCell[0]
+       cellMat[3,1]=normalCell[1]
+       cellMat[3,2]=normalCell[2]
+       cellMat[0,3]=1
+       cellMat[1,3]=1
+       cellMat[2,3]=1
+       cellMat[3,3]=0
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
+       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
+       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
+       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
+       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
+       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
+       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
+       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
+       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2] : 
+               #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
+               RHS[j]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j] # intégrale dans le triangle du produit f x fonction de base
+               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
+               for k in [nodeId0,nodeId1,nodeId2] : 
+                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+
+print("Linear system matrix building done")
+
+# Conditionnement de la matrice de rigidité
+#=================================
+cond = Rigidite.getConditionNumber(True)
+print("Condition number is ",cond)
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")
+LS.setMatrixIsSingular()#En raison de l'absence de bord
+SolSyst=LS.solve()
+print("Preconditioner used : ", LS.getNameOfPc() )
+print("Number of iterations used : ", LS.getNumberOfIter() )
+print("Final residual : ", LS.getResidu() )
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbNodes):
+    my_ResultField[j]=SolSyst[j];#remplissage des valeurs issues du système linéaire dans le champs résultat
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElementsOnCubeSkinPoisson")
+my_RHSfield.writeVTK("RHS_CubeSkinPoisson")
+
+print("Integral of the numerical solution", my_ResultField.integral(0))
+print("Numerical solution of Poisson equation on a cube skin using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal the right hand side divided by 8*pi*pi
+max_abs_sol_exacte=0
+erreur_abs=0
+max_sol_num=0
+min_sol_num=0
+for i in range(nbNodes) :
+    if max_abs_sol_exacte < abs(my_RHSfield[i]) :
+        max_abs_sol_exacte = abs(my_RHSfield[i])
+    if erreur_abs  < abs(my_RHSfield[i]/(8*pi*pi) - my_ResultField[i]) :
+        erreur_abs = abs(my_RHSfield[i]/(8*pi*pi) - my_ResultField[i])
+    if max_sol_num  < my_ResultField[i] :
+        max_sol_num = my_ResultField[i]
+    if min_sol_num  > my_ResultField[i] :
+        min_sol_num = my_ResultField[i]
+max_abs_sol_exacte = max_abs_sol_exacte/(8*pi*pi)
+
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_RHSfield.max()/(8*pi*pi), " Minimum exact solution = ", my_RHSfield.min()/(8*pi*pi) )
+
+#Postprocessing :
+#================
+# save 3D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElementsOnCubeSkinPoisson"+'_0.vtu',"ResultField",'NODES',"FiniteElementsOnCubeSkinPoisson")
+resolution=100
+VTK_routines.Clip_VTK_data_to_VTK("FiniteElementsOnCubeSkinPoisson"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElementsOnCubeSkinPoisson"+'_0.vtu',[0.75,0.75,0.75], [0.,0.5,-0.5],resolution )
+PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElementsOnCubeSkinPoisson"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElementsOnCubeSkinPoisson")
+
+# Plot  over slice circle
+finiteElementsOnCubeSkin_0vtu = pvs.XMLUnstructuredGridReader(FileName=["FiniteElementsOnCubeSkinPoisson"+'_0.vtu'])
+slice1 = pvs.Slice(Input=finiteElementsOnCubeSkin_0vtu)
+slice1.SliceType.Normal = [0, 1, 0]
+renderView1 = pvs.GetActiveViewOrCreate('RenderView')
+finiteElementsOnCubeSkin_0vtuDisplay = pvs.Show(finiteElementsOnCubeSkin_0vtu, renderView1)
+pvs.ColorBy(finiteElementsOnCubeSkin_0vtuDisplay, ('POINTS', 'ResultField'))
+slice1Display = pvs.Show(slice1, renderView1)
+pvs.SaveScreenshot("./FiniteElementsOnCubeSkinPoisson"+"_Slice"+'.png', magnification=1, quality=100, view=renderView1)
+plotOnSortedLines1 = pvs.PlotOnSortedLines(Input=slice1)
+lineChartView2 = pvs.CreateView('XYChartView')
+plotOnSortedLines1Display = pvs.Show(plotOnSortedLines1, lineChartView2)
+plotOnSortedLines1Display.UseIndexForXAxis = 0
+plotOnSortedLines1Display.XArrayName = 'arc_length'
+plotOnSortedLines1Display.SeriesVisibility = ['ResultField (1)']
+pvs.SaveScreenshot("./FiniteElementsOnCubeSkinPoisson"+"_PlotOnSortedLine_"+'.png', magnification=1, quality=100, view=lineChartView2)
+pvs.Delete(lineChartView2)
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DEF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..e9c8165
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/meshCube.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DEF)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_3DEF_CUBE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoisson_CUBE.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DEF/FiniteElements3DPoisson_CUBE.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF/FiniteElements3DPoisson_CUBE.py
new file mode 100755 (executable)
index 0000000..6043a1e
--- /dev/null
@@ -0,0 +1,189 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Poisson 3D -\triangle u = f sur le cube avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga, Sédrick Kameni
+# Copyright   : CEA Saclay 2017
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage tétraédrique
+#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)*sin(pi*z)
+#================================================================================================================================
+
+import cdmath
+from math import sin, pi, sqrt
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+#Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
+#==============================================================================================
+my_mesh = cdmath.Mesh("meshCube.med")
+if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
+if(not my_mesh.isTetrahedral()) :
+       raise ValueError("Wrong cell types : mesh is not made of tetrahedra")
+eps=1e-6
+my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
+my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
+my_mesh.setGroupAtPlan(0.,1,eps,"DirichletBorder")#Bord BAS
+my_mesh.setGroupAtPlan(1.,1,eps,"DirichletBorder")#Bord HAUT
+my_mesh.setGroupAtPlan(0.,2,eps,"DirichletBorder")#Bord AVANT
+my_mesh.setGroupAtPlan(1.,2,eps,"DirichletBorder")#Bord ARRIERE
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Discrétisation du second membre et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
+
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+       y = Ni.y()
+       z = Ni.z()
+
+       my_RHSfield[i]=3*pi*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)#mettre la fonction definie au second membre de l'edp
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               boundaryNodes.append(i)
+               nbBoundaryNodes=nbBoundaryNodes+1
+       else: # Détection des noeuds intérieurs
+               interiorNodes.append(i)
+               nbInteriorNodes=nbInteriorNodes+1
+               maxNbNeighbours= max(1+Ni.getNumberOfEdges(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print("Number of interior nodes=", nbInteriorNodes)
+print("Number of boundary nodes=", nbBoundaryNodes)
+print("Maximum number of neighbours per node=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours) # warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbInteriorNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un tétraèdre
+GradShapeFunc0=cdmath.Vector(3)
+GradShapeFunc1=cdmath.Vector(3)
+GradShapeFunc2=cdmath.Vector(3)
+GradShapeFunc3=cdmath.Vector(3)
+
+#On parcourt les tétraèdres du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Extraction des noeuds de la cellule
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+       nodeId3=Ci.getNodeId(3)
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+       N3=my_mesh.getNode(nodeId3)
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= (N2.y()*N3.z()-N2.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
+       GradShapeFunc0[1]=-(N2.x()*N3.z()-N2.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
+       GradShapeFunc0[2]=(N2.x()*N3.y()-N2.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
+       GradShapeFunc1[0]=- (N2.y()*N3.z()-N2.z()*N3.y()-N0.y()*N3.z()+N3.y()*N0.z()+N0.y()*N2.z()-N2.y()*N0.z())/6
+       GradShapeFunc1[1]=(N2.x()*N3.z()-N2.z()*N3.x()-N0.x()*N3.z()+N3.x()*N0.z()+N0.x()*N2.z()-N2.x()*N0.z())/6
+       GradShapeFunc1[2]=-(N2.x()*N3.y()-N2.y()*N3.x()-N0.x()*N3.y()+N3.x()*N0.y()+N0.x()*N2.y()-N2.x()*N0.y())/6
+       GradShapeFunc2[0]= -(N0.y()*N3.z()-N0.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N0.z()-N0.y()*N1.z())/6
+       GradShapeFunc2[1]=(N0.x()*N3.z()-N0.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N0.z()-N0.x()*N1.z())/6
+       GradShapeFunc2[2]= -(N0.x()*N3.y()-N0.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N0.y()-N0.x()*N1.y())/6
+       GradShapeFunc3[0]=-(N2.y()*N0.z()-N2.z()*N0.y()-N1.y()*N0.z()+N0.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
+       GradShapeFunc3[1]=(N2.x()*N0.z()-N2.z()*N0.x()-N1.x()*N0.z()+N0.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
+       GradShapeFunc3[2]=-(N2.x()*N0.y()-N2.y()*N0.x()-N1.x()*N0.y()+N0.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
+       
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme)
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+       GradShapeFuncs[nodeId3]=GradShapeFunc3
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2,nodeId3] :
+               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
+                       RHS[j_int]=Ci.getMeasure()/4*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
+                       #Contribution de la cellule tétraédrique i à la ligne j_int du système linéaire
+                       for k in [nodeId0,nodeId1,nodeId2,nodeId3] :
+                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#,"ILU" Remplacer CG par CHOLESKY pour solveur direct
+SolSyst=LS.solve()
+print( "Preconditioner used : ", LS.getNameOfPc())
+print( "Number of iterations used : ", LS.getNumberOfIter())
+print( "Final residual : ", LS.getResidu())
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+       my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+
+for j in range(nbBoundaryNodes):
+    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElements3DPoisson_CUBE_ResultField")
+
+#Postprocessing :
+#================
+# save 3D picture
+resolution=100
+VTK_routines.Clip_VTK_data_to_VTK("FiniteElements3DPoisson_CUBE_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElements3DPoisson_CUBE_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
+PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_CUBE_ResultField"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_CUBE_ResultField")
+
+# extract and plot diagonal values
+curv_abs=np.linspace(0,sqrt(3),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,0,0],[1,1,1], resolution)
+plt.plot(curv_abs, diag_data, label= str(nbNodes) + ' nodes 3D mesh')
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 3D tetrahedral mesh')
+plt.savefig("FiniteElements3DPoisson_CUBE_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 3D Poisson equation on a cube using finite elements done")
+
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal the right hand side divided by 3*pi*pi
+max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(3*pi*pi)
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbNodes) :
+    if erreur_abs < abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i]) :
+        erreur_abs = abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_BALL/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_BALL/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..3adada4
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/ballWithTetrahedra.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DEF_BALL)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_3DEF_BALL ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoisson_BALL.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_BALL/FiniteElements3DPoisson_BALL.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_BALL/FiniteElements3DPoisson_BALL.py
new file mode 100755 (executable)
index 0000000..82fa4e8
--- /dev/null
@@ -0,0 +1,186 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Poisson 3D -\triangle u = f sur la boule unité avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage tétraédrique
+#                      Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)**2*cos(phi)
+#================================================================================================================================
+
+import cdmath
+from math import sin, cos, atan2, sqrt
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+#Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
+#==============================================================================================
+my_mesh = cdmath.Mesh("ballWithTetrahedra.med")
+if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
+if(not my_mesh.isTetrahedral()) :
+       raise ValueError("Wrong cell types : mesh is not made of tetrahedra")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Discrétisation du second membre et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.NODES, my_mesh, 1)
+my_ExactSol = cdmath.Field("EXACT_SOL", cdmath.NODES, my_mesh, 1)
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+       y = Ni.y()
+       z = Ni.z()
+
+       r=sqrt(x*x+y*y+z*z)
+       phi=atan2(y,x)
+       theta=atan2(y,z*sin(phi))
+
+       my_RHSfield[i]=6*r*sin(theta)**2*cos(phi)+3*(r-1)*cos(phi)#mettre la fonction definie au second membre de l'edp
+       my_ExactSol[i]=-(r-1)*r**2*sin(theta)**2*cos(phi)
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               boundaryNodes.append(i)
+               nbBoundaryNodes=nbBoundaryNodes+1
+       else: # Détection des noeuds intérieurs
+               interiorNodes.append(i)
+               nbInteriorNodes=nbInteriorNodes+1
+               maxNbNeighbours= max(1+Ni.getNumberOfEdges(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print("Number of interior nodes=", nbInteriorNodes)
+print("Number of boundary nodes=", nbBoundaryNodes)
+print("Maximum number of neighbours per node=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours) # warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbInteriorNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un hexaèdre
+GradShapeFunc0=cdmath.Vector(3)
+GradShapeFunc1=cdmath.Vector(3)
+GradShapeFunc2=cdmath.Vector(3)
+GradShapeFunc3=cdmath.Vector(3)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+       nodeId3=Ci.getNodeId(3)
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+       N3=my_mesh.getNode(nodeId3)
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= (N2.y()*N3.z()-N2.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
+       GradShapeFunc0[1]=-(N2.x()*N3.z()-N2.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
+       GradShapeFunc0[2]=(N2.x()*N3.y()-N2.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
+       GradShapeFunc1[0]=- (N2.y()*N3.z()-N2.z()*N3.y()-N0.y()*N3.z()+N3.y()*N0.z()+N0.y()*N2.z()-N2.y()*N0.z())/6
+       GradShapeFunc1[1]=(N2.x()*N3.z()-N2.z()*N3.x()-N0.x()*N3.z()+N3.x()*N0.z()+N0.x()*N2.z()-N2.x()*N0.z())/6
+       GradShapeFunc1[2]=-(N2.x()*N3.y()-N2.y()*N3.x()-N0.x()*N3.y()+N3.x()*N0.y()+N0.x()*N2.y()-N2.x()*N0.y())/6
+       GradShapeFunc2[0]= -(N0.y()*N3.z()-N0.z()*N3.y()-N1.y()*N3.z()+N3.y()*N1.z()+N1.y()*N0.z()-N0.y()*N1.z())/6
+       GradShapeFunc2[1]=(N0.x()*N3.z()-N0.z()*N3.x()-N1.x()*N3.z()+N3.x()*N1.z()+N1.x()*N0.z()-N0.x()*N1.z())/6
+       GradShapeFunc2[2]= -(N0.x()*N3.y()-N0.y()*N3.x()-N1.x()*N3.y()+N3.x()*N1.y()+N1.x()*N0.y()-N0.x()*N1.y())/6
+       GradShapeFunc3[0]=-(N2.y()*N0.z()-N2.z()*N0.y()-N1.y()*N0.z()+N0.y()*N1.z()+N1.y()*N2.z()-N2.y()*N1.z())/6
+       GradShapeFunc3[1]=(N2.x()*N0.z()-N2.z()*N0.x()-N1.x()*N0.z()+N0.x()*N1.z()+N1.x()*N2.z()-N2.x()*N1.z())/6
+       GradShapeFunc3[2]=-(N2.x()*N0.y()-N2.y()*N0.x()-N1.x()*N0.y()+N0.x()*N1.y()+N1.x()*N2.y()-N2.x()*N1.y())/6
+       
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme)
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+       GradShapeFuncs[nodeId3]=GradShapeFunc3
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2,nodeId3] :
+               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+                       #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
+                       RHS[j_int]=Ci.getMeasure()/4*my_RHSfield[j]+RHS[j_int] # intégrale dans le triangle du produit f x fonction de base
+                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
+                       for k in [nodeId0,nodeId1,nodeId2,nodeId3] :
+                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#,"ILU" Remplacer CG par CHOLESKY pour solveur direct
+SolSyst=LS.solve()
+print("Preconditioner used : ", LS.getNameOfPc() )
+print("Number of iterations used : ", LS.getNumberOfIter() )
+print("Final residual : ", LS.getResidu() )
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+       my_ResultField[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+
+for j in range(nbBoundaryNodes):
+    my_ResultField[boundaryNodes[j]]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElements3DPoisson_BALL_ResultField")
+
+#Postprocessing :
+#================
+# save 3D picture
+resolution=100
+VTK_routines.Clip_VTK_data_to_VTK("FiniteElements3DPoisson_BALL_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElements3DPoisson_BALL_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
+PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_BALL_ResultField"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElements3DPoisson_BALL_ResultField")
+
+# extract and plot diagonal values
+curv_abs=np.linspace(0,sqrt(3),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[-0.577,-0.577,-0.577],[0.577,0.577,0.577], resolution)
+plt.plot(curv_abs, diag_data, label= str(nbNodes) + ' nodes 3D mesh')
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+plt.title('Plot over diagonal line for finite elements \n for Laplace operator on a 3D ball tetrahedral mesh')
+plt.savefig("FiniteElements3DPoisson_BALL_ResultField_"+str(nbNodes) + '_nodes'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 3D Poisson equation on a 3D ball using finite elements done")
+
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbNodes) :
+    if erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
+        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..f628489
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ./Mesh_RadiatorAndWindow.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DEF_RadiatorAndWindow)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_3DEF_CUBE_RadiatorAndWindow ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/FiniteElements3DPoisson_CUBE_RadiatorAndWindow.py
new file mode 100755 (executable)
index 0000000..f58010b
--- /dev/null
@@ -0,0 +1,199 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Laplace 3D -\Delta T = 0 avec conditions aux limites de Dirichlet u non nulle
+# Authors     : Michaël Ndjinga, Sédrick Kameni Ngwamou
+# Copyright   : CEA Saclay 2019
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u discrétisés aux noeuds d'un maillage tétraédrique
+#               Condition limites correspondant au refroidissement dû à une fenêtre et au chauffage dû à un radiateur
+#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#================================================================================================================================
+
+import cdmath
+import numpy as np
+
+# Fonction qui remplace successivement les colonnes d'une matrices par un vecteur donné et retourne la liste des déterminants
+def gradientNodal(M, values):
+       matrices=[0]*(len(values)-1)
+       for i in range(len(values)-1):
+               matrices[i] = M.deepCopy()        
+               for j in range(len(values)):
+                       matrices[i][j,i] = values[j]
+
+       result = cdmath.Vector(len(values)-1)    
+       for i in range(len(values)-1):
+               result[i] = matrices[i].determinant()
+
+       return result
+
+# Fonction qui calcule la valeur de la condition limite en un noeud donné
+def boundaryValue(nodeId): 
+       Ni=my_mesh.getNode(nodeId)
+
+       # 4 groupes sont considérés sur le bord
+       if boundaryNodes.count(nodeId)==0:
+               return 0
+       elif Ni.getGroupName()=='Fenetre':
+               return Tfenetre;
+       elif Ni.getGroupName()=='Radiateur_sous-fenetre':
+               return Tradiateur
+       #elif Ni.getGroupName()=='Radiateur_Devant':
+               #return Tradiateur;
+       #elif Ni.getGroupName()=='Radiateur_droit':
+               #return Tradiateur
+       else:   
+               return Tmur;
+
+#Chargement du maillage tétraédrique du domaine
+#==============================================
+my_mesh = cdmath.Mesh("Mesh_RadiatorAndWindow.med")
+if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
+if(not my_mesh.isTetrahedral()) :
+       raise ValueError("Wrong cell types : mesh is not made of tetrahedra")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("nb of nodes=", nbNodes)
+print("nb of cells=", nbCells)
+
+#Conditions limites
+Tmur=20
+Tfenetre=0
+Tradiateur=40
+
+#Détermination des noeuds intérieurs
+#======================================================================
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes = []
+boundaryNodes = []
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+    
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière getGroupName my_mesh.getNode(i)
+               boundaryNodes.append(i)
+       else: # Détection des noeuds intérieurs
+               interiorNodes.append(i)
+               maxNbNeighbours= max(1+Ni.getNumberOfEdges(),maxNbNeighbours) 
+
+nbInteriorNodes=len(interiorNodes)
+nbBoundaryNodes=len(boundaryNodes)
+
+
+print("nb of interior nodes=", nbInteriorNodes)
+print("nb of Boundary nodes=", nbBoundaryNodes)
+print("Max nb of neighbours=", maxNbNeighbours)
+
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)
+RHS=cdmath.Vector(nbInteriorNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un tétrèdre (hypothèse 3D)
+M=cdmath.Matrix(4,4)
+GradShapeFunc0=cdmath.Vector(3)
+GradShapeFunc1=cdmath.Vector(3)
+GradShapeFunc2=cdmath.Vector(3)
+GradShapeFunc3=cdmath.Vector(3)
+
+#On parcourt les tétraèdres du domaine pour remplir la matrice
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Extraction des noeuds de la cellule
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+       nodeId3=Ci.getNodeId(3)
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+       N3=my_mesh.getNode(nodeId3)
+
+       M[0,0]=N0.x()
+       M[0,1]=N0.y()
+       M[0,2]=N0.z()
+       M[0,3]=1
+       M[1,0]=N1.x()
+       M[1,1]=N1.y()
+       M[1,2]=N1.z()
+       M[1,3]=1
+       M[2,0]=N2.x()
+       M[2,1]=N2.y()
+       M[2,2]=N2.z()
+       M[2,3]=1
+       M[3,0]=N3.x()
+       M[3,1]=N3.y()
+       M[3,2]=N3.z()
+       M[3,3]=1
+
+       #Values of each shape function at each node
+       values0=[1,0,0,0]
+       values1=[0,1,0,0]
+       values2=[0,0,1,0]
+       values3=[0,0,0,1]
+
+       GradShapeFunc0 = gradientNodal(M,values0)*(1./6)
+       GradShapeFunc1 = gradientNodal(M,values1)*(1./6)
+       GradShapeFunc2 = gradientNodal(M,values2)*(1./6)
+       GradShapeFunc3 = gradientNodal(M,values3)*(1./6)
+       
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme)
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+       GradShapeFuncs[nodeId3]=GradShapeFunc3
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2,nodeId3] : 
+               if boundaryNodes.count(j)==0: #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+                       boundaryContributionAdded=False#Needed in case j is a border cell
+                       #Ajout de la contribution de la cellule ttétraédrique i au second membre du noeud j 
+                       for k in [nodeId0,nodeId1,nodeId2,nodeId3] : 
+                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                                       k_int = interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                               elif boundaryContributionAdded == False: #si condition limite non nulle au bord (ou maillage non recouvrant), ajouter la contribution du bord au second membre de la cellule j
+                                       # Valeurs de g_h aux noeuds du tétraèdre
+                                       T0 = boundaryValue(nodeId0)
+                                       T1 = boundaryValue(nodeId1)
+                                       T2 = boundaryValue(nodeId2)
+                                       T3 = boundaryValue(nodeId3)
+                                       boundaryContributionAdded=True#Contribution from the boundary to matrix line j is done in one step
+                                       GradGh = gradientNodal(M,[T0,T1,T2,T3])*(1./6)
+                                       RHS[j_int] += -(GradGh*GradShapeFuncs[j])/Ci.getMeasure()
+            
+
+    
+print("Linear system matrix building done")
+
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"CG","ILU")#,"ILU" Remplacer CG par CHOLESKY pour solveur direct
+
+SolSyst=LS.solve()
+
+# Création du champ résultat
+#===========================
+my_Temperature = cdmath.Field("Temperature", cdmath.NODES, my_mesh, 1)
+for j in range(nbInteriorNodes):
+       my_Temperature[interiorNodes[j]]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs SolSyst[j]
+#Remplissage des valeurs pour les noeuds frontière (condition limite)
+for j in boundaryNodes:
+    my_Temperature[j]=boundaryValue(j)
+
+
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_Temperature.writeVTK("FiniteElements3DTemperature")
+
+print( "Minimum temperature= ", my_Temperature.min(), ", maximum temperature= ", my_Temperature.max() )
+assert my_Temperature.min()>= min(Tmur,Tfenetre,Tradiateur) and my_Temperature.max()<= max(Tmur,Tfenetre,Tradiateur)
+
+print( "Numerical solution of 3D Laplace equation using finite elements done" )
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med
new file mode 100755 (executable)
index 0000000..c22aec1
Binary files /dev/null and b/CDMATH/tests/examples/PoissonEquation/Poisson3DEF_RadiatorAndWindow/Mesh_RadiatorAndWindow.med differ
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DSphereEF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DSphereEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..efd716b
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/meshSphere.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DSphereEF)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoissonBeltrami_3DFE_SPHERE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoissonSphere.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DSphereEF/FiniteElements3DPoissonSphere.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DSphereEF/FiniteElements3DPoissonSphere.py
new file mode 100755 (executable)
index 0000000..9d07572
--- /dev/null
@@ -0,0 +1,216 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Laplace-Beltrami -\triangle u = f sur une sphere 
+# Author      : Michael Ndjinga
+# Copyright   : CEA Saclay 2017
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
+#               Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Référence : M. A. Olshanskii, A. Reusken, and J. Grande. A finite element method for elliptic equations
+#                           on surfaces. SIAM J. Num. Anal., 47, p. 3355
+#               Solution exacte = f/12 : il s'agit d'un vecteur propre du laplacien sur la sphère
+#               Résolution d'un système linéaire à matrice singulière : les vecteurs constants sont dans le noyau
+#================================================================================================================================
+
+import cdmath
+from math import pow
+import numpy as np
+import PV_routines
+import VTK_routines
+import paraview.simple as pvs
+
+#Chargement du maillage triangulaire de la sphère
+#=======================================================================================
+my_mesh = cdmath.Mesh("meshSphere.med")
+if(not my_mesh.isTriangular()) :
+       raise ValueError("Wrong cell types : mesh is not made of triangles")
+if(my_mesh.getMeshDimension()!=2) :
+       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
+if(my_mesh.getSpaceDimension()!=3) :
+       raise ValueError("Wrong space dimension : expected a space of dimension 3")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh building/loading done")
+print("nb of nodes=", nbNodes)
+print("nb of cells=", nbCells)
+
+#Discrétisation du second membre et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS field", cdmath.NODES, my_mesh, 1)
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+
+#parcours des noeuds pour discrétisation du second membre et extraction du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+       y = Ni.y()
+       z = Ni.z()
+
+       my_RHSfield[i]=12*y*(3*x*x-y*y)/pow(x*x+y*y+z*z,3/2)#vecteur propre du laplacien sur la sphère
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               raise ValueError("Mesh should not contain borders")
+       else:
+               maxNbNeighbours = max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only for planar cells, otherwise use function Ni.getNumberOfEdges()
+
+print("Right hand side discretisation done")
+print("Max nb of neighbours=", maxNbNeighbours)
+print("Integral of the RHS", my_RHSfield.integral(0))
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)# warning : third argument is number of non zero coefficients per line
+RHS=cdmath.Vector(nbNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
+GradShapeFunc0=cdmath.Vector(3)
+GradShapeFunc1=cdmath.Vector(3)
+GradShapeFunc2=cdmath.Vector(3)
+
+normalFace0=cdmath.Vector(3)
+normalFace1=cdmath.Vector(3)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+
+       #Build normal to cell Ci
+       normalFace0[0]=Ci.getNormalVector(0,0)
+       normalFace0[1]=Ci.getNormalVector(0,1)
+       normalFace0[2]=Ci.getNormalVector(0,2)
+       normalFace1[0]=Ci.getNormalVector(1,0)
+       normalFace1[1]=Ci.getNormalVector(1,1)
+       normalFace1[2]=Ci.getNormalVector(1,2)
+
+       normalCell = normalFace0.crossProduct(normalFace1)
+       normalCell = normalCell*(1/normalCell.norm())
+
+       cellMat=cdmath.Matrix(4)
+       cellMat[0,0]=N0.x()
+       cellMat[0,1]=N0.y()
+       cellMat[0,2]=N0.z()
+       cellMat[1,0]=N1.x()
+       cellMat[1,1]=N1.y()
+       cellMat[1,2]=N1.z()
+       cellMat[2,0]=N2.x()
+       cellMat[2,1]=N2.y()
+       cellMat[2,2]=N2.z()
+       cellMat[3,0]=normalCell[0]
+       cellMat[3,1]=normalCell[1]
+       cellMat[3,2]=normalCell[2]
+       cellMat[0,3]=1
+       cellMat[1,3]=1
+       cellMat[2,3]=1
+       cellMat[3,3]=0
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
+       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
+       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
+       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
+       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
+       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
+       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
+       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
+       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2] : 
+               #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
+               RHS[j]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j] # intégrale dans le triangle du produit f x fonction de base
+               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
+               for k in [nodeId0,nodeId1,nodeId2] : 
+                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+
+print("Linear system matrix building done")
+
+# Conditionnement de la matrice de rigidité
+#=================================
+cond = Rigidite.getConditionNumber(True)
+print("Condition number is ",cond)
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")
+LS.setMatrixIsSingular()#En raison de l'absence de bord
+SolSyst=LS.solve()
+print("Preconditioner used : ", LS.getNameOfPc() )
+print("Number of iterations used : ", LS.getNumberOfIter() )
+print("Final residual : ", LS.getResidu() )
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.NODES, my_mesh, 1)
+for j in range(nbNodes):
+    my_ResultField[j]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElementsOnSpherePoisson")
+
+print("Integral of the numerical solution", my_ResultField.integral(0))
+print("Numerical solution of Poisson equation on a sphere using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal the right hand side divided by 12
+max_abs_sol_exacte=0
+erreur_abs=0
+max_sol_num=0
+min_sol_num=0
+for i in range(nbNodes) :
+    if max_abs_sol_exacte < abs(my_RHSfield[i]) :
+        max_abs_sol_exacte = abs(my_RHSfield[i])
+    if erreur_abs < abs(my_RHSfield[i]/12 - my_ResultField[i]) :
+        erreur_abs = abs(my_RHSfield[i]/12 - my_ResultField[i])
+    if max_sol_num < my_ResultField[i] :
+        max_sol_num = my_ResultField[i]
+    if min_sol_num > my_ResultField[i] :
+        min_sol_num = my_ResultField[i]
+max_abs_sol_exacte = max_abs_sol_exacte/12
+
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", my_RHSfield.max()/12, " Minimum exact solution = ", my_RHSfield.min()/12 )
+
+#Postprocessing :
+#================
+# save 3D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElementsOnSpherePoisson"+'_0.vtu',"ResultField",'NODES',"FiniteElementsOnSpherePoisson")
+resolution=100
+VTK_routines.Clip_VTK_data_to_VTK("FiniteElementsOnSpherePoisson"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElementsOnSpherePoisson"+'_0.vtu',[0.25,0.25,0.25], [-0.5,-0.5,-0.5],resolution )
+PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElementsOnSpherePoisson"+'_0.vtu',"ResultField",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElementsOnSpherePoisson")
+
+# Plot  over slice circle
+finiteElementsOnSphere_0vtu = pvs.XMLUnstructuredGridReader(FileName=["FiniteElementsOnSpherePoisson"+'_0.vtu'])
+slice1 = pvs.Slice(Input=finiteElementsOnSphere_0vtu)
+slice1.SliceType.Normal = [0.5, 0.5, 0.5]
+renderView1 = pvs.GetActiveViewOrCreate('RenderView')
+finiteElementsOnSphere_0vtuDisplay = pvs.Show(finiteElementsOnSphere_0vtu, renderView1)
+pvs.ColorBy(finiteElementsOnSphere_0vtuDisplay, ('POINTS', 'ResultField'))
+slice1Display = pvs.Show(slice1, renderView1)
+pvs.SaveScreenshot("./FiniteElementsOnSpherePoisson"+"_Slice"+'.png', magnification=1, quality=100, view=renderView1)
+plotOnSortedLines1 = pvs.PlotOnSortedLines(Input=slice1)
+lineChartView2 = pvs.CreateView('XYChartView')
+plotOnSortedLines1Display = pvs.Show(plotOnSortedLines1, lineChartView2)
+plotOnSortedLines1Display.UseIndexForXAxis = 0
+plotOnSortedLines1Display.XArrayName = 'arc_length'
+plotOnSortedLines1Display.SeriesVisibility = ['ResultField (1)']
+pvs.SaveScreenshot("./FiniteElementsOnSpherePoisson"+"_PlotOnSortedLine_"+'.png', magnification=1, quality=100, view=lineChartView2)
+pvs.Delete(lineChartView2)
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DTorusEF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DTorusEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..c56320b
--- /dev/null
@@ -0,0 +1,15 @@
+
+SET(MESH_MED
+  ${MED_MESHES}/meshTorus.med
+  )
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/Poisson3DTorusEF)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoissonBeltrami_3DFE_TORUS ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteElements3DPoissonTorus.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DTorusEF/FiniteElements3DPoissonTorus.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DTorusEF/FiniteElements3DPoissonTorus.py
new file mode 100755 (executable)
index 0000000..6de976e
--- /dev/null
@@ -0,0 +1,213 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution EF de l'équation de Laplace-Beltrami -\triangle u = f sur un tore
+# Author      : Michael Ndjinga
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs u et f discrétisés aux noeuds d'un maillage triangulaire
+#               Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant la librairie CDMATH
+#               Référence : M. A. Olshanskii, A. Reusken, and J. Grande. A finite element method for elliptic equations
+#                           on surfaces. SIAM J. Num. Anal., 47, p. 3355
+#               Résolution d'un système linéaire à matrice singulière : les vecteurs constants sont dans le noyau
+#================================================================================================================================
+
+import cdmath
+from math import sin, cos, atan2, sqrt
+import PV_routines
+import VTK_routines
+import paraview.simple as pvs
+
+#Chargement du maillage triangulaire du tore
+#=======================================================================================
+my_mesh = cdmath.Mesh("meshTorus.med")
+if(not my_mesh.isTriangular()) :
+       raise ValueError("Wrong cell types : mesh is not made of triangles")
+if(my_mesh.getMeshDimension()!=2) :
+       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
+if(my_mesh.getSpaceDimension()!=3) :
+       raise ValueError("Wrong space dimension : expected a space of dimension 3")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh building/loading done")
+print("nb of nodes=", nbNodes)
+print("nb of cells=", nbCells)
+
+# Torus radii (calculation  will fail if the mesh is not correct)
+R=1 #Grand rayon
+r=0.6 #Petit rayon
+
+#Discrétisation du second membre, de la solution exacte et détermination des noeuds intérieurs
+#======================================================================
+my_RHSfield = cdmath.Field("RHS field", cdmath.NODES, my_mesh, 1)
+exactSolField = cdmath.Field("Exact solution field", cdmath.NODES, my_mesh, 1)
+
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+
+#parcours des noeuds pour discrétisation du second membre et extraction du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       x = Ni.x()
+       y = Ni.y()
+       z = Ni.z()
+      
+       theta=atan2(z,sqrt(x*x+y*y)-R)
+       phi=atan2(y,x)
+
+       exactSolField[i] = sin(3*phi)*cos(3*theta+ phi) # for the exact solution we use the funtion given in the article of Olshanskii, Reusken 2009, page 19
+       my_RHSfield[i] = 9*sin(3*phi)*cos(3*theta+ phi)/(r*r) + (10*sin(3*phi)*cos(3*theta+ phi) + 6*cos(3*phi)*sin(3*theta+ phi))/((R+r*cos(theta))*(R+r*cos(theta))) - 3*sin(theta)*sin(3*phi)*sin(3*theta+ phi)/(r*(R+r*cos(theta))) #for the right hand side we use the function given in the article of Olshanskii, Reusken 2009, page 19
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               raise ValueError("Mesh should not contain borders")
+       else:
+               maxNbNeighbours = max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only for planar cells, otherwise use function Ni.getNumberOfEdges()
+
+print("Right hand side discretisation done")
+print("Max nb of neighbours=", maxNbNeighbours)
+print("Integral of the RHS", my_RHSfield.integral(0))
+
+# Construction de la matrice de rigidité et du vecteur second membre du système linéaire
+#=======================================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)
+RHS=cdmath.Vector(nbNodes)
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
+GradShapeFunc0=cdmath.Vector(3)
+GradShapeFunc1=cdmath.Vector(3)
+GradShapeFunc2=cdmath.Vector(3)
+
+normalFace0=cdmath.Vector(3)
+normalFace1=cdmath.Vector(3)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+
+       #Build normal to cell Ci
+       normalFace0[0]=Ci.getNormalVector(0,0)
+       normalFace0[1]=Ci.getNormalVector(0,1)
+       normalFace0[2]=Ci.getNormalVector(0,2)
+       normalFace1[0]=Ci.getNormalVector(1,0)
+       normalFace1[1]=Ci.getNormalVector(1,1)
+       normalFace1[2]=Ci.getNormalVector(1,2)
+
+       normalCell = normalFace0.crossProduct(normalFace1)
+       normalCell = normalCell*(1/normalCell.norm())
+
+       cellMat=cdmath.Matrix(4)
+       cellMat[0,0]=N0.x()
+       cellMat[0,1]=N0.y()
+       cellMat[0,2]=N0.z()
+       cellMat[1,0]=N1.x()
+       cellMat[1,1]=N1.y()
+       cellMat[1,2]=N1.z()
+       cellMat[2,0]=N2.x()
+       cellMat[2,1]=N2.y()
+       cellMat[2,2]=N2.z()
+       cellMat[3,0]=normalCell[0]
+       cellMat[3,1]=normalCell[1]
+       cellMat[3,2]=normalCell[2]
+       cellMat[0,3]=1
+       cellMat[1,3]=1
+       cellMat[2,3]=1
+       cellMat[3,3]=0
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
+       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
+       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
+       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
+       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
+       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
+       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
+       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
+       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2] : 
+               #Ajout de la contribution de la cellule triangulaire i au second membre du noeud j 
+               RHS[j]=Ci.getMeasure()/3*my_RHSfield[j]+RHS[j] # intégrale dans le triangle du produit f x fonction de base
+               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
+               for k in [nodeId0,nodeId1,nodeId2] : 
+                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+
+print("Linear system matrix building done")
+
+# Conditionnement de la matrice de rigidité
+#=================================
+cond = Rigidite.getConditionNumber(True)
+print("Condition number is ",cond)
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,100,1.E-6,"GMRES","ILU")#Remplacer CG par CHOLESKY pour solveur direct
+LS.setMatrixIsSingular()#En raison de l'absence de bord
+SolSyst=LS.solve()
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("Numerical result field", cdmath.NODES, my_mesh, 1)
+for j in range(nbNodes):
+    my_ResultField[j]=SolSyst[j];#remplissage des valeurs pour les noeuds intérieurs
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteElementsOnTorusPoisson")
+
+print("Integral of the numerical solution", my_ResultField.integral(0))
+print("Numerical solution of Poisson equation on a torus using finite elements done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+max_sol_exacte=exactSolField.normMax()[0]
+erreur_max=(exactSolField - my_ResultField).normMax()[0]
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+
+print("Relative error =  max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_max/max_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+print("Maximum exact solution = ", exactSolField.max(), " Minimum exact solution = ", exactSolField.min())
+
+#Postprocessing : 
+#================
+# Save 3D picture
+PV_routines.Save_PV_data_to_picture_file("FiniteElementsOnTorusPoisson"+'_0.vtu',"Numerical result field",'NODES',"FiniteElementsOnTorusPoisson")
+resolution=100
+VTK_routines.Clip_VTK_data_to_VTK("FiniteElementsOnTorusPoisson"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteElementsOnTorusPoisson"+'_0.vtu',[0.25,0.25,0.25], [-0.5,-0.5,-0.5],resolution )
+PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteElementsOnTorusPoisson"+'_0.vtu',"Numerical result field",'NODES',"Clip_VTK_data_to_VTK_"+"FiniteElementsOnTorusPoisson")
+
+# Plot  over slice circle
+finiteElementsOnTorus_0vtu = pvs.XMLUnstructuredGridReader(FileName=["FiniteElementsOnTorusPoisson"+'_0.vtu'])
+slice1 = pvs.Slice(Input=finiteElementsOnTorus_0vtu)
+slice1.SliceType.Normal = [0.5, 0.5, 0.5]
+renderView1 = pvs.GetActiveViewOrCreate('RenderView')
+finiteElementsOnTorus_0vtuDisplay = pvs.Show(finiteElementsOnTorus_0vtu, renderView1)
+pvs.ColorBy(finiteElementsOnTorus_0vtuDisplay, ('POINTS', 'Numerical result field'))
+slice1Display = pvs.Show(slice1, renderView1)
+pvs.SaveScreenshot("./FiniteElementsOnTorusPoisson"+"_Slice"+'.png', magnification=1, quality=100, view=renderView1)
+plotOnSortedLines1 = pvs.PlotOnSortedLines(Input=slice1)
+lineChartView2 = pvs.CreateView('XYChartView')
+plotOnSortedLines1Display = pvs.Show(plotOnSortedLines1, lineChartView2)
+plotOnSortedLines1Display.UseIndexForXAxis = 0
+plotOnSortedLines1Display.XArrayName = 'arc_length'
+plotOnSortedLines1Display.SeriesVisibility = ['Numerical result field (1)']
+pvs.SaveScreenshot("./FiniteElementsOnTorusPoisson"+"_PlotOnSortedLine_"+'.png', magnification=1, quality=100, view=lineChartView2)
+pvs.Delete(lineChartView2)
+
+assert erreur_max/max_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DVF/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DVF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..caef0fe
--- /dev/null
@@ -0,0 +1,20 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_3DVF_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExamplePoisson_3DVF_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithLocRefCubes.med  )
+
+    ADD_TEST(ExamplePoisson_3DVF_CUBE_loc_ref ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
+
+    SET(MESH_FILE  ${MED_MESHES}/3DCheckerboard/checkerboard_4x4x4.med  )
+
+    ADD_TEST(ExamplePoisson_3DVF_CUBE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_CUBE.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DVF/FiniteVolumes3DPoisson_CUBE.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DVF/FiniteVolumes3DPoisson_CUBE.py
new file mode 100755 (executable)
index 0000000..066d1ff
--- /dev/null
@@ -0,0 +1,156 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur unu cube avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2016
+# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
+#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=sin(pi*x)*sin(pi*y)*sin(pi*z)
+#================================================================================================================================
+
+import cdmath
+from math import sin, pi, sqrt
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+import sys
+
+if len(sys.argv) >1 :#non rectangular mesh
+    my_mesh = cdmath.Mesh(sys.argv[1])
+else :   #rectangular mesh
+# Maillage du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
+#====================================================================================
+    xmin=0
+    xmax=1
+    ymin=0
+    ymax=1
+    zmin=0 
+    zmax=1
+    
+    nx=21
+    ny=21
+    nz=21
+    
+    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny,zmin,zmax,nz)
+
+if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
+
+eps=1e-6
+my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
+my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
+my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
+my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
+my_mesh.setGroupAtPlan(0,2,eps,"DirichletBorder")#Bord AVANT 
+my_mesh.setGroupAtPlan(1,2,eps,"DirichletBorder")#Bord ARRIERE 
+
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of cells ", nbCells)
+
+#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
+#================================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
+maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
+for i in range(nbCells): 
+       Ci = my_mesh.getCell(i)
+       x = Ci.x()
+       y = Ci.y()
+       z = Ci.z() 
+       my_RHSfield[i]=3*pi*pi*sin(pi*x)*sin(pi*y)*sin(pi*z)#mettre la fonction definie au second membre de l edp
+       # compute maximum number of neighbours
+       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print("Maximum number of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice et du vecteur second membre du système linéaire
+#===========================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbCells)
+#Parcours des cellules du domaine
+for i in range(nbCells):
+       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
+       Ci=my_mesh.getCell(i)
+       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
+               Fj=my_mesh.getFace(Ci.getFaceId(j))
+               if not Fj.isBorder():
+                       k=Fj.getCellId(0)
+                       if k==i :
+                               k=Fj.getCellId(1)
+                       Ck=my_mesh.getCell(k)
+                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
+                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
+               else:
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
+               Rigidite.addValue(i,i,coeff) # terme diagonal
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
+SolSyst=LS.solve()
+
+print("Preconditioner used : ", LS.getNameOfPc())
+print("Number of iterations used : ", LS.getNumberOfIter())
+print("Final residual : ", LS.getResidu())
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
+for i in range(nbCells):
+    my_ResultField[i]=SolSyst[i];
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteVolumes3DPoisson_CUBE_ResultField")
+
+#Postprocessing 
+#==============
+# save 3D picture
+resolution=100
+VTK_routines.Clip_VTK_data_to_VTK("FiniteVolumes3DPoisson_CUBE_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteVolumes3DPoisson_CUBE_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
+PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_CUBE_ResultField"+'_0.vtu',"ResultField",'CELLS',"Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_CUBE_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=np.linspace(0,sqrt(3),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+if len(sys.argv) >1 :
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 3D cube with  mesh '+my_mesh.getName())
+    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
+    plt.savefig("FiniteVolumes3DPoisson_CUBE_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
+else :   
+    plt.title('Plot over diagonal line for finite Volumes \n for Laplace operator on a 3D cube with a rectangular grid')
+    plt.plot(curv_abs, diag_data, label= str(nx) +'x'+str(ny)+ ' cells mesh')
+    plt.savefig("FiniteVolumes3DPoisson_CUBE_ResultField_"+str(nx) +'x'+str(ny)+ '_cells'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 3D poisson equation using finite volumes done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+#The following formulas use the fact that the exact solution is equal to the right hand side divided by 3*pi*pi
+max_abs_sol_exacte=max(my_RHSfield.max(),-my_RHSfield.min())/(3*pi*pi)
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbCells) :
+       if erreur_abs < abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i]) :
+               erreur_abs = abs(my_RHSfield[i]/(3*pi*pi) - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DVF_BALL/CMakeLists.txt b/CDMATH/tests/examples/PoissonEquation/Poisson3DVF_BALL/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..3a41485
--- /dev/null
@@ -0,0 +1,11 @@
+SET(MESH_FILE  ${MED_MESHES}/ballWithTetrahedra.med  )
+
+file(COPY ${MESH_FILE} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExamplePoisson_3DVF_BALL_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/FiniteVolumes3DPoisson_BALL.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/PoissonEquation/Poisson3DVF_BALL/FiniteVolumes3DPoisson_BALL.py b/CDMATH/tests/examples/PoissonEquation/Poisson3DVF_BALL/FiniteVolumes3DPoisson_BALL.py
new file mode 100755 (executable)
index 0000000..2c32135
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation de Poisson -\triangle u = f sur la boule unité  avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation de la méthode des volumes finis avec champs u et f discrétisés aux cellules d'un maillage quelconque
+#                              Création et sauvegarde du champ résultant ainsi que du champ second membre en utilisant CDMATH
+#               Comparaison de la solution numérique avec la solution exacte u=-(r-1)*r**2*sin(theta)**2*cos(phi)
+#================================================================================================================================
+
+import cdmath
+from math import sin, cos, pi, sqrt, atan2
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import PV_routines
+import VTK_routines
+
+import sys
+
+#Chargement du maillage tétraédrique du domaine cubique [0,1]x[0,1]x[0,1], définition des bords
+#==============================================================================================
+my_mesh = cdmath.Mesh("ballWithTetrahedra.med")
+if( my_mesh.getSpaceDimension()!=3 or my_mesh.getMeshDimension()!=3) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 3")
+
+eps=1e-6
+my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
+my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
+my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
+my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
+my_mesh.setGroupAtPlan(0,2,eps,"DirichletBorder")#Bord AVANT 
+my_mesh.setGroupAtPlan(1,2,eps,"DirichletBorder")#Bord ARRIERE 
+
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of cells ", nbCells)
+
+#Discrétisation du second membre et extraction du nb max de voisins d'une cellule
+#================================================================================
+my_RHSfield = cdmath.Field("RHS_field", cdmath.CELLS, my_mesh, 1)
+my_ExactSol = cdmath.Field("EXACT_SOL", cdmath.CELLS, my_mesh, 1)
+
+maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+#parcours des cellules pour discrétisation du second membre et extraction du nb max de voisins d'une cellule
+for i in range(nbCells): 
+       Ci = my_mesh.getCell(i)
+       x = Ci.x()
+       y = Ci.y()
+       z = Ci.z() 
+
+       r=sqrt(x*x+y*y+z*z)
+       phi=atan2(y,x)
+       theta=atan2(y,z*sin(phi))
+
+       my_RHSfield[i]=6*r*sin(theta)**2*cos(phi)+3*(r-1)*cos(phi)#mettre la fonction definie au second membre de l'edp
+       my_ExactSol[i]=-(r-1)*r**2*sin(theta)**2*cos(phi)
+       # compute maximum number of neighbours
+       maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
+
+print("Right hand side discretisation done")
+print("Maximum number of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice et du vecteur second membre du système linéaire
+#===========================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+RHS=cdmath.Vector(nbCells)
+#Parcours des cellules du domaine
+for i in range(nbCells):
+       RHS[i]=my_RHSfield[i] #la valeur moyenne du second membre f dans la cellule i
+       Ci=my_mesh.getCell(i)
+       for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
+               Fj=my_mesh.getFace(Ci.getFaceId(j))
+               if not Fj.isBorder():
+                       k=Fj.getCellId(0)
+                       if k==i :
+                               k=Fj.getCellId(1)
+                       Ck=my_mesh.getCell(k)
+                       distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/distance
+                       Rigidite.addValue(i,k,-coeff) # terme extradiagonal
+               else:
+                       coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
+               Rigidite.addValue(i,i,coeff) # terme diagonal
+
+print("Linear system matrix building done")
+
+# Résolution du système linéaire
+#=================================
+LS=cdmath.LinearSolver(Rigidite,RHS,500,1.E-6,"GMRES","ILU")
+SolSyst=LS.solve()
+
+print( "Preconditioner used : ", LS.getNameOfPc() )
+print( "Number of iterations used : ", LS.getNumberOfIter() )
+print( "Final residual : ", LS.getResidu() )
+print("Linear system solved")
+
+# Création du champ résultat
+#===========================
+my_ResultField = cdmath.Field("ResultField", cdmath.CELLS, my_mesh, 1)
+for i in range(nbCells):
+    my_ResultField[i]=SolSyst[i];
+#sauvegarde sur le disque dur du résultat dans un fichier paraview
+my_ResultField.writeVTK("FiniteVolumes3DPoisson_BALL_ResultField")
+
+#Postprocessing 
+#==============
+# save 3D picture
+resolution=100
+VTK_routines.Clip_VTK_data_to_VTK("FiniteVolumes3DPoisson_BALL_ResultField"+'_0.vtu',"Clip_VTK_data_to_VTK_"+ "FiniteVolumes3DPoisson_BALL_ResultField"+'_0.vtu',[0.5,0.5,0.5], [-0.5,-0.5,-0.5],resolution )
+PV_routines.Save_PV_data_to_picture_file("Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_BALL_ResultField"+'_0.vtu',"ResultField",'CELLS',"Clip_VTK_data_to_VTK_"+"FiniteVolumes3DPoisson_BALL_ResultField")
+
+# extract and plot diagonal values
+resolution=100
+curv_abs=np.linspace(0,sqrt(3),resolution+1)
+diag_data=VTK_routines.Extract_field_data_over_line_to_numpyArray(my_ResultField,[0,1,0],[1,0,0], resolution)
+plt.legend()
+plt.xlabel('Position on diagonal line')
+plt.ylabel('Value on diagonal line')
+if len(sys.argv) >1 :
+    plt.title('Plot over diagonal line for finite volumes \n for Laplace operator on a 3D BALL with  mesh '+my_mesh.getName())
+    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
+    plt.savefig("FiniteVolumes3DPoisson_BALL_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
+else :   
+    plt.title('Plot over diagonal line for finite volumes \n for Laplace operator on a 3D BALL with a rectangular grid')
+    plt.plot(curv_abs, diag_data, label= str(nbCells)+ ' cells mesh')
+    plt.savefig("FiniteVolumes3DPoisson_BALL_ResultField_"+str(nbCells)+ '_cells'+"_PlotOverDiagonalLine.png")
+
+print("Numerical solution of 3D poisson equation on a 3D ball using finite volumes done")
+
+#Calcul de l'erreur commise par rapport à la solution exacte
+#===========================================================
+max_abs_sol_exacte=max(my_ExactSol.max(),-my_ExactSol.min())
+max_sol_num=my_ResultField.max()
+min_sol_num=my_ResultField.min()
+erreur_abs=0
+for i in range(nbCells) :
+    if erreur_abs < abs(my_ExactSol[i] - my_ResultField[i]) :
+        erreur_abs = abs(my_ExactSol[i] - my_ResultField[i])
+
+print("Absolute error = max(| exact solution - numerical solution |) = ",erreur_abs )
+print("Relative error = max(| exact solution - numerical solution |)/max(| exact solution |) = ",erreur_abs/max_abs_sol_exacte)
+print("Maximum numerical solution = ", max_sol_num, " Minimum numerical solution = ", min_sol_num)
+
+assert erreur_abs/max_abs_sol_exacte <1.
diff --git a/CDMATH/tests/examples/SpectrumLaplace/CMakeLists.txt b/CDMATH/tests/examples/SpectrumLaplace/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..547d871
--- /dev/null
@@ -0,0 +1,15 @@
+file(GLOB SpectrumLaplace_EXAMPLES_TO_INSTALL 
+  SpectrumLaplace2DEF  SpectrumLaplace2DVF  SpectrumLaplaceBeltrami3DEF #Spectrum of Laplace operator
+)
+
+install(DIRECTORY ${SpectrumLaplace_EXAMPLES_TO_INSTALL} DESTINATION share/examples/SpectrumLaplace)
+
+IF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_SUBDIRECTORY(SpectrumLaplace2DEF)
+    ADD_SUBDIRECTORY(SpectrumLaplace2DVF)
+    ADD_SUBDIRECTORY(SpectrumLaplaceBeltrami3DEF)
+
+ENDIF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DEF/CMakeLists.txt b/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..1f49db1
--- /dev/null
@@ -0,0 +1,21 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    #Cartesian cells split into right triangles
+    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_rightTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+    SET(MESH_NAME  "DelaunayTriangles" )
+    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_DelaunayTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+    SET(MESH_FILE  ${MED_MESHES}/2DFlatCrossTriangles/squareWithFlatCrossTriangles_0.med  )
+    SET(MESH_NAME  "flatCrossTriangles" )
+    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_flatCrossTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+    SET(MESH_FILE  ${MED_MESHES}/2DSkinnyTriangles/squareWithSkinnyTriangles_0.med  )
+    SET(MESH_NAME  "skinnyTriangles" )
+    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_skinnyTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DEF/SpectrumLaplace2DEF_SQUARE.py b/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DEF/SpectrumLaplace2DEF_SQUARE.py
new file mode 100755 (executable)
index 0000000..3301a1d
--- /dev/null
@@ -0,0 +1,147 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Calcul EF du spectre de l'opérateur de Laplace 2D -\triangle avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2020
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs discrétisés aux noeuds d'un maillage triangulaire
+#                      Création et sauvegarde des champs résultant en utilisant la librairie CDMATH
+#================================================================================================================================
+
+import cdmath
+import sys
+
+if len(sys.argv) >2 :#load a mesh file
+    my_mesh = cdmath.Mesh(sys.argv[1])
+    mesh_name=sys.argv[2]
+else :   #rectangular mesh split into triangles
+    xmin=0
+    xmax=1
+    ymin=0
+    ymax=1
+    
+    nx=15
+    ny=15
+    
+    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny,0)
+    mesh_name="RightTriangles"
+
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+if(not my_mesh.isTriangular()) :
+       raise ValueError("Wrong cell types : mesh is not made of triangles")
+eps=1e-6
+my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
+my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
+my_mesh.setGroupAtPlan(0.,1,eps,"DirichletBorder")#Bord BAS
+my_mesh.setGroupAtPlan(1.,1,eps,"DirichletBorder")#Bord HAUT
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh loading done")
+print("Number of nodes=", nbNodes)
+print("Number of cells=", nbCells)
+
+#Détermination des noeuds intérieurs
+#===================================
+nbInteriorNodes = 0
+nbBoundaryNodes = 0
+maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+interiorNodes=[]
+boundaryNodes=[]
+
+#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
+for i in range(nbNodes):
+       Ni=my_mesh.getNode(i)
+       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
+               boundaryNodes.append(i)
+               nbBoundaryNodes=nbBoundaryNodes+1
+       else: # Détection des noeuds intérieurs
+               interiorNodes.append(i)
+               nbInteriorNodes=nbInteriorNodes+1
+               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
+
+print("nb of interior nodes=", nbInteriorNodes)
+print("nb of boundary nodes=", nbBoundaryNodes)
+print("Max nb of neighbours=", maxNbNeighbours)
+
+# Construction de la matrice de rigidité
+#========================================
+Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
+GradShapeFunc0=cdmath.Vector(2)
+GradShapeFunc1=cdmath.Vector(2)
+GradShapeFunc2=cdmath.Vector(2)
+
+nodal_volumes=cdmath.Vector(nbInteriorNodes)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= (N1.y()-N2.y())*0.5
+       GradShapeFunc0[1]=-(N1.x()-N2.x())*0.5
+       GradShapeFunc1[0]=-(N0.y()-N2.y())*0.5
+       GradShapeFunc1[1]= (N0.x()-N2.x())*0.5
+       GradShapeFunc2[0]= (N0.y()-N1.y())*0.5
+       GradShapeFunc2[1]=-(N0.x()-N1.x())*0.5
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2] :
+               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
+                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
+                       nodal_volumes[j_int]+=Ci.getMeasure()/3
+                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
+                       for k in [nodeId0,nodeId1,nodeId2] : 
+                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
+                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
+                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
+
+print("Stiffness matrix construction done")
+quit()
+# Conditionnement de la matrice de rigidité
+#=================================
+cond = Rigidite.getConditionNumber()
+print("Condition number is ",cond)
+
+# Spectre de la matrice de rigidité
+#==================================
+#Homogénéisation de la matrice de rigidité (sinon elle tend vers zero de meme que ses valeurs propres)
+for i in range(nbInteriorNodes):
+       nodal_volumes[i]=1/nodal_volumes[i]
+Rigidite.leftDiagonalScale(nodal_volumes)
+
+nev=10
+d=Rigidite.getEigenvectorsDataArrayDouble(nev)
+my_eigenfield = cdmath.Field("Eigenvectors field", cdmath.NODES, my_mesh, nev)
+for j in range(nbInteriorNodes):
+    for k in range(nev):
+      my_eigenfield[interiorNodes[j],k]=d[j,k];#remplissage des valeurs pour les noeuds intérieurs
+for j in range(nbBoundaryNodes):
+    for k in range(nev):
+      my_eigenfield[boundaryNodes[j],k]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
+for k in range(nev):
+    my_eigenfield.setInfoOnComponent(k,d.getInfoOnComponent(k))
+    
+# Sauvegarde du champ résultat
+#===========================
+my_eigenfield.writeVTK("spectrumFiniteElementsOn"+mesh_name+"Laplace")
diff --git a/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DVF/CMakeLists.txt b/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DVF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..a4c51ae
--- /dev/null
@@ -0,0 +1,33 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py )
+
+#    SET(MESH_FILE  ${MED_MESHES}/squareWithLocRefSquares.med  )
+#    SET(MESH_NAME  "LocRefSquares" )
+
+#    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_loc_ref ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithCheckerboardSquares.med  )
+    SET(MESH_NAME  "Checkerboard" )
+
+    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+    SET(MESH_NAME  "DelaunayTriangles" )
+
+    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_DelaunayTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+    SET(MESH_FILE  ${MED_MESHES}/2DFlatCrossTriangles/squareWithFlatCrossTriangles_0.med  )
+    SET(MESH_NAME  "flatCrossTriangles" )
+
+    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_flatCrossTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+    SET(MESH_FILE  ${MED_MESHES}/2DSkinnyTriangles/squareWithSkinnyTriangles_0.med  )
+    SET(MESH_NAME  "skinnyTriangles" )
+
+    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_skinnyTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DVF/SpectrumLaplace2DVF_SQUARE.py b/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplace2DVF/SpectrumLaplace2DVF_SQUARE.py
new file mode 100755 (executable)
index 0000000..a60054c
--- /dev/null
@@ -0,0 +1,92 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Calcul VF du spectre de l'opérateur de Laplace 2D -\triangle avec conditions aux limites de Dirichlet u=0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2020
+# Description : Utilisation de la méthode des volumes finis P1 avec champs discrétisés aux cellules d'un maillage quelconque
+#                      Création et sauvegarde des champs résultant en utilisant la librairie CDMATH
+#================================================================================================================================
+
+import cdmath
+import sys
+
+if len(sys.argv) >2 :#non rectangular mesh
+    my_mesh = cdmath.Mesh(sys.argv[1])
+    mesh_name=sys.argv[2]
+else :   #rectangular mesh
+# Création d'un maillage cartésien du domaine carré [0,1]x[0,1], définition des bords
+#====================================================================================
+    xmin=0
+    xmax=1
+    ymin=0
+    ymax=1
+    
+    nx=15
+    ny=15
+    
+    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny)
+    mesh_name="RegularGrid"
+
+    eps=1e-6
+    my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
+    my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
+    my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
+    my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
+
+nbCells = my_mesh.getNumberOfCells()
+
+if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
+    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
+
+print("Mesh loading done")
+print("Number of cells  = ", nbCells)
+
+#Détermination du nb max de voisins d'une cellule
+#================================================
+maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite volumes rigidity matrix
+#parcours des cellules pour extraction du nb max de voisins d'une cellule
+for i in range(nbCells): 
+    Ci=my_mesh.getCell(i)
+    # compute maximum number of neighbours
+    maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
+
+print("Max nb of neighbours = ", maxNbNeighbours)
+
+# Construction de la matrice et du vecteur second membre du système linéaire
+#===========================================================================
+Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
+#Parcours des cellules du domaine
+for i in range(nbCells):
+    Ci=my_mesh.getCell(i)
+    for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
+        Fj=my_mesh.getFace(Ci.getFaceId(j))
+        if not Fj.isBorder():
+            k=Fj.getCellId(0)
+            if k==i :
+                k=Fj.getCellId(1)
+            Ck=my_mesh.getCell(k)
+            distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
+            coeff=Fj.getMeasure()/Ci.getMeasure()/distance
+            Rigidite.addValue(i,k,-coeff) # terme extradiagonal
+        else:
+            coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
+            #For the particular case where the mesh boundary does not coincide with the domain boundary
+        Rigidite.addValue(i,i,coeff) # terme diagonal
+
+print("Stiffness matrix construction done")
+
+# Conditionnement de la matrice de rigidité
+#=================================
+cond = Rigidite.getConditionNumber()
+print("Condition number is ",cond)
+
+# Spectre de la matrice de rigidité
+#==================================
+nev=10
+d=Rigidite.getEigenvectorsDataArrayDouble(nev)
+my_eigenfield = cdmath.Field("Eigenvectors field", cdmath.CELLS, my_mesh, nev)
+my_eigenfield.setFieldByDataArrayDouble(d)
+
+# Sauvegarde du champ résultat
+#===========================
+my_eigenfield.writeVTK("spectrumFiniteVolumesOn"+mesh_name+"Laplace")
diff --git a/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplaceBeltrami3DEF/CMakeLists.txt b/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplaceBeltrami3DEF/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..0be7f11
--- /dev/null
@@ -0,0 +1,21 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSphere.med  )
+    SET(MESH_NAME  "Sphere" )
+
+    ADD_TEST(ExampleSpectrumLaplaceBeltrami_3DFE_SPHERE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumFiniteElements3DLaplace-Beltrami.py ${MESH_FILE} ${MESH_NAME} )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshTorus.med  )
+    SET(MESH_NAME  "Torus" )
+
+    ADD_TEST(ExampleSpectrumLaplaceBeltrami_3DFE_TORUS ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumFiniteElements3DLaplace-Beltrami.py ${MESH_FILE} ${MESH_NAME} )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCubeSkin.med  )
+    SET(MESH_NAME  "CubeSkin" )
+
+    ADD_TEST(ExampleSpectrumLaplaceBeltrami_3DFE_CUBESKIN ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumFiniteElements3DLaplace-Beltrami.py ${MESH_FILE} ${MESH_NAME} )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplaceBeltrami3DEF/SpectrumFiniteElements3DLaplace-Beltrami.py b/CDMATH/tests/examples/SpectrumLaplace/SpectrumLaplaceBeltrami3DEF/SpectrumFiniteElements3DLaplace-Beltrami.py
new file mode 100755 (executable)
index 0000000..a6b3f3e
--- /dev/null
@@ -0,0 +1,133 @@
+# -*-coding:utf-8 -*
+#===============================================================================================================================
+# Name        : Calcul EF du spectre de l'opérateur de Laplace-Beltrami -\triangle sur une surface en 3D
+# Author      : Michael Ndjinga
+# Copyright   : CEA Saclay 2020
+# Description : Utilisation de la méthode des éléménts finis P1 avec champs discrétisés aux noeuds d'un maillage triangulaire
+#               Création et sauvegarde des champs résultant en utilisant la librairie CDMATH
+#================================================================================================================================
+
+import cdmath
+import sys
+
+#Chargement du maillage triangulaire de la surface
+#=================================================
+my_mesh = cdmath.Mesh(sys.argv[1])
+mesh_name=sys.argv[2]
+if(not my_mesh.isTriangular()) :
+       raise ValueError("Wrong cell types : mesh is not made of triangles")
+if(my_mesh.getMeshDimension()!=2) :
+       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
+if(my_mesh.getSpaceDimension()!=3) :
+       raise ValueError("Wrong space dimension : expected a space of dimension 3")
+
+nbNodes = my_mesh.getNumberOfNodes()
+nbCells = my_mesh.getNumberOfCells()
+
+print("Mesh building/loading done")
+print("nb of nodes=", nbNodes)
+print("nb of cells=", nbCells)
+
+maxNbNeighbours = my_mesh.getMaxNbNeighbours(cdmath.NODES)+1#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
+
+# Construction de la matrice de rigidité
+#=======================================
+Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)# warning : third argument is number of non zero coefficients per line
+
+# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
+GradShapeFunc0=cdmath.Vector(3)
+GradShapeFunc1=cdmath.Vector(3)
+GradShapeFunc2=cdmath.Vector(3)
+
+normalFace0=cdmath.Vector(3)
+normalFace1=cdmath.Vector(3)
+
+nodal_volumes=cdmath.Vector(nbNodes)
+
+#On parcourt les triangles du domaine
+for i in range(nbCells):
+
+       Ci=my_mesh.getCell(i)
+
+       #Contribution à la matrice de rigidité
+       nodeId0=Ci.getNodeId(0)
+       nodeId1=Ci.getNodeId(1)
+       nodeId2=Ci.getNodeId(2)
+       N0=my_mesh.getNode(nodeId0)
+       N1=my_mesh.getNode(nodeId1)
+       N2=my_mesh.getNode(nodeId2)
+
+       #Build normal to cell Ci
+       normalFace0[0]=Ci.getNormalVector(0,0)
+       normalFace0[1]=Ci.getNormalVector(0,1)
+       normalFace0[2]=Ci.getNormalVector(0,2)
+       normalFace1[0]=Ci.getNormalVector(1,0)
+       normalFace1[1]=Ci.getNormalVector(1,1)
+       normalFace1[2]=Ci.getNormalVector(1,2)
+
+       normalCell = normalFace0.crossProduct(normalFace1)
+       normalCell = normalCell*(1/normalCell.norm())
+
+       cellMat=cdmath.Matrix(4)
+       cellMat[0,0]=N0.x()
+       cellMat[0,1]=N0.y()
+       cellMat[0,2]=N0.z()
+       cellMat[1,0]=N1.x()
+       cellMat[1,1]=N1.y()
+       cellMat[1,2]=N1.z()
+       cellMat[2,0]=N2.x()
+       cellMat[2,1]=N2.y()
+       cellMat[2,2]=N2.z()
+       cellMat[3,0]=normalCell[0]
+       cellMat[3,1]=normalCell[1]
+       cellMat[3,2]=normalCell[2]
+       cellMat[0,3]=1
+       cellMat[1,3]=1
+       cellMat[2,3]=1
+       cellMat[3,3]=0
+
+       #Formule des gradients voir EF P1 -> calcul déterminants
+       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
+       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
+       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
+       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
+       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
+       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
+       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
+       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
+       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
+
+       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
+       GradShapeFuncs={nodeId0 : GradShapeFunc0}
+       GradShapeFuncs[nodeId1]=GradShapeFunc1
+       GradShapeFuncs[nodeId2]=GradShapeFunc2
+
+       # Remplissage de  la matrice de rigidité et du second membre
+       for j in [nodeId0,nodeId1,nodeId2] : 
+               nodal_volumes[j]+=Ci.getMeasure()/3
+               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
+               for k in [nodeId0,nodeId1,nodeId2] : 
+                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
+
+print("Linear system matrix building done")
+
+# Conditionnement de la matrice de rigidité
+#==========================================
+cond = Rigidite.getConditionNumber(True)
+print("Condition number is ",cond)
+
+# Spectre de la matrice de rigidité
+#==================================
+#Homogénéisation de la matrice de rigidité (sinon elle tend vers zero de meme que ses valeurs propres)
+for i in range(nbNodes):
+       nodal_volumes[i]=1/nodal_volumes[i]
+Rigidite.leftDiagonalScale(nodal_volumes)
+
+nev=9
+d=Rigidite.getEigenvectorsDataArrayDouble(nev)
+my_eigenfield = cdmath.Field("Eigenvectors field", cdmath.NODES, my_mesh, nev)
+my_eigenfield.setFieldByDataArrayDouble(d)
+
+# Sauvegarde du champ résultat
+#===========================
+my_eigenfield.writeVTK("spectrumFiniteElementsOn"+mesh_name+"LaplaceBeltrami")
diff --git a/CDMATH/tests/examples/SpectrumLaplace2DEF/CMakeLists.txt b/CDMATH/tests/examples/SpectrumLaplace2DEF/CMakeLists.txt
deleted file mode 100755 (executable)
index 23bcad0..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    #Cartesian cells split into right triangles
-    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_rightTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py)
-
-    SET(MESH_FILE  ../../ressources/meshSquare.med  )
-    SET(MESH_NAME  "DelaunayTriangles" )
-    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_DelaunayTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-    SET(MESH_FILE  ../../ressources/2DFlatCrossTriangles/squareWithFlatCrossTriangles_0.med  )
-    SET(MESH_NAME  "flatCrossTriangles" )
-    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_flatCrossTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-    SET(MESH_FILE  ../../ressources/2DSkinnyTriangles/squareWithSkinnyTriangles_0.med  )
-    SET(MESH_NAME  "skinnyTriangles" )
-    ADD_TEST(ExampleSpectrumLaplace_2DEF_SQUARE_skinnyTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DEF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/SpectrumLaplace2DEF/SpectrumLaplace2DEF_SQUARE.py b/CDMATH/tests/examples/SpectrumLaplace2DEF/SpectrumLaplace2DEF_SQUARE.py
deleted file mode 100755 (executable)
index 3301a1d..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Calcul EF du spectre de l'opérateur de Laplace 2D -\triangle avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2020
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs discrétisés aux noeuds d'un maillage triangulaire
-#                      Création et sauvegarde des champs résultant en utilisant la librairie CDMATH
-#================================================================================================================================
-
-import cdmath
-import sys
-
-if len(sys.argv) >2 :#load a mesh file
-    my_mesh = cdmath.Mesh(sys.argv[1])
-    mesh_name=sys.argv[2]
-else :   #rectangular mesh split into triangles
-    xmin=0
-    xmax=1
-    ymin=0
-    ymax=1
-    
-    nx=15
-    ny=15
-    
-    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny,0)
-    mesh_name="RightTriangles"
-
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-if(not my_mesh.isTriangular()) :
-       raise ValueError("Wrong cell types : mesh is not made of triangles")
-eps=1e-6
-my_mesh.setGroupAtPlan(0.,0,eps,"DirichletBorder")#Bord GAUCHE
-my_mesh.setGroupAtPlan(1.,0,eps,"DirichletBorder")#Bord DROIT
-my_mesh.setGroupAtPlan(0.,1,eps,"DirichletBorder")#Bord BAS
-my_mesh.setGroupAtPlan(1.,1,eps,"DirichletBorder")#Bord HAUT
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh loading done")
-print("Number of nodes=", nbNodes)
-print("Number of cells=", nbCells)
-
-#Détermination des noeuds intérieurs
-#===================================
-nbInteriorNodes = 0
-nbBoundaryNodes = 0
-maxNbNeighbours = 0#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-interiorNodes=[]
-boundaryNodes=[]
-
-#parcours des noeuds pour discrétisation du second membre et extraction 1) des noeuds intérieur 2) des noeuds frontière 3) du nb max voisins d'un noeud
-for i in range(nbNodes):
-       Ni=my_mesh.getNode(i)
-       if my_mesh.isBorderNode(i): # Détection des noeuds frontière
-               boundaryNodes.append(i)
-               nbBoundaryNodes=nbBoundaryNodes+1
-       else: # Détection des noeuds intérieurs
-               interiorNodes.append(i)
-               nbInteriorNodes=nbInteriorNodes+1
-               maxNbNeighbours= max(1+Ni.getNumberOfCells(),maxNbNeighbours) #true only in 2D, otherwise use function Ni.getNumberOfEdges()
-
-print("nb of interior nodes=", nbInteriorNodes)
-print("nb of boundary nodes=", nbBoundaryNodes)
-print("Max nb of neighbours=", maxNbNeighbours)
-
-# Construction de la matrice de rigidité
-#========================================
-Rigidite=cdmath.SparseMatrixPetsc(nbInteriorNodes,nbInteriorNodes,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle (hypothèse 2D)
-GradShapeFunc0=cdmath.Vector(2)
-GradShapeFunc1=cdmath.Vector(2)
-GradShapeFunc2=cdmath.Vector(2)
-
-nodal_volumes=cdmath.Vector(nbInteriorNodes)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= (N1.y()-N2.y())*0.5
-       GradShapeFunc0[1]=-(N1.x()-N2.x())*0.5
-       GradShapeFunc1[0]=-(N0.y()-N2.y())*0.5
-       GradShapeFunc1[1]= (N0.x()-N2.x())*0.5
-       GradShapeFunc2[0]= (N0.y()-N1.y())*0.5
-       GradShapeFunc2[1]=-(N0.x()-N1.x())*0.5
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2] :
-               if boundaryNodes.count(j)==0 : #seuls les noeuds intérieurs contribuent au système linéaire (matrice de rigidité et second membre)
-                       j_int=interiorNodes.index(j)#indice du noeud j en tant que noeud intérieur
-                       nodal_volumes[j_int]+=Ci.getMeasure()/3
-                       #Contribution de la cellule triangulaire i à la ligne j_int du système linéaire
-                       for k in [nodeId0,nodeId1,nodeId2] : 
-                               if boundaryNodes.count(k)==0 : #seuls les noeuds intérieurs contribuent à la matrice du système linéaire
-                                       k_int=interiorNodes.index(k)#indice du noeud k en tant que noeud intérieur
-                                       Rigidite.addValue(j_int,k_int,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-                               #else: si condition limite non nulle au bord, ajouter la contribution du bord au second membre de la cellule j
-
-print("Stiffness matrix construction done")
-quit()
-# Conditionnement de la matrice de rigidité
-#=================================
-cond = Rigidite.getConditionNumber()
-print("Condition number is ",cond)
-
-# Spectre de la matrice de rigidité
-#==================================
-#Homogénéisation de la matrice de rigidité (sinon elle tend vers zero de meme que ses valeurs propres)
-for i in range(nbInteriorNodes):
-       nodal_volumes[i]=1/nodal_volumes[i]
-Rigidite.leftDiagonalScale(nodal_volumes)
-
-nev=10
-d=Rigidite.getEigenvectorsDataArrayDouble(nev)
-my_eigenfield = cdmath.Field("Eigenvectors field", cdmath.NODES, my_mesh, nev)
-for j in range(nbInteriorNodes):
-    for k in range(nev):
-      my_eigenfield[interiorNodes[j],k]=d[j,k];#remplissage des valeurs pour les noeuds intérieurs
-for j in range(nbBoundaryNodes):
-    for k in range(nev):
-      my_eigenfield[boundaryNodes[j],k]=0;#remplissage des valeurs pour les noeuds frontière (condition limite)
-for k in range(nev):
-    my_eigenfield.setInfoOnComponent(k,d.getInfoOnComponent(k))
-    
-# Sauvegarde du champ résultat
-#===========================
-my_eigenfield.writeVTK("spectrumFiniteElementsOn"+mesh_name+"Laplace")
diff --git a/CDMATH/tests/examples/SpectrumLaplace2DVF/CMakeLists.txt b/CDMATH/tests/examples/SpectrumLaplace2DVF/CMakeLists.txt
deleted file mode 100755 (executable)
index 115277c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py )
-
-#    SET(MESH_FILE  ../../ressources/squareWithLocRefSquares.med  )
-#    SET(MESH_NAME  "LocRefSquares" )
-
-#    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_loc_ref ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-    SET(MESH_FILE  ../../ressources/squareWithCheckerboardSquares.med  )
-    SET(MESH_NAME  "Checkerboard" )
-
-    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-    SET(MESH_FILE  ../../ressources/meshSquare.med  )
-    SET(MESH_NAME  "DelaunayTriangles" )
-
-    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_DelaunayTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-    SET(MESH_FILE  ../../ressources/2DFlatCrossTriangles/squareWithFlatCrossTriangles_0.med  )
-    SET(MESH_NAME  "flatCrossTriangles" )
-
-    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_flatCrossTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-    SET(MESH_FILE  ../../ressources/2DSkinnyTriangles/squareWithSkinnyTriangles_0.med  )
-    SET(MESH_NAME  "skinnyTriangles" )
-
-    ADD_TEST(ExampleSpectrumLaplace_2DVF_SQUARE_skinnyTriangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumLaplace2DVF_SQUARE.py ${MESH_FILE} ${MESH_NAME})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/SpectrumLaplace2DVF/SpectrumLaplace2DVF_SQUARE.py b/CDMATH/tests/examples/SpectrumLaplace2DVF/SpectrumLaplace2DVF_SQUARE.py
deleted file mode 100755 (executable)
index a60054c..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Calcul VF du spectre de l'opérateur de Laplace 2D -\triangle avec conditions aux limites de Dirichlet u=0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2020
-# Description : Utilisation de la méthode des volumes finis P1 avec champs discrétisés aux cellules d'un maillage quelconque
-#                      Création et sauvegarde des champs résultant en utilisant la librairie CDMATH
-#================================================================================================================================
-
-import cdmath
-import sys
-
-if len(sys.argv) >2 :#non rectangular mesh
-    my_mesh = cdmath.Mesh(sys.argv[1])
-    mesh_name=sys.argv[2]
-else :   #rectangular mesh
-# Création d'un maillage cartésien du domaine carré [0,1]x[0,1], définition des bords
-#====================================================================================
-    xmin=0
-    xmax=1
-    ymin=0
-    ymax=1
-    
-    nx=15
-    ny=15
-    
-    my_mesh = cdmath.Mesh(xmin,xmax,nx,ymin,ymax,ny)
-    mesh_name="RegularGrid"
-
-    eps=1e-6
-    my_mesh.setGroupAtPlan(0,0,eps,"DirichletBorder")#Bord GAUCHE
-    my_mesh.setGroupAtPlan(1,0,eps,"DirichletBorder")#Bord DROIT
-    my_mesh.setGroupAtPlan(0,1,eps,"DirichletBorder")#Bord BAS
-    my_mesh.setGroupAtPlan(1,1,eps,"DirichletBorder")#Bord HAUT
-
-nbCells = my_mesh.getNumberOfCells()
-
-if( my_mesh.getSpaceDimension()!=2 or my_mesh.getMeshDimension()!=2) :
-    raise ValueError("Wrong space or mesh dimension : space and mesh dimensions should be 2")
-
-print("Mesh loading done")
-print("Number of cells  = ", nbCells)
-
-#Détermination du nb max de voisins d'une cellule
-#================================================
-maxNbNeighbours=0#This is to determine the number of non zero coefficients in the sparse finite volumes rigidity matrix
-#parcours des cellules pour extraction du nb max de voisins d'une cellule
-for i in range(nbCells): 
-    Ci=my_mesh.getCell(i)
-    # compute maximum number of neighbours
-    maxNbNeighbours= max(1+Ci.getNumberOfFaces(),maxNbNeighbours)
-
-print("Max nb of neighbours = ", maxNbNeighbours)
-
-# Construction de la matrice et du vecteur second membre du système linéaire
-#===========================================================================
-Rigidite=cdmath.SparseMatrixPetsc(nbCells,nbCells,maxNbNeighbours)# warning : third argument is max number of non zero coefficients per line of the matrix
-#Parcours des cellules du domaine
-for i in range(nbCells):
-    Ci=my_mesh.getCell(i)
-    for j in range(Ci.getNumberOfFaces()):# parcours des faces voisinnes
-        Fj=my_mesh.getFace(Ci.getFaceId(j))
-        if not Fj.isBorder():
-            k=Fj.getCellId(0)
-            if k==i :
-                k=Fj.getCellId(1)
-            Ck=my_mesh.getCell(k)
-            distance=Ci.getBarryCenter().distance(Ck.getBarryCenter())
-            coeff=Fj.getMeasure()/Ci.getMeasure()/distance
-            Rigidite.addValue(i,k,-coeff) # terme extradiagonal
-        else:
-            coeff=Fj.getMeasure()/Ci.getMeasure()/Ci.getBarryCenter().distance(Fj.getBarryCenter())
-            #For the particular case where the mesh boundary does not coincide with the domain boundary
-        Rigidite.addValue(i,i,coeff) # terme diagonal
-
-print("Stiffness matrix construction done")
-
-# Conditionnement de la matrice de rigidité
-#=================================
-cond = Rigidite.getConditionNumber()
-print("Condition number is ",cond)
-
-# Spectre de la matrice de rigidité
-#==================================
-nev=10
-d=Rigidite.getEigenvectorsDataArrayDouble(nev)
-my_eigenfield = cdmath.Field("Eigenvectors field", cdmath.CELLS, my_mesh, nev)
-my_eigenfield.setFieldByDataArrayDouble(d)
-
-# Sauvegarde du champ résultat
-#===========================
-my_eigenfield.writeVTK("spectrumFiniteVolumesOn"+mesh_name+"Laplace")
diff --git a/CDMATH/tests/examples/SpectrumLaplaceBeltrami3DEF/CMakeLists.txt b/CDMATH/tests/examples/SpectrumLaplaceBeltrami3DEF/CMakeLists.txt
deleted file mode 100755 (executable)
index cf124a8..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(MESH_FILE  ../../ressources/meshSphere.med  )
-    SET(MESH_NAME  "Sphere" )
-
-    ADD_TEST(ExampleSpectrumLaplaceBeltrami_3DFE_SPHERE ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumFiniteElements3DLaplace-Beltrami.py ${MESH_FILE} ${MESH_NAME} )
-
-    SET(MESH_FILE  ../../ressources/meshTorus.med  )
-    SET(MESH_NAME  "Torus" )
-
-    ADD_TEST(ExampleSpectrumLaplaceBeltrami_3DFE_TORUS ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumFiniteElements3DLaplace-Beltrami.py ${MESH_FILE} ${MESH_NAME} )
-
-    SET(MESH_FILE  ../../ressources/meshCubeSkin.med  )
-    SET(MESH_NAME  "CubeSkin" )
-
-    ADD_TEST(ExampleSpectrumLaplaceBeltrami_3DFE_CUBESKIN ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SpectrumFiniteElements3DLaplace-Beltrami.py ${MESH_FILE} ${MESH_NAME} )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/SpectrumLaplaceBeltrami3DEF/SpectrumFiniteElements3DLaplace-Beltrami.py b/CDMATH/tests/examples/SpectrumLaplaceBeltrami3DEF/SpectrumFiniteElements3DLaplace-Beltrami.py
deleted file mode 100755 (executable)
index a6b3f3e..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-# -*-coding:utf-8 -*
-#===============================================================================================================================
-# Name        : Calcul EF du spectre de l'opérateur de Laplace-Beltrami -\triangle sur une surface en 3D
-# Author      : Michael Ndjinga
-# Copyright   : CEA Saclay 2020
-# Description : Utilisation de la méthode des éléménts finis P1 avec champs discrétisés aux noeuds d'un maillage triangulaire
-#               Création et sauvegarde des champs résultant en utilisant la librairie CDMATH
-#================================================================================================================================
-
-import cdmath
-import sys
-
-#Chargement du maillage triangulaire de la surface
-#=================================================
-my_mesh = cdmath.Mesh(sys.argv[1])
-mesh_name=sys.argv[2]
-if(not my_mesh.isTriangular()) :
-       raise ValueError("Wrong cell types : mesh is not made of triangles")
-if(my_mesh.getMeshDimension()!=2) :
-       raise ValueError("Wrong mesh dimension : expected a surface of dimension 2")
-if(my_mesh.getSpaceDimension()!=3) :
-       raise ValueError("Wrong space dimension : expected a space of dimension 3")
-
-nbNodes = my_mesh.getNumberOfNodes()
-nbCells = my_mesh.getNumberOfCells()
-
-print("Mesh building/loading done")
-print("nb of nodes=", nbNodes)
-print("nb of cells=", nbCells)
-
-maxNbNeighbours = my_mesh.getMaxNbNeighbours(cdmath.NODES)+1#This is to determine the number of non zero coefficients in the sparse finite element rigidity matrix
-
-# Construction de la matrice de rigidité
-#=======================================
-Rigidite=cdmath.SparseMatrixPetsc(nbNodes,nbNodes,maxNbNeighbours)# warning : third argument is number of non zero coefficients per line
-
-# Vecteurs gradient de la fonction de forme associée à chaque noeud d'un triangle
-GradShapeFunc0=cdmath.Vector(3)
-GradShapeFunc1=cdmath.Vector(3)
-GradShapeFunc2=cdmath.Vector(3)
-
-normalFace0=cdmath.Vector(3)
-normalFace1=cdmath.Vector(3)
-
-nodal_volumes=cdmath.Vector(nbNodes)
-
-#On parcourt les triangles du domaine
-for i in range(nbCells):
-
-       Ci=my_mesh.getCell(i)
-
-       #Contribution à la matrice de rigidité
-       nodeId0=Ci.getNodeId(0)
-       nodeId1=Ci.getNodeId(1)
-       nodeId2=Ci.getNodeId(2)
-       N0=my_mesh.getNode(nodeId0)
-       N1=my_mesh.getNode(nodeId1)
-       N2=my_mesh.getNode(nodeId2)
-
-       #Build normal to cell Ci
-       normalFace0[0]=Ci.getNormalVector(0,0)
-       normalFace0[1]=Ci.getNormalVector(0,1)
-       normalFace0[2]=Ci.getNormalVector(0,2)
-       normalFace1[0]=Ci.getNormalVector(1,0)
-       normalFace1[1]=Ci.getNormalVector(1,1)
-       normalFace1[2]=Ci.getNormalVector(1,2)
-
-       normalCell = normalFace0.crossProduct(normalFace1)
-       normalCell = normalCell*(1/normalCell.norm())
-
-       cellMat=cdmath.Matrix(4)
-       cellMat[0,0]=N0.x()
-       cellMat[0,1]=N0.y()
-       cellMat[0,2]=N0.z()
-       cellMat[1,0]=N1.x()
-       cellMat[1,1]=N1.y()
-       cellMat[1,2]=N1.z()
-       cellMat[2,0]=N2.x()
-       cellMat[2,1]=N2.y()
-       cellMat[2,2]=N2.z()
-       cellMat[3,0]=normalCell[0]
-       cellMat[3,1]=normalCell[1]
-       cellMat[3,2]=normalCell[2]
-       cellMat[0,3]=1
-       cellMat[1,3]=1
-       cellMat[2,3]=1
-       cellMat[3,3]=0
-
-       #Formule des gradients voir EF P1 -> calcul déterminants
-       GradShapeFunc0[0]= cellMat.partMatrix(0,0).determinant()*0.5
-       GradShapeFunc0[1]=-cellMat.partMatrix(0,1).determinant()*0.5
-       GradShapeFunc0[2]= cellMat.partMatrix(0,2).determinant()*0.5
-       GradShapeFunc1[0]=-cellMat.partMatrix(1,0).determinant()*0.5
-       GradShapeFunc1[1]= cellMat.partMatrix(1,1).determinant()*0.5
-       GradShapeFunc1[2]=-cellMat.partMatrix(1,2).determinant()*0.5
-       GradShapeFunc2[0]= cellMat.partMatrix(2,0).determinant()*0.5
-       GradShapeFunc2[1]=-cellMat.partMatrix(2,1).determinant()*0.5
-       GradShapeFunc2[2]= cellMat.partMatrix(2,2).determinant()*0.5
-
-       #Création d'un tableau (numéro du noeud, gradient de la fonction de forme
-       GradShapeFuncs={nodeId0 : GradShapeFunc0}
-       GradShapeFuncs[nodeId1]=GradShapeFunc1
-       GradShapeFuncs[nodeId2]=GradShapeFunc2
-
-       # Remplissage de  la matrice de rigidité et du second membre
-       for j in [nodeId0,nodeId1,nodeId2] : 
-               nodal_volumes[j]+=Ci.getMeasure()/3
-               #Contribution de la cellule triangulaire i à la ligne j du système linéaire
-               for k in [nodeId0,nodeId1,nodeId2] : 
-                       Rigidite.addValue(j,k,GradShapeFuncs[j]*GradShapeFuncs[k]/Ci.getMeasure())
-
-print("Linear system matrix building done")
-
-# Conditionnement de la matrice de rigidité
-#==========================================
-cond = Rigidite.getConditionNumber(True)
-print("Condition number is ",cond)
-
-# Spectre de la matrice de rigidité
-#==================================
-#Homogénéisation de la matrice de rigidité (sinon elle tend vers zero de meme que ses valeurs propres)
-for i in range(nbNodes):
-       nodal_volumes[i]=1/nodal_volumes[i]
-Rigidite.leftDiagonalScale(nodal_volumes)
-
-nev=9
-d=Rigidite.getEigenvectorsDataArrayDouble(nev)
-my_eigenfield = cdmath.Field("Eigenvectors field", cdmath.NODES, my_mesh, nev)
-my_eigenfield.setFieldByDataArrayDouble(d)
-
-# Sauvegarde du champ résultat
-#===========================
-my_eigenfield.writeVTK("spectrumFiniteElementsOn"+mesh_name+"LaplaceBeltrami")
index de602006177f47121e50ab0ef24e259d7a929a70..e7a89159333fe85823b1102973510b7201d28957 100755 (executable)
@@ -1,8 +1,18 @@
+file(GLOB TransportEquation_EXAMPLES_TO_INSTALL 
+  TransportEquation1DUpwindExplicit TransportEquation1DUpwindImplicit TransportEquation1DCenteredImplicit TransportEquation1DCenteredExplicit # 1D Transport equation 
+  TransportEquation
+)
 
-if (CDMATH_WITH_PYTHON )
+install(DIRECTORY ${TransportEquation_EXAMPLES_TO_INSTALL} DESTINATION share/examples/TransportEquation)
 
-    ADD_TEST(ExampleTransportEquation_2DUpwind_Explicit ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/TransportEquationUpwind.py)
+IF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
 
-endif (CDMATH_WITH_PYTHON )
+    ADD_SUBDIRECTORY(TransportEquation1DUpwindExplicit)
+    ADD_SUBDIRECTORY(TransportEquation1DUpwindImplicit)
+    ADD_SUBDIRECTORY(TransportEquation1DCenteredImplicit)
+    ADD_SUBDIRECTORY(TransportEquation1DCenteredExplicit)
+    ADD_SUBDIRECTORY(TransportEquation)
+
+ENDIF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
 
 
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation/TransportEquation/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..de60200
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON )
+
+    ADD_TEST(ExampleTransportEquation_2DUpwind_Explicit ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/TransportEquationUpwind.py)
+
+endif (CDMATH_WITH_PYTHON )
+
+
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation/TransportEquationUpwind.py b/CDMATH/tests/examples/TransportEquation/TransportEquation/TransportEquationUpwind.py
new file mode 100755 (executable)
index 0000000..7047c70
--- /dev/null
@@ -0,0 +1,250 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+from math import sin, cos, pi, sqrt
+import time, json
+import cdmath
+import PV_routines
+import VTK_routines
+
+precision=1e-5
+
+def initial_conditions_transport_equation(my_mesh):
+    print( "Initial_data","Shock")
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    initial_field = cdmath.Field("unknown", cdmath.CELLS, my_mesh, 1)
+
+    rayon = 0.15
+    xcentre = 0.5
+    ycentre = 0.5
+    zcentre = 0.5
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+
+        valX = (x - xcentre) * (x - xcentre)
+        
+        if(dim==1):
+            val=sqrt(valX)
+        if(dim==2):
+            y = my_mesh.getCell(i).y()
+            valY = (y - ycentre) * (y - ycentre)
+            val =  sqrt(valX + valY)
+        if(dim==3):
+            y = my_mesh.getCell(i).y()
+            z = my_mesh.getCell(i).z()
+            valY = (y - ycentre) * (y - ycentre)
+            valZ = (z - zcentre) * (z - zcentre)
+            val =  sqrt(valX + valY + valZ)
+
+        if val < rayon:
+            initial_field[i] = 1
+            pass
+        else:
+            initial_field[i] = 0
+            pass
+        pass
+        
+    return initial_field
+
+def upwinding_coeff(normal, coeff, velocity):
+    dim=normal.size()
+    
+    if(velocity*normal<0.):
+        return velocity*normal*coeff
+    else:
+        return 0.
+    
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,test_bc,velocity):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            Am=upwinding_coeff( normal,dt*Fk.getMeasure()/Cj.getMeasure(),velocity);
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( test_bc=="Periodic" and Fk.getGroupName() != "Neumann"):#Periodic boundary condition unless Wall/Neumann specified explicitly
+                    indexFP = my_mesh.getIndexFacePeriodic(indexFace, my_mesh.getName()== "squareWithBrickWall", my_mesh.getName()== "squareWithHexagons")
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif(test_bc!="Neumann" and Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+                
+    return implMat
+
+def TransportEquationVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution,test_bc,velocity,isImplicit):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False
+    
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    
+    #iteration vectors
+    Un =cdmath.Vector(nbCells)
+    dUn=cdmath.Vector(nbCells)
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    stat_field = initial_conditions_transport_equation(my_mesh)
+    for k in range(nbCells):
+        Un[k] =     stat_field[k]
+    unknown_field = initial_conditions_transport_equation(my_mesh)
+    S = cdmath.Vector(nbCells)#source term is zero
+            
+    total_mass_initial=unknown_field.integral()#For conservation test later
+    
+    #sauvegarde de la donnée initiale
+    unknown_field.writeVTK("TransportEquation"+str(dim)+"DUpwind"+meshName);
+
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / velocity.norm()
+
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,test_bc,velocity)
+    if(isImplicit):
+        #Adding the identity matrix on the diagonal
+        divMat.diagonalShift(1)#only after  filling all coefficients
+        #for j in range(nbCells*(dim+1)):
+        #    divMat.addValue(j,j,1)
+        
+        iterGMRESMax=50
+        LS=cdmath.LinearSolver(divMat,Un+S*dt,iterGMRESMax, precision, "GMRES","ILU")
+        LS.setComputeConditionNumber()
+        
+    print("Starting computation of the linear transport equation with an Upwind scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        if(isImplicit):
+            dUn=Un.deepCopy()
+            LS.setSndMember(Un+S*dt)
+            Un=LS.solve();
+            if(not LS.getStatus()):
+                print("Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
+                raise ValueError("Pas de convergence du système linéaire");
+            dUn-=Un
+
+        else:
+            dUn=divMat*Un-S*dt
+            Un-=dUn
+        
+        maxVector=dUn.maxVector(1)
+        isStationary= maxVector[0]<precision 
+
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+            print( "Variation temporelle relative : ", maxVector[0] )
+            if(isImplicit):
+                print( "Linear system converged in ", LS.getNumberOfIter(), " GMRES iterations" )
+
+            for k in range(nbCells):
+                unknown_field[k]  =Un[k]
+
+            unknown_field.setTime(time,it);
+            unknown_field.writeVTK("TransportEquation"+str(dim)+"DUpwind"+meshName,False);
+
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "Variation temporelle relative : ", maxVector[0] )
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
+        raise ValueError("Maximum number of time steps reached : Stationary state not found !!!!!!!")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        if(test_bc=="Periodic"):
+            print( "Mass loss: ", (total_mass_initial-unknown_field.integral()).norm(), " precision required= ", precision )
+            assert (total_mass_initial-unknown_field.integral()).norm()<precision
+        print( "------------------------------------------------------------------------------------")
+
+        unknown_field.setTime(time,0);
+        unknown_field.writeVTK("TransportEquation"+str(dim)+"DUpwind"+meshName+"_Stat");
+
+        #Postprocessing : Extraction of the diagonal data
+        if(dim==2):
+            diag_data_u=VTK_routines.Extract_field_data_over_line_to_numpyArray(unknown_field,[0,1,0],[1,0,0], resolution)    
+        elif(dim==3):
+            diag_data_u=VTK_routines.Extract_field_data_over_line_to_numpyArray(unknown_field,[0,0,0],[1,1,1], resolution)    
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("TransportEquation"+str(dim)+"DUpwind"+meshName+"_Stat"+'_0.vtu',"unknown",'CELLS',"TransportEquation"+str(dim)+"DUpwind"+meshName+"_Stat")
+        
+        return nbCells, time, it, unknown_field.getNormEuclidean().max(), diag_data_u        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint" )
+        raise ValueError("Maximum time reached : Stationary state not found !!!!!!!")
+
+
+def solve(my_mesh, meshName, resolution, meshType, cfl, test_bc):
+    print( "Resolution of the Transport Equation in dimension ", my_mesh.getMeshDimension() )
+    print( "Numerical method : ", "Upwind" )
+    print( "Initial data : ", "Spherical shock" )
+    print( "Mesh name : ",meshName , ", ", my_mesh.getNumberOfCells(), " cells" )
+    
+    # Problem data
+    tmax = 10000.
+    ntmax = 30000
+    output_freq = 1000
+
+    isImplicit=True
+    
+    dim=my_mesh.getMeshDimension()
+    velocity=cdmath.Vector(dim)
+    for i in range(dim) :
+        velocity[i] = 1
+
+    nbCells, t_final, ndt_final, max_unknown, diag_data_u = TransportEquationVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution, test_bc, velocity,isImplicit)
+
+    return nbCells, t_final, ndt_final, max_unknown, diag_data_u
+
+def solve_file( filename,meshName, resolution,meshType, cfl, test_bc):
+    my_mesh = cdmath.Mesh(filename+".med")
+
+    return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution, meshType, cfl, test_bc)
+    
+
+if __name__ == """__main__""":
+    M1=cdmath.Mesh(0.,1.,20,0.,1.,20,0)
+    cfl=0.5
+    solve(M1,"SquareRegularTriangles",100,"Regular triangles",cfl,"Periodic")
+
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredExplicit/1DTransportEquationCenteredExplicit.py b/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredExplicit/1DTransportEquationCenteredExplicit.py
new file mode 100755 (executable)
index 0000000..9b4336e
--- /dev/null
@@ -0,0 +1,117 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
+# Author      : Michaël Ndjinga, Katia Ait Ameur
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation du schéma centré explicite sur un maillage 1D régulier
+#                      Création et sauvegarde du champ résultant et des figures
+#               Génération d'une video sauvegardée dans un fichier .mp4
+#================================================================================================================================
+
+
+from math import sin, pi, ceil
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+from copy import deepcopy
+
+def Transport1DCenteredExplicit(nx,cfl, isSmooth):
+    print( "Simulation of 1D transport equation with explicit centered scheme" )
+
+    ##################### Simulation parameters
+    a = 0.0 # space domain :  a <= x <= b
+    b = 1.0
+    dx = (b - a) / nx #space step
+
+    c = 0.25 # advection velocity
+    dt = cfl * dx / c
+
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+    
+    ########################## Initial data
+    
+    if(isSmooth):
+        print( "Smooth initial data" )
+        u_initial = [ sin(2*pi*xi)  for xi in x];# to be used with a=0, b=1
+        tmax = 3*(b-a)/c # runs the simulation for 0 <= t <= tMax
+    else:
+        print( "Stiff initial data" )
+        u_initial = [ int(1./3<xi)*int(xi<2./3)  for xi in x];# to be used with a=0, b=1
+        tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
+    ntmax = ceil(tmax/dt)
+
+    u = deepcopy(u_initial)
+    
+    max_initial=max(u_initial)
+    min_initial=min(u_initial)
+
+    time = 0.
+    it = 0
+    output_freq = int(10/cfl)
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Centered explicit scheme for transport equation", artist = "CEA Saclay", comment="CFL="+str(cfl)+", Stable if CFL<1")
+    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "1DTransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+".mp4", ntmax):
+        ########################### Postprocessing initialisation
+        # Picture frame
+        plt.legend()
+        plt.xlabel('x')
+        plt.ylabel('u')
+        plt.xlim(a,b)
+        plt.ylim( min_initial - 0.5*(max_initial-min_initial), max_initial +  0.5*(max_initial-min_initial) )
+        plt.title('Centered explicit scheme for transport equation')
+        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
+    
+        print("Starting time loop")
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+        np.savetxt( "TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
+        writer.grab_frame()
+        plt.savefig("TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_0.png")
+
+        ############################# Time loop
+        while (it < ntmax and time <= tmax):
+            un=deepcopy(u)
+            for i in range(nx):
+                u[i] = un[i] - c * dt / dx * (un[(i+1)%nx] - un[(i-1)%nx])/2
+    
+            time += dt
+            it += 1
+
+            # Postprocessing
+            line1.set_ydata(u)
+            writer.grab_frame()
+            if (it % output_freq == 0):
+                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+                np.savetxt( "TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
+                plt.savefig("TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
+                #plt.show()
+
+    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
+    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
+    print( "Exact solution variation : ",    np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
+    print( "l1 numerical error       : ", dx*np.sum([abs(u[i]         - u_initial[i]       ) for i in range(nx)]))
+
+    print( "Simulation of 1D transport equation with explicit centered scheme done" )
+
+    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
+
+
+if __name__ == """__main__""":
+    if len(sys.argv) >3 :
+        nx = int(sys.argv[1])
+        cfl = float(sys.argv[2])
+        isSmooth=bool(int(sys.argv[3]))
+        Transport1DCenteredExplicit(nx,cfl,isSmooth)
+    else :
+        nx = 50 # number of cells
+        cfl = 0.99 # c*dt/dx <= CFL
+        isSmooth=True
+        Transport1DCenteredExplicit(nx,cfl,isSmooth)
+    
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredExplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredExplicit/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..cc7cf3a
--- /dev/null
@@ -0,0 +1,29 @@
+
+if (CDMATH_WITH_PYTHON )
+
+    SET(NX 50 )#Number of cells
+
+    SET(SMOOTHNESS  0 )
+
+    SET(CFL  0.99  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Stiff_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} )
+
+   SET(CFL  0.5  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Stiff_CFL0.5 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} ) 
+
+
+    SET(SMOOTHNESS  1 )
+
+    SET(CFL  0.99  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Smooth_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} )
+
+    SET(CFL  0.5  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Smooth_CFL0.5 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} )
+
+endif (CDMATH_WITH_PYTHON )
+
+
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredImplicit/1DTransportEquationCenteredImplicit.py b/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredImplicit/1DTransportEquationCenteredImplicit.py
new file mode 100755 (executable)
index 0000000..af12e79
--- /dev/null
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
+# Author      : Michaël Ndjinga, Katia Ait Ameur
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation du schéma centré implicite sur un maillage 1D régulier
+#               Schéma à 3 points implicite
+#                      Création et sauvegarde du champ résultant et des figures
+#               Génération d'une video sauvegardée dans un fichier .mp4
+#================================================================================================================================
+
+
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+from math import sin, pi, ceil
+import cdmath
+
+def centeredSchemeMatrix(nx,cfl):
+    centeredMat=cdmath.SparseMatrixPetsc(nx,nx,3)
+    for i in range(nx):
+        centeredMat.setValue(i,(i+1)%nx,cfl/2)
+        centeredMat.setValue(i,i,1.)
+        centeredMat.setValue(i,(i-1)%nx,-cfl/2.)
+
+    return centeredMat
+    
+def Transport1DCenteredImplicit(nx,cfl):
+    print( "Simulation of 1D transport equation with implicit centered scheme" )
+
+    ##################### Simulation parameters
+    a = 0.0 # space domain :  a <= x <= b
+    b = 1.0
+    dx = (b - a) / nx #space step
+
+    c = 0.25 # advection velocity
+    tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
+    dt = cfl * dx / c
+    ntmax = ceil(tmax/dt)
+
+    if(cfl>nx):
+        raise("Impossible to run this simulation with cfl>nx. Choose another value for nx or cfl.")
+        
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+    
+    ########################## Initial data
+    
+    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+
+    max_initial=max(u_initial)
+    min_initial=min(u_initial)
+    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
+
+    time = 0.
+    it = 0
+    output_freq = 10
+        
+    #Linear system initialisation
+    systemMat=centeredSchemeMatrix(nx,cfl)
+    iterGMRESMax=50
+    precision=1.e-5
+    Un =cdmath.Vector(nx)
+    for i in range(nx):
+        Un[i]=u[i]
+    LS=cdmath.LinearSolver(systemMat,Un,iterGMRESMax, precision, "GMRES","ILU")
+    LS.setComputeConditionNumber()
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Centered implicit scheme for transport equation, "+"CFL="+str(cfl), artist = "CEA Saclay", comment="Stable for any CFL>0")
+    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "1DTransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
+        ########################### Postprocessing initialisation
+        # Picture frame
+        plt.legend()
+        plt.xlabel('x')
+        plt.ylabel('u')
+        plt.xlim(a,b)
+        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
+        plt.title("Centered implicit scheme for transport equation, "+"CFL="+str(cfl))
+        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
+
+        print("Starting time loop")
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+        np.savetxt( "TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
+        writer.grab_frame()
+        plt.savefig("TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
+    
+        ############################# Time loop
+        while (it < ntmax and time <= tmax):
+            # Solve linear system
+            for i in range(nx):
+                Un[i]=u[i]
+            LS.setSndMember(Un)
+            Un=LS.solve()
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
+                raise ValueError("Pas de convergence du système linéaire");
+            for i in range(nx):
+                u[i]=Un[i]
+    
+            if ( max(u) > max_initial ):
+                print( "-- Iter: " + str(it) + " max principle violated : max(t) > max(0) : max(t)= ",max(u), " max(0)= ", max_initial )
+            if ( min(u) < min_initial ):
+                print( "-- Iter: " + str(it) + " min principle violated : min(t) < min(0) : min(t)= ",min(u), " min(0)= ", min_initial )
+            if ( np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) > total_var_initial ):
+                print( "-- Iter: " + str(it) + " total variation increased : var(t) > var(0) : var(t)= ", np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), " var(0)= ", total_var_initial )
+
+            time += dt
+            it += 1
+
+            # Postprocessing
+            line1.set_ydata(u)
+            writer.grab_frame()
+            if (it % output_freq == 0):
+                print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+                np.savetxt( "TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
+                plt.savefig("TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
+                #plt.show()
+
+    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
+    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
+    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
+    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) )       
+    
+    print("Simulation of transport equation with implicit centered scheme done.")
+    
+    #return min, max, total variation and l1 error
+    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
+
+
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        nx = int(sys.argv[1])
+        cfl = float(sys.argv[2])
+        Transport1DCenteredImplicit(nx,cfl)
+    else :
+        nx = 50 # number of cells
+        cfl = 0.99 # c*dt/dx <= CFL
+        Transport1DCenteredImplicit(nx,cfl)
+    
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredImplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation/TransportEquation1DCenteredImplicit/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..b2ffc39
--- /dev/null
@@ -0,0 +1,17 @@
+
+if (CDMATH_WITH_PYTHON )
+
+    SET(NX 50 )#Number of cells
+
+    SET(CFL  1  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_Centered_Implicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredImplicit.py ${NX} ${CFL})
+
+    SET(CFL  2  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_Centered_Implicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredImplicit.py ${NX} ${CFL})
+
+
+endif (CDMATH_WITH_PYTHON )
+
+
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindExplicit/1DTransportEquationUpwindExplicit.py b/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindExplicit/1DTransportEquationUpwindExplicit.py
new file mode 100755 (executable)
index 0000000..d49da95
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
+# Author      : Michaël Ndjinga, Katia Ait Ameur
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation du schéma upwind explicite sur un maillage 1D régulier
+#                      Création et sauvegarde du champ résultant et des figures
+#               Génération d'une video sauvegardée dans un fichier .mp4
+#================================================================================================================================
+
+
+from math import sin, pi, ceil
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+from copy import deepcopy
+
+def Transport1DUpwindExplicit(nx,cfl):
+    print( "Simulation of 1D transport equation with explicit upwind scheme" )
+
+    ##################### Simulation parameters
+    a = 0.0 # space domain :  a <= x <= b
+    b = 1.0
+    dx = (b - a) / nx #space step
+
+    c = 0.25 # advection velocity
+    tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
+    dt = cfl * dx / c
+    ntmax = ceil(tmax/dt)
+
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+    
+    ########################## Initial data
+    
+    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+
+    max_initial=max(u_initial)
+    min_initial=min(u_initial)
+    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
+
+    time = 0.
+    it = 0
+    output_freq = 10
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Upwind explicit scheme for transport equation, CFL="+str(cfl), artist = "CEA Saclay", comment="Stable if CFL<1")
+    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "1DTransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
+        ########################### Postprocessing initialisation
+        # Picture frame
+        plt.legend()
+        plt.xlabel('x')
+        plt.ylabel('u')
+        plt.xlim(a,b)
+        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
+        plt.title("Upwind explicit scheme for transport equation, CFL="+str(cfl))
+        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
+    
+        print("Starting time loop")
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+        np.savetxt( "TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
+        writer.grab_frame()
+        plt.savefig("TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
+
+        ############################# Time loop
+        while (it < ntmax and time <= tmax):
+            un=deepcopy(u)
+            for i in range(nx):
+                u[i] = un[i] - c * dt / dx * (un[i] - un[(i-1)%nx])
+    
+            time += dt
+            it += 1
+
+            if cfl<1 :
+                assert max(u) <= max_initial
+                assert min(u) >= min_initial
+                assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial + 1e-15#Tiny margin required
+
+            # Postprocessing
+            line1.set_ydata(u)
+            writer.grab_frame()
+            if (it % output_freq == 0):
+                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+                np.savetxt( "TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
+                plt.savefig("TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
+                #plt.show()
+
+    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
+    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
+    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
+    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) )       
+    
+    print("Simulation of transport equation with explicit upwind scheme done.")
+    
+    #return min, max, total variation and l1 error
+    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
+
+
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        nx = int(sys.argv[1])
+        cfl = float(sys.argv[2])
+        Transport1DUpwindExplicit(nx,cfl)
+    else :
+        nx = 50 # number of cells
+        cfl = 0.99 # c*dt/dx <= CFL
+        Transport1DUpwindExplicit(nx,cfl)
+    
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindExplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindExplicit/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..f1fe640
--- /dev/null
@@ -0,0 +1,20 @@
+
+if (CDMATH_WITH_PYTHON )
+
+    SET(NX 100 )#Number of cells
+
+    SET(CFL  0.9999  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Explicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindExplicit.py ${NX} ${CFL})
+
+    SET(CFL  0.5  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Explicit_CFL0.5 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindExplicit.py ${NX} ${CFL})
+
+    SET(CFL  2  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Explicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindExplicit.py ${NX} ${CFL})
+
+endif (CDMATH_WITH_PYTHON )
+
+
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindImplicit/1DTransportEquationUpwindImplicit.py b/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindImplicit/1DTransportEquationUpwindImplicit.py
new file mode 100755 (executable)
index 0000000..6f990fb
--- /dev/null
@@ -0,0 +1,142 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
+# Author      : Michaël Ndjinga, Katia Ait Ameur
+# Copyright   : CEA Saclay 2018
+# Description : Utilisation du schéma upwind implicite sur un maillage 1D régulier
+#                      Création et sauvegarde du champ résultant et des figures
+#               Génération d'une video sauvegardée dans un fichier .mp4
+#================================================================================================================================
+
+
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+from math import sin, pi, ceil
+import cdmath
+
+precision=1.e-5
+
+def upwindSchemeMatrix(nx,cfl):
+    upwindMat=cdmath.SparseMatrixPetsc(nx,nx,2)
+    for i in range(nx):
+        upwindMat.setValue(i,i,1+cfl)
+        upwindMat.setValue(i,(i-1)%nx,-cfl)
+
+    return upwindMat
+    
+def Transport1DUpwindImplicit(nx,cfl):
+    print( "Simulation of 1D transport equation with implicit upwind scheme" )
+
+    ##################### Simulation parameters
+    a = 0.0 # space domain :  a <= x <= b
+    b = 1.0
+    dx = (b - a) / nx #space step
+
+    c = 0.25 # advection velocity
+    tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
+    dt = cfl * dx / c
+    ntmax = ceil(tmax/dt)
+
+    if(cfl>nx):
+        raise("Impossible to run this simulation with cfl>nx. Choose another value for nx or cfl.")
+        
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+    
+    ########################## Initial data
+    
+    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
+
+    max_initial=max(u_initial)
+    min_initial=min(u_initial)
+    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
+
+    time = 0.
+    it = 0
+    output_freq = 10
+        
+    #Linear system initialisation
+    systemMat=upwindSchemeMatrix(nx,cfl)
+    iterGMRESMax=50
+    Un =cdmath.Vector(nx)
+    for i in range(nx):
+        Un[i]=u[i]
+    LS=cdmath.LinearSolver(systemMat,Un,iterGMRESMax, precision, "GMRES","ILU")
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Upwind implicit scheme for transport equation, "+"CFL="+str(cfl), artist = "CEA Saclay", comment="Stable for any CFL>0")
+    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "1DTransportEquation_UpwindImplicit_"+str(nx)+"CELLS_CFL"+str(cfl)+".mp4", ntmax):
+        ########################### Postprocessing initialisation
+        # Picture frame
+        plt.legend()
+        plt.xlabel('x')
+        plt.ylabel('u')
+        plt.xlim(a,b)
+        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
+        plt.title("Upwind implicit scheme for transport equation, "+"CFL="+str(cfl))
+        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
+
+        print("Starting time loop")
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+        np.savetxt( "TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
+        writer.grab_frame()
+        plt.savefig("TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
+    
+        ############################# Time loop
+        while (it < ntmax and time <= tmax):
+            # Solve linear system
+            for i in range(nx):
+                Un[i]=u[i]
+            LS.setSndMember(Un)
+            Un=LS.solve()
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
+                raise ValueError("Pas de convergence du système linéaire");
+            for i in range(nx):
+                u[i]=Un[i]
+    
+            time += dt
+            it += 1
+
+            assert max(u) <= max_initial
+            assert min(u) >= min_initial
+            assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial
+
+            # Postprocessing
+            line1.set_ydata(u)
+            writer.grab_frame()
+            if (it % output_freq == 0):
+                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+                np.savetxt( "TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
+                plt.savefig("TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
+                #plt.show()
+
+    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
+    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
+    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
+    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) )       
+    
+    print("Simulation of transport equation with implicit upwind scheme done.")
+    
+    #return min, max, total variation and l1 error
+    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
+
+
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        nx = int(sys.argv[1])
+        cfl = float(sys.argv[2])
+        Transport1DUpwindImplicit(nx,cfl)
+    else :
+        nx = 50 # number of cells
+        cfl = 0.99 # c*dt/dx <= CFL
+        Transport1DUpwindImplicit(nx,cfl)
+    
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindImplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation/TransportEquation1DUpwindImplicit/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..1045385
--- /dev/null
@@ -0,0 +1,17 @@
+
+if (CDMATH_WITH_PYTHON )
+
+    SET(NX 50 )#Number of cells
+
+    SET(CFL  1  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Implicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindImplicit.py ${NX} ${CFL})
+
+    SET(CFL  2  )#Courant Friedrichs Lewy number
+
+    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Implicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindImplicit.py ${NX} ${CFL})
+
+
+endif (CDMATH_WITH_PYTHON )
+
+
diff --git a/CDMATH/tests/examples/TransportEquation/TransportEquationUpwind.py b/CDMATH/tests/examples/TransportEquation/TransportEquationUpwind.py
deleted file mode 100755 (executable)
index 7047c70..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-from math import sin, cos, pi, sqrt
-import time, json
-import cdmath
-import PV_routines
-import VTK_routines
-
-precision=1e-5
-
-def initial_conditions_transport_equation(my_mesh):
-    print( "Initial_data","Shock")
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    initial_field = cdmath.Field("unknown", cdmath.CELLS, my_mesh, 1)
-
-    rayon = 0.15
-    xcentre = 0.5
-    ycentre = 0.5
-    zcentre = 0.5
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-
-        valX = (x - xcentre) * (x - xcentre)
-        
-        if(dim==1):
-            val=sqrt(valX)
-        if(dim==2):
-            y = my_mesh.getCell(i).y()
-            valY = (y - ycentre) * (y - ycentre)
-            val =  sqrt(valX + valY)
-        if(dim==3):
-            y = my_mesh.getCell(i).y()
-            z = my_mesh.getCell(i).z()
-            valY = (y - ycentre) * (y - ycentre)
-            valZ = (z - zcentre) * (z - zcentre)
-            val =  sqrt(valX + valY + valZ)
-
-        if val < rayon:
-            initial_field[i] = 1
-            pass
-        else:
-            initial_field[i] = 0
-            pass
-        pass
-        
-    return initial_field
-
-def upwinding_coeff(normal, coeff, velocity):
-    dim=normal.size()
-    
-    if(velocity*normal<0.):
-        return velocity*normal*coeff
-    else:
-        return 0.
-    
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,test_bc,velocity):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            Am=upwinding_coeff( normal,dt*Fk.getMeasure()/Cj.getMeasure(),velocity);
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( test_bc=="Periodic" and Fk.getGroupName() != "Neumann"):#Periodic boundary condition unless Wall/Neumann specified explicitly
-                    indexFP = my_mesh.getIndexFacePeriodic(indexFace, my_mesh.getName()== "squareWithBrickWall", my_mesh.getName()== "squareWithHexagons")
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(test_bc!="Neumann" and Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-                
-    return implMat
-
-def TransportEquationVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution,test_bc,velocity,isImplicit):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False
-    
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    
-    #iteration vectors
-    Un =cdmath.Vector(nbCells)
-    dUn=cdmath.Vector(nbCells)
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    stat_field = initial_conditions_transport_equation(my_mesh)
-    for k in range(nbCells):
-        Un[k] =     stat_field[k]
-    unknown_field = initial_conditions_transport_equation(my_mesh)
-    S = cdmath.Vector(nbCells)#source term is zero
-            
-    total_mass_initial=unknown_field.integral()#For conservation test later
-    
-    #sauvegarde de la donnée initiale
-    unknown_field.writeVTK("TransportEquation"+str(dim)+"DUpwind"+meshName);
-
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / velocity.norm()
-
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,test_bc,velocity)
-    if(isImplicit):
-        #Adding the identity matrix on the diagonal
-        divMat.diagonalShift(1)#only after  filling all coefficients
-        #for j in range(nbCells*(dim+1)):
-        #    divMat.addValue(j,j,1)
-        
-        iterGMRESMax=50
-        LS=cdmath.LinearSolver(divMat,Un+S*dt,iterGMRESMax, precision, "GMRES","ILU")
-        LS.setComputeConditionNumber()
-        
-    print("Starting computation of the linear transport equation with an Upwind scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        if(isImplicit):
-            dUn=Un.deepCopy()
-            LS.setSndMember(Un+S*dt)
-            Un=LS.solve();
-            if(not LS.getStatus()):
-                print("Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
-                raise ValueError("Pas de convergence du système linéaire");
-            dUn-=Un
-
-        else:
-            dUn=divMat*Un-S*dt
-            Un-=dUn
-        
-        maxVector=dUn.maxVector(1)
-        isStationary= maxVector[0]<precision 
-
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-            print( "Variation temporelle relative : ", maxVector[0] )
-            if(isImplicit):
-                print( "Linear system converged in ", LS.getNumberOfIter(), " GMRES iterations" )
-
-            for k in range(nbCells):
-                unknown_field[k]  =Un[k]
-
-            unknown_field.setTime(time,it);
-            unknown_field.writeVTK("TransportEquation"+str(dim)+"DUpwind"+meshName,False);
-
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "Variation temporelle relative : ", maxVector[0] )
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
-        raise ValueError("Maximum number of time steps reached : Stationary state not found !!!!!!!")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        if(test_bc=="Periodic"):
-            print( "Mass loss: ", (total_mass_initial-unknown_field.integral()).norm(), " precision required= ", precision )
-            assert (total_mass_initial-unknown_field.integral()).norm()<precision
-        print( "------------------------------------------------------------------------------------")
-
-        unknown_field.setTime(time,0);
-        unknown_field.writeVTK("TransportEquation"+str(dim)+"DUpwind"+meshName+"_Stat");
-
-        #Postprocessing : Extraction of the diagonal data
-        if(dim==2):
-            diag_data_u=VTK_routines.Extract_field_data_over_line_to_numpyArray(unknown_field,[0,1,0],[1,0,0], resolution)    
-        elif(dim==3):
-            diag_data_u=VTK_routines.Extract_field_data_over_line_to_numpyArray(unknown_field,[0,0,0],[1,1,1], resolution)    
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("TransportEquation"+str(dim)+"DUpwind"+meshName+"_Stat"+'_0.vtu',"unknown",'CELLS',"TransportEquation"+str(dim)+"DUpwind"+meshName+"_Stat")
-        
-        return nbCells, time, it, unknown_field.getNormEuclidean().max(), diag_data_u        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint" )
-        raise ValueError("Maximum time reached : Stationary state not found !!!!!!!")
-
-
-def solve(my_mesh, meshName, resolution, meshType, cfl, test_bc):
-    print( "Resolution of the Transport Equation in dimension ", my_mesh.getMeshDimension() )
-    print( "Numerical method : ", "Upwind" )
-    print( "Initial data : ", "Spherical shock" )
-    print( "Mesh name : ",meshName , ", ", my_mesh.getNumberOfCells(), " cells" )
-    
-    # Problem data
-    tmax = 10000.
-    ntmax = 30000
-    output_freq = 1000
-
-    isImplicit=True
-    
-    dim=my_mesh.getMeshDimension()
-    velocity=cdmath.Vector(dim)
-    for i in range(dim) :
-        velocity[i] = 1
-
-    nbCells, t_final, ndt_final, max_unknown, diag_data_u = TransportEquationVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution, test_bc, velocity,isImplicit)
-
-    return nbCells, t_final, ndt_final, max_unknown, diag_data_u
-
-def solve_file( filename,meshName, resolution,meshType, cfl, test_bc):
-    my_mesh = cdmath.Mesh(filename+".med")
-
-    return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution, meshType, cfl, test_bc)
-    
-
-if __name__ == """__main__""":
-    M1=cdmath.Mesh(0.,1.,20,0.,1.,20,0)
-    cfl=0.5
-    solve(M1,"SquareRegularTriangles",100,"Regular triangles",cfl,"Periodic")
-
diff --git a/CDMATH/tests/examples/TransportEquation/thermique1d/main.cxx b/CDMATH/tests/examples/TransportEquation/thermique1d/main.cxx
new file mode 100755 (executable)
index 0000000..b80f292
--- /dev/null
@@ -0,0 +1,335 @@
+//============================================================================
+// Name        : Thermique 1D Entrée sortie
+// Author      : M. Ndjinga
+// Version     :
+// Copyright   : CEA Saclay 2014
+// Description : Modélisation 1D d'un cœur de réacteur
+//============================================================================
+
+#include <iostream>
+#include <cmath>
+//#include<complex>
+
+//#include "Matrix.hxx"
+#include "Vector.hxx"
+#include "LinearSolver.hxx"
+#include "Mesh.hxx"
+#include "Field.hxx"
+#include "Cell.hxx"
+//#include "Face.hxx"
+//#include "Node.hxx"
+#include "CdmathException.hxx"
+
+using namespace std;
+
+
+void champ_heaviside(Field& Temp, double milieu, double TempLeft, double TempRight)
+{
+    Mesh M=Temp.getMesh();
+    int nbCells=M.getNumberOfCells();
+    double x;
+    for (int j=0 ; j<nbCells ; j++)
+    {
+        x = M.getCell(j).x() ;
+        //cout<<"cellule "<< j<<" x= "<< x<<" milieu= "<< milieu <<endl;
+        if (x<milieu)
+            Temp(j) = TempLeft;
+        else
+            Temp(j) = TempRight;
+    }
+}
+
+
+double sign(double x)
+{
+    if(x>0)
+        return 1.;
+    else if(x<0)
+            return -1.;
+        else
+            return 0.;
+}
+
+
+double theta_upwind(double Tim1, double Ti, double Tip1, double Tip2, double VitesseX, double dt, double Tin, double Tip1n)
+{
+    if(abs(Tip1-Ti)<1.e-5)
+        return 1.;
+
+    double denominateur = abs(VitesseX)*(2.-sign(Tip1-Ti)*(sign(Tip2-Tip1)+sign(Ti-Tim1)));
+
+    if( abs(denominateur) <=1.e-5 )
+                return 0.5;
+    else
+    {
+        double result = (1-sign(Tip1-Ti)*sign(Ti-Tim1))/denominateur;
+        if(result <0.5)
+            return 0.5;
+        else
+            return result;
+    }
+}
+
+
+void solveTriDiag(vector<double>& a,vector<double>& b,vector<double>& c,Field &d, int nbCells)
+{
+    int n= nbCells;
+
+    if(a.size()!=c.size() || a.size()+1 != b.size() || n != (int) b.size() || n != (int) (d.getMesh()).getNumberOfCells())
+        throw CdmathException("solveTriDiag(): vectors with inapropriate size");
+
+/*  cout<<"avant solveTri"<<endl;
+    for(int i=0;i<nbCells-2;i++)
+        cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
+
+    /* Algorithme de résolution d'un Système Tridiagonal*/
+         n--; // since we start from x0 (not x1)
+         c[0] /= b[0];
+         d[0] /= b[0];
+         for (int i = 1; i < n; i++) {
+            c[i] /= b[i] - a[i-1]*c[i-1];
+            d[i] = (d[i] - a[i-1]*d[i-1]) / (b[i] - a[i-1]*c[i-1]);
+            }
+
+            d[n] = (d[n] - a[n-1]*d[n-1]) / (b[n] - a[n-1]*c[n-1]);
+
+            for (int i = n; i-- > 0;) {
+                d[i] -= c[i]*d[i+1];
+            }
+
+        /*cout<<"apres solveTri"<<endl;
+        for(int i=0;i<nbCells-2;i++)
+            cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
+}
+
+
+void solveEntreeImplicit(Field& phi, Field& Temp, int nbCells, double VitesseX, double cfl, double Tentree, double dt) {
+
+    /* Coefficients de la matrice tridiagonalee liee au systeme*/
+    /*b=coeff diag, c= coeff au dessus diag, a= coeff sous diag */
+    vector<double> a(nbCells-1),b(nbCells),c(nbCells-1);
+    double theta, epsilon=1.e-2, erreur=1/epsilon;
+    int iterMax=100, k=0;
+    Field d, ScndMbre=phi, Tempn=Temp;
+    ScndMbre*=dt;
+    ScndMbre+=Tempn;//On obtient Tn+dt*phi
+    //On décentre le terme source
+    for (int i = 1; i < nbCells-1; i++)
+        {
+        ScndMbre[i]-=cfl*(phi[i]-phi[i-1])*dt/2;
+        }
+    ScndMbre[0]-=cfl*(phi[0])*dt/2;
+        //d[0]-=cfl*(phi[n-1]-phi[n-2]);
+
+    if(nbCells<3)
+        throw CdmathException("solveEntreeImplicit(): mesh should have at least three cells");
+
+    while( k<iterMax && erreur>epsilon)
+    {
+    d= ScndMbre;//contiendra le second membre du système
+    /*cout<< " Debut itération d= "<<endl;
+    for(int i=0;i<nbCells-1;i++)
+            cout<< " , "<< d(i);
+    cout<<endl;*/
+    cout<<"theta="<<endl;
+    /* On traite la première face (entrée) */
+    theta=theta_upwind(Tentree,Tentree,Temp(0),Temp(1),VitesseX, dt, Tentree, Tempn(0));
+    b[0]=1+ cfl*(2*theta-1);
+    c[0]=(1-theta)*cfl;
+    d(0)+=theta*cfl*Tentree;
+
+    cout<< theta << " , ";
+
+    /* On traite la deuxième face interne */
+    theta=theta_upwind(Tentree,Temp(0),Temp(1),Temp(2),VitesseX, dt, Tempn(0), Tempn(1));
+    b[1]=1+ cfl*(2*theta-1);
+    c[1]=(1-theta)*cfl;
+    a[0]=-theta*cfl;
+
+    cout<< theta << " , ";
+
+    //On traite les faces internes
+    for(int i=2; i<nbCells-2; i++)
+    {
+        theta=theta_upwind(Temp(i-2),Temp(i-1),Temp(i),Temp(i+1),VitesseX, dt, Tempn(i-1), Tempn(i));
+        b[i]=1+ cfl*(2*theta-1);
+        c[i]=(1-theta)*cfl;
+        a[i-1]=-theta*cfl;
+        cout<< theta << " , ";
+    }
+
+    /* On traite l'avant dernière face interne */
+    theta=theta_upwind(Temp(nbCells-3),Temp(nbCells-2),Temp(nbCells-1),Temp(nbCells-1),VitesseX, dt, Tempn(nbCells-2), Tempn(nbCells-1));
+    b[nbCells-2]=1+ cfl*(2*theta-1);
+    c[nbCells-2]=(1-theta)*cfl;
+    a[nbCells-3]=-theta*cfl;
+
+    cout<< theta << " , ";
+
+    /* On traite la dernière face (sortie) */
+    theta=theta_upwind(Temp(nbCells-2),Temp(nbCells-1),Temp(nbCells-1),Temp(nbCells-1),VitesseX, dt, Tempn(nbCells-1), Tempn(nbCells));
+    b[nbCells-1]=1+ cfl*theta;
+    a[nbCells-2]=-theta*cfl;
+    //d(nbCells-1)+=-(1-theta_sortie)*cfl*Tempn(nbCells-1);
+
+    cout<< theta << endl;
+
+    cout<<" k= " << k<<endl;
+    /*cout<<"avant solveTri"<<endl;
+    for(int i=0;i<nbCells-2;i++)
+        cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
+    solveTriDiag(a,b,c,d,nbCells);
+    /*cout<<"après solveTri"<<endl;
+    for(int i=0;i<nbCells-2;i++)
+        cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
+    k++;
+    erreur = 0;
+    for(int i=0;i<nbCells; i++)
+        erreur=max(erreur, abs(Temp(i)-d[i])/300);
+    cout<< " erreur= "<<erreur<<endl;
+    /*cout<< " Fin itération d= "<<endl;
+    for(int i=0;i<nbCells-1;i++)
+            cout<< " , "<< d(i);
+    cout<<endl;*/
+    Temp=d;
+//  for(int i=0;i<nbCells-1;i++)
+//      cout<< " Temp= "<< Temp(i)<<endl;
+    }
+
+    if(k>=iterMax)
+        throw CdmathException("solveEntreeImplicit: Newton scheme not convergent");
+}
+
+
+void EquationTransport1D_entree(double tmax, double VitesseX, int ntmax, double dt, double cfl,int freqSortie, const Mesh& M, const string file, double milieu, double TempLeft, double TempRight)
+{
+    /* --------------------------------------------- */
+    /* Condition initiale */
+    cout << "Construction de la condition initiale ... " << endl;
+    Field Temp("Temperature",CELLS,M,1) ;
+    champ_heaviside(Temp,milieu,TempLeft, TempRight);
+
+    /*terme source */
+    cout << "Construction du terme source ... " << endl;
+    Field phi("Flux thermique",CELLS,M,1) ;
+    champ_heaviside(phi,milieu,-10, 10);
+    /*
+     * Sortie MED de la condition initiale et du flux thermique à t=0 et iter = 0
+     */
+    int iter=0;
+    double time=0.;
+    int nbCells=M.getNumberOfCells();
+    cout << "Post-traitement MED du flux thermique constant en temps"<< " ..." << endl;
+    //phi.setTime(time,iter);
+    //phi.writeCSV(file);
+    cout << "Post-traitement MED de la solution à t=" << time << " ..." << endl;
+    Temp.setTime(time,iter);
+    //Temp.writeCSV(file);
+    Temp.writeVTK(file);
+    /* boucle de temps */
+    cout << " Resolution de l'equation de transport 1D avec entree par un schema Implicite TVD" << endl;
+
+    while (iter<ntmax && time <= tmax )
+    {
+        cout << "-- Iter : " << iter << " Time : " << time << " dt : " << dt << endl;
+
+        /* Avancement en temps */
+            solveEntreeImplicit(phi, Temp,nbCells, VitesseX, cfl, TempLeft, dt);
+        time+=dt;
+        iter+=1;
+        // sortie visu tous les freq iterations
+        if (iter%freqSortie==0)
+        {
+            Temp.setTime(time,iter);
+            Temp.writeVTK(file,false);
+            //Temp.writeCSV(file);
+        }
+    }
+}
+
+
+int Equation_Transport()
+{
+    cout << "RESOLUTION EQUATION DE TRANSPORT 1D :" << endl;
+    cout << "- DOMAINE : Segment 0,10" << endl;
+    cout << "- MAILLAGE CARTESIEN : GENERATION INTERNE CDMATH " << endl;
+
+    // Problem data
+    double VitesseX=1.0;
+    double tmax=100.;
+    int freqSortie=1;
+    int ntmax=3;
+    int nx=50;
+    double xinf=0.0;
+    double xsup=10.;
+    double dx=(xsup-xinf)/nx;
+    double cfl=1;
+    double dt=cfl*dx/abs(VitesseX);
+
+    double TempLeft=300;//285.;
+    double TempRight=300;//315.;
+
+    cout << "Début Construction du maillage Cartesien…" << endl;
+    Mesh M(xinf,xsup,nx);
+    cout << "Fin Construction du maillage Cartesien…" << endl;
+
+    //  theta=1;
+    EquationTransport1D_entree(tmax, VitesseX, ntmax, dt, cfl, freqSortie, M, "TemperatureEntreeImplicitTVD50CellsSourceUpwind", (xsup+xinf)/2, TempLeft, TempRight);
+    //EquationTransport1D_entree(tmax, VitesseX, ntmax, dt, cfl, freqSortie, M, "TemperatureEntreeImplicitUpwindCreneau50Cells", (xsup+xinf)/4, TempLeft, TempRight);
+
+    cout << "CDMATH calculation done." << endl;
+    return 0;
+}
+
+
+int main() {
+/* Test solveur tridiagonal
+    int n=6;
+    Matrix A2(n,n,n+2*(n-1));
+
+       A2(0,0)=2.;
+       vector<double> e(n-1);
+       for(int i=0;i<n-1;i++)
+           {
+           e[i]=-1/(i+1);
+           A2(i,i+1)=-1/(i+1);
+           A2(i+1,i)=-1.;
+           A2(i+1,i+1)=2.;
+           }
+       Vector Xana2(n);
+       for(int i=0;i<n;i++)
+            Xana2(i)=i;
+
+       Vector B2=A2*Xana2;
+
+       LinearSolver LS11(A2,B2,500,1.E-10,"GMRES","ILU");
+       Vector X11=LS11.solve();
+       bool correct=true;
+       for (int i=0;i<X11.getNumberOfRows();i++)
+        correct=correct && (abs(X11(i)-Xana2(i))<1.E-10);
+
+       if(correct)
+           cout<<"OK"<<endl;
+       else
+           cout<<"KO"<<endl;
+       vector<double> a(n-1,-1),b(n,2),c(n-1,-0.5);
+       Mesh M(0,1,n);
+       Field d("Test",CELLS,M,1);
+       int nbCells=M.getNumberOfCells();
+       for(int i=0;i<nbCells;i++)
+           d[i]=B2(i);
+       solveTriDiag(a,b,e,d,nbCells);
+       correct=true;
+       for (int i=0;i<X11.getNumberOfRows();i++)
+        correct=correct && (abs(d(i)-Xana2(i))<1.E-10);
+
+       if(correct)
+           cout<<"OK"<<endl;
+       else
+           cout<<"KO"<<endl;
+
+        Fin Test solveur tridiagonal */
+
+       int ret=Equation_Transport();
+       return ret;
+}
diff --git a/CDMATH/tests/examples/TransportEquation/thermique1d/makefile b/CDMATH/tests/examples/TransportEquation/thermique1d/makefile
new file mode 100755 (executable)
index 0000000..8c7b9db
--- /dev/null
@@ -0,0 +1,28 @@
+# thermique1d makefile
+
+CC = g++
+
+# Adapt the following lines to your own system:
+PETSCDIR = /usr/lib/petscdir/3.4.5
+MPIDIR = /usr/lib/openmpi
+CDMATHDIR = ../../../../..
+
+IFLAG = -I$(PETSCDIR)/include -I$(MPIDIR)/include -I$(CDMATHDIR)/include -I.
+LFLAG = -L$(CDMATHDIR)/lib
+LIBS  = -linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver
+OBJ = main.o
+
+all: $(OBJ)
+       $(CC) -o main $^ $(IFLAG) $(LFLAG) $(LIBS)
+       
+%.o: %.cxx
+       $(CC) -c -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
+       
+.PHONY: clean
+
+clean:
+       rm -f *.o *~ core $(INCDIR)/*~
+
+sweep:
+       rm -f *.vtu
+       rm -f *.pvd
diff --git a/CDMATH/tests/examples/TransportEquation/transport1d/main.cxx b/CDMATH/tests/examples/TransportEquation/transport1d/main.cxx
new file mode 100755 (executable)
index 0000000..e0fe662
--- /dev/null
@@ -0,0 +1,77 @@
+//============================================================================
+// Author      : Anouar MEKKAS
+// Version     :
+// Description : 1D linear transport equation
+//============================================================================
+
+#include <iostream>
+#include <cmath>
+
+#include "Cell.hxx"
+#include "Mesh.hxx"
+#include "Field.hxx"
+
+using namespace std;
+
+
+int main( void )
+{
+  double a=-5.0;
+  double b=5.0;
+  int nx=1000;
+  int ntmax=3;
+  double dx = (b-a)/nx;
+  double pi=3.1415927;
+  // Transport velocity
+  double cfl=0.5;
+  double u=3.;
+  double dt=cfl*dx/u;
+
+  Mesh myMesh(a,b,nx);
+
+  Field conc("Concentration",CELLS,myMesh,1);
+
+  // Initial conditions
+  double sigma=sqrt(0.2);
+  for (int i=0 ; i<myMesh.getNumberOfCells() ; i++)
+  {
+   double x=myMesh.getCell(i).x();
+   conc(i) = 0.5/(sigma*sqrt(2*pi))*exp(-0.5*pow((x/sigma),2));
+  }
+
+  double time=0.;
+  double tmax=3.0;
+  int iter=0;
+
+  cout << "MED post-treatment of the solution at T=" << time << "…" << endl;
+  string fileOutPut="EqTr1D";
+  conc.setTime(time,iter);
+  conc.writeMED(fileOutPut);
+  conc.writeVTK(fileOutPut);
+  conc.writeCSV(fileOutPut);
+  int outputFreq=10;
+
+  // Time loop
+  while (iter<ntmax && time <= tmax )
+  {
+   cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
+   conc(0) = conc(0) -u*dt/dx*(conc(0)-conc(myMesh.getNumberOfCells()-1));
+   for (int j=1 ; j<myMesh.getNumberOfCells() ; j++)
+   {
+    conc(j) = conc(j) -u*dt/dx*(conc(j)-conc(j-1));
+   }
+   time+=dt;
+   iter+=1;
+   if (iter%outputFreq==0)
+   {
+       conc.setTime(time,iter);
+       conc.writeMED(fileOutPut,false);
+       conc.writeVTK(fileOutPut,false);
+       conc.writeCSV(fileOutPut);
+   }
+  }
+  cout << "CDMATH calculation done." << endl;
+  return 0;
+}
+
+
diff --git a/CDMATH/tests/examples/TransportEquation/transport1d/main.py b/CDMATH/tests/examples/TransportEquation/transport1d/main.py
new file mode 100755 (executable)
index 0000000..e573b8b
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+import math
+
+import cdmath
+
+
+def main():
+    a = -5.0
+    b = 5.0
+    nx = 1000
+    ntmax = 1000
+    dx = (b - a) / nx
+    pi = 3.1415927
+    # Transport velocity
+    cfl = 0.5
+    u = 3.
+    dt = cfl * dx / u
+
+    my_mesh = cdmath.Mesh(a, b, nx)
+    conc = cdmath.Field("Concentration", cdmath.CELLS, my_mesh, 1)
+
+    # Initial conditions
+    sigma = math.sqrt(0.2)
+    for i in range(my_mesh.getNumberOfCells()):
+        x = my_mesh.getCell(i).x()
+        conc[i] = 0.5 / (sigma * math.sqrt(2 * pi)) * math.exp(-0.5 * math.pow((x / sigma), 2))
+        pass
+
+    time = 0.
+    tmax = 3.0
+    it = 0
+
+    print("MED post-treatment of the solution at T=" + str(time) + "…")
+    output_filename = "EqTr1D"
+    conc.setTime(time, it)
+    conc.writeMED(output_filename)
+    conc.writeVTK(output_filename)
+    conc.writeCSV(output_filename)
+    output_freq = 10
+
+    # Time loop
+    while (it < ntmax and time <= tmax):
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+        conc[0] = conc[0] - u * dt / dx * (conc[0] - conc[my_mesh.getNumberOfCells() - 1])
+        for j in range(1, my_mesh.getNumberOfCells()):
+            conc[j] = conc[j] - u * dt / dx * (conc[j] - conc[j - 1])
+            pass
+        time += dt
+        it += 1
+        if (it % output_freq == 0):
+            conc.setTime(time, it)
+            conc.writeMED(output_filename, False)
+            conc.writeVTK(output_filename, False)
+            conc.writeCSV(output_filename)
+            pass
+        pass
+    print("CDMATH calculation done.")
+    return
+
+
+if __name__ == """__main__""":
+    main()
diff --git a/CDMATH/tests/examples/TransportEquation/transport1d/makefile b/CDMATH/tests/examples/TransportEquation/transport1d/makefile
new file mode 100755 (executable)
index 0000000..9e9121a
--- /dev/null
@@ -0,0 +1,26 @@
+# Transport1d makefile
+
+CC = g++
+# Adapt the following line to your own system:
+CDMATHDIR = ../../../../..
+IFLAG = -I$(CDMATHDIR)/include -I.
+LFLAG = -L$(CDMATHDIR)/lib
+LIBS  =-linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver
+OBJ = main.o
+
+all: $(OBJ)
+       $(CC) -o main $^ $(IFLAG) $(LFLAG) $(LIBS)
+       
+%.o: %.cxx
+       $(CC) -c -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
+       
+.PHONY: clean
+
+clean:
+       rm -f *.o *~ core $(INCDIR)/*~
+
+sweep:
+       rm -f *.vtu
+       rm -f *.pvd
+       rm -f *.csv
+       rm -f *.med
diff --git a/CDMATH/tests/examples/TransportEquation/transport2d_ns/main.cxx b/CDMATH/tests/examples/TransportEquation/transport2d_ns/main.cxx
new file mode 100755 (executable)
index 0000000..5ae5640
--- /dev/null
@@ -0,0 +1,192 @@
+//============================================================================
+// Author      : Anouar MEKKAS
+// Version     :
+// Description : Equation de transport lineaire 2D non structure
+//============================================================================
+
+#include <iostream>
+#include <string>
+#include <cmath>
+
+#include "Mesh.hxx"
+#include "Cell.hxx"
+#include "Face.hxx"
+#include "Field.hxx"
+
+using namespace std;
+
+
+void conditions_initiales(Field& yField)
+{
+    double rayon=0.15;
+    double xcentre=0.25;
+    double ycentre=0.25;
+    Mesh myMesh=yField.getMesh();
+    int nbCells=myMesh.getNumberOfCells();
+    for (int j=0 ; j<nbCells ; j++)
+    {
+        double x = myMesh.getCell(j).x() ;
+        double y = myMesh.getCell(j).y() ;
+        double valX=(x-xcentre)*(x-xcentre);
+        double valY=(y-ycentre)*(y-ycentre);
+        double val=sqrt(valX+valY);
+        if (val<rayon)
+            yField(j) = 1.0;
+        else
+            yField(j) = 0.0;
+    }
+}
+
+void sigma_flux(double VitesseX, double VitesseY, double cfl, const Field& yField, const IntTab indexFacesPerio, double& dt, Field& SumFlux)
+{
+    // Calculation of fluxes
+    Mesh myMesh=yField.getMesh();
+    int nbCells=myMesh.getNumberOfCells();
+    double normU=sqrt(VitesseX*VitesseX+VitesseY*VitesseY);
+    for (int j=0 ; j<nbCells ; j++)
+    {
+        Cell Cj=myMesh.getCell(j);
+        int nbFace=Cj.getNumberOfFaces();
+        double SumF=0.0;
+        double minlengthFk=1.E30;
+
+        int cellCourante,cellAutre;
+        for (int k=0 ; k<nbFace ; k++)
+        {
+            int indexFace=Cj.getFacesId()[k];
+            Face Fk=myMesh.getFace(indexFace);
+            double NormalX=Cj.getNormalVector(k,0);
+            double NormalY=Cj.getNormalVector(k,1);
+            double LengthFk = Fk.getMeasure();
+            double UN=VitesseX*NormalX+VitesseY*NormalY;
+
+            minlengthFk=min(minlengthFk,LengthFk/fabs(UN));
+            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseX));
+            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseY));
+
+            double conc=0.0;
+            cellCourante=j;
+            cellAutre=-1;
+
+            if (!Fk.isBorder())
+            {
+                int indexC1=Fk.getCellsId()[0];
+                int indexC2=Fk.getCellsId()[1];
+                /* hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if ( indexC1 == j )
+                {
+                    /* hypothese verifie */
+                    cellCourante=indexC1;
+                    cellAutre=indexC2;
+                } else if ( indexC2 == j )
+                {
+                    /* hypothese non verifie */
+                    cellCourante=indexC2;
+                    cellAutre=indexC1;
+                }
+                // definir la cellule gauche et droite par le prduit vitesse * normale sortante
+                // si u*n>0 : rien a faire sinon inverser la gauche et la droite
+                if (UN>1.E-15)
+                    conc=yField(cellCourante);
+                else
+                    conc=yField(cellAutre);
+            }else
+            {
+                /* conditions aux limites neumann homogene */
+                if (Fk.getGroupName().compare("GAUCHE")==0 || Fk.getGroupName().compare("DROITE")==0)
+                {
+                    if (UN>1.E-15)
+                        conc=yField(cellCourante);
+                    else
+                        conc=0.0;
+                }
+                /* conditions aux limites periodiques */
+                if (Fk.getGroupName().compare("BAS")==0 || Fk.getGroupName().compare("HAUT")==0)
+                {
+                        int indexFP=indexFacesPerio[indexFace];
+                        /* une autre manière de recuperer l'index de la face periodique */
+                        //int indexFP=M.getIndexFacePeriodic(indexFace);
+                        Face Fp=myMesh.getFace(indexFP);
+                        int indexCp=Fp.getCellsId()[0];
+                        if (UN>1.E-15)
+                            conc=yField(cellCourante);
+                        else
+                            conc=yField(indexCp);
+                }
+            }
+            SumF=SumF+UN*LengthFk*conc;
+          }
+        dt=cfl*minlengthFk/normU;
+        SumFlux(j)=dt*SumF/Cj.getMeasure();
+    }
+}
+
+void EquationTransport2D(double tmax, double VitesseX, double VitesseY, double cfl, int freqSortie, const Mesh& myMesh, const string file)
+{
+    /* Initial conditions */
+    cout << "Construction of the initial condition …" << endl;
+    Field yField("Y field",CELLS,myMesh,1) ;
+    conditions_initiales(yField);
+
+    /*
+     * MED output of the initial condition at t=0 and iter = 0
+     */
+    int iter=0;
+    double time=0.;
+    cout << "Saving the solution at T=" << time << "…" << endl;
+    yField.setTime(time,iter);
+    yField.writeMED(file);
+    yField.writeVTK(file);
+    yField.writeCSV(file);
+    /* --------------------------------------------- */
+
+    /* Time loop */
+    cout << "Resolution of the transport equation with an UPWIND scheme …" << endl;
+    int ntmax=3;
+    double dt;
+    IntTab indexFacesPerio=myMesh.getIndexFacePeriodic();
+    while (iter<ntmax && time <= tmax )
+    {
+        Field SumFlux("Fluxes sum",CELLS,myMesh,1) ;
+        sigma_flux(VitesseX,VitesseY,cfl,yField,indexFacesPerio,dt,SumFlux);
+        cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
+
+        /* Advancing time step */
+        yField-=SumFlux;
+
+        time+=dt;
+        iter+=1;
+        // Output every freq iterations
+        if (iter%freqSortie==0)
+        {
+            yField.setTime(time,iter);
+            yField.writeMED(file,false);
+            yField.writeVTK(file,false);
+            yField.writeCSV(file);
+        }
+    }
+}
+
+int main()
+{
+    cout << "Resolution of the 2D transport equation:" << endl;
+    cout << "- DOMAIN: SQUARE" << endl;
+    cout << "- MESH: TRIANGULAR, GENERATED WITH SALOME" << endl;
+    cout << "- PERIODIC BC ON TOP AND BOTTOM" << endl;
+    cout << "- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT" << endl;
+
+    // Problem data
+    double cfl=0.4;
+    double VitesseX=1.0;
+    double VitesseY=1.0;
+    double tmax=1.;
+    int freqSortie=10;
+
+    cout << "Construction of Cartesian mesh…" << endl;
+    Mesh myMesh("../../tests/ressources/meshSquare.med");
+    string fileOutPut="Exercice2";
+    EquationTransport2D(tmax,VitesseX,VitesseY,cfl,freqSortie,myMesh,fileOutPut);
+    cout << "CDMATH calculation done." << endl;
+
+    return 0;
+}
diff --git a/CDMATH/tests/examples/TransportEquation/transport2d_ns/main.py b/CDMATH/tests/examples/TransportEquation/transport2d_ns/main.py
new file mode 100755 (executable)
index 0000000..1315426
--- /dev/null
@@ -0,0 +1,175 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+import math
+
+import cdmath
+
+
+def initial_conditions(my_mesh):
+    rayon = 0.15
+    xcentre = 0.25
+    ycentre = 0.25
+    y_field = cdmath.Field("Y field", cdmath.CELLS, my_mesh, 1)
+    nbCells = my_mesh.getNumberOfCells()
+    for j in range(nbCells):
+        x = my_mesh.getCell(j).x()
+        y = my_mesh.getCell(j).y()
+        valX = (x - xcentre) * (x - xcentre)
+        valY = (y - ycentre) * (y - ycentre)
+        val = math.sqrt(valX + valY)
+        if val < rayon:
+            y_field[j] = 1.0
+            pass
+        else:
+            y_field[j] = 0.0
+            pass
+        pass
+    return y_field
+
+
+def sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio):
+    # Calculation of fluxes #
+    SumFlux = cdmath.Field("Fluxes", cdmath.CELLS, y_field.getMesh(), 1)
+    my_mesh = y_field.getMesh()
+    nbCells = my_mesh.getNumberOfCells()
+    normU = math.sqrt(VitesseX * VitesseX + VitesseY * VitesseY)
+    for j in range(nbCells):
+        Cj = my_mesh.getCell(j)
+        nbFace = Cj.getNumberOfFaces()
+        SumF = 0.0
+        minlengthFk = 1.E30
+        for k in range(nbFace):
+            indexFace = Cj.getFacesId()[k]
+            Fk = my_mesh.getFace(indexFace)
+            NormalX = Cj.getNormalVector(k, 0)
+            NormalY = Cj.getNormalVector(k, 1)
+            LengthFk = Fk.getMeasure()
+            UN = VitesseX * NormalX + VitesseY * NormalY
+            minlengthFk = min(minlengthFk, LengthFk / abs(UN))
+            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseX))
+            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseY))
+            conc = 0.0
+            cellCourante = j
+            cellAutre = -1
+            if (not Fk.isBorder()):
+                indexC1 = Fk.getCellsId()[0]
+                indexC2 = Fk.getCellsId()[1]
+                # hypothesis: the cell of index indexC1 is the current cell of index j #
+                if (indexC1 == j):
+                    # hypothese is verified #
+                    cellCourante = indexC1
+                    cellAutre = indexC2
+                    pass
+                elif (indexC2 == j):
+                    # hypothesis is not verified #
+                    cellCourante = indexC2
+                    cellAutre = indexC1
+                    pass
+                # define left and right cell with the product of velocity * outward normal vector
+                # if u*n>0: nothing to do, else invert left and right
+                if (UN > 1.E-15):
+                    conc = y_field[cellCourante]
+                    pass
+                else:
+                    conc = y_field[cellAutre]
+                    pass
+                pass
+            else:
+                # homogeneous Neumann boundary conditions #
+                if (Fk.getGroupName() == "GAUCHE" or Fk.getGroupName() == "DROITE"):
+                    if (UN > 1.E-15):
+                        conc = y_field[cellCourante]
+                        pass
+                    else:
+                        conc = 0.0
+                        pass
+                    pass
+                # periodical boundary conditions #
+                if (Fk.getGroupName() == "BAS" or Fk.getGroupName() == "HAUT"):
+                    indexFP = indexFacesPerio[indexFace]
+                    # another way to get the index of the periodical face #
+                    # int indexFP=my_mesh.getIndexFacePeriodic(indexFace);
+                    Fp = my_mesh.getFace(indexFP)
+                    indexCp = Fp.getCellsId()[0]
+                    if (UN > 1.E-15):
+                        conc = y_field[cellCourante]
+                        pass
+                    else:
+                        conc = y_field[indexCp]
+                        pass
+                    pass
+                pass
+            SumF = SumF + UN * LengthFk * conc
+            pass
+        dt = cfl * minlengthFk / normU
+        SumFlux[j] = dt * SumF / Cj.getMeasure()
+        pass
+    return dt, SumFlux
+
+
+def EquationTransport2D(tmax, VitesseX, VitesseY, cfl, freqSortie, my_mesh, output_filename):
+
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    y_field = initial_conditions(my_mesh)
+    #
+    # MED output of the initial condition at t=0 and iter = 0
+    #
+
+    it = 0
+    time = 0.
+    print("Saving the solution at T=" + str(time) + "…")
+    y_field.setTime(time, it)
+    y_field.writeMED(output_filename)
+    y_field.writeVTK(output_filename)
+    y_field.writeCSV(output_filename)
+
+    # Time loop #
+    print("Resolution of the transport equation with an UPWIND scheme…")
+    ntmax = 3
+    indexFacesPerio = my_mesh.getIndexFacePeriodic()
+    dt = 0.
+    while (it < ntmax and time <= tmax):
+        dt, SumFlux = sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio)
+        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+
+        # Advancing one time step #
+        y_field -= SumFlux
+        time += dt
+        it += 1
+        # Output every freq times
+        if (it % freqSortie == 0):
+            y_field.setTime(time, it)
+            y_field.writeMED(output_filename, False)
+            y_field.writeVTK(output_filename, False)
+            y_field.writeCSV(output_filename)
+            pass
+        pass
+    return
+
+
+def main():
+    print("Resolution of the 2D transport equation:")
+    print("- DOMAIN: SQUARE")
+    print("- MESH: TRIANGULAR, GENERATED WITH SALOME")
+    print("- PERIODICAL BC UP AND DOWN")
+    print("- HOMOGENEOUS NEUMANN BC LEFT AND RIGHT")
+
+    # Problem data
+    cfl = 0.4
+    VitesseX = 1.0
+    VitesseY = 1.0
+    tmax = 1.
+    freqSortie = 10
+
+    print("Loading triangular mesh …")
+    my_mesh = cdmath.Mesh("../../tests/ressources/meshSquare.med")
+    output_filename = "Exercice2PyTest"
+    EquationTransport2D(tmax, VitesseX, VitesseY, cfl, freqSortie, my_mesh, output_filename)
+    print("CDMATH calculation done.")
+    return
+
+
+if __name__ == """__main__""":
+    main()
diff --git a/CDMATH/tests/examples/TransportEquation/transport2d_ns/main2.cxx b/CDMATH/tests/examples/TransportEquation/transport2d_ns/main2.cxx
new file mode 100755 (executable)
index 0000000..ff6845e
--- /dev/null
@@ -0,0 +1,243 @@
+//============================================================================
+// Author      : Anouar MEKKAS
+// Version     :
+// Description : Equation de transport lineaire 2D non structure
+//============================================================================
+
+#include <iostream>
+#include <string>
+#include <cmath>
+
+#include "Mesh.hxx"
+#include "Cell.hxx"
+#include "Face.hxx"
+#include "Field.hxx"
+
+using namespace std;
+
+struct parameters {
+    double cfl;
+    double VitesseX;
+    double VitesseY;
+    int freqSortie;
+    std::string outFile;
+};
+
+void conditions_initiales(Field& yField)
+{
+    double rayon=0.15;
+    double xcentre=0.25;
+    double ycentre=0.25;
+    Mesh myMesh=yField.getMesh();
+    int nbCells=myMesh.getNumberOfCells();
+    for (int j=0 ; j<nbCells ; j++)
+    {
+        double x = myMesh.getCell(j).x() ;
+        double y = myMesh.getCell(j).y() ;
+        double valX=(x-xcentre)*(x-xcentre);
+        double valY=(y-ycentre)*(y-ycentre);
+        double val=sqrt(valX+valY);
+        if (val<rayon)
+            yField(j) = 1.0;
+        else
+            yField(j) = 0.0;
+    }
+}
+
+void sigma_flux(const parameters & p, const Field& yField, const IntTab indexFacesPerio, double& dt, Field& SumFlux)
+{
+    /* Calcul des flux */
+    Mesh myMesh=yField.getMesh();
+    int nbCells=myMesh.getNumberOfCells();
+    double normU=sqrt(p.VitesseX*p.VitesseX+p.VitesseY*p.VitesseY);
+    for (int j=0 ; j<nbCells ; j++)
+    {
+        Cell Cj=myMesh.getCell(j);
+        int nbFace=Cj.getNumberOfFaces();
+        double SumF=0.0;
+        double minlengthFk=1.E30;
+
+        int cellCourante,cellAutre;
+        for (int k=0 ; k<nbFace ; k++)
+        {
+            int indexFace=Cj.getFacesId()[k];
+            Face Fk=myMesh.getFace(indexFace);
+            double NormalX=Cj.getNormalVector(k,0);
+            double NormalY=Cj.getNormalVector(k,1);
+            double LengthFk = Fk.getMeasure();
+            double UN=p.VitesseX*NormalX+p.VitesseY*NormalY;
+
+            minlengthFk=min(minlengthFk,LengthFk/fabs(UN));
+            minlengthFk=min(minlengthFk,LengthFk/fabs(p.VitesseX));
+            minlengthFk=min(minlengthFk,LengthFk/fabs(p.VitesseY));
+
+            double conc=0.0;
+            cellCourante=j;
+            cellAutre=-1;
+
+            if (!Fk.isBorder())
+            {
+                int indexC1=Fk.getCellsId()[0];
+                int indexC2=Fk.getCellsId()[1];
+                /* hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if ( indexC1 == j )
+                {
+                    /* hypothese verifie */
+                    cellCourante=indexC1;
+                    cellAutre=indexC2;
+                } else if ( indexC2 == j )
+                {
+                    /* hypothese non verifie */
+                    cellCourante=indexC2;
+                    cellAutre=indexC1;
+                }
+                // definir la cellule gauche et droite par le prduit vitesse * normale sortante
+                // si u*n>0 : rien a faire sinon inverser la gauche et la droite
+                if (UN>1.E-15)
+                    conc=yField(cellCourante);
+                else
+                    conc=yField(cellAutre);
+            }else
+            {
+                /* conditions aux limites neumann homogene */
+                if (Fk.getGroupName().compare("GAUCHE")==0 || Fk.getGroupName().compare("DROITE")==0)
+                {
+                    if (UN>1.E-15)
+                        conc=yField(cellCourante);
+                    else
+                        conc=0.0;
+                }
+                /* conditions aux limites periodiques */
+                if (Fk.getGroupName().compare("BAS")==0 || Fk.getGroupName().compare("HAUT")==0)
+                {
+                        int indexFP=indexFacesPerio[indexFace];
+                        /* une autre manière de recuperer l'index de la face periodique */
+                        //int indexFP=M.getIndexFacePeriodic(indexFace);
+                        Face Fp=myMesh.getFace(indexFP);
+                        int indexCp=Fp.getCellsId()[0];
+                        if (UN>1.E-15)
+                            conc=yField(cellCourante);
+                        else
+                            conc=yField(indexCp);
+                }
+            }
+            SumF=SumF+UN*LengthFk*conc;
+          }
+        dt=p.cfl*minlengthFk/normU;
+        SumFlux(j)=dt*SumF/Cj.getMeasure();
+    }
+}
+
+void EquationTransport2D(int &iter, double tmin, double & tmax,
+                         const parameters & p, Field & yField)
+{
+  
+    /*
+     * MED output of the initial condition at t=0 and iter = 0
+     */
+    double time=tmin;
+    const Mesh& myMesh = yField.getMesh();
+    
+    yField.setTime(time,iter);
+    yField.writeMED(p.outFile,true);
+    yField.writeVTK(p.outFile);
+    yField.writeCSV(p.outFile);
+    /* --------------------------------------------- */
+
+    /* Time loop */
+    cout << "Resolution of the transport equation with an UPWIND scheme…" << endl;
+    int ntmax=3 + iter;
+    double dt;
+    IntTab indexFacesPerio=myMesh.getIndexFacePeriodic();
+    while (iter<ntmax && time <= tmax )
+    {
+        Field SumFlux("Fluxes sum",CELLS,myMesh,1) ;
+        sigma_flux(p,yField,indexFacesPerio,dt,SumFlux);
+        cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
+
+        /* Advancing time step */
+        yField-=SumFlux;
+
+        time+=dt;
+        iter+=1;
+        // Output every freq iterations
+        if (iter % p.freqSortie==0)
+        {
+            yField.setTime(time,iter);
+            yField.writeVTK(p.outFile,false);
+            yField.writeCSV(p.outFile);
+        }
+    }
+
+    cout << "MED post-treatment of the solution at T=" << time << endl;
+    yField.setTime(time,iter);
+    yField.writeMED(p.outFile,false);
+    yField.writeCSV(p.outFile);
+
+    tmax = time;
+    cout << "End of EquationTransport2D." << endl;
+}
+
+void compute_onepass(double tmin, double tmax, const Mesh & M, const parameters & p)
+{
+       int iter = 0;
+
+    /* Initial conditions */
+    cout << "Construction of initial condition…" << endl;
+    Field f("Y field",CELLS,M,1) ;
+    conditions_initiales(f);
+
+    EquationTransport2D(iter, tmin, tmax, p, f);
+}
+
+void compute_twopass(double tmin, double tmax, const Mesh & M, const parameters & p)
+{
+       int iter = 0;
+       parameters q(p);
+       double tstep = 0.5 * (tmin + tmax);
+
+    /* Initial conditions */
+    cout << "Construction of initial condition…" << endl;
+    Field f("Y field",CELLS,M,1) ;
+    conditions_initiales(f);
+
+       q.outFile = p.outFile + "_A";
+    EquationTransport2D(iter, tmin, tstep, q, f);
+
+    Field f2(q.outFile, CELLS, "Y field", iter, 0);
+
+       q.outFile = p.outFile + "_B";
+    EquationTransport2D(iter, tstep, tmax, q, f2);
+
+}
+
+int main()
+{
+    cout << "Resolution of the 2D transport equation:" << endl;
+    cout << "- DOMAIN: SQUARE" << endl;
+    cout << "- MESH: TRIANGULAR, GENERATED WITH SALOME" << endl;
+    cout << "- PERIODIC BC ON TOP AND BOTTOM" << endl;
+    cout << "- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT" << endl;
+
+    // donnees du probleme
+    parameters p;
+    int iter;
+
+    p.cfl=0.4;
+    p.VitesseX=1.0;
+    p.VitesseY=1.0;
+    p.freqSortie=50;
+    p.outFile="res2D";
+
+    cout << "Construction of Cartesian mesh…" << endl;
+    Mesh M("../../tests/ressources/meshSquare.med");
+
+    double tmin = 0;
+    double tmax = 0.1;
+    
+    compute_onepass(tmin, tmax, M, p);
+    compute_twopass(tmin, tmax, M, p);
+    cout << "CDMATH calculation done." << endl;
+
+    return 0;
+}
diff --git a/CDMATH/tests/examples/TransportEquation/transport2d_ns/makefile b/CDMATH/tests/examples/TransportEquation/transport2d_ns/makefile
new file mode 100755 (executable)
index 0000000..331cbaf
--- /dev/null
@@ -0,0 +1,30 @@
+# Transport2D_NS makefile
+
+CC = g++
+# Adapt the following line to your own system:
+CDMATHDIR = ../../../../..
+IFLAG = -I$(CDMATHDIR)/include -I.
+LFLAG = -L$(CDMATHDIR)/lib -L$(PETSC_DIR)/$(PETSC_ARCH)/lib
+LIBS  = -linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver -lpetsc
+
+all: main main2
+
+main: main.cxx 
+       $(CC) -g -o $@ $^ $(IFLAG) $(LFLAG) $(LIBS)
+
+main2: main2.cxx 
+       $(CC) -g -o $@ $^ $(IFLAG) $(LFLAG) $(LIBS)
+
+%.o: %.cxx
+       $(CC) -c -g -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
+
+.PHONY: clean
+
+clean:
+       rm -f main main2 *.o *~ core $(INCDIR)/*~
+
+sweep:
+       rm -f *.vtu
+       rm -f *.pvd
+       rm -f *.csv
+       rm -f Exercie2*.med
diff --git a/CDMATH/tests/examples/TransportEquation/transport2d_s/main.cxx b/CDMATH/tests/examples/TransportEquation/transport2d_s/main.cxx
new file mode 100755 (executable)
index 0000000..e49be9f
--- /dev/null
@@ -0,0 +1,202 @@
+//============================================================================
+// Author      : Anouar MEKKAS
+// Version     :
+// Description : 2D linear transport equation on cartesian grid
+//============================================================================
+
+#include <iostream>
+#include <string>
+#include <cmath>
+
+#include "Mesh.hxx"
+#include "Cell.hxx"
+#include "Face.hxx"
+#include "Field.hxx"
+
+using namespace std;
+
+
+void initial_conditions(Field& yField)
+{
+    double rayon=0.15;
+    double xcentre=0.25;
+    double ycentre=0.25;
+    Mesh myMesh=yField.getMesh();
+    int nbCells=myMesh.getNumberOfCells();
+    for (int j=0 ; j<nbCells ; j++)
+    {
+        double x = myMesh.getCell(j).x() ;
+        double y = myMesh.getCell(j).y() ;
+        double valX=(x-xcentre)*(x-xcentre);
+        double valY=(y-ycentre)*(y-ycentre);
+        double val=sqrt(valX+valY);
+        if (val<rayon)
+            yField(j) = 1.0;
+        else
+            yField(j) = 0.0;
+    }
+}
+
+void sigma_flux(double VitesseX, double VitesseY, double cfl, const Field& yField, const IntTab indexFacesPerio, double& dt, Field& SumFlux)
+{
+    /* Fluxes calculation */
+    Mesh myMesh=yField.getMesh();
+    int nbCells=myMesh.getNumberOfCells();
+    double normU=sqrt(VitesseX*VitesseX+VitesseY*VitesseY);
+    for (int j=0 ; j<nbCells ; j++)
+    {
+        Cell Cj=myMesh.getCell(j);
+        int nbFace=Cj.getNumberOfFaces();
+        double SumF=0.0;
+        double minlengthFk=1.E30;
+
+        int cellCourante,cellAutre;
+        for (int k=0 ; k<nbFace ; k++)
+        {
+            int indexFace=Cj.getFacesId()[k];
+            Face Fk=myMesh.getFace(indexFace);
+            double NormalX=Cj.getNormalVector(k,0);
+            double NormalY=Cj.getNormalVector(k,1);
+            double LengthFk = Fk.getMeasure();
+            double UN=VitesseX*NormalX+VitesseY*NormalY;
+
+            minlengthFk=min(minlengthFk,LengthFk/fabs(UN));
+            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseX));
+            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseY));
+
+            double conc=0.0;
+            cellCourante=j;
+            cellAutre=-1;
+
+            if (!Fk.isBorder())
+            {
+                int indexC1=Fk.getCellsId()[0];
+                int indexC2=Fk.getCellsId()[1];
+                /* Hypothesis: the cell of index indexC1 is the current cell index j */
+                if ( indexC1 == j )
+                {
+                    /* Hypothesis verified */
+                    cellCourante=indexC1;
+                    cellAutre=indexC2;
+                } else if ( indexC2 == j )
+                {
+                    /* Hypothesis not verified */
+                    cellCourante=indexC2;
+                    cellAutre=indexC1;
+                }
+                // Define left and right cells with the product velocity * outward normal
+                // If u*n>0, then nothing to do, else invert left and right
+                if (UN>1.E-15)
+                    conc=yField(cellCourante);
+                else
+                    conc=yField(cellAutre);
+            }else
+            {
+                /* Homogeneous Neumann boundary conditions */
+                if (Fk.getGroupName().compare("LeftEdge")==0 || Fk.getGroupName().compare("RightEdge")==0)
+                {
+                    if (UN>1.E-15)
+                        conc=yField(cellCourante);
+                    else
+                        conc=0.0;
+                }
+                /* Periodic boundary conditions */
+                if (Fk.getGroupName().compare("BottomEdge")==0 || Fk.getGroupName().compare("TopEdge")==0)
+                {
+                        int indexFP=indexFacesPerio[indexFace];
+                        /* une autre manière de recuperer l'index de la face periodique */
+                        //int indexFP=myMesh.getIndexFacePeriodic(indexFace);
+                        Face Fp=myMesh.getFace(indexFP);
+                        int indexCp=Fp.getCellsId()[0];
+                        if (UN>1.E-15)
+                            conc=yField(cellCourante);
+                        else
+                            conc=yField(indexCp);
+                }
+            }
+            SumF=SumF+UN*LengthFk*conc;
+          }
+        dt=cfl*minlengthFk/normU;
+        SumFlux(j)=dt*SumF/Cj.getMeasure();
+    }
+}
+
+void EquationTransport2D(double tmax, double VitesseX, double VitesseY, double cfl, int freqSortie, const Mesh& myMesh, const string file)
+{
+    /* Initial conditions */
+    cout << "Construction of the initial condition …" << endl;
+    Field yField("Y field",CELLS,myMesh,1) ;
+    initial_conditions(yField);
+
+    /*
+     * MED output of the initial condition at t=0 and iter = 0
+     */
+    int iter=0;
+    double time=0.;
+    cout << "Saving the solution at T=" << time << "…" << endl;
+    yField.setTime(time,iter);
+    yField.writeMED(file);
+    yField.writeVTK(file);
+    yField.writeCSV(file);
+    /* --------------------------------------------- */
+
+    /* Time loop */
+    cout << "Resolution of the transport equation with an UPWIND scheme …" << endl;
+    int ntmax=3;
+    double dt;
+    IntTab indexFacesPerio=myMesh.getIndexFacePeriodic();
+    while (iter<ntmax && time <= tmax )
+    {
+        Field SumFlux("Sum Flux",CELLS,myMesh,1) ;
+        sigma_flux(VitesseX,VitesseY,cfl,yField,indexFacesPerio,dt,SumFlux);
+        cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
+
+        /* Advancing time step */
+        yField-=SumFlux;
+
+        time+=dt;
+        iter+=1;
+        // Ouput every freq iterations
+        if (iter%freqSortie==0)
+        {
+            yField.setTime(time,iter);
+            yField.writeMED(file,false);
+            yField.writeVTK(file,false);
+            yField.writeCSV(file);
+        }
+    }
+}
+
+int main()
+{
+    cout << "RESOLUTION OF 2D TRANSPORT EQUATION:" << endl;
+    cout << "- DOMAIN: SQUARE" << endl;
+    cout << "- MESH: CARTESIAN, GENERATED INTERNALLY WITH CDMATH" << endl;
+    cout << "- PERIODIC BC ON TOP AND BOTTOM" << endl;
+    cout << "- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT" << endl;
+
+    // Problem data
+    double cfl=0.4;
+    double VitesseX=1.0;
+    double VitesseY=1.0;
+    double tmax=1.;
+    int freqSortie=10;
+
+    cout << "Construction of a cartesian mesh …" << endl;
+    double xinf=0.0;
+    double xsup=1.0;
+    double yinf=0.0;
+    double ysup=1.0;
+    int nx=100;
+    int ny=100;
+    Mesh myMesh(xinf,xsup,nx,yinf,ysup,ny);
+    double eps=1.E-10;
+    myMesh.setGroupAtPlan(xsup,0,eps,"RightEdge");
+    myMesh.setGroupAtPlan(xinf,0,eps,"LeftEdge");
+    myMesh.setGroupAtPlan(yinf,1,eps,"BottomEdge");
+    myMesh.setGroupAtPlan(ysup,1,eps,"TopEdge");
+    string fileOutPutCart="Exercice1";
+    EquationTransport2D(tmax,VitesseX,VitesseY,cfl,freqSortie,myMesh,fileOutPutCart);
+    cout << "CDMATH calculation done." << endl;
+    return 0;
+}
diff --git a/CDMATH/tests/examples/TransportEquation/transport2d_s/main.py b/CDMATH/tests/examples/TransportEquation/transport2d_s/main.py
new file mode 100755 (executable)
index 0000000..f033815
--- /dev/null
@@ -0,0 +1,186 @@
+#!/usr/bin/env python
+# -*-coding:utf-8 -*
+
+import math
+
+import cdmath
+
+
+def initial_conditions(my_mesh):
+    rayon = 0.15
+    xcentre = 0.25
+    ycentre = 0.25
+    y_field = cdmath.Field("Y field", cdmath.CELLS, my_mesh, 1)
+    nbCells = my_mesh.getNumberOfCells()
+    for j in range(nbCells):
+        x = my_mesh.getCell(j).x()
+        y = my_mesh.getCell(j).y()
+        valX = (x - xcentre) * (x - xcentre)
+        valY = (y - ycentre) * (y - ycentre)
+        val = math.sqrt(valX + valY)
+        if val < rayon:
+            y_field[j] = 1.0
+            pass
+        else:
+            y_field[j] = 0.0
+            pass
+        pass
+    return y_field
+
+
+def sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio):
+    # Fluxes calculation #
+    SumFlux = cdmath.Field("Fluxes", cdmath.CELLS, y_field.getMesh(), 1)
+    my_mesh = y_field.getMesh()
+    nbCells = my_mesh.getNumberOfCells()
+    normU = math.sqrt(VitesseX * VitesseX + VitesseY * VitesseY)
+    for j in range(nbCells):
+        Cj = my_mesh.getCell(j)
+        nbFace = Cj.getNumberOfFaces()
+        SumF = 0.0
+        minlengthFk = 1.E30
+        for k in range(nbFace):
+            indexFace = Cj.getFacesId()[k]
+            Fk = my_mesh.getFace(indexFace)
+            NormalX = Cj.getNormalVector(k, 0)
+            NormalY = Cj.getNormalVector(k, 1)
+            LengthFk = Fk.getMeasure()
+            UN = VitesseX * NormalX + VitesseY * NormalY
+            minlengthFk = min(minlengthFk, LengthFk / abs(UN))
+            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseX))
+            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseY))
+            conc = 0.0
+            cellCourante = j
+            cellAutre = -1
+            if (not Fk.isBorder()):
+                indexC1 = Fk.getCellsId()[0]
+                indexC2 = Fk.getCellsId()[1]
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j #
+                if (indexC1 == j):
+                    # hypothese verifie #
+                    cellCourante = indexC1
+                    cellAutre = indexC2
+                    pass
+                elif (indexC2 == j):
+                    # hypothese non verifie #
+                    cellCourante = indexC2
+                    cellAutre = indexC1
+                    pass
+                # definir la cellule gauche et droite par le prduit vitesse * normale sortante
+                # si u*n>0 : rien a faire sinon inverser la gauche et la droite
+                if (UN > 1.E-15):
+                    conc = y_field[cellCourante]
+                    pass
+                else:
+                    conc = y_field[cellAutre]
+                    pass
+                pass
+            else:
+                # conditions aux limites neumann homogene #
+                if (Fk.getGroupName() == "LeftEdge" or Fk.getGroupName() == "RightEdge"):
+                    if (UN > 1.E-15):
+                        conc = y_field[cellCourante]
+                        pass
+                    else:
+                        conc = 0.0
+                        pass
+                    pass
+                # conditions aux limites periodiques #
+                if (Fk.getGroupName() == "BottomEdge" or Fk.getGroupName() == "TopEdge"):
+                    indexFP = indexFacesPerio[indexFace]
+                    # une autre manière de recuperer l'index de la face periodique #
+                    # int indexFP=my_mesh.getIndexFacePeriodic(indexFace);
+                    Fp = my_mesh.getFace(indexFP)
+                    indexCp = Fp.getCellsId()[0]
+                    if (UN > 1.E-15):
+                        conc = y_field[cellCourante]
+                        pass
+                    else:
+                        conc = y_field[indexCp]
+                        pass
+                    pass
+                pass
+            SumF = SumF + UN * LengthFk * conc
+            pass
+        dt = cfl * minlengthFk / normU
+        SumFlux[j] = dt * SumF / Cj.getMeasure()
+        pass
+    return dt, SumFlux
+
+
+def EquationTransport2D(tmax, VitesseX, VitesseY, cfl, output_freq, my_mesh, file):
+
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    y_field = initial_conditions(my_mesh)
+    #
+    #  MED output of the initial conditions at t=0 and iteration = 0
+    #
+
+    iteration = 0
+    time = 0.
+    print("Saving the solution at T=" + str(time) + "…")
+    y_field.setTime(time, iteration)
+    y_field.writeMED(file)
+    y_field.writeVTK(file)
+    y_field.writeCSV(file)
+
+    # Time loop #
+    print("Resolution of the transport equation with an UPWIND scheme …")
+    ntmax = 3
+    indexFacesPerio = my_mesh.getIndexFacePeriodic()
+    dt = 0.
+    while (iteration < ntmax and time <= tmax):
+        dt, SumFlux = sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio)
+        print("-- Iter: " + str(iteration) + ", Time: " + str(time) + ", dt: " + str(dt))
+
+        # Advancing time step #
+        y_field -= SumFlux
+        time += dt
+        iteration += 1
+        # Output every output_freq iterations
+        if (iteration % output_freq == 0):
+            y_field.setTime(time, iteration)
+            y_field.writeMED(file, False)
+            y_field.writeVTK(file, False)
+            y_field.writeCSV(file)
+            pass
+        pass
+    return
+
+
+def main():
+    print("RESOLUTION OF THE 2D TRANSPORT EQUATION:")
+    print("- DOMAIN: SQUARE [0,1]x[0,1]")
+    print("- MESH: CARTESIAN, INTERNAL GENERATION WITH CDMATH")
+    print("- PERIODIC BC ON TOP AND BOTTOM")
+    print("- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT")
+
+    # Problem data
+    cfl = 0.4
+    VitesseX = 1.0
+    VitesseY = 1.0
+    tmax = 1.
+    output_freq = 10
+
+    print("Construction of a cartesian mesh …")
+    xinf = 0.0
+    xsup = 1.0
+    yinf = 0.0
+    ysup = 1.0
+    nx = 100
+    ny = 100
+    my_mesh = cdmath.Mesh(xinf, xsup, nx, yinf, ysup, ny)
+    eps = 1.E-10
+    my_mesh.setGroupAtPlan(xsup, 0, eps, "RightEdge")
+    my_mesh.setGroupAtPlan(xinf, 0, eps, "LeftEdge")
+    my_mesh.setGroupAtPlan(yinf, 1, eps, "BottomEdge")
+    my_mesh.setGroupAtPlan(ysup, 1, eps, "TopEdge")
+    fileOutPutCart = "Exercice1PyTest"
+    EquationTransport2D(tmax, VitesseX, VitesseY, cfl, output_freq, my_mesh, fileOutPutCart)
+    print("CDMATH calculation done.")
+    return
+
+
+if __name__ == """__main__""":
+    main()
diff --git a/CDMATH/tests/examples/TransportEquation/transport2d_s/makefile b/CDMATH/tests/examples/TransportEquation/transport2d_s/makefile
new file mode 100755 (executable)
index 0000000..3ef2bc7
--- /dev/null
@@ -0,0 +1,26 @@
+# Transport2D_S makefile
+
+CC = g++
+# Adapt the following line to your own system:
+CDMATHDIR = ../../../../..
+IFLAG = -I$(CDMATHDIR)/include -I.
+LFLAG = -L$(CDMATHDIR)/lib
+LIBS  =-linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver
+OBJ = main.o
+
+all: $(OBJ)
+       $(CC) -o main $^ $(IFLAG) $(LFLAG) $(LIBS)
+       
+%.o: %.cxx
+       $(CC) -c -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
+       
+.PHONY: clean
+
+clean:
+       rm -f *.o *~ core $(INCDIR)/*~
+
+sweep:
+       rm -f *.vtu
+       rm -f *.pvd
+       rm -f *.csv
+       rm -f Exercie1*.med
diff --git a/CDMATH/tests/examples/TransportEquation1DCenteredExplicit/1DTransportEquationCenteredExplicit.py b/CDMATH/tests/examples/TransportEquation1DCenteredExplicit/1DTransportEquationCenteredExplicit.py
deleted file mode 100755 (executable)
index 9b4336e..0000000
+++ /dev/null
@@ -1,117 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
-# Author      : Michaël Ndjinga, Katia Ait Ameur
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation du schéma centré explicite sur un maillage 1D régulier
-#                      Création et sauvegarde du champ résultant et des figures
-#               Génération d'une video sauvegardée dans un fichier .mp4
-#================================================================================================================================
-
-
-from math import sin, pi, ceil
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-from copy import deepcopy
-
-def Transport1DCenteredExplicit(nx,cfl, isSmooth):
-    print( "Simulation of 1D transport equation with explicit centered scheme" )
-
-    ##################### Simulation parameters
-    a = 0.0 # space domain :  a <= x <= b
-    b = 1.0
-    dx = (b - a) / nx #space step
-
-    c = 0.25 # advection velocity
-    dt = cfl * dx / c
-
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-    
-    ########################## Initial data
-    
-    if(isSmooth):
-        print( "Smooth initial data" )
-        u_initial = [ sin(2*pi*xi)  for xi in x];# to be used with a=0, b=1
-        tmax = 3*(b-a)/c # runs the simulation for 0 <= t <= tMax
-    else:
-        print( "Stiff initial data" )
-        u_initial = [ int(1./3<xi)*int(xi<2./3)  for xi in x];# to be used with a=0, b=1
-        tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
-    ntmax = ceil(tmax/dt)
-
-    u = deepcopy(u_initial)
-    
-    max_initial=max(u_initial)
-    min_initial=min(u_initial)
-
-    time = 0.
-    it = 0
-    output_freq = int(10/cfl)
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Centered explicit scheme for transport equation", artist = "CEA Saclay", comment="CFL="+str(cfl)+", Stable if CFL<1")
-    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "1DTransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+".mp4", ntmax):
-        ########################### Postprocessing initialisation
-        # Picture frame
-        plt.legend()
-        plt.xlabel('x')
-        plt.ylabel('u')
-        plt.xlim(a,b)
-        plt.ylim( min_initial - 0.5*(max_initial-min_initial), max_initial +  0.5*(max_initial-min_initial) )
-        plt.title('Centered explicit scheme for transport equation')
-        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
-    
-        print("Starting time loop")
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-        np.savetxt( "TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
-        writer.grab_frame()
-        plt.savefig("TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_0.png")
-
-        ############################# Time loop
-        while (it < ntmax and time <= tmax):
-            un=deepcopy(u)
-            for i in range(nx):
-                u[i] = un[i] - c * dt / dx * (un[(i+1)%nx] - un[(i-1)%nx])/2
-    
-            time += dt
-            it += 1
-
-            # Postprocessing
-            line1.set_ydata(u)
-            writer.grab_frame()
-            if (it % output_freq == 0):
-                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-                np.savetxt( "TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
-                plt.savefig("TransportEquation_CenteredExplicit_"+str(nx)+"Cells_Smoothness"+str(isSmooth)+"_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
-                #plt.show()
-
-    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
-    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
-    print( "Exact solution variation : ",    np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
-    print( "l1 numerical error       : ", dx*np.sum([abs(u[i]         - u_initial[i]       ) for i in range(nx)]))
-
-    print( "Simulation of 1D transport equation with explicit centered scheme done" )
-
-    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
-
-
-if __name__ == """__main__""":
-    if len(sys.argv) >3 :
-        nx = int(sys.argv[1])
-        cfl = float(sys.argv[2])
-        isSmooth=bool(int(sys.argv[3]))
-        Transport1DCenteredExplicit(nx,cfl,isSmooth)
-    else :
-        nx = 50 # number of cells
-        cfl = 0.99 # c*dt/dx <= CFL
-        isSmooth=True
-        Transport1DCenteredExplicit(nx,cfl,isSmooth)
-    
diff --git a/CDMATH/tests/examples/TransportEquation1DCenteredExplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation1DCenteredExplicit/CMakeLists.txt
deleted file mode 100755 (executable)
index cc7cf3a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-
-if (CDMATH_WITH_PYTHON )
-
-    SET(NX 50 )#Number of cells
-
-    SET(SMOOTHNESS  0 )
-
-    SET(CFL  0.99  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Stiff_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} )
-
-   SET(CFL  0.5  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Stiff_CFL0.5 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} ) 
-
-
-    SET(SMOOTHNESS  1 )
-
-    SET(CFL  0.99  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Smooth_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} )
-
-    SET(CFL  0.5  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_CenteredExplicit_Smooth_CFL0.5 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredExplicit.py ${NX} ${CFL} ${SMOOTHNESS} )
-
-endif (CDMATH_WITH_PYTHON )
-
-
diff --git a/CDMATH/tests/examples/TransportEquation1DCenteredImplicit/1DTransportEquationCenteredImplicit.py b/CDMATH/tests/examples/TransportEquation1DCenteredImplicit/1DTransportEquationCenteredImplicit.py
deleted file mode 100755 (executable)
index af12e79..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
-# Author      : Michaël Ndjinga, Katia Ait Ameur
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation du schéma centré implicite sur un maillage 1D régulier
-#               Schéma à 3 points implicite
-#                      Création et sauvegarde du champ résultant et des figures
-#               Génération d'une video sauvegardée dans un fichier .mp4
-#================================================================================================================================
-
-
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-from math import sin, pi, ceil
-import cdmath
-
-def centeredSchemeMatrix(nx,cfl):
-    centeredMat=cdmath.SparseMatrixPetsc(nx,nx,3)
-    for i in range(nx):
-        centeredMat.setValue(i,(i+1)%nx,cfl/2)
-        centeredMat.setValue(i,i,1.)
-        centeredMat.setValue(i,(i-1)%nx,-cfl/2.)
-
-    return centeredMat
-    
-def Transport1DCenteredImplicit(nx,cfl):
-    print( "Simulation of 1D transport equation with implicit centered scheme" )
-
-    ##################### Simulation parameters
-    a = 0.0 # space domain :  a <= x <= b
-    b = 1.0
-    dx = (b - a) / nx #space step
-
-    c = 0.25 # advection velocity
-    tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
-    dt = cfl * dx / c
-    ntmax = ceil(tmax/dt)
-
-    if(cfl>nx):
-        raise("Impossible to run this simulation with cfl>nx. Choose another value for nx or cfl.")
-        
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-    
-    ########################## Initial data
-    
-    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-
-    max_initial=max(u_initial)
-    min_initial=min(u_initial)
-    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
-
-    time = 0.
-    it = 0
-    output_freq = 10
-        
-    #Linear system initialisation
-    systemMat=centeredSchemeMatrix(nx,cfl)
-    iterGMRESMax=50
-    precision=1.e-5
-    Un =cdmath.Vector(nx)
-    for i in range(nx):
-        Un[i]=u[i]
-    LS=cdmath.LinearSolver(systemMat,Un,iterGMRESMax, precision, "GMRES","ILU")
-    LS.setComputeConditionNumber()
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Centered implicit scheme for transport equation, "+"CFL="+str(cfl), artist = "CEA Saclay", comment="Stable for any CFL>0")
-    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "1DTransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
-        ########################### Postprocessing initialisation
-        # Picture frame
-        plt.legend()
-        plt.xlabel('x')
-        plt.ylabel('u')
-        plt.xlim(a,b)
-        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
-        plt.title("Centered implicit scheme for transport equation, "+"CFL="+str(cfl))
-        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
-
-        print("Starting time loop")
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-        np.savetxt( "TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
-        writer.grab_frame()
-        plt.savefig("TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
-    
-        ############################# Time loop
-        while (it < ntmax and time <= tmax):
-            # Solve linear system
-            for i in range(nx):
-                Un[i]=u[i]
-            LS.setSndMember(Un)
-            Un=LS.solve()
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
-                raise ValueError("Pas de convergence du système linéaire");
-            for i in range(nx):
-                u[i]=Un[i]
-    
-            if ( max(u) > max_initial ):
-                print( "-- Iter: " + str(it) + " max principle violated : max(t) > max(0) : max(t)= ",max(u), " max(0)= ", max_initial )
-            if ( min(u) < min_initial ):
-                print( "-- Iter: " + str(it) + " min principle violated : min(t) < min(0) : min(t)= ",min(u), " min(0)= ", min_initial )
-            if ( np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) > total_var_initial ):
-                print( "-- Iter: " + str(it) + " total variation increased : var(t) > var(0) : var(t)= ", np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), " var(0)= ", total_var_initial )
-
-            time += dt
-            it += 1
-
-            # Postprocessing
-            line1.set_ydata(u)
-            writer.grab_frame()
-            if (it % output_freq == 0):
-                print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-                np.savetxt( "TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
-                plt.savefig("TransportEquation_CenteredImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
-                #plt.show()
-
-    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
-    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
-    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
-    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) )       
-    
-    print("Simulation of transport equation with implicit centered scheme done.")
-    
-    #return min, max, total variation and l1 error
-    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
-
-
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        nx = int(sys.argv[1])
-        cfl = float(sys.argv[2])
-        Transport1DCenteredImplicit(nx,cfl)
-    else :
-        nx = 50 # number of cells
-        cfl = 0.99 # c*dt/dx <= CFL
-        Transport1DCenteredImplicit(nx,cfl)
-    
diff --git a/CDMATH/tests/examples/TransportEquation1DCenteredImplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation1DCenteredImplicit/CMakeLists.txt
deleted file mode 100755 (executable)
index b2ffc39..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-
-if (CDMATH_WITH_PYTHON )
-
-    SET(NX 50 )#Number of cells
-
-    SET(CFL  1  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_Centered_Implicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredImplicit.py ${NX} ${CFL})
-
-    SET(CFL  2  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_Centered_Implicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationCenteredImplicit.py ${NX} ${CFL})
-
-
-endif (CDMATH_WITH_PYTHON )
-
-
diff --git a/CDMATH/tests/examples/TransportEquation1DUpwindExplicit/1DTransportEquationUpwindExplicit.py b/CDMATH/tests/examples/TransportEquation1DUpwindExplicit/1DTransportEquationUpwindExplicit.py
deleted file mode 100755 (executable)
index d49da95..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
-# Author      : Michaël Ndjinga, Katia Ait Ameur
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation du schéma upwind explicite sur un maillage 1D régulier
-#                      Création et sauvegarde du champ résultant et des figures
-#               Génération d'une video sauvegardée dans un fichier .mp4
-#================================================================================================================================
-
-
-from math import sin, pi, ceil
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-from copy import deepcopy
-
-def Transport1DUpwindExplicit(nx,cfl):
-    print( "Simulation of 1D transport equation with explicit upwind scheme" )
-
-    ##################### Simulation parameters
-    a = 0.0 # space domain :  a <= x <= b
-    b = 1.0
-    dx = (b - a) / nx #space step
-
-    c = 0.25 # advection velocity
-    tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
-    dt = cfl * dx / c
-    ntmax = ceil(tmax/dt)
-
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-    
-    ########################## Initial data
-    
-    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-
-    max_initial=max(u_initial)
-    min_initial=min(u_initial)
-    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
-
-    time = 0.
-    it = 0
-    output_freq = 10
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Upwind explicit scheme for transport equation, CFL="+str(cfl), artist = "CEA Saclay", comment="Stable if CFL<1")
-    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "1DTransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+".mp4", ntmax):
-        ########################### Postprocessing initialisation
-        # Picture frame
-        plt.legend()
-        plt.xlabel('x')
-        plt.ylabel('u')
-        plt.xlim(a,b)
-        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
-        plt.title("Upwind explicit scheme for transport equation, CFL="+str(cfl))
-        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
-    
-        print("Starting time loop")
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-        np.savetxt( "TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
-        writer.grab_frame()
-        plt.savefig("TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
-
-        ############################# Time loop
-        while (it < ntmax and time <= tmax):
-            un=deepcopy(u)
-            for i in range(nx):
-                u[i] = un[i] - c * dt / dx * (un[i] - un[(i-1)%nx])
-    
-            time += dt
-            it += 1
-
-            if cfl<1 :
-                assert max(u) <= max_initial
-                assert min(u) >= min_initial
-                assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial + 1e-15#Tiny margin required
-
-            # Postprocessing
-            line1.set_ydata(u)
-            writer.grab_frame()
-            if (it % output_freq == 0):
-                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-                np.savetxt( "TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
-                plt.savefig("TransportEquation_UpwindExplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
-                #plt.show()
-
-    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
-    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
-    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
-    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) )       
-    
-    print("Simulation of transport equation with explicit upwind scheme done.")
-    
-    #return min, max, total variation and l1 error
-    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
-
-
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        nx = int(sys.argv[1])
-        cfl = float(sys.argv[2])
-        Transport1DUpwindExplicit(nx,cfl)
-    else :
-        nx = 50 # number of cells
-        cfl = 0.99 # c*dt/dx <= CFL
-        Transport1DUpwindExplicit(nx,cfl)
-    
diff --git a/CDMATH/tests/examples/TransportEquation1DUpwindExplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation1DUpwindExplicit/CMakeLists.txt
deleted file mode 100755 (executable)
index f1fe640..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-
-if (CDMATH_WITH_PYTHON )
-
-    SET(NX 100 )#Number of cells
-
-    SET(CFL  0.9999  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Explicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindExplicit.py ${NX} ${CFL})
-
-    SET(CFL  0.5  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Explicit_CFL0.5 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindExplicit.py ${NX} ${CFL})
-
-    SET(CFL  2  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Explicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindExplicit.py ${NX} ${CFL})
-
-endif (CDMATH_WITH_PYTHON )
-
-
diff --git a/CDMATH/tests/examples/TransportEquation1DUpwindImplicit/1DTransportEquationUpwindImplicit.py b/CDMATH/tests/examples/TransportEquation1DUpwindImplicit/1DTransportEquationUpwindImplicit.py
deleted file mode 100755 (executable)
index 6f990fb..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF de l'équation du transport 1D \partial_t u + c \partial_x u = 0 avec conditions aux limites périodiques
-# Author      : Michaël Ndjinga, Katia Ait Ameur
-# Copyright   : CEA Saclay 2018
-# Description : Utilisation du schéma upwind implicite sur un maillage 1D régulier
-#                      Création et sauvegarde du champ résultant et des figures
-#               Génération d'une video sauvegardée dans un fichier .mp4
-#================================================================================================================================
-
-
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-from math import sin, pi, ceil
-import cdmath
-
-precision=1.e-5
-
-def upwindSchemeMatrix(nx,cfl):
-    upwindMat=cdmath.SparseMatrixPetsc(nx,nx,2)
-    for i in range(nx):
-        upwindMat.setValue(i,i,1+cfl)
-        upwindMat.setValue(i,(i-1)%nx,-cfl)
-
-    return upwindMat
-    
-def Transport1DUpwindImplicit(nx,cfl):
-    print( "Simulation of 1D transport equation with implicit upwind scheme" )
-
-    ##################### Simulation parameters
-    a = 0.0 # space domain :  a <= x <= b
-    b = 1.0
-    dx = (b - a) / nx #space step
-
-    c = 0.25 # advection velocity
-    tmax = (b-a)/c # runs the simulation for 0 <= t <= tMax
-    dt = cfl * dx / c
-    ntmax = ceil(tmax/dt)
-
-    if(cfl>nx):
-        raise("Impossible to run this simulation with cfl>nx. Choose another value for nx or cfl.")
-        
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-    
-    ########################## Initial data
-    
-    u_initial = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-    u         = [ 0.5*(1+sin(4*pi*xi-pi*.5))*int(xi<0.5)*int(0<xi) + int(0.6<xi)*int(xi<0.85)  for xi in x];# to be used with a=0, b=1
-
-    max_initial=max(u_initial)
-    min_initial=min(u_initial)
-    total_var_initial = np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)])
-
-    time = 0.
-    it = 0
-    output_freq = 10
-        
-    #Linear system initialisation
-    systemMat=upwindSchemeMatrix(nx,cfl)
-    iterGMRESMax=50
-    Un =cdmath.Vector(nx)
-    for i in range(nx):
-        Un[i]=u[i]
-    LS=cdmath.LinearSolver(systemMat,Un,iterGMRESMax, precision, "GMRES","ILU")
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Upwind implicit scheme for transport equation, "+"CFL="+str(cfl), artist = "CEA Saclay", comment="Stable for any CFL>0")
-    writer=FFMpegWriter(fps=output_freq, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "1DTransportEquation_UpwindImplicit_"+str(nx)+"CELLS_CFL"+str(cfl)+".mp4", ntmax):
-        ########################### Postprocessing initialisation
-        # Picture frame
-        plt.legend()
-        plt.xlabel('x')
-        plt.ylabel('u')
-        plt.xlim(a,b)
-        plt.ylim( min_initial - 0.1*(max_initial-min_initial), max_initial +  0.1*(max_initial-min_initial) )
-        plt.title("Upwind implicit scheme for transport equation, "+"CFL="+str(cfl))
-        line1, = plt.plot(x, u, label='u') #new picture for video # Returns a tuple of line objects, thus the comma
-
-        print("Starting time loop")
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-        np.savetxt( "TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.txt", u, delimiter="\n")
-        writer.grab_frame()
-        plt.savefig("TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_0.png")
-    
-        ############################# Time loop
-        while (it < ntmax and time <= tmax):
-            # Solve linear system
-            for i in range(nx):
-                Un[i]=u[i]
-            LS.setSndMember(Un)
-            Un=LS.solve()
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
-                raise ValueError("Pas de convergence du système linéaire");
-            for i in range(nx):
-                u[i]=Un[i]
-    
-            time += dt
-            it += 1
-
-            assert max(u) <= max_initial
-            assert min(u) >= min_initial
-            assert np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) <= total_var_initial
-
-            # Postprocessing
-            line1.set_ydata(u)
-            writer.grab_frame()
-            if (it % output_freq == 0):
-                print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-                np.savetxt( "TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".txt", u, delimiter="\n")
-                plt.savefig("TransportEquation_UpwindImplicit_"+str(nx)+"Cells_CFL"+str(cfl)+"_ResultField_"+str(it)+".png")
-                #plt.show()
-
-    print( "Exact solution minimum   : ", min(u_initial), "Numerical solution minimum   : ",  min(u) )
-    print( "Exact solution maximum   : ", max(u_initial), "Numerical solution maximum   : ",  max(u) )
-    print( "Exact solution variation : ", np.sum([abs(u_initial[i] - u_initial[(i-1)%nx]) for i in range(nx)]), "Numerical solution variation : ",  np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]) )
-    print( "l1 numerical error       : ", dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)]) )       
-    
-    print("Simulation of transport equation with implicit upwind scheme done.")
-    
-    #return min, max, total variation and l1 error
-    return min(u), max(u), np.sum([abs(u[i] - u[(i-1)%nx]) for i in range(nx)]), dx*np.sum([abs(u[i] - u_initial[i]) for i in range(nx)])
-
-
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        nx = int(sys.argv[1])
-        cfl = float(sys.argv[2])
-        Transport1DUpwindImplicit(nx,cfl)
-    else :
-        nx = 50 # number of cells
-        cfl = 0.99 # c*dt/dx <= CFL
-        Transport1DUpwindImplicit(nx,cfl)
-    
diff --git a/CDMATH/tests/examples/TransportEquation1DUpwindImplicit/CMakeLists.txt b/CDMATH/tests/examples/TransportEquation1DUpwindImplicit/CMakeLists.txt
deleted file mode 100755 (executable)
index 1045385..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-
-if (CDMATH_WITH_PYTHON )
-
-    SET(NX 50 )#Number of cells
-
-    SET(CFL  1  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Implicit_CFL1 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindImplicit.py ${NX} ${CFL})
-
-    SET(CFL  2  )#Courant Friedrichs Lewy number
-
-    ADD_TEST(ExampleTransportEquation_1DFV_Upwind_Implicit_CFL2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/1DTransportEquationUpwindImplicit.py ${NX} ${CFL})
-
-
-endif (CDMATH_WITH_PYTHON )
-
-
diff --git a/CDMATH/tests/examples/WaveSystem/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..a4f396f
--- /dev/null
@@ -0,0 +1,36 @@
+file(GLOB WaveSystem_EXAMPLES_TO_INSTALL 
+
+  WaveSystem1DUpwind WaveSystem1DUpwind_RiemannProblem WaveSystem1Staggered_RiemannProblem WaveSystem2DUpwind_RiemannProblem
+  WaveSystem_Stationary/WaveSystemUpwind WaveSystem_Stationary/WaveSystemCentered WaveSystem_Stationary/WaveSystemPStag WaveSystem_Stationary/WaveSystemStaggered 
+  WaveSystem_Shock/WaveSystemUpwind WaveSystem_Shock/WaveSystemCentered WaveSystem_Shock/WaveSystemPStag WaveSystem_Shock/WaveSystemStaggered 
+)
+
+install(DIRECTORY ${WaveSystem_EXAMPLES_TO_INSTALL} DESTINATION share/examples/WaveSystem)
+
+SET(MESH_MED
+  ${MED_MESHES}/squareWithTriangles.med
+  ${MED_MESHES}/squareWithSquares.med
+  ${MED_MESHES}/squareWithBrickWall.med
+  ${MED_MESHES}/squareWithCheckerboardSquares.med
+  ${MED_MESHES}/squareWithDeformedQuadrangles.med
+  ${MED_MESHES}/squareWithHexagons.med
+  )
+
+IF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_SUBDIRECTORY(WaveSystem1DUpwind)
+    ADD_SUBDIRECTORY(WaveSystem1DStaggered_RiemannProblem)
+    ADD_SUBDIRECTORY(WaveSystem1DUpwind_RiemannProblem)
+    ADD_SUBDIRECTORY(WaveSystem2DUpwind_RiemannProblem)
+    ADD_SUBDIRECTORY(WaveSystem_Stationary/WaveSystemUpwind)
+    ADD_SUBDIRECTORY(WaveSystem_Stationary/WaveSystemPStag)
+    ADD_SUBDIRECTORY(WaveSystem_Stationary/WaveSystemStaggered)
+    ADD_SUBDIRECTORY(WaveSystem_Stationary/WaveSystemCentered)
+    ADD_SUBDIRECTORY(WaveSystem_Shock/WaveSystemUpwind)
+    ADD_SUBDIRECTORY(WaveSystem_Shock/WaveSystemPStag)
+    ADD_SUBDIRECTORY(WaveSystem_Shock/WaveSystemStaggered)
+    ADD_SUBDIRECTORY(WaveSystem_Shock/WaveSystemCentered)
+
+ENDIF (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem1DStaggered_RiemannProblem/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem1DStaggered_RiemannProblem/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..2ab500a
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleWaveSystem_1DStaggered_RiemannProblem ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystem1DStaggered_RiemannProblem.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem1DStaggered_RiemannProblem/WaveSystem1DStaggered_RiemannProblem.py b/CDMATH/tests/examples/WaveSystem/WaveSystem1DStaggered_RiemannProblem/WaveSystem1DStaggered_RiemannProblem.py
new file mode 100755 (executable)
index 0000000..3603977
--- /dev/null
@@ -0,0 +1,198 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+import cdmath
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+
+p0=155.e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_Riemann_problem(a,b,nx):
+    print( "Initial data Riemann problem" )
+
+    dx = (b - a) / nx #space step
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+
+    u_initial = [ 0 ]*nx
+    p_initial = [ (xi<(a+b)/2)*p0 + (xi>=(a+b)/2)*p0/2  for xi in x]
+
+    return p_initial, u_initial
+
+def staggeredMatrices(coeff,scaling):
+    dim=1
+    S1=cdmath.Matrix(dim+1,dim+1)
+    S2=cdmath.Matrix(dim+1,dim+1)
+
+    for i in range(dim):
+        if( scaling==0):
+            S1[0,i+1]=c0*c0*coeff
+            S2[i+1,0]=      coeff
+        else:
+            S1[0,i+1]=   c0*coeff
+            S2[i+1,0]=   c0*coeff
+       
+    return S1,S2
+        
+def computeStaggeredDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling):
+    nbCells = nx
+    dx=(b-a)/nx
+    dim=1
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    S1,S2 = staggeredMatrices(dt/dx,scaling)
+    for k in range(nbCells):#On parcourt les cellules
+        if ( k==0) :
+            implMat.addValue(k*nbComp, (k+1)*nbComp, S1)
+            implMat.addValue(k*nbComp,  k   *nbComp, S1*(-1.))
+        elif ( k==nbCells-1) :
+            implMat.addValue(k*nbComp,  k   *nbComp, S2)
+            implMat.addValue(k*nbComp, (k-1)*nbComp, S2*(-1.))
+        else :
+            implMat.addValue(k*nbComp, (k+1)*nbComp, S1)
+            implMat.addValue(k*nbComp,  k   *nbComp, S1*(-1.))
+
+            implMat.addValue(k*nbComp,  k   *nbComp, S2)
+            implMat.addValue(k*nbComp, (k-1)*nbComp, S2*(-1.))
+        
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName,scaling):
+    dim=1
+    nbCells = nx
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False
+    
+    dx=(b-a)/nx
+    dt = cfl * dx / c0
+
+    nbVoisinsMax=2
+    
+    #iteration vectors
+    Un_staggered =cdmath.Vector(nbCells*(dim+1))
+    dUn_staggered=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    pressure_field_staggered, velocity_field_staggered = initial_conditions_Riemann_problem(a,b,nx)
+    max_initial_p=max(pressure_field_staggered)
+    min_initial_p=min(pressure_field_staggered)
+    max_initial_v=max(velocity_field_staggered)
+    min_initial_v=min(velocity_field_staggered)
+    
+    for k in range(nbCells):
+        Un_staggered[k*(dim+1)+0] =     pressure_field_staggered[k]
+        Un_staggered[k*(dim+1)+1] =rho0*velocity_field_staggered[k]
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Finite volumes schemes for the 2D Wave System", artist = "CEA Saclay", comment="Shock propagation")
+    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "2DWaveSystem_Staggered"+".mp4", ntmax):
+        #sauvegarde de la donnée initiale
+        plt.xlabel('x (m)')
+        plt.ylabel('Pressure -Pa)')
+        plt.xlim(a,b)
+        plt.ylim( min_initial_p - 0.1*(max_initial_p-min_initial_p), max_initial_p +  0.1*(max_initial_p-min_initial_p) )
+        plt.title("Riemann problem for Wave system on " + str(nx) + " cells")
+        line2, = plt.plot([a+0.5*dx + i*dx for i in range(nx)], pressure_field_staggered, label='Staggered scheme') #new picture for video # Returns a tuple of line objects, thus the comma
+        plt.legend()
+        writer.grab_frame()
+        plt.savefig("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+"_0"+".png")
+        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+"_0"+".txt", pressure_field_staggered, delimiter="\n")
+        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+"_0"+".txt", velocity_field_staggered, delimiter="\n")
+        
+        divMat_staggered=computeStaggeredDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling)
+            
+        iterGMRESMax=50
+    
+        divMat_staggered.diagonalShift(1)#only after  filling all coefficients
+        LS_staggered=cdmath.LinearSolver(divMat_staggered,Un_staggered,iterGMRESMax, precision, "GMRES","ILU")
+    
+        print("Starting computation of the linear wave system with staggered scheme …")
+        
+        # Starting time loop
+        while (it<ntmax and time <= tmax and not isStationary):
+            dUn_staggered=Un_staggered.deepCopy()
+            LS_staggered.setSndMember(Un_staggered)
+            Un_staggered=LS_staggered.solve();
+            if(not LS_staggered.getStatus()):
+                print( "Linear system did not converge for staggered scheme ", LS.getNumberOfIter(), " GMRES iterations" )
+                raise ValueError("Pas de convergence du système linéaire");
+            dUn_staggered-=Un_staggered
+    
+            for k in range(nbCells):
+                pressure_field_staggered[k] = Un_staggered[k*(dim+1)+0]
+                velocity_field_staggered[k] = Un_staggered[k*(dim+1)+1] / rho0
+    
+            line2.set_ydata(pressure_field_staggered)
+            writer.grab_frame()
+    
+            time=time+dt;
+            it=it+1;
+        
+            #Sauvegardes
+            if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+                print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+                print( "Linear system converged in ", LS_staggered.getNumberOfIter(), " GMRES iterations" )
+    
+                np.savetxt("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+str(it)+".txt", pressure_field_staggered, delimiter="\n")
+                np.savetxt("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+str(it)+".txt", velocity_field_staggered, delimiter="\n")
+                plt.savefig("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+str(it)+".png")
+    
+                print()
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
+        return
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print( "------------------------------------------------------------------------------------")
+
+        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat.txt", pressure_field_staggered, delimiter="\n")
+        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat.txt", velocity_field_staggered, delimiter="\n")
+        plt.savefig("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat.png")
+
+        return
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+        return
+
+
+def solve( a,b,nx, meshName, scaling, meshType, cfl):
+
+    print( "Resolution of the Wave system in dimension 1 on "+str(nx)+ " cells, staggered scheme")
+    print( "Initial data : ", "Riemann problem")
+    print( "Boundary conditions : ", "Neumann")
+    print( "Mesh name : ",meshName , ", ", nx, " cells")
+    
+    # Problem data
+    tmax = 10000.
+    ntmax = 50
+    output_freq = 1
+
+    WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName, scaling)
+    
+    return
+    
+
+if __name__ == """__main__""":
+    a=0.
+    b=1.
+    nx=100
+    cfl=0.99
+    scaling=0
+    solve( a,b,nx,"SquareRegularSquares",scaling,"RegularSquares",cfl)
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..9026531
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleWaveSystem_1DFV_Upwind ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystem1DUpwind.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind/WaveSystem1DUpwind.py b/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind/WaveSystem1DUpwind.py
new file mode 100755 (executable)
index 0000000..945f163
--- /dev/null
@@ -0,0 +1,199 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+import cdmath
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_wave_system(my_mesh):
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    if(dim!=1):
+        raise ValueError("initial_conditions_wave_system: Mesh dimension should be 1")
+        
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, dim)
+    U              = cdmath.Field("Conservative vector", cdmath.CELLS, my_mesh, dim+1)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+
+        
+        pressure_field[i] = p0
+        if(x>0.5):
+            velocity_field[i,0] =   1
+        else:    
+            velocity_field[i,0] =  -1
+            
+        U[i,0] =   p0
+        U[i,1] =  rho0*velocity_field[i,0]
+        
+    return U, pressure_field, velocity_field
+
+def jacobianMatrices():
+    A=cdmath.Matrix(2,2)
+    absA=cdmath.Matrix(2,2)
+
+    absA[0,0]=c0
+    absA[1,1]=c0
+    A[1,0]=1
+    A[0,1]=c0*c0
+    
+    return A, absA
+    
+def Flux(U):
+
+    result=cdmath.Vector(2)
+    result[0] = c0*c0*U[1]
+    result[1] = U[0]
+            
+    return result
+    
+def numericalFlux(Uj,Ujp1,absA):
+
+    Fj   = Flux(Uj)
+    Fjp1 = Flux(Ujp1)
+            
+    return Fj+Fjp1 +absA*(Uj-Ujp1)
+        
+def computeFluxes(U, SumFluxes):
+    my_mesh =U.getMesh();
+    nbCells = my_mesh.getNumberOfCells();
+    dim=my_mesh.getMeshDimension();
+    nbComp=U.getNumberOfComponents();
+    Fj=cdmath.Vector(nbComp)
+    Fjp1=cdmath.Vector(nbComp)
+    Fjm1=cdmath.Vector(nbComp)
+    Uj=cdmath.Vector(nbComp)
+    Ujp1=cdmath.Vector(nbComp)
+    Ujm1=cdmath.Vector(nbComp)
+    normal=cdmath.Vector(dim)
+    sumFluxCourant=cdmath.Vector(nbComp)
+    sumFluxCourant2=cdmath.Vector(nbComp)
+
+    A, absA=jacobianMatrices()
+
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+
+        for i in range(nbComp) :
+            Uj[i]=U[j,i];
+            sumFluxCourant[i]=0;
+
+        if ( j==0) :
+            for i in range(nbComp) :
+                Ujp1[i]=U[j+1,i];
+                Ujm1[i]=U[j  ,i];
+        elif ( j==nbCells-1) :
+            for i in range(nbComp) :
+                Ujp1[i]=U[j  ,i];
+                Ujm1[i]=U[j-1,i];
+        else :
+            for i in range(nbComp) :
+                Ujp1[i]=U[j+1,i];
+                Ujm1[i]=U[j-1,i];
+            
+        Fr=numericalFlux(Uj,Ujp1,absA)
+        Fl=numericalFlux(Ujm1,Uj,absA)
+
+        sumFluxCourant = (Fr - Fl)*0.5*(1./Cj.getMeasure())
+            
+        #On divise par le volume de la cellule la contribution des flux au snd membre
+        for i in range(nbComp):
+            SumFluxes[j,i]=sumFluxCourant[i];
+
+
+def WaveSystem1DVF(ntmax, tmax, cfl, my_mesh, output_freq, resolution):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    
+    SumFluxes = cdmath.Field("Fluxes", cdmath.CELLS, my_mesh, dim+1)
+
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    U, pressure_field, velocity_field = initial_conditions_wave_system(my_mesh)
+
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+    
+    print("Starting computation of the linear wave system with an UPWIND explicit scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        computeFluxes(U,SumFluxes);
+        
+        SumFluxes*=dt;
+        maxVector=SumFluxes.normMax()
+        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision
+        U-=SumFluxes;
+    
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 )
+            print()
+
+            for k in range(nbCells):
+                pressure_field[k]=U[k,0]
+                velocity_field[k,0]=U[k,1]/rho0
+
+            pressure_field.setTime(time,it);
+            pressure_field.writeCSV("WaveSystem1DUpwind_pressure");
+            velocity_field.setTime(time,it);
+            velocity_field.writeCSV("WaveSystem1DUpwind_velocity");
+    
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "|| Un+1 - Un || : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 )
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
+        raise ValueError("Maximum number of time steps reached : Stationary state not found !!!!!!!")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time )
+        for k in range(nbCells):
+            pressure_field[k]=U[k,0]
+            velocity_field[k,0]=U[k,1]/rho0
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeCSV("WaveSystem1DUpwind_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeCSV("WaveSystem1DUpwind_velocity_Stat");
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint" )
+        raise ValueError("Maximum time reached : Stationary state not found !!!!!!!")
+
+
+def solve(my_mesh,resolution):
+    print("Resolution of the 1D Riemann problem for the Wave system with Upwind explicit scheme:")
+
+    # Problem data
+    tmax = 1.
+    ntmax = 100
+    cfl = 0.95
+    output_freq = 10
+
+    WaveSystem1DVF(ntmax, tmax, cfl, my_mesh, output_freq,resolution)
+
+if __name__ == """__main__""":
+
+    xinf=0
+    xsup=1
+    M=cdmath.Mesh(xinf,xsup,10)
+
+    solve(M,100)
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind_RiemannProblem/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind_RiemannProblem/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..51c6c6b
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleWaveSystem_1DUpwind_RiemannProblem ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystem1DUpwind_RiemannProblem.py)
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind_RiemannProblem/WaveSystem1DUpwind_RiemannProblem.py b/CDMATH/tests/examples/WaveSystem/WaveSystem1DUpwind_RiemannProblem/WaveSystem1DUpwind_RiemannProblem.py
new file mode 100755 (executable)
index 0000000..ad3f8d6
--- /dev/null
@@ -0,0 +1,226 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+import cdmath
+import numpy as np
+import matplotlib
+matplotlib.use("Agg")
+import matplotlib.pyplot as plt
+import matplotlib.animation as manimation
+import sys
+
+p0=155.e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_Riemann_problem(a,b,nx):
+    print( "Initial data Riemann problem" )
+
+    dx = (b - a) / nx #space step
+    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
+
+    u_initial = [ 0 ]*nx
+    p_initial = [ (xi<(a+b)/2)*p0 + (xi>=(a+b)/2)*p0/2  for xi in x]
+
+    return p_initial, u_initial
+
+def jacobianMatrices(coeff,scaling):
+    dim=1
+    A=cdmath.Matrix(dim+1,dim+1)
+    absA=cdmath.Matrix(dim+1,dim+1)
+
+    absA[0,0]=c0*coeff
+    for i in range(dim):
+        for j in range(dim):
+            absA[i+1,j+1]=c0*coeff
+        if( scaling==0):
+            A[0,i+1]=c0*c0*coeff
+            A[i+1,0]=      coeff
+        elif( scaling==1):
+            A[0,i+1]=      coeff
+            A[i+1,0]=      coeff
+        else:
+            A[0,i+1]=   c0*coeff
+            A[i+1,0]=   c0*coeff
+       
+    return A,absA
+    
+    
+def computeUpwindDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling):
+    nbCells = nx
+    dx=(b-a)/nx
+    dim=1
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    A,absA= jacobianMatrices(dt/dx,scaling)
+    for j in range(nbCells):#On parcourt les cellules
+        if ( j==0) :
+            implMat.addValue(j*nbComp,(j+1)*nbComp,(A-absA)*(1./2))
+            implMat.addValue(j*nbComp,    j*nbComp,(A-absA)*(-1./2))
+        elif ( j==nbCells-1) :
+            implMat.addValue(j*nbComp,    j*nbComp,(A+absA)*(1./2))
+            implMat.addValue(j*nbComp,(j-1)*nbComp,(A+absA)*(-1./2))
+        else :
+            implMat.addValue(j*nbComp,(j+1)*nbComp,(A-absA)*(1./2))
+            implMat.addValue(j*nbComp,    j*nbComp,(A-absA)*(-1./2))
+
+            implMat.addValue(j*nbComp,    j*nbComp,(A+absA)*(1./2))
+            implMat.addValue(j*nbComp,(j-1)*nbComp,(A+absA)*(-1./2))
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName,scaling):
+    dim=1
+    nbCells = nx
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False
+    
+    dx=(b-a)/nx
+    dt = cfl * dx / c0
+
+    nbVoisinsMax=2
+
+    #iteration vectors
+    Un =cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    Un_implicite =cdmath.Vector(nbCells*(dim+1))
+    dUn_implicite=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    pressure_field, velocity_field = initial_conditions_Riemann_problem(a,b,nx)
+    pressure_field_implicite, velocity_field_implicite = initial_conditions_Riemann_problem(a,b,nx)
+    max_initial_p=max(pressure_field)
+    min_initial_p=min(pressure_field)
+    max_initial_v=max(velocity_field)
+    min_initial_v=min(velocity_field)
+    
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =     pressure_field[k]
+        Un[k*(dim+1)+1] =rho0*velocity_field[k]
+        Un_implicite[k*(dim+1)+0] =     pressure_field_implicite[k]
+        Un_implicite[k*(dim+1)+1] =rho0*velocity_field_implicite[k]
+
+    # Video settings
+    FFMpegWriter = manimation.writers['ffmpeg']
+    metadata = dict(title="Finite volumes schemes for the 2D Wave System", artist = "CEA Saclay", comment="Shock propagation")
+    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
+    with writer.saving(plt.figure(), "2DWaveSystem_Upwind"+".mp4", ntmax):
+        #sauvegarde de la donnée initiale
+        plt.xlabel('x (m)')
+        plt.ylabel('Pressure -Pa)')
+        plt.xlim(a,b)
+        plt.ylim( min_initial_p - 0.1*(max_initial_p-min_initial_p), max_initial_p +  0.1*(max_initial_p-min_initial_p) )
+        plt.title("Riemann problem for Wave system on " + str(nx) + " cells")
+        line1, = plt.plot([a+0.5*dx + i*dx for i in range(nx)], pressure_field, label='Explicit upwind scheme') #new picture for video # Returns a tuple of line objects, thus the comma
+        line3, = plt.plot([a+0.5*dx + i*dx for i in range(nx)], pressure_field_implicite, label='Implicit upwind scheme') #new picture for video # Returns a tuple of line objects, thus the comma
+        plt.legend()
+        writer.grab_frame()
+        np.savetxt( "WaveSystem"+str(dim)+"DUpwindExplicit"+meshName+"_pressure"+"_0"+".txt", pressure_field, delimiter="\n")
+        np.savetxt( "WaveSystem"+str(dim)+"DUpwindExplicit"+meshName+"_velocity"+"_0"+".txt", velocity_field, delimiter="\n")
+        np.savetxt( "WaveSystem"+str(dim)+"DUpwindImplicit"+meshName+"_pressure"+"_0"+".txt", pressure_field_implicite, delimiter="\n")
+        np.savetxt( "WaveSystem"+str(dim)+"DUpwindImplicit"+meshName+"_velocity"+"_0"+".txt", velocity_field_implicite, delimiter="\n")
+        plt.savefig("WaveSystem"+str(dim)+"DUpwind"        +meshName+"_pressure"+"_0"+".png")
+        
+        divMat=computeUpwindDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling)
+        divMat_implicit=computeUpwindDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling)
+            
+        iterGMRESMax=50
+    
+        divMat_implicit.diagonalShift(1)#only after  filling all coefficients
+        if( scaling==0):
+            LS=cdmath.LinearSolver(divMat_implicit,Un,iterGMRESMax, precision, "GMRES","ILU")
+        else:
+            LS=cdmath.LinearSolver(divMat_implicit,Vn,iterGMRESMax, precision, "GMRES","ILU")
+    
+        print("Starting computation of the linear wave system with an upwind scheme …")
+        
+        # Starting time loop
+        while (it<ntmax and time <= tmax and not isStationary):
+            dUn=divMat*Un
+            Un-=dUn
+    
+            dUn_implicite=Un_implicite.deepCopy()
+            LS.setSndMember(Un_implicite)
+            Un_implicite=LS.solve();
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations" )
+                raise ValueError("Pas de convergence du système linéaire");
+            dUn_implicite-=Un_implicite
+    
+            for k in range(nbCells):
+                pressure_field[k] = Un[k*(dim+1)+0]
+                velocity_field[k] = Un[k*(dim+1)+1] / rho0
+                pressure_field_implicite[k] = Un_implicite[k*(dim+1)+0]
+                velocity_field_implicite[k] = Un_implicite[k*(dim+1)+1] / rho0
+    
+            line1.set_ydata(pressure_field)
+            line3.set_ydata(pressure_field_implicite)
+            writer.grab_frame()
+    
+            time=time+dt;
+            it=it+1;
+        
+            #Sauvegardes
+            if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+                print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+                print( "Linear system converged in ", LS.getNumberOfIter(), " GMRES iterations" )
+    
+                np.savetxt("WaveSystem" +str(dim)+"DUpwindExplicit"+meshName+"_pressure"+str(it)+".txt", pressure_field          , delimiter="\n")
+                np.savetxt("WaveSystem" +str(dim)+"DUpwindExplicit"+meshName+"_velocity"+str(it)+".txt", velocity_field          , delimiter="\n")
+                np.savetxt("WaveSystem" +str(dim)+"DUpwindImplicit"+meshName+"_pressure"+str(it)+".txt", pressure_field          , delimiter="\n")
+                np.savetxt("WaveSystem" +str(dim)+"DUpwindImplicit"+meshName+"_velocity"+str(it)+".txt", velocity_field          , delimiter="\n")
+                plt.savefig("WaveSystem"+str(dim)+"DUpwind"        +meshName+"_pressure"+str(it)+".png")
+    
+                print()
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
+        return
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time )
+        print( "------------------------------------------------------------------------------------")
+
+        np.savetxt( "WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat.txt", pressure_field, delimiter="\n")
+        np.savetxt( "WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat.txt", velocity_field, delimiter="\n")
+        plt.savefig("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat.png")
+
+        return
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+        return
+
+
+def solve( a,b,nx, meshName, scaling, meshType, cfl):
+
+    print( "Resolution of the Wave system in dimension 1 on "+str(nx)+ " cells, upwind scheme")
+    print( "Initial data : ", "Riemann problem")
+    print( "Boundary conditions : ", "Neumann")
+    print( "Mesh name : ",meshName , ", ", nx, " cells")
+    
+    # Problem data
+    tmax = 10000.
+    ntmax = 50
+    output_freq = 1
+
+    WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName, scaling)
+    
+    return
+    
+
+if __name__ == """__main__""":
+    a=0.
+    b=1.
+    nx=100
+    cfl=0.99
+    scaling=0
+    solve( a,b,nx,"SquareRegularSquares",scaling,"RegularSquares",cfl)
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem2DUpwind_RiemannProblem/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem2DUpwind_RiemannProblem/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..d271c53
--- /dev/null
@@ -0,0 +1,61 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemUpwind)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(IMPLICIT_SCHEME  0 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithBrickWall.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_brickwall ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithCheckerboardSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithDeformedQuadrangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_deformedQuadrangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(IMPLICIT_SCHEME  1 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithBrickWall.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_brickwall ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithCheckerboardSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithDeformedQuadrangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_deformedQuadrangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem2DUpwind_RiemannProblem/WaveSystemUpwind.py b/CDMATH/tests/examples/WaveSystem/WaveSystem2DUpwind_RiemannProblem/WaveSystemUpwind.py
new file mode 100755 (executable)
index 0000000..9d3abde
--- /dev/null
@@ -0,0 +1,244 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Propagation d'une onde de choc droite
+#               Utilisation du schéma upwind explicite ou implicite sur un maillage général
+#               Initialisation par une discontinuité verticale
+#               Conditions aux limites de Neumann
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sin, cos, pi, sqrt
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_RiemannProblem(my_mesh):
+    print( "Initial data : Riemann problem" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    xcentre = 0
+
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+
+        velocity_field[i,0] = 0
+        velocity_field[i,1] = 0
+        velocity_field[i,2] = 0
+
+        if x < xcentre:
+            pressure_field[i] = p0
+            pass
+        else:
+            pressure_field[i] = p0/2
+            pass
+        pass
+
+    return pressure_field, velocity_field
+
+def jacobianMatrices(normal,coeff):
+    dim=normal.size()
+    A=cdmath.Matrix(dim+1,dim+1)
+    absA=cdmath.Matrix(dim+1,dim+1)
+
+    absA[0,0]=c0*coeff
+    for i in range(dim):
+        A[i+1,0]=      normal[i]*coeff
+        A[0,i+1]=c0*c0*normal[i]*coeff
+        for j in range(dim):
+            absA[i+1,j+1]=c0*normal[i]*normal[j]*coeff
+    
+    return (A - absA)*(1./2)
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+    
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure());
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    
+    SumFluxes = cdmath.Field("Fluxes", cdmath.CELLS, my_mesh, dim+1)
+
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    pressure_field, velocity_field = initial_conditions_RiemannProblem(my_mesh)
+
+    #iteration vectors
+    Un =cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =     pressure_field[k]
+        Un[k*(dim+1)+1] =rho0*velocity_field[k,0]
+        Un[k*(dim+1)+2] =rho0*velocity_field[k,1]
+        if(dim==3):
+            Un[k*(dim+1)+3] =rho0*velocity_field[k,2]
+
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity");
+
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+    
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
+    if( isImplicit):
+        #Adding the identity matrix on the diagonal
+        divMat.diagonalShift(1)#only after  filling all coefficients
+        
+        iterGMRESMax=50
+        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
+
+        LS.setComputeConditionNumber()
+        
+    print("Starting computation of the linear wave system with an explicit UPWIND scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        if(isImplicit):
+            dUn=Un.deepCopy()
+            LS.setSndMember(Un)
+            Un=LS.solve();
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations" )
+                raise ValueError("Pas de convergence du système linéaire");
+            dUn-=Un
+
+        else:
+            dUn=divMat*Un
+            Un-=dUn
+        
+        time=time+dt;
+        it=it+1;
+         #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+
+            for k in range(nbCells):
+                pressure_field[k]  =Un[k*(dim+1)+0]
+                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
+
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity",False);
+
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat");
+
+        #Postprocessing : Extraction of the diagonal data
+        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
+        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+
+
+def solve(my_mesh,filename,resolution, isImplicit):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
+    print( "Numerical method : upwind")
+    print( "Initial data : single straight discontinuity (Riemann problem)")
+    print( "Neumann boundary conditions")
+    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells")
+
+    # Problem data
+    tmax = 1.
+    ntmax = 50
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 1
+
+    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
+
+def solve_file( filename,resolution, isImplicit):
+    my_mesh = cdmath.Mesh(filename+".med")
+    solve(my_mesh, filename,resolution, isImplicit)
+    
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        filename=sys.argv[1]
+        isImplicit=bool(int(sys.argv[2]))
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100, isImplicit)
+    else :
+        raise ValueError("WaveSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemCentered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemCentered/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..f21cbe8
--- /dev/null
@@ -0,0 +1,45 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemCentered)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Centered_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Centered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_Centered_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_Centered_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshHexagonWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Centered_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemCentered/WaveSystemCentered.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemCentered/WaveSystemCentered.py
new file mode 100755 (executable)
index 0000000..95fa24f
--- /dev/null
@@ -0,0 +1,298 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Propagation d'une onde de choc sphérique
+#               Utilisation du schéma centré (implicite) sur un maillage général
+#               Initialisation par une surpression sphérique
+#               Conditions aux limites parois
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sqrt
+from numpy import sign
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_shock(my_mesh, isCircle):
+    print( "Initial data : Spherical wave" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    rayon = 0.15
+    if(not isCircle):
+        xcentre = 0.5
+        ycentre = 0.5
+        zcentre = 0.5
+    else:
+        xcentre = 0.
+        ycentre = 0.
+        zcentre = 0.
+
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        velocity_field[i,0] = 0
+        velocity_field[i,1] = 0
+        velocity_field[i,2] = 0
+
+        x = my_mesh.getCell(i).x()
+        valX = (x - xcentre) * (x - xcentre)
+
+        if(dim==1):
+            val =  sqrt(valX)
+        if(dim==2):
+            y = my_mesh.getCell(i).y()
+            valY = (y - ycentre) * (y - ycentre)
+            val =  sqrt(valX + valY)
+        if(dim==3):
+            y = my_mesh.getCell(i).y()
+            z = my_mesh.getCell(i).z()
+            valY = (y - ycentre) * (y - ycentre)
+            valZ = (z - zcentre) * (z - zcentre)
+            val =  sqrt(valX + valY + valZ)
+
+        if val < rayon:
+            pressure_field[i] = p0
+            pass
+        else:
+            pressure_field[i] = p0/2
+            pass
+        pass
+
+    return pressure_field, velocity_field
+
+def jacobianMatrices(normal, coeff, signun):
+    dim=normal.size()
+    A=cdmath.Matrix(dim+1,dim+1)
+
+    for i in range(dim):
+        A[i+1,0]=normal[i]*coeff
+        A[0,i+1]=c0*c0*normal[i]*coeff
+    
+    return A*(1./2)
+    
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+
+    v0=cdmath.Vector(dim)
+    for i in range(dim) :
+        v0[i] = 1.
+
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            signun=sign(normal*v0)
+            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
+                    v=cdmath.Vector(dim+1)
+                    for i in range(dim) :
+                        v[i+1]=normal[i]
+                    idMoinsJacCL=v.tensProduct(v)*2
+                    
+                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
+                    
+                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
+                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    iterGMRESMax=50
+    
+    #iteration vectors
+    Un=cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
+    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
+    else:
+        print( "Mesh name : ", filename )
+        raise ValueError("Mesh name should contain substring square, cube, Hexagon or disk")
+
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =      pressure_field[k]
+        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
+        if(dim>=2):
+            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
+            if(dim==3):
+                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
+            
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity");
+    #Postprocessing : save 2D picture
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_initial")
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_initial")
+    
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
+
+    # Add the identity matrix on the diagonal
+    for j in range(nbCells*(dim+1)):
+        divMat.addValue(j,j,1.)
+    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
+
+    print("Starting computation of the linear wave system with a centered scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        dUn=Un.deepCopy()
+        LS.setSndMember(Un)
+        Un=LS.solve();
+        cvgceLS=LS.getStatus();
+        iterGMRES=LS.getNumberOfIter();
+        if(not cvgceLS):
+            print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
+            raise ValueError("Pas de convergence du système linéaire");
+        dUn-=Un
+        
+        maxVector=dUn.maxVector(dim+1)
+        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
+        if(dim==3):
+            isStationary=isStationary and maxVector[3]/rho0<precision
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
+            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
+
+            for k in range(nbCells):
+                pressure_field[k]=Un[k*(dim+1)+0]
+                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
+                
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity",False);
+
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time )
+        print( "------------------------------------------------------------------------------------" )
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat");
+
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint" )
+
+
+def solve(my_mesh,meshName,resolution):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
+    print( "Numerical method : implicit centered")
+    print( "Initial data : spherical wave")
+    print( "Wall boundary conditions")
+    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells")
+    
+    # Problem data
+    tmax = 1000.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 1
+
+    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
+
+def solve_file( filename,meshName, resolution):
+    my_mesh = cdmath.Mesh(filename+".med")
+
+    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
+    
+
+if __name__ == """__main__""":
+    if len(sys.argv) >1 :
+        filename=sys.argv[1]
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100)
+    else :
+        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemPStag/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemPStag/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..61c7332
--- /dev/null
@@ -0,0 +1,45 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemPStag)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_PStag_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_PStag_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_PStag_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_PStag_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshHexagonWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_PStag_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemPStag/WaveSystemPStag.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemPStag/WaveSystemPStag.py
new file mode 100755 (executable)
index 0000000..1130af8
--- /dev/null
@@ -0,0 +1,301 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Propagation d'une onde de choc sphérique
+#               Utilisation du schéma MAC sur un maillage cartésien
+#               Initialisation par une surpression sphérique
+#               Conditions aux limites parois
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sqrt
+from numpy import sign
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_shock(my_mesh, isCircle):
+    print( "Initial data : Spherical wave" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    rayon = 0.15
+    if(not isCircle):
+        xcentre = 0.5
+        ycentre = 0.5
+        zcentre = 0.5
+    else:
+        xcentre = 0.
+        ycentre = 0.
+        zcentre = 0.
+
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        velocity_field[i,0] = 0
+        velocity_field[i,1] = 0
+        velocity_field[i,2] = 0
+
+        x = my_mesh.getCell(i).x()
+        valX = (x - xcentre) * (x - xcentre)
+
+        if(dim==1):
+            val =  sqrt(valX)
+        if(dim==2):
+            y = my_mesh.getCell(i).y()
+            valY = (y - ycentre) * (y - ycentre)
+            val =  sqrt(valX + valY)
+        if(dim==3):
+            y = my_mesh.getCell(i).y()
+            z = my_mesh.getCell(i).z()
+            valY = (y - ycentre) * (y - ycentre)
+            valZ = (z - zcentre) * (z - zcentre)
+            val =  sqrt(valX + valY + valZ)
+
+        if val < rayon:
+            pressure_field[i] = p0
+            pass
+        else:
+            pressure_field[i] = p0/2
+            pass
+        pass
+
+    return pressure_field, velocity_field
+
+def jacobianMatrices(normal, coeff, signun):
+    dim=normal.size()
+    A=cdmath.Matrix(dim+1,dim+1)
+    absA=cdmath.Matrix(dim+1,dim+1)
+
+    for i in range(dim):
+        A[i+1,0]=normal[i]*coeff
+        absA[i+1,0]=-signun*A[i+1,0]
+        A[0,i+1]=c0*c0*normal[i]*coeff
+        absA[0,i+1]=signun*A[0,i+1]
+    
+    return (A-absA)*(1./2)
+    
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+
+    v0=cdmath.Vector(dim)
+    for i in range(dim) :
+        v0[i] = 1.
+
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            signun=sign(normal*v0)
+            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
+                    v=cdmath.Vector(dim+1)
+                    for i in range(dim) :
+                        v[i+1]=normal[i]
+                    idMoinsJacCL=v.tensProduct(v)*2
+                    
+                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
+                    
+                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
+                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    iterGMRESMax=50
+    
+    #iteration vectors
+    Un=cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
+    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
+    else:
+        print( "Mesh name : ", filename )
+        raise ValueError("Mesh name should contain substring square, cube, Hexagon or disk")
+
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =      pressure_field[k]
+        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
+        if(dim>=2):
+            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
+            if(dim==3):
+                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
+            
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity");
+    #Postprocessing : save 2D picture
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_initial")
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_initial")
+    
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
+
+    # Add the identity matrix on the diagonal
+    for j in range(nbCells*(dim+1)):
+        divMat.addValue(j,j,1.)
+    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
+
+    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        dUn=Un.deepCopy()
+        LS.setSndMember(Un)
+        Un=LS.solve();
+        cvgceLS=LS.getStatus();
+        iterGMRES=LS.getNumberOfIter();
+        if(not cvgceLS):
+            print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
+            raise ValueError("Pas de convergence du système linéaire");
+        dUn-=Un
+        
+        maxVector=dUn.maxVector(dim+1)
+        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
+        if(dim==3):
+            isStationary=isStationary and maxVector[3]/rho0<precision
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
+            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
+
+            for k in range(nbCells):
+                pressure_field[k]=Un[k*(dim+1)+0]
+                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
+                
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity",False);
+
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0)
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print( "------------------------------------------------------------------------------------")
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat");
+
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint" )
+
+
+def solve(my_mesh,meshName,resolution):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
+    print( "Numerical method : implicit pseudo staggered" )
+    print( "Initial data : spherical wave" )
+    print( "Wall boundary conditions" )
+    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
+    
+    # Problem data
+    tmax = 1000.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 1
+
+    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
+
+def solve_file( filename,meshName, resolution):
+    my_mesh = cdmath.Mesh(filename+".med")
+
+    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
+    
+
+if __name__ == """__main__""":
+    if len(sys.argv) >1 :
+        filename=sys.argv[1]
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100)
+    else :
+        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemStaggered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemStaggered/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..5fc4636
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleWaveSystem_2DShock_Staggered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemStaggered.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemStaggered/WaveSystemStaggered.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemStaggered/WaveSystemStaggered.py
new file mode 100755 (executable)
index 0000000..752c378
--- /dev/null
@@ -0,0 +1,367 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Propagation d'une onde de choc sphérique
+#               Utilisation du schéma MAC sur un maillage cartésien
+#               Initialisation par une surpression sphérique
+#               Conditions aux limites périodiques
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sqrt
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_shock(my_mesh, isCircle):
+    print( "Initial data : Spherical wave")
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    rayon = 0.15
+    if(not isCircle):
+        xcentre = 0.5
+        ycentre = 0.5
+        zcentre = 0.5
+    else:
+        xcentre = 0.
+        ycentre = 0.
+        zcentre = 0.
+
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        velocity_field[i,0] = 0
+        velocity_field[i,1] = 0
+        velocity_field[i,2] = 0
+
+        x = my_mesh.getCell(i).x()
+        valX = (x - xcentre) * (x - xcentre)
+
+        if(dim==1):
+            val =  sqrt(valX)
+        if(dim==2):
+            y = my_mesh.getCell(i).y()
+            valY = (y - ycentre) * (y - ycentre)
+            val =  sqrt(valX + valY)
+        if(dim==3):
+            y = my_mesh.getCell(i).y()
+            z = my_mesh.getCell(i).z()
+            valY = (y - ycentre) * (y - ycentre)
+            valZ = (z - zcentre) * (z - zcentre)
+            val =  sqrt(valX + valY + valZ)
+
+        if val < rayon:
+            pressure_field[i] = p0
+            pass
+        else:
+            pressure_field[i] = p0/2
+            pass
+        pass
+
+    return pressure_field, velocity_field
+
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+
+    if(not my_mesh.isStructured()):
+        raise ValueError("WaveSystemStaggered: the mesh should be structured");
+
+    NxNyNz=my_mesh.getCellGridStructure()
+    DxDyDz=my_mesh.getDXYZ()
+    
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+    
+    if( dim == 1) :    
+        nx=NxNyNz[0]
+        dx=DxDyDz[0]
+            
+        if( scaling==0 ):
+            for k in range(nbCells):
+                implMat.addValue(k,1*nbCells +  k      , -c0*c0*dt/dx)
+                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*c0*dt/dx)
+    
+                implMat.addValue(  1*nbCells +  k      ,k,  dt/dx)
+                implMat.addValue(  1*nbCells + (k+1)%nx,k, -dt/dx)
+        else : # scaling >0    
+            for k in range(nbCells):
+                implMat.addValue(k,1*nbCells +  k      , -c0*dt/dx)
+                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*dt/dx)
+    
+                implMat.addValue(  1*nbCells +  k      ,k,  c0*dt/dx)
+                implMat.addValue(  1*nbCells + (k+1)%nx,k, -c0*dt/dx)
+    
+    elif( dim == 2) :# k = j*nx+i
+        nx=NxNyNz[0]
+        ny=NxNyNz[1]
+        dx=DxDyDz[0]
+        dy=DxDyDz[1]
+                
+        if( scaling==0 ):
+            for k in range(nbCells):
+                i = k % nx
+                j = k //nx
+    
+                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*c0*dt/dx)
+                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*c0*dt/dy)
+                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
+    
+                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  dt/dx)
+                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -dt/dx)
+    
+                implMat.addValue(  2*nbCells +   j       *nx + i,k,  dt/dy)
+                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -dt/dy)
+    
+        else :# scaling >0
+            for k in range(nbCells):
+                i = k % nx
+                j = k //nx
+    
+                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*dt/dx)
+                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*dt/dy)
+                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*dt/dy)
+    
+                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  c0*dt/dx)
+                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -c0*dt/dx)
+    
+                implMat.addValue(  2*nbCells +   j       *nx + i,k,  c0*dt/dy)
+                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
+    
+    elif( dim == 3) :# k = l*nx*ny+j*nx+i
+        nx=NxNyNz[0]
+        ny=NxNyNz[1]
+        nz=NxNyNz[2]
+        dx=DxDyDz[0]
+        dy=DxDyDz[1]
+        dz=DxDyDz[2]
+                
+        if( scaling==0 ):
+            for k in range(nbCells):
+                i =  k % nx
+                j = (k //nx)%ny 
+                l =  k //(nx*ny)
+                
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*c0*dt/dx)
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*c0*dt/dy)
+                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
+    
+                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*c0*dt/dz)
+                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*c0*dt/dz)
+    
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  dt/dx)
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -dt/dx)
+    
+                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  dt/dy)
+                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -dt/dy)
+    
+                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  dt/dz)
+                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -dt/dz)
+
+        else:# scaling >0
+            for k in range(nbCells):
+                i =  k % nx
+                j = (k //nx)%ny 
+                l =  k //(nx*ny)
+                
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*dt/dx)
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*dt/dy)
+                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*dt/dy)
+    
+                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*dt/dz)
+                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*dt/dz)
+    
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  c0*dt/dx)
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -c0*dt/dx)
+    
+                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  c0*dt/dy)
+                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
+    
+                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  c0*dt/dz)
+                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -c0*dt/dz)
+
+    return implMat
+
+def WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    
+    scaling=0
+    
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    iterGMRESMax=50
+    
+    #iteration vectors
+    Un=cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(dim==1 or meshName.find("square")>-1 or meshName.find("Square")>-1 or meshName.find("cube")>-1 or meshName.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
+    elif(meshName.find("disk")>-1 or meshName.find("Disk")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
+    else:
+        print( "Mesh name : ", meshName )
+        raise ValueError("Mesh name should contain substring square, cube or disk")
+
+    for k in range(nbCells):
+        Un[k + 0*nbCells] =      pressure_field[k]
+        Un[k + 1*nbCells] = rho0*velocity_field[k,0] # value on the left face
+        if(dim>=2):
+            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
+            if(dim==3):
+                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
+
+    if( scaling>0):
+        Vn = Un.deepCopy()
+        for k in range(nbCells):
+            Vn[k] = Vn[k]/c0
+            
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity");
+    #Postprocessing : save 2D picture
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_initial")
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_initial")
+    
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling)
+
+    #Add the identity matrix on the diagonal
+    for j in range(nbCells*(dim+1)):
+        divMat.addValue(j,j,1)
+
+    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
+
+    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        dUn=Un.deepCopy()
+        LS.setSndMember(Un)
+        Un=LS.solve();
+        cvgceLS=LS.getStatus();
+        iterGMRES=LS.getNumberOfIter();
+        if(not cvgceLS):
+            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
+            raise ValueError("Pas de convergence du système linéaire");
+        dUn-=Un
+        
+        max_dp=0 ;        max_dq=0
+        for k in range(nbCells):
+            max_dp = max(max_dp,abs(dUn[k]))
+            for i in range(dim):
+                max_dq=max(max_dq,abs(dUn[k+(1+i)*nbCells]))
+                
+        isStationary= max_dp/p0<precision and max_dq/rho0<precision
+
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+            print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0 )
+            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
+
+            for k in range(nbCells):
+                pressure_field[k]=Un[k]
+                velocity_field[k,0]=Un[k+1*nbCells]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k+2*nbCells]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k+3*nbCells]/rho0
+                
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity",False);
+
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0 )
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print( "------------------------------------------------------------------------------------")
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat");
+
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+
+
+def solve(my_mesh,meshName,resolution):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
+    print( "Numerical method : staggered scheme" )
+    print( "Initial data : Spherical wave" )
+    print( "Periodic boundary conditions" )
+    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
+    
+    # Problem data
+    tmax = 1000.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 1
+
+    WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
+
+def solve_file( filename,meshName, resolution):
+    my_mesh = cdmath.Mesh(filename+".med")
+
+    return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution)
+    
+
+if __name__ == """__main__""":
+    if len(sys.argv) >1 :
+        my_mesh = cdmath.Mesh(sys.argv[1])
+        solve(my_mesh,my_mesh.getName(),100)
+    else :
+        nx=50
+        my_mesh = cdmath.Mesh(0,1,nx,0,1,nx)
+        solve(my_mesh,"square",100)
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemUpwind/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemUpwind/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..68313a5
--- /dev/null
@@ -0,0 +1,81 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemUpwind)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(IMPLICIT_SCHEME  0 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_UpwindExplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_UpwindExplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshHexagonWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(IMPLICIT_SCHEME  1 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_UpwindImplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DShock_UpwindImplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemUpwind/WaveSystemUpwind.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Shock/WaveSystemUpwind/WaveSystemUpwind.py
new file mode 100755 (executable)
index 0000000..10b55c9
--- /dev/null
@@ -0,0 +1,290 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Propagation d'une onde de choc sphérique
+#               Utilisation du schéma upwind explicite ou implicite sur un maillage général
+#               Initialisation par une surpression sphérique
+#               Conditions aux limites parois
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sqrt
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_shock(my_mesh, isCircle):
+    print( "Initial data : Spherical wave" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    rayon = 0.15
+    if(not isCircle):#Case of a square domain
+        xcentre = 0.5
+        ycentre = 0.5
+        zcentre = 0.5
+    else:#Case of a disk or a hexagonal domain
+        xcentre = 0.
+        ycentre = 0.
+        zcentre = 0.
+
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        velocity_field[i,0] = 0
+        velocity_field[i,1] = 0
+        velocity_field[i,2] = 0
+
+        x = my_mesh.getCell(i).x()
+        valX = (x - xcentre) * (x - xcentre)
+
+        if(dim==1):
+            val =  sqrt(valX)
+        if(dim==2):
+            y = my_mesh.getCell(i).y()
+            valY = (y - ycentre) * (y - ycentre)
+            val =  sqrt(valX + valY)
+        if(dim==3):
+            y = my_mesh.getCell(i).y()
+            z = my_mesh.getCell(i).z()
+            valY = (y - ycentre) * (y - ycentre)
+            valZ = (z - zcentre) * (z - zcentre)
+            val =  sqrt(valX + valY + valZ)
+
+        if val < rayon:
+            pressure_field[i] = p0
+            pass
+        else:
+            pressure_field[i] = p0/2
+            pass
+        pass
+
+    return pressure_field, velocity_field
+
+def jacobianMatrices(normal,coeff):
+    dim=normal.size()
+    A=cdmath.Matrix(dim+1,dim+1)
+    absA=cdmath.Matrix(dim+1,dim+1)
+
+    absA[0,0]=c0*coeff
+    for i in range(dim):
+        A[i+1,0]=      normal[i]*coeff
+        A[0,i+1]=c0*c0*normal[i]*coeff
+        for j in range(dim):
+            absA[i+1,j+1]=c0*normal[i]*normal[j]*coeff
+    
+    return (A - absA)*(1./2)
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+    
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure());
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
+                    v=cdmath.Vector(dim+1)
+                    for i in range(dim) :
+                        v[i+1]=normal[i]
+                    idMoinsJacCL=v.tensProduct(v)*2
+                    
+                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
+                    
+                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
+                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
+    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
+        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
+    else:
+        print( "Mesh name : ", filename )
+        raise ValueError("Mesh name should contain substring square, cube, hexagon or disk")
+
+    #iteration vectors
+    Un =cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =     pressure_field[k]
+        Un[k*(dim+1)+1] =rho0*velocity_field[k,0]
+        if(dim>=2):
+            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
+            if(dim==3):
+                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
+
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity");
+
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+    
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
+    if( isImplicit):
+        #Adding the identity matrix on the diagonal
+        divMat.diagonalShift(1)#only after  filling all coefficients
+        
+        iterGMRESMax=50
+        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
+
+        LS.setComputeConditionNumber()
+        
+    print("Starting computation of the linear wave system with an explicit UPWIND scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        if(isImplicit):
+            dUn=Un.deepCopy()
+            LS.setSndMember(Un)
+            Un=LS.solve();
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations" )
+                raise ValueError("Pas de convergence du système linéaire");
+            dUn-=Un
+
+        else:
+            dUn=divMat*Un
+            Un-=dUn
+        
+        time=time+dt;
+        it=it+1;
+         #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+
+            for k in range(nbCells):
+                pressure_field[k]  =Un[k*(dim+1)+0]
+                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
+
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity",False);
+
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat");
+
+        #Postprocessing : Extraction of the diagonal data
+        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
+        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+
+
+def solve(my_mesh,filename,resolution, isImplicit):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
+    print( "Numerical method : upwind" )
+    print( "Initial data : spherical wave" )
+    print( "Wall boundary conditions" )
+    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells" )
+
+    # Problem data
+    tmax = 1.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 1
+
+    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
+
+def solve_file( filename,resolution, isImplicit):
+    my_mesh = cdmath.Mesh(filename+".med")
+    solve(my_mesh, filename,resolution, isImplicit)
+    
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        filename=sys.argv[1]
+        isImplicit=bool(int(sys.argv[2]))
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100, isImplicit)
+    else :
+        raise ValueError("WaveSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemCentered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemCentered/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..51f79f6
--- /dev/null
@@ -0,0 +1,41 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemCentered)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_Centered_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_Centered_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemCentered/WaveSystemCentered.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemCentered/WaveSystemCentered.py
new file mode 100755 (executable)
index 0000000..c6c6fa8
--- /dev/null
@@ -0,0 +1,300 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Test de préservation d'un état stationnaire
+#               Utilisation du schéma centré (implicite) sur un maillage général
+#               Initialisation par un vortex stationnaire
+#               Conditions aux limites parois
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sin, cos, pi, sqrt
+from numpy import sign
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_disk_vortex(my_mesh):
+    print( "Disk vortex initial data")
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    if(dim!=2):
+        raise ValueError("Wave system on disk : mesh dimension should be 2")
+        
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+        y = my_mesh.getCell(i).y()
+
+        pressure_field[i] = p0
+
+        velocity_field[i,0] = -y
+        velocity_field[i,1] =  x
+        velocity_field[i,2] = 0
+
+    return pressure_field, velocity_field
+
+def initial_conditions_square_vortex(my_mesh):
+    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)")
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+        y = my_mesh.getCell(i).y()
+        z = my_mesh.getCell(i).z()
+
+        pressure_field[i] = p0
+        if(dim==1):
+            velocity_field[i,0] = 1
+            velocity_field[i,1] = 0
+            velocity_field[i,2] = 0
+        elif(dim==2):
+            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
+            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
+            velocity_field[i,2] = 0
+        elif(dim==3):
+            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
+            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
+            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
+        
+    return pressure_field, velocity_field
+
+def jacobianMatrices(normal, coeff, signun):
+    dim=normal.size()
+    A=cdmath.Matrix(dim+1,dim+1)
+
+    for i in range(dim):
+        A[i+1,0]=normal[i]*coeff
+        A[0,i+1]=c0*c0*normal[i]*coeff
+    
+    return A*(1./2)
+    
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+
+    v0=cdmath.Vector(dim)
+    for i in range(dim) :
+        v0[i] = 1.
+
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            signun=sign(normal*v0)
+            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
+                    v=cdmath.Vector(dim+1)
+                    for i in range(dim) :
+                        v[i+1]=normal[i]
+                    idMoinsJacCL=v.tensProduct(v)*2
+                    
+                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
+                    
+                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
+                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    iterGMRESMax=50
+    
+    #iteration vectors
+    Un=cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
+    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
+        pressure_field, velocity_field = initial_conditions_disk_vortex(my_mesh)
+    else:
+        print( "Mesh name : ", filename)
+        raise ValueError("Mesh name should contain substring square, cube, Hexagon or disk")
+
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =      pressure_field[k]
+        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
+        Un[k*(dim+1)+2] = rho0*velocity_field[k,1]
+        if(dim==3):
+            Un[k*(dim+1)+3] = rho0*velocity_field[k,2]
+            
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity");
+    #Postprocessing : save 2D picture
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_initial")
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_initial")
+    
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
+
+    # Add the identity matrix on the diagonal
+    for j in range(nbCells*(dim+1)):
+        divMat.addValue(j,j,1.)
+    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
+
+    print("Starting computation of the linear wave system with a centered scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        dUn=Un.deepCopy()
+        LS.setSndMember(Un)
+        Un=LS.solve();
+        cvgceLS=LS.getStatus();
+        iterGMRES=LS.getNumberOfIter();
+        if(not cvgceLS):
+            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
+            raise ValueError("Pas de convergence du système linéaire");
+        dUn-=Un
+        
+        maxVector=dUn.maxVector(dim+1)
+        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
+        if(dim==3):
+            isStationary=isStationary and maxVector[3]/rho0<precision
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
+            print( "Linear system converged in ", iterGMRES, " GMRES iterations")
+
+            for k in range(nbCells):
+                pressure_field[k]=Un[k*(dim+1)+0]
+                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
+                
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity",False);
+
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print( "------------------------------------------------------------------------------------")
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat");
+
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+
+
+def solve(my_mesh,meshName,resolution):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
+    print( "Numerical method : implicit centered" )
+    print( "Initial data : stationary solution (constant pressure, divergence free velocity)" )
+    print( "Wall boundary conditions" )
+    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
+    
+    # Problem data
+    tmax = 1000.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 100
+
+    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
+
+def solve_file( filename,meshName, resolution):
+    my_mesh = cdmath.Mesh(filename+".med")
+
+    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
+    
+
+if __name__ == """__main__""":
+    if len(sys.argv) >1 :
+        filename=sys.argv[1]
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100)
+    else :
+        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemPStag/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemPStag/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..c272a17
--- /dev/null
@@ -0,0 +1,41 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemPStag)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_PStag_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_PStag_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemPStag/WaveSystemPStag.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemPStag/WaveSystemPStag.py
new file mode 100755 (executable)
index 0000000..f73e2b4
--- /dev/null
@@ -0,0 +1,303 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Test de préservation d'un état stationnaire
+#               Utilisation du schéma pseudo décalé (implicite) sur un maillage général
+#               Initialisation par un vortex stationnaire
+#               Conditions aux limites parois
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sin, cos, pi, sqrt
+from numpy import sign
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_disk_vortex(my_mesh):
+    print( "Disk vortex initial data" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    if(dim!=2):
+        raise ValueError("Wave system on disk : mesh dimension should be 2")
+        
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+        y = my_mesh.getCell(i).y()
+
+        pressure_field[i] = p0
+
+        velocity_field[i,0] = -y
+        velocity_field[i,1] =  x
+        velocity_field[i,2] = 0
+
+    return pressure_field, velocity_field
+
+def initial_conditions_square_vortex(my_mesh):
+    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+        y = my_mesh.getCell(i).y()
+        z = my_mesh.getCell(i).z()
+
+        pressure_field[i] = p0
+        if(dim==1):
+            velocity_field[i,0] = 1
+            velocity_field[i,1] = 0
+            velocity_field[i,2] = 0
+        elif(dim==2):
+            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
+            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
+            velocity_field[i,2] = 0
+        elif(dim==3):
+            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
+            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
+            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
+        
+    return pressure_field, velocity_field
+
+def jacobianMatrices(normal, coeff, signun):
+    dim=normal.size()
+    A=cdmath.Matrix(dim+1,dim+1)
+    absA=cdmath.Matrix(dim+1,dim+1)
+
+    for i in range(dim):
+        A[i+1,0]=normal[i]*coeff
+        absA[i+1,0]=-signun*A[i+1,0]
+        A[0,i+1]=c0*c0*normal[i]*coeff
+        absA[0,i+1]=signun*A[0,i+1]
+    
+    return (A-absA)*(1./2)
+    
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+
+    v0=cdmath.Vector(dim)
+    for i in range(dim) :
+        v0[i] = 1.
+
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            signun=sign(normal*v0)
+            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
+                    v=cdmath.Vector(dim+1)
+                    for i in range(dim) :
+                        v[i+1]=normal[i]
+                    idMoinsJacCL=v.tensProduct(v)*2
+                    
+                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
+                    
+                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
+                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    iterGMRESMax=50
+    
+    #iteration vectors
+    Un=cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
+    elif(filename.find("disk")>-1 or filename.find("Disk")>-1):
+        pressure_field, velocity_field = initial_conditions_disk_vortex(my_mesh)
+    else:
+        print( "Mesh name : ", filename)
+        raise ValueError("Mesh name should contain substring square, cube or disk")
+
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =      pressure_field[k]
+        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
+        Un[k*(dim+1)+2] = rho0*velocity_field[k,1]
+        if(dim==3):
+            Un[k*(dim+1)+3] = rho0*velocity_field[k,2]
+            
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity");
+    #Postprocessing : save 2D picture
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_initial")
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_initial")
+    
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
+
+    # Add the identity matrix on the diagonal
+    for j in range(nbCells*(dim+1)):
+        divMat.addValue(j,j,1.)
+    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
+
+    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        dUn=Un.deepCopy()
+        LS.setSndMember(Un)
+        Un=LS.solve();
+        cvgceLS=LS.getStatus();
+        iterGMRES=LS.getNumberOfIter();
+        if(not cvgceLS):
+            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
+            raise ValueError("Pas de convergence du système linéaire");
+        dUn-=Un
+        
+        maxVector=dUn.maxVector(dim+1)
+        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
+        if(dim==3):
+            isStationary=isStationary and maxVector[3]/rho0<precision
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
+            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
+
+            for k in range(nbCells):
+                pressure_field[k]=Un[k*(dim+1)+0]
+                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
+                
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity",False);
+
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print( "------------------------------------------------------------------------------------")
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat");
+
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+
+
+def solve(my_mesh,meshName,resolution):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension())
+    print( "Numerical method : implicit pseudo staggered")
+    print( "Initial data : stationary solution (constant pressure, divergence free velocity)")
+    print( "Wall boundary conditions")
+    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
+    
+    # Problem data
+    tmax = 1000.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 100
+
+    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
+
+def solve_file( filename,meshName, resolution):
+    my_mesh = cdmath.Mesh(filename+".med")
+
+    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
+    
+
+if __name__ == """__main__""":
+    if len(sys.argv) >1 :
+        filename=sys.argv[1]
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100)
+    else :
+        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemStaggered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemStaggered/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..c30f344
--- /dev/null
@@ -0,0 +1,8 @@
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_Staggered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemStaggered.py )
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemStaggered/WaveSystemStaggered.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemStaggered/WaveSystemStaggered.py
new file mode 100755 (executable)
index 0000000..092ab28
--- /dev/null
@@ -0,0 +1,339 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Test de préservation d'un état stationnaire
+#               Utilisation du schéma MAC sur un maillage cartésien
+#               Initialisation par un vortex stationnaire
+#               Conditions aux limites périodiques
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sin, cos, pi, sqrt
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_square_vortex(my_mesh):
+    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+        y = my_mesh.getCell(i).y()
+        z = my_mesh.getCell(i).z()
+
+        pressure_field[i] = p0
+        if(dim==1):
+            velocity_field[i,0] = 1
+            velocity_field[i,1] = 0
+            velocity_field[i,2] = 0
+        elif(dim==2):
+            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
+            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
+            velocity_field[i,2] = 0
+        elif(dim==3):
+            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
+            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
+            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
+        
+    return pressure_field, velocity_field
+
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+
+    if(not my_mesh.isStructured()):
+        raise ValueError("WaveSystemStaggered: the mesh should be structured");
+
+    NxNyNz=my_mesh.getCellGridStructure()
+    DxDyDz=my_mesh.getDXYZ()
+    
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+    
+    if( dim == 1) :    
+        nx=NxNyNz[0]
+        dx=DxDyDz[0]
+            
+        if( scaling==0 ):
+            for k in range(nbCells):
+                implMat.addValue(k,1*nbCells +  k      , -c0*c0*dt/dx)
+                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*c0*dt/dx)
+    
+                implMat.addValue(  1*nbCells +  k      ,k,  dt/dx)
+                implMat.addValue(  1*nbCells + (k+1)%nx,k, -dt/dx)
+        else : # scaling >0    
+            for k in range(nbCells):
+                implMat.addValue(k,1*nbCells +  k      , -c0*dt/dx)
+                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*dt/dx)
+    
+                implMat.addValue(  1*nbCells +  k      ,k,  c0*dt/dx)
+                implMat.addValue(  1*nbCells + (k+1)%nx,k, -c0*dt/dx)
+    
+    elif( dim == 2) :# k = j*nx+i
+        nx=NxNyNz[0]
+        ny=NxNyNz[1]
+        dx=DxDyDz[0]
+        dy=DxDyDz[1]
+                
+        if( scaling==0 ):
+            for k in range(nbCells):
+                i = k % nx
+                j = k //nx
+    
+                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*c0*dt/dx)
+                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*c0*dt/dy)
+                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
+    
+                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  dt/dx)
+                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -dt/dx)
+    
+                implMat.addValue(  2*nbCells +   j       *nx + i,k,  dt/dy)
+                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -dt/dy)
+    
+        else :# scaling >0
+            for k in range(nbCells):
+                i = k % nx
+                j = k //nx
+    
+                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*dt/dx)
+                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*dt/dy)
+                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*dt/dy)
+    
+                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  c0*dt/dx)
+                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -c0*dt/dx)
+    
+                implMat.addValue(  2*nbCells +   j       *nx + i,k,  c0*dt/dy)
+                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
+    
+    elif( dim == 3) :# k = l*nx*ny+j*nx+i
+        nx=NxNyNz[0]
+        ny=NxNyNz[1]
+        nz=NxNyNz[2]
+        dx=DxDyDz[0]
+        dy=DxDyDz[1]
+        dz=DxDyDz[2]
+                
+        if( scaling==0 ):
+            for k in range(nbCells):
+                i =  k % nx
+                j = (k //nx)%ny 
+                l =  k //(nx*ny)
+                
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*c0*dt/dx)
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*c0*dt/dy)
+                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
+    
+                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*c0*dt/dz)
+                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*c0*dt/dz)
+    
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  dt/dx)
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -dt/dx)
+    
+                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  dt/dy)
+                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -dt/dy)
+    
+                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  dt/dz)
+                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -dt/dz)
+
+        else:# scaling >0
+            for k in range(nbCells):
+                i =  k % nx
+                j = (k //nx)%ny 
+                l =  k //(nx*ny)
+                
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*dt/dx)
+                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*dt/dx)
+    
+                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*dt/dy)
+                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*dt/dy)
+    
+                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*dt/dz)
+                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*dt/dz)
+    
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  c0*dt/dx)
+                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -c0*dt/dx)
+    
+                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  c0*dt/dy)
+                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
+    
+                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  c0*dt/dz)
+                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -c0*dt/dz)
+
+    return implMat
+
+def WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    
+    scaling=0
+    
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+    iterGMRESMax=50
+    
+    #iteration vectors
+    Un=cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
+
+    for k in range(nbCells):
+        Un[k + 0*nbCells] =      pressure_field[k]
+        Un[k + 1*nbCells] = rho0*velocity_field[k,0] # value on the left face
+        Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
+        if(dim==3):
+            Un[k + 3*nbCells] = rho0*initial_velocity[k,2]
+    if( scaling>0):
+        Vn = Un.deepCopy()
+        for k in range(nbCells):
+            Vn[k] = Vn[k]/c0
+            
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity");
+    #Postprocessing : save 2D picture
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_initial")
+    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_initial")
+    
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling)
+
+    #Add the identity matrix on the diagonal
+    for j in range(nbCells*(dim+1)):
+        divMat.addValue(j,j,1)
+
+    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
+
+    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        dUn=Un.deepCopy()
+        LS.setSndMember(Un)
+        Un=LS.solve();
+        cvgceLS=LS.getStatus();
+        iterGMRES=LS.getNumberOfIter();
+        if(not cvgceLS):
+            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
+            raise ValueError("Pas de convergence du système linéaire");
+        dUn-=Un
+        
+        max_dp=0 ;        max_dq=0
+        for k in range(nbCells):
+            max_dp = max(max_dp,abs(dUn[k]))
+            for i in range(dim):
+                max_dq=max(max_dq,abs(dUn[k+(1+i)*nbCells]))
+                
+        isStationary= max_dp/p0<precision and max_dq/rho0<precision
+
+        time=time+dt;
+        it=it+1;
+    
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+            print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0)
+            print( "Linear system converged in ", iterGMRES, " GMRES iterations")
+
+            for k in range(nbCells):
+                pressure_field[k]=Un[k]
+                velocity_field[k,0]=Un[k+1*nbCells]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k+2*nbCells]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k+3*nbCells]/rho0
+                
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity",False);
+
+    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
+    print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0 )
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+        print( "------------------------------------------------------------------------------------")
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat");
+
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint" )
+
+
+def solve(my_mesh,meshName,resolution):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension())
+    print( "Numerical method : staggered scheme")
+    print( "Initial data : stationary solution (constant pressure, divergence free velocity)")
+    print( "Periodic boundary conditions")
+    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells")
+    
+    # Problem data
+    tmax = 1000.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 100
+
+    WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
+
+def solve_file( filename,meshName, resolution):
+    my_mesh = cdmath.Mesh(filename+".med")
+
+    return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution)
+    
+
+if __name__ == """__main__""":
+    if len(sys.argv) >1 :
+        my_mesh = cdmath.Mesh(sys.argv[1])
+        solve(my_mesh,my_mesh.getName(),100)
+    else :
+        nx=50
+        my_mesh = cdmath.Mesh(0,1,nx,0,1,nx)
+        solve(my_mesh,my_mesh.getName(),100)
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemUpwind/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemUpwind/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..912b52c
--- /dev/null
@@ -0,0 +1,77 @@
+
+file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
+install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemUpwind)
+
+if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+    SET(IMPLICIT_SCHEME  0 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindExplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindExplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(IMPLICIT_SCHEME  0 )
+
+    SET(MESH_FILE  ${MED_MESHES}/meshSquare.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/squareWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/meshCube.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindImplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/cubeWithCubes.med  )
+
+    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindImplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithTriangles.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSquares.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithSpiderWeb.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+    SET(MESH_FILE  ${MED_MESHES}/diskWithHexagons.med  )
+
+    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
+
+endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
+
+
diff --git a/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemUpwind/WaveSystemUpwind.py b/CDMATH/tests/examples/WaveSystem/WaveSystem_Stationary/WaveSystemUpwind/WaveSystemUpwind.py
new file mode 100755 (executable)
index 0000000..bb190e0
--- /dev/null
@@ -0,0 +1,292 @@
+#!/usr/bin/env python3
+# -*-coding:utf-8 -*
+
+#===============================================================================================================================
+# Name        : Résolution VF du système des ondes 2D sans terme source
+#                \partial_t p + c^2 \div q = 0
+#                \partial_t q +    \grad p = 0
+# Author      : Michaël Ndjinga
+# Copyright   : CEA Saclay 2019
+# Description : Test de préservation d'un état stationnaire
+#               Utilisation du schéma upwind explicite ou implicite sur un maillage général
+#               Initialisation par une vortex stationnaire
+#               Conditions aux limites parois
+#                      Création et sauvegarde du champ résultant et des figures
+#================================================================================================================================
+
+
+from math import sin, cos, pi, sqrt
+import cdmath
+import PV_routines
+import VTK_routines
+import sys
+
+p0=155e5#reference pressure in a pressurised nuclear vessel
+c0=700.#reference sound speed for water at 155 bars, 600K
+rho0=p0/c0*c0#reference density
+precision=1e-5
+
+def initial_conditions_disk_vortex(my_mesh):
+    print( "Disk vortex initial data")
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    if(dim!=2):
+        raise ValueError("Wave system on disk : mesh dimension should be 2")
+        
+    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+        y = my_mesh.getCell(i).y()
+
+        pressure_field[i] = p0
+
+        velocity_field[i,0] = -y
+        velocity_field[i,1] =  x
+        velocity_field[i,2] = 0
+
+    return pressure_field, velocity_field
+
+def initial_conditions_square_vortex(my_mesh):
+    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)" )
+    dim     = my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+
+    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
+    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
+
+    for i in range(nbCells):
+        x = my_mesh.getCell(i).x()
+        y = my_mesh.getCell(i).y()
+        z = my_mesh.getCell(i).z()
+
+        pressure_field[i] = p0
+        if(dim==1):
+            velocity_field[i,0] = 1
+            velocity_field[i,1] = 0
+            velocity_field[i,2] = 0
+        elif(dim==2):
+            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
+            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
+            velocity_field[i,2] = 0
+        elif(dim==3):
+            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
+            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
+            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
+        
+    return pressure_field, velocity_field
+
+def jacobianMatrices(normal,coeff):
+    dim=normal.size()
+    A=cdmath.Matrix(dim+1,dim+1)
+    absA=cdmath.Matrix(dim+1,dim+1)
+
+    absA[0,0]=c0*coeff
+    for i in range(dim):
+        A[i+1,0]=      normal[i]*coeff
+        A[0,i+1]=c0*c0*normal[i]*coeff
+        for j in range(dim):
+            absA[i+1,j+1]=c0*normal[i]*normal[j]*coeff
+    
+    return (A - absA)*(1./2)
+    
+def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
+    nbCells = my_mesh.getNumberOfCells()
+    dim=my_mesh.getMeshDimension()
+    nbComp=dim+1
+    normal=cdmath.Vector(dim)
+
+    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
+
+    idMoinsJacCL=cdmath.Matrix(nbComp)
+    
+    for j in range(nbCells):#On parcourt les cellules
+        Cj = my_mesh.getCell(j)
+        nbFaces = Cj.getNumberOfFaces();
+
+        for k in range(nbFaces) :
+            indexFace = Cj.getFacesId()[k];
+            Fk = my_mesh.getFace(indexFace);
+            for i in range(dim) :
+                normal[i] = Cj.getNormalVector(k, i);#normale sortante
+
+            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure());
+
+            cellAutre =-1
+            if ( not Fk.isBorder()) :
+                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
+                if (Fk.getCellsId()[0] == j) :
+                    # hypothese verifiée 
+                    cellAutre = Fk.getCellsId()[1];
+                elif(Fk.getCellsId()[1] == j) :
+                    # hypothese non verifiée 
+                    cellAutre = Fk.getCellsId()[0];
+                else :
+                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
+                    
+                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+            else  :
+                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
+                    v=cdmath.Vector(dim+1)
+                    for i in range(dim) :
+                        v[i+1]=normal[i]
+                    idMoinsJacCL=v.tensProduct(v)*2
+                    
+                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
+                    
+                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
+                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
+                    Fp = my_mesh.getFace(indexFP)
+                    cellAutre = Fp.getCellsId()[0]
+                    
+                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
+                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
+                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
+                    print( Fk.getGroupName() )
+                    raise ValueError("computeFluxes: Unknown boundary condition name");
+                
+    return implMat
+
+def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
+    dim=my_mesh.getMeshDimension()
+    nbCells = my_mesh.getNumberOfCells()
+    meshName=my_mesh.getName()
+    
+    dt = 0.
+    time = 0.
+    it=0;
+    isStationary=False;
+    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
+
+    # Initial conditions #
+    print("Construction of the initial condition …")
+    if(filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
+        pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
+    elif(filename.find("disk")>-1 or filename.find("Disk")>-1):
+        pressure_field, velocity_field = initial_conditions_disk_vortex(my_mesh)
+    else:
+        print( "Mesh name : ", filename)
+        raise ValueError("Mesh name should contain substring square, cube or disk")
+
+    #iteration vectors
+    Un =cdmath.Vector(nbCells*(dim+1))
+    dUn=cdmath.Vector(nbCells*(dim+1))
+    
+    for k in range(nbCells):
+        Un[k*(dim+1)+0] =     pressure_field[k]
+        Un[k*(dim+1)+1] =rho0*velocity_field[k,0]
+        Un[k*(dim+1)+2] =rho0*velocity_field[k,1]
+        if(dim==3):
+            Un[k*(dim+1)+3] =rho0*velocity_field[k,2]
+
+    #sauvegarde de la donnée initiale
+    pressure_field.setTime(time,it);
+    pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure");
+    velocity_field.setTime(time,it);
+    velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity");
+
+    dx_min=my_mesh.minRatioVolSurf()
+
+    dt = cfl * dx_min / c0
+    
+    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
+    if( isImplicit):
+        #Adding the identity matrix on the diagonal
+        divMat.diagonalShift(1)#only after  filling all coefficients
+        
+        iterGMRESMax=50
+        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
+
+        LS.setComputeConditionNumber()
+        
+    print("Starting computation of the linear wave system with an UPWIND scheme …")
+    
+    # Starting time loop
+    while (it<ntmax and time <= tmax and not isStationary):
+        if(isImplicit):
+            dUn=Un.deepCopy()
+            LS.setSndMember(Un)
+            Un=LS.solve();
+            if(not LS.getStatus()):
+                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
+                raise ValueError("Pas de convergence du système linéaire");
+            dUn-=Un
+
+        else:
+            dUn=divMat*Un
+            Un-=dUn
+        
+        time=time+dt;
+        it=it+1;
+        #Sauvegardes
+        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
+            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+
+            for k in range(nbCells):
+                pressure_field[k]  =Un[k*(dim+1)+0]
+                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
+                if(dim>1):
+                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
+                    if(dim>2):
+                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
+
+            pressure_field.setTime(time,it);
+            pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure",False);
+            velocity_field.setTime(time,it);
+            velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity",False);
+
+    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
+    print()
+
+    if(it>=ntmax):
+        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
+    elif(isStationary):
+        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
+
+        pressure_field.setTime(time,0);
+        pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat");
+        velocity_field.setTime(time,0);
+        velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat");
+
+        #Postprocessing : Extraction of the diagonal data
+        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
+        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
+        #Postprocessing : save 2D picture
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
+        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
+        
+    else:
+        print( "Temps maximum Tmax= ", tmax, " atteint")
+
+
+def solve(my_mesh,filename,resolution, isImplicit):
+    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension())
+    print( "Numerical method : upwind")
+    print( "Initial data : stationary solution (constant pressure, divergence free velocity)")
+    print( "Wall boundary conditions")
+    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells")
+
+    # Problem data
+    tmax = 1.
+    ntmax = 100
+    cfl = 1./my_mesh.getSpaceDimension()
+    output_freq = 100
+
+    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
+
+def solve_file( filename,resolution):
+    my_mesh = cdmath.Mesh(filename+".med")
+    solve(my_mesh, filename,resolution, isImplicit)
+    
+if __name__ == """__main__""":
+    if len(sys.argv) >2 :
+        filename=sys.argv[1]
+        isImplicit=bool(int(sys.argv[2]))
+        my_mesh = cdmath.Mesh(filename)
+        solve(my_mesh,filename,100, isImplicit)
+    else :
+        raise ValueError("WaveSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/WaveSystem1DStaggered_RiemannProblem/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem1DStaggered_RiemannProblem/CMakeLists.txt
deleted file mode 100755 (executable)
index 2ab500a..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleWaveSystem_1DStaggered_RiemannProblem ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystem1DStaggered_RiemannProblem.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem1DStaggered_RiemannProblem/WaveSystem1DStaggered_RiemannProblem.py b/CDMATH/tests/examples/WaveSystem1DStaggered_RiemannProblem/WaveSystem1DStaggered_RiemannProblem.py
deleted file mode 100755 (executable)
index 3603977..0000000
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-import cdmath
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-
-p0=155.e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_Riemann_problem(a,b,nx):
-    print( "Initial data Riemann problem" )
-
-    dx = (b - a) / nx #space step
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-
-    u_initial = [ 0 ]*nx
-    p_initial = [ (xi<(a+b)/2)*p0 + (xi>=(a+b)/2)*p0/2  for xi in x]
-
-    return p_initial, u_initial
-
-def staggeredMatrices(coeff,scaling):
-    dim=1
-    S1=cdmath.Matrix(dim+1,dim+1)
-    S2=cdmath.Matrix(dim+1,dim+1)
-
-    for i in range(dim):
-        if( scaling==0):
-            S1[0,i+1]=c0*c0*coeff
-            S2[i+1,0]=      coeff
-        else:
-            S1[0,i+1]=   c0*coeff
-            S2[i+1,0]=   c0*coeff
-       
-    return S1,S2
-        
-def computeStaggeredDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling):
-    nbCells = nx
-    dx=(b-a)/nx
-    dim=1
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    S1,S2 = staggeredMatrices(dt/dx,scaling)
-    for k in range(nbCells):#On parcourt les cellules
-        if ( k==0) :
-            implMat.addValue(k*nbComp, (k+1)*nbComp, S1)
-            implMat.addValue(k*nbComp,  k   *nbComp, S1*(-1.))
-        elif ( k==nbCells-1) :
-            implMat.addValue(k*nbComp,  k   *nbComp, S2)
-            implMat.addValue(k*nbComp, (k-1)*nbComp, S2*(-1.))
-        else :
-            implMat.addValue(k*nbComp, (k+1)*nbComp, S1)
-            implMat.addValue(k*nbComp,  k   *nbComp, S1*(-1.))
-
-            implMat.addValue(k*nbComp,  k   *nbComp, S2)
-            implMat.addValue(k*nbComp, (k-1)*nbComp, S2*(-1.))
-        
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName,scaling):
-    dim=1
-    nbCells = nx
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False
-    
-    dx=(b-a)/nx
-    dt = cfl * dx / c0
-
-    nbVoisinsMax=2
-    
-    #iteration vectors
-    Un_staggered =cdmath.Vector(nbCells*(dim+1))
-    dUn_staggered=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    pressure_field_staggered, velocity_field_staggered = initial_conditions_Riemann_problem(a,b,nx)
-    max_initial_p=max(pressure_field_staggered)
-    min_initial_p=min(pressure_field_staggered)
-    max_initial_v=max(velocity_field_staggered)
-    min_initial_v=min(velocity_field_staggered)
-    
-    for k in range(nbCells):
-        Un_staggered[k*(dim+1)+0] =     pressure_field_staggered[k]
-        Un_staggered[k*(dim+1)+1] =rho0*velocity_field_staggered[k]
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Finite volumes schemes for the 2D Wave System", artist = "CEA Saclay", comment="Shock propagation")
-    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "2DWaveSystem_Staggered"+".mp4", ntmax):
-        #sauvegarde de la donnée initiale
-        plt.xlabel('x (m)')
-        plt.ylabel('Pressure -Pa)')
-        plt.xlim(a,b)
-        plt.ylim( min_initial_p - 0.1*(max_initial_p-min_initial_p), max_initial_p +  0.1*(max_initial_p-min_initial_p) )
-        plt.title("Riemann problem for Wave system on " + str(nx) + " cells")
-        line2, = plt.plot([a+0.5*dx + i*dx for i in range(nx)], pressure_field_staggered, label='Staggered scheme') #new picture for video # Returns a tuple of line objects, thus the comma
-        plt.legend()
-        writer.grab_frame()
-        plt.savefig("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+"_0"+".png")
-        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+"_0"+".txt", pressure_field_staggered, delimiter="\n")
-        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+"_0"+".txt", velocity_field_staggered, delimiter="\n")
-        
-        divMat_staggered=computeStaggeredDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling)
-            
-        iterGMRESMax=50
-    
-        divMat_staggered.diagonalShift(1)#only after  filling all coefficients
-        LS_staggered=cdmath.LinearSolver(divMat_staggered,Un_staggered,iterGMRESMax, precision, "GMRES","ILU")
-    
-        print("Starting computation of the linear wave system with staggered scheme …")
-        
-        # Starting time loop
-        while (it<ntmax and time <= tmax and not isStationary):
-            dUn_staggered=Un_staggered.deepCopy()
-            LS_staggered.setSndMember(Un_staggered)
-            Un_staggered=LS_staggered.solve();
-            if(not LS_staggered.getStatus()):
-                print( "Linear system did not converge for staggered scheme ", LS.getNumberOfIter(), " GMRES iterations" )
-                raise ValueError("Pas de convergence du système linéaire");
-            dUn_staggered-=Un_staggered
-    
-            for k in range(nbCells):
-                pressure_field_staggered[k] = Un_staggered[k*(dim+1)+0]
-                velocity_field_staggered[k] = Un_staggered[k*(dim+1)+1] / rho0
-    
-            line2.set_ydata(pressure_field_staggered)
-            writer.grab_frame()
-    
-            time=time+dt;
-            it=it+1;
-        
-            #Sauvegardes
-            if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-                print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-                print( "Linear system converged in ", LS_staggered.getNumberOfIter(), " GMRES iterations" )
-    
-                np.savetxt("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+str(it)+".txt", pressure_field_staggered, delimiter="\n")
-                np.savetxt("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+str(it)+".txt", velocity_field_staggered, delimiter="\n")
-                plt.savefig("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+str(it)+".png")
-    
-                print()
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
-        return
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print( "------------------------------------------------------------------------------------")
-
-        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat.txt", pressure_field_staggered, delimiter="\n")
-        np.savetxt( "WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat.txt", velocity_field_staggered, delimiter="\n")
-        plt.savefig("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat.png")
-
-        return
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-        return
-
-
-def solve( a,b,nx, meshName, scaling, meshType, cfl):
-
-    print( "Resolution of the Wave system in dimension 1 on "+str(nx)+ " cells, staggered scheme")
-    print( "Initial data : ", "Riemann problem")
-    print( "Boundary conditions : ", "Neumann")
-    print( "Mesh name : ",meshName , ", ", nx, " cells")
-    
-    # Problem data
-    tmax = 10000.
-    ntmax = 50
-    output_freq = 1
-
-    WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName, scaling)
-    
-    return
-    
-
-if __name__ == """__main__""":
-    a=0.
-    b=1.
-    nx=100
-    cfl=0.99
-    scaling=0
-    solve( a,b,nx,"SquareRegularSquares",scaling,"RegularSquares",cfl)
diff --git a/CDMATH/tests/examples/WaveSystem1DUpwind/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem1DUpwind/CMakeLists.txt
deleted file mode 100755 (executable)
index 9026531..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleWaveSystem_1DFV_Upwind ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystem1DUpwind.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem1DUpwind/WaveSystem1DUpwind.py b/CDMATH/tests/examples/WaveSystem1DUpwind/WaveSystem1DUpwind.py
deleted file mode 100755 (executable)
index 945f163..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-import cdmath
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_wave_system(my_mesh):
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    if(dim!=1):
-        raise ValueError("initial_conditions_wave_system: Mesh dimension should be 1")
-        
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, dim)
-    U              = cdmath.Field("Conservative vector", cdmath.CELLS, my_mesh, dim+1)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-
-        
-        pressure_field[i] = p0
-        if(x>0.5):
-            velocity_field[i,0] =   1
-        else:    
-            velocity_field[i,0] =  -1
-            
-        U[i,0] =   p0
-        U[i,1] =  rho0*velocity_field[i,0]
-        
-    return U, pressure_field, velocity_field
-
-def jacobianMatrices():
-    A=cdmath.Matrix(2,2)
-    absA=cdmath.Matrix(2,2)
-
-    absA[0,0]=c0
-    absA[1,1]=c0
-    A[1,0]=1
-    A[0,1]=c0*c0
-    
-    return A, absA
-    
-def Flux(U):
-
-    result=cdmath.Vector(2)
-    result[0] = c0*c0*U[1]
-    result[1] = U[0]
-            
-    return result
-    
-def numericalFlux(Uj,Ujp1,absA):
-
-    Fj   = Flux(Uj)
-    Fjp1 = Flux(Ujp1)
-            
-    return Fj+Fjp1 +absA*(Uj-Ujp1)
-        
-def computeFluxes(U, SumFluxes):
-    my_mesh =U.getMesh();
-    nbCells = my_mesh.getNumberOfCells();
-    dim=my_mesh.getMeshDimension();
-    nbComp=U.getNumberOfComponents();
-    Fj=cdmath.Vector(nbComp)
-    Fjp1=cdmath.Vector(nbComp)
-    Fjm1=cdmath.Vector(nbComp)
-    Uj=cdmath.Vector(nbComp)
-    Ujp1=cdmath.Vector(nbComp)
-    Ujm1=cdmath.Vector(nbComp)
-    normal=cdmath.Vector(dim)
-    sumFluxCourant=cdmath.Vector(nbComp)
-    sumFluxCourant2=cdmath.Vector(nbComp)
-
-    A, absA=jacobianMatrices()
-
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-
-        for i in range(nbComp) :
-            Uj[i]=U[j,i];
-            sumFluxCourant[i]=0;
-
-        if ( j==0) :
-            for i in range(nbComp) :
-                Ujp1[i]=U[j+1,i];
-                Ujm1[i]=U[j  ,i];
-        elif ( j==nbCells-1) :
-            for i in range(nbComp) :
-                Ujp1[i]=U[j  ,i];
-                Ujm1[i]=U[j-1,i];
-        else :
-            for i in range(nbComp) :
-                Ujp1[i]=U[j+1,i];
-                Ujm1[i]=U[j-1,i];
-            
-        Fr=numericalFlux(Uj,Ujp1,absA)
-        Fl=numericalFlux(Ujm1,Uj,absA)
-
-        sumFluxCourant = (Fr - Fl)*0.5*(1./Cj.getMeasure())
-            
-        #On divise par le volume de la cellule la contribution des flux au snd membre
-        for i in range(nbComp):
-            SumFluxes[j,i]=sumFluxCourant[i];
-
-
-def WaveSystem1DVF(ntmax, tmax, cfl, my_mesh, output_freq, resolution):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    
-    SumFluxes = cdmath.Field("Fluxes", cdmath.CELLS, my_mesh, dim+1)
-
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    U, pressure_field, velocity_field = initial_conditions_wave_system(my_mesh)
-
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-    
-    print("Starting computation of the linear wave system with an UPWIND explicit scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        computeFluxes(U,SumFluxes);
-        
-        SumFluxes*=dt;
-        maxVector=SumFluxes.normMax()
-        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision
-        U-=SumFluxes;
-    
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 )
-            print()
-
-            for k in range(nbCells):
-                pressure_field[k]=U[k,0]
-                velocity_field[k,0]=U[k,1]/rho0
-
-            pressure_field.setTime(time,it);
-            pressure_field.writeCSV("WaveSystem1DUpwind_pressure");
-            velocity_field.setTime(time,it);
-            velocity_field.writeCSV("WaveSystem1DUpwind_velocity");
-    
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "|| Un+1 - Un || : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 )
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
-        raise ValueError("Maximum number of time steps reached : Stationary state not found !!!!!!!")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time )
-        for k in range(nbCells):
-            pressure_field[k]=U[k,0]
-            velocity_field[k,0]=U[k,1]/rho0
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeCSV("WaveSystem1DUpwind_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeCSV("WaveSystem1DUpwind_velocity_Stat");
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint" )
-        raise ValueError("Maximum time reached : Stationary state not found !!!!!!!")
-
-
-def solve(my_mesh,resolution):
-    print("Resolution of the 1D Riemann problem for the Wave system with Upwind explicit scheme:")
-
-    # Problem data
-    tmax = 1.
-    ntmax = 100
-    cfl = 0.95
-    output_freq = 10
-
-    WaveSystem1DVF(ntmax, tmax, cfl, my_mesh, output_freq,resolution)
-
-if __name__ == """__main__""":
-
-    xinf=0
-    xsup=1
-    M=cdmath.Mesh(xinf,xsup,10)
-
-    solve(M,100)
diff --git a/CDMATH/tests/examples/WaveSystem1DUpwind_RiemannProblem/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem1DUpwind_RiemannProblem/CMakeLists.txt
deleted file mode 100755 (executable)
index 51c6c6b..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleWaveSystem_1DUpwind_RiemannProblem ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystem1DUpwind_RiemannProblem.py)
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem1DUpwind_RiemannProblem/WaveSystem1DUpwind_RiemannProblem.py b/CDMATH/tests/examples/WaveSystem1DUpwind_RiemannProblem/WaveSystem1DUpwind_RiemannProblem.py
deleted file mode 100755 (executable)
index ad3f8d6..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-import cdmath
-import numpy as np
-import matplotlib
-matplotlib.use("Agg")
-import matplotlib.pyplot as plt
-import matplotlib.animation as manimation
-import sys
-
-p0=155.e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_Riemann_problem(a,b,nx):
-    print( "Initial data Riemann problem" )
-
-    dx = (b - a) / nx #space step
-    x=[a+0.5*dx + i*dx for i in range(nx)]   # array of cell center (1D mesh)
-
-    u_initial = [ 0 ]*nx
-    p_initial = [ (xi<(a+b)/2)*p0 + (xi>=(a+b)/2)*p0/2  for xi in x]
-
-    return p_initial, u_initial
-
-def jacobianMatrices(coeff,scaling):
-    dim=1
-    A=cdmath.Matrix(dim+1,dim+1)
-    absA=cdmath.Matrix(dim+1,dim+1)
-
-    absA[0,0]=c0*coeff
-    for i in range(dim):
-        for j in range(dim):
-            absA[i+1,j+1]=c0*coeff
-        if( scaling==0):
-            A[0,i+1]=c0*c0*coeff
-            A[i+1,0]=      coeff
-        elif( scaling==1):
-            A[0,i+1]=      coeff
-            A[i+1,0]=      coeff
-        else:
-            A[0,i+1]=   c0*coeff
-            A[i+1,0]=   c0*coeff
-       
-    return A,absA
-    
-    
-def computeUpwindDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling):
-    nbCells = nx
-    dx=(b-a)/nx
-    dim=1
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    A,absA= jacobianMatrices(dt/dx,scaling)
-    for j in range(nbCells):#On parcourt les cellules
-        if ( j==0) :
-            implMat.addValue(j*nbComp,(j+1)*nbComp,(A-absA)*(1./2))
-            implMat.addValue(j*nbComp,    j*nbComp,(A-absA)*(-1./2))
-        elif ( j==nbCells-1) :
-            implMat.addValue(j*nbComp,    j*nbComp,(A+absA)*(1./2))
-            implMat.addValue(j*nbComp,(j-1)*nbComp,(A+absA)*(-1./2))
-        else :
-            implMat.addValue(j*nbComp,(j+1)*nbComp,(A-absA)*(1./2))
-            implMat.addValue(j*nbComp,    j*nbComp,(A-absA)*(-1./2))
-
-            implMat.addValue(j*nbComp,    j*nbComp,(A+absA)*(1./2))
-            implMat.addValue(j*nbComp,(j-1)*nbComp,(A+absA)*(-1./2))
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName,scaling):
-    dim=1
-    nbCells = nx
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False
-    
-    dx=(b-a)/nx
-    dt = cfl * dx / c0
-
-    nbVoisinsMax=2
-
-    #iteration vectors
-    Un =cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    Un_implicite =cdmath.Vector(nbCells*(dim+1))
-    dUn_implicite=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    pressure_field, velocity_field = initial_conditions_Riemann_problem(a,b,nx)
-    pressure_field_implicite, velocity_field_implicite = initial_conditions_Riemann_problem(a,b,nx)
-    max_initial_p=max(pressure_field)
-    min_initial_p=min(pressure_field)
-    max_initial_v=max(velocity_field)
-    min_initial_v=min(velocity_field)
-    
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =     pressure_field[k]
-        Un[k*(dim+1)+1] =rho0*velocity_field[k]
-        Un_implicite[k*(dim+1)+0] =     pressure_field_implicite[k]
-        Un_implicite[k*(dim+1)+1] =rho0*velocity_field_implicite[k]
-
-    # Video settings
-    FFMpegWriter = manimation.writers['ffmpeg']
-    metadata = dict(title="Finite volumes schemes for the 2D Wave System", artist = "CEA Saclay", comment="Shock propagation")
-    writer=FFMpegWriter(fps=10, metadata=metadata, codec='h264')
-    with writer.saving(plt.figure(), "2DWaveSystem_Upwind"+".mp4", ntmax):
-        #sauvegarde de la donnée initiale
-        plt.xlabel('x (m)')
-        plt.ylabel('Pressure -Pa)')
-        plt.xlim(a,b)
-        plt.ylim( min_initial_p - 0.1*(max_initial_p-min_initial_p), max_initial_p +  0.1*(max_initial_p-min_initial_p) )
-        plt.title("Riemann problem for Wave system on " + str(nx) + " cells")
-        line1, = plt.plot([a+0.5*dx + i*dx for i in range(nx)], pressure_field, label='Explicit upwind scheme') #new picture for video # Returns a tuple of line objects, thus the comma
-        line3, = plt.plot([a+0.5*dx + i*dx for i in range(nx)], pressure_field_implicite, label='Implicit upwind scheme') #new picture for video # Returns a tuple of line objects, thus the comma
-        plt.legend()
-        writer.grab_frame()
-        np.savetxt( "WaveSystem"+str(dim)+"DUpwindExplicit"+meshName+"_pressure"+"_0"+".txt", pressure_field, delimiter="\n")
-        np.savetxt( "WaveSystem"+str(dim)+"DUpwindExplicit"+meshName+"_velocity"+"_0"+".txt", velocity_field, delimiter="\n")
-        np.savetxt( "WaveSystem"+str(dim)+"DUpwindImplicit"+meshName+"_pressure"+"_0"+".txt", pressure_field_implicite, delimiter="\n")
-        np.savetxt( "WaveSystem"+str(dim)+"DUpwindImplicit"+meshName+"_velocity"+"_0"+".txt", velocity_field_implicite, delimiter="\n")
-        plt.savefig("WaveSystem"+str(dim)+"DUpwind"        +meshName+"_pressure"+"_0"+".png")
-        
-        divMat=computeUpwindDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling)
-        divMat_implicit=computeUpwindDivergenceMatrix(a,b,nx,nbVoisinsMax,dt,scaling)
-            
-        iterGMRESMax=50
-    
-        divMat_implicit.diagonalShift(1)#only after  filling all coefficients
-        if( scaling==0):
-            LS=cdmath.LinearSolver(divMat_implicit,Un,iterGMRESMax, precision, "GMRES","ILU")
-        else:
-            LS=cdmath.LinearSolver(divMat_implicit,Vn,iterGMRESMax, precision, "GMRES","ILU")
-    
-        print("Starting computation of the linear wave system with an upwind scheme …")
-        
-        # Starting time loop
-        while (it<ntmax and time <= tmax and not isStationary):
-            dUn=divMat*Un
-            Un-=dUn
-    
-            dUn_implicite=Un_implicite.deepCopy()
-            LS.setSndMember(Un_implicite)
-            Un_implicite=LS.solve();
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations" )
-                raise ValueError("Pas de convergence du système linéaire");
-            dUn_implicite-=Un_implicite
-    
-            for k in range(nbCells):
-                pressure_field[k] = Un[k*(dim+1)+0]
-                velocity_field[k] = Un[k*(dim+1)+1] / rho0
-                pressure_field_implicite[k] = Un_implicite[k*(dim+1)+0]
-                velocity_field_implicite[k] = Un_implicite[k*(dim+1)+1] / rho0
-    
-            line1.set_ydata(pressure_field)
-            line3.set_ydata(pressure_field_implicite)
-            writer.grab_frame()
-    
-            time=time+dt;
-            it=it+1;
-        
-            #Sauvegardes
-            if(it==1 or it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-                print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-                print( "Linear system converged in ", LS.getNumberOfIter(), " GMRES iterations" )
-    
-                np.savetxt("WaveSystem" +str(dim)+"DUpwindExplicit"+meshName+"_pressure"+str(it)+".txt", pressure_field          , delimiter="\n")
-                np.savetxt("WaveSystem" +str(dim)+"DUpwindExplicit"+meshName+"_velocity"+str(it)+".txt", velocity_field          , delimiter="\n")
-                np.savetxt("WaveSystem" +str(dim)+"DUpwindImplicit"+meshName+"_pressure"+str(it)+".txt", pressure_field          , delimiter="\n")
-                np.savetxt("WaveSystem" +str(dim)+"DUpwindImplicit"+meshName+"_velocity"+str(it)+".txt", velocity_field          , delimiter="\n")
-                plt.savefig("WaveSystem"+str(dim)+"DUpwind"        +meshName+"_pressure"+str(it)+".png")
-    
-                print()
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
-        return
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time )
-        print( "------------------------------------------------------------------------------------")
-
-        np.savetxt( "WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat.txt", pressure_field, delimiter="\n")
-        np.savetxt( "WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat.txt", velocity_field, delimiter="\n")
-        plt.savefig("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat.png")
-
-        return
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-        return
-
-
-def solve( a,b,nx, meshName, scaling, meshType, cfl):
-
-    print( "Resolution of the Wave system in dimension 1 on "+str(nx)+ " cells, upwind scheme")
-    print( "Initial data : ", "Riemann problem")
-    print( "Boundary conditions : ", "Neumann")
-    print( "Mesh name : ",meshName , ", ", nx, " cells")
-    
-    # Problem data
-    tmax = 10000.
-    ntmax = 50
-    output_freq = 1
-
-    WaveSystemVF(ntmax, tmax, cfl, a,b,nx, output_freq, meshName, scaling)
-    
-    return
-    
-
-if __name__ == """__main__""":
-    a=0.
-    b=1.
-    nx=100
-    cfl=0.99
-    scaling=0
-    solve( a,b,nx,"SquareRegularSquares",scaling,"RegularSquares",cfl)
diff --git a/CDMATH/tests/examples/WaveSystem2DUpwind_RiemannProblem/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem2DUpwind_RiemannProblem/CMakeLists.txt
deleted file mode 100755 (executable)
index fdc4fc0..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-
-SET(MESH_MED
-  ../../ressources/squareWithTriangles.med
-  ../../ressources/squareWithSquares.med
-  ../../ressources/squareWithBrickWall.med
-  ../../ressources/squareWithCheckerboardSquares.med
-  ../../ressources/squareWithDeformedQuadrangles.med
-  ../../ressources/squareWithHexagons.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemUpwind)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(IMPLICIT_SCHEME  0 )
-
-    SET(MESH_FILE  ../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithBrickWall.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_brickwall ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithCheckerboardSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithDeformedQuadrangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_deformedQuadrangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindExplicit_SQUARE_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(IMPLICIT_SCHEME  1 )
-
-    SET(MESH_FILE  ../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithBrickWall.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_brickwall ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithCheckerboardSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_checkerboard ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithDeformedQuadrangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_deformedQuadrangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../ressources/squareWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DRiemannProblem_UpwindImplicit_SQUARE_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem2DUpwind_RiemannProblem/WaveSystemUpwind.py b/CDMATH/tests/examples/WaveSystem2DUpwind_RiemannProblem/WaveSystemUpwind.py
deleted file mode 100755 (executable)
index 9d3abde..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Propagation d'une onde de choc droite
-#               Utilisation du schéma upwind explicite ou implicite sur un maillage général
-#               Initialisation par une discontinuité verticale
-#               Conditions aux limites de Neumann
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sin, cos, pi, sqrt
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_RiemannProblem(my_mesh):
-    print( "Initial data : Riemann problem" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    xcentre = 0
-
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-
-        velocity_field[i,0] = 0
-        velocity_field[i,1] = 0
-        velocity_field[i,2] = 0
-
-        if x < xcentre:
-            pressure_field[i] = p0
-            pass
-        else:
-            pressure_field[i] = p0/2
-            pass
-        pass
-
-    return pressure_field, velocity_field
-
-def jacobianMatrices(normal,coeff):
-    dim=normal.size()
-    A=cdmath.Matrix(dim+1,dim+1)
-    absA=cdmath.Matrix(dim+1,dim+1)
-
-    absA[0,0]=c0*coeff
-    for i in range(dim):
-        A[i+1,0]=      normal[i]*coeff
-        A[0,i+1]=c0*c0*normal[i]*coeff
-        for j in range(dim):
-            absA[i+1,j+1]=c0*normal[i]*normal[j]*coeff
-    
-    return (A - absA)*(1./2)
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-    
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure());
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    
-    SumFluxes = cdmath.Field("Fluxes", cdmath.CELLS, my_mesh, dim+1)
-
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    pressure_field, velocity_field = initial_conditions_RiemannProblem(my_mesh)
-
-    #iteration vectors
-    Un =cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =     pressure_field[k]
-        Un[k*(dim+1)+1] =rho0*velocity_field[k,0]
-        Un[k*(dim+1)+2] =rho0*velocity_field[k,1]
-        if(dim==3):
-            Un[k*(dim+1)+3] =rho0*velocity_field[k,2]
-
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity");
-
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-    
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
-    if( isImplicit):
-        #Adding the identity matrix on the diagonal
-        divMat.diagonalShift(1)#only after  filling all coefficients
-        
-        iterGMRESMax=50
-        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
-
-        LS.setComputeConditionNumber()
-        
-    print("Starting computation of the linear wave system with an explicit UPWIND scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        if(isImplicit):
-            dUn=Un.deepCopy()
-            LS.setSndMember(Un)
-            Un=LS.solve();
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations" )
-                raise ValueError("Pas de convergence du système linéaire");
-            dUn-=Un
-
-        else:
-            dUn=divMat*Un
-            Un-=dUn
-        
-        time=time+dt;
-        it=it+1;
-         #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-
-            for k in range(nbCells):
-                pressure_field[k]  =Un[k*(dim+1)+0]
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity",False);
-
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat");
-
-        #Postprocessing : Extraction of the diagonal data
-        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
-        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-
-
-def solve(my_mesh,filename,resolution, isImplicit):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
-    print( "Numerical method : upwind")
-    print( "Initial data : single straight discontinuity (Riemann problem)")
-    print( "Neumann boundary conditions")
-    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells")
-
-    # Problem data
-    tmax = 1.
-    ntmax = 50
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 1
-
-    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
-
-def solve_file( filename,resolution, isImplicit):
-    my_mesh = cdmath.Mesh(filename+".med")
-    solve(my_mesh, filename,resolution, isImplicit)
-    
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        filename=sys.argv[1]
-        isImplicit=bool(int(sys.argv[2]))
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100, isImplicit)
-    else :
-        raise ValueError("WaveSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemCentered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemCentered/CMakeLists.txt
deleted file mode 100755 (executable)
index 1a18ab0..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-SET(MESH_MED
-  ../../../ressources/squareWithTriangles.med
-  ../../../ressources/meshCube.med
-  ../../../ressources/squareWithSquares.med
-  ../../../ressources/cubeWithCubes.med
-  ../../../ressources/diskWithTriangles.med
-  ../../../ressources/diskWithSquares.med
-  ../../../ressources/diskWithSpiderWeb.med
-  ../../../ressources/diskWithHexagons.med
-  ../../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemCentered)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Centered_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Centered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_Centered_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_Centered_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Centered_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/meshHexagonWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Centered_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemCentered/WaveSystemCentered.py b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemCentered/WaveSystemCentered.py
deleted file mode 100755 (executable)
index 95fa24f..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Propagation d'une onde de choc sphérique
-#               Utilisation du schéma centré (implicite) sur un maillage général
-#               Initialisation par une surpression sphérique
-#               Conditions aux limites parois
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sqrt
-from numpy import sign
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_shock(my_mesh, isCircle):
-    print( "Initial data : Spherical wave" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    rayon = 0.15
-    if(not isCircle):
-        xcentre = 0.5
-        ycentre = 0.5
-        zcentre = 0.5
-    else:
-        xcentre = 0.
-        ycentre = 0.
-        zcentre = 0.
-
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        velocity_field[i,0] = 0
-        velocity_field[i,1] = 0
-        velocity_field[i,2] = 0
-
-        x = my_mesh.getCell(i).x()
-        valX = (x - xcentre) * (x - xcentre)
-
-        if(dim==1):
-            val =  sqrt(valX)
-        if(dim==2):
-            y = my_mesh.getCell(i).y()
-            valY = (y - ycentre) * (y - ycentre)
-            val =  sqrt(valX + valY)
-        if(dim==3):
-            y = my_mesh.getCell(i).y()
-            z = my_mesh.getCell(i).z()
-            valY = (y - ycentre) * (y - ycentre)
-            valZ = (z - zcentre) * (z - zcentre)
-            val =  sqrt(valX + valY + valZ)
-
-        if val < rayon:
-            pressure_field[i] = p0
-            pass
-        else:
-            pressure_field[i] = p0/2
-            pass
-        pass
-
-    return pressure_field, velocity_field
-
-def jacobianMatrices(normal, coeff, signun):
-    dim=normal.size()
-    A=cdmath.Matrix(dim+1,dim+1)
-
-    for i in range(dim):
-        A[i+1,0]=normal[i]*coeff
-        A[0,i+1]=c0*c0*normal[i]*coeff
-    
-    return A*(1./2)
-    
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-
-    v0=cdmath.Vector(dim)
-    for i in range(dim) :
-        v0[i] = 1.
-
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            signun=sign(normal*v0)
-            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
-                    v=cdmath.Vector(dim+1)
-                    for i in range(dim) :
-                        v[i+1]=normal[i]
-                    idMoinsJacCL=v.tensProduct(v)*2
-                    
-                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
-                    
-                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
-                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    iterGMRESMax=50
-    
-    #iteration vectors
-    Un=cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
-    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
-    else:
-        print( "Mesh name : ", filename )
-        raise ValueError("Mesh name should contain substring square, cube, Hexagon or disk")
-
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =      pressure_field[k]
-        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
-        if(dim>=2):
-            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
-            if(dim==3):
-                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
-            
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity");
-    #Postprocessing : save 2D picture
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_initial")
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_initial")
-    
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
-
-    # Add the identity matrix on the diagonal
-    for j in range(nbCells*(dim+1)):
-        divMat.addValue(j,j,1.)
-    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
-
-    print("Starting computation of the linear wave system with a centered scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        dUn=Un.deepCopy()
-        LS.setSndMember(Un)
-        Un=LS.solve();
-        cvgceLS=LS.getStatus();
-        iterGMRES=LS.getNumberOfIter();
-        if(not cvgceLS):
-            print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
-            raise ValueError("Pas de convergence du système linéaire");
-        dUn-=Un
-        
-        maxVector=dUn.maxVector(dim+1)
-        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
-        if(dim==3):
-            isStationary=isStationary and maxVector[3]/rho0<precision
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
-            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
-
-            for k in range(nbCells):
-                pressure_field[k]=Un[k*(dim+1)+0]
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-                
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity",False);
-
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint" )
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time )
-        print( "------------------------------------------------------------------------------------" )
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat");
-
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint" )
-
-
-def solve(my_mesh,meshName,resolution):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
-    print( "Numerical method : implicit centered")
-    print( "Initial data : spherical wave")
-    print( "Wall boundary conditions")
-    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells")
-    
-    # Problem data
-    tmax = 1000.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 1
-
-    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
-
-def solve_file( filename,meshName, resolution):
-    my_mesh = cdmath.Mesh(filename+".med")
-
-    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
-    
-
-if __name__ == """__main__""":
-    if len(sys.argv) >1 :
-        filename=sys.argv[1]
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100)
-    else :
-        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemPStag/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemPStag/CMakeLists.txt
deleted file mode 100755 (executable)
index 2f349fd..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-
-SET(MESH_MED
-  ../../../ressources/squareWithTriangles.med
-  ../../../ressources/meshCube.med
-  ../../../ressources/squareWithSquares.med
-  ../../../ressources/cubeWithCubes.med
-  ../../../ressources/diskWithTriangles.med
-  ../../../ressources/diskWithSquares.med
-  ../../../ressources/diskWithSpiderWeb.med
-  ../../../ressources/diskWithHexagons.med
-  ../../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemPStag)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_PStag_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_PStag_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_PStag_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_PStag_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_PStag_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/meshHexagonWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_PStag_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemPStag/WaveSystemPStag.py b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemPStag/WaveSystemPStag.py
deleted file mode 100755 (executable)
index 1130af8..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Propagation d'une onde de choc sphérique
-#               Utilisation du schéma MAC sur un maillage cartésien
-#               Initialisation par une surpression sphérique
-#               Conditions aux limites parois
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sqrt
-from numpy import sign
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_shock(my_mesh, isCircle):
-    print( "Initial data : Spherical wave" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    rayon = 0.15
-    if(not isCircle):
-        xcentre = 0.5
-        ycentre = 0.5
-        zcentre = 0.5
-    else:
-        xcentre = 0.
-        ycentre = 0.
-        zcentre = 0.
-
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        velocity_field[i,0] = 0
-        velocity_field[i,1] = 0
-        velocity_field[i,2] = 0
-
-        x = my_mesh.getCell(i).x()
-        valX = (x - xcentre) * (x - xcentre)
-
-        if(dim==1):
-            val =  sqrt(valX)
-        if(dim==2):
-            y = my_mesh.getCell(i).y()
-            valY = (y - ycentre) * (y - ycentre)
-            val =  sqrt(valX + valY)
-        if(dim==3):
-            y = my_mesh.getCell(i).y()
-            z = my_mesh.getCell(i).z()
-            valY = (y - ycentre) * (y - ycentre)
-            valZ = (z - zcentre) * (z - zcentre)
-            val =  sqrt(valX + valY + valZ)
-
-        if val < rayon:
-            pressure_field[i] = p0
-            pass
-        else:
-            pressure_field[i] = p0/2
-            pass
-        pass
-
-    return pressure_field, velocity_field
-
-def jacobianMatrices(normal, coeff, signun):
-    dim=normal.size()
-    A=cdmath.Matrix(dim+1,dim+1)
-    absA=cdmath.Matrix(dim+1,dim+1)
-
-    for i in range(dim):
-        A[i+1,0]=normal[i]*coeff
-        absA[i+1,0]=-signun*A[i+1,0]
-        A[0,i+1]=c0*c0*normal[i]*coeff
-        absA[0,i+1]=signun*A[0,i+1]
-    
-    return (A-absA)*(1./2)
-    
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-
-    v0=cdmath.Vector(dim)
-    for i in range(dim) :
-        v0[i] = 1.
-
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            signun=sign(normal*v0)
-            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
-                    v=cdmath.Vector(dim+1)
-                    for i in range(dim) :
-                        v[i+1]=normal[i]
-                    idMoinsJacCL=v.tensProduct(v)*2
-                    
-                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
-                    
-                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
-                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    iterGMRESMax=50
-    
-    #iteration vectors
-    Un=cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
-    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
-    else:
-        print( "Mesh name : ", filename )
-        raise ValueError("Mesh name should contain substring square, cube, Hexagon or disk")
-
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =      pressure_field[k]
-        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
-        if(dim>=2):
-            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
-            if(dim==3):
-                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
-            
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity");
-    #Postprocessing : save 2D picture
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_initial")
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_initial")
-    
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
-
-    # Add the identity matrix on the diagonal
-    for j in range(nbCells*(dim+1)):
-        divMat.addValue(j,j,1.)
-    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
-
-    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        dUn=Un.deepCopy()
-        LS.setSndMember(Un)
-        Un=LS.solve();
-        cvgceLS=LS.getStatus();
-        iterGMRES=LS.getNumberOfIter();
-        if(not cvgceLS):
-            print( "Linear system did not converge ", iterGMRES, " GMRES iterations" )
-            raise ValueError("Pas de convergence du système linéaire");
-        dUn-=Un
-        
-        maxVector=dUn.maxVector(dim+1)
-        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
-        if(dim==3):
-            isStationary=isStationary and maxVector[3]/rho0<precision
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
-            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
-
-            for k in range(nbCells):
-                pressure_field[k]=Un[k*(dim+1)+0]
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-                
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity",False);
-
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0)
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print( "------------------------------------------------------------------------------------")
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat");
-
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint" )
-
-
-def solve(my_mesh,meshName,resolution):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
-    print( "Numerical method : implicit pseudo staggered" )
-    print( "Initial data : spherical wave" )
-    print( "Wall boundary conditions" )
-    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
-    
-    # Problem data
-    tmax = 1000.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 1
-
-    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
-
-def solve_file( filename,meshName, resolution):
-    my_mesh = cdmath.Mesh(filename+".med")
-
-    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
-    
-
-if __name__ == """__main__""":
-    if len(sys.argv) >1 :
-        filename=sys.argv[1]
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100)
-    else :
-        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemStaggered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemStaggered/CMakeLists.txt
deleted file mode 100755 (executable)
index 5fc4636..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleWaveSystem_2DShock_Staggered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemStaggered.py )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemStaggered/WaveSystemStaggered.py b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemStaggered/WaveSystemStaggered.py
deleted file mode 100755 (executable)
index 752c378..0000000
+++ /dev/null
@@ -1,367 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Propagation d'une onde de choc sphérique
-#               Utilisation du schéma MAC sur un maillage cartésien
-#               Initialisation par une surpression sphérique
-#               Conditions aux limites périodiques
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sqrt
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_shock(my_mesh, isCircle):
-    print( "Initial data : Spherical wave")
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    rayon = 0.15
-    if(not isCircle):
-        xcentre = 0.5
-        ycentre = 0.5
-        zcentre = 0.5
-    else:
-        xcentre = 0.
-        ycentre = 0.
-        zcentre = 0.
-
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        velocity_field[i,0] = 0
-        velocity_field[i,1] = 0
-        velocity_field[i,2] = 0
-
-        x = my_mesh.getCell(i).x()
-        valX = (x - xcentre) * (x - xcentre)
-
-        if(dim==1):
-            val =  sqrt(valX)
-        if(dim==2):
-            y = my_mesh.getCell(i).y()
-            valY = (y - ycentre) * (y - ycentre)
-            val =  sqrt(valX + valY)
-        if(dim==3):
-            y = my_mesh.getCell(i).y()
-            z = my_mesh.getCell(i).z()
-            valY = (y - ycentre) * (y - ycentre)
-            valZ = (z - zcentre) * (z - zcentre)
-            val =  sqrt(valX + valY + valZ)
-
-        if val < rayon:
-            pressure_field[i] = p0
-            pass
-        else:
-            pressure_field[i] = p0/2
-            pass
-        pass
-
-    return pressure_field, velocity_field
-
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-
-    if(not my_mesh.isStructured()):
-        raise ValueError("WaveSystemStaggered: the mesh should be structured");
-
-    NxNyNz=my_mesh.getCellGridStructure()
-    DxDyDz=my_mesh.getDXYZ()
-    
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-    
-    if( dim == 1) :    
-        nx=NxNyNz[0]
-        dx=DxDyDz[0]
-            
-        if( scaling==0 ):
-            for k in range(nbCells):
-                implMat.addValue(k,1*nbCells +  k      , -c0*c0*dt/dx)
-                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*c0*dt/dx)
-    
-                implMat.addValue(  1*nbCells +  k      ,k,  dt/dx)
-                implMat.addValue(  1*nbCells + (k+1)%nx,k, -dt/dx)
-        else : # scaling >0    
-            for k in range(nbCells):
-                implMat.addValue(k,1*nbCells +  k      , -c0*dt/dx)
-                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*dt/dx)
-    
-                implMat.addValue(  1*nbCells +  k      ,k,  c0*dt/dx)
-                implMat.addValue(  1*nbCells + (k+1)%nx,k, -c0*dt/dx)
-    
-    elif( dim == 2) :# k = j*nx+i
-        nx=NxNyNz[0]
-        ny=NxNyNz[1]
-        dx=DxDyDz[0]
-        dy=DxDyDz[1]
-                
-        if( scaling==0 ):
-            for k in range(nbCells):
-                i = k % nx
-                j = k //nx
-    
-                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*c0*dt/dx)
-                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*c0*dt/dy)
-                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
-    
-                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  dt/dx)
-                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -dt/dx)
-    
-                implMat.addValue(  2*nbCells +   j       *nx + i,k,  dt/dy)
-                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -dt/dy)
-    
-        else :# scaling >0
-            for k in range(nbCells):
-                i = k % nx
-                j = k //nx
-    
-                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*dt/dx)
-                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*dt/dy)
-                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*dt/dy)
-    
-                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  c0*dt/dx)
-                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -c0*dt/dx)
-    
-                implMat.addValue(  2*nbCells +   j       *nx + i,k,  c0*dt/dy)
-                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
-    
-    elif( dim == 3) :# k = l*nx*ny+j*nx+i
-        nx=NxNyNz[0]
-        ny=NxNyNz[1]
-        nz=NxNyNz[2]
-        dx=DxDyDz[0]
-        dy=DxDyDz[1]
-        dz=DxDyDz[2]
-                
-        if( scaling==0 ):
-            for k in range(nbCells):
-                i =  k % nx
-                j = (k //nx)%ny 
-                l =  k //(nx*ny)
-                
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*c0*dt/dx)
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*c0*dt/dy)
-                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
-    
-                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*c0*dt/dz)
-                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*c0*dt/dz)
-    
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  dt/dx)
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -dt/dx)
-    
-                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  dt/dy)
-                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -dt/dy)
-    
-                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  dt/dz)
-                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -dt/dz)
-
-        else:# scaling >0
-            for k in range(nbCells):
-                i =  k % nx
-                j = (k //nx)%ny 
-                l =  k //(nx*ny)
-                
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*dt/dx)
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*dt/dy)
-                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*dt/dy)
-    
-                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*dt/dz)
-                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*dt/dz)
-    
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  c0*dt/dx)
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -c0*dt/dx)
-    
-                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  c0*dt/dy)
-                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
-    
-                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  c0*dt/dz)
-                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -c0*dt/dz)
-
-    return implMat
-
-def WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    
-    scaling=0
-    
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    iterGMRESMax=50
-    
-    #iteration vectors
-    Un=cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(dim==1 or meshName.find("square")>-1 or meshName.find("Square")>-1 or meshName.find("cube")>-1 or meshName.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
-    elif(meshName.find("disk")>-1 or meshName.find("Disk")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
-    else:
-        print( "Mesh name : ", meshName )
-        raise ValueError("Mesh name should contain substring square, cube or disk")
-
-    for k in range(nbCells):
-        Un[k + 0*nbCells] =      pressure_field[k]
-        Un[k + 1*nbCells] = rho0*velocity_field[k,0] # value on the left face
-        if(dim>=2):
-            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
-            if(dim==3):
-                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
-
-    if( scaling>0):
-        Vn = Un.deepCopy()
-        for k in range(nbCells):
-            Vn[k] = Vn[k]/c0
-            
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity");
-    #Postprocessing : save 2D picture
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_initial")
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_initial")
-    
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling)
-
-    #Add the identity matrix on the diagonal
-    for j in range(nbCells*(dim+1)):
-        divMat.addValue(j,j,1)
-
-    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
-
-    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        dUn=Un.deepCopy()
-        LS.setSndMember(Un)
-        Un=LS.solve();
-        cvgceLS=LS.getStatus();
-        iterGMRES=LS.getNumberOfIter();
-        if(not cvgceLS):
-            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
-            raise ValueError("Pas de convergence du système linéaire");
-        dUn-=Un
-        
-        max_dp=0 ;        max_dq=0
-        for k in range(nbCells):
-            max_dp = max(max_dp,abs(dUn[k]))
-            for i in range(dim):
-                max_dq=max(max_dq,abs(dUn[k+(1+i)*nbCells]))
-                
-        isStationary= max_dp/p0<precision and max_dq/rho0<precision
-
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-            print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0 )
-            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
-
-            for k in range(nbCells):
-                pressure_field[k]=Un[k]
-                velocity_field[k,0]=Un[k+1*nbCells]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k+2*nbCells]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k+3*nbCells]/rho0
-                
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity",False);
-
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0 )
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print( "------------------------------------------------------------------------------------")
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat");
-
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-
-
-def solve(my_mesh,meshName,resolution):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
-    print( "Numerical method : staggered scheme" )
-    print( "Initial data : Spherical wave" )
-    print( "Periodic boundary conditions" )
-    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
-    
-    # Problem data
-    tmax = 1000.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 1
-
-    WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
-
-def solve_file( filename,meshName, resolution):
-    my_mesh = cdmath.Mesh(filename+".med")
-
-    return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution)
-    
-
-if __name__ == """__main__""":
-    if len(sys.argv) >1 :
-        my_mesh = cdmath.Mesh(sys.argv[1])
-        solve(my_mesh,my_mesh.getName(),100)
-    else :
-        nx=50
-        my_mesh = cdmath.Mesh(0,1,nx,0,1,nx)
-        solve(my_mesh,"square",100)
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemUpwind/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemUpwind/CMakeLists.txt
deleted file mode 100755 (executable)
index 5b36455..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-
-SET(MESH_MED
-  ../../../ressources/squareWithTriangles.med
-  ../../../ressources/meshCube.med
-  ../../../ressources/squareWithSquares.med
-  ../../../ressources/cubeWithCubes.med
-  ../../../ressources/diskWithTriangles.med
-  ../../../ressources/diskWithSquares.med
-  ../../../ressources/diskWithSpiderWeb.med
-  ../../../ressources/diskWithHexagons.med
-  ../../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemUpwind)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(IMPLICIT_SCHEME  0 )
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_UpwindExplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_UpwindExplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshHexagonWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindExplicit_HEXAGON_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(IMPLICIT_SCHEME  1 )
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_UpwindImplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DShock_UpwindImplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DShock_UpwindImplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemUpwind/WaveSystemUpwind.py b/CDMATH/tests/examples/WaveSystem_Shock/WaveSystemUpwind/WaveSystemUpwind.py
deleted file mode 100755 (executable)
index 10b55c9..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Propagation d'une onde de choc sphérique
-#               Utilisation du schéma upwind explicite ou implicite sur un maillage général
-#               Initialisation par une surpression sphérique
-#               Conditions aux limites parois
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sqrt
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_shock(my_mesh, isCircle):
-    print( "Initial data : Spherical wave" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    rayon = 0.15
-    if(not isCircle):#Case of a square domain
-        xcentre = 0.5
-        ycentre = 0.5
-        zcentre = 0.5
-    else:#Case of a disk or a hexagonal domain
-        xcentre = 0.
-        ycentre = 0.
-        zcentre = 0.
-
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        velocity_field[i,0] = 0
-        velocity_field[i,1] = 0
-        velocity_field[i,2] = 0
-
-        x = my_mesh.getCell(i).x()
-        valX = (x - xcentre) * (x - xcentre)
-
-        if(dim==1):
-            val =  sqrt(valX)
-        if(dim==2):
-            y = my_mesh.getCell(i).y()
-            valY = (y - ycentre) * (y - ycentre)
-            val =  sqrt(valX + valY)
-        if(dim==3):
-            y = my_mesh.getCell(i).y()
-            z = my_mesh.getCell(i).z()
-            valY = (y - ycentre) * (y - ycentre)
-            valZ = (z - zcentre) * (z - zcentre)
-            val =  sqrt(valX + valY + valZ)
-
-        if val < rayon:
-            pressure_field[i] = p0
-            pass
-        else:
-            pressure_field[i] = p0/2
-            pass
-        pass
-
-    return pressure_field, velocity_field
-
-def jacobianMatrices(normal,coeff):
-    dim=normal.size()
-    A=cdmath.Matrix(dim+1,dim+1)
-    absA=cdmath.Matrix(dim+1,dim+1)
-
-    absA[0,0]=c0*coeff
-    for i in range(dim):
-        A[i+1,0]=      normal[i]*coeff
-        A[0,i+1]=c0*c0*normal[i]*coeff
-        for j in range(dim):
-            absA[i+1,j+1]=c0*normal[i]*normal[j]*coeff
-    
-    return (A - absA)*(1./2)
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-    
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure());
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
-                    v=cdmath.Vector(dim+1)
-                    for i in range(dim) :
-                        v[i+1]=normal[i]
-                    idMoinsJacCL=v.tensProduct(v)*2
-                    
-                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
-                    
-                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
-                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(dim==1 or filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,False)
-    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
-        pressure_field, velocity_field = initial_conditions_shock(my_mesh,True)
-    else:
-        print( "Mesh name : ", filename )
-        raise ValueError("Mesh name should contain substring square, cube, hexagon or disk")
-
-    #iteration vectors
-    Un =cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =     pressure_field[k]
-        Un[k*(dim+1)+1] =rho0*velocity_field[k,0]
-        if(dim>=2):
-            Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
-            if(dim==3):
-                Un[k + 3*nbCells] = rho0*velocity_field[k,2]
-
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity");
-
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-    
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
-    if( isImplicit):
-        #Adding the identity matrix on the diagonal
-        divMat.diagonalShift(1)#only after  filling all coefficients
-        
-        iterGMRESMax=50
-        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
-
-        LS.setComputeConditionNumber()
-        
-    print("Starting computation of the linear wave system with an explicit UPWIND scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        if(isImplicit):
-            dUn=Un.deepCopy()
-            LS.setSndMember(Un)
-            Un=LS.solve();
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations" )
-                raise ValueError("Pas de convergence du système linéaire");
-            dUn-=Un
-
-        else:
-            dUn=divMat*Un
-            Un-=dUn
-        
-        time=time+dt;
-        it=it+1;
-         #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-
-            for k in range(nbCells):
-                pressure_field[k]  =Un[k*(dim+1)+0]
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity",False);
-
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat");
-
-        #Postprocessing : Extraction of the diagonal data
-        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
-        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+"_isImplicit"+str(isImplicit)+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-
-
-def solve(my_mesh,filename,resolution, isImplicit):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
-    print( "Numerical method : upwind" )
-    print( "Initial data : spherical wave" )
-    print( "Wall boundary conditions" )
-    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells" )
-
-    # Problem data
-    tmax = 1.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 1
-
-    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
-
-def solve_file( filename,resolution, isImplicit):
-    my_mesh = cdmath.Mesh(filename+".med")
-    solve(my_mesh, filename,resolution, isImplicit)
-    
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        filename=sys.argv[1]
-        isImplicit=bool(int(sys.argv[2]))
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100, isImplicit)
-    else :
-        raise ValueError("WaveSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemCentered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemCentered/CMakeLists.txt
deleted file mode 100755 (executable)
index d54c556..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-
-SET(MESH_MED
-  ../../../ressources/squareWithTriangles.med
-  ../../../ressources/meshCube.med
-  ../../../ressources/squareWithSquares.med
-  ../../../ressources/cubeWithCubes.med
-  ../../../ressources/diskWithTriangles.med
-  ../../../ressources/diskWithSquares.med
-  ../../../ressources/diskWithSpiderWeb.med
-  ../../../ressources/diskWithHexagons.med
-  ../../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemCentered)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_Centered_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_Centered_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_Centered_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemCentered.py  ${MESH_FILE})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemCentered/WaveSystemCentered.py b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemCentered/WaveSystemCentered.py
deleted file mode 100755 (executable)
index c6c6fa8..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Test de préservation d'un état stationnaire
-#               Utilisation du schéma centré (implicite) sur un maillage général
-#               Initialisation par un vortex stationnaire
-#               Conditions aux limites parois
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sin, cos, pi, sqrt
-from numpy import sign
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_disk_vortex(my_mesh):
-    print( "Disk vortex initial data")
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    if(dim!=2):
-        raise ValueError("Wave system on disk : mesh dimension should be 2")
-        
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-        y = my_mesh.getCell(i).y()
-
-        pressure_field[i] = p0
-
-        velocity_field[i,0] = -y
-        velocity_field[i,1] =  x
-        velocity_field[i,2] = 0
-
-    return pressure_field, velocity_field
-
-def initial_conditions_square_vortex(my_mesh):
-    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)")
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-        y = my_mesh.getCell(i).y()
-        z = my_mesh.getCell(i).z()
-
-        pressure_field[i] = p0
-        if(dim==1):
-            velocity_field[i,0] = 1
-            velocity_field[i,1] = 0
-            velocity_field[i,2] = 0
-        elif(dim==2):
-            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
-            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
-            velocity_field[i,2] = 0
-        elif(dim==3):
-            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
-            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
-            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
-        
-    return pressure_field, velocity_field
-
-def jacobianMatrices(normal, coeff, signun):
-    dim=normal.size()
-    A=cdmath.Matrix(dim+1,dim+1)
-
-    for i in range(dim):
-        A[i+1,0]=normal[i]*coeff
-        A[0,i+1]=c0*c0*normal[i]*coeff
-    
-    return A*(1./2)
-    
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-
-    v0=cdmath.Vector(dim)
-    for i in range(dim) :
-        v0[i] = 1.
-
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            signun=sign(normal*v0)
-            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
-                    v=cdmath.Vector(dim+1)
-                    for i in range(dim) :
-                        v[i+1]=normal[i]
-                    idMoinsJacCL=v.tensProduct(v)*2
-                    
-                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
-                    
-                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
-                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    iterGMRESMax=50
-    
-    #iteration vectors
-    Un=cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
-    elif(filename.find("disk")>-1 or filename.find("Disk")>-1 or filename.find("Hexagon")>-1):
-        pressure_field, velocity_field = initial_conditions_disk_vortex(my_mesh)
-    else:
-        print( "Mesh name : ", filename)
-        raise ValueError("Mesh name should contain substring square, cube, Hexagon or disk")
-
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =      pressure_field[k]
-        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
-        Un[k*(dim+1)+2] = rho0*velocity_field[k,1]
-        if(dim==3):
-            Un[k*(dim+1)+3] = rho0*velocity_field[k,2]
-            
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity");
-    #Postprocessing : save 2D picture
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_initial")
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_initial")
-    
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
-
-    # Add the identity matrix on the diagonal
-    for j in range(nbCells*(dim+1)):
-        divMat.addValue(j,j,1.)
-    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
-
-    print("Starting computation of the linear wave system with a centered scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        dUn=Un.deepCopy()
-        LS.setSndMember(Un)
-        Un=LS.solve();
-        cvgceLS=LS.getStatus();
-        iterGMRES=LS.getNumberOfIter();
-        if(not cvgceLS):
-            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
-            raise ValueError("Pas de convergence du système linéaire");
-        dUn-=Un
-        
-        maxVector=dUn.maxVector(dim+1)
-        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
-        if(dim==3):
-            isStationary=isStationary and maxVector[3]/rho0<precision
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
-            print( "Linear system converged in ", iterGMRES, " GMRES iterations")
-
-            for k in range(nbCells):
-                pressure_field[k]=Un[k*(dim+1)+0]
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-                
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity",False);
-
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print( "------------------------------------------------------------------------------------")
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat");
-
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DCentered"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-
-
-def solve(my_mesh,meshName,resolution):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension() )
-    print( "Numerical method : implicit centered" )
-    print( "Initial data : stationary solution (constant pressure, divergence free velocity)" )
-    print( "Wall boundary conditions" )
-    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
-    
-    # Problem data
-    tmax = 1000.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 100
-
-    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
-
-def solve_file( filename,meshName, resolution):
-    my_mesh = cdmath.Mesh(filename+".med")
-
-    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
-    
-
-if __name__ == """__main__""":
-    if len(sys.argv) >1 :
-        filename=sys.argv[1]
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100)
-    else :
-        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemPStag/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemPStag/CMakeLists.txt
deleted file mode 100755 (executable)
index 3aa9d62..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-
-SET(MESH_MED
-  ../../../ressources/squareWithTriangles.med
-  ../../../ressources/meshCube.med
-  ../../../ressources/squareWithSquares.med
-  ../../../ressources/cubeWithCubes.med
-  ../../../ressources/diskWithTriangles.med
-  ../../../ressources/diskWithSquares.med
-  ../../../ressources/diskWithSpiderWeb.med
-  ../../../ressources/diskWithHexagons.med
-  ../../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemPStag)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_PStag_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_PStag_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_PStag_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemPStag.py  ${MESH_FILE})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemPStag/WaveSystemPStag.py b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemPStag/WaveSystemPStag.py
deleted file mode 100755 (executable)
index f73e2b4..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Test de préservation d'un état stationnaire
-#               Utilisation du schéma pseudo décalé (implicite) sur un maillage général
-#               Initialisation par un vortex stationnaire
-#               Conditions aux limites parois
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sin, cos, pi, sqrt
-from numpy import sign
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_disk_vortex(my_mesh):
-    print( "Disk vortex initial data" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    if(dim!=2):
-        raise ValueError("Wave system on disk : mesh dimension should be 2")
-        
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-        y = my_mesh.getCell(i).y()
-
-        pressure_field[i] = p0
-
-        velocity_field[i,0] = -y
-        velocity_field[i,1] =  x
-        velocity_field[i,2] = 0
-
-    return pressure_field, velocity_field
-
-def initial_conditions_square_vortex(my_mesh):
-    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-        y = my_mesh.getCell(i).y()
-        z = my_mesh.getCell(i).z()
-
-        pressure_field[i] = p0
-        if(dim==1):
-            velocity_field[i,0] = 1
-            velocity_field[i,1] = 0
-            velocity_field[i,2] = 0
-        elif(dim==2):
-            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
-            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
-            velocity_field[i,2] = 0
-        elif(dim==3):
-            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
-            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
-            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
-        
-    return pressure_field, velocity_field
-
-def jacobianMatrices(normal, coeff, signun):
-    dim=normal.size()
-    A=cdmath.Matrix(dim+1,dim+1)
-    absA=cdmath.Matrix(dim+1,dim+1)
-
-    for i in range(dim):
-        A[i+1,0]=normal[i]*coeff
-        absA[i+1,0]=-signun*A[i+1,0]
-        A[0,i+1]=c0*c0*normal[i]*coeff
-        absA[0,i+1]=signun*A[0,i+1]
-    
-    return (A-absA)*(1./2)
-    
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-
-    v0=cdmath.Vector(dim)
-    for i in range(dim) :
-        v0[i] = 1.
-
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            signun=sign(normal*v0)
-            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure(),signun);
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cel number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
-                    v=cdmath.Vector(dim+1)
-                    for i in range(dim) :
-                        v[i+1]=normal[i]
-                    idMoinsJacCL=v.tensProduct(v)*2
-                    
-                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
-                    
-                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
-                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    iterGMRESMax=50
-    
-    #iteration vectors
-    Un=cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
-    elif(filename.find("disk")>-1 or filename.find("Disk")>-1):
-        pressure_field, velocity_field = initial_conditions_disk_vortex(my_mesh)
-    else:
-        print( "Mesh name : ", filename)
-        raise ValueError("Mesh name should contain substring square, cube or disk")
-
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =      pressure_field[k]
-        Un[k*(dim+1)+1] = rho0*velocity_field[k,0]
-        Un[k*(dim+1)+2] = rho0*velocity_field[k,1]
-        if(dim==3):
-            Un[k*(dim+1)+3] = rho0*velocity_field[k,2]
-            
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity");
-    #Postprocessing : save 2D picture
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_initial")
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_initial")
-    
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
-
-    # Add the identity matrix on the diagonal
-    for j in range(nbCells*(dim+1)):
-        divMat.addValue(j,j,1.)
-    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
-
-    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        dUn=Un.deepCopy()
-        LS.setSndMember(Un)
-        Un=LS.solve();
-        cvgceLS=LS.getStatus();
-        iterGMRES=LS.getNumberOfIter();
-        if(not cvgceLS):
-            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
-            raise ValueError("Pas de convergence du système linéaire");
-        dUn-=Un
-        
-        maxVector=dUn.maxVector(dim+1)
-        isStationary= maxVector[0]/p0<precision and maxVector[1]/rho0<precision and maxVector[2]/rho0<precision;
-        if(dim==3):
-            isStationary=isStationary and maxVector[3]/rho0<precision
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-            print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
-            print( "Linear system converged in ", iterGMRES, " GMRES iterations" )
-
-            for k in range(nbCells):
-                pressure_field[k]=Un[k*(dim+1)+0]
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-                
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity",False);
-
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "Variation temporelle relative : pressure ", maxVector[0]/p0 ,", velocity x", maxVector[1]/rho0 ,", velocity y", maxVector[2]/rho0 )
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print( "------------------------------------------------------------------------------------")
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat");
-
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DPStag"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-
-
-def solve(my_mesh,meshName,resolution):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension())
-    print( "Numerical method : implicit pseudo staggered")
-    print( "Initial data : stationary solution (constant pressure, divergence free velocity)")
-    print( "Wall boundary conditions")
-    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells" )
-    
-    # Problem data
-    tmax = 1000.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 100
-
-    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
-
-def solve_file( filename,meshName, resolution):
-    my_mesh = cdmath.Mesh(filename+".med")
-
-    return solve(my_mesh, filename+str(my_mesh.getNumberOfCells()),resolution)
-    
-
-if __name__ == """__main__""":
-    if len(sys.argv) >1 :
-        filename=sys.argv[1]
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100)
-    else :
-        raise ValueError("WaveSystemUpwind.py expects a mesh file name")
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemStaggered/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemStaggered/CMakeLists.txt
deleted file mode 100755 (executable)
index c30f344..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_Staggered_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemStaggered.py )
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemStaggered/WaveSystemStaggered.py b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemStaggered/WaveSystemStaggered.py
deleted file mode 100755 (executable)
index 092ab28..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Test de préservation d'un état stationnaire
-#               Utilisation du schéma MAC sur un maillage cartésien
-#               Initialisation par un vortex stationnaire
-#               Conditions aux limites périodiques
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sin, cos, pi, sqrt
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_square_vortex(my_mesh):
-    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-        y = my_mesh.getCell(i).y()
-        z = my_mesh.getCell(i).z()
-
-        pressure_field[i] = p0
-        if(dim==1):
-            velocity_field[i,0] = 1
-            velocity_field[i,1] = 0
-            velocity_field[i,2] = 0
-        elif(dim==2):
-            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
-            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
-            velocity_field[i,2] = 0
-        elif(dim==3):
-            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
-            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
-            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
-        
-    return pressure_field, velocity_field
-
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-
-    if(not my_mesh.isStructured()):
-        raise ValueError("WaveSystemStaggered: the mesh should be structured");
-
-    NxNyNz=my_mesh.getCellGridStructure()
-    DxDyDz=my_mesh.getDXYZ()
-    
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-    
-    if( dim == 1) :    
-        nx=NxNyNz[0]
-        dx=DxDyDz[0]
-            
-        if( scaling==0 ):
-            for k in range(nbCells):
-                implMat.addValue(k,1*nbCells +  k      , -c0*c0*dt/dx)
-                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*c0*dt/dx)
-    
-                implMat.addValue(  1*nbCells +  k      ,k,  dt/dx)
-                implMat.addValue(  1*nbCells + (k+1)%nx,k, -dt/dx)
-        else : # scaling >0    
-            for k in range(nbCells):
-                implMat.addValue(k,1*nbCells +  k      , -c0*dt/dx)
-                implMat.addValue(k,1*nbCells + (k+1)%nx,  c0*dt/dx)
-    
-                implMat.addValue(  1*nbCells +  k      ,k,  c0*dt/dx)
-                implMat.addValue(  1*nbCells + (k+1)%nx,k, -c0*dt/dx)
-    
-    elif( dim == 2) :# k = j*nx+i
-        nx=NxNyNz[0]
-        ny=NxNyNz[1]
-        dx=DxDyDz[0]
-        dy=DxDyDz[1]
-                
-        if( scaling==0 ):
-            for k in range(nbCells):
-                i = k % nx
-                j = k //nx
-    
-                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*c0*dt/dx)
-                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*c0*dt/dy)
-                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
-    
-                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  dt/dx)
-                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -dt/dx)
-    
-                implMat.addValue(  2*nbCells +   j       *nx + i,k,  dt/dy)
-                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -dt/dy)
-    
-        else :# scaling >0
-            for k in range(nbCells):
-                i = k % nx
-                j = k //nx
-    
-                implMat.addValue(k,1*nbCells + j*nx +  i      ,   -c0*dt/dx)
-                implMat.addValue(k,1*nbCells + j*nx + (i+1)%nx,    c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells +   j       *nx + i, -c0*dt/dy)
-                implMat.addValue(k,2*nbCells + ((j+1)%ny)*nx + i,  c0*dt/dy)
-    
-                implMat.addValue(  1*nbCells + j*nx +  i      ,  k,  c0*dt/dx)
-                implMat.addValue(  1*nbCells + j*nx + (i+1)%nx,  k, -c0*dt/dx)
-    
-                implMat.addValue(  2*nbCells +   j       *nx + i,k,  c0*dt/dy)
-                implMat.addValue(  2*nbCells + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
-    
-    elif( dim == 3) :# k = l*nx*ny+j*nx+i
-        nx=NxNyNz[0]
-        ny=NxNyNz[1]
-        nz=NxNyNz[2]
-        dx=DxDyDz[0]
-        dy=DxDyDz[1]
-        dz=DxDyDz[2]
-                
-        if( scaling==0 ):
-            for k in range(nbCells):
-                i =  k % nx
-                j = (k //nx)%ny 
-                l =  k //(nx*ny)
-                
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*c0*dt/dx)
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*c0*dt/dy)
-                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*c0*dt/dy)
-    
-                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*c0*dt/dz)
-                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*c0*dt/dz)
-    
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  dt/dx)
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -dt/dx)
-    
-                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  dt/dy)
-                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -dt/dy)
-    
-                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  dt/dz)
-                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -dt/dz)
-
-        else:# scaling >0
-            for k in range(nbCells):
-                i =  k % nx
-                j = (k //nx)%ny 
-                l =  k //(nx*ny)
-                
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx +  i      ,  -c0*dt/dx)
-                implMat.addValue(k,1*nbCells + l*nx*ny + j*nx + (i+1)%nx,   c0*dt/dx)
-    
-                implMat.addValue(k,2*nbCells + l*nx*ny +   j       *nx + i, -c0*dt/dy)
-                implMat.addValue(k,2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,  c0*dt/dy)
-    
-                implMat.addValue(k,3*nbCells +   l*nx*ny        + j*nx + i, -c0*dt/dz)
-                implMat.addValue(k,3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,  c0*dt/dz)
-    
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx +  i      ,  k,  c0*dt/dx)
-                implMat.addValue(  1*nbCells + l*nx*ny + j*nx + (i+1)%nx,  k, -c0*dt/dx)
-    
-                implMat.addValue(  2*nbCells + l*nx*ny +   j       *nx + i,k,  c0*dt/dy)
-                implMat.addValue(  2*nbCells + l*nx*ny + ((j+1)%ny)*nx + i,k, -c0*dt/dy)
-    
-                implMat.addValue(  3*nbCells +   l*nx*ny        + j*nx + i,k,  c0*dt/dz)
-                implMat.addValue(  3*nbCells + ((l+1)%nz)*nx*ny + j*nx + i,k, -c0*dt/dz)
-
-    return implMat
-
-def WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    
-    scaling=0
-    
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-    iterGMRESMax=50
-    
-    #iteration vectors
-    Un=cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
-
-    for k in range(nbCells):
-        Un[k + 0*nbCells] =      pressure_field[k]
-        Un[k + 1*nbCells] = rho0*velocity_field[k,0] # value on the left face
-        Un[k + 2*nbCells] = rho0*velocity_field[k,1] # value on the bottom face
-        if(dim==3):
-            Un[k + 3*nbCells] = rho0*initial_velocity[k,2]
-    if( scaling>0):
-        Vn = Un.deepCopy()
-        for k in range(nbCells):
-            Vn[k] = Vn[k]/c0
-            
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity");
-    #Postprocessing : save 2D picture
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_initial")
-    PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_initial")
-    
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt,scaling)
-
-    #Add the identity matrix on the diagonal
-    for j in range(nbCells*(dim+1)):
-        divMat.addValue(j,j,1)
-
-    LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","LU")
-
-    print("Starting computation of the linear wave system with an pseudo staggered scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        dUn=Un.deepCopy()
-        LS.setSndMember(Un)
-        Un=LS.solve();
-        cvgceLS=LS.getStatus();
-        iterGMRES=LS.getNumberOfIter();
-        if(not cvgceLS):
-            print( "Linear system did not converge ", iterGMRES, " GMRES iterations")
-            raise ValueError("Pas de convergence du système linéaire");
-        dUn-=Un
-        
-        max_dp=0 ;        max_dq=0
-        for k in range(nbCells):
-            max_dp = max(max_dp,abs(dUn[k]))
-            for i in range(dim):
-                max_dq=max(max_dq,abs(dUn[k+(1+i)*nbCells]))
-                
-        isStationary= max_dp/p0<precision and max_dq/rho0<precision
-
-        time=time+dt;
-        it=it+1;
-    
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-            print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0)
-            print( "Linear system converged in ", iterGMRES, " GMRES iterations")
-
-            for k in range(nbCells):
-                pressure_field[k]=Un[k]
-                velocity_field[k,0]=Un[k+1*nbCells]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k+2*nbCells]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k+3*nbCells]/rho0
-                
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity",False);
-
-    print( "-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt) )
-    print( "Variation temporelle relative : pressure ", max_dp/p0 ,", velocity ", max_dq/rho0 )
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-        print( "------------------------------------------------------------------------------------")
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat");
-
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DStaggered"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint" )
-
-
-def solve(my_mesh,meshName,resolution):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension())
-    print( "Numerical method : staggered scheme")
-    print( "Initial data : stationary solution (constant pressure, divergence free velocity)")
-    print( "Periodic boundary conditions")
-    print( "Mesh name : ",meshName , my_mesh.getNumberOfCells(), " cells")
-    
-    # Problem data
-    tmax = 1000.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 100
-
-    WaveSystemStaggered(ntmax, tmax, cfl, my_mesh, output_freq, meshName, resolution)
-
-def solve_file( filename,meshName, resolution):
-    my_mesh = cdmath.Mesh(filename+".med")
-
-    return solve(my_mesh, meshName+str(my_mesh.getNumberOfCells()),resolution)
-    
-
-if __name__ == """__main__""":
-    if len(sys.argv) >1 :
-        my_mesh = cdmath.Mesh(sys.argv[1])
-        solve(my_mesh,my_mesh.getName(),100)
-    else :
-        nx=50
-        my_mesh = cdmath.Mesh(0,1,nx,0,1,nx)
-        solve(my_mesh,my_mesh.getName(),100)
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemUpwind/CMakeLists.txt b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemUpwind/CMakeLists.txt
deleted file mode 100755 (executable)
index 376bb9d..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-
-SET(MESH_MED
-  ../../../ressources/squareWithTriangles.med
-  ../../../ressources/meshCube.med
-  ../../../ressources/squareWithSquares.med
-  ../../../ressources/cubeWithCubes.med
-  ../../../ressources/diskWithTriangles.med
-  ../../../ressources/diskWithSquares.med
-  ../../../ressources/diskWithSpiderWeb.med
-  ../../../ressources/diskWithHexagons.med
-  ../../../ressources/ballWithTetrahedra.med
-  )
-
-file(COPY ${MESH_MED} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
-install(FILES ${MESH_MED} DESTINATION share/examples/WaveSystemUpwind)
-
-if (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-    SET(IMPLICIT_SCHEME  0 )
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindExplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindExplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindExplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(IMPLICIT_SCHEME  0 )
-
-    SET(MESH_FILE  ../../../ressources/meshSquare.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_SQUARE_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/squareWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_SQUARE_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/meshCube.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindImplicit_CUBE_tetrahedra ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/cubeWithCubes.med  )
-
-    ADD_TEST(ExampleWaveSystem_3DVortex_UpwindImplicit_CUBE_cubes ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithTriangles.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_triangles ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSquares.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_squares ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithSpiderWeb.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_spiderWeb ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-    SET(MESH_FILE  ../../../ressources/diskWithHexagons.med  )
-
-    ADD_TEST(ExampleWaveSystem_2DVortex_UpwindImplicit_DISK_hexagons ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/WaveSystemUpwind.py  ${MESH_FILE} ${IMPLICIT_SCHEME})
-
-endif (CDMATH_WITH_PYTHON AND CDMATH_WITH_PETSC AND CDMATH_WITH_POSTPRO)
-
-
diff --git a/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemUpwind/WaveSystemUpwind.py b/CDMATH/tests/examples/WaveSystem_Stationary/WaveSystemUpwind/WaveSystemUpwind.py
deleted file mode 100755 (executable)
index bb190e0..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-#!/usr/bin/env python3
-# -*-coding:utf-8 -*
-
-#===============================================================================================================================
-# Name        : Résolution VF du système des ondes 2D sans terme source
-#                \partial_t p + c^2 \div q = 0
-#                \partial_t q +    \grad p = 0
-# Author      : Michaël Ndjinga
-# Copyright   : CEA Saclay 2019
-# Description : Test de préservation d'un état stationnaire
-#               Utilisation du schéma upwind explicite ou implicite sur un maillage général
-#               Initialisation par une vortex stationnaire
-#               Conditions aux limites parois
-#                      Création et sauvegarde du champ résultant et des figures
-#================================================================================================================================
-
-
-from math import sin, cos, pi, sqrt
-import cdmath
-import PV_routines
-import VTK_routines
-import sys
-
-p0=155e5#reference pressure in a pressurised nuclear vessel
-c0=700.#reference sound speed for water at 155 bars, 600K
-rho0=p0/c0*c0#reference density
-precision=1e-5
-
-def initial_conditions_disk_vortex(my_mesh):
-    print( "Disk vortex initial data")
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    if(dim!=2):
-        raise ValueError("Wave system on disk : mesh dimension should be 2")
-        
-    pressure_field = cdmath.Field("Pressure",            cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity",            cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-        y = my_mesh.getCell(i).y()
-
-        pressure_field[i] = p0
-
-        velocity_field[i,0] = -y
-        velocity_field[i,1] =  x
-        velocity_field[i,2] = 0
-
-    return pressure_field, velocity_field
-
-def initial_conditions_square_vortex(my_mesh):
-    print( "Initial data : Square vortex (Constant pressure, divergence free velocity)" )
-    dim     = my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-
-    pressure_field = cdmath.Field("Pressure", cdmath.CELLS, my_mesh, 1)
-    velocity_field = cdmath.Field("Velocity", cdmath.CELLS, my_mesh, 3)
-
-    for i in range(nbCells):
-        x = my_mesh.getCell(i).x()
-        y = my_mesh.getCell(i).y()
-        z = my_mesh.getCell(i).z()
-
-        pressure_field[i] = p0
-        if(dim==1):
-            velocity_field[i,0] = 1
-            velocity_field[i,1] = 0
-            velocity_field[i,2] = 0
-        elif(dim==2):
-            velocity_field[i,0] =  sin(pi*x)*cos(pi*y)
-            velocity_field[i,1] = -sin(pi*y)*cos(pi*x)
-            velocity_field[i,2] = 0
-        elif(dim==3):
-            velocity_field[i,0] =    sin(pi*x)*cos(pi*y)*cos(pi*z)
-            velocity_field[i,1] =    sin(pi*y)*cos(pi*x)*cos(pi*z)
-            velocity_field[i,2] = -2*sin(pi*z)*cos(pi*x)*cos(pi*y)
-        
-    return pressure_field, velocity_field
-
-def jacobianMatrices(normal,coeff):
-    dim=normal.size()
-    A=cdmath.Matrix(dim+1,dim+1)
-    absA=cdmath.Matrix(dim+1,dim+1)
-
-    absA[0,0]=c0*coeff
-    for i in range(dim):
-        A[i+1,0]=      normal[i]*coeff
-        A[0,i+1]=c0*c0*normal[i]*coeff
-        for j in range(dim):
-            absA[i+1,j+1]=c0*normal[i]*normal[j]*coeff
-    
-    return (A - absA)*(1./2)
-    
-def computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt):
-    nbCells = my_mesh.getNumberOfCells()
-    dim=my_mesh.getMeshDimension()
-    nbComp=dim+1
-    normal=cdmath.Vector(dim)
-
-    implMat=cdmath.SparseMatrixPetsc(nbCells*nbComp,nbCells*nbComp,(nbVoisinsMax+1)*nbComp)
-
-    idMoinsJacCL=cdmath.Matrix(nbComp)
-    
-    for j in range(nbCells):#On parcourt les cellules
-        Cj = my_mesh.getCell(j)
-        nbFaces = Cj.getNumberOfFaces();
-
-        for k in range(nbFaces) :
-            indexFace = Cj.getFacesId()[k];
-            Fk = my_mesh.getFace(indexFace);
-            for i in range(dim) :
-                normal[i] = Cj.getNormalVector(k, i);#normale sortante
-
-            Am=jacobianMatrices( normal,dt*Fk.getMeasure()/Cj.getMeasure());
-
-            cellAutre =-1
-            if ( not Fk.isBorder()) :
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if (Fk.getCellsId()[0] == j) :
-                    # hypothese verifiée 
-                    cellAutre = Fk.getCellsId()[1];
-                elif(Fk.getCellsId()[1] == j) :
-                    # hypothese non verifiée 
-                    cellAutre = Fk.getCellsId()[0];
-                else :
-                    raise ValueError("computeFluxes: problem with mesh, unknown cell number")
-                    
-                implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-            else  :
-                if( Fk.getGroupName() != "Periodic" and Fk.getGroupName() != "Neumann"):#Wall boundary condition unless Periodic/Neumann specified explicitly
-                    v=cdmath.Vector(dim+1)
-                    for i in range(dim) :
-                        v[i+1]=normal[i]
-                    idMoinsJacCL=v.tensProduct(v)*2
-                    
-                    implMat.addValue(j*nbComp,j*nbComp,Am*(-1.)*idMoinsJacCL)
-                    
-                elif( Fk.getGroupName() == "Periodic"):#Periodic boundary condition
-                    indexFP=my_mesh.getIndexFacePeriodic(indexFace)
-                    Fp = my_mesh.getFace(indexFP)
-                    cellAutre = Fp.getCellsId()[0]
-                    
-                    implMat.addValue(j*nbComp,cellAutre*nbComp,Am)
-                    implMat.addValue(j*nbComp,        j*nbComp,Am*(-1.))
-                elif(Fk.getGroupName() != "Neumann"):#Nothing to do for Neumann boundary condition
-                    print( Fk.getGroupName() )
-                    raise ValueError("computeFluxes: Unknown boundary condition name");
-                
-    return implMat
-
-def WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit):
-    dim=my_mesh.getMeshDimension()
-    nbCells = my_mesh.getNumberOfCells()
-    meshName=my_mesh.getName()
-    
-    dt = 0.
-    time = 0.
-    it=0;
-    isStationary=False;
-    nbVoisinsMax=my_mesh.getMaxNbNeighbours(cdmath.CELLS)
-
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    if(filename.find("square")>-1 or filename.find("Square")>-1 or filename.find("cube")>-1 or filename.find("Cube")>-1):
-        pressure_field, velocity_field = initial_conditions_square_vortex(my_mesh)
-    elif(filename.find("disk")>-1 or filename.find("Disk")>-1):
-        pressure_field, velocity_field = initial_conditions_disk_vortex(my_mesh)
-    else:
-        print( "Mesh name : ", filename)
-        raise ValueError("Mesh name should contain substring square, cube or disk")
-
-    #iteration vectors
-    Un =cdmath.Vector(nbCells*(dim+1))
-    dUn=cdmath.Vector(nbCells*(dim+1))
-    
-    for k in range(nbCells):
-        Un[k*(dim+1)+0] =     pressure_field[k]
-        Un[k*(dim+1)+1] =rho0*velocity_field[k,0]
-        Un[k*(dim+1)+2] =rho0*velocity_field[k,1]
-        if(dim==3):
-            Un[k*(dim+1)+3] =rho0*velocity_field[k,2]
-
-    #sauvegarde de la donnée initiale
-    pressure_field.setTime(time,it);
-    pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure");
-    velocity_field.setTime(time,it);
-    velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity");
-
-    dx_min=my_mesh.minRatioVolSurf()
-
-    dt = cfl * dx_min / c0
-    
-    divMat=computeDivergenceMatrix(my_mesh,nbVoisinsMax,dt)
-    if( isImplicit):
-        #Adding the identity matrix on the diagonal
-        divMat.diagonalShift(1)#only after  filling all coefficients
-        
-        iterGMRESMax=50
-        LS=cdmath.LinearSolver(divMat,Un,iterGMRESMax, precision, "GMRES","ILU")
-
-        LS.setComputeConditionNumber()
-        
-    print("Starting computation of the linear wave system with an UPWIND scheme …")
-    
-    # Starting time loop
-    while (it<ntmax and time <= tmax and not isStationary):
-        if(isImplicit):
-            dUn=Un.deepCopy()
-            LS.setSndMember(Un)
-            Un=LS.solve();
-            if(not LS.getStatus()):
-                print( "Linear system did not converge ", LS.getNumberOfIter(), " GMRES iterations")
-                raise ValueError("Pas de convergence du système linéaire");
-            dUn-=Un
-
-        else:
-            dUn=divMat*Un
-            Un-=dUn
-        
-        time=time+dt;
-        it=it+1;
-        #Sauvegardes
-        if(it%output_freq==0 or it>=ntmax or isStationary or time >=tmax):
-            print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-
-            for k in range(nbCells):
-                pressure_field[k]  =Un[k*(dim+1)+0]
-                velocity_field[k,0]=Un[k*(dim+1)+1]/rho0
-                if(dim>1):
-                    velocity_field[k,1]=Un[k*(dim+1)+2]/rho0
-                    if(dim>2):
-                        velocity_field[k,2]=Un[k*(dim+1)+3]/rho0
-
-            pressure_field.setTime(time,it);
-            pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure",False);
-            velocity_field.setTime(time,it);
-            velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity",False);
-
-    print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-    print()
-
-    if(it>=ntmax):
-        print( "Nombre de pas de temps maximum ntmax= ", ntmax, " atteint")
-    elif(isStationary):
-        print( "Régime stationnaire atteint au pas de temps ", it, ", t= ", time)
-
-        pressure_field.setTime(time,0);
-        pressure_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat");
-        velocity_field.setTime(time,0);
-        velocity_field.writeVTK("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat");
-
-        #Postprocessing : Extraction of the diagonal data
-        diag_data_press=VTK_routines.Extract_field_data_over_line_to_numpyArray(pressure_field,[0,1,0],[1,0,0], resolution)    
-        diag_data_vel  =VTK_routines.Extract_field_data_over_line_to_numpyArray(velocity_field,[0,1,0],[1,0,0], resolution)    
-        #Postprocessing : save 2D picture
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat"+'_0.vtu',"Pressure",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_pressure_Stat")
-        PV_routines.Save_PV_data_to_picture_file("WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat"+'_0.vtu',"Velocity",'CELLS',"WaveSystem"+str(dim)+"DUpwind"+meshName+"_velocity_Stat")
-        
-    else:
-        print( "Temps maximum Tmax= ", tmax, " atteint")
-
-
-def solve(my_mesh,filename,resolution, isImplicit):
-    print( "Resolution of the Wave system in dimension ", my_mesh.getSpaceDimension())
-    print( "Numerical method : upwind")
-    print( "Initial data : stationary solution (constant pressure, divergence free velocity)")
-    print( "Wall boundary conditions")
-    print( "Mesh name : ",filename , my_mesh.getNumberOfCells(), " cells")
-
-    # Problem data
-    tmax = 1.
-    ntmax = 100
-    cfl = 1./my_mesh.getSpaceDimension()
-    output_freq = 100
-
-    WaveSystemVF(ntmax, tmax, cfl, my_mesh, output_freq, filename,resolution, isImplicit)
-
-def solve_file( filename,resolution):
-    my_mesh = cdmath.Mesh(filename+".med")
-    solve(my_mesh, filename,resolution, isImplicit)
-    
-if __name__ == """__main__""":
-    if len(sys.argv) >2 :
-        filename=sys.argv[1]
-        isImplicit=bool(int(sys.argv[2]))
-        my_mesh = cdmath.Mesh(filename)
-        solve(my_mesh,filename,100, isImplicit)
-    else :
-        raise ValueError("WaveSystemUpwind.py expects a mesh file name and a boolean (isImplicit)")
diff --git a/CDMATH/tests/examples/thermique1d/main.cxx b/CDMATH/tests/examples/thermique1d/main.cxx
deleted file mode 100644 (file)
index b80f292..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-//============================================================================
-// Name        : Thermique 1D Entrée sortie
-// Author      : M. Ndjinga
-// Version     :
-// Copyright   : CEA Saclay 2014
-// Description : Modélisation 1D d'un cœur de réacteur
-//============================================================================
-
-#include <iostream>
-#include <cmath>
-//#include<complex>
-
-//#include "Matrix.hxx"
-#include "Vector.hxx"
-#include "LinearSolver.hxx"
-#include "Mesh.hxx"
-#include "Field.hxx"
-#include "Cell.hxx"
-//#include "Face.hxx"
-//#include "Node.hxx"
-#include "CdmathException.hxx"
-
-using namespace std;
-
-
-void champ_heaviside(Field& Temp, double milieu, double TempLeft, double TempRight)
-{
-    Mesh M=Temp.getMesh();
-    int nbCells=M.getNumberOfCells();
-    double x;
-    for (int j=0 ; j<nbCells ; j++)
-    {
-        x = M.getCell(j).x() ;
-        //cout<<"cellule "<< j<<" x= "<< x<<" milieu= "<< milieu <<endl;
-        if (x<milieu)
-            Temp(j) = TempLeft;
-        else
-            Temp(j) = TempRight;
-    }
-}
-
-
-double sign(double x)
-{
-    if(x>0)
-        return 1.;
-    else if(x<0)
-            return -1.;
-        else
-            return 0.;
-}
-
-
-double theta_upwind(double Tim1, double Ti, double Tip1, double Tip2, double VitesseX, double dt, double Tin, double Tip1n)
-{
-    if(abs(Tip1-Ti)<1.e-5)
-        return 1.;
-
-    double denominateur = abs(VitesseX)*(2.-sign(Tip1-Ti)*(sign(Tip2-Tip1)+sign(Ti-Tim1)));
-
-    if( abs(denominateur) <=1.e-5 )
-                return 0.5;
-    else
-    {
-        double result = (1-sign(Tip1-Ti)*sign(Ti-Tim1))/denominateur;
-        if(result <0.5)
-            return 0.5;
-        else
-            return result;
-    }
-}
-
-
-void solveTriDiag(vector<double>& a,vector<double>& b,vector<double>& c,Field &d, int nbCells)
-{
-    int n= nbCells;
-
-    if(a.size()!=c.size() || a.size()+1 != b.size() || n != (int) b.size() || n != (int) (d.getMesh()).getNumberOfCells())
-        throw CdmathException("solveTriDiag(): vectors with inapropriate size");
-
-/*  cout<<"avant solveTri"<<endl;
-    for(int i=0;i<nbCells-2;i++)
-        cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
-
-    /* Algorithme de résolution d'un Système Tridiagonal*/
-         n--; // since we start from x0 (not x1)
-         c[0] /= b[0];
-         d[0] /= b[0];
-         for (int i = 1; i < n; i++) {
-            c[i] /= b[i] - a[i-1]*c[i-1];
-            d[i] = (d[i] - a[i-1]*d[i-1]) / (b[i] - a[i-1]*c[i-1]);
-            }
-
-            d[n] = (d[n] - a[n-1]*d[n-1]) / (b[n] - a[n-1]*c[n-1]);
-
-            for (int i = n; i-- > 0;) {
-                d[i] -= c[i]*d[i+1];
-            }
-
-        /*cout<<"apres solveTri"<<endl;
-        for(int i=0;i<nbCells-2;i++)
-            cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
-}
-
-
-void solveEntreeImplicit(Field& phi, Field& Temp, int nbCells, double VitesseX, double cfl, double Tentree, double dt) {
-
-    /* Coefficients de la matrice tridiagonalee liee au systeme*/
-    /*b=coeff diag, c= coeff au dessus diag, a= coeff sous diag */
-    vector<double> a(nbCells-1),b(nbCells),c(nbCells-1);
-    double theta, epsilon=1.e-2, erreur=1/epsilon;
-    int iterMax=100, k=0;
-    Field d, ScndMbre=phi, Tempn=Temp;
-    ScndMbre*=dt;
-    ScndMbre+=Tempn;//On obtient Tn+dt*phi
-    //On décentre le terme source
-    for (int i = 1; i < nbCells-1; i++)
-        {
-        ScndMbre[i]-=cfl*(phi[i]-phi[i-1])*dt/2;
-        }
-    ScndMbre[0]-=cfl*(phi[0])*dt/2;
-        //d[0]-=cfl*(phi[n-1]-phi[n-2]);
-
-    if(nbCells<3)
-        throw CdmathException("solveEntreeImplicit(): mesh should have at least three cells");
-
-    while( k<iterMax && erreur>epsilon)
-    {
-    d= ScndMbre;//contiendra le second membre du système
-    /*cout<< " Debut itération d= "<<endl;
-    for(int i=0;i<nbCells-1;i++)
-            cout<< " , "<< d(i);
-    cout<<endl;*/
-    cout<<"theta="<<endl;
-    /* On traite la première face (entrée) */
-    theta=theta_upwind(Tentree,Tentree,Temp(0),Temp(1),VitesseX, dt, Tentree, Tempn(0));
-    b[0]=1+ cfl*(2*theta-1);
-    c[0]=(1-theta)*cfl;
-    d(0)+=theta*cfl*Tentree;
-
-    cout<< theta << " , ";
-
-    /* On traite la deuxième face interne */
-    theta=theta_upwind(Tentree,Temp(0),Temp(1),Temp(2),VitesseX, dt, Tempn(0), Tempn(1));
-    b[1]=1+ cfl*(2*theta-1);
-    c[1]=(1-theta)*cfl;
-    a[0]=-theta*cfl;
-
-    cout<< theta << " , ";
-
-    //On traite les faces internes
-    for(int i=2; i<nbCells-2; i++)
-    {
-        theta=theta_upwind(Temp(i-2),Temp(i-1),Temp(i),Temp(i+1),VitesseX, dt, Tempn(i-1), Tempn(i));
-        b[i]=1+ cfl*(2*theta-1);
-        c[i]=(1-theta)*cfl;
-        a[i-1]=-theta*cfl;
-        cout<< theta << " , ";
-    }
-
-    /* On traite l'avant dernière face interne */
-    theta=theta_upwind(Temp(nbCells-3),Temp(nbCells-2),Temp(nbCells-1),Temp(nbCells-1),VitesseX, dt, Tempn(nbCells-2), Tempn(nbCells-1));
-    b[nbCells-2]=1+ cfl*(2*theta-1);
-    c[nbCells-2]=(1-theta)*cfl;
-    a[nbCells-3]=-theta*cfl;
-
-    cout<< theta << " , ";
-
-    /* On traite la dernière face (sortie) */
-    theta=theta_upwind(Temp(nbCells-2),Temp(nbCells-1),Temp(nbCells-1),Temp(nbCells-1),VitesseX, dt, Tempn(nbCells-1), Tempn(nbCells));
-    b[nbCells-1]=1+ cfl*theta;
-    a[nbCells-2]=-theta*cfl;
-    //d(nbCells-1)+=-(1-theta_sortie)*cfl*Tempn(nbCells-1);
-
-    cout<< theta << endl;
-
-    cout<<" k= " << k<<endl;
-    /*cout<<"avant solveTri"<<endl;
-    for(int i=0;i<nbCells-2;i++)
-        cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
-    solveTriDiag(a,b,c,d,nbCells);
-    /*cout<<"après solveTri"<<endl;
-    for(int i=0;i<nbCells-2;i++)
-        cout<< " a= "<< a[i]<<" b= "<< b[i]<<" c= "<< c[i]<< " d= "<< d[i]<<endl;*/
-    k++;
-    erreur = 0;
-    for(int i=0;i<nbCells; i++)
-        erreur=max(erreur, abs(Temp(i)-d[i])/300);
-    cout<< " erreur= "<<erreur<<endl;
-    /*cout<< " Fin itération d= "<<endl;
-    for(int i=0;i<nbCells-1;i++)
-            cout<< " , "<< d(i);
-    cout<<endl;*/
-    Temp=d;
-//  for(int i=0;i<nbCells-1;i++)
-//      cout<< " Temp= "<< Temp(i)<<endl;
-    }
-
-    if(k>=iterMax)
-        throw CdmathException("solveEntreeImplicit: Newton scheme not convergent");
-}
-
-
-void EquationTransport1D_entree(double tmax, double VitesseX, int ntmax, double dt, double cfl,int freqSortie, const Mesh& M, const string file, double milieu, double TempLeft, double TempRight)
-{
-    /* --------------------------------------------- */
-    /* Condition initiale */
-    cout << "Construction de la condition initiale ... " << endl;
-    Field Temp("Temperature",CELLS,M,1) ;
-    champ_heaviside(Temp,milieu,TempLeft, TempRight);
-
-    /*terme source */
-    cout << "Construction du terme source ... " << endl;
-    Field phi("Flux thermique",CELLS,M,1) ;
-    champ_heaviside(phi,milieu,-10, 10);
-    /*
-     * Sortie MED de la condition initiale et du flux thermique à t=0 et iter = 0
-     */
-    int iter=0;
-    double time=0.;
-    int nbCells=M.getNumberOfCells();
-    cout << "Post-traitement MED du flux thermique constant en temps"<< " ..." << endl;
-    //phi.setTime(time,iter);
-    //phi.writeCSV(file);
-    cout << "Post-traitement MED de la solution à t=" << time << " ..." << endl;
-    Temp.setTime(time,iter);
-    //Temp.writeCSV(file);
-    Temp.writeVTK(file);
-    /* boucle de temps */
-    cout << " Resolution de l'equation de transport 1D avec entree par un schema Implicite TVD" << endl;
-
-    while (iter<ntmax && time <= tmax )
-    {
-        cout << "-- Iter : " << iter << " Time : " << time << " dt : " << dt << endl;
-
-        /* Avancement en temps */
-            solveEntreeImplicit(phi, Temp,nbCells, VitesseX, cfl, TempLeft, dt);
-        time+=dt;
-        iter+=1;
-        // sortie visu tous les freq iterations
-        if (iter%freqSortie==0)
-        {
-            Temp.setTime(time,iter);
-            Temp.writeVTK(file,false);
-            //Temp.writeCSV(file);
-        }
-    }
-}
-
-
-int Equation_Transport()
-{
-    cout << "RESOLUTION EQUATION DE TRANSPORT 1D :" << endl;
-    cout << "- DOMAINE : Segment 0,10" << endl;
-    cout << "- MAILLAGE CARTESIEN : GENERATION INTERNE CDMATH " << endl;
-
-    // Problem data
-    double VitesseX=1.0;
-    double tmax=100.;
-    int freqSortie=1;
-    int ntmax=3;
-    int nx=50;
-    double xinf=0.0;
-    double xsup=10.;
-    double dx=(xsup-xinf)/nx;
-    double cfl=1;
-    double dt=cfl*dx/abs(VitesseX);
-
-    double TempLeft=300;//285.;
-    double TempRight=300;//315.;
-
-    cout << "Début Construction du maillage Cartesien…" << endl;
-    Mesh M(xinf,xsup,nx);
-    cout << "Fin Construction du maillage Cartesien…" << endl;
-
-    //  theta=1;
-    EquationTransport1D_entree(tmax, VitesseX, ntmax, dt, cfl, freqSortie, M, "TemperatureEntreeImplicitTVD50CellsSourceUpwind", (xsup+xinf)/2, TempLeft, TempRight);
-    //EquationTransport1D_entree(tmax, VitesseX, ntmax, dt, cfl, freqSortie, M, "TemperatureEntreeImplicitUpwindCreneau50Cells", (xsup+xinf)/4, TempLeft, TempRight);
-
-    cout << "CDMATH calculation done." << endl;
-    return 0;
-}
-
-
-int main() {
-/* Test solveur tridiagonal
-    int n=6;
-    Matrix A2(n,n,n+2*(n-1));
-
-       A2(0,0)=2.;
-       vector<double> e(n-1);
-       for(int i=0;i<n-1;i++)
-           {
-           e[i]=-1/(i+1);
-           A2(i,i+1)=-1/(i+1);
-           A2(i+1,i)=-1.;
-           A2(i+1,i+1)=2.;
-           }
-       Vector Xana2(n);
-       for(int i=0;i<n;i++)
-            Xana2(i)=i;
-
-       Vector B2=A2*Xana2;
-
-       LinearSolver LS11(A2,B2,500,1.E-10,"GMRES","ILU");
-       Vector X11=LS11.solve();
-       bool correct=true;
-       for (int i=0;i<X11.getNumberOfRows();i++)
-        correct=correct && (abs(X11(i)-Xana2(i))<1.E-10);
-
-       if(correct)
-           cout<<"OK"<<endl;
-       else
-           cout<<"KO"<<endl;
-       vector<double> a(n-1,-1),b(n,2),c(n-1,-0.5);
-       Mesh M(0,1,n);
-       Field d("Test",CELLS,M,1);
-       int nbCells=M.getNumberOfCells();
-       for(int i=0;i<nbCells;i++)
-           d[i]=B2(i);
-       solveTriDiag(a,b,e,d,nbCells);
-       correct=true;
-       for (int i=0;i<X11.getNumberOfRows();i++)
-        correct=correct && (abs(d(i)-Xana2(i))<1.E-10);
-
-       if(correct)
-           cout<<"OK"<<endl;
-       else
-           cout<<"KO"<<endl;
-
-        Fin Test solveur tridiagonal */
-
-       int ret=Equation_Transport();
-       return ret;
-}
diff --git a/CDMATH/tests/examples/thermique1d/makefile b/CDMATH/tests/examples/thermique1d/makefile
deleted file mode 100644 (file)
index 8c7b9db..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# thermique1d makefile
-
-CC = g++
-
-# Adapt the following lines to your own system:
-PETSCDIR = /usr/lib/petscdir/3.4.5
-MPIDIR = /usr/lib/openmpi
-CDMATHDIR = ../../../../..
-
-IFLAG = -I$(PETSCDIR)/include -I$(MPIDIR)/include -I$(CDMATHDIR)/include -I.
-LFLAG = -L$(CDMATHDIR)/lib
-LIBS  = -linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver
-OBJ = main.o
-
-all: $(OBJ)
-       $(CC) -o main $^ $(IFLAG) $(LFLAG) $(LIBS)
-       
-%.o: %.cxx
-       $(CC) -c -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
-       
-.PHONY: clean
-
-clean:
-       rm -f *.o *~ core $(INCDIR)/*~
-
-sweep:
-       rm -f *.vtu
-       rm -f *.pvd
diff --git a/CDMATH/tests/examples/transport1d/main.cxx b/CDMATH/tests/examples/transport1d/main.cxx
deleted file mode 100644 (file)
index e0fe662..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-//============================================================================
-// Author      : Anouar MEKKAS
-// Version     :
-// Description : 1D linear transport equation
-//============================================================================
-
-#include <iostream>
-#include <cmath>
-
-#include "Cell.hxx"
-#include "Mesh.hxx"
-#include "Field.hxx"
-
-using namespace std;
-
-
-int main( void )
-{
-  double a=-5.0;
-  double b=5.0;
-  int nx=1000;
-  int ntmax=3;
-  double dx = (b-a)/nx;
-  double pi=3.1415927;
-  // Transport velocity
-  double cfl=0.5;
-  double u=3.;
-  double dt=cfl*dx/u;
-
-  Mesh myMesh(a,b,nx);
-
-  Field conc("Concentration",CELLS,myMesh,1);
-
-  // Initial conditions
-  double sigma=sqrt(0.2);
-  for (int i=0 ; i<myMesh.getNumberOfCells() ; i++)
-  {
-   double x=myMesh.getCell(i).x();
-   conc(i) = 0.5/(sigma*sqrt(2*pi))*exp(-0.5*pow((x/sigma),2));
-  }
-
-  double time=0.;
-  double tmax=3.0;
-  int iter=0;
-
-  cout << "MED post-treatment of the solution at T=" << time << "…" << endl;
-  string fileOutPut="EqTr1D";
-  conc.setTime(time,iter);
-  conc.writeMED(fileOutPut);
-  conc.writeVTK(fileOutPut);
-  conc.writeCSV(fileOutPut);
-  int outputFreq=10;
-
-  // Time loop
-  while (iter<ntmax && time <= tmax )
-  {
-   cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
-   conc(0) = conc(0) -u*dt/dx*(conc(0)-conc(myMesh.getNumberOfCells()-1));
-   for (int j=1 ; j<myMesh.getNumberOfCells() ; j++)
-   {
-    conc(j) = conc(j) -u*dt/dx*(conc(j)-conc(j-1));
-   }
-   time+=dt;
-   iter+=1;
-   if (iter%outputFreq==0)
-   {
-       conc.setTime(time,iter);
-       conc.writeMED(fileOutPut,false);
-       conc.writeVTK(fileOutPut,false);
-       conc.writeCSV(fileOutPut);
-   }
-  }
-  cout << "CDMATH calculation done." << endl;
-  return 0;
-}
-
-
diff --git a/CDMATH/tests/examples/transport1d/main.py b/CDMATH/tests/examples/transport1d/main.py
deleted file mode 100644 (file)
index e573b8b..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-import math
-
-import cdmath
-
-
-def main():
-    a = -5.0
-    b = 5.0
-    nx = 1000
-    ntmax = 1000
-    dx = (b - a) / nx
-    pi = 3.1415927
-    # Transport velocity
-    cfl = 0.5
-    u = 3.
-    dt = cfl * dx / u
-
-    my_mesh = cdmath.Mesh(a, b, nx)
-    conc = cdmath.Field("Concentration", cdmath.CELLS, my_mesh, 1)
-
-    # Initial conditions
-    sigma = math.sqrt(0.2)
-    for i in range(my_mesh.getNumberOfCells()):
-        x = my_mesh.getCell(i).x()
-        conc[i] = 0.5 / (sigma * math.sqrt(2 * pi)) * math.exp(-0.5 * math.pow((x / sigma), 2))
-        pass
-
-    time = 0.
-    tmax = 3.0
-    it = 0
-
-    print("MED post-treatment of the solution at T=" + str(time) + "…")
-    output_filename = "EqTr1D"
-    conc.setTime(time, it)
-    conc.writeMED(output_filename)
-    conc.writeVTK(output_filename)
-    conc.writeCSV(output_filename)
-    output_freq = 10
-
-    # Time loop
-    while (it < ntmax and time <= tmax):
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-        conc[0] = conc[0] - u * dt / dx * (conc[0] - conc[my_mesh.getNumberOfCells() - 1])
-        for j in range(1, my_mesh.getNumberOfCells()):
-            conc[j] = conc[j] - u * dt / dx * (conc[j] - conc[j - 1])
-            pass
-        time += dt
-        it += 1
-        if (it % output_freq == 0):
-            conc.setTime(time, it)
-            conc.writeMED(output_filename, False)
-            conc.writeVTK(output_filename, False)
-            conc.writeCSV(output_filename)
-            pass
-        pass
-    print("CDMATH calculation done.")
-    return
-
-
-if __name__ == """__main__""":
-    main()
diff --git a/CDMATH/tests/examples/transport1d/makefile b/CDMATH/tests/examples/transport1d/makefile
deleted file mode 100644 (file)
index 9e9121a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# Transport1d makefile
-
-CC = g++
-# Adapt the following line to your own system:
-CDMATHDIR = ../../../../..
-IFLAG = -I$(CDMATHDIR)/include -I.
-LFLAG = -L$(CDMATHDIR)/lib
-LIBS  =-linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver
-OBJ = main.o
-
-all: $(OBJ)
-       $(CC) -o main $^ $(IFLAG) $(LFLAG) $(LIBS)
-       
-%.o: %.cxx
-       $(CC) -c -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
-       
-.PHONY: clean
-
-clean:
-       rm -f *.o *~ core $(INCDIR)/*~
-
-sweep:
-       rm -f *.vtu
-       rm -f *.pvd
-       rm -f *.csv
-       rm -f *.med
diff --git a/CDMATH/tests/examples/transport2d_ns/main.cxx b/CDMATH/tests/examples/transport2d_ns/main.cxx
deleted file mode 100644 (file)
index 5ae5640..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-//============================================================================
-// Author      : Anouar MEKKAS
-// Version     :
-// Description : Equation de transport lineaire 2D non structure
-//============================================================================
-
-#include <iostream>
-#include <string>
-#include <cmath>
-
-#include "Mesh.hxx"
-#include "Cell.hxx"
-#include "Face.hxx"
-#include "Field.hxx"
-
-using namespace std;
-
-
-void conditions_initiales(Field& yField)
-{
-    double rayon=0.15;
-    double xcentre=0.25;
-    double ycentre=0.25;
-    Mesh myMesh=yField.getMesh();
-    int nbCells=myMesh.getNumberOfCells();
-    for (int j=0 ; j<nbCells ; j++)
-    {
-        double x = myMesh.getCell(j).x() ;
-        double y = myMesh.getCell(j).y() ;
-        double valX=(x-xcentre)*(x-xcentre);
-        double valY=(y-ycentre)*(y-ycentre);
-        double val=sqrt(valX+valY);
-        if (val<rayon)
-            yField(j) = 1.0;
-        else
-            yField(j) = 0.0;
-    }
-}
-
-void sigma_flux(double VitesseX, double VitesseY, double cfl, const Field& yField, const IntTab indexFacesPerio, double& dt, Field& SumFlux)
-{
-    // Calculation of fluxes
-    Mesh myMesh=yField.getMesh();
-    int nbCells=myMesh.getNumberOfCells();
-    double normU=sqrt(VitesseX*VitesseX+VitesseY*VitesseY);
-    for (int j=0 ; j<nbCells ; j++)
-    {
-        Cell Cj=myMesh.getCell(j);
-        int nbFace=Cj.getNumberOfFaces();
-        double SumF=0.0;
-        double minlengthFk=1.E30;
-
-        int cellCourante,cellAutre;
-        for (int k=0 ; k<nbFace ; k++)
-        {
-            int indexFace=Cj.getFacesId()[k];
-            Face Fk=myMesh.getFace(indexFace);
-            double NormalX=Cj.getNormalVector(k,0);
-            double NormalY=Cj.getNormalVector(k,1);
-            double LengthFk = Fk.getMeasure();
-            double UN=VitesseX*NormalX+VitesseY*NormalY;
-
-            minlengthFk=min(minlengthFk,LengthFk/fabs(UN));
-            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseX));
-            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseY));
-
-            double conc=0.0;
-            cellCourante=j;
-            cellAutre=-1;
-
-            if (!Fk.isBorder())
-            {
-                int indexC1=Fk.getCellsId()[0];
-                int indexC2=Fk.getCellsId()[1];
-                /* hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if ( indexC1 == j )
-                {
-                    /* hypothese verifie */
-                    cellCourante=indexC1;
-                    cellAutre=indexC2;
-                } else if ( indexC2 == j )
-                {
-                    /* hypothese non verifie */
-                    cellCourante=indexC2;
-                    cellAutre=indexC1;
-                }
-                // definir la cellule gauche et droite par le prduit vitesse * normale sortante
-                // si u*n>0 : rien a faire sinon inverser la gauche et la droite
-                if (UN>1.E-15)
-                    conc=yField(cellCourante);
-                else
-                    conc=yField(cellAutre);
-            }else
-            {
-                /* conditions aux limites neumann homogene */
-                if (Fk.getGroupName().compare("GAUCHE")==0 || Fk.getGroupName().compare("DROITE")==0)
-                {
-                    if (UN>1.E-15)
-                        conc=yField(cellCourante);
-                    else
-                        conc=0.0;
-                }
-                /* conditions aux limites periodiques */
-                if (Fk.getGroupName().compare("BAS")==0 || Fk.getGroupName().compare("HAUT")==0)
-                {
-                        int indexFP=indexFacesPerio[indexFace];
-                        /* une autre manière de recuperer l'index de la face periodique */
-                        //int indexFP=M.getIndexFacePeriodic(indexFace);
-                        Face Fp=myMesh.getFace(indexFP);
-                        int indexCp=Fp.getCellsId()[0];
-                        if (UN>1.E-15)
-                            conc=yField(cellCourante);
-                        else
-                            conc=yField(indexCp);
-                }
-            }
-            SumF=SumF+UN*LengthFk*conc;
-          }
-        dt=cfl*minlengthFk/normU;
-        SumFlux(j)=dt*SumF/Cj.getMeasure();
-    }
-}
-
-void EquationTransport2D(double tmax, double VitesseX, double VitesseY, double cfl, int freqSortie, const Mesh& myMesh, const string file)
-{
-    /* Initial conditions */
-    cout << "Construction of the initial condition …" << endl;
-    Field yField("Y field",CELLS,myMesh,1) ;
-    conditions_initiales(yField);
-
-    /*
-     * MED output of the initial condition at t=0 and iter = 0
-     */
-    int iter=0;
-    double time=0.;
-    cout << "Saving the solution at T=" << time << "…" << endl;
-    yField.setTime(time,iter);
-    yField.writeMED(file);
-    yField.writeVTK(file);
-    yField.writeCSV(file);
-    /* --------------------------------------------- */
-
-    /* Time loop */
-    cout << "Resolution of the transport equation with an UPWIND scheme …" << endl;
-    int ntmax=3;
-    double dt;
-    IntTab indexFacesPerio=myMesh.getIndexFacePeriodic();
-    while (iter<ntmax && time <= tmax )
-    {
-        Field SumFlux("Fluxes sum",CELLS,myMesh,1) ;
-        sigma_flux(VitesseX,VitesseY,cfl,yField,indexFacesPerio,dt,SumFlux);
-        cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
-
-        /* Advancing time step */
-        yField-=SumFlux;
-
-        time+=dt;
-        iter+=1;
-        // Output every freq iterations
-        if (iter%freqSortie==0)
-        {
-            yField.setTime(time,iter);
-            yField.writeMED(file,false);
-            yField.writeVTK(file,false);
-            yField.writeCSV(file);
-        }
-    }
-}
-
-int main()
-{
-    cout << "Resolution of the 2D transport equation:" << endl;
-    cout << "- DOMAIN: SQUARE" << endl;
-    cout << "- MESH: TRIANGULAR, GENERATED WITH SALOME" << endl;
-    cout << "- PERIODIC BC ON TOP AND BOTTOM" << endl;
-    cout << "- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT" << endl;
-
-    // Problem data
-    double cfl=0.4;
-    double VitesseX=1.0;
-    double VitesseY=1.0;
-    double tmax=1.;
-    int freqSortie=10;
-
-    cout << "Construction of Cartesian mesh…" << endl;
-    Mesh myMesh("../../tests/ressources/meshSquare.med");
-    string fileOutPut="Exercice2";
-    EquationTransport2D(tmax,VitesseX,VitesseY,cfl,freqSortie,myMesh,fileOutPut);
-    cout << "CDMATH calculation done." << endl;
-
-    return 0;
-}
diff --git a/CDMATH/tests/examples/transport2d_ns/main.py b/CDMATH/tests/examples/transport2d_ns/main.py
deleted file mode 100644 (file)
index 1315426..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-import math
-
-import cdmath
-
-
-def initial_conditions(my_mesh):
-    rayon = 0.15
-    xcentre = 0.25
-    ycentre = 0.25
-    y_field = cdmath.Field("Y field", cdmath.CELLS, my_mesh, 1)
-    nbCells = my_mesh.getNumberOfCells()
-    for j in range(nbCells):
-        x = my_mesh.getCell(j).x()
-        y = my_mesh.getCell(j).y()
-        valX = (x - xcentre) * (x - xcentre)
-        valY = (y - ycentre) * (y - ycentre)
-        val = math.sqrt(valX + valY)
-        if val < rayon:
-            y_field[j] = 1.0
-            pass
-        else:
-            y_field[j] = 0.0
-            pass
-        pass
-    return y_field
-
-
-def sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio):
-    # Calculation of fluxes #
-    SumFlux = cdmath.Field("Fluxes", cdmath.CELLS, y_field.getMesh(), 1)
-    my_mesh = y_field.getMesh()
-    nbCells = my_mesh.getNumberOfCells()
-    normU = math.sqrt(VitesseX * VitesseX + VitesseY * VitesseY)
-    for j in range(nbCells):
-        Cj = my_mesh.getCell(j)
-        nbFace = Cj.getNumberOfFaces()
-        SumF = 0.0
-        minlengthFk = 1.E30
-        for k in range(nbFace):
-            indexFace = Cj.getFacesId()[k]
-            Fk = my_mesh.getFace(indexFace)
-            NormalX = Cj.getNormalVector(k, 0)
-            NormalY = Cj.getNormalVector(k, 1)
-            LengthFk = Fk.getMeasure()
-            UN = VitesseX * NormalX + VitesseY * NormalY
-            minlengthFk = min(minlengthFk, LengthFk / abs(UN))
-            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseX))
-            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseY))
-            conc = 0.0
-            cellCourante = j
-            cellAutre = -1
-            if (not Fk.isBorder()):
-                indexC1 = Fk.getCellsId()[0]
-                indexC2 = Fk.getCellsId()[1]
-                # hypothesis: the cell of index indexC1 is the current cell of index j #
-                if (indexC1 == j):
-                    # hypothese is verified #
-                    cellCourante = indexC1
-                    cellAutre = indexC2
-                    pass
-                elif (indexC2 == j):
-                    # hypothesis is not verified #
-                    cellCourante = indexC2
-                    cellAutre = indexC1
-                    pass
-                # define left and right cell with the product of velocity * outward normal vector
-                # if u*n>0: nothing to do, else invert left and right
-                if (UN > 1.E-15):
-                    conc = y_field[cellCourante]
-                    pass
-                else:
-                    conc = y_field[cellAutre]
-                    pass
-                pass
-            else:
-                # homogeneous Neumann boundary conditions #
-                if (Fk.getGroupName() == "GAUCHE" or Fk.getGroupName() == "DROITE"):
-                    if (UN > 1.E-15):
-                        conc = y_field[cellCourante]
-                        pass
-                    else:
-                        conc = 0.0
-                        pass
-                    pass
-                # periodical boundary conditions #
-                if (Fk.getGroupName() == "BAS" or Fk.getGroupName() == "HAUT"):
-                    indexFP = indexFacesPerio[indexFace]
-                    # another way to get the index of the periodical face #
-                    # int indexFP=my_mesh.getIndexFacePeriodic(indexFace);
-                    Fp = my_mesh.getFace(indexFP)
-                    indexCp = Fp.getCellsId()[0]
-                    if (UN > 1.E-15):
-                        conc = y_field[cellCourante]
-                        pass
-                    else:
-                        conc = y_field[indexCp]
-                        pass
-                    pass
-                pass
-            SumF = SumF + UN * LengthFk * conc
-            pass
-        dt = cfl * minlengthFk / normU
-        SumFlux[j] = dt * SumF / Cj.getMeasure()
-        pass
-    return dt, SumFlux
-
-
-def EquationTransport2D(tmax, VitesseX, VitesseY, cfl, freqSortie, my_mesh, output_filename):
-
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    y_field = initial_conditions(my_mesh)
-    #
-    # MED output of the initial condition at t=0 and iter = 0
-    #
-
-    it = 0
-    time = 0.
-    print("Saving the solution at T=" + str(time) + "…")
-    y_field.setTime(time, it)
-    y_field.writeMED(output_filename)
-    y_field.writeVTK(output_filename)
-    y_field.writeCSV(output_filename)
-
-    # Time loop #
-    print("Resolution of the transport equation with an UPWIND scheme…")
-    ntmax = 3
-    indexFacesPerio = my_mesh.getIndexFacePeriodic()
-    dt = 0.
-    while (it < ntmax and time <= tmax):
-        dt, SumFlux = sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio)
-        print("-- Iter: " + str(it) + ", Time: " + str(time) + ", dt: " + str(dt))
-
-        # Advancing one time step #
-        y_field -= SumFlux
-        time += dt
-        it += 1
-        # Output every freq times
-        if (it % freqSortie == 0):
-            y_field.setTime(time, it)
-            y_field.writeMED(output_filename, False)
-            y_field.writeVTK(output_filename, False)
-            y_field.writeCSV(output_filename)
-            pass
-        pass
-    return
-
-
-def main():
-    print("Resolution of the 2D transport equation:")
-    print("- DOMAIN: SQUARE")
-    print("- MESH: TRIANGULAR, GENERATED WITH SALOME")
-    print("- PERIODICAL BC UP AND DOWN")
-    print("- HOMOGENEOUS NEUMANN BC LEFT AND RIGHT")
-
-    # Problem data
-    cfl = 0.4
-    VitesseX = 1.0
-    VitesseY = 1.0
-    tmax = 1.
-    freqSortie = 10
-
-    print("Loading triangular mesh …")
-    my_mesh = cdmath.Mesh("../../tests/ressources/meshSquare.med")
-    output_filename = "Exercice2PyTest"
-    EquationTransport2D(tmax, VitesseX, VitesseY, cfl, freqSortie, my_mesh, output_filename)
-    print("CDMATH calculation done.")
-    return
-
-
-if __name__ == """__main__""":
-    main()
diff --git a/CDMATH/tests/examples/transport2d_ns/main2.cxx b/CDMATH/tests/examples/transport2d_ns/main2.cxx
deleted file mode 100644 (file)
index ff6845e..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-//============================================================================
-// Author      : Anouar MEKKAS
-// Version     :
-// Description : Equation de transport lineaire 2D non structure
-//============================================================================
-
-#include <iostream>
-#include <string>
-#include <cmath>
-
-#include "Mesh.hxx"
-#include "Cell.hxx"
-#include "Face.hxx"
-#include "Field.hxx"
-
-using namespace std;
-
-struct parameters {
-    double cfl;
-    double VitesseX;
-    double VitesseY;
-    int freqSortie;
-    std::string outFile;
-};
-
-void conditions_initiales(Field& yField)
-{
-    double rayon=0.15;
-    double xcentre=0.25;
-    double ycentre=0.25;
-    Mesh myMesh=yField.getMesh();
-    int nbCells=myMesh.getNumberOfCells();
-    for (int j=0 ; j<nbCells ; j++)
-    {
-        double x = myMesh.getCell(j).x() ;
-        double y = myMesh.getCell(j).y() ;
-        double valX=(x-xcentre)*(x-xcentre);
-        double valY=(y-ycentre)*(y-ycentre);
-        double val=sqrt(valX+valY);
-        if (val<rayon)
-            yField(j) = 1.0;
-        else
-            yField(j) = 0.0;
-    }
-}
-
-void sigma_flux(const parameters & p, const Field& yField, const IntTab indexFacesPerio, double& dt, Field& SumFlux)
-{
-    /* Calcul des flux */
-    Mesh myMesh=yField.getMesh();
-    int nbCells=myMesh.getNumberOfCells();
-    double normU=sqrt(p.VitesseX*p.VitesseX+p.VitesseY*p.VitesseY);
-    for (int j=0 ; j<nbCells ; j++)
-    {
-        Cell Cj=myMesh.getCell(j);
-        int nbFace=Cj.getNumberOfFaces();
-        double SumF=0.0;
-        double minlengthFk=1.E30;
-
-        int cellCourante,cellAutre;
-        for (int k=0 ; k<nbFace ; k++)
-        {
-            int indexFace=Cj.getFacesId()[k];
-            Face Fk=myMesh.getFace(indexFace);
-            double NormalX=Cj.getNormalVector(k,0);
-            double NormalY=Cj.getNormalVector(k,1);
-            double LengthFk = Fk.getMeasure();
-            double UN=p.VitesseX*NormalX+p.VitesseY*NormalY;
-
-            minlengthFk=min(minlengthFk,LengthFk/fabs(UN));
-            minlengthFk=min(minlengthFk,LengthFk/fabs(p.VitesseX));
-            minlengthFk=min(minlengthFk,LengthFk/fabs(p.VitesseY));
-
-            double conc=0.0;
-            cellCourante=j;
-            cellAutre=-1;
-
-            if (!Fk.isBorder())
-            {
-                int indexC1=Fk.getCellsId()[0];
-                int indexC2=Fk.getCellsId()[1];
-                /* hypothese: La cellule d'index indexC1 est la cellule courante index j */
-                if ( indexC1 == j )
-                {
-                    /* hypothese verifie */
-                    cellCourante=indexC1;
-                    cellAutre=indexC2;
-                } else if ( indexC2 == j )
-                {
-                    /* hypothese non verifie */
-                    cellCourante=indexC2;
-                    cellAutre=indexC1;
-                }
-                // definir la cellule gauche et droite par le prduit vitesse * normale sortante
-                // si u*n>0 : rien a faire sinon inverser la gauche et la droite
-                if (UN>1.E-15)
-                    conc=yField(cellCourante);
-                else
-                    conc=yField(cellAutre);
-            }else
-            {
-                /* conditions aux limites neumann homogene */
-                if (Fk.getGroupName().compare("GAUCHE")==0 || Fk.getGroupName().compare("DROITE")==0)
-                {
-                    if (UN>1.E-15)
-                        conc=yField(cellCourante);
-                    else
-                        conc=0.0;
-                }
-                /* conditions aux limites periodiques */
-                if (Fk.getGroupName().compare("BAS")==0 || Fk.getGroupName().compare("HAUT")==0)
-                {
-                        int indexFP=indexFacesPerio[indexFace];
-                        /* une autre manière de recuperer l'index de la face periodique */
-                        //int indexFP=M.getIndexFacePeriodic(indexFace);
-                        Face Fp=myMesh.getFace(indexFP);
-                        int indexCp=Fp.getCellsId()[0];
-                        if (UN>1.E-15)
-                            conc=yField(cellCourante);
-                        else
-                            conc=yField(indexCp);
-                }
-            }
-            SumF=SumF+UN*LengthFk*conc;
-          }
-        dt=p.cfl*minlengthFk/normU;
-        SumFlux(j)=dt*SumF/Cj.getMeasure();
-    }
-}
-
-void EquationTransport2D(int &iter, double tmin, double & tmax,
-                         const parameters & p, Field & yField)
-{
-  
-    /*
-     * MED output of the initial condition at t=0 and iter = 0
-     */
-    double time=tmin;
-    const Mesh& myMesh = yField.getMesh();
-    
-    yField.setTime(time,iter);
-    yField.writeMED(p.outFile,true);
-    yField.writeVTK(p.outFile);
-    yField.writeCSV(p.outFile);
-    /* --------------------------------------------- */
-
-    /* Time loop */
-    cout << "Resolution of the transport equation with an UPWIND scheme…" << endl;
-    int ntmax=3 + iter;
-    double dt;
-    IntTab indexFacesPerio=myMesh.getIndexFacePeriodic();
-    while (iter<ntmax && time <= tmax )
-    {
-        Field SumFlux("Fluxes sum",CELLS,myMesh,1) ;
-        sigma_flux(p,yField,indexFacesPerio,dt,SumFlux);
-        cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
-
-        /* Advancing time step */
-        yField-=SumFlux;
-
-        time+=dt;
-        iter+=1;
-        // Output every freq iterations
-        if (iter % p.freqSortie==0)
-        {
-            yField.setTime(time,iter);
-            yField.writeVTK(p.outFile,false);
-            yField.writeCSV(p.outFile);
-        }
-    }
-
-    cout << "MED post-treatment of the solution at T=" << time << endl;
-    yField.setTime(time,iter);
-    yField.writeMED(p.outFile,false);
-    yField.writeCSV(p.outFile);
-
-    tmax = time;
-    cout << "End of EquationTransport2D." << endl;
-}
-
-void compute_onepass(double tmin, double tmax, const Mesh & M, const parameters & p)
-{
-       int iter = 0;
-
-    /* Initial conditions */
-    cout << "Construction of initial condition…" << endl;
-    Field f("Y field",CELLS,M,1) ;
-    conditions_initiales(f);
-
-    EquationTransport2D(iter, tmin, tmax, p, f);
-}
-
-void compute_twopass(double tmin, double tmax, const Mesh & M, const parameters & p)
-{
-       int iter = 0;
-       parameters q(p);
-       double tstep = 0.5 * (tmin + tmax);
-
-    /* Initial conditions */
-    cout << "Construction of initial condition…" << endl;
-    Field f("Y field",CELLS,M,1) ;
-    conditions_initiales(f);
-
-       q.outFile = p.outFile + "_A";
-    EquationTransport2D(iter, tmin, tstep, q, f);
-
-    Field f2(q.outFile, CELLS, "Y field", iter, 0);
-
-       q.outFile = p.outFile + "_B";
-    EquationTransport2D(iter, tstep, tmax, q, f2);
-
-}
-
-int main()
-{
-    cout << "Resolution of the 2D transport equation:" << endl;
-    cout << "- DOMAIN: SQUARE" << endl;
-    cout << "- MESH: TRIANGULAR, GENERATED WITH SALOME" << endl;
-    cout << "- PERIODIC BC ON TOP AND BOTTOM" << endl;
-    cout << "- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT" << endl;
-
-    // donnees du probleme
-    parameters p;
-    int iter;
-
-    p.cfl=0.4;
-    p.VitesseX=1.0;
-    p.VitesseY=1.0;
-    p.freqSortie=50;
-    p.outFile="res2D";
-
-    cout << "Construction of Cartesian mesh…" << endl;
-    Mesh M("../../tests/ressources/meshSquare.med");
-
-    double tmin = 0;
-    double tmax = 0.1;
-    
-    compute_onepass(tmin, tmax, M, p);
-    compute_twopass(tmin, tmax, M, p);
-    cout << "CDMATH calculation done." << endl;
-
-    return 0;
-}
diff --git a/CDMATH/tests/examples/transport2d_ns/makefile b/CDMATH/tests/examples/transport2d_ns/makefile
deleted file mode 100644 (file)
index 331cbaf..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-# Transport2D_NS makefile
-
-CC = g++
-# Adapt the following line to your own system:
-CDMATHDIR = ../../../../..
-IFLAG = -I$(CDMATHDIR)/include -I.
-LFLAG = -L$(CDMATHDIR)/lib -L$(PETSC_DIR)/$(PETSC_ARCH)/lib
-LIBS  = -linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver -lpetsc
-
-all: main main2
-
-main: main.cxx 
-       $(CC) -g -o $@ $^ $(IFLAG) $(LFLAG) $(LIBS)
-
-main2: main2.cxx 
-       $(CC) -g -o $@ $^ $(IFLAG) $(LFLAG) $(LIBS)
-
-%.o: %.cxx
-       $(CC) -c -g -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
-
-.PHONY: clean
-
-clean:
-       rm -f main main2 *.o *~ core $(INCDIR)/*~
-
-sweep:
-       rm -f *.vtu
-       rm -f *.pvd
-       rm -f *.csv
-       rm -f Exercie2*.med
diff --git a/CDMATH/tests/examples/transport2d_s/main.cxx b/CDMATH/tests/examples/transport2d_s/main.cxx
deleted file mode 100644 (file)
index e49be9f..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-//============================================================================
-// Author      : Anouar MEKKAS
-// Version     :
-// Description : 2D linear transport equation on cartesian grid
-//============================================================================
-
-#include <iostream>
-#include <string>
-#include <cmath>
-
-#include "Mesh.hxx"
-#include "Cell.hxx"
-#include "Face.hxx"
-#include "Field.hxx"
-
-using namespace std;
-
-
-void initial_conditions(Field& yField)
-{
-    double rayon=0.15;
-    double xcentre=0.25;
-    double ycentre=0.25;
-    Mesh myMesh=yField.getMesh();
-    int nbCells=myMesh.getNumberOfCells();
-    for (int j=0 ; j<nbCells ; j++)
-    {
-        double x = myMesh.getCell(j).x() ;
-        double y = myMesh.getCell(j).y() ;
-        double valX=(x-xcentre)*(x-xcentre);
-        double valY=(y-ycentre)*(y-ycentre);
-        double val=sqrt(valX+valY);
-        if (val<rayon)
-            yField(j) = 1.0;
-        else
-            yField(j) = 0.0;
-    }
-}
-
-void sigma_flux(double VitesseX, double VitesseY, double cfl, const Field& yField, const IntTab indexFacesPerio, double& dt, Field& SumFlux)
-{
-    /* Fluxes calculation */
-    Mesh myMesh=yField.getMesh();
-    int nbCells=myMesh.getNumberOfCells();
-    double normU=sqrt(VitesseX*VitesseX+VitesseY*VitesseY);
-    for (int j=0 ; j<nbCells ; j++)
-    {
-        Cell Cj=myMesh.getCell(j);
-        int nbFace=Cj.getNumberOfFaces();
-        double SumF=0.0;
-        double minlengthFk=1.E30;
-
-        int cellCourante,cellAutre;
-        for (int k=0 ; k<nbFace ; k++)
-        {
-            int indexFace=Cj.getFacesId()[k];
-            Face Fk=myMesh.getFace(indexFace);
-            double NormalX=Cj.getNormalVector(k,0);
-            double NormalY=Cj.getNormalVector(k,1);
-            double LengthFk = Fk.getMeasure();
-            double UN=VitesseX*NormalX+VitesseY*NormalY;
-
-            minlengthFk=min(minlengthFk,LengthFk/fabs(UN));
-            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseX));
-            minlengthFk=min(minlengthFk,LengthFk/fabs(VitesseY));
-
-            double conc=0.0;
-            cellCourante=j;
-            cellAutre=-1;
-
-            if (!Fk.isBorder())
-            {
-                int indexC1=Fk.getCellsId()[0];
-                int indexC2=Fk.getCellsId()[1];
-                /* Hypothesis: the cell of index indexC1 is the current cell index j */
-                if ( indexC1 == j )
-                {
-                    /* Hypothesis verified */
-                    cellCourante=indexC1;
-                    cellAutre=indexC2;
-                } else if ( indexC2 == j )
-                {
-                    /* Hypothesis not verified */
-                    cellCourante=indexC2;
-                    cellAutre=indexC1;
-                }
-                // Define left and right cells with the product velocity * outward normal
-                // If u*n>0, then nothing to do, else invert left and right
-                if (UN>1.E-15)
-                    conc=yField(cellCourante);
-                else
-                    conc=yField(cellAutre);
-            }else
-            {
-                /* Homogeneous Neumann boundary conditions */
-                if (Fk.getGroupName().compare("LeftEdge")==0 || Fk.getGroupName().compare("RightEdge")==0)
-                {
-                    if (UN>1.E-15)
-                        conc=yField(cellCourante);
-                    else
-                        conc=0.0;
-                }
-                /* Periodic boundary conditions */
-                if (Fk.getGroupName().compare("BottomEdge")==0 || Fk.getGroupName().compare("TopEdge")==0)
-                {
-                        int indexFP=indexFacesPerio[indexFace];
-                        /* une autre manière de recuperer l'index de la face periodique */
-                        //int indexFP=myMesh.getIndexFacePeriodic(indexFace);
-                        Face Fp=myMesh.getFace(indexFP);
-                        int indexCp=Fp.getCellsId()[0];
-                        if (UN>1.E-15)
-                            conc=yField(cellCourante);
-                        else
-                            conc=yField(indexCp);
-                }
-            }
-            SumF=SumF+UN*LengthFk*conc;
-          }
-        dt=cfl*minlengthFk/normU;
-        SumFlux(j)=dt*SumF/Cj.getMeasure();
-    }
-}
-
-void EquationTransport2D(double tmax, double VitesseX, double VitesseY, double cfl, int freqSortie, const Mesh& myMesh, const string file)
-{
-    /* Initial conditions */
-    cout << "Construction of the initial condition …" << endl;
-    Field yField("Y field",CELLS,myMesh,1) ;
-    initial_conditions(yField);
-
-    /*
-     * MED output of the initial condition at t=0 and iter = 0
-     */
-    int iter=0;
-    double time=0.;
-    cout << "Saving the solution at T=" << time << "…" << endl;
-    yField.setTime(time,iter);
-    yField.writeMED(file);
-    yField.writeVTK(file);
-    yField.writeCSV(file);
-    /* --------------------------------------------- */
-
-    /* Time loop */
-    cout << "Resolution of the transport equation with an UPWIND scheme …" << endl;
-    int ntmax=3;
-    double dt;
-    IntTab indexFacesPerio=myMesh.getIndexFacePeriodic();
-    while (iter<ntmax && time <= tmax )
-    {
-        Field SumFlux("Sum Flux",CELLS,myMesh,1) ;
-        sigma_flux(VitesseX,VitesseY,cfl,yField,indexFacesPerio,dt,SumFlux);
-        cout << "-- Iter: " << iter << ", Time: " << time << ", dt: " << dt << endl;
-
-        /* Advancing time step */
-        yField-=SumFlux;
-
-        time+=dt;
-        iter+=1;
-        // Ouput every freq iterations
-        if (iter%freqSortie==0)
-        {
-            yField.setTime(time,iter);
-            yField.writeMED(file,false);
-            yField.writeVTK(file,false);
-            yField.writeCSV(file);
-        }
-    }
-}
-
-int main()
-{
-    cout << "RESOLUTION OF 2D TRANSPORT EQUATION:" << endl;
-    cout << "- DOMAIN: SQUARE" << endl;
-    cout << "- MESH: CARTESIAN, GENERATED INTERNALLY WITH CDMATH" << endl;
-    cout << "- PERIODIC BC ON TOP AND BOTTOM" << endl;
-    cout << "- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT" << endl;
-
-    // Problem data
-    double cfl=0.4;
-    double VitesseX=1.0;
-    double VitesseY=1.0;
-    double tmax=1.;
-    int freqSortie=10;
-
-    cout << "Construction of a cartesian mesh …" << endl;
-    double xinf=0.0;
-    double xsup=1.0;
-    double yinf=0.0;
-    double ysup=1.0;
-    int nx=100;
-    int ny=100;
-    Mesh myMesh(xinf,xsup,nx,yinf,ysup,ny);
-    double eps=1.E-10;
-    myMesh.setGroupAtPlan(xsup,0,eps,"RightEdge");
-    myMesh.setGroupAtPlan(xinf,0,eps,"LeftEdge");
-    myMesh.setGroupAtPlan(yinf,1,eps,"BottomEdge");
-    myMesh.setGroupAtPlan(ysup,1,eps,"TopEdge");
-    string fileOutPutCart="Exercice1";
-    EquationTransport2D(tmax,VitesseX,VitesseY,cfl,freqSortie,myMesh,fileOutPutCart);
-    cout << "CDMATH calculation done." << endl;
-    return 0;
-}
diff --git a/CDMATH/tests/examples/transport2d_s/main.py b/CDMATH/tests/examples/transport2d_s/main.py
deleted file mode 100644 (file)
index f033815..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/usr/bin/env python
-# -*-coding:utf-8 -*
-
-import math
-
-import cdmath
-
-
-def initial_conditions(my_mesh):
-    rayon = 0.15
-    xcentre = 0.25
-    ycentre = 0.25
-    y_field = cdmath.Field("Y field", cdmath.CELLS, my_mesh, 1)
-    nbCells = my_mesh.getNumberOfCells()
-    for j in range(nbCells):
-        x = my_mesh.getCell(j).x()
-        y = my_mesh.getCell(j).y()
-        valX = (x - xcentre) * (x - xcentre)
-        valY = (y - ycentre) * (y - ycentre)
-        val = math.sqrt(valX + valY)
-        if val < rayon:
-            y_field[j] = 1.0
-            pass
-        else:
-            y_field[j] = 0.0
-            pass
-        pass
-    return y_field
-
-
-def sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio):
-    # Fluxes calculation #
-    SumFlux = cdmath.Field("Fluxes", cdmath.CELLS, y_field.getMesh(), 1)
-    my_mesh = y_field.getMesh()
-    nbCells = my_mesh.getNumberOfCells()
-    normU = math.sqrt(VitesseX * VitesseX + VitesseY * VitesseY)
-    for j in range(nbCells):
-        Cj = my_mesh.getCell(j)
-        nbFace = Cj.getNumberOfFaces()
-        SumF = 0.0
-        minlengthFk = 1.E30
-        for k in range(nbFace):
-            indexFace = Cj.getFacesId()[k]
-            Fk = my_mesh.getFace(indexFace)
-            NormalX = Cj.getNormalVector(k, 0)
-            NormalY = Cj.getNormalVector(k, 1)
-            LengthFk = Fk.getMeasure()
-            UN = VitesseX * NormalX + VitesseY * NormalY
-            minlengthFk = min(minlengthFk, LengthFk / abs(UN))
-            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseX))
-            minlengthFk = min(minlengthFk, LengthFk / abs(VitesseY))
-            conc = 0.0
-            cellCourante = j
-            cellAutre = -1
-            if (not Fk.isBorder()):
-                indexC1 = Fk.getCellsId()[0]
-                indexC2 = Fk.getCellsId()[1]
-                # hypothese: La cellule d'index indexC1 est la cellule courante index j #
-                if (indexC1 == j):
-                    # hypothese verifie #
-                    cellCourante = indexC1
-                    cellAutre = indexC2
-                    pass
-                elif (indexC2 == j):
-                    # hypothese non verifie #
-                    cellCourante = indexC2
-                    cellAutre = indexC1
-                    pass
-                # definir la cellule gauche et droite par le prduit vitesse * normale sortante
-                # si u*n>0 : rien a faire sinon inverser la gauche et la droite
-                if (UN > 1.E-15):
-                    conc = y_field[cellCourante]
-                    pass
-                else:
-                    conc = y_field[cellAutre]
-                    pass
-                pass
-            else:
-                # conditions aux limites neumann homogene #
-                if (Fk.getGroupName() == "LeftEdge" or Fk.getGroupName() == "RightEdge"):
-                    if (UN > 1.E-15):
-                        conc = y_field[cellCourante]
-                        pass
-                    else:
-                        conc = 0.0
-                        pass
-                    pass
-                # conditions aux limites periodiques #
-                if (Fk.getGroupName() == "BottomEdge" or Fk.getGroupName() == "TopEdge"):
-                    indexFP = indexFacesPerio[indexFace]
-                    # une autre manière de recuperer l'index de la face periodique #
-                    # int indexFP=my_mesh.getIndexFacePeriodic(indexFace);
-                    Fp = my_mesh.getFace(indexFP)
-                    indexCp = Fp.getCellsId()[0]
-                    if (UN > 1.E-15):
-                        conc = y_field[cellCourante]
-                        pass
-                    else:
-                        conc = y_field[indexCp]
-                        pass
-                    pass
-                pass
-            SumF = SumF + UN * LengthFk * conc
-            pass
-        dt = cfl * minlengthFk / normU
-        SumFlux[j] = dt * SumF / Cj.getMeasure()
-        pass
-    return dt, SumFlux
-
-
-def EquationTransport2D(tmax, VitesseX, VitesseY, cfl, output_freq, my_mesh, file):
-
-    # Initial conditions #
-    print("Construction of the initial condition …")
-    y_field = initial_conditions(my_mesh)
-    #
-    #  MED output of the initial conditions at t=0 and iteration = 0
-    #
-
-    iteration = 0
-    time = 0.
-    print("Saving the solution at T=" + str(time) + "…")
-    y_field.setTime(time, iteration)
-    y_field.writeMED(file)
-    y_field.writeVTK(file)
-    y_field.writeCSV(file)
-
-    # Time loop #
-    print("Resolution of the transport equation with an UPWIND scheme …")
-    ntmax = 3
-    indexFacesPerio = my_mesh.getIndexFacePeriodic()
-    dt = 0.
-    while (iteration < ntmax and time <= tmax):
-        dt, SumFlux = sigma_flux(VitesseX, VitesseY, cfl, y_field, indexFacesPerio)
-        print("-- Iter: " + str(iteration) + ", Time: " + str(time) + ", dt: " + str(dt))
-
-        # Advancing time step #
-        y_field -= SumFlux
-        time += dt
-        iteration += 1
-        # Output every output_freq iterations
-        if (iteration % output_freq == 0):
-            y_field.setTime(time, iteration)
-            y_field.writeMED(file, False)
-            y_field.writeVTK(file, False)
-            y_field.writeCSV(file)
-            pass
-        pass
-    return
-
-
-def main():
-    print("RESOLUTION OF THE 2D TRANSPORT EQUATION:")
-    print("- DOMAIN: SQUARE [0,1]x[0,1]")
-    print("- MESH: CARTESIAN, INTERNAL GENERATION WITH CDMATH")
-    print("- PERIODIC BC ON TOP AND BOTTOM")
-    print("- HOMOGENEOUS NEUMANN BC ON LEFT AND RIGHT")
-
-    # Problem data
-    cfl = 0.4
-    VitesseX = 1.0
-    VitesseY = 1.0
-    tmax = 1.
-    output_freq = 10
-
-    print("Construction of a cartesian mesh …")
-    xinf = 0.0
-    xsup = 1.0
-    yinf = 0.0
-    ysup = 1.0
-    nx = 100
-    ny = 100
-    my_mesh = cdmath.Mesh(xinf, xsup, nx, yinf, ysup, ny)
-    eps = 1.E-10
-    my_mesh.setGroupAtPlan(xsup, 0, eps, "RightEdge")
-    my_mesh.setGroupAtPlan(xinf, 0, eps, "LeftEdge")
-    my_mesh.setGroupAtPlan(yinf, 1, eps, "BottomEdge")
-    my_mesh.setGroupAtPlan(ysup, 1, eps, "TopEdge")
-    fileOutPutCart = "Exercice1PyTest"
-    EquationTransport2D(tmax, VitesseX, VitesseY, cfl, output_freq, my_mesh, fileOutPutCart)
-    print("CDMATH calculation done.")
-    return
-
-
-if __name__ == """__main__""":
-    main()
diff --git a/CDMATH/tests/examples/transport2d_s/makefile b/CDMATH/tests/examples/transport2d_s/makefile
deleted file mode 100644 (file)
index 3ef2bc7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# Transport2D_S makefile
-
-CC = g++
-# Adapt the following line to your own system:
-CDMATHDIR = ../../../../..
-IFLAG = -I$(CDMATHDIR)/include -I.
-LFLAG = -L$(CDMATHDIR)/lib
-LIBS  =-linterpkernel -lmedC -lmedloader -lmedcoupling -lbase -lmesh -llinearsolver
-OBJ = main.o
-
-all: $(OBJ)
-       $(CC) -o main $^ $(IFLAG) $(LFLAG) $(LIBS)
-       
-%.o: %.cxx
-       $(CC) -c -o $@ $< $(CFLAGS) $(IFLAG) $(LFLAG) $(LIBS)
-       
-.PHONY: clean
-
-clean:
-       rm -f *.o *~ core $(INCDIR)/*~
-
-sweep:
-       rm -f *.vtu
-       rm -f *.pvd
-       rm -f *.csv
-       rm -f Exercie1*.med
index acf794c07b08a85d8a060a88f5aafd8a2708cceb..ad1b6cf6edd817e3f1f5fcb0481d906dc79270b9 100755 (executable)
@@ -1,9 +1,6 @@
-SET(MESH_MED2
-  ../ressources/
-  )
 
-file(COPY ${MESH_MED2} DESTINATION ${CMAKE_BINARY_DIR}/CDMATH/tests/ressources)
+file(COPY ${MED_MESHES} DESTINATION ${CMAKE_BINARY_DIR}/CDMATH/tests/ressources)
 
-install(DIRECTORY ${MESH_MED2} DESTINATION share/meshes)
+install(DIRECTORY ${MED_MESHES} DESTINATION share/meshes)