From 64d78f80b35fd0a81a2be641b8bba43f14239096 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:28:13 -0700 Subject: [PATCH 01/60] bug-fix GSPH reimann gradients from sametimeSPHderivs --- src/GSPH/MFMHydroBase.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/GSPH/MFMHydroBase.cc b/src/GSPH/MFMHydroBase.cc index 09e28bcfe..dd893e83f 100644 --- a/src/GSPH/MFMHydroBase.cc +++ b/src/GSPH/MFMHydroBase.cc @@ -204,7 +204,25 @@ initialize(const typename Dimension::Scalar time, const DataBase& dataBase, State& state, StateDerivatives& derivs) { + + // initialize spatial gradients so we can store them + if (this->isFirstCycle()){ + this->computeMCorrection(time,dt,dataBase,state,derivs); + } + GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); + + if (this->isFirstCycle()){ + auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); + auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + + M.Zero(); + newRiemannDpDx.Zero(); + newRiemannDvDx.Zero(); + this->isFirstCycle(false); + } + } //------------------------------------------------------------------------------ From 95998891f9ff518eb2757b79bcbae5ee2bc79feb Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:28:54 -0700 Subject: [PATCH 02/60] exposing the GSPH volume field to Python --- src/Pybind11Wraps/GSPH/GenericRiemannHydro.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Pybind11Wraps/GSPH/GenericRiemannHydro.py b/src/Pybind11Wraps/GSPH/GenericRiemannHydro.py index 68fb9f6b3..6e1f373cc 100644 --- a/src/Pybind11Wraps/GSPH/GenericRiemannHydro.py +++ b/src/Pybind11Wraps/GSPH/GenericRiemannHydro.py @@ -172,6 +172,7 @@ def enforceBoundaries(state = "State<%(Dimension)s>&", timeStepMask = PYB11property("const FieldList<%(Dimension)s, int>&", "timeStepMask", returnpolicy="reference_internal") pressure = PYB11property("const FieldList<%(Dimension)s, Scalar>&", "pressure", returnpolicy="reference_internal") + volume = PYB11property("const FieldList<%(Dimension)s, Scalar>&", "volume", returnpolicy="reference_internal") soundSpeed = PYB11property("const FieldList<%(Dimension)s, Scalar>&", "soundSpeed", returnpolicy="reference_internal") Hideal = PYB11property("const FieldList<%(Dimension)s, SymTensor>&","Hideal", returnpolicy="reference_internal") normalization = PYB11property("const FieldList<%(Dimension)s, Scalar>&", "normalization", returnpolicy="reference_internal") From 5c59b848adce77f832810dd88af21c5eb45578c7 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:30:03 -0700 Subject: [PATCH 03/60] bug-fix GSPH riemann deriv options --- src/GSPH/GSPHEvaluateDerivatives.cc | 29 ++++++++++++++++------------- src/GSPH/GSPHHydroBase.cc | 17 ++++++++++++++++- src/GSPH/MFMEvaluateDerivatives.cc | 17 +++++++++-------- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index 37445f96e..789f16aeb 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -139,7 +139,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& vi = velocity(nodeListi, i); const auto& rhoi = massDensity(nodeListi, i); const auto& voli = volume(nodeListi, i); - //const auto& epsi = specificThermalEnergy(nodeListi, i); const auto& Pi = pressure(nodeListi, i); const auto& Hi = H(nodeListi, i); const auto& ci = soundSpeed(nodeListi, i); @@ -169,7 +168,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& vj = velocity(nodeListj, j); const auto& rhoj = massDensity(nodeListj, j); const auto& volj = volume(nodeListj, j); - //const auto& epsj = specificThermalEnergy(nodeListj, j); const auto& Pj = pressure(nodeListj, j); const auto& Hj = H(nodeListj, j); const auto& cj = soundSpeed(nodeListj, j); @@ -189,7 +187,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); const auto& Mj = M(nodeListj,j); - + // Node displacement. const auto rij = ri - rj; const auto rhatij =rij.unitVector(); @@ -234,11 +232,12 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto gradVi = riemannDvDxi; auto gradVj = riemannDvDxj; if (gradType==GradientType::SPHSameTimeGradient){ - gradPi = newRiemannDpDxi; - gradPj = newRiemannDpDxj; - gradVi = newRiemannDvDxi; - gradVj = newRiemannDvDxj; + gradPi = newRiemannDpDx(nodeListi,i); + gradPj = newRiemannDpDx(nodeListj,j); + gradVi = newRiemannDvDx(nodeListi,i); + gradVj = newRiemannDvDx(nodeListj,j); } + riemannSolver.interfaceState(i, j, nodeListi, nodeListj, ri, rj, @@ -252,7 +251,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, vstar, rhostari, rhostarj); - + // get our basis function and interface area vectors //-------------------------------------------------------- psii = volj*Wi; @@ -437,8 +436,8 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, // The kernels and such. const auto& W = this->kernel(); - const auto gradType = this->gradientType(); - + const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient + or this->isFirstCycle()); // The connectivity. const auto& connectivityMap = dataBase.connectivityMap(); const auto& nodeLists = connectivityMap.nodeLists(); @@ -531,7 +530,8 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mj -= rij.dyad(gradPsij); // // based on nodal values - if (gradType == GradientType::SPHSameTimeGradient){ + if (calcSpatialGradients){ + const auto& vi = velocity(nodeListi, i); const auto& Pi = pressure(nodeListi, i); const auto& vj = velocity(nodeListj, j); @@ -546,6 +546,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, newRiemannDvDxi -= (vi-vj).dyad(gradPsii); newRiemannDvDxj -= (vi-vj).dyad(gradPsij); + } } // loop over pairs @@ -570,12 +571,14 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi = ( goodM ? Mi.Inverse() : Tensor::one); - if (gradType == GradientType::SPHSameTimeGradient){ + if (calcSpatialGradients){ + auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); newRiemannDpDxi = Mi.Transpose()*newRiemannDpDxi; newRiemannDvDxi = newRiemannDvDxi*Mi; + } } @@ -585,7 +588,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, boundItr != this->boundaryEnd(); ++boundItr)(*boundItr)->applyFieldListGhostBoundary(M); - if (gradType == GradientType::SPHSameTimeGradient){ + if (calcSpatialGradients){ for (ConstBoundaryIterator boundItr = this->boundaryBegin(); boundItr != this->boundaryEnd(); ++boundItr){ diff --git a/src/GSPH/GSPHHydroBase.cc b/src/GSPH/GSPHHydroBase.cc index f93c1c38e..03b07428a 100644 --- a/src/GSPH/GSPHHydroBase.cc +++ b/src/GSPH/GSPHHydroBase.cc @@ -225,8 +225,23 @@ initialize(const typename Dimension::Scalar time, StateDerivatives& derivs) { TIME_GSPHinitialize.start(); - GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); + // initialize spatial gradients so we can store them + if (this->isFirstCycle()){ + this->computeMCorrection(time,dt,dataBase,state,derivs); + } + + GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); + if (this->isFirstCycle()){ + auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); + auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + + M.Zero(); + newRiemannDpDx.Zero(); + newRiemannDvDx.Zero(); + this->isFirstCycle(false); + } TIME_GSPHinitialize.stop(); } diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index eba73a7aa..4440f4953 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -234,10 +234,10 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto gradVi = riemannDvDxi; auto gradVj = riemannDvDxj; if (gradType==GradientType::SPHSameTimeGradient){ - gradPi = newRiemannDpDxi; - gradPj = newRiemannDpDxj; - gradVi = newRiemannDvDxi; - gradVj = newRiemannDvDxj; + gradPi = newRiemannDpDx(nodeListi,i); + gradPj = newRiemannDpDx(nodeListj,j); + gradVi = newRiemannDvDx(nodeListi,i); + gradVj = newRiemannDvDx(nodeListj,j); } riemannSolver.interfaceState(i, j, nodeListi, nodeListj, @@ -431,9 +431,10 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, const State& state, StateDerivatives& derivatives) const { + const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient + or this->isFirstCycle()); // The kernels and such. const auto& W = this->kernel(); - const auto gradType = this->gradientType(); // The connectivity. const auto& connectivityMap = dataBase.connectivityMap(); @@ -525,7 +526,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mj -= rij.dyad(gradPsij); // // based on nodal values - if (gradType == GradientType::SPHSameTimeGradient){ + if (calcSpatialGradients){ const auto& vi = velocity(nodeListi, i); const auto& Pi = pressure(nodeListi, i); const auto& vj = velocity(nodeListj, j); @@ -564,7 +565,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi = ( goodM ? Mi.Inverse() : Tensor::one); - if (gradType == GradientType::SPHSameTimeGradient){ + if (calcSpatialGradients){ auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); @@ -579,7 +580,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, boundItr != this->boundaryEnd(); ++boundItr)(*boundItr)->applyFieldListGhostBoundary(M); - if (gradType == GradientType::SPHSameTimeGradient){ + if (calcSpatialGradients){ for (ConstBoundaryIterator boundItr = this->boundaryBegin(); boundItr != this->boundaryEnd(); ++boundItr){ From 72fbaa22167f6dd8aebbe92d5e967ab7bb5b4c31 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:31:22 -0700 Subject: [PATCH 04/60] update generic GSPH --- src/GSPH/GenericRiemannHydro.cc | 21 +++++++-------------- src/GSPH/GenericRiemannHydro.hh | 6 +++++- src/GSPH/GenericRiemannHydroInline.hh | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 803c7fbc2..15be4d909 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -97,6 +97,7 @@ GenericRiemannHydro(const SmoothingScaleBase& smoothingScaleMethod, mGradientType(gradType), mDensityUpdate(densityUpdate), mHEvolution(HUpdate), + mIsFirstCycle(true), mCompatibleEnergyEvolution(compatibleEnergyEvolution), mEvolveTotalEnergy(evolveTotalEnergy), mXSPH(XSPH), @@ -491,16 +492,6 @@ initialize(const typename Dimension::Scalar time, StateDerivatives& derivs) { auto& riemannSolver = this->riemannSolver(); - // const auto& W = this->kernel(); - - // riemannSolver.initialize(dataBase, - // state, - // derivs, - // this->boundaryBegin(), - // this->boundaryEnd(), - // time, - // dt, - // W); if(riemannSolver.linearReconstruction()){ const auto& connectivityMap = dataBase.connectivityMap(); @@ -569,7 +560,7 @@ template void GenericRiemannHydro:: applyGhostBoundaries(State& state, - StateDerivatives& /*derivs*/) { + StateDerivatives& derivs) { // Apply boundary conditions to the basic fluid state Fields. auto volume = state.fields(HydroFieldNames::volume, 0.0); auto mass = state.fields(HydroFieldNames::mass, 0.0); @@ -582,10 +573,11 @@ applyGhostBoundaries(State& state, // our store vars in the riemann solver auto DpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto DvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - + auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); boundaryItr != this->boundaryEnd(); ++boundaryItr) { + (*boundaryItr)->applyFieldListGhostBoundary(M); (*boundaryItr)->applyFieldListGhostBoundary(volume); (*boundaryItr)->applyFieldListGhostBoundary(mass); (*boundaryItr)->applyFieldListGhostBoundary(massDensity); @@ -606,7 +598,7 @@ template void GenericRiemannHydro:: enforceBoundaries(State& state, - StateDerivatives& /*derivs*/) { + StateDerivatives& derivs) { // Enforce boundary conditions on the fluid state Fields. auto volume = state.fields(HydroFieldNames::volume, 0.0); @@ -620,11 +612,12 @@ enforceBoundaries(State& state, // our store vars in the riemann solver auto DpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto DvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - + auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); boundaryItr != this->boundaryEnd(); ++boundaryItr) { + (*boundaryItr)->enforceFieldListBoundary(M); (*boundaryItr)->enforceFieldListBoundary(volume); (*boundaryItr)->enforceFieldListBoundary(mass); (*boundaryItr)->enforceFieldListBoundary(massDensity); diff --git a/src/GSPH/GenericRiemannHydro.hh b/src/GSPH/GenericRiemannHydro.hh index bd17a2718..b294fb49c 100644 --- a/src/GSPH/GenericRiemannHydro.hh +++ b/src/GSPH/GenericRiemannHydro.hh @@ -145,6 +145,9 @@ public: void HEvolution(HEvolutionType type); // setter-getters for our bool switches + bool isFirstCycle() const; + void isFirstCycle(bool val); + bool compatibleEnergyEvolution() const; void compatibleEnergyEvolution(bool val); @@ -228,7 +231,8 @@ private: MassDensityType mDensityUpdate; HEvolutionType mHEvolution; - // A bunch of switches. + // A bunch of switches. + bool mIsFirstCycle; bool mCompatibleEnergyEvolution; bool mEvolveTotalEnergy; bool mXSPH; diff --git a/src/GSPH/GenericRiemannHydroInline.hh b/src/GSPH/GenericRiemannHydroInline.hh index ab296c78f..d90581b28 100644 --- a/src/GSPH/GenericRiemannHydroInline.hh +++ b/src/GSPH/GenericRiemannHydroInline.hh @@ -264,6 +264,26 @@ HEvolution(HEvolutionType type) { mHEvolution = type; } + +//------------------------------------------------------------------------------ +// Access the trigger need to store spatial derivs on problem start up +//------------------------------------------------------------------------------ +template +inline +bool +GenericRiemannHydro::isFirstCycle() const { + return mIsFirstCycle; +} + +template +inline +void +GenericRiemannHydro::isFirstCycle(bool val) { + mIsFirstCycle = val; +} + + + //------------------------------------------------------------------------------ // Access the flag determining if we're using the compatible energy evolution // algorithm. From ca1d8b2e46087fc2b3e896beb62ade48bc938fba Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:32:07 -0700 Subject: [PATCH 05/60] adding MFM/GSPH to acoustic test --- .../Hydro/AcousticWave/AcousticWave-1d.py | 195 +++++++++++++----- 1 file changed, 143 insertions(+), 52 deletions(-) diff --git a/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py b/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py index c0b9a97e3..fcec62dbc 100644 --- a/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py +++ b/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py @@ -11,6 +11,7 @@ from SpheralTestUtilities import * import mpi import numpy as np +from DistributeNodes import distributeNodesInRange1d #import matplotlib.pyplot as plt def smooth(x,window_len=11,window='hanning'): @@ -35,44 +36,73 @@ def smooth(x,window_len=11,window='hanning'): #------------------------------------------------------------------------------- # Generic problem parameters #------------------------------------------------------------------------------- -commandLine(nx1 = 100, +commandLine(# problem geometry + nx1 = 100, x0 = 0.0, x1 = 1.0, + # problem I.C.s rho1 = 1.0, eps1 = 1.0, A = 1.0e-6, kfreq = 1.0, - cs2 = 1.0, mu = 1.0, - nPerh = 3.01, - - Cl = 1.0, - Cq = 2.0, - linearInExpansion = False, - Qlimiter = False, - epsilon2 = 1e-30, - hmin = 1.0e-10, - hmax = 0.1, - cfl = 0.25, - XSPH = False, - epsilonTensile = 0.0, - nTensile = 4, - filter = 0.0, + # Kernel properties KernelConstructor = WendlandC2Kernel, - order = 5, - + nPerh = 2.5, + HUpdate = IntegrateH, + hmin = 1.0e-10, + hmax = 0.25, + order = 3, + + #hydros (out different solvers) svph = False, crksph = False, psph = False, fsisph = False, + gsph = False, + mfm = False, + + # general hydro options solid = False, - IntegratorConstructor = CheapSynchronousRK2Integrator, + XSPH = False, + epsilonTensile = 0.0, + nTensile = 4, + filter = 0.0, + densityUpdate = IntegrateDensity, + correctVelocityGradient=True, + compatibleEnergy = True, + evolveTotalEnergy = False, + + # Default SPH options + gradhCorrection = True, + + # CRKSPH options correctionOrder = LinearOrder, + + # SVPH options + linearConsistent = False, + + # MFM/GSPH options + WaveSpeedConstructor = DavisWaveSpeed, # Davis, Einfeldt, Acoustic + LimiterConstructor = VanLeerLimiter, # VanLeer, Opsre, MinMod, VanAlba, Superbee + riemannLinearReconstruction = True, # True - second order, False - first order + riemannGradientType = HydroAccelerationGradient, # HydroAccelerationGradient, SPHGradient, RiemannGradient, MixedMethodGradient, SPHSameTimeGradient + + # Artificial Viscosity + Cl = 1.0, + Cq = 1.0, + linearInExpansion = False, + Qlimiter = False, + epsilon2 = 1e-30, + + # integrator options + IntegratorConstructor = VerletIntegrator,#CheapSynchronousRK2Integrator, + cfl = 0.25, steps = None, - goalTime = 5.0, + goalTime = 1.0, dt = 1.0e-10, dtMin = 1.0e-10, dtMax = 0.1, @@ -82,21 +112,17 @@ def smooth(x,window_len=11,window='hanning'): maxSteps = None, statsStep = 1, smoothIters = 0, - HUpdate = IntegrateH, - densityUpdate = RigorousSumDensity, - compatibleEnergy = True, - gradhCorrection = True, - linearConsistent = False, - + + # outputs restoreCycle = None, restartStep = 10000, clearDirectories = True, dataDirBase = "dumps-planar-AcousticWave-1d", outputFile = "AcousticWave-planar-1d.gnu", - normOutputFile = "Limited_asciiDump.dat", + normOutputFile = "_cfl2_asciiDump.dat", writeOutputLabel = True, - graphics = "gnu", + graphics = False,#"gnu", checkReversibility = False, ) @@ -109,9 +135,28 @@ def smooth(x,window_len=11,window='hanning'): hydroname = "PSPH" elif fsisph: hydroname = "FSISPH" +elif mfm: + hydroname = "MFM" +elif gsph: + hydroname = "GSPH" else: hydroname = "SPH" + +normOutputFile = str(riemannGradientType)+"_"+normOutputFile +if LimiterConstructor==VanLeerLimiter: + normOutputFile = "vanLeer_"+normOutputFile +elif LimiterConstructor==VanAlbaLimiter: + normOutputFile = "vanalba_"+normOutputFile +elif LimiterConstructor==OspreLimiter: + normOutputFile = "opsre_"+normOutputFile +elif LimiterConstructor==MinModLimiter: + normOutputFile = "MinMod_"+normOutputFile +elif LimiterConstructor==SuperbeeLimiter: + normOutputFile = "Superbee_"+normOutputFile +normOutputFile = str(densityUpdate)+"_"+normOutputFile normOutputFile = hydroname+"_"+normOutputFile + +print normOutputFile dataDir = os.path.join(dataDirBase, hydroname, "nx=%i" % nx1) @@ -137,9 +182,9 @@ def smooth(x,window_len=11,window='hanning'): # Interpolation kernels. #------------------------------------------------------------------------------- if KernelConstructor==NBSplineKernel: - WT = TableKernel(NBSplineKernel(order), 10000) + WT = TableKernel(NBSplineKernel(order), 100000) else: - WT = TableKernel(KernelConstructor(), 10000) + WT = TableKernel(KernelConstructor(), 100000) output("WT") kernelExtent = WT.kernelExtent output("WT") @@ -164,7 +209,6 @@ def smooth(x,window_len=11,window='hanning'): #------------------------------------------------------------------------------- # Set the node properties. #------------------------------------------------------------------------------- -from DistributeNodes import distributeNodesInRange1d distributeNodesInRange1d([(nodes1, nx1, rho1, (x0, x1))], nPerh = nPerh) nNodesThisDomain1 = nodes1.numInternalNodes @@ -209,8 +253,8 @@ def __call__(self, x): for i in xrange(nodes1.numInternalNodes): func0 = MassFunctor(max(0.0, Mi[i] - mi)) func1 = MassFunctor(Mi[i]) - xi0 = newtonRaphsonFindRoot(func0, xi, xi + 2.0*dx, 1.0e-18, 1.0e-18) - xi1 = newtonRaphsonFindRoot(func1, xi, xi + 2.0*dx, 1.0e-18, 1.0e-18) + xi0 = newtonRaphsonFindRoot(func0, xi, xi + 2.0*dx, 1.0e-35, 1.0e-35) + xi1 = newtonRaphsonFindRoot(func1, xi, xi + 2.0*dx, 1.0e-35, 1.0e-35) rhoi0 = rho1*(1.0 + A*sin(twopi*kfreq*(xi0 - x0)/(x1 - x0))) rhoi1 = rho1*(1.0 + A*sin(twopi*kfreq*(xi1 - x0)/(x1 - x0))) xi = x0 + (x1 - x0)*(rhoi0*xi0 + rhoi1*xi1)/(rhoi0 + rhoi1) @@ -218,6 +262,8 @@ def __call__(self, x): vel[i].x = A*cs*sin(twopi*kfreq*(xi - x0)/(x1 - x0)) rho[i] = rho1*(1.0 + A*sin(twopi*kfreq*(xi - x0)/(x1 - x0))) mass[i] = rho1*((xi1 - xi0) - A/(twopi*kfreq)*(cos(twopi*kfreq*xi1) - cos(twopi*kfreq*xi0))) + print A/(twopi*kfreq)*(cos(twopi*kfreq*xi1) - cos(twopi*kfreq*xi0)) + print("%3.16e" % mass[i]) H[i] *= rho[i]/rho1 # xi0 = 0.0 # dx0 = (x1 - x0)/nx1 @@ -240,7 +286,11 @@ def __call__(self, x): print "Compute analytic rho scaling of %16.12e." % rhoscale for i in xrange(nodes1.numInternalNodes): mass[i] *= rhoscale - + #print 1.0-rhoscale + #print rho[i] + #print mass[i] +#print(mass.max()) +#print(mass.min()) #------------------------------------------------------------------------------- # Construct a DataBase to hold our node list #------------------------------------------------------------------------------- @@ -283,21 +333,60 @@ def __call__(self, x): HUpdate = HUpdate, XSPH = XSPH) elif fsisph: + if densityUpdate == RigorousSumDensity: + sumDensityNodeLists = [nodes1] + else: + sumDensityNodeLists = [] hydro = FSISPH(dataBase = db, W = WT, cfl = cfl, - sumDensityNodeLists = [nodes1], + sumDensityNodeLists = sumDensityNodeLists, compatibleEnergyEvolution = compatibleEnergy, epsTensile = epsilonTensile) +elif gsph: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + hydro = GSPH(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + gradientType = riemannGradientType, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient=correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = XSPH, + densityUpdate=densityUpdate, + HUpdate = IdealH, + epsTensile = epsilonTensile, + nTensile = nTensile) +elif mfm: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + hydro = MFM(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + gradientType = riemannGradientType, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient=correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = XSPH, + densityUpdate=densityUpdate, + HUpdate = IdealH, + epsTensile = epsilonTensile, + nTensile = nTensile) else: + Q = MonaghanGingoldViscosity(Cl,Cq,linearInExpansion) hydro = SPH(dataBase = db, - #Q=MonaghanGingoldViscosity(Cl,Cq), + Q = Q, W = WT, cfl = cfl, compatibleEnergyEvolution = compatibleEnergy, gradhCorrection = gradhCorrection, XSPH = XSPH, - correctVelocityGradient=False, + correctVelocityGradient=correctVelocityGradient, densityUpdate = densityUpdate, HUpdate = HUpdate, epsTensile = epsilonTensile, @@ -307,16 +396,17 @@ def __call__(self, x): #------------------------------------------------------------------------------- # Construct the artificial viscosity. #------------------------------------------------------------------------------- -q = hydro.Q -q.Cl = Cl -q.Cq = Cq -q.epsilon2 = epsilon2 -q.limiter = Qlimiter -output("q") -output("q.Cl") -output("q.Cq") -output("q.epsilon2") -output("q.limiter") +if not (mfm or gsph): + q = hydro.Q + q.Cl = Cl + q.Cq = Cq + q.epsilon2 = epsilon2 + q.limiter = Qlimiter + output("q") + output("q.Cl") + output("q.Cq") + output("q.epsilon2") + output("q.limiter") #------------------------------------------------------------------------------- # Create boundary conditions. @@ -382,6 +472,7 @@ def printTotalEnergy(cycle,time,dt): control = SpheralController(integrator, WT, statsStep = statsStep, restartStep = restartStep, + vizTime=1.0, restartBaseName = restartBaseName, restoreCycle = restoreCycle, periodicWork=[(printTotalEnergy,1)]) @@ -517,10 +608,10 @@ def printTotalEnergy(cycle,time,dt): ("h ", hprof, hans)]: assert len(data) == len(ans) error = [data[i] - ans[i] for i in xrange(len(data))] - Pn = Pnorm.Pnorm(error, xprof) - L1 = Pn.gridpnorm(1, xmin, xmax) - L2 = Pn.gridpnorm(2, xmin, xmax) - Linf = Pn.gridpnorm("inf", xmin, xmax) + #Pn = Pnorm.Pnorm(error, xprof) + L1 = sum([abs(data[i] - ans[i]) for i in range(len(data))])/len(data)#Pn.pnorm(1, xmin, xmax) + L2 = (sum([abs(data[i] - ans[i])**2.0 for i in range(len(data))]))**(1.0/2.0)/len(data) + Linf = (sum([abs(data[i] - ans[i])**100.0 for i in range(len(data))]))**(1.0/100.0)/len(data) print "\t%s \t\t%g \t\t%g \t\t%g" % (name, L1, L2, Linf) if normOutputFile != "None": f.write((3*"%16.12e ") % (L1, L2, Linf)) @@ -547,7 +638,7 @@ def printTotalEnergy(cycle,time,dt): # pickle.dump(data,f) -if compatibleEnergy and abs(Eerror) > 1e-5: +if compatibleEnergy and abs(Eerror) > 1e-4: raise ValueError, "Energy error outside allowed bounds." From cef562e2ff07c4774a84fb0e4a97f0a822187e07 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:32:47 -0700 Subject: [PATCH 06/60] updating Llyods algo --- .../Hydro/YeeVortex/LlyodsAlgorithm.py | 89 ++++++++ tests/functional/Hydro/YeeVortex/YeeVortex.py | 200 ++++++++++++++---- 2 files changed, 248 insertions(+), 41 deletions(-) create mode 100755 tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py diff --git a/tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py b/tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py new file mode 100755 index 000000000..7b282545e --- /dev/null +++ b/tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py @@ -0,0 +1,89 @@ +import mpi +from Spheral import computeVoronoiVolume, HydroFieldNames + +def LlyodsAlgorithm(db,hydro,inDomain,rhoAtmo,nPerh,nRelaxIters): +#=============================================================================== +# inputs: +# db ---------- database containing nodeLists for mass correction +# hydro ------- hydro obj used to access the boundary conditions +# inDomain ---- logic function returns true if point is inside domain false otherwise +# rhoAtmo ----- function specifying the density profile +# nPerh ------- nodes per smoothing length (implementation hack) +# nRelaxIters - number of centroidal relaxation steps (0 for simple voronoi volume correction) +#=============================================================================== + + # multiplication factor for centroid relaxation delta + assert db.nDim in (2,3) + + # geometry specific functions + exec('from Spheral{0}d import SymTensor, IntFieldList, Vector, vector_of_Vector, FacetedVolumeFieldList, vector_of_CellFaceFlagFieldList, vector_of_FacetedVolume, vector_of_Boundary, ScalarFieldList, SymTensorFieldList, vector_of_vector_of_FacetedVolume, vector_of_FacetedVolume'.format(db.nDim)) + + # Fields we need to create for the voronoi volumme calculation function + faceted_bounds = vector_of_FacetedVolume() + bounds = vector_of_Boundary() # Bounds enforced by inDomain function + weight = ScalarFieldList() # No weights + damage = SymTensorFieldList() # No damage + holes = vector_of_vector_of_FacetedVolume([vector_of_FacetedVolume()]) + surfacePoint = IntFieldList() # db.newFluidIntFieldList(0, HydroFieldNames.surfacePoint) + vol = db.newFluidScalarFieldList(0.0, HydroFieldNames.volume) + deltaMedian = db.newFluidVectorFieldList(Vector.zero, "centroidal delta") + etaVoidPoints = db.newFluidvector_of_VectorFieldList(vector_of_Vector(), "eta void points") + cells = FacetedVolumeFieldList()#db.newFluidFacetedVolumeFieldList(FacetedVolume(), "cells") + cellFaceFlags = vector_of_CellFaceFlagFieldList()#db.newFluidvector_of_CellFaceFlagFieldList(vector_of_int(), "face flags") + + + + # get the bcs from hydro and add in parallel domain bcs if appropriate + bcs = hydro.boundaryConditions() + + # loop through nodeLists and zero out nPerh to + # circumvent computeVoronoiVolumes void point feature + fluidNodeLists = db.fluidNodeLists() + #for nodes in fluidNodeLists: + + print(db.numFluidNodeLists,db.numSolidNodeLists) + for j in range(nRelaxIters): # centroidal relax n times + print('centroidal relaxation: iteration {0}'.format(j)) + + # centroidal relaxation + #print(' relax...') + for k in range(db.numFluidNodeLists): + for i in range(fluidNodeLists[k].numInternalNodes): + if inDomain(db.fluidPosition(k,i)): # I used this to handle constant BC + db.fluidPosition[k][i] = db.fluidPosition(k,i)+deltaMedian(k,i) # move to centroid + + for nodes in fluidNodeLists: + nodes.numGhostNodes=0 + + #print(' bcs...') + for bc in bcs: + bc.setAllGhostNodes(db) # generate all the ghost nodes + bc.finalizeGhostBoundary() # hit the finalize for bcs that need that + + #print(' connectivity...') + db.reinitializeNeighbors() # update neighbors + db.updateConnectivityMap(False,False) # update connectivity + #(False,False) + # 1) dont compute connectivity for ghosts + # 2) dont compute overlap connectivity + + #print(' volume...') + computeVoronoiVolume(db.fluidPosition, + db.fluidHfield, + db.connectivityMap(), + damage, # believe this is inactive? + faceted_bounds, # specify domain extent + holes, # polygonal/polyhedral holes in region + bounds, # boundaries + weight, # weighting function + surfacePoint, # between substances + vol, # those volumes we want + deltaMedian, # distance from centroid + etaVoidPoints, # void nodes + cells, # polygon/polyhedron object + cellFaceFlags) + for k in range(db.numFluidNodeLists): + fluidNodeLists[k].nodesPerSmoothingScale = nPerh + + + \ No newline at end of file diff --git a/tests/functional/Hydro/YeeVortex/YeeVortex.py b/tests/functional/Hydro/YeeVortex/YeeVortex.py index c8e695a9a..cfc2c4c39 100644 --- a/tests/functional/Hydro/YeeVortex/YeeVortex.py +++ b/tests/functional/Hydro/YeeVortex/YeeVortex.py @@ -5,7 +5,7 @@ #------------------------------------------------------------------------------- # The Yee-Vortex Test #------------------------------------------------------------------------------- -import shutil +import shutil, os, sys, mpi from math import * from Spheral2d import * from SpheralTestUtilities import * @@ -13,9 +13,8 @@ from findLastRestart import * from GenerateNodeDistribution2d import * from CubicNodeGenerator import GenerateSquareNodeDistribution -from CentroidalVoronoiRelaxation import * - -import mpi +from CentroidalVoronoiRelaxation import * +from LlyodsAlgorithm import LlyodsAlgorithm import DistributeNodes class YeeDensity: @@ -63,26 +62,62 @@ def __call__(self, r): #Vortex strength beta = 5.0, + #Tempurature at inf temp_inf = 1.0, # Resolution and node seeding. nRadial = 64, seed = "constantDTheta", + numLlyodIters = 10, + # kernel options + KernelConstructor = NBSplineKernel, nPerh = 1.51, + order = 5, + hmin = 1e-5, + hmax = 0.5, + hminratio = 0.1, + # hydros svph = False, crksph = False, fsisph = False, psph = False, + gsph = False, + mfm = False, + + # general hydro options asph = False, solid = False, + XSPH = False, + epsilonTensile = 0.0, + nTensile = 8, + densityUpdate = IntegrateDensity, # VolumeScaledDensity, + compatibleEnergy = True, + evolveTotalEnergy = False, + correctVelocityGradient = True, + + # default SPH options + gradhCorrection = True, + + # CRKSPH options filter = 0.0, # For CRKSPH - KernelConstructor = NBSplineKernel, - order = 5, - Qconstructor = MonaghanGingoldViscosity, - #Qconstructor = TensorMonaghanGingoldViscosity, + + # PSPH options + HopkinsConductivity = False, + XPSH=False, + + # MFM/GSPH options + WaveSpeedConstructor = DavisWaveSpeed, # Einfeldt, Acoustic + LimiterConstructor = VanLeerLimiter, # VanLeer, Opsre, MinMod, VanAlba, Superbee + riemannLinearReconstruction = True, + riemannGradientType = SPHSameTimeGradient, # HydroAccelerationGradient, SPHGradient, RiemannGradient, MixedMethodGradient, SPHSameTimeGradient + + # artificial viscosity + Qconstructor = LimitedMonaghanGingoldViscosity, # TensorMonaghanGingoldViscosity, + Cl = 0.0, + Cq = 0.0, boolReduceViscosity = False, nhQ = 5.0, nhL = 10.0, @@ -99,25 +134,18 @@ def __call__(self, r): linearConsistent = False, fcentroidal = 0.0, fcellPressure = 0.0, - Cl = 1.0, - Cq = 0.75, linearInExpansion = False, Qlimiter = False, balsaraCorrection = False, epsilon2 = 1e-2, - hmin = 1e-5, - hmax = 0.5, - hminratio = 0.1, - cfl = 0.5, - XSPH = False, - epsilonTensile = 0.0, - nTensile = 8, - - IntegratorConstructor = CheapSynchronousRK2Integrator, + + # integrator + IntegratorConstructor = VerletIntegrator, + cfl = 0.25, goalTime = 8.0, steps = None, - vizCycle = 20, - vizTime = 0.1, + vizCycle = None, + vizTime = 2.0, dt = 0.0001, dtMin = 1.0e-5, dtMax = 1.0, @@ -128,23 +156,17 @@ def __call__(self, r): domainIndependent = False, rigorousBoundaries = False, dtverbose = False, - - densityUpdate = RigorousSumDensity, # VolumeScaledDensity, - compatibleEnergy = True, - gradhCorrection = True, - HopkinsConductivity = False, # For PSPH - correctVelocityGradient = True, - evolveTotalEnergy = False, - XPSH=False, - + + # output useVoronoiOutput = False, clearDirectories = False, restoreCycle = -1, restartStep = 200, dataDir = "dumps-yeevortex-xy", graphics = True, - smooth = None, - outputFile = "None", + smooth = False, + outputFileBase = ".out", + convergenceFileBase = "converge.txt", ) assert not(boolReduceViscosity and boolCullenViscosity) @@ -159,7 +181,12 @@ def __call__(self, r): elif psph: hydroname = "PSPH" elif fsisph: + Qconstructor = LimitedMonaghanGingoldViscosity hydroname = "FSISPH" +elif mfm: + hydroname = "MFM" +elif gsph: + hydroname = "GSPH" else: hydroname = "SPH" if asph: @@ -167,6 +194,13 @@ def __call__(self, r): if solid: hydroname = "solid"+hydroname + +if mfm or gsph: + convergenceFile = hydroname + "_" + str(densityUpdate) + "_" + str(riemannGradientType) + "_" + convergenceFileBase + outputFile = hydroname + "_" + str(densityUpdate) + "_" + str(riemannGradientType) + "_" + str(nRadial) + ".out" +else: + convergenceFile = hydroname+"_"+str(densityUpdate) + "_" + convergenceFileBase + outputFile = hydroname + "_" + str(densityUpdate) + "_" + str(nRadial) + ".out" #------------------------------------------------------------------------------- # Build our directory paths. #------------------------------------------------------------------------------- @@ -199,7 +233,6 @@ def __call__(self, r): #------------------------------------------------------------------------------- # Check if the necessary output directories exist. If not, create them. #------------------------------------------------------------------------------- -import os, sys if mpi.rank == 0: if clearDirectories and os.path.exists(baseDir): shutil.rmtree(baseDir) @@ -216,7 +249,7 @@ def __call__(self, r): K = 1.0 eos = GammaLawGasMKS(gamma, mu) #eos = PolytropicEquationOfStateMKS(K,gamma,mu) - +YeeDensityFunc = YeeDensity(xc,yc,gamma,beta,temp_inf) #------------------------------------------------------------------------------- # Interpolation kernels. #------------------------------------------------------------------------------- @@ -253,7 +286,7 @@ def __call__(self, r): nr1 = nRadial + nbcrind if seed == "lattice": generator = GenerateNodeDistribution2d(2*nr1, 2*nr1, - rho = YeeDensity(xc,yc,gamma,beta,temp_inf), + rho = YeeDensityFunc, distributionType = seed, xmin = (-rmaxbound, -rmaxbound), xmax = (rmaxbound, rmaxbound), @@ -264,7 +297,7 @@ def __call__(self, r): SPH = SPH) else: generator = GenerateNodeDistribution2d(nr1, nr1, - rho = YeeDensity(xc,yc,gamma,beta,temp_inf), + rho = YeeDensityFunc, distributionType = seed, xmin = (-rmaxbound, -rmaxbound), xmax = (rmaxbound, rmaxbound), @@ -358,10 +391,15 @@ def __call__(self, r): densityUpdate = densityUpdate, HUpdate = HUpdate) elif fsisph: + if densityUpdate==RigorousSumDensity: + sumDensityNodeLists = [nodes] + else: + sumDensityNodeLists = [] hydro = FSISPH(dataBase = db, Q=q, W = WT, - cfl = cfl, + cfl = cfl, + sumDensityNodeLists = sumDensityNodeLists, densityStabilizationCoefficient = 0.1, specificThermalEnergyDiffusionCoefficient = 0.1, correctVelocityGradient = correctVelocityGradient, @@ -370,6 +408,40 @@ def __call__(self, r): ASPH = asph, epsTensile = epsilonTensile, nTensile = nTensile) +elif gsph: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + hydro = GSPH(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + gradientType = riemannGradientType, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient=correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = XSPH, + densityUpdate=densityUpdate, + HUpdate = IdealH, + epsTensile = epsilonTensile, + nTensile = nTensile) +elif mfm: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + hydro = MFM(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + gradientType = riemannGradientType, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient=correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = XSPH, + densityUpdate=densityUpdate, + HUpdate = IdealH, + epsTensile = epsilonTensile, + nTensile = nTensile) elif psph: hydro = PSPH(dataBase=db, W=WT, @@ -492,20 +564,58 @@ def __call__(self, r): # vizMethod = SpheralVoronoiSiloDump.dumpPhysicsState # else: # vizMethod = None # default +from SpheralPointmeshSiloDump import dumpPhysicsState + control = SpheralController(integrator, WT, initializeDerivatives = True, statsStep = statsStep, restartStep = restartStep, restartBaseName = restartBaseName, restoreCycle = restoreCycle, - #vizMethod = vizMethod, + #vizMethod = dumpPhysicsState, + #vizGhosts=True, vizBaseName = vizBaseName, + vizDerivs=True, vizDir = vizDir, vizStep = vizCycle, vizTime = vizTime, skipInitialPeriodicWork = svph) output("control") +if numLlyodIters>0: + + def inDomain(pos): + if pos.magnitude() < rmax: + return True + else: + return False + + LlyodsAlgorithm(db,hydro,inDomain,YeeDensity(xc,yc,gamma,beta,temp_inf),nPerh,numLlyodIters) + + vel = nodes.velocity() + eps = nodes.specificThermalEnergy() + pos = nodes.positions() + rho = nodes.massDensity() + mass = nodes.mass() + vol = hydro.volume[0] + VolTot=0.0 + for i in xrange(nodes.numInternalNodes): + VolTot += vol[i] + VolTot = mpi.allreduce(VolTot,mpi.SUM) + numTotal = mpi.allreduce(nodes.numInternalNodes,mpi.SUM) + volNominal = VolTot/numTotal + + for i in xrange(nodes.numInternalNodes): + xi, yi = pos[i] + xci = (xi-xc) + yci = (yi-yc) + r2=xci*xci+yci*yci + velx = vel_infx-yci*exp((1.0-r2)*0.5)*beta/(2.0*pi) + vely = vel_infy+xci*exp((1.0-r2)*0.5)*beta/(2.0*pi) + rho[i] = YeeDensityFunc(pos[i]) + mass[i] = rho[i]*vol[i] + vel[i] = Vector(velx,vely) + eps[i] = pow(rho[i],(gamma-1.0))/(gamma-1.0) #------------------------------------------------------------------------------- # Advance to the end time. #------------------------------------------------------------------------------- @@ -521,7 +631,7 @@ def __call__(self, r): # If requested, write out the state in a global ordering to a file. #------------------------------------------------------------------------------- if outputFile != "None": - outputFile = os.path.join(baseDir, outputFile) + #outputFile = os.path.join(baseDir, outputFile) from SpheralGnuPlotUtilities import multiSort P = ScalarField("pressure", nodes) nodes.pressure(P) @@ -540,6 +650,7 @@ def __call__(self, r): if mpi.rank == 0: import numpy as np from Pnorm import Pnorm + rprof = np.array([sqrt(xi*xi + yi*yi) for xi, yi in zip(xprof, yprof)]) multiSort(rprof, mo, xprof, yprof, rhoprof, Pprof, vprof, epsprof, hprof,velx,vely) epsans = [] @@ -560,9 +671,13 @@ def __call__(self, r): rhoans.append(rhoi) velans.append(Vector(velxans,velyans).magnitude()) Pans.append(temp*rhoi) + L1rho2 =sum([abs(rhoprof[i]-rhoans[i]) for i in range(len(rhoans))])/len(rhoans) + Linfrho2 =max([abs(rhoprof[i]-rhoans[i]) for i in range(len(rhoans))])/len(rhoans) L1rho = Pnorm(rhoprof, rprof, rhoans).pnorm(1, rmin=0.0, rmax=rmaxnorm) + print (L1rho2,L1rho) L2rho = Pnorm(rhoprof, rprof, rhoans).pnorm(2, rmin=0.0, rmax=rmaxnorm) Linfrho = Pnorm(rhoprof, rprof, rhoans).pnorm("inf", rmin=0.0, rmax=rmaxnorm) + print (Linfrho2,Linfrho) L1eps = Pnorm(epsprof, rprof, epsans).pnorm(1, rmin=0.0, rmax=rmaxnorm) L2eps = Pnorm(epsprof, rprof, epsans).pnorm(2, rmin=0.0, rmax=rmaxnorm) Linfeps = Pnorm(epsprof, rprof, epsans).pnorm("inf", rmin=0.0, rmax=rmaxnorm) @@ -572,8 +687,11 @@ def __call__(self, r): L1P = Pnorm(Pprof, rprof, Pans).pnorm(1, rmin=0.0, rmax=rmaxnorm) L2P = Pnorm(Pprof, rprof, Pans).pnorm(2, rmin=0.0, rmax=rmaxnorm) LinfP = Pnorm(Pprof, rprof, velans).pnorm("inf", rmin=0.0, rmax=rmaxnorm) - with open("converge-CRK-%s-cullen-%s-PSPH-%s.txt" % (CRKSPH,boolCullenViscosity,PSPH), "a") as myfile: - myfile.write(("#" + 14*"%16s\t " + "%16s\n") % ("nRadial", "L1rho", "L1eps", "L1vel", "L2rho", "L2eps", "L2vel", "Linfrho", "Linfeps", "Linfvel", "L1P", "L2P", "LinfP", "cycles", "runtime")) + + isNewFile = not os.path.exists(convergenceFile) + with open(convergenceFile, "a") as myfile: + if isNewFile: + myfile.write(("#" + 14*"%16s\t " + "%16s\n") % ("nRadial", "L1rho", "L1eps", "L1vel", "L2rho", "L2eps", "L2vel", "Linfrho", "Linfeps", "Linfvel", "L1P", "L2P", "LinfP", "cycles", "runtime")) myfile.write((14*"%16s\t " + "%16s\n") % (nRadial, L1rho, L1eps, L1vel, L2rho, L2eps, L2vel, Linfrho, Linfeps, Linfvel, L1P, L2P, LinfP, control.totalSteps, control.stepTimer.elapsedTime)) f = open(outputFile, "w") f.write(("# " + 19*"%15s " + "\n") % ("r", "x", "y", "rho", "P", "v", "eps", "h", "mortonOrder", "rhoans", "epsans", "velans", From 4071db67587aa9b878bbc642e5e24bfc292441bf Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:33:24 -0700 Subject: [PATCH 07/60] updating RT tests --- .../functional/Hydro/RayleighTaylor/RT-2d.py | 435 ++++++++++++------ .../Hydro/RayleighTaylor/RT-2d_Hopkins.py | 346 ++++++++------ 2 files changed, 496 insertions(+), 285 deletions(-) diff --git a/tests/functional/Hydro/RayleighTaylor/RT-2d.py b/tests/functional/Hydro/RayleighTaylor/RT-2d.py index 36c7cbc0a..f39ed9523 100644 --- a/tests/functional/Hydro/RayleighTaylor/RT-2d.py +++ b/tests/functional/Hydro/RayleighTaylor/RT-2d.py @@ -1,7 +1,7 @@ #------------------------------------------------------------------------------- # This is the basic Rayleigh-Taylor Problem #------------------------------------------------------------------------------- -import shutil +import shutil, os, sys, mpi from math import * from Spheral2d import * from SpheralTestUtilities import * @@ -10,13 +10,16 @@ from GenerateNodeDistribution2d import * from CompositeNodeDistribution import * from CentroidalVoronoiRelaxation import * +from HydrostaticReflectingBoundary import HydrostaticReflectingBoundary2d as HydrostaticReflectingBoundary -import mpi -import DistributeNodes +if mpi.procs > 1: + from PeanoHilbertDistributeNodes import distributeNodes2d +else: + from DistributeNodes import distributeNodes2d title("Rayleigh-Taylor test problem in 2D") -class ExponentialDensity: +class ExponentialProfile: def __init__(self, y1, rho0, @@ -26,6 +29,8 @@ def __init__(self, self.alpha = alpha return def __call__(self, r): + #if r.y > 1.0: + # print self.rho0*exp(self.alpha*(r.y - self.y1)) return self.rho0*exp(self.alpha*(r.y - self.y1)) #------------------------------------------------------------------------------- @@ -35,6 +40,9 @@ def __call__(self, r): ny1 = 100, nx2 = 100, ny2 = 100, + refineFactor = 1, + nybound = 8, # number of layers in const node bc + rho0 = 1.0, eps0 = 1.0, x0 = 0.0, @@ -47,53 +55,94 @@ def __call__(self, r): vx1 = 0.0, vx2 = 0.0, freq = 1.0, - alpha = 0.01, # amplitude of displacement + alpha = 0.0025, # amplitude of displacement beta = 5.0, # speed at which displacement decays away from midline - S = 3.0, # density jump at surface - g0 = -2.0, - w0 = 0.1, + S = 10.0, # density jump at surface + g0 = -0.5, + w0 = 0.005, sigma = 0.05/sqrt(2.0), gamma = 5.0/3.0, mu = 1.0, - nPerh = 1.51, + useHydrostaticBoundary = True, + + # kernel options + HUpdate = IdealH, + KernelConstructor = WendlandC2Kernel, + order = 3, + nPerh = 3.0, + hmin = 0.0001, + hmax = 0.5, + hminratio = 0.1, + + # hydro type + svph = False, + crksph = False, + psph = False, + fsisph = False, + gsph = False, + mfm = False, + + # hydro options + asph = False, + xsph = False, + solid = False, + filter = 0.0, + densityUpdate = IntegrateDensity, + compatibleEnergy = True, + evolveTotalEnergy = False, + useVelocityMagnitudeForDt = False, + correctVelocityGradient = False, + epsilonTensile = 0.0, + nTensile = 8, + + # SPH/PSPH options + gradhCorrection = False, - SVPH = False, - CRKSPH = False, - ASPH = False, - SPH = True, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. - filter = 0.0, # CRKSPH filtering - Qconstructor = MonaghanGingoldViscosity, - #Qconstructor = TensorMonaghanGingoldViscosity, - linearConsistent = False, + # svph options fcentroidal = 0.0, fcellPressure = 0.0, - boolReduceViscosity = False, - nh = 5.0, - aMin = 0.1, - aMax = 2.0, - Qhmult = 1.0, + linearConsistent = False, + + # FSISPH parameters + fsiSurfaceCoefficient = 0.00, # adds additional repulsive force to material interfaces) + fsiRhoStabilizeCoeff = 0.1, # coefficient that smooths the density field + fsiEpsDiffuseCoeff = 0.1, # explicit diiffusion of the thermal energy + fsiXSPHCoeff = 0.00, # fsi uses multiplier for XSPH instead of binary switch + fsiInterfaceMethod = ModulusInterface, # (HLLCInterface, ModulusInterface) + fsiKernelMethod = NeverAverageKernels, # (NeverAverageKernels, AlwaysAverageKernels, AverageInterfaceKernels) + + # GSPH/MFM parameters + gsphEpsDiffuseCoeff = 0.0, + gsphLinearCorrect = True, + LimiterConstructor = VanLeerLimiter, + WaveSpeedConstructor = DavisWaveSpeed, + + # artificial viscosity options + Qconstructor = LimitedMonaghanGingoldViscosity, Cl = 1.0, Cq = 1.0, linearInExpansion = False, Qlimiter = False, balsaraCorrection = False, epsilon2 = 1e-2, - hmin = 0.0001, - hmax = 0.5, - hminratio = 0.1, - cfl = 0.5, - useVelocityMagnitudeForDt = False, - XSPH = False, - epsilonTensile = 0.0, - nTensile = 8, + + boolReduceViscosity = False, + nh = 5.0, + aMin = 0.1, + aMax = 2.0, + Qhmult = 1.0, + # artificial conduction options + bArtificialConduction = False, + arCondAlpha = 0.5, + + # integrator & options IntegratorConstructor = CheapSynchronousRK2Integrator, + cfl = 0.25, goalTime = 2.0, steps = None, - vizCycle = None, - vizTime = 0.01, dt = 0.0001, dtMin = 1.0e-8, dtMax = 0.1, @@ -101,54 +150,64 @@ def __call__(self, r): maxSteps = None, statsStep = 10, smoothIters = 0, - HUpdate = IdealH, domainIndependent = False, rigorousBoundaries = False, dtverbose = False, - densityUpdate = RigorousSumDensity, # VolumeScaledDensity, - compatibleEnergy = True, # <--- Important! rigorousBoundaries does not work with the compatibleEnergy algorithm currently. - gradhCorrection = False, - + # output options + vizCycle = None, + vizTime = 0.1, useVoronoiOutput = False, clearDirectories = False, restoreCycle = None, restartStep = 100, - redistributeStep = 500, + redistributeStep = 50000, checkRestart = False, dataDir = "dumps-Rayleigh-Taylor-2d", outputFile = "None", comparisonFile = "None", serialDump = False, #whether to dump a serial ascii file at the end for viz - - bArtificialConduction = False, - arCondAlpha = 0.5, ) + +assert not svph +assert not (compatibleEnergy and evolveTotalEnergy) +assert sum([fsisph,psph,gsph,crksph,svph,mfm])<=1 +assert not (fsisph and not solid) +assert not ((mfm or gsph) and (boolReduceViscosity)) + + # Decide on our hydro algorithm. -if SVPH: - if ASPH: - HydroConstructor = ASVPHFacetedHydro - else: - HydroConstructor = SVPHFacetedHydro -elif CRKSPH: - if ASPH: - HydroConstructor = ACRKSPHHydro - else: - HydroConstructor = CRKSPHHydro -else: - if ASPH: - HydroConstructor = ASPHHydro - else: - HydroConstructor = SPHHydro +hydroname = 'SPH' +useArtificialViscosity=True + +if svph: + hydroname = "SVPH" +elif crksph: + Qconstructor = LimitedMonaghanGingoldViscosity + hydroname = "CRK"+hydroname +elif psph: + hydroname = "P"+hydroname +elif fsisph: + hydroname = "FSI"+hydroname +elif gsph: + hydroname = "G"+hydroname + useArtificialViscosity=False +elif mfm: + hydroname = "MFM" + useArtificialViscosity=False +if asph: + hydorname = "A"+hydroname +if solid: + hydroname = "solid"+hydroname dataDir = os.path.join(dataDir, "S=%g" % (S), "vx1=%g-vx2=%g" % (abs(vx1), abs(vx2)), - str(HydroConstructor).split("'")[1].split(".")[-1], + hydroname, "densityUpdate=%s" % (densityUpdate), - "XSPH=%s" % XSPH, + "XSPH=%s" % xsph, "filter=%s" % filter, "%s-Cl=%g-Cq=%g" % (str(Qconstructor).split("'")[1].split(".")[-1], Cl, Cq), "%ix%i" % (nx1, ny1 + ny2), @@ -158,16 +217,10 @@ def __call__(self, r): restartBaseName = os.path.join(restartDir, "Rayleigh-Taylor-2d") vizBaseName = "Rayleigh-Taylor-2d" -#------------------------------------------------------------------------------- -# CRKSPH Switches to ensure consistency -#------------------------------------------------------------------------------- -if CRKSPH: - Qconstructor = LimitedMonaghanGingoldViscosity #------------------------------------------------------------------------------- # Check if the necessary output directories exist. If not, create them. #------------------------------------------------------------------------------- -import os, sys if mpi.rank == 0: if clearDirectories and os.path.exists(dataDir): shutil.rmtree(dataDir) @@ -191,19 +244,27 @@ def __call__(self, r): #------------------------------------------------------------------------------- # Interpolation kernels. #------------------------------------------------------------------------------- -WT = TableKernel(BSplineKernel(), 1000) +if KernelConstructor==NBSplineKernel: + WT = TableKernel(NBSplineKernel(order), 1000) +else: + WT = TableKernel(KernelConstructor(), 1000) output("WT") kernelExtent = WT.kernelExtent #------------------------------------------------------------------------------- # Make the NodeList. #------------------------------------------------------------------------------- -nodes1 = makeFluidNodeList("High density gas", eos, +if solid: + nodeListConstructor=makeSolidNodeList +else: + nodeListConstructor=makeFluidNodeList + +nodes1 = nodeListConstructor("Low density gas", eos, hmin = hmin, hmax = hmax, hminratio = hminratio, nPerh = nPerh) -nodes2 = makeFluidNodeList("Low density gas", eos, +nodes2 = nodeListConstructor("High density gas", eos, hmin = hmin, hmax = hmax, hminratio = hminratio, @@ -216,35 +277,47 @@ def __call__(self, r): output("nodes.hminratio") output("nodes.nodesPerSmoothingScale") + +#------------------------------------------------------------------------------- +# functions for ICs. +#------------------------------------------------------------------------------- +eps1=eps0 +eps2=eps1/S + +lowerDensity = ExponentialProfile(y1, + rho0/S, + g0/((gamma - 1.0)*eps1)) +upperDensity = ExponentialProfile(y1, + rho0, + g0/((gamma - 1.0)*eps2)) + + #------------------------------------------------------------------------------- # Set the node properties. #------------------------------------------------------------------------------- + if restoreCycle is None: - generator1 = GenerateNodeDistribution2d(nx1, ny1, - rho = ExponentialDensity(y1, - rho0/S, - g0/((gamma - 1.0)*eps0)), - distributionType = "lattice", - xmin = (x0,y0), + nx1 *= refineFactor + ny1 *= refineFactor + nx2 *= refineFactor + ny2 *= refineFactor + dy = (y1 - y0)/ny1 + + generator1 = GenerateNodeDistribution2d(nx1, ny1+nybound, + rho = lowerDensity, + distributionType = "xstaggeredLattice", + xmin = (x0,y0-nybound*dy), xmax = (x1,y1), - nNodePerh = nPerh, SPH = SPH) - generator2 = GenerateNodeDistribution2d(nx2, ny2, - rho = ExponentialDensity(y1, - rho0, - g0*S/((gamma - 1.0)*eps0)), - distributionType = "lattice", + generator2 = GenerateNodeDistribution2d(nx2, ny2+nybound, + rho = upperDensity, + distributionType = "xstaggeredLattice", xmin = (x0,y1), - xmax = (x1,y2), + xmax = (x1,y2+nybound*dy), nNodePerh = nPerh, SPH = SPH) - if mpi.procs > 1: - from VoronoiDistributeNodes import distributeNodes2d - else: - from DistributeNodes import distributeNodes2d - distributeNodes2d((nodes1, generator1), (nodes2, generator2)) @@ -260,7 +333,12 @@ def dy(ri): pos = nodes.positions() vel = nodes.velocity() for i in xrange(nodes.numInternalNodes): - pos[i].y += dy(pos[i]) + xi, yi = pos[i] + velx = 0.0 + vely = 0.0 + if yi > 0.5 and yi < 1.5: + vely = w0*(cos(2.0*pi*(xi-0.5)))*(cos(pi*(yi-1.0))) + vel[i]=Vector(velx,vely) #------------------------------------------------------------------------------- # Construct a DataBase to hold our node list @@ -275,64 +353,114 @@ def dy(ri): #------------------------------------------------------------------------------- # Construct the artificial viscosity. #------------------------------------------------------------------------------- -q = Qconstructor(Cl, Cq, linearInExpansion) -q.epsilon2 = epsilon2 -q.limiter = Qlimiter -q.balsaraShearCorrection = balsaraCorrection -output("q") -output("q.Cl") -output("q.Cq") -output("q.epsilon2") -output("q.limiter") -output("q.balsaraShearCorrection") -output("q.linearInExpansion") -output("q.quadraticInExpansion") +if useArtificialViscosity: + q = Qconstructor(Cl, Cq, linearInExpansion) + q.epsilon2 = epsilon2 + q.limiter = Qlimiter + q.balsaraShearCorrection = balsaraCorrection + output("q") + output("q.Cl") + output("q.Cq") + output("q.epsilon2") + output("q.limiter") + output("q.balsaraShearCorrection") + output("q.linearInExpansion") + output("q.quadraticInExpansion") #------------------------------------------------------------------------------- # Construct the hydro physics object. #------------------------------------------------------------------------------- -if SVPH: - hydro = HydroConstructor(W = WT, - Q = q, - cfl = cfl, - useVelocityMagnitudeForDt = useVelocityMagnitudeForDt, - compatibleEnergyEvolution = compatibleEnergy, - densityUpdate = densityUpdate, - XSVPH = XSPH, - linearConsistent = linearConsistent, - generateVoid = False, - HUpdate = HUpdate, - fcentroidal = fcentroidal, - fcellPressure = fcellPressure, - xmin = Vector(-2.0, -2.0), - xmax = Vector(3.0, 3.0)) -# xmin = Vector(x0 - 0.5*(x2 - x0), y0 - 0.5*(y2 - y0)), -# xmax = Vector(x2 + 0.5*(x2 - x0), y2 + 0.5*(y2 - y0))) -elif CRKSPH: - hydro = HydroConstructor(W = WT, - Q = q, - filter = filter, - cfl = cfl, - useVelocityMagnitudeForDt = useVelocityMagnitudeForDt, - compatibleEnergyEvolution = compatibleEnergy, - XSPH = XSPH, - densityUpdate = densityUpdate, - HUpdate = HUpdate) +if crksph: + hydro = CRKSPH(dataBase = db, + cfl = cfl, + filter = filter, + epsTensile = epsilonTensile, + nTensile = nTensile, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = xsph, + densityUpdate = densityUpdate, + HUpdate = HUpdate) +elif psph: + hydro = PSPH(dataBase = db, + cfl = cfl, + W = WT, + Q = q, + filter = filter, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate = densityUpdate, + HUpdate = HUpdate, + XSPH = xsph, + ASPH = asph) +if fsisph: + sumDensityNodeListSwitch =[nodes1,nodes2] + hydro = FSISPH(dataBase = db, + Q=q, + W = WT, + cfl = cfl, + surfaceForceCoefficient = fsiSurfaceCoefficient, + densityStabilizationCoefficient = fsiRhoStabilizeCoeff, + specificThermalEnergyDiffusionCoefficient = fsiEpsDiffuseCoeff, + xsphCoefficient = fsiXSPHCoeff, + interfaceMethod = fsiInterfaceMethod, + kernelAveragingMethod = fsiKernelMethod, + sumDensityNodeLists = sumDensityNodeListSwitch, + correctVelocityGradient = correctVelocityGradient, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + ASPH = asph, + epsTensile = epsilonTensile) +elif gsph: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) + hydro = GSPH(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate=densityUpdate, + XSPH = xsph, + ASPH = asph, + epsTensile = epsilonTensile, + nTensile = nTensile) +elif mfm: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) + hydro = MFM(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate=densityUpdate, + XSPH = xsph, + ASPH = asph, + epsTensile = epsilonTensile, + nTensile = nTensile) else: - hydro = HydroConstructor(W = WT, - Q = q, - cfl = cfl, - useVelocityMagnitudeForDt = useVelocityMagnitudeForDt, - compatibleEnergyEvolution = compatibleEnergy, - gradhCorrection = gradhCorrection, - XSPH = XSPH, - densityUpdate = densityUpdate, - HUpdate = HUpdate, - epsTensile = epsilonTensile, - nTensile = nTensile) + hydro = SPH(dataBase = db, + cfl = cfl, + W = WT, + Q = q, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + gradhCorrection = gradhCorrection, + correctVelocityGradient = correctVelocityGradient, + XSPH = xsph, + ASPH = asph, + densityUpdate = densityUpdate, + HUpdate = HUpdate, + epsTensile = epsilonTensile, + nTensile = nTensile) + output("hydro") output("hydro.kernel()") -output("hydro.PiKernel()") output("hydro.cfl") output("hydro.compatibleEnergyEvolution") output("hydro.densityUpdate") @@ -344,9 +472,8 @@ def dy(ri): # Construct the MMRV physics object. #------------------------------------------------------------------------------- -if boolReduceViscosity: +if boolReduceViscosity and useArtificialViscosity: evolveReducingViscosityMultiplier = MorrisMonaghanReducingViscosity(q,nh,aMin,aMax) - packages.append(evolveReducingViscosityMultiplier) #------------------------------------------------------------------------------- @@ -354,9 +481,7 @@ def dy(ri): #------------------------------------------------------------------------------- if bArtificialConduction: - #q.reducingViscosityCorrection = True - ArtyCond = ArtificialConduction(WT,arCondAlpha) - + ArtyCond = ArtificialConduction(WT,arCondAlpha) packages.append(ArtyCond) #------------------------------------------------------------------------------- @@ -370,9 +495,6 @@ def dy(ri): for i in xrange(nodes2.numInternalNodes): nodeIndicies2.append(i) -#nodeIndicies1.extend(range(nodes1.numInternalNodes)) -#nodeIndicies2.extend(range(nodes2.numInternalNodes)) - gravity1 = ConstantAcceleration2d(Vector2d(0.0, g0), nodes1, nodeIndicies1) @@ -391,11 +513,23 @@ def dy(ri): yp1 = Plane(Vector(x0, y0), Vector(0.0, 1.0)) yp2 = Plane(Vector(x0, y2), Vector(0.0, -1.0)) xbc = PeriodicBoundary(xp1, xp2) -#ybc = PeriodicBoundary(yp1, yp2) -ybc1 = ReflectingBoundary(yp1) -ybc2 = ReflectingBoundary(yp2) -bcSet = [xbc, ybc1, ybc2] -#bcSet = [xbc,ybc1] + +pos = nodes1.positions() +ylow, yhigh = vector_of_int(), vector_of_int() +for i in xrange(nodes1.numInternalNodes): + if pos[i].y < y0: + ylow.append(i) + +pos = nodes2.positions() +for i in xrange(nodes2.numInternalNodes): + if pos[i].y > y2: + yhigh.append(i) + +print(yhigh) +ybc1 = ConstantBoundary(db, nodes1, ylow, yp1) +ybc2 = ConstantBoundary(db, nodes2, yhigh, yp2) + +bcSet = [ybc1, ybc2, xbc] for bc in bcSet: for p in packages: @@ -443,6 +577,7 @@ def dy(ri): redistributeStep = redistributeStep, vizMethod = vizMethod, vizBaseName = vizBaseName, + vizGhosts=True, vizDir = vizDir, vizStep = vizCycle, vizTime = vizTime, diff --git a/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py b/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py index a813b9554..728e32d71 100644 --- a/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py +++ b/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py @@ -5,7 +5,7 @@ #------------------------------------------------------------------------------- # This is the basic Rayleigh-Taylor Problem #------------------------------------------------------------------------------- -import shutil +import shutil, os, sys from math import * from Spheral2d import * from SpheralTestUtilities import * @@ -18,7 +18,10 @@ from RTMixLength import RTMixLength import mpi -import DistributeNodes +if mpi.procs > 1: + from PeanoHilbertDistributeNodes import distributeNodes2d +else: + from DistributeNodes import distributeNodes2d class ExponentialDensity: def __init__(self, @@ -46,25 +49,72 @@ def __call__(self, r): y0 = 0.0, y1 = 1.0, gval = -0.5, - w0 = 0.025, + w0 = 0.025, delta = 0.025, gamma = 1.4, mu = 1.0, - nPerh = 1.01, - - SVPH = False, - CRKSPH = False, - PSPH = False, - SPH = True, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. - filter = 0.0, # CRKSPH filtering - Qconstructor = MonaghanGingoldViscosity, - #Qconstructor = TensorMonaghanGingoldViscosity, - KernelConstructor = BSplineKernel, + # kernel options + KernelConstructor = WendlandC2Kernel, + HUpdate = IdealH, + nPerh = 3.01, order = 5, + hmin = 0.0001, + hmax = 0.5, + hminratio = 0.1, + + # hydros + svph = False, + crksph = False, + psph = False, + fsisph = False, + gsph = False, + mfm = False, + + # general hydro options + asph = False, + xsph = False, + solid = False, + filter = 0.0, + epsilonTensile = 0.0, + nTensile = 8, + useVelocityMagnitudeForDt = False, + densityUpdate = IntegrateDensity, + compatibleEnergy = True, + correctVelocityGradient = True, + evolveTotalEnergy= False, + + # SPH/PSPH options + gradhCorrection = True, + HopkinsConductivity=False, + + # svph options linearConsistent = False, fcentroidal = 0.0, fcellPressure = 0.0, + + # crksph options + correctionOrder = LinearOrder, + + # FSISPH parameters + fsiSurfaceCoefficient = 0.00, # adds additional repulsive force to material interfaces) + fsiRhoStabilizeCoeff = 0.1, # coefficient that smooths the density field + fsiEpsDiffuseCoeff = 0.1, # explicit diiffusion of the thermal energy + fsiXSPHCoeff = 0.00, # fsi uses multiplier for XSPH instead of binary switch + fsiInterfaceMethod = ModulusInterface, # (HLLCInterface, ModulusInterface) + fsiKernelMethod = NeverAverageKernels, # (NeverAverageKernels, AlwaysAverageKernels, AverageInterfaceKernels) + + # GSPH/MFM parameters + gsphEpsDiffuseCoeff = 0.0, + gsphLinearCorrect = True, + LimiterConstructor = VanLeerLimiter, + WaveSpeedConstructor = DavisWaveSpeed, + riemannGradientType = HydroAccelerationGradient, + + # artificial viscosity + Qconstructor = LimitedMonaghanGingoldViscosity, + Cl = 1.0, + Cq = 1.0, boolReduceViscosity = False, nh = 5.0, aMin = 0.1, @@ -78,22 +128,13 @@ def __call__(self, r): betaE = 1.0, fKern = 1.0/3.0, boolHopkinsCorrection = True, - Cl = 1.0, - Cq = 1.0, linearInExpansion = False, Qlimiter = False, balsaraCorrection = False, epsilon2 = 1e-2, - hmin = 0.0001, - hmax = 0.5, - hminratio = 0.1, - cfl = 0.5, - useVelocityMagnitudeForDt = False, - XSPH = False, - epsilonTensile = 0.0, - nTensile = 8, IntegratorConstructor = CheapSynchronousRK2Integrator, + cfl = 0.5, goalTime = 4.0, steps = None, vizCycle = None, @@ -105,18 +146,9 @@ def __call__(self, r): maxSteps = None, statsStep = 10, smoothIters = 0, - HUpdate = IdealH, domainIndependent = False, rigorousBoundaries = False, dtverbose = False, - - correctionOrder = LinearOrder, - densityUpdate = RigorousSumDensity, # VolumeScaledDensity, - compatibleEnergy = True, # <--- Important! rigorousBoundaries does not work with the compatibleEnergy algorithm currently. - gradhCorrection = True, - correctVelocityGradient = True, - evolveTotalEnergy= False, - HopkinsConductivity=False, clearDirectories = False, restoreCycle = -1, @@ -134,39 +166,48 @@ def __call__(self, r): arCondAlpha = 0.5, ) + + +assert not svph +assert not (compatibleEnergy and evolveTotalEnergy) +assert sum([fsisph,psph,gsph,crksph,svph,mfm])<=1 +assert not (fsisph and not solid) +assert not ((mfm or gsph) and (boolReduceViscosity or boolReduceViscosity)) assert not(boolReduceViscosity and boolCullenViscosity) -# Decide on our hydro algorithm. -if SVPH: - if SPH: - HydroConstructor = SVPHFacetedHydro - else: - HydroConstructor = ASVPHFacetedHydro -elif CRKSPH: + + +hydroname = 'SPH' +useArtificialViscosity=True + +if svph: + hydroname = "SVPH" +elif crksph: Qconstructor = LimitedMonaghanGingoldViscosity - if SPH: - HydroConstructor = CRKSPHHydro - else: - HydroConstructor = ACRKSPHHydro -elif PSPH: - if SPH: - HydroConstructor = PSPHHydro - else: - HydroConstructor = APSPHHydro -else: - if SPH: - HydroConstructor = SPHHydro - else: - HydroConstructor = ASPHHydro + hydroname = "CRK"+hydroname +elif psph: + hydroname = "P"+hydroname +elif fsisph: + hydroname = "FSI"+hydroname +elif gsph: + hydroname = "G"+hydroname + useArtificialViscosity=False +elif mfm: + hydroname = "MFM" + useArtificialViscosity=False +if asph: + hydorname = "A"+hydroname +if solid: + hydroname = "solid"+hydroname dataDir = os.path.join(dataDir, "gval=%g" % (gval), "w0=%g" % w0, - HydroConstructor.__name__, + hydroname, Qconstructor.__name__, KernelConstructor.__name__, "densityUpdate=%s" % (densityUpdate), "correctionOrder=%s" % (correctionOrder), - "XSPH=%s" % XSPH, + "XSPH=%s" % xsph, "filter=%s" % filter, "compatible=%s" % compatibleEnergy, "Cullen=%s" % boolCullenViscosity, @@ -181,7 +222,6 @@ def __call__(self, r): #------------------------------------------------------------------------------- # Check if the necessary output directories exist. If not, create them. #------------------------------------------------------------------------------- -import os, sys if mpi.rank == 0: if clearDirectories and os.path.exists(dataDir): shutil.rmtree(dataDir) @@ -201,18 +241,20 @@ def __call__(self, r): #------------------------------------------------------------------------------- if KernelConstructor==NBSplineKernel: WT = TableKernel(NBSplineKernel(order), 10000) - WTPi = TableKernel(NBSplineKernel(order), 10000, Qhmult) else: WT = TableKernel(KernelConstructor(), 10000) - WTPi = TableKernel(KernelConstructor(), 10000, Qhmult) output("WT") -output("WTPi") kernelExtent = WT.kernelExtent #------------------------------------------------------------------------------- # Make the NodeList. #------------------------------------------------------------------------------- -nodes = makeFluidNodeList("High density gas", eos, +if solid: + nodeListConstructor=makeSolidNodeList +else: + nodeListConstructor=makeFluidNodeList + +nodes = nodeListConstructor("High density gas", eos, hmin = hmin, hmax = hmax, hminratio = hminratio, @@ -240,11 +282,6 @@ def __call__(self, r): nNodePerh = nPerh, SPH = SPH) -if mpi.procs > 1: - from VoronoiDistributeNodes import distributeNodes2d -else: - from DistributeNodes import distributeNodes2d - distributeNodes2d((nodes, generator)) #Set IC @@ -276,78 +313,117 @@ def __call__(self, r): #------------------------------------------------------------------------------- # Construct the artificial viscosity. #------------------------------------------------------------------------------- -q = Qconstructor(Cl, Cq, linearInExpansion) -q.epsilon2 = epsilon2 -q.limiter = Qlimiter -q.balsaraShearCorrection = balsaraCorrection -output("q") -output("q.Cl") -output("q.Cq") -output("q.epsilon2") -output("q.limiter") -output("q.balsaraShearCorrection") -output("q.linearInExpansion") -output("q.quadraticInExpansion") +if useArtificialViscosity: + q = Qconstructor(Cl, Cq, linearInExpansion) + q.epsilon2 = epsilon2 + q.limiter = Qlimiter + q.balsaraShearCorrection = balsaraCorrection + output("q") + output("q.Cl") + output("q.Cq") + output("q.epsilon2") + output("q.limiter") + output("q.balsaraShearCorrection") + output("q.linearInExpansion") + output("q.quadraticInExpansion") + #------------------------------------------------------------------------------- # Construct the hydro physics object. #------------------------------------------------------------------------------- -if SVPH: - hydro = HydroConstructor(W = WT, - Q = q, - cfl = cfl, - useVelocityMagnitudeForDt = useVelocityMagnitudeForDt, - compatibleEnergyEvolution = compatibleEnergy, - densityUpdate = densityUpdate, - XSVPH = XSPH, - linearConsistent = linearConsistent, - generateVoid = False, - HUpdate = HUpdate, - fcentroidal = fcentroidal, - fcellPressure = fcellPressure, - xmin = Vector(-2.0, -2.0), - xmax = Vector(3.0, 3.0)) -elif CRKSPH: - hydro = HydroConstructor(W = WT, - WPi = WTPi, - Q = q, - filter = filter, - cfl = cfl, - useVelocityMagnitudeForDt = useVelocityMagnitudeForDt, - compatibleEnergyEvolution = compatibleEnergy, - XSPH = XSPH, - correctionOrder = correctionOrder, - densityUpdate = densityUpdate, - HUpdate = HUpdate) -elif PSPH: - hydro = HydroConstructor(W = WT, - Q = q, - filter = filter, - cfl = cfl, - compatibleEnergyEvolution = compatibleEnergy, - evolveTotalEnergy = evolveTotalEnergy, - HopkinsConductivity = HopkinsConductivity, - densityUpdate = densityUpdate, - correctVelocityGradient = correctVelocityGradient, - HUpdate = HUpdate, - XSPH = XSPH) +if crksph: + hydro = CRKSPH(dataBase = db, + cfl = cfl, + filter = filter, + epsTensile = epsilonTensile, + nTensile = nTensile, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = xsph, + densityUpdate = densityUpdate, + HUpdate = HUpdate) +elif psph: + hydro = PSPH(dataBase = db, + cfl = cfl, + W = WT, + Q = q, + filter = filter, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate = densityUpdate, + HUpdate = HUpdate, + XSPH = xsph, + ASPH = asph) +if fsisph: + sumDensityNodeListSwitch =[nodes] + hydro = FSISPH(dataBase = db, + Q=q, + W = WT, + cfl = cfl, + surfaceForceCoefficient = fsiSurfaceCoefficient, + densityStabilizationCoefficient = fsiRhoStabilizeCoeff, + specificThermalEnergyDiffusionCoefficient = fsiEpsDiffuseCoeff, + xsphCoefficient = fsiXSPHCoeff, + interfaceMethod = fsiInterfaceMethod, + kernelAveragingMethod = fsiKernelMethod, + sumDensityNodeLists = sumDensityNodeListSwitch, + correctVelocityGradient = correctVelocityGradient, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + ASPH = asph, + epsTensile = epsilonTensile) +elif gsph: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) + hydro = GSPH(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + gradientType = riemannGradientType, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate=densityUpdate, + XSPH = xsph, + ASPH = asph, + epsTensile = epsilonTensile, + nTensile = nTensile) +elif mfm: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) + hydro = MFM(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + gradientType = riemannGradientType, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate=densityUpdate, + XSPH = xsph, + ASPH = asph, + epsTensile = epsilonTensile, + nTensile = nTensile) else: - hydro = HydroConstructor(W = WT, - WPi = WTPi, - Q = q, - cfl = cfl, - useVelocityMagnitudeForDt = useVelocityMagnitudeForDt, - compatibleEnergyEvolution = compatibleEnergy, - gradhCorrection = gradhCorrection, - correctVelocityGradient = correctVelocityGradient, - evolveTotalEnergy = evolveTotalEnergy, - XSPH = XSPH, - densityUpdate = densityUpdate, - HUpdate = HUpdate, - epsTensile = epsilonTensile) + hydro = SPH(dataBase = db, + cfl = cfl, + W = WT, + Q = q, + compatibleEnergyEvolution = compatibleEnergy, + evolveTotalEnergy = evolveTotalEnergy, + gradhCorrection = gradhCorrection, + correctVelocityGradient = correctVelocityGradient, + XSPH = xsph, + ASPH = asph, + densityUpdate = densityUpdate, + HUpdate = HUpdate, + epsTensile = epsilonTensile, + nTensile = nTensile) + output("hydro") output("hydro.kernel()") -output("hydro.PiKernel()") output("hydro.cfl") output("hydro.compatibleEnergyEvolution") output("hydro.densityUpdate") @@ -358,10 +434,10 @@ def __call__(self, r): #------------------------------------------------------------------------------- # Construct the MMRV physics object. #------------------------------------------------------------------------------- -if boolReduceViscosity: +if boolReduceViscosity and useArtificialViscosity: evolveReducingViscosityMultiplier = MorrisMonaghanReducingViscosity(q,nh,aMin,aMax) packages.append(evolveReducingViscosityMultiplier) -elif boolCullenViscosity: +elif boolCullenViscosity and useArtificialViscosity: evolveCullenViscosityMultiplier = CullenDehnenViscosity(q,WTPi,alphMax,alphMin,betaC,betaD,betaE,fKern,boolHopkinsCorrection) packages.append(evolveCullenViscosityMultiplier) @@ -407,8 +483,8 @@ def __call__(self, r): ylow.append(i) elif pos[i].y > y1: yhigh.append(i) -ybc1 = ConstantBoundary(nodes, ylow, yp1) -ybc2 = ConstantBoundary(nodes, yhigh, yp2) +ybc1 = ConstantBoundary(db,nodes, ylow, yp1) +ybc2 = ConstantBoundary(db,nodes, yhigh, yp2) bcSet = [ybc1, ybc2, xbc] # <-- ybc should be first! @@ -465,7 +541,7 @@ def __call__(self, r): restartBaseName = restartBaseName, restoreCycle = restoreCycle, redistributeStep = None, - vizMethod = vizMethod, + #vizMethod = vizMethod, vizBaseName = vizBaseName, vizDir = vizDir, vizStep = vizCycle, From f3095d07deceb2f7fbff8823fcd3e5f1923677a3 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 13 Jul 2022 18:34:08 -0700 Subject: [PATCH 08/60] updating KH tests --- .../KelvinHelmholtz/KelvinHelmholtz-2d.py | 50 +++++++++++++------ .../KelvinHelmholtz-2d_McNally.py | 48 ++++++++++++++---- 2 files changed, 74 insertions(+), 24 deletions(-) diff --git a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py index 74e9ee21f..138c28f98 100644 --- a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py +++ b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py @@ -64,6 +64,7 @@ crksph = False, fsisph = False, gsph = False, + mfm = False, # hydro options solid = False, # fluid limit of the solid hydro @@ -78,6 +79,7 @@ evolveTotalEnergy = False, # integrate total instead of specific energy gradhCorrection = True, # correct for temporal variation in h correctVelocityGradient = True, # linear exact velocity gradient (M correction) (corrected kernesl for GSPH and FSISPH) + # SVPH parameters fcentroidal = 0.0, fcellPressure = 0.0, @@ -90,14 +92,16 @@ fsiInterfaceMethod = HLLCInterface, # (HLLCInterface, ModulusInterface) fsiKernelMethod = NeverAverageKernels, # (NeverAverageKernels, AlwaysAverageKernels, AverageInterfaceKernels) - # GSPH parameters + # GSPH/MFM parameters gsphEpsDiffuseCoeff = 0.0, gsphLinearCorrect = True, + LimiterConstructor = VanLeerLimiter, + WaveSpeedConstructor = DavisWaveSpeed, # artificial viscosity + Qconstructor = LimitedMonaghanGingoldViscosity, Cl = 1.0, Cq = 1.0, - Qconstructor = MonaghanGingoldViscosity, linearConsistent = False, boolReduceViscosity = False, nh = 5.0, @@ -150,21 +154,29 @@ assert not svph assert not (compatibleEnergy and evolveTotalEnergy) -assert sum([fsisph,psph,gsph,crksph,svph])<=1 +assert sum([fsisph,psph,gsph,crksph,svph,mfm])<=1 assert not (fsisph and not solid) +assert not ((mfm or gsph) and (boolCullenViscosity or boolReduceViscosity)) # Decide on our hydro algorithm. hydroname = 'SPH' +useArtificialViscosity=True + if svph: hydroname = "SVPH" elif crksph: hydroname = "CRK"+hydroname + Qconstructor = LimitedMonaghanGingoldViscosity elif psph: hydroname = "P"+hydroname elif fsisph: hydroname = "FSI"+hydroname elif gsph: hydroname = "G"+hydroname + useArtificialViscosity=False +elif mfm: + hydroname = "MFM" + useArtificialViscosity=False if asph: hydorname = "A"+hydroname if solid: @@ -186,12 +198,6 @@ restartBaseName = os.path.join(restartDir, "KelvinHelmholtz-2d") vizBaseName = "KelvinHelmholtz-2d" -#------------------------------------------------------------------------------- -# CRKSPH Switches to ensure consistency -#------------------------------------------------------------------------------- -if crksph or fsisph: - Qconstructor = LimitedMonaghanGingoldViscosity - #------------------------------------------------------------------------------- # Check if the necessary output directories exist. If not, create them. #------------------------------------------------------------------------------- @@ -332,7 +338,7 @@ def vy(ri): #------------------------------------------------------------------------------- # Construct the artificial viscosity. #------------------------------------------------------------------------------- -if not gsph: +if useArtificialViscosity: q = Qconstructor(Cl, Cq, linearInExpansion) q.epsilon2 = epsilon2 q.limiter = Qlimiter @@ -351,6 +357,7 @@ def vy(ri): #------------------------------------------------------------------------------- if crksph: hydro = CRKSPH(dataBase = db, + Q=q, cfl = cfl, filter = filter, epsTensile = epsilonTensile, @@ -391,14 +398,29 @@ def vy(ri): ASPH = asph, epsTensile = epsilonTensile) elif gsph: - limiter = VanLeerLimiter() - waveSpeed = DavisWaveSpeed() + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) hydro = GSPH(dataBase = db, riemannSolver = solver, W = WT, cfl=cfl, - specificThermalEnergyDiffusionCoefficient = gsphEpsDiffuseCoeff, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate=densityUpdate, + XSPH = xsph, + ASPH = asph, + epsTensile = epsilonTensile, + nTensile = nTensile) +elif mfm: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) + hydro = MFM(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, @@ -433,7 +455,7 @@ def vy(ri): #------------------------------------------------------------------------------- # Construct the MMRV physics object. #------------------------------------------------------------------------------- -if boolReduceViscosity: +if boolReduceViscosity and useArtificialViscosity: evolveReducingViscosityMultiplier = MorrisMonaghanReducingViscosity(q,nh,aMin,aMax) packages.append(evolveReducingViscosityMultiplier) diff --git a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d_McNally.py b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d_McNally.py index 37ea2302c..2ca92d9fe 100644 --- a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d_McNally.py +++ b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d_McNally.py @@ -64,12 +64,13 @@ psph = False, fsisph = False, gsph = False, + mfm = False, # hydro options solid = False, asph = False, # Just for choosing the H algorithm - useVelocityMagnitudeForDt = False, XSPH = False, + useVelocityMagnitudeForDt = False, epsilonTensile = 0.0, nTensile = 8, filter = 0.0, @@ -80,6 +81,8 @@ evolveTotalEnergy = False, # artificial viscosity + Cl = None, + Cq = None, linearConsistent = False, boolReduceViscosity = False, nh = 5.0, @@ -94,8 +97,6 @@ betaE = 1.0, fKern = 1.0/3.0, boolHopkinsCorrection = True, - Cl = None, - Cq = None, linearInExpansion = False, Qlimiter = None, balsaraCorrection = False, @@ -120,6 +121,8 @@ # GSPH parameters gsphEpsDiffuseCoeff = 0.0, gsphLinearCorrect = True, + LimiterConstructor = VanLeerLimiter, + WaveSpeedConstructor = DavisWaveSpeed, ## integrator cfl = 0.5, @@ -164,10 +167,12 @@ assert numNodeLists in (1, 2) assert not svph assert not (compatibleEnergy and evolveTotalEnergy) -assert sum([fsisph,psph,gsph,crksph,svph])<=1 +assert sum([fsisph,psph,gsph,crksph,svph,mfm])<=1 assert not (fsisph and not solid) +assert not ((mfm or gsph) and (boolCullenViscosity or boolReduceViscosity)) # hydro algorithm label +useArtificialViscosity = True if svph: hydroname = "SVPH" elif crksph: @@ -180,11 +185,19 @@ hydroname = "FSISPH" elif gsph: hydroname = "GSPH" + useArtificialViscosity=False +elif mfm: + hydroname = "MFM" + useArtificialViscosity=False else: hydroname = "SPH" + if asph: hydroname = "A" + hydroname +if solid: + hydroname = "solid" + hydroname + dataDir = os.path.join(dataDir, "rho1=%g-rho2=%g" % (rho1, rho2), "vx1=%g-vx2=%g" % (abs(vx1), abs(vx2)), @@ -429,14 +442,29 @@ ASPH = asph, epsTensile = epsilonTensile) elif gsph: - limiter = VanLeerLimiter() - waveSpeed = DavisWaveSpeed() + limiter = LimiterConstructor + waveSpeed = WaveSpeedConstructor + solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) + hydro = GSPH(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + densityUpdate=densityUpdate, + XSPH = XSPH, + ASPH = asph, + epsTensile = epsilonTensile, + nTensile = nTensile) +elif mfm: + limiter = LimiterConstructor + waveSpeed = WaveSpeedConstructor solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) hydro = GSPH(dataBase = db, riemannSolver = solver, W = WT, cfl=cfl, - specificThermalEnergyDiffusionCoefficient = gsphEpsDiffuseCoeff, compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, @@ -471,7 +499,7 @@ #------------------------------------------------------------------------------- # Set the artificial viscosity parameters. #------------------------------------------------------------------------------- -if not gsph: +if useArtificialViscosity: q = hydro.Q if not Cl is None: q.Cl = Cl @@ -498,10 +526,10 @@ #------------------------------------------------------------------------------- # Construct the MMRV physics object. #------------------------------------------------------------------------------- -if boolReduceViscosity: +if boolReduceViscosity and useArtificialViscosity: evolveReducingViscosityMultiplier = MorrisMonaghanReducingViscosity(q,nh,aMin,aMax) packages.append(evolveReducingViscosityMultiplier) -elif boolCullenViscosity: +elif boolCullenViscosity and useArtificialViscosity: evolveCullenViscosityMultiplier = CullenDehnenViscosity(q,WT,alphMax,alphMin,betaC,betaD,betaE,fKern,boolHopkinsCorrection) packages.append(evolveCullenViscosityMultiplier) From f9db8132728b8647444bf60a46b29ac5bbe1c69f Mon Sep 17 00:00:00 2001 From: jmpearl Date: Sun, 31 Jul 2022 12:56:42 -0700 Subject: [PATCH 09/60] storing for merge --- src/GSPH/RiemannSolvers/HLLC.cc | 19 ++-- tests/functional/Hydro/YeeVortex/YeeVortex.py | 97 ++++++++++--------- 2 files changed, 61 insertions(+), 55 deletions(-) diff --git a/src/GSPH/RiemannSolvers/HLLC.cc b/src/GSPH/RiemannSolvers/HLLC.cc index f108e8a83..5094b2de6 100644 --- a/src/GSPH/RiemannSolvers/HLLC.cc +++ b/src/GSPH/RiemannSolvers/HLLC.cc @@ -1,7 +1,7 @@ //---------------------------------Spheral++----------------------------------// // HLLC -- approximate riemann solver -// Toro E.F., Spruce M., Speares W., (1994) "Restoration of the Contact Surface in -// the HLL-Riemann Solver," Shock Waves, 4:25-34 +// Toro E.F., Spruce M., Speares W., (1994) "Restoration of the Contact +// Surface in the HLL-Riemann Solver," Shock Waves, 4:25-34 // // J.M. Pearl 2021 //----------------------------------------------------------------------------// @@ -218,10 +218,10 @@ interfaceState(const int i, if(this->linearReconstruction()){ // gradients along line of action - this->linearReconstruction(ri,rj, Pi,Pj, DpDxi,DpDxj, - p1i,p1j); - this->linearReconstruction(ri,rj, vi,vj, DvDxi,DvDxj, - v1i,v1j); + this->linearReconstruction(ri,rj, Pi,Pj,DpDxi,DpDxj, //inputs + p1i,p1j); //outputs + this->linearReconstruction(ri,rj, vi,vj,DvDxi,DvDxj, //inputs + v1i,v1j); //outputs } @@ -230,13 +230,14 @@ interfaceState(const int i, const auto wi = v1i - ui*rhatij; const auto wj = v1j - uj*rhatij; - waveSpeedObject.waveSpeed(rhoi,rhoj,ci,cj,ui,uj,Si,Sj); + waveSpeedObject.waveSpeed(rhoi,rhoj,ci,cj,ui,uj, //inputs + Si,Sj); //outputs const auto denom = safeInv(Si - Sj); - const auto ustar = (Si*ui - Sj*uj - p1i + p1j )*denom; + const auto ustar = (Si*ui - Sj*uj )*denom; const auto wstar = (Si*wi - Sj*wj)*denom; - vstar = ustar*rhatij + wstar; + //vstar = ustar*rhatij + wstar; Pstar = Sj * (ustar-uj) + p1j; }else{ // if ci & cj too small punt to normal av diff --git a/tests/functional/Hydro/YeeVortex/YeeVortex.py b/tests/functional/Hydro/YeeVortex/YeeVortex.py index cfc2c4c39..96b98ed2e 100644 --- a/tests/functional/Hydro/YeeVortex/YeeVortex.py +++ b/tests/functional/Hydro/YeeVortex/YeeVortex.py @@ -52,13 +52,13 @@ def __call__(self, r): #Center and radius of Vortex xc=0.0, yc=0.0, - rmax = 5.0, + rmax = 6.0, # How far should we measure the error norms? rmaxnorm = 5.0, # The number of radial points on the outside to force with constant BC - nbcrind = 10, + nbcrind = 6, #Vortex strength beta = 5.0, @@ -69,12 +69,12 @@ def __call__(self, r): # Resolution and node seeding. nRadial = 64, seed = "constantDTheta", - numLlyodIters = 10, + numLlyodIters = 4, # kernel options - KernelConstructor = NBSplineKernel, - nPerh = 1.51, - order = 5, + KernelConstructor = WendlandC2Kernel, + nPerh = 3.01, + order = 7, hmin = 1e-5, hmax = 0.5, hminratio = 0.1, @@ -93,7 +93,7 @@ def __call__(self, r): XSPH = False, epsilonTensile = 0.0, nTensile = 8, - densityUpdate = IntegrateDensity, # VolumeScaledDensity, + densityUpdate = RigorousSumDensity, # VolumeScaledDensity, compatibleEnergy = True, evolveTotalEnergy = False, correctVelocityGradient = True, @@ -116,8 +116,8 @@ def __call__(self, r): # artificial viscosity Qconstructor = LimitedMonaghanGingoldViscosity, # TensorMonaghanGingoldViscosity, - Cl = 0.0, - Cq = 0.0, + Cl = 1.0, + Cq = 1.0, boolReduceViscosity = False, nhQ = 5.0, nhL = 10.0, @@ -140,7 +140,7 @@ def __call__(self, r): epsilon2 = 1e-2, # integrator - IntegratorConstructor = VerletIntegrator, + IntegratorConstructor = CheapSynchronousRK2Integrator, cfl = 0.25, goalTime = 8.0, steps = None, @@ -166,7 +166,7 @@ def __call__(self, r): graphics = True, smooth = False, outputFileBase = ".out", - convergenceFileBase = "converge.txt", + convergenceFileBase = "xstaglattice_converge.txt", ) assert not(boolReduceViscosity and boolCullenViscosity) @@ -210,16 +210,18 @@ def __call__(self, r): SumVoronoiCellDensity : "SumVoronoiCellDensity"} baseDir = os.path.join(dataDir, hydroname, - Qconstructor.__name__, - KernelConstructor.__name__, - "Cl=%g_Cq=%g" % (Cl, Cq), - densityUpdateLabel[densityUpdate], - "compatibleEnergy=%s" % compatibleEnergy, - "Cullen=%s" % boolCullenViscosity, - "nPerh=%3.1f" % nPerh, - "fcentroidal=%f" % max(fcentroidal, filter), - "fcellPressure=%f" % fcellPressure, - "seed=%s" % seed, + #str(riemannGradientType), + #LimiterConstructor.__name__, + #Qconstructor.__name__, + #KernelConstructor.__name__, + #"Cl=%g_Cq=%g" % (Cl, Cq), + #densityUpdateLabel[densityUpdate], + #"compatibleEnergy=%s" % compatibleEnergy, + #"Cullen=%s" % boolCullenViscosity, + #"nPerh=%3.1f" % nPerh, + #"fcentroidal=%f" % max(fcentroidal, filter), + #"fcellPressure=%f" % fcellPressure, + #"seed=%s" % seed, str(nRadial)) restartDir = os.path.join(baseDir, "restarts") restartBaseName = os.path.join(restartDir, "yeevortex-xy-%i" % nRadial) @@ -283,8 +285,9 @@ def __call__(self, r): # Set the node properties. #------------------------------------------------------------------------------- rmaxbound = rmax + rmax/nRadial*nbcrind +print rmaxbound nr1 = nRadial + nbcrind -if seed == "lattice": +if seed == "lattice" or "xstaggeredLattice": generator = GenerateNodeDistribution2d(2*nr1, 2*nr1, rho = YeeDensityFunc, distributionType = seed, @@ -296,6 +299,7 @@ def __call__(self, r): nNodePerh = nPerh, SPH = SPH) else: + generator = GenerateNodeDistribution2d(nr1, nr1, rho = YeeDensityFunc, distributionType = seed, @@ -559,11 +563,11 @@ def __call__(self, r): #------------------------------------------------------------------------------- # Make the problem controller. #------------------------------------------------------------------------------- -# if useVoronoiOutput: -# import SpheralVoronoiSiloDump -# vizMethod = SpheralVoronoiSiloDump.dumpPhysicsState -# else: -# vizMethod = None # default +if useVoronoiOutput: + import SpheralVoronoiSiloDump + vizMethod = SpheralVoronoiSiloDump.dumpPhysicsState +else: + vizMethod = None # default from SpheralPointmeshSiloDump import dumpPhysicsState control = SpheralController(integrator, WT, @@ -597,25 +601,26 @@ def inDomain(pos): pos = nodes.positions() rho = nodes.massDensity() mass = nodes.mass() - vol = hydro.volume[0] - VolTot=0.0 - for i in xrange(nodes.numInternalNodes): - VolTot += vol[i] - VolTot = mpi.allreduce(VolTot,mpi.SUM) - numTotal = mpi.allreduce(nodes.numInternalNodes,mpi.SUM) - volNominal = VolTot/numTotal - - for i in xrange(nodes.numInternalNodes): - xi, yi = pos[i] - xci = (xi-xc) - yci = (yi-yc) - r2=xci*xci+yci*yci - velx = vel_infx-yci*exp((1.0-r2)*0.5)*beta/(2.0*pi) - vely = vel_infy+xci*exp((1.0-r2)*0.5)*beta/(2.0*pi) - rho[i] = YeeDensityFunc(pos[i]) - mass[i] = rho[i]*vol[i] - vel[i] = Vector(velx,vely) - eps[i] = pow(rho[i],(gamma-1.0))/(gamma-1.0) + #vol = hydro.volume[0] + + # for i in xrange(nodes.numInternalNodes): + # xi, yi = pos[i] + # xci = (xi-xc) + # yci = (yi-yc) + # r2=xci*xci+yci*yci + # velx = vel_infx-yci*exp((1.0-r2)*0.5)*beta/(2.0*pi) + # vely = vel_infy+xci*exp((1.0-r2)*0.5)*beta/(2.0*pi) + # rhoNew = YeeDensityFunc(pos[i]) + # mass[i] = rhoNew*mass[i]*rho[i] + # rho[i] = rhoNew + # vel[i] = Vector(velx,vely) + # eps[i] = pow(rho[i],(gamma-1.0))/(gamma-1.0) + # packages = integrator.physicsPackages() + # state = State2d(db, packages) + # integrator.setGhostNodes() + # derivs = StateDerivatives2d(db, packages) + # integrator.applyGhostBoundaries(state, derivs) + # integrator.finalizeGhostBoundaries() #------------------------------------------------------------------------------- # Advance to the end time. #------------------------------------------------------------------------------- From 26a4d664364488a2ceb26ef68666e6a2c6b663f5 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Sun, 31 Jul 2022 15:21:16 -0700 Subject: [PATCH 10/60] GSPH RiemannSolver interface update removing GHLLC (depricate), adding a ArtificialViscosity implementation for direct comparison in the GSPH paper. Might need to rename to make it less confusing with the AV class heirarchy in Spheral --- src/GSPH/CMakeLists.txt | 4 +- src/GSPH/GSPHEvaluateDerivatives.cc | 13 +- src/GSPH/MFMEvaluateDerivatives.cc | 13 +- src/GSPH/RiemannSolvers/GHLLC.cc | 182 ------------------ src/GSPH/RiemannSolvers/GHLLCInline.hh | 21 -- src/GSPH/RiemannSolvers/HLLC.cc | 144 +------------- src/GSPH/RiemannSolvers/HLLC.hh | 37 +--- src/GSPH/RiemannSolvers/RiemannSolverBase.cc | 127 ++---------- src/GSPH/RiemannSolvers/RiemannSolverBase.hh | 47 +---- .../RiemannSolvers/RiemannSolverBaseInline.hh | 40 ---- .../SecondOrderArtificialViscosity.cc | 133 +++++++++++++ ...C.hh => SecondOrderArtificialViscosity.hh} | 82 ++++---- .../SecondOrderArtificialViscosityInline.hh | 40 ++++ ... SecondOrderArtificialViscosityInst.cc.py} | 4 +- src/Pybind11Wraps/GSPH/GSPHMOD.py | 4 +- .../GSPH/RiemannSolverBaseAbstractMethods.py | 55 ------ src/Pybind11Wraps/GSPH/RiemannSolvers.py | 21 +- 17 files changed, 266 insertions(+), 701 deletions(-) delete mode 100644 src/GSPH/RiemannSolvers/GHLLC.cc delete mode 100644 src/GSPH/RiemannSolvers/GHLLCInline.hh create mode 100644 src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc rename src/GSPH/RiemannSolvers/{GHLLC.hh => SecondOrderArtificialViscosity.hh} (56%) create mode 100644 src/GSPH/RiemannSolvers/SecondOrderArtificialViscosityInline.hh rename src/GSPH/RiemannSolvers/{GHLLCInst.cc.py => SecondOrderArtificialViscosityInst.cc.py} (66%) delete mode 100644 src/Pybind11Wraps/GSPH/RiemannSolverBaseAbstractMethods.py diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 13a01ee97..3fc9f6489 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -21,7 +21,7 @@ set(GSPH_inst WaveSpeeds/EinfeldtWaveSpeed RiemannSolvers/RiemannSolverBase RiemannSolvers/HLLC - RiemannSolvers/GHLLC) + RiemannSolvers/SecondOrderArtificialViscosity) set(GSPH_sources GSPHFieldNames.cc) @@ -48,7 +48,7 @@ set(GSPH_headers WaveSpeeds/EinfeldtWaveSpeed.hh RiemannSolvers/RiemannSolverBase.hh RiemannSolvers/HLLC.hh - RiemannSolvers/GHLLC.hh) + RiemannSolvers/SecondOrderArtificialViscosity.hh) add_subdirectory(Limiters) add_subdirectory(WaveSpeeds) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index 789f16aeb..eb839c4ca 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -238,19 +238,18 @@ evaluateDerivatives(const typename Dimension::Scalar time, gradVj = newRiemannDvDx(nodeListj,j); } - riemannSolver.interfaceState(i, j, - nodeListi, nodeListj, - ri, rj, + riemannSolver.interfaceState(ri, rj, + Hi, Hj, rhoi, rhoj, ci, cj, Peffi, Peffj, vi, vj, gradPi, gradPj, gradVi, gradVj, - Pstar, - vstar, - rhostari, - rhostarj); + Pstar, //output + vstar, //output + rhostari, //output + rhostarj); //output // get our basis function and interface area vectors //-------------------------------------------------------- diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index 4440f4953..5e020e8c8 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -239,19 +239,18 @@ evaluateDerivatives(const typename Dimension::Scalar time, gradVi = newRiemannDvDx(nodeListi,i); gradVj = newRiemannDvDx(nodeListj,j); } - riemannSolver.interfaceState(i, j, - nodeListi, nodeListj, - ri, rj, + riemannSolver.interfaceState(ri, rj, + Hi, Hj, rhoi, rhoj, ci, cj, Peffi, Peffj, vi, vj, gradPi, gradPj, gradVi, gradVj, - Pstar, - vstar, - rhostari, - rhostarj); + Pstar, //output + vstar, //output + rhostari, //output + rhostarj); //output // get our basis function and interface area vectors //-------------------------------------------------------- diff --git a/src/GSPH/RiemannSolvers/GHLLC.cc b/src/GSPH/RiemannSolvers/GHLLC.cc deleted file mode 100644 index e26aebcfd..000000000 --- a/src/GSPH/RiemannSolvers/GHLLC.cc +++ /dev/null @@ -1,182 +0,0 @@ -//---------------------------------Spheral++----------------------------------// -// GHLLC -- HLLC with gravitational source term -// -// J.M. Pearl 2021 -//----------------------------------------------------------------------------// -#include "FileIO/FileIO.hh" -#include "DataBase/DataBase.hh" -#include "DataBase/State.hh" -#include "DataBase/StateDerivatives.hh" - -#include "Field/FieldList.hh" -#include "Neighbor/ConnectivityMap.hh" - -#include "Hydro/HydroFieldNames.hh" -#include "GSPH/GSPHFieldNames.hh" - -#include "GSPH/WaveSpeeds/WaveSpeedBase.hh" -#include "GSPH/Limiters/LimiterBase.hh" -#include "GSPH/RiemannSolvers/HLLC.hh" -#include "GSPH/RiemannSolvers/GHLLC.hh" - -#include - -namespace Spheral { - -//------------------------------------------------------------------------------ -// Constructor -//------------------------------------------------------------------------------ -template -GHLLC:: -GHLLC(LimiterBase& slopeLimiter, - WaveSpeedBase& waveSpeed, - const bool linearReconstruction, - const typename Dimension::Vector gravitationalAcceleration): - HLLC(slopeLimiter, - waveSpeed, - linearReconstruction), - mGravitationalAcceleration(gravitationalAcceleration){ - -} - -//------------------------------------------------------------------------------ -// Destructor -//------------------------------------------------------------------------------ -template -GHLLC:: -~GHLLC(){} - - -//------------------------------------------------------------------------------ -// Interface State fluid hydro -//------------------------------------------------------------------------------ -// template -// void -// GHLLC:: -// interfaceState(const int i, -// const int j, -// const int nodelisti, -// const int nodelistj, -// const typename Dimension::Vector& ri, -// const typename Dimension::Vector& rj, -// const typename Dimension::Scalar& rhoi, -// const typename Dimension::Scalar& rhoj, -// const typename Dimension::Scalar& ci, -// const typename Dimension::Scalar& cj, -// const typename Dimension::Scalar& Pi, -// const typename Dimension::Scalar& Pj, -// const typename Dimension::Vector& vi, -// const typename Dimension::Vector& vj, -// typename Dimension::Scalar& Pstar, -// typename Dimension::Vector& vstar, -// typename Dimension::Scalar& rhostari, -// typename Dimension::Scalar& rhostarj) const{ - -// // pressure + linear grav contribution -// const auto rhogh = 0.5*(rhoi+rhoj)*mGravitationalAcceleration.dot(ri-rj); -// const auto p1i = Pi - rhogh; -// const auto p1j = Pj + rhogh; -// HLLC::interfaceState(i, -// j, -// nodelisti, -// nodelistj, -// ri, -// rj, -// rhoi, -// rhoj, -// ci, -// cj, -// p1i, -// p1j, -// vi, -// vj, -// Pstar, -// vstar, -// rhostari, -// rhostarj); -// }// Scalar interface class - - -template -void -GHLLC:: -interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const typename Dimension::Vector& ri, - const typename Dimension::Vector& rj, - const typename Dimension::Scalar& rhoi, - const typename Dimension::Scalar& rhoj, - const typename Dimension::Scalar& ci, - const typename Dimension::Scalar& cj, - const typename Dimension::Scalar& Pi, - const typename Dimension::Scalar& Pj, - const typename Dimension::Vector& vi, - const typename Dimension::Vector& vj, - const typename Dimension::Vector& DpDxi, - const typename Dimension::Vector& DpDxj, - const typename Dimension::Tensor& DvDxi, - const typename Dimension::Tensor& DvDxj, - typename Dimension::Scalar& Pstar, - typename Dimension::Vector& vstar, - typename Dimension::Scalar& rhostari, - typename Dimension::Scalar& rhostarj) const{ - - // pressure + linear grav contribution - const auto rhogh = 0.5*(rhoi+rhoj)*mGravitationalAcceleration.dot(ri-rj); - const auto p1i = Pi - rhogh; - const auto p1j = Pj + rhogh; - HLLC::interfaceState(i, - j, - nodelisti, - nodelistj, - ri, - rj, - rhoi, - rhoj, - ci, - cj, - p1i, - p1j, - vi, - vj, - DpDxi, - DpDxj, - DvDxi, - DvDxj, - Pstar, - vstar, - rhostari, - rhostarj); -}// Scalar interface class - -template -void -GHLLC:: -interfaceState(const int /*i*/, - const int /*j*/, - const int /*nodelisti*/, - const int /*nodelistj*/, - const Vector& /*ri*/, - const Vector& /*rj*/, - const Scalar& /*rhoi*/, - const Scalar& /*rhoj*/, - const Scalar& /*ci*/, - const Scalar& /*cj*/, - const Scalar& /*Pi*/, - const Scalar& /*Pj*/, - const Vector& /*vi*/, - const Vector& /*vj*/, - const SymTensor& /*Si*/, - const SymTensor& /*Sj*/, - const Tensor& /*Di*/, - const Tensor& /*Dj*/, - Vector& /*Tstar*/, - Vector& /*vstar*/) const{ - - - -} - -} // spheral namespace \ No newline at end of file diff --git a/src/GSPH/RiemannSolvers/GHLLCInline.hh b/src/GSPH/RiemannSolvers/GHLLCInline.hh deleted file mode 100644 index ad222696e..000000000 --- a/src/GSPH/RiemannSolvers/GHLLCInline.hh +++ /dev/null @@ -1,21 +0,0 @@ -namespace Spheral { - - -//-------------------------------------------------------- -// setter/getter for the gravitational acceleration -//-------------------------------------------------------- -template -typename Dimension::Vector -GHLLC:: -gravitationalAcceleration() const{ - return mGravitationalAcceleration; -} - -template -void -GHLLC:: -gravitationalAcceleration(const typename Dimension::Vector g) { - mGravitationalAcceleration = g; -} - -} \ No newline at end of file diff --git a/src/GSPH/RiemannSolvers/HLLC.cc b/src/GSPH/RiemannSolvers/HLLC.cc index 5094b2de6..a925123ee 100644 --- a/src/GSPH/RiemannSolvers/HLLC.cc +++ b/src/GSPH/RiemannSolvers/HLLC.cc @@ -6,14 +6,6 @@ // J.M. Pearl 2021 //----------------------------------------------------------------------------// -#include "FileIO/FileIO.hh" -#include "DataBase/DataBase.hh" -#include "DataBase/State.hh" -#include "DataBase/StateDerivatives.hh" - -#include "Field/FieldList.hh" -#include "Neighbor/ConnectivityMap.hh" - #include "Hydro/HydroFieldNames.hh" #include "GSPH/GSPHFieldNames.hh" @@ -47,134 +39,16 @@ HLLC:: ~HLLC(){} -//------------------------------------------------------------------------------ -// Interface State scalar -//------------------------------------------------------------------------------ -// template -// void -// HLLC:: -// interfaceState(const int i, -// const int j, -// const int nodelisti, -// const int nodelistj, -// const typename Dimension::Vector& ri, -// const typename Dimension::Vector& rj, -// const typename Dimension::Scalar& rhoi, -// const typename Dimension::Scalar& rhoj, -// const typename Dimension::Scalar& ci, -// const typename Dimension::Scalar& cj, -// const typename Dimension::Scalar& Pi, -// const typename Dimension::Scalar& Pj, -// const typename Dimension::Vector& vi, -// const typename Dimension::Vector& vj, -// typename Dimension::Scalar& Pstar, -// typename Dimension::Vector& vstar, -// typename Dimension::Scalar& /*rhostari*/, -// typename Dimension::Scalar& /*rhostarj*/) const{ - -// Scalar Si, Sj; - -// const auto tiny = std::numeric_limits::epsilon(); - -// const auto& limiter = this->limiter(); -// const auto& waveSpeedObject = this->waveSpeed(); - -// const auto& DpDx0 = this->DpDx(); -// const auto& DvDx0 = this->DvDx(); - -// const auto rij = ri - rj; -// const auto rhatij = rij.unitVector(); - -// vstar = 0.5*(vi+vj); -// Pstar = 0.5*(Pi+Pj); - -// if (ci > tiny or cj > tiny){ - - -// // default to nodal values -// auto v1i = vi; -// auto v1j = vj; - -// auto p1i = Pi; -// auto p1j = Pj; - -// // linear reconstruction -// if(this->linearReconstruction()){ - -// // gradients -// const auto DvDxi = DvDx0(nodelisti,i); -// const auto DvDxj = DvDx0(nodelistj,j); -// const auto DpDxi = DpDx0(nodelisti,i); -// const auto DpDxj = DpDx0(nodelistj,j); - -// // gradients along line of action -// if (true){ -// this->linearReconstruction(ri,rj, Pi,Pj, DpDxi,DpDxj, -// p1i,p1j); -// this->linearReconstruction(ri,rj, vi,vj, DvDxi,DvDxj, -// v1i,v1j); -// }else{ - -// const auto xij = 0.5*(rij); -// const auto Dpi = DpDxi.dot(xij); -// const auto Dpj = DpDxj.dot(xij); -// const auto Dvi = DvDxi.dot(xij); -// const auto Dvj = DvDxj.dot(xij); -// const auto Dui = Dvi.dot(rhatij); -// const auto Duj = Dvj.dot(rhatij); -// //const auto Dp0 = 0.5*(Pi-Pj); -// //const auto Du0 = 0.5*(vi-vj).dot(rhatij); -// const auto rui = Dui/(sgn(Duj)*std::max(tiny, abs(Duj))); -// const auto ruj = Duj/(sgn(Dui)*std::max(tiny, abs(Dui))); -// const auto xu = std::min(rui,ruj); -// const auto phiu = limiter.slopeLimiter(xu); - -// const auto rpi = Dpi/(sgn(Dpj)*std::max(tiny, abs(Dpj))); -// const auto rpj = Dpj/(sgn(Dpi)*std::max(tiny, abs(Dpi))); -// const auto xp = std::min(rpi,rpj); -// const auto phip = limiter.slopeLimiter(xp); - -// v1i = vi - phiu * Dvi; -// v1j = vj + phiu * Dvj; -// p1i = Pi - phip * Dpi; -// p1j = Pj + phip * Dpj; -// } - -// } - -// const auto ui = v1i.dot(rhatij); -// const auto uj = v1j.dot(rhatij); -// const auto wi = v1i - ui*rhatij; -// const auto wj = v1j - uj*rhatij; - -// waveSpeedObject.waveSpeed(rhoi,rhoj,ci,cj,ui,uj,Si,Sj); - -// const auto denom = safeInv(Si - Sj); - -// const auto ustar = (Si*ui - Sj*uj - p1i + p1j )*denom; -// const auto wstar = (Si*wi - Sj*wj)*denom; -// vstar = ustar*rhatij + wstar; -// Pstar = Sj * (ustar-uj) + p1j; - -// }else{ // if ci & cj too small punt to normal av -// const auto uij = std::min((vi-vj).dot(rhatij),0.0); -// Pstar += 0.25 * (rhoi+rhoj) * (uij*uij); -// } -// }// Scalar interface class - - //------------------------------------------------------------------------------ // Interface State fluid hydro //------------------------------------------------------------------------------ template void HLLC:: -interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const typename Dimension::Vector& ri, +interfaceState(const typename Dimension::Vector& ri, const typename Dimension::Vector& rj, + const typename Dimension::SymTensor& Hi, + const typename Dimension::SymTensor& Hj, const typename Dimension::Scalar& rhoi, const typename Dimension::Scalar& rhoj, const typename Dimension::Scalar& ci, @@ -235,9 +109,9 @@ interfaceState(const int i, const auto denom = safeInv(Si - Sj); - const auto ustar = (Si*ui - Sj*uj )*denom; + const auto ustar = (Si*ui - Sj*uj - p1i + p1j )*denom; const auto wstar = (Si*wi - Sj*wj)*denom; - //vstar = ustar*rhatij + wstar; + vstar = ustar*rhatij + wstar; Pstar = Sj * (ustar-uj) + p1j; }else{ // if ci & cj too small punt to normal av @@ -250,12 +124,10 @@ interfaceState(const int i, template void HLLC:: -interfaceState(const int /*i*/, - const int /*j*/, - const int /*nodelisti*/, - const int /*nodelistj*/, - const Vector& /*ri*/, +interfaceState(const Vector& /*ri*/, const Vector& /*rj*/, + const SymTensor& /*Hi*/, + const SymTensor& /*Hj*/, const Scalar& /*rhoi*/, const Scalar& /*rhoj*/, const Scalar& /*ci*/, diff --git a/src/GSPH/RiemannSolvers/HLLC.hh b/src/GSPH/RiemannSolvers/HLLC.hh index c885583f5..822bae67a 100644 --- a/src/GSPH/RiemannSolvers/HLLC.hh +++ b/src/GSPH/RiemannSolvers/HLLC.hh @@ -37,34 +37,11 @@ public: ~HLLC(); - // virtual - // void interfaceState(const int i, - // const int j, - // const int nodelisti, - // const int nodelistj, - // const Vector& ri, - // const Vector& rj, - // const Scalar& rhoi, - // const Scalar& rhoj, - // const Scalar& ci, - // const Scalar& cj, - // const Scalar& sigmai, - // const Scalar& sigmaj, - // const Vector& vi, - // const Vector& vj, - // Scalar& Pstar, - // Vector& vstar, - // Scalar& rhostari, - // Scalar& rhostarj) const override; - - // ^ temporary class to wrap the above ^ virtual - void interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const Vector& ri, + void interfaceState(const Vector& ri, const Vector& rj, + const SymTensor& Hi, + const SymTensor& Hj, const Scalar& rhoi, const Scalar& rhoj, const Scalar& ci, @@ -84,12 +61,10 @@ public: virtual - void interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const Vector& ri, + void interfaceState(const Vector& ri, const Vector& rj, + const SymTensor& Hi, + const SymTensor& Hj, const Scalar& rhoi, const Scalar& rhoj, const Scalar& ci, diff --git a/src/GSPH/RiemannSolvers/RiemannSolverBase.cc b/src/GSPH/RiemannSolvers/RiemannSolverBase.cc index 4e68e2f91..3c062bc62 100644 --- a/src/GSPH/RiemannSolvers/RiemannSolverBase.cc +++ b/src/GSPH/RiemannSolvers/RiemannSolverBase.cc @@ -35,8 +35,6 @@ RiemannSolverBase(LimiterBase& slopeLimiter, mSlopeLimiter(slopeLimiter), mWaveSpeed(waveSpeed), mLinearReconstruction(linearReconstruction){ - //mDpDx(FieldStorageType::CopyFields), - //mDvDx(FieldStorageType::CopyFields){ } //------------------------------------------------------------------------------ @@ -52,92 +50,15 @@ RiemannSolverBase:: template void RiemannSolverBase:: -initialize(const DataBase& dataBase, - const State& state, - const StateDerivatives& derivs, - typename RiemannSolverBase::ConstBoundaryIterator boundaryBegin, - typename RiemannSolverBase::ConstBoundaryIterator boundaryEnd, +initialize(const DataBase& /*dataBase*/, + const State& /*state*/, + const StateDerivatives& /*derivs*/, + typename RiemannSolverBase::ConstBoundaryIterator /*boundaryBegin*/, + typename RiemannSolverBase::ConstBoundaryIterator /*boundaryEnd*/, const typename Dimension::Scalar /*time*/, const typename Dimension::Scalar /*dt*/, const TableKernel& /*W*/){ - // if(mLinearReconstruction){ - // dataBase.resizeFluidFieldList(mDpDx,Vector::zero,GSPHFieldNames::RiemannPressureGradient0,true); - // dataBase.resizeFluidFieldList(mDvDx,Tensor::zero,GSPHFieldNames::RiemannVelocityGradient0,true); - - // //const auto& DpDx0 = derivs.fields( GSPHFieldNames::pressureGradient, Vector::zero); - // //const auto& DpDxRaw0 = derivs.fields( GSPHFieldNames::pressureGradient+"RAW", Vector::zero); - // const auto& DvDx0 = derivs.fields( HydroFieldNames::velocityGradient,Tensor::zero); - // //const auto& localDvDx0 = derivs.fields( HydroFieldNames::internalVelocityGradient,Tensor::zero); - // //const auto& DvDxRaw0 = derivs.fields( HydroFieldNames::velocityGradient+"RAW",Tensor::zero); - // const auto& DvDt0 = derivs.fields(HydroFieldNames::hydroAcceleration, Vector::zero); - // const auto& rho0 = state.fields(HydroFieldNames::massDensity, 0.0); - - // const auto& connectivityMap = dataBase.connectivityMap(); - // const auto& nodeLists = connectivityMap.nodeLists(); - // const auto numNodeLists = nodeLists.size(); - - // // copy from previous time step - // for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { - // const auto& nodeList = nodeLists[nodeListi]; - // const auto ni = nodeList->numInternalNodes(); - // #pragma omp parallel for - // for (auto i = 0u; i < ni; ++i) { - // //const auto localDvDxi = localDvDx0(nodeListi,i); - // const auto DvDxi = DvDx0(nodeListi,i); - // //const auto DvDxRawi = DvDxRaw0(nodeListi,i); - // //const auto DpDxi = DpDx0(nodeListi,i); - // //const auto DpDxRawi = DpDxRaw0(nodeListi,i); - // const auto DvDti = DvDt0(nodeListi,i); - // const auto rhoi = rho0(nodeListi,i); - - // // this'll need some cleaning - // // switch(mGradientType){ - // // case GradientType::RiemannGradient: // default grad based on riemann soln - // mDvDx(nodeListi,i) = DvDxi; - // mDpDx(nodeListi,i) = -rhoi*DvDti; - // // break; - // // case GradientType::HydroAccelerationGradient: // based on hydro accel for DpDx - // // mDvDx(nodeListi,i) = DvDxi; - // // mDpDx(nodeListi,i) = -rhoi*DvDti; - // // break; - // // case GradientType::SPHGradient: // raw gradients - // // mDvDx(nodeListi,i) = DvDxRawi; - // // mDpDx(nodeListi,i) = DpDxRawi; - // // break; - // // case GradientType::MixedMethodGradient: // raw gradient for P riemann gradient for v - // // mDvDx(nodeListi,i) = DvDxi; - // // mDpDx(nodeListi,i) = DpDxRawi; - // // break; - // // case GradientType::OnlyDvDxGradient: // raw gradients - // // mDvDx(nodeListi,i) = DvDxi; - // // mDpDx(nodeListi,i) = Vector::zero; - // // break; - // // case GradientType::LocalDvDxGradient: // local velocity gradient - // // mDvDx(nodeListi,i) = localDvDxi; - // // mDpDx(nodeListi,i) = DpDxi; - // // break; - // // default : - // // mDvDx(nodeListi,i) = Tensor::zero; - // // mDpDx(nodeListi,i) = Vector::zero; - - // // } - // } - // } - - // for (auto boundItr = boundaryBegin; - // boundItr != boundaryEnd; - // ++boundItr) { - // (*boundItr)->applyFieldListGhostBoundary(mDpDx); - // (*boundItr)->applyFieldListGhostBoundary(mDvDx); - // } - - // for (auto boundItr = boundaryBegin; - // boundItr != boundaryEnd; - // ++boundItr) (*boundItr)->finalizeGhostBoundary(); - - // } // if LinearReconstruction - } // initialize method @@ -227,39 +148,15 @@ linearReconstruction(const typename Dimension::Vector& ri, //------------------------------------------------------------------------------ // default to non-op //------------------------------------------------------------------------------ -// template -// void -// RiemannSolverBase:: -// interfaceState(const int /*i*/, -// const int /*j*/, -// const int /*nodelisti*/, -// const int /*nodelistj*/, -// const Vector& /*ri*/, -// const Vector& /*rj*/, -// const Scalar& /*rhoi*/, -// const Scalar& /*rhoj*/, -// const Scalar& /*ci*/, -// const Scalar& /*cj*/, -// const Scalar& /*sigmai*/, -// const Scalar& /*sigmaj*/, -// const Vector& /*vi*/, -// const Vector& /*vj*/, -// Scalar& /*Pstar*/, -// Vector& /*vstar*/, -// Scalar& /*rhostari*/, -// Scalar& /*rhostarj*/) const{ -// } template void RiemannSolverBase:: -interfaceState(const int /*i*/, - const int /*j*/, - const int /*nodelisti*/, - const int /*nodelistj*/, - const Vector& /*ri*/, +interfaceState(const Vector& /*ri*/, const Vector& /*rj*/, + const SymTensor& /*Hi*/, + const SymTensor& /*Hj*/, const Scalar& /*rhoi*/, const Scalar& /*rhoj*/, const Scalar& /*ci*/, @@ -285,12 +182,10 @@ interfaceState(const int /*i*/, template void RiemannSolverBase:: -interfaceState(const int /*i*/, - const int /*j*/, - const int /*nodelisti*/, - const int /*nodelistj*/, - const Vector& /*ri*/, +interfaceState(const Vector& /*ri*/, const Vector& /*rj*/, + const SymTensor& /*Hi*/, + const SymTensor& /*Hj*/, const Scalar& /*rhoi*/, const Scalar& /*rhoj*/, const Scalar& /*ci*/, diff --git a/src/GSPH/RiemannSolvers/RiemannSolverBase.hh b/src/GSPH/RiemannSolvers/RiemannSolverBase.hh index d1f62c9aa..0743bfb49 100644 --- a/src/GSPH/RiemannSolvers/RiemannSolverBase.hh +++ b/src/GSPH/RiemannSolvers/RiemannSolverBase.hh @@ -46,33 +46,12 @@ public: const Scalar dt, const TableKernel& W); - // virtual - // void interfaceState(const int i, - // const int j, - // const int nodelisti, - // const int nodelistj, - // const Vector& ri, - // const Vector& rj, - // const Scalar& rhoi, - // const Scalar& rhoj, - // const Scalar& ci, - // const Scalar& cj, - // const Scalar& Pi, - // const Scalar& Pj, - // const Vector& vi, - // const Vector& vj, - // Scalar& Pstar, - // Vector& vstar, - // Scalar& rhostari, - // Scalar& rhostarj) const; virtual - void interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const Vector& ri, + void interfaceState(const Vector& ri, const Vector& rj, + const SymTensor& Hi, + const SymTensor& Hj, const Scalar& rhoi, const Scalar& rhoj, const Scalar& ci, @@ -92,12 +71,10 @@ public: virtual - void interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const Vector& ri, + void interfaceState(const Vector& ri, const Vector& rj, + const SymTensor& Hi, + const SymTensor& Hj, const Scalar& rhoi, const Scalar& rhoj, const Scalar& ci, @@ -118,9 +95,6 @@ public: bool linearReconstruction() const; void linearReconstruction(bool x); - - // GradientType gradientType() const; - // void gradientType(GradientType x); virtual void linearReconstruction(const Vector& ri, @@ -142,22 +116,13 @@ public: Vector& ytildei, Vector& ytildej) const; - // we'll want the ability to modify these (make better) - // FieldList& DpDx(); - // FieldList& DvDx(); - // const FieldList& DpDx() const; - // const FieldList& DvDx() const; private: LimiterBase& mSlopeLimiter; WaveSpeedBase& mWaveSpeed; bool mLinearReconstruction; - //GradientType mGradientType; - - // FieldList mDpDx; - // FieldList mDvDx; }; diff --git a/src/GSPH/RiemannSolvers/RiemannSolverBaseInline.hh b/src/GSPH/RiemannSolvers/RiemannSolverBaseInline.hh index 6df4c6f3a..d04dec1d2 100644 --- a/src/GSPH/RiemannSolvers/RiemannSolverBaseInline.hh +++ b/src/GSPH/RiemannSolvers/RiemannSolverBaseInline.hh @@ -41,44 +41,4 @@ linearReconstruction(bool x) { mLinearReconstruction=x; } - -//------------------------------------------------------------------------------ -// field getters -//------------------------------------------------------------------------------ - - -// template -// inline -// FieldList& -// RiemannSolverBase:: -// DpDx() { -// return mDpDx; -// } - -// template -// inline -// FieldList& -// RiemannSolverBase:: -// DvDx() { -// return mDvDx; -// } - - -// template -// inline -// const FieldList& -// RiemannSolverBase:: -// DpDx() const { -// return mDpDx; -// } - -// template -// inline -// const FieldList& -// RiemannSolverBase:: -// DvDx() const { -// return mDvDx; -// } - - } \ No newline at end of file diff --git a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc new file mode 100644 index 000000000..43c0a2de8 --- /dev/null +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc @@ -0,0 +1,133 @@ +//---------------------------------Spheral++----------------------------------// +// SecondOrderArtificialViscosity -- approximate riemann solver +// Frontiere, Raskin, Owen (2017) "CRKSPH:- A Conservative Reproducing Kernel +// Smoothed Particle Hydrodynamics Scheme," J. Comp. Phys. +// +// This is a reimplementation of the LimitedArtificialViscosity class as a +// derivative of RiemannSolverBase so it can be used with GSPH derived +// classes +// +// J.M. Pearl 2021 +//----------------------------------------------------------------------------// + +#include "Hydro/HydroFieldNames.hh" +#include "GSPH/GSPHFieldNames.hh" + +#include "GSPH/WaveSpeeds/WaveSpeedBase.hh" +#include "GSPH/Limiters/LimiterBase.hh" +#include "GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh" + +#include + +namespace Spheral { + +//------------------------------------------------------------------------------ +// Constructor +//------------------------------------------------------------------------------ +template +SecondOrderArtificialViscosity:: +SecondOrderArtificialViscosity(const Scalar Cl, + const Scalar Cq, + LimiterBase& slopeLimiter, + WaveSpeedBase& waveSpeed, + const bool linearReconstruction): + RiemannSolverBase(slopeLimiter, + waveSpeed, + linearReconstruction), + mCl(Cl), + mCq(Cq){ + +} + +//------------------------------------------------------------------------------ +// Destructor +//------------------------------------------------------------------------------ +template +SecondOrderArtificialViscosity:: +~SecondOrderArtificialViscosity(){} + + +//------------------------------------------------------------------------------ +// Interface State fluid hydro +//------------------------------------------------------------------------------ +template +void +SecondOrderArtificialViscosity:: +interfaceState(const typename Dimension::Vector& ri, + const typename Dimension::Vector& rj, + const typename Dimension::SymTensor& Hi, + const typename Dimension::SymTensor& Hj, + const typename Dimension::Scalar& rhoi, + const typename Dimension::Scalar& rhoj, + const typename Dimension::Scalar& ci, + const typename Dimension::Scalar& cj, + const typename Dimension::Scalar& Pi, + const typename Dimension::Scalar& Pj, + const typename Dimension::Vector& vi, + const typename Dimension::Vector& vj, + const typename Dimension::Vector& DpDxi, + const typename Dimension::Vector& DpDxj, + const typename Dimension::Tensor& DvDxi, + const typename Dimension::Tensor& DvDxj, + typename Dimension::Scalar& Pstar, + typename Dimension::Vector& vstar, + typename Dimension::Scalar& /*rhostari*/, + typename Dimension::Scalar& /*rhostarj*/) const{ + + + const auto tiny = std::numeric_limits::epsilon(); + + const Vector rij = ri - rj; + const Vector rhatij = rij.unitVector(); + const Vector etaij = 0.5*(Hi+Hj)*rij; + + // default to nodal values + Vector v1i = vi; + Vector v1j = vj; + + // linear reconstruction + if(this->linearReconstruction()){ + + this->linearReconstruction(ri,rj, vi,vj,DvDxi,DvDxj, //inputs + v1i,v1j); //outputs + + } + const Vector vij = v1i-v1j; + const Scalar muij = std::max(0.0,-vij.dot(etaij)/(etaij.magnitude2() + tiny)); + const Scalar cij = 0.5*(ci+cj); + const Scalar rhoij = 2*rhoi*rhoj/(rhoi+rhoj); + Pstar = 0.5*(Pi+Pj) + + rhoij*muij*(this->Cl()*cij + +this->Cq()*muij); + vstar = 0.5*(vi+vj); + +}// Scalar interface class + + +template +void +SecondOrderArtificialViscosity:: +interfaceState(const Vector& /*ri*/, + const Vector& /*rj*/, + const SymTensor& /*Hi*/, + const SymTensor& /*Hj*/, + const Scalar& /*rhoi*/, + const Scalar& /*rhoj*/, + const Scalar& /*ci*/, + const Scalar& /*cj*/, + const Scalar& /*Pi*/, + const Scalar& /*Pj*/, + const Vector& /*vi*/, + const Vector& /*vj*/, + const SymTensor& /*Si*/, + const SymTensor& /*Sj*/, + const Tensor& /*Di*/, + const Tensor& /*Dj*/, + Vector& /*Tstar*/, + Vector& /*vstar*/) const{ + + + +} + +} // spheral namespace \ No newline at end of file diff --git a/src/GSPH/RiemannSolvers/GHLLC.hh b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh similarity index 56% rename from src/GSPH/RiemannSolvers/GHLLC.hh rename to src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh index 43033bf17..c99881ffe 100644 --- a/src/GSPH/RiemannSolvers/GHLLC.hh +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh @@ -1,10 +1,15 @@ //---------------------------------Spheral++----------------------------------// -// GHLLC -- HLLC solver w/ gravitational source term +// SecondOrderArtificialViscosity -- approximate riemann solver +// Toro E.F., Spruce M., Speares W., (1994) "Restoration of the Contact Surface in +// the HLL-Riemann Solver," Shock Waves, 4:25-34 +// +// J.M. Pearl 2021 //----------------------------------------------------------------------------// -#ifndef __Spheral_GHLLC_hh__ -#define __Spheral_GHLLC_hh__ -#include "HLLC.hh" +#ifndef __Spheral_SecondOrderArtificialViscosity_hh__ +#define __Spheral_SecondOrderArtificialViscosity_hh__ + +#include "RiemannSolverBase.hh" namespace Spheral { @@ -17,7 +22,7 @@ template class Field; template class FieldList; template -class GHLLC : public HLLC { +class SecondOrderArtificialViscosity : public RiemannSolverBase { typedef typename Dimension::Scalar Scalar; typedef typename Dimension::Vector Vector; @@ -26,40 +31,20 @@ class GHLLC : public HLLC { public: - GHLLC(LimiterBase& slopeLimiter, - WaveSpeedBase& waveSpeedBase, - const bool linearReconstruction, - const Vector gravitationalAcceleration); - - ~GHLLC(); - - // virtual - // void interfaceState(const int i, - // const int j, - // const int nodelisti, - // const int nodelistj, - // const Vector& ri, - // const Vector& rj, - // const Scalar& rhoi, - // const Scalar& rhoj, - // const Scalar& ci, - // const Scalar& cj, - // const Scalar& sigmai, - // const Scalar& sigmaj, - // const Vector& vi, - // const Vector& vj, - // Scalar& Pstar, - // Vector& vstar, - // Scalar& rhostari, - // Scalar& rhostarj) const override; + SecondOrderArtificialViscosity(const Scalar Cl, + const Scalar Cq, + LimiterBase& slopeLimiter, + WaveSpeedBase& waveSpeedBase, + const bool linearReconstruction); + + ~SecondOrderArtificialViscosity(); + virtual - void interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const Vector& ri, + void interfaceState(const Vector& ri, const Vector& rj, + const SymTensor& Hi, + const SymTensor& Hj, const Scalar& rhoi, const Scalar& rhoj, const Scalar& ci, @@ -77,13 +62,12 @@ public: Scalar& rhostari, Scalar& rhostarj) const override; + virtual - void interfaceState(const int i, - const int j, - const int nodelisti, - const int nodelistj, - const Vector& ri, + void interfaceState(const Vector& ri, const Vector& rj, + const SymTensor& Hi, + const SymTensor& Hj, const Scalar& rhoi, const Scalar& rhoj, const Scalar& ci, @@ -99,23 +83,27 @@ public: Vector& Tstar, Vector& vstar) const override; - - void gravitationalAcceleration(const Vector g); - Vector gravitationalAcceleration() const; + Scalar Cl() const; + void Cl(const Scalar x); + + Scalar Cq() const; + void Cq(const Scalar x); private: - Vector mGravitationalAcceleration; + Scalar mCl; + Scalar mCq; + }; } -#include "GHLLCInline.hh" +#include "SecondOrderArtificialViscosityInline.hh" #else // Forward declaration. namespace Spheral { - template class GHLLC; + template class SecondOrderArtificialViscosity; } #endif diff --git a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosityInline.hh b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosityInline.hh new file mode 100644 index 000000000..baa102bd7 --- /dev/null +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosityInline.hh @@ -0,0 +1,40 @@ +namespace Spheral { + +//------------------------------------------------------------------------------ +// set/get linear reconstruction switch +//------------------------------------------------------------------------------ +template +inline +typename Dimension::Scalar +SecondOrderArtificialViscosity:: +Cl() const { + return mCl; +} + +template +inline +void +SecondOrderArtificialViscosity:: +Cl(typename Dimension::Scalar x) { + mCl=x; +} + + +template +inline +typename Dimension::Scalar +SecondOrderArtificialViscosity:: +Cq() const { + return mCq; +} + +template +inline +void +SecondOrderArtificialViscosity:: +Cq(typename Dimension::Scalar x) { + mCq=x; +} + + +} \ No newline at end of file diff --git a/src/GSPH/RiemannSolvers/GHLLCInst.cc.py b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosityInst.cc.py similarity index 66% rename from src/GSPH/RiemannSolvers/GHLLCInst.cc.py rename to src/GSPH/RiemannSolvers/SecondOrderArtificialViscosityInst.cc.py index db174ede1..4aebeff1f 100644 --- a/src/GSPH/RiemannSolvers/GHLLCInst.cc.py +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosityInst.cc.py @@ -3,9 +3,9 @@ // Explicit instantiation. //------------------------------------------------------------------------------ #include "Geometry/Dimension.hh" -#include "GSPH/RiemannSolvers/GHLLC.cc" +#include "GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc" namespace Spheral { - template class GHLLC >; + template class SecondOrderArtificialViscosity >; } """ diff --git a/src/Pybind11Wraps/GSPH/GSPHMOD.py b/src/Pybind11Wraps/GSPH/GSPHMOD.py index c465528a4..34ece28c5 100644 --- a/src/Pybind11Wraps/GSPH/GSPHMOD.py +++ b/src/Pybind11Wraps/GSPH/GSPHMOD.py @@ -34,7 +34,7 @@ '"GSPH/Limiters/OspreLimiter.hh"', '"GSPH/RiemannSolvers/RiemannSolverBase.hh"', '"GSPH/RiemannSolvers/HLLC.hh"', - '"GSPH/RiemannSolvers/GHLLC.hh"', + '"GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh"', '"FileIO/FileIO.hh"'] #------------------------------------------------------------------------------- @@ -71,7 +71,7 @@ OspreLimiter%(ndim)id = PYB11TemplateClass(OspreLimiter, template_parameters="%(Dimension)s") RiemannSolverBase%(ndim)id = PYB11TemplateClass(RiemannSolverBase, template_parameters="%(Dimension)s") HLLC%(ndim)id = PYB11TemplateClass(HLLC, template_parameters="%(Dimension)s") -GHLLC%(ndim)id = PYB11TemplateClass(GHLLC, template_parameters="%(Dimension)s") +SecondOrderArtificialViscosity%(ndim)id = PYB11TemplateClass(SecondOrderArtificialViscosity, template_parameters="%(Dimension)s") ''' % {"ndim" : ndim, "Dimension" : "Dim<" + str(ndim) + ">"}) diff --git a/src/Pybind11Wraps/GSPH/RiemannSolverBaseAbstractMethods.py b/src/Pybind11Wraps/GSPH/RiemannSolverBaseAbstractMethods.py deleted file mode 100644 index 2a66cdc4d..000000000 --- a/src/Pybind11Wraps/GSPH/RiemannSolverBaseAbstractMethods.py +++ /dev/null @@ -1,55 +0,0 @@ -#------------------------------------------------------------------------------- -# wave Speed pure virtual interface -#------------------------------------------------------------------------------- -#from PYB11Generator import * - -# @PYB11ignore -# class RiemannSolverBaseAbstractMethods: - -# @PYB11const -# def inferfaceState(self, -# i = "const int", -# j = "const int", -# nodelisti = "const int", -# nodelistj = "const int", -# ri = "const Vector&", -# rj = "const Vector&", -# rhoi = "const Scalar&", -# rhoj = "const Scalar&", -# ci = "const Scalar&", -# cj = "const Scalar&", -# sigmai = "const Scalar&", -# sigmaj = "const Scalar&", -# vi = "const Vector&", -# vj = "const Vector&", -# Pstar = "Scalar&", -# ustar = "Scalar&"): -# "calculate riemann solution." -# return "void" - - # @PYB11const - # def inferfaceState(self, - # i = "const int", - # j = "const int", - # nodelisti = "const int", - # nodelistj = "const int", - # ri = "const Vector&", - # rj = "const Vector&", - # rhoi = "const Scalar&", - # rhoj = "const Scalar&", - # ci = "const Scalar&", - # cj = "const Scalar&", - # Pi = "const Scalar&", - # Pj = "const Scalar&", - # vi = "const Vector&", - # vj = "const Vector&", - # Si = "const SymTensor&", - # Sj = "const SymTensor&", - # Di = "const Tensor&", - # Dj = "const Tensor&", - # Tstar = "Vector&", - # vstar = "Vector&"): - # "calculate riemann solution." - # return "void" - - diff --git a/src/Pybind11Wraps/GSPH/RiemannSolvers.py b/src/Pybind11Wraps/GSPH/RiemannSolvers.py index 3c1c4a1db..1f3206327 100644 --- a/src/Pybind11Wraps/GSPH/RiemannSolvers.py +++ b/src/Pybind11Wraps/GSPH/RiemannSolvers.py @@ -25,11 +25,6 @@ def pyinit(slopeLimiter = "LimiterBase<%(Dimension)s>&", waveSpeed = PYB11property("WaveSpeedBase<%(Dimension)s>&", "waveSpeed",returnpolicy="reference_internal", doc="wave speed object") limiter = PYB11property("LimiterBase<%(Dimension)s>&", "limiter",returnpolicy="reference_internal", doc="slope limiter object") - #DpDx = PYB11property("const FieldList<%(Dimension)s, Vector>&", "DpDx",returnpolicy="reference_internal") - #DvDx = PYB11property("const FieldList<%(Dimension)s, Tensor>&", "DvDx",returnpolicy="reference_internal") - -#PYB11inject(RiemannSolverBaseAbstractMethods, RiemannSolverBase, pure_virtual=True) - #------------------------------------------------------------------------------- # HLLC Approximate Riemann Solver #------------------------------------------------------------------------------- @@ -47,10 +42,11 @@ def pyinit(slopeLimiter = "LimiterBase<%(Dimension)s>&", linearReconstruction = "const bool"): "slope limiter constructor" + #------------------------------------------------------------------------------- -# HLLC Approximate Riemann Solver with constant grav acceleration +# HLLC Approximate Riemann Solver #------------------------------------------------------------------------------- -class GHLLC(HLLC): +class SecondOrderArtificialViscosity(RiemannSolverBase): PYB11typedefs = """ typedef typename %(Dimension)s::Scalar Scalar; @@ -59,11 +55,12 @@ class GHLLC(HLLC): typedef typename %(Dimension)s::SymTensor SymTensor; """ - def pyinit(slopeLimiter = "LimiterBase<%(Dimension)s>&", + def pyinit(Cl = "const Scalar", + Cq = "const Scalar", + slopeLimiter = "LimiterBase<%(Dimension)s>&", waveSpeed = "WaveSpeedBase<%(Dimension)s>&", - linearReconstruction = "const bool", - gravitationalAcceleration = "const Vector"): + linearReconstruction = "const bool"): "slope limiter constructor" - - gravitationalAcceleration = PYB11property("Vector", "gravitationalAcceleration", "gravitationalAcceleration", doc="constant gravitational acceleration vector") + Cl = PYB11property("Scalar", "Cl", "Cl", doc="linear artificial viscosity coefficient") + Cq = PYB11property("Scalar", "Cq", "Cq", doc="quadratic artificial viscosity coefficient") From 5685c8b0c2ed6fc776b709adabc8fd1d7f903fe9 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 5 Oct 2022 10:32:35 -0700 Subject: [PATCH 11/60] MFV placeholders --- src/GSPH/MFVEvaluateDerivatives.cc | 596 +++++++++++++++++++++++++++++ src/GSPH/MFVHydroBase.cc | 290 ++++++++++++++ src/GSPH/MFVHydroBase.hh | 155 ++++++++ src/GSPH/MFVHydroBaseInline.hh | 12 + src/GSPH/MFVHydroBaseInst.cc.py | 12 + 5 files changed, 1065 insertions(+) create mode 100644 src/GSPH/MFVEvaluateDerivatives.cc create mode 100644 src/GSPH/MFVHydroBase.cc create mode 100644 src/GSPH/MFVHydroBase.hh create mode 100644 src/GSPH/MFVHydroBaseInline.hh create mode 100644 src/GSPH/MFVHydroBaseInst.cc.py diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc new file mode 100644 index 000000000..8a1194ece --- /dev/null +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -0,0 +1,596 @@ +namespace Spheral { +//------------------------------------------------------------------------------ +// Determine the principle derivatives. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +evaluateDerivatives(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const { + + const auto& riemannSolver = this->riemannSolver(); + + const auto& smoothingScale = this->smoothingScaleMethod(); + + // A few useful constants we'll use in the following loop. + const auto tiny = std::numeric_limits::epsilon(); + const auto xsph = this->XSPH(); + const auto epsTensile = this->epsilonTensile(); + //const auto epsDiffusionCoeff = this->specificThermalEnergyDiffusionCoefficient(); + const auto compatibleEnergy = this->compatibleEnergyEvolution(); + const auto totalEnergy = this->evolveTotalEnergy(); + const auto gradType = this->gradientType(); + //const auto correctVelocityGradient = this->correctVelocityGradient(); + + // The connectivity. + const auto& connectivityMap = dataBase.connectivityMap(); + const auto& nodeLists = connectivityMap.nodeLists(); + const auto& pairs = connectivityMap.nodePairList(); + const auto npairs = pairs.size(); + const auto numNodeLists = nodeLists.size(); + const auto nPerh = nodeLists[0]->nodesPerSmoothingScale(); + + // kernel + const auto& W = this->kernel(); + const auto WnPerh = W(1.0/nPerh, 1.0); + const auto W0 = W(0.0, 1.0); + + // Get the state and derivative FieldLists. + // State FieldLists. + const auto mass = state.fields(HydroFieldNames::mass, 0.0); + const auto position = state.fields(HydroFieldNames::position, Vector::zero); + const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); + const auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); + const auto volume = state.fields(HydroFieldNames::volume, 0.0); + const auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); + const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); + const auto pressure = state.fields(HydroFieldNames::pressure, 0.0); + const auto soundSpeed = state.fields(HydroFieldNames::soundSpeed, 0.0); + const auto riemannDpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); + const auto riemannDvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + + CHECK(mass.size() == numNodeLists); + CHECK(position.size() == numNodeLists); + CHECK(velocity.size() == numNodeLists); + CHECK(massDensity.size() == numNodeLists); + CHECK(volume.size() == numNodeLists); + CHECK(specificThermalEnergy.size() == numNodeLists); + CHECK(H.size() == numNodeLists); + CHECK(pressure.size() == numNodeLists); + CHECK(soundSpeed.size() == numNodeLists); + CHECK(riemannDpDx.size() == numNodeLists); + CHECK(riemannDvDx.size() == numNodeLists); + + // Derivative FieldLists. + const auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto normalization = derivatives.fields(HydroFieldNames::normalization, 0.0); + auto DxDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::position, Vector::zero); + auto DvolDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::volume, 0.0); + auto DvDt = derivatives.fields(HydroFieldNames::hydroAcceleration, Vector::zero); + auto DepsDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); + auto DvDx = derivatives.fields(HydroFieldNames::velocityGradient, Tensor::zero); + auto DHDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::H, SymTensor::zero); + auto Hideal = derivatives.fields(ReplaceBoundedFieldList::prefix() + HydroFieldNames::H, SymTensor::zero); + auto& pairAccelerations = derivatives.getAny(HydroFieldNames::pairAccelerations, vector()); + auto& pairDepsDt = derivatives.getAny(HydroFieldNames::pairWork, vector()); + auto XSPHDeltaV = derivatives.fields(HydroFieldNames::XSPHDeltaV, Vector::zero); + auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); + auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); + auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); + auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + + CHECK(M.size() == numNodeLists); + CHECK(normalization.size() == numNodeLists); + CHECK(DxDt.size() == numNodeLists); + CHECK(DvolDt.size() == numNodeLists); + CHECK(DvDt.size() == numNodeLists); + CHECK(DepsDt.size() == numNodeLists); + CHECK(DvDx.size() == numNodeLists); + CHECK(DHDt.size() == numNodeLists); + CHECK(Hideal.size() == numNodeLists); + CHECK(XSPHDeltaV.size() == numNodeLists); + CHECK(weightedNeighborSum.size() == numNodeLists); + CHECK(massSecondMoment.size() == numNodeLists); + CHECK(newRiemannDpDx.size() == numNodeLists); + CHECK(newRiemannDvDx.size() == numNodeLists); + + if (compatibleEnergy){ + pairAccelerations.resize(npairs); + pairDepsDt.resize(2*npairs); + } + + this->computeMCorrection(time,dt,dataBase,state,derivatives); + + // Walk all the interacting pairs. +#pragma omp parallel + { + // Thread private scratch variables + int i, j, nodeListi, nodeListj; + Scalar psii,psij, Wi, gWi, Wj, gWj, Pstar, rhostari, rhostarj; + Vector gradPsii, gradPsij, Ai, Aj, vstar; + + typename SpheralThreads::FieldListStack threadStack; + auto DvDt_thread = DvDt.threadCopy(threadStack); + auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); + auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); + auto DepsDt_thread = DepsDt.threadCopy(threadStack); + auto DvDx_thread = DvDx.threadCopy(threadStack); + auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); + auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); + auto XSPHDeltaV_thread = XSPHDeltaV.threadCopy(threadStack); + auto normalization_thread = normalization.threadCopy(threadStack); + +#pragma omp for + for (auto kk = 0u; kk < npairs; ++kk) { + i = pairs[kk].i_node; + j = pairs[kk].j_node; + nodeListi = pairs[kk].i_list; + nodeListj = pairs[kk].j_list; + + // Get the state for node i. + const auto& riemannDpDxi = riemannDpDx(nodeListi, i); + const auto& riemannDvDxi = riemannDvDx(nodeListi, i); + const auto& ri = position(nodeListi, i); + const auto& mi = mass(nodeListi, i); + const auto& vi = velocity(nodeListi, i); + const auto& rhoi = massDensity(nodeListi, i); + const auto& voli = volume(nodeListi, i); + //const auto& epsi = specificThermalEnergy(nodeListi, i); + const auto& Pi = pressure(nodeListi, i); + const auto& Hi = H(nodeListi, i); + const auto& ci = soundSpeed(nodeListi, i); + const auto Hdeti = Hi.Determinant(); + CHECK(mi > 0.0); + CHECK(voli > 0.0); + CHECK(rhoi > 0.0); + CHECK(Hdeti > 0.0); + + auto& normi = normalization_thread(nodeListi,i); + auto& DepsDti = DepsDt_thread(nodeListi, i); + auto& DvDti = DvDt_thread(nodeListi, i); + auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi,i); + auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi,i); + auto& DvDxi = DvDx_thread(nodeListi, i); + auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); + auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); + auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); + const auto& Mi = M(nodeListi,i); + + + // Get the state for node j + const auto& riemannDpDxj = riemannDpDx(nodeListj, j); + const auto& riemannDvDxj = riemannDvDx(nodeListj, j); + const auto& rj = position(nodeListj, j); + const auto& mj = mass(nodeListj, j); + const auto& vj = velocity(nodeListj, j); + const auto& rhoj = massDensity(nodeListj, j); + const auto& volj = volume(nodeListj, j); + //const auto& epsj = specificThermalEnergy(nodeListj, j); + const auto& Pj = pressure(nodeListj, j); + const auto& Hj = H(nodeListj, j); + const auto& cj = soundSpeed(nodeListj, j); + const auto Hdetj = Hj.Determinant(); + CHECK(mj > 0.0); + CHECK(rhoj > 0.0); + CHECK(volj > 0.0); + CHECK(Hdetj > 0.0); + + auto& normj = normalization_thread(nodeListj,j); + auto& DvDtj = DvDt_thread(nodeListj, j); + auto& DepsDtj = DepsDt_thread(nodeListj, j); + auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj,j); + auto& newRiemannDvDxj = newRiemannDvDx_thread(nodeListj,j); + auto& DvDxj = DvDx_thread(nodeListj, j); + auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); + auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); + auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); + const auto& Mj = M(nodeListj,j); + + // Node displacement. + const auto rij = ri - rj; + const auto rhatij =rij.unitVector(); + const auto vij = vi - vj; + const auto etai = Hi*rij; + const auto etaj = Hj*rij; + const auto etaMagi = etai.magnitude(); + const auto etaMagj = etaj.magnitude(); + CHECK(etaMagi >= 0.0); + CHECK(etaMagj >= 0.0); + + + // Symmetrized kernel weight and gradient. + W.kernelAndGradValue(etaMagi, Hdeti, Wi, gWi); + const auto Hetai = Hi*etai.unitVector(); + const auto gradWi = gWi*Hetai; + + W.kernelAndGradValue(etaMagj, Hdetj, Wj, gWj); + const auto Hetaj = Hj*etaj.unitVector(); + const auto gradWj = gWj*Hetaj; + + // Zero'th and second moment of the node distribution -- used for the + // ideal H calculation. + const auto rij2 = rij.magnitude2(); + const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); + weightedNeighborSumi += std::abs(gWi); + weightedNeighborSumj += std::abs(gWj); + massSecondMomenti += gradWi.magnitude2()*thpt; + massSecondMomentj += gradWj.magnitude2()*thpt; + + // Determine an effective pressure including a term to fight the tensile instability. + //const auto fij = epsTensile*pow(Wi/(Hdeti*WnPerh), nTensile); + const auto fij = epsTensile*FastMath::pow4(Wi/(Hdeti*WnPerh)); + const auto Ri = fij*(Pi < 0.0 ? -Pi : 0.0); + const auto Rj = fij*(Pj < 0.0 ? -Pj : 0.0); + const auto Peffi = Pi + Ri; + const auto Peffj = Pj + Rj; + + // we'll clean this up when we have a gradient + // implementation we're in love with + auto gradPi = riemannDpDxi; + auto gradPj = riemannDpDxj; + auto gradVi = riemannDvDxi; + auto gradVj = riemannDvDxj; + if (gradType==GradientType::SPHSameTimeGradient){ + gradPi = newRiemannDpDx(nodeListi,i); + gradPj = newRiemannDpDx(nodeListj,j); + gradVi = newRiemannDvDx(nodeListi,i); + gradVj = newRiemannDvDx(nodeListj,j); + } + riemannSolver.interfaceState(ri, rj, + Hi, Hj, + rhoi, rhoj, + ci, cj, + Peffi, Peffj, + vi, vj, + gradPi, gradPj, + gradVi, gradVj, + Pstar, //output + vstar, //output + rhostari, //output + rhostarj); //output + + // get our basis function and interface area vectors + //-------------------------------------------------------- + psii = voli*Wi; + psij = volj*Wj; + gradPsii = voli * Mi.Transpose()*gradWi; + gradPsij = volj * Mj.Transpose()*gradWj; + + const auto Astar = voli*gradPsii + volj*gradPsij; + + // acceleration + //------------------------------------------------------ + const auto deltaDvDt = Pstar*Astar; + DvDti -= deltaDvDt; + DvDtj += deltaDvDt; + + // energy + //------------------------------------------------------ + const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar); + const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj); + + DepsDti += deltaDepsDti; + DepsDtj += deltaDepsDtj; + + if(compatibleEnergy){ + const auto invmij = 1.0/(mi*mj); + pairAccelerations[kk] = deltaDvDt*invmij; + pairDepsDt[2*kk] = deltaDepsDti*invmij; + pairDepsDt[2*kk+1] = deltaDepsDtj*invmij; + } + + // gradients + //------------------------------------------------------ + const auto deltaDvDxi = 2.0*(vi-vstar).dyad(gradPsii); + const auto deltaDvDxj = 2.0*(vstar-vj).dyad(gradPsij); + + // based on riemann soln + DvDxi -= deltaDvDxi; + DvDxj -= deltaDvDxj; + + // while we figure out what we want ... + switch(gradType){ + case GradientType::RiemannGradient: // default grad based on riemann soln + newRiemannDvDxi -= deltaDvDxi; + newRiemannDvDxj -= deltaDvDxj; + newRiemannDpDxi -= 2.0*(Pi-Pstar)*gradPsii; + newRiemannDpDxj -= 2.0*(Pstar-Pj)*gradPsij; + break; + case GradientType::HydroAccelerationGradient: // based on hydro accel for DpDx + newRiemannDvDxi -= deltaDvDxi; + newRiemannDvDxj -= deltaDvDxj; + newRiemannDpDxi += rhoi/mi*deltaDvDt; + newRiemannDpDxj -= rhoj/mj*deltaDvDt; + break; + case GradientType::SPHGradient: // raw gradients + newRiemannDvDxi -= (vi-vj).dyad(gradPsii); + newRiemannDvDxj -= (vi-vj).dyad(gradPsij); + newRiemannDpDxi -= (Pi-Pj)*gradPsii; + newRiemannDpDxj -= (Pi-Pj)*gradPsij; + break; + case GradientType::MixedMethodGradient: // raw gradient for P riemann gradient for v + newRiemannDvDxi -= deltaDvDxi; + newRiemannDvDxj -= deltaDvDxj; + newRiemannDpDxi -= (Pi-Pj)*gradPsii; + newRiemannDpDxj -= (Pi-Pj)*gradPsij; + break; + default: + break; + // do nada + } + + // XSPH + //----------------------------------------------------------- + if (xsph) { + XSPHDeltaVi -= psii*(vi-vstar); + XSPHDeltaVj -= psij*(vj-vstar); + } + + normi += psii; + normj += psij; + + } // loop over pairs + threadReduceFieldLists(threadStack); + } // OpenMP parallel region + + + // Finish up the derivatives for each point. + for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { + const auto& nodeList = mass[nodeListi]->nodeList(); + const auto hmin = nodeList.hmin(); + const auto hmax = nodeList.hmax(); + const auto hminratio = nodeList.hminratio(); + const auto nPerh = nodeList.nodesPerSmoothingScale(); + + const auto ni = nodeList.numInternalNodes(); +#pragma omp parallel for + for (auto i = 0u; i < ni; ++i) { + + // Get the state for node i. + const auto& ri = position(nodeListi, i); + const auto& mi = mass(nodeListi, i); + const auto& voli = volume(nodeListi,i); + const auto& vi = velocity(nodeListi, i); + const auto& Hi = H(nodeListi, i); + const auto Hdeti = Hi.Determinant(); + CHECK(mi > 0.0); + CHECK(voli > 0.0); + CHECK(Hdeti > 0.0); + + auto& normi = normalization(nodeListi, i); + auto& DxDti = DxDt(nodeListi, i); + auto& DvolDti = DvolDt(nodeListi, i); + auto& DvDti = DvDt(nodeListi, i); + auto& DepsDti = DepsDt(nodeListi, i); + auto& DvDxi = DvDx(nodeListi, i); + auto& DHDti = DHDt(nodeListi, i); + auto& Hideali = Hideal(nodeListi, i); + auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); + auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); + auto& massSecondMomenti = massSecondMoment(nodeListi, i); + + DvDti /= mi; + DepsDti /= mi; + + normi += voli*Hdeti*W0; + + DvolDti = voli * DvDxi.Trace() ; + + // If needed finish the total energy derivative. + if (totalEnergy) DepsDti = mi*(vi.dot(DvDti) + DepsDti); + + // Complete the moments of the node distribution for use in the ideal H calculation. + weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); + massSecondMomenti /= Hdeti*Hdeti; + + // Determine the position evolution, based on whether we're doing XSPH or not. + DxDti = vi; + if (xsph){ + DxDti += XSPHDeltaVi/max(tiny, normi); + } + + // The H tensor evolution. + DHDti = smoothingScale.smoothingScaleDerivative(Hi, + ri, + DvDxi, + hmin, + hmax, + hminratio, + nPerh); + Hideali = smoothingScale.newSmoothingScale(Hi, + ri, + weightedNeighborSumi, + massSecondMomenti, + W, + hmin, + hmax, + hminratio, + nPerh, + connectivityMap, + nodeListi, + i); + } // nodes loop + } // nodeLists loop + +} // eval derivs method + + +//------------------------------------------------------------------------------ +// EvalDerivs subroutine for spatial derivs +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +computeMCorrection(const typename Dimension::Scalar /*time*/, + const typename Dimension::Scalar /*dt*/, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const { + + const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient + or this->isFirstCycle()); + // The kernels and such. + const auto& W = this->kernel(); + + // The connectivity. + const auto& connectivityMap = dataBase.connectivityMap(); + const auto& nodeLists = connectivityMap.nodeLists(); + const auto numNodeLists = nodeLists.size(); + + // Get the state and derivative FieldLists. + const auto volume = state.fields(HydroFieldNames::volume, 0.0); + const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); + const auto pressure = state.fields(HydroFieldNames::pressure, 0.0); + const auto position = state.fields(HydroFieldNames::position, Vector::zero); + const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); + CHECK(volume.size() == numNodeLists); + CHECK(velocity.size() == numNodeLists); + CHECK(pressure.size() == numNodeLists); + CHECK(position.size() == numNodeLists); + CHECK(H.size() == numNodeLists); + + auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); + auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + + CHECK(M.size() == numNodeLists); + CHECK(newRiemannDpDx.size() == numNodeLists); + CHECK(newRiemannDvDx.size() == numNodeLists); + + // The set of interacting node pairs. + const auto& pairs = connectivityMap.nodePairList(); + const auto npairs = pairs.size(); + +#pragma omp parallel + { + // Thread private scratch variables + int i, j, nodeListi, nodeListj; + + typename SpheralThreads::FieldListStack threadStack; + auto M_thread = M.threadCopy(threadStack); + auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); + auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); + +#pragma omp for + for (auto kk = 0u; kk < npairs; ++kk) { + i = pairs[kk].i_node; + j = pairs[kk].j_node; + nodeListi = pairs[kk].i_list; + nodeListj = pairs[kk].j_list; + + // Get the state for node i. + const auto& ri = position(nodeListi, i); + const auto& voli = volume(nodeListi, i); + const auto& Hi = H(nodeListi, i); + const auto Hdeti = Hi.Determinant(); + CHECK(voli > 0.0); + CHECK(Hdeti > 0.0); + + auto& Mi = M_thread(nodeListi, i); + + // Get the state for node j + const auto& rj = position(nodeListj, j); + const auto& volj = volume(nodeListj, j); + const auto& Hj = H(nodeListj, j); + const auto Hdetj = Hj.Determinant(); + CHECK(volj > 0.0); + CHECK(Hdetj > 0.0); + + auto& Mj = M_thread(nodeListj, j); + + const auto rij = ri - rj; + + const auto etai = Hi*rij; + const auto etaj = Hj*rij; + const auto etaMagi = etai.magnitude(); + const auto etaMagj = etaj.magnitude(); + CHECK(etaMagi >= 0.0); + CHECK(etaMagj >= 0.0); + + const auto gWi = W.gradValue(etaMagi, Hdeti); + const auto Hetai = Hi*etai.unitVector(); + const auto gradWi = gWi*Hetai; + + const auto gWj = W.gradValue(etaMagj, Hdetj); + const auto Hetaj = Hj*etaj.unitVector(); + const auto gradWj = gWj*Hetaj; + + const auto gradPsii = voli*gradWi; + const auto gradPsij = volj*gradWj; + + Mi -= rij.dyad(gradPsii); + Mj -= rij.dyad(gradPsij); + + // // based on nodal values + if (calcSpatialGradients){ + const auto& vi = velocity(nodeListi, i); + const auto& Pi = pressure(nodeListi, i); + const auto& vj = velocity(nodeListj, j); + const auto& Pj = pressure(nodeListj, j); + auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); + auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); + auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj, j); + auto& newRiemannDvDxj = newRiemannDvDx_thread(nodeListj, j); + + newRiemannDpDxi -= (Pi-Pj)*gradPsii; + newRiemannDpDxj -= (Pi-Pj)*gradPsij; + + newRiemannDvDxi -= (vi-vj).dyad(gradPsii); + newRiemannDvDxj -= (vi-vj).dyad(gradPsij); + } + } // loop over pairs + + // Reduce the thread values to the master. + threadReduceFieldLists(threadStack); + + } // OpenMP parallel region + + // Finish up the spatial gradient calculation + for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { + const auto& nodeList = M[nodeListi]->nodeList(); + const auto ni = nodeList.numInternalNodes(); +#pragma omp parallel for + for (auto i = 0u; i < ni; ++i) { + const auto numNeighborsi = connectivityMap.numNeighborsForNode(nodeListi, i); + auto& Mi = M(nodeListi, i); + + const auto Mdeti = std::abs(Mi.Determinant()); + + const auto enoughNeighbors = numNeighborsi > Dimension::pownu(2); + const auto goodM = (Mdeti > 1e-2 and enoughNeighbors); + + Mi = ( goodM ? Mi.Inverse() : Tensor::one); + + if (calcSpatialGradients){ + auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); + auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); + + newRiemannDpDxi = Mi.Transpose()*newRiemannDpDxi; + newRiemannDvDxi = newRiemannDvDxi*Mi; + } + } + + } + + for (ConstBoundaryIterator boundItr = this->boundaryBegin(); + boundItr != this->boundaryEnd(); + ++boundItr)(*boundItr)->applyFieldListGhostBoundary(M); + + if (calcSpatialGradients){ + for (ConstBoundaryIterator boundItr = this->boundaryBegin(); + boundItr != this->boundaryEnd(); + ++boundItr){ + (*boundItr)->applyFieldListGhostBoundary(newRiemannDpDx); + (*boundItr)->applyFieldListGhostBoundary(newRiemannDvDx); + } + } + for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); + boundaryItr != this->boundaryEnd(); + ++boundaryItr) (*boundaryItr)->finalizeGhostBoundary(); + +} + +} // spheral namespace diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc new file mode 100644 index 000000000..ff4fa4eb5 --- /dev/null +++ b/src/GSPH/MFVHydroBase.cc @@ -0,0 +1,290 @@ +//---------------------------------Spheral++----------------------------------// +// MFVHydroBase -- spheralized verions of "Meshless Finite Mass" +// Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic +// Simulation Methods," MNRAS, 450(1):53-110 +// +// J.M. Pearl 2022 +//----------------------------------------------------------------------------// + +#include "FileIO/FileIO.hh" +#include "NodeList/SmoothingScaleBase.hh" +#include "Hydro/HydroFieldNames.hh" + +#include "DataBase/DataBase.hh" +#include "DataBase/State.hh" +#include "DataBase/StateDerivatives.hh" +#include "DataBase/IncrementFieldList.hh" +#include "DataBase/ReplaceFieldList.hh" +#include "DataBase/ReplaceBoundedFieldList.hh" +#include "DataBase/IncrementBoundedState.hh" +#include "DataBase/CompositeFieldListPolicy.hh" + +#include "Field/FieldList.hh" +#include "Field/NodeIterators.hh" +#include "Boundary/Boundary.hh" +#include "Neighbor/ConnectivityMap.hh" + +#include "GSPH/MFVHydroBase.hh" +#include "GSPH/GSPHFieldNames.hh" +#include "GSPH/computeSumVolume.hh" +#include "GSPH/computeMFMDensity.hh" +#include "GSPH/Policies/ReplaceWithRatioPolicy.hh" +#include "GSPH/RiemannSolvers/RiemannSolverBase.hh" + +#ifdef _OPENMP +#include "omp.h" +#endif + +#include + +using std::string; +using std::min; +using std::max; + +namespace Spheral { + +//------------------------------------------------------------------------------ +// Constructor. +//------------------------------------------------------------------------------ +template +MFVHydroBase:: +MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, + DataBase& dataBase, + RiemannSolverBase& riemannSolver, + const TableKernel& W, + const Scalar epsDiffusionCoeff, + const double cfl, + const bool useVelocityMagnitudeForDt, + const bool compatibleEnergyEvolution, + const bool evolveTotalEnergy, + const bool XSPH, + const bool correctVelocityGradient, + const GradientType gradType, + const MassDensityType densityUpdate, + const HEvolutionType HUpdate, + const double epsTensile, + const double nTensile, + const Vector& xmin, + const Vector& xmax): + GenericRiemannHydro(smoothingScaleMethod, + dataBase, + riemannSolver, + W, + epsDiffusionCoeff, + cfl, + useVelocityMagnitudeForDt, + compatibleEnergyEvolution, + evolveTotalEnergy, + XSPH, + correctVelocityGradient, + gradType, + densityUpdate, + HUpdate, + epsTensile, + nTensile, + xmin, + xmax), + mDvolumeDt(FieldStorageType::CopyFields){ + + mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::volume); + + +} + +//------------------------------------------------------------------------------ +// Destructor +//------------------------------------------------------------------------------ +template +MFVHydroBase:: +~MFVHydroBase() { +} + +//------------------------------------------------------------------------------ +// On problem start up, we need to initialize our internal data. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +initializeProblemStartup(DataBase& dataBase) { + GenericRiemannHydro::initializeProblemStartup(dataBase); +} + +//------------------------------------------------------------------------------ +// Register the state we need/are going to evolve. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +registerState(DataBase& dataBase, + State& state) { + + typedef typename State::PolicyPointer PolicyPointer; + + GenericRiemannHydro::registerState(dataBase,state); + + auto massDensity = dataBase.fluidMassDensity(); + auto volume = state.fields(HydroFieldNames::volume, 0.0); + + std::shared_ptr > volumePolicy(new CompositeFieldListPolicy()); + for (auto itr = dataBase.fluidNodeListBegin(); + itr != dataBase.fluidNodeListEnd(); + ++itr) { + auto massi = (*itr)->mass(); + auto minVolume = massi.min()/(*itr)->rhoMax(); + auto maxVolume = massi.max()/(*itr)->rhoMin(); + volumePolicy->push_back(new IncrementBoundedState(minVolume, + maxVolume)); + } + + PolicyPointer rhoPolicy(new ReplaceWithRatioPolicy(HydroFieldNames::mass, + HydroFieldNames::volume, + HydroFieldNames::volume)); + + // normal state variables + state.enroll(massDensity, rhoPolicy); + state.enroll(volume, volumePolicy); +} + +//------------------------------------------------------------------------------ +// Register the state derivative fields. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +registerDerivatives(DataBase& dataBase, + StateDerivatives& derivs) { + GenericRiemannHydro::registerDerivatives(dataBase,derivs); + + dataBase.resizeFluidFieldList(mDvolumeDt, 0.0, IncrementFieldList::prefix() + HydroFieldNames::volume, false); + derivs.enroll(mDvolumeDt); +} + +//------------------------------------------------------------------------------ +// This method is called once at the beginning of a timestep, after all state registration. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +preStepInitialize(const DataBase& dataBase, + State& state, + StateDerivatives& derivs) { + GenericRiemannHydro::preStepInitialize(dataBase,state,derivs); + + if(this->densityUpdate() == MassDensityType::RigorousSumDensity){ + // plop into an intialize volume function + const auto position = state.fields(HydroFieldNames::position, Vector::zero); + const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); + const auto mass = state.fields(HydroFieldNames::mass, 0.0); + auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); + auto volume = state.fields(HydroFieldNames::volume, 0.0); + + computeSumVolume(dataBase.connectivityMap(),this->kernel(),position,H,volume); + computeMFMDensity(mass,volume,massDensity); + + for (auto boundaryItr = this->boundaryBegin(); + boundaryItr != this->boundaryEnd(); + ++boundaryItr){ + (*boundaryItr)->applyFieldListGhostBoundary(volume); + (*boundaryItr)->applyFieldListGhostBoundary(massDensity); + } + for (auto boundaryItr = this->boundaryBegin(); + boundaryItr < this->boundaryEnd(); + ++boundaryItr) (*boundaryItr)->finalizeGhostBoundary(); + } +} + +//------------------------------------------------------------------------------ +// Initialize the hydro before calling evaluateDerivatives +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +initialize(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + State& state, + StateDerivatives& derivs) { + + // initialize spatial gradients so we can store them + if (this->isFirstCycle()){ + this->computeMCorrection(time,dt,dataBase,state,derivs); + } + + GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); + + if (this->isFirstCycle()){ + auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); + auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + + M.Zero(); + newRiemannDpDx.Zero(); + newRiemannDvDx.Zero(); + this->isFirstCycle(false); + } + +} + +//------------------------------------------------------------------------------ +// Finalize the derivatives. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +finalizeDerivatives(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivs) const { + GenericRiemannHydro::finalizeDerivatives(time,dt,dataBase,state,derivs); +} + +//------------------------------------------------------------------------------ +// Apply the ghost boundary conditions for hydro state fields. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +applyGhostBoundaries(State& state, + StateDerivatives& derivs) { + GenericRiemannHydro::applyGhostBoundaries(state,derivs); +} + +//------------------------------------------------------------------------------ +// Enforce the boundary conditions for hydro state fields. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +enforceBoundaries(State& state, + StateDerivatives& derivs) { + GenericRiemannHydro::enforceBoundaries(state,derivs); +} + + +//------------------------------------------------------------------------------ +// Dump the current state to the given file. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +dumpState(FileIO& file, const string& pathName) const { + GenericRiemannHydro::dumpState(file,pathName); + + file.write(mDvolumeDt, pathName + "/DvolumeDt"); +} + +//------------------------------------------------------------------------------ +// Restore the state from the given file. +//------------------------------------------------------------------------------ +template +void +MFVHydroBase:: +restoreState(const FileIO& file, const string& pathName) { + GenericRiemannHydro::restoreState(file,pathName); + + file.read(mDvolumeDt, pathName + "/DvolumeDt"); +} + +} + diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh new file mode 100644 index 000000000..8de5f6d41 --- /dev/null +++ b/src/GSPH/MFVHydroBase.hh @@ -0,0 +1,155 @@ +//---------------------------------Spheral++----------------------------------// +// MFVHydroBase -- spheralized verions of "Meshless Finite Mass" +// Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic +// Simulation Methods," MNRAS, 450(1):53-110 +// +// J.M. Pearl 2022 +//----------------------------------------------------------------------------// + +#ifndef __Spheral_MFVHydroBase_hh__ +#define __Spheral_MFVHydroBase_hh__ + +#include + +#include "GSPH/GenericRiemannHydro.hh" + +namespace Spheral { + +template class State; +template class StateDerivatives; +template class SmoothingScaleBase; +template class TableKernel; +template class RiemannSolverBase; +template class DataBase; +template class Field; +template class FieldList; +class FileIO; + +template +class MFVHydroBase: public GenericRiemannHydro { + +public: + //--------------------------- Public Interface ---------------------------// + typedef typename Dimension::Scalar Scalar; + typedef typename Dimension::Vector Vector; + typedef typename Dimension::Tensor Tensor; + typedef typename Dimension::SymTensor SymTensor; + typedef typename Dimension::ThirdRankTensor ThirdRankTensor; + + typedef typename GenericRiemannHydro::TimeStepType TimeStepType; + typedef typename GenericRiemannHydro::ConstBoundaryIterator ConstBoundaryIterator; + + // Constructors. + MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, + DataBase& dataBase, + RiemannSolverBase& riemannSolver, + const TableKernel& W, + const Scalar epsDiffusionCoeff, + const double cfl, + const bool useVelocityMagnitudeForDt, + const bool compatibleEnergyEvolution, + const bool evolveTotalEnergy, + const bool XSPH, + const bool correctVelocityGradient, + const GradientType gradType, + const MassDensityType densityUpdate, + const HEvolutionType HUpdate, + const double epsTensile, + const double nTensile, + const Vector& xmin, + const Vector& xmax); + + // Destructor. + virtual ~MFVHydroBase(); + + // Tasks we do once on problem startup. + virtual + void initializeProblemStartup(DataBase& dataBase) override; + + // Register the state Hydro expects to use and evolve. + virtual + void registerState(DataBase& dataBase, + State& state) override; + + // Register the derivatives/change fields for updating state. + virtual + void registerDerivatives(DataBase& dataBase, + StateDerivatives& derivs) override; + + + // This method is called once at the beginning of a timestep, after all state registration. + virtual void preStepInitialize(const DataBase& dataBase, + State& state, + StateDerivatives& derivs) override; + + // Initialize the Hydro before we start a derivative evaluation. + virtual + void initialize(const Scalar time, + const Scalar dt, + const DataBase& dataBase, + State& state, + StateDerivatives& derivs) override; + + // Evaluate the derivatives for the principle hydro variables: + // mass density, velocity, and specific thermal energy. + virtual + void evaluateDerivatives(const Scalar time, + const Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const override; + void + computeMCorrection(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const; + + // Finalize the derivatives. + virtual + void finalizeDerivatives(const Scalar time, + const Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivs) const override; + + // Apply boundary conditions to the physics specific fields. + virtual + void applyGhostBoundaries(State& state, + StateDerivatives& derivs) override; + + // Enforce boundary conditions for the physics specific fields. + virtual + void enforceBoundaries(State& state, + StateDerivatives& derivs) override; + + const FieldList& DvolumeDt() const; + + //**************************************************************************** + // Methods required for restarting. + virtual std::string label() const override { return "MFVHydroBase" ; } + virtual void dumpState(FileIO& file, const std::string& pathName) const override; + virtual void restoreState(const FileIO& file, const std::string& pathName) override; + //**************************************************************************** +private: + + FieldList mDvolumeDt; + + // No default constructor, copying, or assignment. + MFVHydroBase(); + MFVHydroBase(const MFVHydroBase&); + MFVHydroBase& operator=(const MFVHydroBase&); +}; + +} + +#include "MFVHydroBaseInline.hh" + +#else + +// Forward declaration. +namespace Spheral { + template class MFVHydroBase; +} + +#endif diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh new file mode 100644 index 000000000..22ce90ac0 --- /dev/null +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -0,0 +1,12 @@ +namespace Spheral { +//------------------------------------------------------------------------------ +// The internal state field lists. +//------------------------------------------------------------------------------ +template +inline +const FieldList& +MFVHydroBase:: +DvolumeDt() const { + return mDvolumeDt; +} +} \ No newline at end of file diff --git a/src/GSPH/MFVHydroBaseInst.cc.py b/src/GSPH/MFVHydroBaseInst.cc.py new file mode 100644 index 000000000..4f1510ced --- /dev/null +++ b/src/GSPH/MFVHydroBaseInst.cc.py @@ -0,0 +1,12 @@ +text = """ +//------------------------------------------------------------------------------ +// Explict instantiation. +//------------------------------------------------------------------------------ +#include "GSPH/MFVHydroBase.cc" +#include "GSPH/MFVEvaluateDerivatives.cc" +#include "Geometry/Dimension.hh" + +namespace Spheral { + template class MFVHydroBase< Dim< %(ndim)s > >; +} +""" From 3bf05a3f89576951b681d32ec696d096890e0290 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 2 Nov 2022 04:40:07 -0700 Subject: [PATCH 12/60] GSPH new gradient options --- src/GSPH/GSPHEvaluateDerivatives.cc | 10 +++++++--- src/GSPH/GenericRiemannHydro.hh | 4 +++- src/Pybind11Wraps/GSPH/GSPHMOD.py | 4 +++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index 4c71a5e76..3a37a32fb 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -231,7 +231,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto gradPj = riemannDpDxj; auto gradVi = riemannDvDxi; auto gradVj = riemannDvDxj; - if (gradType==GradientType::SPHSameTimeGradient){ + if (gradType==GradientType::SPHSameTimeGradient or + gradType==GradientType::SPHUncorrectedGradient){ gradPi = newRiemannDpDx(nodeListi,i); gradPj = newRiemannDpDx(nodeListj,j); gradVi = newRiemannDvDx(nodeListi,i); @@ -436,7 +437,10 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, // The kernels and such. const auto& W = this->kernel(); const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient - or this->isFirstCycle()); + or this->isFirstCycle() + or this->gradientType() == GradientType::SPHUncorrectedGradient); + const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient + or this->isFirstCycle()); // The connectivity. const auto& connectivityMap = dataBase.connectivityMap(); const auto& nodeLists = connectivityMap.nodeLists(); @@ -570,7 +574,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi = ( goodM ? Mi.Inverse() : Tensor::one); - if (calcSpatialGradients){ + if (correctSpatialGradients){ auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); diff --git a/src/GSPH/GenericRiemannHydro.hh b/src/GSPH/GenericRiemannHydro.hh index b294fb49c..7e6f68728 100644 --- a/src/GSPH/GenericRiemannHydro.hh +++ b/src/GSPH/GenericRiemannHydro.hh @@ -20,7 +20,9 @@ enum class GradientType { HydroAccelerationGradient = 1, SPHGradient = 2, MixedMethodGradient = 3, - SPHSameTimeGradient = 4 + SPHSameTimeGradient = 4, + SPHUncorrectedGradient = 5, + NoGradient = 6 }; template class State; diff --git a/src/Pybind11Wraps/GSPH/GSPHMOD.py b/src/Pybind11Wraps/GSPH/GSPHMOD.py index 34ece28c5..de3060785 100644 --- a/src/Pybind11Wraps/GSPH/GSPHMOD.py +++ b/src/Pybind11Wraps/GSPH/GSPHMOD.py @@ -49,7 +49,9 @@ "HydroAccelerationGradient", "SPHGradient", "MixedMethodGradient", - "SPHSameTimeGradient"), export_values = True) + "SPHSameTimeGradient", + "SPHUncorrectedGradient", + "NoGradient"), export_values = True) #------------------------------------------------------------------------------- # Instantiate our types From 0f345789a24abf5146c5e41833f8ebb3c9611b44 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 2 Nov 2022 04:40:38 -0700 Subject: [PATCH 13/60] GSPH new gradient options added to MFM --- src/GSPH/MFMEvaluateDerivatives.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index 5e020e8c8..3cbc2156d 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -233,7 +233,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto gradPj = riemannDpDxj; auto gradVi = riemannDvDxi; auto gradVj = riemannDvDxj; - if (gradType==GradientType::SPHSameTimeGradient){ + if (gradType==GradientType::SPHSameTimeGradient or + gradType==GradientType::SPHUncorrectedGradient){ gradPi = newRiemannDpDx(nodeListi,i); gradPj = newRiemannDpDx(nodeListj,j); gradVi = newRiemannDvDx(nodeListi,i); @@ -431,7 +432,10 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, StateDerivatives& derivatives) const { const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient - or this->isFirstCycle()); + or this->isFirstCycle() + or this->gradientType() == GradientType::SPHUncorrectedGradient); + const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient + or this->isFirstCycle()); // The kernels and such. const auto& W = this->kernel(); @@ -564,7 +568,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi = ( goodM ? Mi.Inverse() : Tensor::one); - if (calcSpatialGradients){ + if (correctSpatialGradients){ auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); From f2a086ab2394fe29edb7cb6716ea650ff1f39db2 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 2 Nov 2022 04:41:02 -0700 Subject: [PATCH 14/60] GSPH new gradient options added to MFV --- src/GSPH/MFVEvaluateDerivatives.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index 8a1194ece..34d3b062b 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -233,7 +233,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto gradPj = riemannDpDxj; auto gradVi = riemannDvDxi; auto gradVj = riemannDvDxj; - if (gradType==GradientType::SPHSameTimeGradient){ + if (gradType==GradientType::SPHSameTimeGradient or + gradType==GradientType::SPHUncorrectedGradient){ gradPi = newRiemannDpDx(nodeListi,i); gradPj = newRiemannDpDx(nodeListj,j); gradVi = newRiemannDvDx(nodeListi,i); From 07113da7ed6713fb08ef6c0adadafcfe375728d1 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 2 Nov 2022 04:43:12 -0700 Subject: [PATCH 15/60] GSPH Acoustic test fiddling --- .../Hydro/AcousticWave/AcousticWave-1d.py | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py b/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py index fcec62dbc..addbb0420 100644 --- a/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py +++ b/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py @@ -43,11 +43,12 @@ def smooth(x,window_len=11,window='hanning'): # problem I.C.s rho1 = 1.0, - eps1 = 1.0, + #eps1 = 1.0, A = 1.0e-6, kfreq = 1.0, cs2 = 1.0, mu = 1.0, + gamma1 = 5.0/3.0, # Kernel properties KernelConstructor = WendlandC2Kernel, @@ -90,6 +91,7 @@ def smooth(x,window_len=11,window='hanning'): LimiterConstructor = VanLeerLimiter, # VanLeer, Opsre, MinMod, VanAlba, Superbee riemannLinearReconstruction = True, # True - second order, False - first order riemannGradientType = HydroAccelerationGradient, # HydroAccelerationGradient, SPHGradient, RiemannGradient, MixedMethodGradient, SPHSameTimeGradient + gsphRiemannSolver = "HLLC", # HLLC / ArtificialViscosity # Artificial Viscosity Cl = 1.0, @@ -100,7 +102,7 @@ def smooth(x,window_len=11,window='hanning'): # integrator options IntegratorConstructor = VerletIntegrator,#CheapSynchronousRK2Integrator, - cfl = 0.25, + cfl = 0.35, steps = None, goalTime = 1.0, dt = 1.0e-10, @@ -119,7 +121,7 @@ def smooth(x,window_len=11,window='hanning'): clearDirectories = True, dataDirBase = "dumps-planar-AcousticWave-1d", outputFile = "AcousticWave-planar-1d.gnu", - normOutputFile = "_cfl2_asciiDump.dat", + normOutputFile = "_asciiDump.dat", writeOutputLabel = True, graphics = False,#"gnu", @@ -154,7 +156,7 @@ def smooth(x,window_len=11,window='hanning'): elif LimiterConstructor==SuperbeeLimiter: normOutputFile = "Superbee_"+normOutputFile normOutputFile = str(densityUpdate)+"_"+normOutputFile -normOutputFile = hydroname+"_"+normOutputFile +normOutputFile = hydroname+"_"+gsphRiemannSolver+"_"+normOutputFile print normOutputFile dataDir = os.path.join(dataDirBase, @@ -176,8 +178,8 @@ def smooth(x,window_len=11,window='hanning'): #------------------------------------------------------------------------------- # Material properties. #------------------------------------------------------------------------------- -eos = IsothermalEquationOfStateMKS(cs2, mu) - +#eos = IsothermalEquationOfStateMKS(cs2, mu) +eos = GammaLawGasMKS(gamma1, mu) #------------------------------------------------------------------------------- # Interpolation kernels. #------------------------------------------------------------------------------- @@ -247,9 +249,12 @@ def __call__(self, x): vel = nodes1.velocity() rho = nodes1.massDensity() mass = nodes1.mass() +eps = nodes1.specificThermalEnergy() H = nodes1.Hfield() dx = (x1 - x0)/nx1 xi = x0 +eps1 = cs2/(gamma1*(gamma1-1.0)) +P1 = (gamma1-1.0)*rho1*eps1 for i in xrange(nodes1.numInternalNodes): func0 = MassFunctor(max(0.0, Mi[i] - mi)) func1 = MassFunctor(Mi[i]) @@ -262,6 +267,8 @@ def __call__(self, x): vel[i].x = A*cs*sin(twopi*kfreq*(xi - x0)/(x1 - x0)) rho[i] = rho1*(1.0 + A*sin(twopi*kfreq*(xi - x0)/(x1 - x0))) mass[i] = rho1*((xi1 - xi0) - A/(twopi*kfreq)*(cos(twopi*kfreq*xi1) - cos(twopi*kfreq*xi0))) + Pi = P1+A*sin(twopi*kfreq*(xi - x0)/(x1 - x0)) + eps[i] = Pi/((gamma1 - 1.0)*rho[i]) print A/(twopi*kfreq)*(cos(twopi*kfreq*xi1) - cos(twopi*kfreq*xi0)) print("%3.16e" % mass[i]) H[i] *= rho[i]/rho1 @@ -346,7 +353,12 @@ def __call__(self, x): elif gsph: limiter = LimiterConstructor() waveSpeed = WaveSpeedConstructor() - solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + if gsphRiemannSolver == "HLLC": + solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + elif gsphRiemannSolver == "ArtificialViscosity": + solver = SecondOrderArtificialViscosity(Cl,Cq,limiter,waveSpeed,riemannLinearReconstruction) + else: + raise ValueError, "WRONG!" hydro = GSPH(dataBase = db, riemannSolver = solver, W = WT, @@ -363,7 +375,13 @@ def __call__(self, x): elif mfm: limiter = LimiterConstructor() waveSpeed = WaveSpeedConstructor() - solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + if gsphRiemannSolver == "HLLC": + solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) + elif gsphRiemannSolver == "ArtificialViscosity": + solver = SecondOrderArtificialViscosity(Cl,Cq,limiter,waveSpeed,riemannLinearReconstruction) + else: + raise ValueError, "WRONG!" + hydro = MFM(dataBase = db, riemannSolver = solver, W = WT, From 0b34b88266b468328a6f027fb838f27f92b5b006 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Mon, 26 Dec 2022 09:32:06 -0800 Subject: [PATCH 16/60] updating SolidGSPH riemann gradient update method update policy is now used to handle the Riemann gradients that are stored between steps. for problems with const bc and initial pressure gradients (hydrostatic atmospheres etc...) the pressure gradient will need to be given initial conditions similar to eps or rho or any other field --- src/GSPH/GSPHHydroBase.cc | 26 +++---- src/GSPH/GenericRiemannHydro.cc | 129 +++++++++++++++++--------------- src/GSPH/MFMHydroBase.cc | 26 +++---- 3 files changed, 94 insertions(+), 87 deletions(-) diff --git a/src/GSPH/GSPHHydroBase.cc b/src/GSPH/GSPHHydroBase.cc index 2c91cd382..95ad1271f 100644 --- a/src/GSPH/GSPHHydroBase.cc +++ b/src/GSPH/GSPHHydroBase.cc @@ -214,22 +214,22 @@ initialize(const typename Dimension::Scalar time, TIME_BEGIN("GSPHinitialize"); // initialize spatial gradients so we can store them - if (this->isFirstCycle()){ - this->computeMCorrection(time,dt,dataBase,state,derivs); - } + // if (this->isFirstCycle()){ + // this->computeMCorrection(time,dt,dataBase,state,derivs); + // } - GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); + // GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); - if (this->isFirstCycle()){ - auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); - auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); - auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + // if (this->isFirstCycle()){ + // auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + // auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); + // auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - M.Zero(); - newRiemannDpDx.Zero(); - newRiemannDvDx.Zero(); - this->isFirstCycle(false); - } + // M.Zero(); + // newRiemannDpDx.Zero(); + // newRiemannDvDx.Zero(); + // this->isFirstCycle(false); + // } TIME_END("GSPHinitialize"); diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 15be4d909..0d7a0b73a 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -36,6 +36,7 @@ #include "GSPH/GSPHFieldNames.hh" #include "GSPH/GenericRiemannHydro.hh" #include "GSPH/computeSPHVolume.hh" +#include "GSPH/Policies/PureReplaceFieldList.hh" #include "GSPH/RiemannSolvers/RiemannSolverBase.hh" #ifdef _OPENMP @@ -51,6 +52,7 @@ using std::string; using std::pair; using std::to_string; using std::make_pair; +using std::make_shared; namespace { @@ -121,9 +123,9 @@ GenericRiemannHydro(const SmoothingScaleBase& smoothingScaleMethod, mXSPHDeltaV(FieldStorageType::CopyFields), mM(FieldStorageType::CopyFields), mDxDt(FieldStorageType::CopyFields), - mDvDt(FieldStorageType::CopyFields), - mDspecificThermalEnergyDt(FieldStorageType::CopyFields), - mDHDt(FieldStorageType::CopyFields), + mDvDt(FieldStorageType::CopyFields), // move up one layer + mDspecificThermalEnergyDt(FieldStorageType::CopyFields), // move up one layer + mDHDt(FieldStorageType::CopyFields), mDvDx(FieldStorageType::CopyFields), mRiemannDpDx(FieldStorageType::CopyFields), mRiemannDvDx(FieldStorageType::CopyFields), @@ -191,7 +193,7 @@ GenericRiemannHydro:: registerState(DataBase& dataBase, State& state) { - typedef typename State::PolicyPointer PolicyPointer; + //typedef typename State::PolicyPointer PolicyPointer; VERIFY2(not (mCompatibleEnergyEvolution and mEvolveTotalEnergy), "SPH error : you cannot simultaneously use both compatibleEnergyEvolution and evolveTotalEnergy"); @@ -220,10 +222,12 @@ registerState(DataBase& dataBase, Hpolicy->push_back(new ReplaceBoundedState(hmaxInv, hminInv)); } } - - PolicyPointer positionPolicy(new IncrementFieldList()); - PolicyPointer pressurePolicy(new PressurePolicy()); - PolicyPointer csPolicy(new SoundSpeedPolicy()); + //auto yieldStrengthPolicy = make_shared>() + auto positionPolicy = make_shared>(); + auto pressurePolicy = make_shared>(); + auto csPolicy = make_shared>(); + auto pressureGradientPolicy = make_shared>(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient); + auto velocityGradientPolicy = make_shared>(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient); // normal state variables state.enroll(mTimeStepMask); @@ -234,31 +238,36 @@ registerState(DataBase& dataBase, state.enroll(position, positionPolicy); state.enroll(mPressure, pressurePolicy); state.enroll(mSoundSpeed, csPolicy); - state.enroll(mRiemannDpDx); - state.enroll(mRiemannDvDx); + + if (mRiemannSolver.linearReconstruction()){ + state.enroll(mRiemannDpDx, pressureGradientPolicy); + state.enroll(mRiemannDvDx, velocityGradientPolicy); + }else{ + state.enroll(mRiemannDpDx); + state.enroll(mRiemannDvDx); + } // conditional for energy method if (mCompatibleEnergyEvolution) { - - PolicyPointer thermalEnergyPolicy(new CompatibleDifferenceSpecificThermalEnergyPolicy(dataBase)); - PolicyPointer velocityPolicy(new IncrementFieldList(HydroFieldNames::position, - HydroFieldNames::specificThermalEnergy, - true)); + auto thermalEnergyPolicy = make_shared>(dataBase); + auto velocityPolicy = make_shared>(HydroFieldNames::position, + HydroFieldNames::specificThermalEnergy, + true); state.enroll(specificThermalEnergy, thermalEnergyPolicy); state.enroll(velocity, velocityPolicy); }else if (mEvolveTotalEnergy) { - PolicyPointer thermalEnergyPolicy(new SpecificFromTotalThermalEnergyPolicy()); - PolicyPointer velocityPolicy(new IncrementFieldList(HydroFieldNames::position, - HydroFieldNames::specificThermalEnergy, - true)); + auto thermalEnergyPolicy = make_shared>(); + auto velocityPolicy = make_shared>(HydroFieldNames::position, + HydroFieldNames::specificThermalEnergy, + true) ; state.enroll(specificThermalEnergy, thermalEnergyPolicy); state.enroll(velocity, velocityPolicy); } else { - PolicyPointer thermalEnergyPolicy(new IncrementFieldList()); - PolicyPointer velocityPolicy(new IncrementFieldList(HydroFieldNames::position, - true)); + auto thermalEnergyPolicy = make_shared>(); + auto velocityPolicy = make_shared>(HydroFieldNames::position, + true); state.enroll(specificThermalEnergy, thermalEnergyPolicy); state.enroll(velocity, velocityPolicy); } @@ -491,40 +500,40 @@ initialize(const typename Dimension::Scalar time, State& state, StateDerivatives& derivs) { - auto& riemannSolver = this->riemannSolver(); + // auto& riemannSolver = this->riemannSolver(); - if(riemannSolver.linearReconstruction()){ - const auto& connectivityMap = dataBase.connectivityMap(); - const auto& nodeLists = connectivityMap.nodeLists(); - const auto numNodeLists = nodeLists.size(); + // if(riemannSolver.linearReconstruction()){ + // const auto& connectivityMap = dataBase.connectivityMap(); + // const auto& nodeLists = connectivityMap.nodeLists(); + // const auto numNodeLists = nodeLists.size(); - // copy from previous time step - for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { - const auto& nodeList = nodeLists[nodeListi]; - const auto ni = nodeList->numInternalNodes(); - #pragma omp parallel for - for (auto i = 0u; i < ni; ++i) { - const auto DvDxi = mNewRiemannDvDx(nodeListi,i); - const auto DpDxi = mNewRiemannDpDx(nodeListi,i); + // // copy from previous time step + // for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { + // const auto& nodeList = nodeLists[nodeListi]; + // const auto ni = nodeList->numInternalNodes(); + // #pragma omp parallel for + // for (auto i = 0u; i < ni; ++i) { + // const auto DvDxi = mNewRiemannDvDx(nodeListi,i); + // const auto DpDxi = mNewRiemannDpDx(nodeListi,i); - mRiemannDvDx(nodeListi,i) = DvDxi; - mRiemannDpDx(nodeListi,i) = DpDxi; + // mRiemannDvDx(nodeListi,i) = DvDxi; + // mRiemannDpDx(nodeListi,i) = DpDxi; - } - } - - for (auto boundItr =this->boundaryBegin(); - boundItr != this->boundaryEnd(); - ++boundItr) { - (*boundItr)->applyFieldListGhostBoundary(mRiemannDvDx); - (*boundItr)->applyFieldListGhostBoundary(mRiemannDpDx); - } - - for (auto boundItr = this->boundaryBegin(); - boundItr != this->boundaryEnd(); - ++boundItr) (*boundItr)->finalizeGhostBoundary(); + // } + // } + + // for (auto boundItr =this->boundaryBegin(); + // boundItr != this->boundaryEnd(); + // ++boundItr) { + // (*boundItr)->applyFieldListGhostBoundary(mRiemannDvDx); + // (*boundItr)->applyFieldListGhostBoundary(mRiemannDpDx); + // } + + // for (auto boundItr = this->boundaryBegin(); + // boundItr != this->boundaryEnd(); + // ++boundItr) (*boundItr)->finalizeGhostBoundary(); - } // if LinearReconstruction + // } // if LinearReconstruction } @@ -561,7 +570,7 @@ void GenericRiemannHydro:: applyGhostBoundaries(State& state, StateDerivatives& derivs) { - // Apply boundary conditions to the basic fluid state Fields. + auto volume = state.fields(HydroFieldNames::volume, 0.0); auto mass = state.fields(HydroFieldNames::mass, 0.0); auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); @@ -569,15 +578,14 @@ applyGhostBoundaries(State& state, auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); auto pressure = state.fields(HydroFieldNames::pressure, 0.0); auto soundSpeed = state.fields(HydroFieldNames::soundSpeed, 0.0); - - // our store vars in the riemann solver auto DpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto DvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + + //auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); boundaryItr != this->boundaryEnd(); ++boundaryItr) { - (*boundaryItr)->applyFieldListGhostBoundary(M); + //(*boundaryItr)->applyFieldListGhostBoundary(M); (*boundaryItr)->applyFieldListGhostBoundary(volume); (*boundaryItr)->applyFieldListGhostBoundary(mass); (*boundaryItr)->applyFieldListGhostBoundary(massDensity); @@ -600,7 +608,6 @@ GenericRiemannHydro:: enforceBoundaries(State& state, StateDerivatives& derivs) { - // Enforce boundary conditions on the fluid state Fields. auto volume = state.fields(HydroFieldNames::volume, 0.0); auto mass = state.fields(HydroFieldNames::mass, 0.0); auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); @@ -608,16 +615,16 @@ enforceBoundaries(State& state, auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); auto pressure = state.fields(HydroFieldNames::pressure, 0.0); auto soundSpeed = state.fields(HydroFieldNames::soundSpeed, 0.0); - - // our store vars in the riemann solver auto DpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto DvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + + // our store vars in the riemann solver + //auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); boundaryItr != this->boundaryEnd(); ++boundaryItr) { - (*boundaryItr)->enforceFieldListBoundary(M); + //(*boundaryItr)->enforceFieldListBoundary(M); (*boundaryItr)->enforceFieldListBoundary(volume); (*boundaryItr)->enforceFieldListBoundary(mass); (*boundaryItr)->enforceFieldListBoundary(massDensity); diff --git a/src/GSPH/MFMHydroBase.cc b/src/GSPH/MFMHydroBase.cc index dd893e83f..9753c53a7 100644 --- a/src/GSPH/MFMHydroBase.cc +++ b/src/GSPH/MFMHydroBase.cc @@ -206,22 +206,22 @@ initialize(const typename Dimension::Scalar time, StateDerivatives& derivs) { // initialize spatial gradients so we can store them - if (this->isFirstCycle()){ - this->computeMCorrection(time,dt,dataBase,state,derivs); - } + // if (this->isFirstCycle()){ + // this->computeMCorrection(time,dt,dataBase,state,derivs); + // } - GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); + // GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); - if (this->isFirstCycle()){ - auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); - auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); - auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + // if (this->isFirstCycle()){ + // auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + // auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); + // auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - M.Zero(); - newRiemannDpDx.Zero(); - newRiemannDvDx.Zero(); - this->isFirstCycle(false); - } + // M.Zero(); + // newRiemannDpDx.Zero(); + // newRiemannDvDx.Zero(); + // this->isFirstCycle(false); + // } } From d57d22de41d81715660bc3d719c33b98aa620999 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Mon, 26 Dec 2022 11:41:59 -0800 Subject: [PATCH 17/60] improved implementation of GSPH initialization of pressure and velocity gradient on start up --- src/GSPH/CMakeLists.txt | 2 + src/GSPH/GenericRiemannHydro.cc | 34 +++++- src/GSPH/initializeGradients.cc | 160 +++++++++++++++++++++++++ src/GSPH/initializeGradients.hh | 34 ++++++ src/GSPH/initializeGradientsInst.cc.py | 21 ++++ 5 files changed, 248 insertions(+), 3 deletions(-) create mode 100644 src/GSPH/initializeGradients.cc create mode 100644 src/GSPH/initializeGradients.hh create mode 100644 src/GSPH/initializeGradientsInst.cc.py diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 3fc9f6489..11553bf96 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -4,6 +4,7 @@ set(GSPH_inst computeSPHVolume computeSumVolume computeMFMDensity + initializeGradients GenericRiemannHydro GSPHHydroBase MFMHydroBase @@ -30,6 +31,7 @@ set(GSPH_headers computeSPHVolume.hh computeSumVolume.hh computeMFMDensity.hh + initializeGradients.hh GSPHFieldNames.hh GenericRiemannHydro.hh GSPHHydroBase.hh diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 0d7a0b73a..8dc76846d 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -36,6 +36,7 @@ #include "GSPH/GSPHFieldNames.hh" #include "GSPH/GenericRiemannHydro.hh" #include "GSPH/computeSPHVolume.hh" +#include "GSPH/initializeGradients.hh" #include "GSPH/Policies/PureReplaceFieldList.hh" #include "GSPH/RiemannSolvers/RiemannSolverBase.hh" @@ -175,15 +176,42 @@ template void GenericRiemannHydro:: initializeProblemStartup(DataBase& dataBase) { + + auto mass = dataBase.fluidMass(); + auto massDensity = dataBase.fluidMassDensity(); + auto position = dataBase.fluidPosition(); + auto velocity = dataBase.fluidVelocity(); + auto H = dataBase.fluidHfield(); + dataBase.fluidPressure(mPressure); dataBase.fluidSoundSpeed(mSoundSpeed); - // for now initialize with SPH volume to make sure things are defined - const auto mass = dataBase.fluidMass(); - const auto massDensity = dataBase.fluidMassDensity(); computeSPHVolume(mass,massDensity,mVolume); + + for (ConstBoundaryIterator boundItr = this->boundaryBegin(); + boundItr != this->boundaryEnd(); + ++boundItr){ + (*boundItr)->applyFieldListGhostBoundary(mVolume); + (*boundItr)->applyFieldListGhostBoundary(velocity); + (*boundItr)->applyFieldListGhostBoundary(mPressure); + } + for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); + boundaryItr != this->boundaryEnd(); + ++boundaryItr) (*boundaryItr)->finalizeGhostBoundary(); + + initializeGradients(dataBase.connectivityMap(), + this->kernel(), + position, + H, + mVolume, + mPressure, + velocity, + mRiemannDpDx, + mRiemannDvDx); + } + //------------------------------------------------------------------------------ // Register the state we need/are going to evolve. //------------------------------------------------------------------------------ diff --git a/src/GSPH/initializeGradients.cc b/src/GSPH/initializeGradients.cc new file mode 100644 index 000000000..7d29af523 --- /dev/null +++ b/src/GSPH/initializeGradients.cc @@ -0,0 +1,160 @@ +//---------------------------------Spheral++----------------------------------// +// Compute volume from inverse of the kernel summation +//----------------------------------------------------------------------------// + +#include "GSPH/initializeGradients.hh" +#include "Field/FieldList.hh" +#include "Neighbor/ConnectivityMap.hh" +#include "Kernel/TableKernel.hh" +#include "NodeList/NodeList.hh" + +namespace Spheral{ + +template +void +initializeGradients(const ConnectivityMap& connectivityMap, + const TableKernel& W, + const FieldList& position, + const FieldList& H, + const FieldList& volume, + const FieldList& pressure, + const FieldList& velocity, + FieldList& DpDx, + FieldList& DvDx) { + + typedef typename Dimension::Tensor Tensor; + + const auto& nodeLists = connectivityMap.nodeLists(); + const auto& pairs = connectivityMap.nodePairList(); + const auto npairs = pairs.size(); + const auto numNodeLists = nodeLists.size(); + + REQUIRE(volume.size() == numNodeLists); + REQUIRE(velocity.size() == numNodeLists); + REQUIRE(pressure.size() == numNodeLists); + REQUIRE(position.size() == numNodeLists); + REQUIRE(H.size() == numNodeLists); + + REQUIRE(DpDx.size() == numNodeLists); + REQUIRE(DvDx.size() == numNodeLists); + + // Prepare the kernel sum correction field. + FieldList M(FieldStorageType::CopyFields); + for (auto nodeListi = 0u; nodeListi != numNodeLists; ++nodeListi) { + M.appendNewField("temporary linear correction matrix M", volume[nodeListi]->nodeList(), Tensor::zero); + } + + +#pragma omp parallel + { + // Thread private scratch variables + int i, j, nodeListi, nodeListj; + + typename SpheralThreads::FieldListStack threadStack; + auto M_thread = M.threadCopy(threadStack); + auto DpDx_thread = DpDx.threadCopy(threadStack); + auto DvDx_thread = DvDx.threadCopy(threadStack); + +#pragma omp for + for (auto kk = 0u; kk < npairs; ++kk) { + i = pairs[kk].i_node; + j = pairs[kk].j_node; + nodeListi = pairs[kk].i_list; + nodeListj = pairs[kk].j_list; + + // Get the state for node i. + const auto& ri = position(nodeListi, i); + const auto& voli = volume(nodeListi, i); + const auto& Hi = H(nodeListi, i); + const auto Hdeti = Hi.Determinant(); + + CHECK(voli > 0.0); + CHECK(Hdeti > 0.0); + + auto& Mi = M_thread(nodeListi, i); + + // Get the state for node j + const auto& rj = position(nodeListj, j); + const auto& volj = volume(nodeListj, j); + const auto& Hj = H(nodeListj, j); + const auto Hdetj = Hj.Determinant(); + + CHECK(volj > 0.0); + CHECK(Hdetj > 0.0); + + auto& Mj = M_thread(nodeListj, j); + + const auto rij = ri - rj; + + const auto etai = Hi*rij; + const auto etaj = Hj*rij; + const auto etaMagi = etai.magnitude(); + const auto etaMagj = etaj.magnitude(); + + CHECK(etaMagi >= 0.0); + CHECK(etaMagj >= 0.0); + + const auto gWi = W.gradValue(etaMagi, Hdeti); + const auto Hetai = Hi*etai.unitVector(); + const auto gradWi = gWi*Hetai; + + const auto gWj = W.gradValue(etaMagj, Hdetj); + const auto Hetaj = Hj*etaj.unitVector(); + const auto gradWj = gWj*Hetaj; + + const auto gradPsii = volj*gradWi; + const auto gradPsij = voli*gradWj; + + // Linear gradient correction term. + Mi -= rij.dyad(gradPsii); + Mj -= rij.dyad(gradPsij); + + // // based on nodal values + const auto& vi = velocity(nodeListi, i); + const auto& Pi = pressure(nodeListi, i); + const auto& vj = velocity(nodeListj, j); + const auto& Pj = pressure(nodeListj, j); + auto& DpDxi = DpDx_thread(nodeListi, i); + auto& DvDxi = DvDx_thread(nodeListi, i); + auto& DpDxj = DpDx_thread(nodeListj, j); + auto& DvDxj = DvDx_thread(nodeListj, j); + + DpDxi -= (Pi-Pj)*gradPsii; + DpDxj -= (Pi-Pj)*gradPsij; + + DvDxi -= (vi-vj).dyad(gradPsii); + DvDxj -= (vi-vj).dyad(gradPsij); + + } // loop over pairs + + // Reduce the thread values to the master. + threadReduceFieldLists(threadStack); + + } // OpenMP parallel region + + // Finish up the spatial gradient calculation + for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { + const auto& nodeList = volume[nodeListi]->nodeList(); + const auto ni = nodeList.numInternalNodes(); +#pragma omp parallel for + for (auto i = 0u; i < ni; ++i) { + const auto numNeighborsi = connectivityMap.numNeighborsForNode(nodeListi, i); + + auto& Mi = M(nodeListi, i); + auto& DpDxi = DpDx(nodeListi, i); + auto& DvDxi = DvDx(nodeListi, i); + + const auto Mdeti = std::abs(Mi.Determinant()); + + const auto enoughNeighbors = numNeighborsi > Dimension::pownu(2); + const auto goodM = (Mdeti > 1e-2 and enoughNeighbors); + + Mi = ( goodM ? Mi.Inverse() : Tensor::one); + + DpDxi = Mi.Transpose()*DpDxi; + DvDxi = DvDxi*Mi; + + } // loop nodes + } // loop nodelists +} // function +} // spheral namespace diff --git a/src/GSPH/initializeGradients.hh b/src/GSPH/initializeGradients.hh new file mode 100644 index 000000000..46a7aa666 --- /dev/null +++ b/src/GSPH/initializeGradients.hh @@ -0,0 +1,34 @@ +//---------------------------------Spheral++----------------------------------// +// initializes the pressure and velocity gradients for Riemann solver - based +// SPH varients +//----------------------------------------------------------------------------// + +#ifndef __Spheral__initializeGradients__ +#define __Spheral__initializeGradients__ + +#include + +namespace Spheral { + + // Forward declarations. + template class ConnectivityMap; + template class TableKernel; + template class FieldList; + + +template +void +initializeGradients(const ConnectivityMap& connectivityMap, + const TableKernel& W, + const FieldList& position, + const FieldList& H, + const FieldList& volume, + const FieldList& pressure, + const FieldList& velocity, + FieldList& DpDx, + FieldList& DvDx); + +} + + + #endif \ No newline at end of file diff --git a/src/GSPH/initializeGradientsInst.cc.py b/src/GSPH/initializeGradientsInst.cc.py new file mode 100644 index 000000000..42d25b736 --- /dev/null +++ b/src/GSPH/initializeGradientsInst.cc.py @@ -0,0 +1,21 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "GSPH/initializeGradients.cc" +#include "Geometry/Dimension.hh" + +namespace Spheral { + + + template void initializeGradients(const ConnectivityMap >&, + const TableKernel >&, + const FieldList, Dim< %(ndim)s >::Vector>&, + const FieldList, Dim< %(ndim)s >::SymTensor>&, + const FieldList, Dim< %(ndim)s >::Scalar>&, + const FieldList, Dim< %(ndim)s >::Scalar>&, + const FieldList, Dim< %(ndim)s >::Vector>&, + FieldList, Dim< %(ndim)s >::Vector>&, + FieldList, Dim< %(ndim)s >::Tensor>&); +} +""" From 20e3b4d4ca20ed1f8828501dcebdc3364ae68b13 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 27 Dec 2022 10:17:35 -0800 Subject: [PATCH 18/60] updating GSPH for cleaner initialization implementation this commit removes the isFirstCycle switch which I was using to hackishly initialize the spatial derivatives. When switching over to using the initializeOnStartUp method the switch never flipped messing up the gradients. --- src/GSPH/GSPHEvaluateDerivatives.cc | 16 +++++------- src/GSPH/GSPHHydroBase.cc | 25 +------------------ src/GSPH/GenericRiemannHydro.cc | 36 --------------------------- src/GSPH/GenericRiemannHydro.hh | 4 --- src/GSPH/GenericRiemannHydroInline.hh | 20 --------------- src/GSPH/MFMEvaluateDerivatives.cc | 4 +-- src/GSPH/MFMHydroBase.cc | 20 +-------------- 7 files changed, 9 insertions(+), 116 deletions(-) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index 3a37a32fb..1d1e9f344 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -437,10 +437,8 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, // The kernels and such. const auto& W = this->kernel(); const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient - or this->isFirstCycle() or this->gradientType() == GradientType::SPHUncorrectedGradient); - const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient - or this->isFirstCycle()); + const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient); // The connectivity. const auto& connectivityMap = dataBase.connectivityMap(); const auto& nodeLists = connectivityMap.nodeLists(); @@ -558,7 +556,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, } // OpenMP parallel region - // Finish up the spatial gradient calculation + // loop the nodes to finish up the spatial gradient calculation for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { const auto& nodeList = M[nodeListi]->nodeList(); const auto ni = nodeList.numInternalNodes(); @@ -582,10 +580,9 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, newRiemannDpDxi = Mi.Transpose()*newRiemannDpDxi; newRiemannDvDxi = newRiemannDvDxi*Mi; - } - } - - } + } // if correctSpatialGradients + } // for each node + } // for each node list for (ConstBoundaryIterator boundItr = this->boundaryBegin(); boundItr != this->boundaryEnd(); @@ -603,6 +600,5 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, boundaryItr != this->boundaryEnd(); ++boundaryItr) (*boundaryItr)->finalizeGhostBoundary(); -} - +} // MC correction method } // spheral namespace diff --git a/src/GSPH/GSPHHydroBase.cc b/src/GSPH/GSPHHydroBase.cc index 95ad1271f..8a9960432 100644 --- a/src/GSPH/GSPHHydroBase.cc +++ b/src/GSPH/GSPHHydroBase.cc @@ -212,27 +212,8 @@ initialize(const typename Dimension::Scalar time, State& state, StateDerivatives& derivs) { TIME_BEGIN("GSPHinitialize"); - - // initialize spatial gradients so we can store them - // if (this->isFirstCycle()){ - // this->computeMCorrection(time,dt,dataBase,state,derivs); - // } - - // GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); - - // if (this->isFirstCycle()){ - // auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); - // auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); - // auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - - // M.Zero(); - // newRiemannDpDx.Zero(); - // newRiemannDvDx.Zero(); - // this->isFirstCycle(false); - // } - + GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); TIME_END("GSPHinitialize"); - } //------------------------------------------------------------------------------ @@ -260,9 +241,7 @@ GSPHHydroBase:: applyGhostBoundaries(State& state, StateDerivatives& derivs) { TIME_BEGIN("GSPHghostBounds"); - GenericRiemannHydro::applyGhostBoundaries(state,derivs); - TIME_END("GSPHghostBounds"); } @@ -275,9 +254,7 @@ GSPHHydroBase:: enforceBoundaries(State& state, StateDerivatives& derivs) { TIME_BEGIN("GSPHenforceBounds"); - GenericRiemannHydro::enforceBoundaries(state,derivs); - TIME_END("GSPHenforceBounds"); } diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 8dc76846d..b84d027ff 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -100,7 +100,6 @@ GenericRiemannHydro(const SmoothingScaleBase& smoothingScaleMethod, mGradientType(gradType), mDensityUpdate(densityUpdate), mHEvolution(HUpdate), - mIsFirstCycle(true), mCompatibleEnergyEvolution(compatibleEnergyEvolution), mEvolveTotalEnergy(evolveTotalEnergy), mXSPH(XSPH), @@ -527,41 +526,6 @@ initialize(const typename Dimension::Scalar time, const DataBase& dataBase, State& state, StateDerivatives& derivs) { - - // auto& riemannSolver = this->riemannSolver(); - - // if(riemannSolver.linearReconstruction()){ - // const auto& connectivityMap = dataBase.connectivityMap(); - // const auto& nodeLists = connectivityMap.nodeLists(); - // const auto numNodeLists = nodeLists.size(); - - // // copy from previous time step - // for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { - // const auto& nodeList = nodeLists[nodeListi]; - // const auto ni = nodeList->numInternalNodes(); - // #pragma omp parallel for - // for (auto i = 0u; i < ni; ++i) { - // const auto DvDxi = mNewRiemannDvDx(nodeListi,i); - // const auto DpDxi = mNewRiemannDpDx(nodeListi,i); - - // mRiemannDvDx(nodeListi,i) = DvDxi; - // mRiemannDpDx(nodeListi,i) = DpDxi; - - // } - // } - - // for (auto boundItr =this->boundaryBegin(); - // boundItr != this->boundaryEnd(); - // ++boundItr) { - // (*boundItr)->applyFieldListGhostBoundary(mRiemannDvDx); - // (*boundItr)->applyFieldListGhostBoundary(mRiemannDpDx); - // } - - // for (auto boundItr = this->boundaryBegin(); - // boundItr != this->boundaryEnd(); - // ++boundItr) (*boundItr)->finalizeGhostBoundary(); - - // } // if LinearReconstruction } diff --git a/src/GSPH/GenericRiemannHydro.hh b/src/GSPH/GenericRiemannHydro.hh index 7e6f68728..894305bf8 100644 --- a/src/GSPH/GenericRiemannHydro.hh +++ b/src/GSPH/GenericRiemannHydro.hh @@ -147,9 +147,6 @@ public: void HEvolution(HEvolutionType type); // setter-getters for our bool switches - bool isFirstCycle() const; - void isFirstCycle(bool val); - bool compatibleEnergyEvolution() const; void compatibleEnergyEvolution(bool val); @@ -234,7 +231,6 @@ private: HEvolutionType mHEvolution; // A bunch of switches. - bool mIsFirstCycle; bool mCompatibleEnergyEvolution; bool mEvolveTotalEnergy; bool mXSPH; diff --git a/src/GSPH/GenericRiemannHydroInline.hh b/src/GSPH/GenericRiemannHydroInline.hh index d90581b28..ab296c78f 100644 --- a/src/GSPH/GenericRiemannHydroInline.hh +++ b/src/GSPH/GenericRiemannHydroInline.hh @@ -264,26 +264,6 @@ HEvolution(HEvolutionType type) { mHEvolution = type; } - -//------------------------------------------------------------------------------ -// Access the trigger need to store spatial derivs on problem start up -//------------------------------------------------------------------------------ -template -inline -bool -GenericRiemannHydro::isFirstCycle() const { - return mIsFirstCycle; -} - -template -inline -void -GenericRiemannHydro::isFirstCycle(bool val) { - mIsFirstCycle = val; -} - - - //------------------------------------------------------------------------------ // Access the flag determining if we're using the compatible energy evolution // algorithm. diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index 3cbc2156d..1a2a26f64 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -432,10 +432,8 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, StateDerivatives& derivatives) const { const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient - or this->isFirstCycle() or this->gradientType() == GradientType::SPHUncorrectedGradient); - const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient - or this->isFirstCycle()); + const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient); // The kernels and such. const auto& W = this->kernel(); diff --git a/src/GSPH/MFMHydroBase.cc b/src/GSPH/MFMHydroBase.cc index 9753c53a7..71b716505 100644 --- a/src/GSPH/MFMHydroBase.cc +++ b/src/GSPH/MFMHydroBase.cc @@ -204,25 +204,7 @@ initialize(const typename Dimension::Scalar time, const DataBase& dataBase, State& state, StateDerivatives& derivs) { - - // initialize spatial gradients so we can store them - // if (this->isFirstCycle()){ - // this->computeMCorrection(time,dt,dataBase,state,derivs); - // } - - // GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); - - // if (this->isFirstCycle()){ - // auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); - // auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); - // auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - - // M.Zero(); - // newRiemannDpDx.Zero(); - // newRiemannDvDx.Zero(); - // this->isFirstCycle(false); - // } - + GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); } //------------------------------------------------------------------------------ From de117306580dcbf8d414f150280cbbfe8775d37f Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 10 Jan 2023 11:31:21 -0800 Subject: [PATCH 19/60] removing some uneccessary BC applications --- src/GSPH/GenericRiemannHydro.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index b84d027ff..d1107d2a0 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -573,11 +573,9 @@ applyGhostBoundaries(State& state, auto DpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto DvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - //auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); boundaryItr != this->boundaryEnd(); ++boundaryItr) { - //(*boundaryItr)->applyFieldListGhostBoundary(M); (*boundaryItr)->applyFieldListGhostBoundary(volume); (*boundaryItr)->applyFieldListGhostBoundary(mass); (*boundaryItr)->applyFieldListGhostBoundary(massDensity); @@ -609,14 +607,10 @@ enforceBoundaries(State& state, auto soundSpeed = state.fields(HydroFieldNames::soundSpeed, 0.0); auto DpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto DvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - - // our store vars in the riemann solver - //auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); boundaryItr != this->boundaryEnd(); ++boundaryItr) { - //(*boundaryItr)->enforceFieldListBoundary(M); (*boundaryItr)->enforceFieldListBoundary(volume); (*boundaryItr)->enforceFieldListBoundary(mass); (*boundaryItr)->enforceFieldListBoundary(massDensity); From 9456a231e423457b669f400e8a53a01e3994ca0e Mon Sep 17 00:00:00 2001 From: jmpearl Date: Fri, 13 Jan 2023 20:35:57 -0800 Subject: [PATCH 20/60] from Mike's DEM fix realized GSPH/MFM both assumed they were the only DvDt modifiers --- src/GSPH/GSPHEvaluateDerivatives.cc | 8 ++++---- src/GSPH/MFMEvaluateDerivatives.cc | 11 ++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index 1d1e9f344..acfc017f7 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -265,16 +265,16 @@ evaluateDerivatives(const typename Dimension::Scalar time, // acceleration //------------------------------------------------------ const auto deltaDvDt = Pstar*(Ai+Aj); - DvDti -= deltaDvDt; - DvDtj += deltaDvDt; + DvDti -= deltaDvDt/mi; + DvDtj += deltaDvDt/mj; // energy //------------------------------------------------------ const auto deltaDepsDti = 2.0*Pstar*Ai.dot(vi-vstar); const auto deltaDepsDtj = 2.0*Pstar*Aj.dot(vstar-vj); - DepsDti += deltaDepsDti; - DepsDtj += deltaDepsDtj; + DepsDti += deltaDepsDti/mi; + DepsDtj += deltaDepsDtj/mj; if(compatibleEnergy){ const auto invmij = 1.0/(mi*mj); diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index 1a2a26f64..430235bb1 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -265,16 +265,16 @@ evaluateDerivatives(const typename Dimension::Scalar time, // acceleration //------------------------------------------------------ const auto deltaDvDt = Pstar*Astar; - DvDti -= deltaDvDt; - DvDtj += deltaDvDt; + DvDti -= deltaDvDt/mi; + DvDtj += deltaDvDt/mj; // energy //------------------------------------------------------ const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar); const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj); - DepsDti += deltaDepsDti; - DepsDtj += deltaDepsDtj; + DepsDti += deltaDepsDti/mi; + DepsDtj += deltaDepsDtj/mj; if(compatibleEnergy){ const auto invmij = 1.0/(mi*mj); @@ -373,9 +373,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); - DvDti /= mi; - DepsDti /= mi; - normi += voli*Hdeti*W0; DvolDti = voli * DvDxi.Trace() ; From bd9c8e5e34326f2f1fd65f1ef19e9e0814c42ce2 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Sun, 15 Jan 2023 08:33:21 -0800 Subject: [PATCH 21/60] volume missing from restart read/write methods --- src/GSPH/GenericRiemannHydro.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index d1107d2a0..2ece0fafe 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -633,6 +633,7 @@ GenericRiemannHydro:: dumpState(FileIO& file, const string& pathName) const { file.write(mTimeStepMask, pathName + "/timeStepMask"); + file.write(mVolume, pathName + "/volume"); file.write(mPressure, pathName + "/pressure"); file.write(mSoundSpeed, pathName + "/soundSpeed"); @@ -669,6 +670,7 @@ GenericRiemannHydro:: restoreState(const FileIO& file, const string& pathName) { file.read(mTimeStepMask, pathName + "/timeStepMask"); + file.read(mVolume, pathName + "/volume"); file.read(mPressure, pathName + "/pressure"); file.read(mSoundSpeed, pathName + "/soundSpeed"); From 746a251859d280668fb04c35ed4a043aa53dc261 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Sun, 15 Jan 2023 08:34:35 -0800 Subject: [PATCH 22/60] bugfix GSPH eval-derivs --- src/GSPH/GSPHEvaluateDerivatives.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index acfc017f7..6ef7a6cfa 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -375,9 +375,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); - DvDti /= mi; - DepsDti /= mi; - normi += voli*Hdeti*W0; DrhoDti = - rhoi * DvDxi.Trace(); From e171cc63640b5587a2a8b351a4bc93ae15d44af3 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Thu, 18 May 2023 21:25:36 -0700 Subject: [PATCH 23/60] update --- src/GSPH/CMakeLists.txt | 2 ++ src/GSPH/GSPHFieldNames.cc | 2 ++ src/GSPH/GSPHFieldNames.hh | 2 ++ src/GSPH/MFMHydroBase.cc | 1 - src/GSPH/MFVEvaluateDerivatives.cc | 37 +++++++++++++++++++----------- src/GSPH/MFVHydroBase.cc | 34 ++++++++------------------- src/GSPH/MFVHydroBase.hh | 5 +++- src/GSPH/MFVHydroBaseInline.hh | 14 +++++++++++ 8 files changed, 58 insertions(+), 39 deletions(-) diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 11553bf96..3f2cc7df5 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -8,6 +8,7 @@ set(GSPH_inst GenericRiemannHydro GSPHHydroBase MFMHydroBase + MFVHydroBase Policies/PureReplaceFieldList Policies/ReplaceWithRatioPolicy Limiters/LimiterBase @@ -36,6 +37,7 @@ set(GSPH_headers GenericRiemannHydro.hh GSPHHydroBase.hh MFMHydroBase.hh + MFVHydroBase.hh Policies/PureReplaceFieldList.hh Policies/ReplaceWithRatioPolicy.hh Limiters/LimiterBase.hh diff --git a/src/GSPH/GSPHFieldNames.cc b/src/GSPH/GSPHFieldNames.cc index 46d5b6b83..717109da6 100644 --- a/src/GSPH/GSPHFieldNames.cc +++ b/src/GSPH/GSPHFieldNames.cc @@ -6,6 +6,8 @@ #include "GSPHFieldNames.hh" +const std::string Spheral::GSPHFieldNames::momentum = "momentum"; +const std::string Spheral::GSPHFieldNames::thermalEnergy = "thermal energy"; const std::string Spheral::GSPHFieldNames::densityGradient = "density gradient"; const std::string Spheral::GSPHFieldNames::pressureGradient = "pressure gradient"; const std::string Spheral::GSPHFieldNames::deviatoricStressTensorGradient = "deviatoric stress tensor gradient"; diff --git a/src/GSPH/GSPHFieldNames.hh b/src/GSPH/GSPHFieldNames.hh index 941aa9ae7..acd55b6a9 100644 --- a/src/GSPH/GSPHFieldNames.hh +++ b/src/GSPH/GSPHFieldNames.hh @@ -12,6 +12,8 @@ namespace Spheral { struct GSPHFieldNames { + static const std::string momentum; + static const std::string thermalEnergy; static const std::string densityGradient; static const std::string pressureGradient; static const std::string deviatoricStressTensorGradient; diff --git a/src/GSPH/MFMHydroBase.cc b/src/GSPH/MFMHydroBase.cc index 71b716505..3496f7e4c 100644 --- a/src/GSPH/MFMHydroBase.cc +++ b/src/GSPH/MFMHydroBase.cc @@ -88,7 +88,6 @@ MFMHydroBase(const SmoothingScaleBase& smoothingScaleMethod, mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::volume); - } //------------------------------------------------------------------------------ diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index 34d3b062b..2097b582b 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -71,6 +71,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto DvolDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::volume, 0.0); auto DvDt = derivatives.fields(HydroFieldNames::hydroAcceleration, Vector::zero); auto DepsDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); + auto DEDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, 0.0); + auto DpDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::momentum, Vector::zero); auto DvDx = derivatives.fields(HydroFieldNames::velocityGradient, Tensor::zero); auto DHDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::H, SymTensor::zero); auto Hideal = derivatives.fields(ReplaceBoundedFieldList::prefix() + HydroFieldNames::H, SymTensor::zero); @@ -81,13 +83,15 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - + CHECK(M.size() == numNodeLists); CHECK(normalization.size() == numNodeLists); CHECK(DxDt.size() == numNodeLists); CHECK(DvolDt.size() == numNodeLists); CHECK(DvDt.size() == numNodeLists); CHECK(DepsDt.size() == numNodeLists); + CHECK(DEDt.size() == numNodeLists); + CHECK(DpDt.size() == numNodeLists); CHECK(DvDx.size() == numNodeLists); CHECK(DHDt.size() == numNodeLists); CHECK(Hideal.size() == numNodeLists); @@ -117,6 +121,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); auto DepsDt_thread = DepsDt.threadCopy(threadStack); + auto DEDt_thread = DEDt.threadCopy(threadStack); + auto DpDt_thread = DpDt.threadCopy(threadStack); auto DvDx_thread = DvDx.threadCopy(threadStack); auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); @@ -150,6 +156,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& normi = normalization_thread(nodeListi,i); auto& DepsDti = DepsDt_thread(nodeListi, i); + auto& DEDti = DEDt_thread(nodeListi, i); + auto& DpDti = DpDt_thread(nodeListi, i); auto& DvDti = DvDt_thread(nodeListi, i); auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi,i); auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi,i); @@ -181,6 +189,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& normj = normalization_thread(nodeListj,j); auto& DvDtj = DvDt_thread(nodeListj, j); auto& DepsDtj = DepsDt_thread(nodeListj, j); + auto& DEDtj = DEDt_thread(nodeListj, j); + auto& DpDtj = DpDt_thread(nodeListj, j); auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj,j); auto& newRiemannDvDxj = newRiemannDvDx_thread(nodeListj,j); auto& DvDxj = DvDx_thread(nodeListj, j); @@ -264,17 +274,20 @@ evaluateDerivatives(const typename Dimension::Scalar time, // acceleration //------------------------------------------------------ - const auto deltaDvDt = Pstar*Astar; - DvDti -= deltaDvDt; - DvDtj += deltaDvDt; + const auto fluxSwitch = 1; + const auto vflux = vstar-(vi+vj)/2.0; + const auto rhostar = (vflux.dot(rhatij) > 0 ? rhostarj : rhostari); + const auto deltaDvDt = Pstar*Astar + fluxSwitch * (rhostar*vflux.dyad(vstar)).dot(Astar); + DpDti -= deltaDvDt; + DpDtj += deltaDvDt; // energy //------------------------------------------------------ - const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar); - const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj); + const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar) + rhostar*epsstar*vflux.dot(Astar); + const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj) + rhostar*epsstar*vflux.dot(Astar); - DepsDti += deltaDepsDti; - DepsDtj += deltaDepsDtj; + DEDti += deltaDepsDti; + DEDtj += deltaDepsDtj; if(compatibleEnergy){ const auto invmij = 1.0/(mi*mj); @@ -373,9 +386,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); - DvDti /= mi; - DepsDti /= mi; - normi += voli*Hdeti*W0; DvolDti = voli * DvDxi.Trace() ; @@ -432,7 +442,8 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, StateDerivatives& derivatives) const { const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient - or this->isFirstCycle()); + or this->gradientType() == GradientType::SPHUncorrectedGradient); + const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient); // The kernels and such. const auto& W = this->kernel(); @@ -565,7 +576,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi = ( goodM ? Mi.Inverse() : Tensor::one); - if (calcSpatialGradients){ + if (correctSpatialGradients){ auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index ff4fa4eb5..f9b0ea036 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -84,11 +84,12 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, nTensile, xmin, xmax), + mDthermalEnergyDt(FieldStorageType::CopyFields), + mDmomentumDt(FieldStorageType::CopyFields), mDvolumeDt(FieldStorageType::CopyFields){ - + mDthermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); + mDmomentumDt = dataBase.newFluidFieldList(Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum); mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::volume); - - } //------------------------------------------------------------------------------ @@ -154,7 +155,8 @@ MFVHydroBase:: registerDerivatives(DataBase& dataBase, StateDerivatives& derivs) { GenericRiemannHydro::registerDerivatives(dataBase,derivs); - + dataBase.resizeFluidFieldList(mDmomentumDt, Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum, false); + dataBase.resizeFluidFieldList(mDthermalEnergyDt, 0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, false); dataBase.resizeFluidFieldList(mDvolumeDt, 0.0, IncrementFieldList::prefix() + HydroFieldNames::volume, false); derivs.enroll(mDvolumeDt); } @@ -204,25 +206,7 @@ initialize(const typename Dimension::Scalar time, const DataBase& dataBase, State& state, StateDerivatives& derivs) { - - // initialize spatial gradients so we can store them - if (this->isFirstCycle()){ - this->computeMCorrection(time,dt,dataBase,state,derivs); - } - GenericRiemannHydro::initialize(time,dt,dataBase,state,derivs); - - if (this->isFirstCycle()){ - auto M = derivs.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); - auto newRiemannDpDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); - auto newRiemannDvDx = derivs.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - - M.Zero(); - newRiemannDpDx.Zero(); - newRiemannDvDx.Zero(); - this->isFirstCycle(false); - } - } //------------------------------------------------------------------------------ @@ -270,7 +254,8 @@ void MFVHydroBase:: dumpState(FileIO& file, const string& pathName) const { GenericRiemannHydro::dumpState(file,pathName); - + file.write(mDmomentumDt, pathName + "/DmomentumDt"); + file.write(mDthermalEnergyDt, pathName + "/DthermalEnergyDt"); file.write(mDvolumeDt, pathName + "/DvolumeDt"); } @@ -282,7 +267,8 @@ void MFVHydroBase:: restoreState(const FileIO& file, const string& pathName) { GenericRiemannHydro::restoreState(file,pathName); - + file.read(mDmomentumDt, pathName + "/DmomentumDt"); + file.read(mDthermalEnergyDt, pathName + "/DthermalEnergyDt"); file.read(mDvolumeDt, pathName + "/DvolumeDt"); } diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 8de5f6d41..628119f80 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -123,6 +123,8 @@ public: void enforceBoundaries(State& state, StateDerivatives& derivs) override; + const FieldList& DthermalEnergyDt() const; + const FieldList& DmomentumDt() const; const FieldList& DvolumeDt() const; //**************************************************************************** @@ -132,7 +134,8 @@ public: virtual void restoreState(const FileIO& file, const std::string& pathName) override; //**************************************************************************** private: - + FieldList mDthermalEnergyDt; + FieldList mDmomentumDt; FieldList mDvolumeDt; // No default constructor, copying, or assignment. diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index 22ce90ac0..57c936997 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -6,6 +6,20 @@ template inline const FieldList& MFVHydroBase:: +DthermalEnergyDt() const { + return mDthermalEnergyDt; +} +template +inline +const FieldList& +MFVHydroBase:: +DmomentumDt() const { + return mDmomentumDt; +} +template +inline +const FieldList& +MFVHydroBase:: DvolumeDt() const { return mDvolumeDt; } From 20923c47786daeff5b4221745e1928ddc17ec3cf Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Wed, 14 Jun 2023 19:22:36 -0700 Subject: [PATCH 24/60] step --- src/GSPH/CMakeLists.txt | 2 + src/GSPH/GSPHFieldNames.cc | 5 +- src/GSPH/GSPHFieldNames.hh | 3 + src/GSPH/GSPHHydros.py | 106 +++++++- src/GSPH/GSPHHydros2.py | 253 ++++++++++++++++++ src/GSPH/MFVEvaluateDerivatives.cc | 61 +++-- src/GSPH/MFVHydroBase.cc | 36 ++- src/GSPH/MFVHydroBase.hh | 2 + src/GSPH/MFVHydroBaseInline.hh | 7 + .../IncrementSpecificFromTotalPolicy.cc | 152 +++++++++++ .../IncrementSpecificFromTotalPolicy.hh | 67 +++++ ...IncrementSpecificFromTotalPolicyInst.cc.py | 12 + src/PYB11/GSPH/GSPH_PYB11.py | 3 + src/PYB11/GSPH/MFVHydroBase.py | 115 ++++++++ .../Hydro/Noh/Noh-cylindrical-2d.py | 1 - 15 files changed, 789 insertions(+), 36 deletions(-) create mode 100644 src/GSPH/GSPHHydros2.py create mode 100644 src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc create mode 100644 src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh create mode 100644 src/GSPH/Policies/IncrementSpecificFromTotalPolicyInst.cc.py create mode 100644 src/PYB11/GSPH/MFVHydroBase.py diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 3f2cc7df5..37dad075d 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -11,6 +11,7 @@ set(GSPH_inst MFVHydroBase Policies/PureReplaceFieldList Policies/ReplaceWithRatioPolicy + Policies/IncrementSpecificFromTotalPolicy Limiters/LimiterBase Limiters/VanLeerLimiter Limiters/SuperbeeLimiter @@ -40,6 +41,7 @@ set(GSPH_headers MFVHydroBase.hh Policies/PureReplaceFieldList.hh Policies/ReplaceWithRatioPolicy.hh + Policies/IncrementSpecificFromTotalPolicy.hh Limiters/LimiterBase.hh Limiters/VanLeerLimiter.hh Limiters/SuperbeeLimiter.hh diff --git a/src/GSPH/GSPHFieldNames.cc b/src/GSPH/GSPHFieldNames.cc index 717109da6..2aefe99c1 100644 --- a/src/GSPH/GSPHFieldNames.cc +++ b/src/GSPH/GSPHFieldNames.cc @@ -13,4 +13,7 @@ const std::string Spheral::GSPHFieldNames::pressureGradient = "pressure gradient const std::string Spheral::GSPHFieldNames::deviatoricStressTensorGradient = "deviatoric stress tensor gradient"; const std::string Spheral::GSPHFieldNames::RiemannPressureGradient = "Riemann solvers pressure gradient"; const std::string Spheral::GSPHFieldNames::RiemannVelocityGradient = "Riemann solvers velocity gradient"; -const std::string Spheral::GSPHFieldNames::RiemannDeviatoricStressTensorGradient = "Riemann solvers deviatoric stress tensor gradient"; \ No newline at end of file +const std::string Spheral::GSPHFieldNames::RiemannDeviatoricStressTensorGradient = "Riemann solvers deviatoric stress tensor gradient"; + +const std::string Spheral::GSPHFieldNames::momentumPolicy = "update policy momentum"; +const std::string Spheral::GSPHFieldNames::thermalEnergyPolicy = "update policy thermal energy"; \ No newline at end of file diff --git a/src/GSPH/GSPHFieldNames.hh b/src/GSPH/GSPHFieldNames.hh index acd55b6a9..776c037ff 100644 --- a/src/GSPH/GSPHFieldNames.hh +++ b/src/GSPH/GSPHFieldNames.hh @@ -20,6 +20,9 @@ struct GSPHFieldNames { static const std::string RiemannPressureGradient; static const std::string RiemannVelocityGradient; static const std::string RiemannDeviatoricStressTensorGradient; + + static const std::string momentumPolicy; + static const std::string thermalEnergyPolicy; }; } diff --git a/src/GSPH/GSPHHydros.py b/src/GSPH/GSPHHydros.py index 618871580..1b217f289 100644 --- a/src/GSPH/GSPHHydros.py +++ b/src/GSPH/GSPHHydros.py @@ -233,10 +233,14 @@ def MFM(dataBase, print(" which will result in fluid behaviour for those nodes.") raise RuntimeError("Cannot mix solid and fluid NodeLists.") + Constructor = eval("MFMHydroBase%id" % ndim) + + # Smoothing scale update if ASPH: - Constructor = eval("AMFMHydro%id" % ndim) + smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) else: - Constructor = eval("MFMHydro%id" % ndim) + smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) + if riemannSolver is None: waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) @@ -248,7 +252,9 @@ def MFM(dataBase, xmin = (ndim,) + xmin xmax = (ndim,) + xmax - kwargs = {"riemannSolver" : riemannSolver, + kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, + "dataBase" : dataBase, + "riemannSolver" : riemannSolver, "W" : W, "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, "dataBase" : dataBase, @@ -258,7 +264,96 @@ def MFM(dataBase, "evolveTotalEnergy" : evolveTotalEnergy, "XSPH" : XSPH, "correctVelocityGradient" : correctVelocityGradient, - "gradientType" : gradientType, + "gradType" : gradientType, + "densityUpdate" : densityUpdate, + "HUpdate" : HUpdate, + "epsTensile" : epsTensile, + "nTensile" : nTensile, + "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), + "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} + + + # Build and return the thing. + result = Constructor(**kwargs) + #result._smoothingScaleMethod = smoothingScaleMethod + result.riemannSolver = riemannSolver + + return result + + + +#------------------------------------------------------------------------------- +# MFM convience wrapper function +#------------------------------------------------------------------------------- +def MFV(dataBase, + W, + riemannSolver=None, + specificThermalEnergyDiffusionCoefficient = 0.0, + cfl = 0.25, + gradientType = HydroAccelerationGradient, + densityUpdate = IntegrateDensity, + useVelocityMagnitudeForDt = False, + compatibleEnergyEvolution = True, + evolveTotalEnergy = False, + XSPH = False, + correctVelocityGradient = False, + HUpdate = IdealH, + epsTensile = 0.0, + nTensile = 4.0, + damageRelieveRubble = False, + negativePressureInDamage = False, + strengthInDamage = False, + xmin = (-1e100, -1e100, -1e100), + xmax = ( 1e100, 1e100, 1e100), + ASPH = False, + RZ = False): + + # for now we'll just piggy back off this enum + assert densityUpdate in (RigorousSumDensity,IntegrateDensity) + + # We use the provided DataBase to sniff out what sort of NodeLists are being + # used, and based on this determine which SPH object to build. + ndim = dataBase.nDim + nfluid = dataBase.numFluidNodeLists + nsolid = dataBase.numSolidNodeLists + if nsolid > 0 and nsolid != nfluid: + print("MFM Error: you have provided both solid and fluid NodeLists, which is currently not supported.") + print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,") + print(" which will result in fluid behaviour for those nodes.") + raise RuntimeError("Cannot mix solid and fluid NodeLists.") + + Constructor = eval("MFVHydroBase%id" % ndim) + + # Smoothing scale update + if ASPH: + smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) + else: + smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) + + + if riemannSolver is None: + waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) + slopeLimiter = eval("VanLeerLimiter%id()" % (ndim)) + linearReconstruction=True + riemannSolver = eval("HLLC%id(slopeLimiter,waveSpeedMethod,linearReconstruction)" % (ndim)) + + # Build the constructor arguments + xmin = (ndim,) + xmin + xmax = (ndim,) + xmax + + kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, + "dataBase" : dataBase, + "riemannSolver" : riemannSolver, + "W" : W, + "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, + "dataBase" : dataBase, + "cfl" : cfl, + "useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt, + "compatibleEnergyEvolution" : compatibleEnergyEvolution, + "evolveTotalEnergy" : evolveTotalEnergy, + "XSPH" : XSPH, + "correctVelocityGradient" : correctVelocityGradient, + "gradType" : gradientType, "densityUpdate" : densityUpdate, "HUpdate" : HUpdate, "epsTensile" : epsTensile, @@ -269,5 +364,8 @@ def MFM(dataBase, # Build and return the thing. result = Constructor(**kwargs) + #result._smoothingScaleMethod = smoothingScaleMethod + #result.riemannSolver = riemannSolver + return result diff --git a/src/GSPH/GSPHHydros2.py b/src/GSPH/GSPHHydros2.py new file mode 100644 index 000000000..85a52e3d3 --- /dev/null +++ b/src/GSPH/GSPHHydros2.py @@ -0,0 +1,253 @@ +from SpheralCompiledPackages import * + +from spheralDimensions import spheralDimensions +dims = spheralDimensions() + + +#------------------------------------------------------------------------------- +# GSPH convience wrapper function +#------------------------------------------------------------------------------- +def GSPH(dataBase, + W, + riemannSolver=None, + specificThermalEnergyDiffusionCoefficient = 0.0, + cfl = 0.25, + gradientType = HydroAccelerationGradient, + densityUpdate = IntegrateDensity, + useVelocityMagnitudeForDt = False, + compatibleEnergyEvolution = True, + evolveTotalEnergy = False, + XSPH = False, + correctVelocityGradient = False, + HUpdate = IdealH, + epsTensile = 0.0, + nTensile = 4.0, + damageRelieveRubble = False, + negativePressureInDamage = False, + strengthInDamage = False, + xmin = (-1e100, -1e100, -1e100), + xmax = ( 1e100, 1e100, 1e100), + ASPH = False, + RZ = False): + + + assert densityUpdate in (RigorousSumDensity,IntegrateDensity) + + # We use the provided DataBase to sniff out what sort of NodeLists are being + # used, and based on this determine which SPH object to build. + ndim = dataBase.nDim + nfluid = dataBase.numFluidNodeLists + nsolid = dataBase.numSolidNodeLists + if nsolid > 0 and nsolid != nfluid: + print("GSPH Error: you have provided both solid and fluid NodeLists, which is currently not supported.") + print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,") + print(" which will result in fluid behaviour for those nodes.") + raise RuntimeError("Cannot mix solid and fluid NodeLists.") + + Constructor = eval("GSPHHydroBase%id" % ndim) + + if riemannSolver is None: + waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) + slopeLimiter = eval("VanLeerLimiter%id()" % (ndim)) + linearReconstruction=True + riemannSolver = eval("HLLC%id(slopeLimiter,waveSpeedMethod,linearReconstruction)" % (ndim)) + + # Build the constructor arguments + xmin = (ndim,) + xmin + xmax = (ndim,) + xmax + + # Smoothing scale update + if ASPH: + smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) + else: + smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) + + kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, + "dataBase" : dataBase, + "riemannSolver" : riemannSolver, + "W" : W, + "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, + "cfl" : cfl, + "useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt, + "compatibleEnergyEvolution" : compatibleEnergyEvolution, + "evolveTotalEnergy" : evolveTotalEnergy, + "XSPH" : XSPH, + "correctVelocityGradient" : correctVelocityGradient, + "gradType" : gradientType, + "densityUpdate" : densityUpdate, + "HUpdate" : HUpdate, + "epsTensile" : epsTensile, + "nTensile" : nTensile, + "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), + "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} + + # Build and return the thing. + result = Constructor(**kwargs) + return result + +#------------------------------------------------------------------------------- +# MFM convience wrapper function +#------------------------------------------------------------------------------- +def MFM(dataBase, + W, + riemannSolver=None, + specificThermalEnergyDiffusionCoefficient = 0.0, + cfl = 0.25, + gradientType = HydroAccelerationGradient, + densityUpdate = IntegrateDensity, + useVelocityMagnitudeForDt = False, + compatibleEnergyEvolution = True, + evolveTotalEnergy = False, + XSPH = False, + correctVelocityGradient = False, + HUpdate = IdealH, + epsTensile = 0.0, + nTensile = 4.0, + damageRelieveRubble = False, + negativePressureInDamage = False, + strengthInDamage = False, + xmin = (-1e100, -1e100, -1e100), + xmax = ( 1e100, 1e100, 1e100), + ASPH = False, + RZ = False): + + # for now we'll just piggy back off this enum + assert densityUpdate in (RigorousSumDensity,IntegrateDensity) + + # We use the provided DataBase to sniff out what sort of NodeLists are being + # used, and based on this determine which SPH object to build. + ndim = dataBase.nDim + nfluid = dataBase.numFluidNodeLists + nsolid = dataBase.numSolidNodeLists + if nsolid > 0 and nsolid != nfluid: + print("MFM Error: you have provided both solid and fluid NodeLists, which is currently not supported.") + print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,") + print(" which will result in fluid behaviour for those nodes.") + raise RuntimeError("Cannot mix solid and fluid NodeLists.") + + Constructor = eval("MFMHydroBase%id" % ndim) + + if riemannSolver is None: + waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) + slopeLimiter = eval("VanLeerLimiter%id()" % (ndim)) + linearReconstruction=True + riemannSolver = eval("HLLC%id(slopeLimiter,waveSpeedMethod,linearReconstruction)" % (ndim)) + + # Build the constructor arguments + xmin = (ndim,) + xmin + xmax = (ndim,) + xmax + + # Smoothing scale update + if ASPH: + smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) + else: + smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) + + kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, + "dataBase" : dataBase, + "riemannSolver" : riemannSolver, + "W" : W, + "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, + "cfl" : cfl, + "useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt, + "compatibleEnergyEvolution" : compatibleEnergyEvolution, + "evolveTotalEnergy" : evolveTotalEnergy, + "XSPH" : XSPH, + "correctVelocityGradient" : correctVelocityGradient, + "gradType" : gradientType, + "densityUpdate" : densityUpdate, + "HUpdate" : HUpdate, + "epsTensile" : epsTensile, + "nTensile" : nTensile, + "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), + "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} + + + # Build and return the thing. + result = Constructor(**kwargs) + return result + + + +#------------------------------------------------------------------------------- +# MFM convience wrapper function +#------------------------------------------------------------------------------- +def MFV(dataBase, + W, + riemannSolver=None, + specificThermalEnergyDiffusionCoefficient = 0.0, + cfl = 0.25, + gradientType = HydroAccelerationGradient, + densityUpdate = IntegrateDensity, + useVelocityMagnitudeForDt = False, + compatibleEnergyEvolution = True, + evolveTotalEnergy = False, + XSPH = False, + correctVelocityGradient = False, + HUpdate = IdealH, + epsTensile = 0.0, + nTensile = 4.0, + damageRelieveRubble = False, + negativePressureInDamage = False, + strengthInDamage = False, + xmin = (-1e100, -1e100, -1e100), + xmax = ( 1e100, 1e100, 1e100), + ASPH = False, + RZ = False): + + # for now we'll just piggy back off this enum + assert densityUpdate in (RigorousSumDensity,IntegrateDensity) + + # We use the provided DataBase to sniff out what sort of NodeLists are being + # used, and based on this determine which SPH object to build. + ndim = dataBase.nDim + nfluid = dataBase.numFluidNodeLists + nsolid = dataBase.numSolidNodeLists + if nsolid > 0 and nsolid != nfluid: + print("MFV Error: you have provided both solid and fluid NodeLists, which is currently not supported.") + print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,") + print(" which will result in fluid behaviour for those nodes.") + raise RuntimeError("Cannot mix solid and fluid NodeLists.") + + Constructor = eval("MFVHydroBase%id" % ndim) + + if riemannSolver is None: + waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) + slopeLimiter = eval("VanLeerLimiter%id()" % (ndim)) + linearReconstruction=True + riemannSolver = eval("HLLC%id(slopeLimiter,waveSpeedMethod,linearReconstruction)" % (ndim)) + + # Build the constructor arguments + xmin = (ndim,) + xmin + xmax = (ndim,) + xmax + + # Smoothing scale update + if ASPH: + smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) + else: + smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) + + kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, + "dataBase" : dataBase, + "riemannSolver" : riemannSolver, + "W" : W, + "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, + "cfl" : cfl, + "useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt, + "compatibleEnergyEvolution" : compatibleEnergyEvolution, + "evolveTotalEnergy" : evolveTotalEnergy, + "XSPH" : XSPH, + "correctVelocityGradient" : correctVelocityGradient, + "gradType" : gradientType, + "densityUpdate" : densityUpdate, + "HUpdate" : HUpdate, + "epsTensile" : epsTensile, + "nTensile" : nTensile, + "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), + "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} + + + # Build and return the thing. + result = Constructor(**kwargs) + return result + diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index 2097b582b..db6c60251 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -71,6 +71,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto DvolDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::volume, 0.0); auto DvDt = derivatives.fields(HydroFieldNames::hydroAcceleration, Vector::zero); auto DepsDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); + auto DmDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, 0.0); auto DEDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, 0.0); auto DpDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::momentum, Vector::zero); auto DvDx = derivatives.fields(HydroFieldNames::velocityGradient, Tensor::zero); @@ -120,7 +121,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto DvDt_thread = DvDt.threadCopy(threadStack); auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); - auto DepsDt_thread = DepsDt.threadCopy(threadStack); + //auto DepsDt_thread = DepsDt.threadCopy(threadStack); + auto DmDt_thread = DmDt.threadCopy(threadStack); auto DEDt_thread = DEDt.threadCopy(threadStack); auto DpDt_thread = DpDt.threadCopy(threadStack); auto DvDx_thread = DvDx.threadCopy(threadStack); @@ -144,7 +146,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& vi = velocity(nodeListi, i); const auto& rhoi = massDensity(nodeListi, i); const auto& voli = volume(nodeListi, i); - //const auto& epsi = specificThermalEnergy(nodeListi, i); + const auto& epsi = specificThermalEnergy(nodeListi, i); const auto& Pi = pressure(nodeListi, i); const auto& Hi = H(nodeListi, i); const auto& ci = soundSpeed(nodeListi, i); @@ -155,12 +157,13 @@ evaluateDerivatives(const typename Dimension::Scalar time, CHECK(Hdeti > 0.0); auto& normi = normalization_thread(nodeListi,i); - auto& DepsDti = DepsDt_thread(nodeListi, i); + //auto& DepsDti = DepsDt_thread(nodeListi, i); + auto& DmDti = DmDt_thread(nodeListi, i); auto& DEDti = DEDt_thread(nodeListi, i); auto& DpDti = DpDt_thread(nodeListi, i); auto& DvDti = DvDt_thread(nodeListi, i); - auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi,i); - auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi,i); + auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); + auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); auto& DvDxi = DvDx_thread(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); @@ -176,7 +179,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& vj = velocity(nodeListj, j); const auto& rhoj = massDensity(nodeListj, j); const auto& volj = volume(nodeListj, j); - //const auto& epsj = specificThermalEnergy(nodeListj, j); + const auto& epsj = specificThermalEnergy(nodeListj, j); const auto& Pj = pressure(nodeListj, j); const auto& Hj = H(nodeListj, j); const auto& cj = soundSpeed(nodeListj, j); @@ -188,7 +191,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& normj = normalization_thread(nodeListj,j); auto& DvDtj = DvDt_thread(nodeListj, j); - auto& DepsDtj = DepsDt_thread(nodeListj, j); + //auto& DepsDtj = DepsDt_thread(nodeListj, j); + auto& DmDtj = DmDt_thread(nodeListj, j); auto& DEDtj = DEDt_thread(nodeListj, j); auto& DpDtj = DpDt_thread(nodeListj, j); auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj,j); @@ -212,6 +216,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Symmetrized kernel weight and gradient. + //------------------------------------------------------ W.kernelAndGradValue(etaMagi, Hdeti, Wi, gWi); const auto Hetai = Hi*etai.unitVector(); const auto gradWi = gWi*Hetai; @@ -220,6 +225,13 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto Hetaj = Hj*etaj.unitVector(); const auto gradWj = gWj*Hetaj; + psii = voli*Wi; + psij = volj*Wj; + gradPsii = voli * Mi.Transpose()*gradWi; + gradPsij = volj * Mj.Transpose()*gradWj; + + const auto Astar = voli*gradPsii + volj*gradPsij; + // Zero'th and second moment of the node distribution -- used for the // ideal H calculation. const auto rij2 = rij.magnitude2(); @@ -237,6 +249,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto Peffi = Pi + Ri; const auto Peffj = Pj + Rj; + // Reimann Solver and Fluxes + //------------------------------------------------------ // we'll clean this up when we have a gradient // implementation we're in love with auto gradPi = riemannDpDxi; @@ -263,28 +277,31 @@ evaluateDerivatives(const typename Dimension::Scalar time, rhostari, //output rhostarj); //output - // get our basis function and interface area vectors - //-------------------------------------------------------- - psii = voli*Wi; - psij = volj*Wj; - gradPsii = voli * Mi.Transpose()*gradWi; - gradPsij = volj * Mj.Transpose()*gradWj; - - const auto Astar = voli*gradPsii + volj*gradPsij; - - // acceleration - //------------------------------------------------------ const auto fluxSwitch = 1; const auto vflux = vstar-(vi+vj)/2.0; - const auto rhostar = (vflux.dot(rhatij) > 0 ? rhostarj : rhostari); - const auto deltaDvDt = Pstar*Astar + fluxSwitch * (rhostar*vflux.dyad(vstar)).dot(Astar); + const auto fluxTowardsNodei = vflux.dot(rhatij) > 0; + const auto rhostar = (fluxTowardsNodei ? rhostarj : rhostari); // we'll need to fix these later + const auto epsstar = (fluxTowardsNodei ? epsj : epsi); // we'll need to fix these later + + const auto massFlux = fluxSwitch * rhostar * vflux.dot(Astar); + const auto momentumFlux = massFlux * vstar; + const auto energyFlux = massFlux * epsstar; + + // mass + //------------------------------------------------------ + DmDti -= massFlux; + DmDtj += massFlux; + + // momentum + //------------------------------------------------------ + const auto deltaDvDt = Pstar*Astar + momentumFlux; DpDti -= deltaDvDt; DpDtj += deltaDvDt; // energy //------------------------------------------------------ - const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar) + rhostar*epsstar*vflux.dot(Astar); - const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj) + rhostar*epsstar*vflux.dot(Astar); + const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar) - energyFlux; + const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj) + energyFlux; DEDti += deltaDepsDti; DEDtj += deltaDepsDtj; diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index f9b0ea036..5d953b673 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -29,6 +29,7 @@ #include "GSPH/computeSumVolume.hh" #include "GSPH/computeMFMDensity.hh" #include "GSPH/Policies/ReplaceWithRatioPolicy.hh" +#include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" #include "GSPH/RiemannSolvers/RiemannSolverBase.hh" #ifdef _OPENMP @@ -84,9 +85,11 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, nTensile, xmin, xmax), + mDmassDt(FieldStorageType::CopyFields), mDthermalEnergyDt(FieldStorageType::CopyFields), mDmomentumDt(FieldStorageType::CopyFields), mDvolumeDt(FieldStorageType::CopyFields){ + mDmassDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::mass); mDthermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); mDmomentumDt = dataBase.newFluidFieldList(Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum); mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::volume); @@ -125,6 +128,8 @@ registerState(DataBase& dataBase, auto massDensity = dataBase.fluidMassDensity(); auto volume = state.fields(HydroFieldNames::volume, 0.0); + auto mass = state.fields(HydroFieldNames::mass, 0.0); + auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); std::shared_ptr > volumePolicy(new CompositeFieldListPolicy()); for (auto itr = dataBase.fluidNodeListBegin(); @@ -137,13 +142,22 @@ registerState(DataBase& dataBase, maxVolume)); } - PolicyPointer rhoPolicy(new ReplaceWithRatioPolicy(HydroFieldNames::mass, - HydroFieldNames::volume, - HydroFieldNames::volume)); - + auto rhoPolicy = std::make_shared>(HydroFieldNames::mass, + HydroFieldNames::volume, + HydroFieldNames::volume); + + auto massPolicy = std::make_shared>(true); + auto momentumPolicy = std::make_shared>(HydroFieldNames::velocity, IncrementFieldList::prefix() + GSPHFieldNames::momentum); + auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); + + // special policies to get velocity update from momentum deriv + state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); + state.enroll(GSPHFieldNames::thermalEnergyPolicy,thermalEnergyPolicy); + // normal state variables + state.enroll(mass, massPolicy); state.enroll(massDensity, rhoPolicy); - state.enroll(volume, volumePolicy); + state.enroll(volume, volumePolicy); } //------------------------------------------------------------------------------ @@ -155,9 +169,13 @@ MFVHydroBase:: registerDerivatives(DataBase& dataBase, StateDerivatives& derivs) { GenericRiemannHydro::registerDerivatives(dataBase,derivs); - dataBase.resizeFluidFieldList(mDmomentumDt, Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum, false); + dataBase.resizeFluidFieldList(mDmassDt, 0.0, IncrementFieldList::prefix() + HydroFieldNames::mass, false); dataBase.resizeFluidFieldList(mDthermalEnergyDt, 0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, false); + dataBase.resizeFluidFieldList(mDmomentumDt, Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum, false); dataBase.resizeFluidFieldList(mDvolumeDt, 0.0, IncrementFieldList::prefix() + HydroFieldNames::volume, false); + derivs.enroll(mDmassDt); + derivs.enroll(mDthermalEnergyDt); + derivs.enroll(mDmomentumDt); derivs.enroll(mDvolumeDt); } @@ -254,8 +272,9 @@ void MFVHydroBase:: dumpState(FileIO& file, const string& pathName) const { GenericRiemannHydro::dumpState(file,pathName); - file.write(mDmomentumDt, pathName + "/DmomentumDt"); + file.write(mDmassDt, pathName + "/DmassDt"); file.write(mDthermalEnergyDt, pathName + "/DthermalEnergyDt"); + file.write(mDmomentumDt, pathName + "/DmomentumDt"); file.write(mDvolumeDt, pathName + "/DvolumeDt"); } @@ -267,8 +286,9 @@ void MFVHydroBase:: restoreState(const FileIO& file, const string& pathName) { GenericRiemannHydro::restoreState(file,pathName); - file.read(mDmomentumDt, pathName + "/DmomentumDt"); + file.read(mDmassDt, pathName + "/DmassDt"); file.read(mDthermalEnergyDt, pathName + "/DthermalEnergyDt"); + file.read(mDmomentumDt, pathName + "/DmomentumDt"); file.read(mDvolumeDt, pathName + "/DvolumeDt"); } diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 628119f80..373f0ae8e 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -123,6 +123,7 @@ public: void enforceBoundaries(State& state, StateDerivatives& derivs) override; + const FieldList& DmassDt() const; const FieldList& DthermalEnergyDt() const; const FieldList& DmomentumDt() const; const FieldList& DvolumeDt() const; @@ -134,6 +135,7 @@ public: virtual void restoreState(const FileIO& file, const std::string& pathName) override; //**************************************************************************** private: + FieldList mDmassDt; FieldList mDthermalEnergyDt; FieldList mDmomentumDt; FieldList mDvolumeDt; diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index 57c936997..8fd7c4d77 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -6,6 +6,13 @@ template inline const FieldList& MFVHydroBase:: +DmassDt() const { + return mDmassDt; +} +template +inline +const FieldList& +MFVHydroBase:: DthermalEnergyDt() const { return mDthermalEnergyDt; } diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc new file mode 100644 index 000000000..db60d636e --- /dev/null +++ b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc @@ -0,0 +1,152 @@ +//---------------------------------Spheral++----------------------------------// +// IncrementSpecificFromTotalPolicy -- replaces one fieldlist with the ratio of two +// fieldlists from the state. +// +// J.M. Pearl 2022 +//----------------------------------------------------------------------------// + +#include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" +#include "DataBase/IncrementFieldList.hh" +#include "DataBase/State.hh" +#include "DataBase/StateDerivatives.hh" +#include "Field/FieldList.hh" +#include "Utilities/DBC.hh" +#include "Hydro/HydroFieldNames.hh" + +#include + +namespace Spheral { + +//------------------------------------------------------------------------------ +// Constructors. +//------------------------------------------------------------------------------ +template +IncrementSpecificFromTotalPolicy:: +IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivsKey): + FieldListUpdatePolicyBase(HydroFieldNames::mass), + mStateKey(stateKey), + mDerivativeKey(derivsKey){ +} + +template +IncrementSpecificFromTotalPolicy:: +IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivsKey, const std::string& depend0): + FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0), + mStateKey(stateKey), + mDerivativeKey(derivsKey) { +} + +template +IncrementSpecificFromTotalPolicy:: +IncrementSpecificFromTotalPolicy(const std::string& stateKey, + const std::string& derivsKey, + const std::string& depend0, + const std::string& depend1): + FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1), + mStateKey(stateKey), + mDerivativeKey(derivsKey) { +} + +template +IncrementSpecificFromTotalPolicy:: +IncrementSpecificFromTotalPolicy(const std::string& stateKey, + const std::string& derivsKey, + const std::string& depend0, + const std::string& depend1, + const std::string& depend2): + FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1, depend2), + mStateKey(stateKey), + mDerivativeKey(derivsKey){ +} + +template +IncrementSpecificFromTotalPolicy:: +IncrementSpecificFromTotalPolicy(const std::string& stateKey, + const std::string& derivsKey, + const std::string& depend0, + const std::string& depend1, + const std::string& depend2, + const std::string& depend3): + FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1, depend2, depend3), + mStateKey(stateKey), + mDerivativeKey(derivsKey){ +} + +template +IncrementSpecificFromTotalPolicy:: +IncrementSpecificFromTotalPolicy(const std::string& stateKey, + const std::string& derivsKey, + const std::string& depend0, + const std::string& depend1, + const std::string& depend2, + const std::string& depend3, + const std::string& depend4): + FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1, depend2, depend3, depend4), + mStateKey(stateKey), + mDerivativeKey(derivsKey){ +} + +//------------------------------------------------------------------------------ +// Destructor. +//------------------------------------------------------------------------------ +template +IncrementSpecificFromTotalPolicy:: +~IncrementSpecificFromTotalPolicy() { +} + +//------------------------------------------------------------------------------ +// Update the field. +//------------------------------------------------------------------------------ +template +void +IncrementSpecificFromTotalPolicy:: +update(const KeyType& /*key*/, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt) { + + const auto tiny = std::numeric_limits::epsilon(); + + const auto m = state.fields(HydroFieldNames::mass, Scalar()); + auto q = state.fields(mStateKey, Value()); + + const auto DmDt = derivs.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, Scalar()); + const auto DQDt = derivs.fields(mDerivativeKey, Value()); + + + // Get the field name portion of the key. + //KeyType fieldKey, nodeListKey; + //StateBase::splitFieldKey(key, fieldKey, nodeListKey); + //CHECK(nodeListKey == UpdatePolicyBase::wildcard()); + + // Find the matching replacement FieldList from the StateDerivatives. + //FieldList f = state.fields(fieldKey, Value()); + + // Loop over the internal values of the field. + const unsigned numNodeLists = q.size(); + for (unsigned k = 0; k != numNodeLists; ++k) { + const unsigned n = q[k]->numInternalElements(); + for (unsigned i = 0; i != n; ++i) { + q(k, i) += (DQDt(k, i) - DmDt(k, i)*q(k, i)) * multiplier/ (m(k,i)+DmDt(k,i)*multiplier); + } + } +} + + +//------------------------------------------------------------------------------ +// Equivalence operator. +//------------------------------------------------------------------------------ +template +bool +IncrementSpecificFromTotalPolicy:: +operator==(const UpdatePolicyBase& rhs) const { + + // We're only equal if the other guy is also an replace operator. + const IncrementSpecificFromTotalPolicy* rhsPtr = dynamic_cast*>(&rhs); + return rhsPtr != 0; +} + +} + diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh new file mode 100644 index 000000000..d122ded4d --- /dev/null +++ b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh @@ -0,0 +1,67 @@ +//---------------------------------Spheral++----------------------------------// +// IncrementSpecificFromTotalPolicy -- policy to update the velocity from the +// momentum time derivative +// +// J.M. Pearl 2022 +//----------------------------------------------------------------------------// + +#ifndef __Spheral_IncrementSpecificFromTotalPolicy_hh__ +#define __Spheral_IncrementSpecificFromTotalPolicy_hh__ + +#include "DataBase/FieldListUpdatePolicyBase.hh" + +namespace Spheral { + +template +class IncrementSpecificFromTotalPolicy: public FieldListUpdatePolicyBase { +public: + + //--------------------------- Public Interface ---------------------------// + // Useful typedefs + typedef typename FieldListUpdatePolicyBase::KeyType KeyType; + typedef typename Dimension::Scalar Scalar; + typedef typename Dimension::Vector Vector; + + // Constructors, destructor. + + IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey); + IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey, const std::string& depend0); + IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey, const std::string& depend0, const std::string& depend1); + IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey, const std::string& depend0, const std::string& depend1, const std::string& depend2); + IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey, const std::string& depend0, const std::string& depend1, const std::string& depend2, const std::string& depend3); + IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey, const std::string& depend0, const std::string& depend1, const std::string& depend2, const std::string& depend3, const std::string& depend4); + IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey, const std::string& depend0, const std::string& depend1, const std::string& depend2, const std::string& depend3, const std::string& depend4, const std::string& depend5); + virtual ~IncrementSpecificFromTotalPolicy(); + + // Overload the methods describing how to update FieldLists. + virtual void update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt) override; + + // Equivalence. + virtual bool operator==(const UpdatePolicyBase& rhs) const override; + +private: + + const std::string mStateKey; + const std::string mDerivativeKey; + + //--------------------------- Private Interface ---------------------------// + IncrementSpecificFromTotalPolicy(); + IncrementSpecificFromTotalPolicy(const IncrementSpecificFromTotalPolicy& rhs); + IncrementSpecificFromTotalPolicy& operator=(const IncrementSpecificFromTotalPolicy& rhs); +}; + +} + +#else + +// Forward declaration. +namespace Spheral { + template class IncrementSpecificFromTotalPolicy; +} + +#endif diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicyInst.cc.py b/src/GSPH/Policies/IncrementSpecificFromTotalPolicyInst.cc.py new file mode 100644 index 000000000..0b4c30002 --- /dev/null +++ b/src/GSPH/Policies/IncrementSpecificFromTotalPolicyInst.cc.py @@ -0,0 +1,12 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "Geometry/Dimension.hh" +#include "GSPH/Policies/IncrementSpecificFromTotalPolicy.cc" + +namespace Spheral { + template class IncrementSpecificFromTotalPolicy, Dim< %(ndim)s >::Scalar>; + template class IncrementSpecificFromTotalPolicy, Dim< %(ndim)s >::Vector>; +} +""" diff --git a/src/PYB11/GSPH/GSPH_PYB11.py b/src/PYB11/GSPH/GSPH_PYB11.py index de3060785..e3c498c04 100644 --- a/src/PYB11/GSPH/GSPH_PYB11.py +++ b/src/PYB11/GSPH/GSPH_PYB11.py @@ -12,6 +12,7 @@ from GenericRiemannHydro import * from GSPHHydroBase import * from MFMHydroBase import * +from MFVHydroBase import * from WaveSpeeds import * from Limiters import * from RiemannSolvers import * @@ -22,6 +23,7 @@ PYB11includes += ['"GSPH/GenericRiemannHydro.hh"', '"GSPH/GSPHHydroBase.hh"', '"GSPH/MFMHydroBase.hh"', + '"GSPH/MFVHydroBase.hh"', '"GSPH/WaveSpeeds/WaveSpeedBase.hh"', '"GSPH/WaveSpeeds/AcousticWaveSpeed.hh"', '"GSPH/WaveSpeeds/DavisWaveSpeed.hh"', @@ -61,6 +63,7 @@ GenericRiemannHydro%(ndim)id = PYB11TemplateClass(GenericRiemannHydro, template_parameters="%(Dimension)s") GSPHHydroBase%(ndim)id = PYB11TemplateClass(GSPHHydroBase, template_parameters="%(Dimension)s") MFMHydroBase%(ndim)id = PYB11TemplateClass(MFMHydroBase, template_parameters="%(Dimension)s") +MFVHydroBase%(ndim)id = PYB11TemplateClass(MFVHydroBase, template_parameters="%(Dimension)s") WaveSpeedBase%(ndim)id = PYB11TemplateClass(WaveSpeedBase, template_parameters="%(Dimension)s") AcousticWaveSpeed%(ndim)id = PYB11TemplateClass(AcousticWaveSpeed, template_parameters="%(Dimension)s") DavisWaveSpeed%(ndim)id = PYB11TemplateClass(DavisWaveSpeed, template_parameters="%(Dimension)s") diff --git a/src/PYB11/GSPH/MFVHydroBase.py b/src/PYB11/GSPH/MFVHydroBase.py new file mode 100644 index 000000000..21d8f8a9e --- /dev/null +++ b/src/PYB11/GSPH/MFVHydroBase.py @@ -0,0 +1,115 @@ +#------------------------------------------------------------------------------- +# GSPHHydroBase +#------------------------------------------------------------------------------- +from PYB11Generator import * +from GenericRiemannHydro import * +from RestartMethods import * + +@PYB11template("Dimension") +@PYB11module("SpheralGSPH") +class MFVHydroBase(GenericRiemannHydro): + + PYB11typedefs = """ + typedef typename %(Dimension)s::Scalar Scalar; + typedef typename %(Dimension)s::Vector Vector; + typedef typename %(Dimension)s::Tensor Tensor; + typedef typename %(Dimension)s::SymTensor SymTensor; + typedef typename Physics<%(Dimension)s>::TimeStepType TimeStepType; +""" + + def pyinit(smoothingScaleMethod = "const SmoothingScaleBase<%(Dimension)s>&", + dataBase = "DataBase<%(Dimension)s>&", + riemannSolver = "RiemannSolverBase<%(Dimension)s>&", + W = "const TableKernel<%(Dimension)s>&", + epsDiffusionCoeff = "const Scalar", + cfl = "const double", + useVelocityMagnitudeForDt = "const bool", + compatibleEnergyEvolution = "const bool", + evolveTotalEnergy = "const bool", + XSPH = "const bool", + correctVelocityGradient = "const bool", + gradType = "const GradientType", + densityUpdate = "const MassDensityType", + HUpdate = "const HEvolutionType", + epsTensile = "const double", + nTensile = "const double", + xmin = "const Vector&", + xmax = "const Vector&"): + "GSPHHydroBase constructor" + + #........................................................................... + # Virtual methods + + @PYB11virtual + def initializeProblemStartup(dataBase = "DataBase<%(Dimension)s>&"): + "Tasks we do once on problem startup." + return "void" + + @PYB11virtual + def registerState(dataBase = "DataBase<%(Dimension)s>&", + state = "State<%(Dimension)s>&"): + "Register the state Hydro expects to use and evolve." + return "void" + + @PYB11virtual + def registerDerivatives(dataBase = "DataBase<%(Dimension)s>&", + derivs = "StateDerivatives<%(Dimension)s>&"): + "Register the derivatives/change fields for updating state." + return "void" + + @PYB11virtual + def preStepInitialize(self, + dataBase = "const DataBase<%(Dimension)s>&", + state = "State<%(Dimension)s>&", + derivs = "StateDerivatives<%(Dimension)s>&"): + "Optional hook to be called at the beginning of a time step." + return "void" + + @PYB11virtual + def initialize(time = "const Scalar", + dt = "const Scalar", + dataBase = "const DataBase<%(Dimension)s>&", + state = "State<%(Dimension)s>&", + derivs = "StateDerivatives<%(Dimension)s>&"): + "Initialize the Hydro before we start a derivative evaluation." + return "void" + + @PYB11virtual + @PYB11const + def evaluateDerivatives(time = "const Scalar", + dt = "const Scalar", + dataBase = "const DataBase<%(Dimension)s>&", + state = "const State<%(Dimension)s>&", + derivs = "StateDerivatives<%(Dimension)s>&"): + """Evaluate the derivatives for the principle hydro +mass density, velocity, and specific thermal energy.""" + return "void" + + @PYB11virtual + @PYB11const + def finalizeDerivatives(time = "const Scalar", + dt = "const Scalar", + dataBase = "const DataBase<%(Dimension)s>&", + state = "const State<%(Dimension)s>&", + derivs = "StateDerivatives<%(Dimension)s>&"): + "Finalize the derivatives." + return "void" + + @PYB11virtual + def applyGhostBoundaries(state = "State<%(Dimension)s>&", + derivs = "StateDerivatives<%(Dimension)s>&"): + "Apply boundary conditions to the physics specific fields." + return "void" + + @PYB11virtual + def enforceBoundaries(state = "State<%(Dimension)s>&", + derivs = "StateDerivatives<%(Dimension)s>&"): + "Enforce boundary conditions for the physics specific fields." + return "void" + + DvolumeDt = PYB11property("const FieldList<%(Dimension)s, Scalar>&", "DvolumeDt", returnpolicy="reference_internal") + +#------------------------------------------------------------------------------- +# Inject methods +#------------------------------------------------------------------------------- +PYB11inject(RestartMethods, MFVHydroBase) diff --git a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py index 0bb7d453f..d54647eec 100644 --- a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py +++ b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py @@ -341,7 +341,6 @@ interfaceMethod = ModulusInterface, sumDensityNodeLists=[nodes1], densityStabilizationCoefficient = 0.00, - useVelocityMagnitudeForDt = useVelocityMagnitudeForDt, compatibleEnergyEvolution = compatibleEnergy, evolveTotalEnergy = evolveTotalEnergy, correctVelocityGradient = correctVelocityGradient, From 3a4a86d4d3f96a44c3cc3de43c48e11dc4f2ec5c Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Thu, 15 Jun 2023 08:44:15 -0700 Subject: [PATCH 25/60] typo in Noh test --- tests/functional/Hydro/Noh/Noh-cylindrical-2d.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py index d54647eec..0701c47c6 100644 --- a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py +++ b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py @@ -141,6 +141,7 @@ assert not(boolReduceViscosity and boolCullenViscosity) assert not((gsph or mfm) and (boolReduceViscosity or boolCullenViscosity)) assert not(fsisph and not solid) +assert sum([crksph,psph,fsisph,svph,gsph,mfm])<=1 assert thetaFactor in (0.5, 1.0, 2.0) theta = thetaFactor * pi @@ -163,6 +164,8 @@ hydroname = os.path.join("CRKSPH", str(correctionOrder), str(volumeType)) +elif fsisph: + hydroname = "FSISPH" elif gsph: hydroname = "GSPH" elif mfm: From f8e81da433eba7534dda23cba4fae7fe4ece8342 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Thu, 15 Jun 2023 08:45:00 -0700 Subject: [PATCH 26/60] GSPH updating to new convience constructror format --- src/GSPH/GSPHHydros.py | 135 ++------------ src/GSPH/GSPHHydros2.py | 253 -------------------------- src/PYB11/GSPH/GSPHHydroBase.py | 1 + src/PYB11/GSPH/GenericRiemannHydro.py | 3 +- src/PYB11/GSPH/MFMHydroBase.py | 1 + src/PYB11/GSPH/MFVHydroBase.py | 1 + 6 files changed, 19 insertions(+), 375 deletions(-) delete mode 100644 src/GSPH/GSPHHydros2.py diff --git a/src/GSPH/GSPHHydros.py b/src/GSPH/GSPHHydros.py index 1b217f289..9023b5d44 100644 --- a/src/GSPH/GSPHHydros.py +++ b/src/GSPH/GSPHHydros.py @@ -3,118 +3,6 @@ from spheralDimensions import spheralDimensions dims = spheralDimensions() -#------------------------------------------------------------------------------- -# density-based GSPH factory string -#------------------------------------------------------------------------------- -GSPHHydroFactoryString = """ -class %(classname)s%(dim)s(GSPHHydroBase%(dim)s): - - def __init__(self, - dataBase, - riemannSolver, - W, - epsDiffusionCoeff = 0.0, - cfl = 0.25, - useVelocityMagnitudeForDt = False, - compatibleEnergyEvolution = True, - evolveTotalEnergy = False, - XSPH = True, - correctVelocityGradient = True, - gradientType = HydroAccelerationGradient, - densityUpdate = IntegrateDensity, - HUpdate = IdealH, - epsTensile = 0.0, - nTensile = 4.0, - xmin = Vector%(dim)s(-1e100, -1e100, -1e100), - xmax = Vector%(dim)s( 1e100, 1e100, 1e100)): - self._smoothingScaleMethod = %(smoothingScaleMethod)s%(dim)s() - GSPHHydroBase%(dim)s.__init__(self, - self._smoothingScaleMethod, - dataBase, - riemannSolver, - W, - epsDiffusionCoeff, - cfl, - useVelocityMagnitudeForDt, - compatibleEnergyEvolution, - evolveTotalEnergy, - XSPH, - correctVelocityGradient, - gradientType, - densityUpdate, - HUpdate, - epsTensile, - nTensile, - xmin, - xmax) - return -""" - -#------------------------------------------------------------------------------- -# volume-based GSPH factory string (MFM) -#------------------------------------------------------------------------------- -MFMHydroFactoryString = """ -class %(classname)s%(dim)s(MFMHydroBase%(dim)s): - - def __init__(self, - dataBase, - riemannSolver, - W, - epsDiffusionCoeff = 0.0, - cfl = 0.25, - useVelocityMagnitudeForDt = False, - compatibleEnergyEvolution = True, - evolveTotalEnergy = False, - XSPH = True, - correctVelocityGradient = True, - gradientType = HydroAccelerationGradient, - densityUpdate = IntegrateDensity, - HUpdate = IdealH, - epsTensile = 0.0, - nTensile = 4.0, - xmin = Vector%(dim)s(-1e100, -1e100, -1e100), - xmax = Vector%(dim)s( 1e100, 1e100, 1e100)): - self._smoothingScaleMethod = %(smoothingScaleMethod)s%(dim)s() - MFMHydroBase%(dim)s.__init__(self, - self._smoothingScaleMethod, - dataBase, - riemannSolver, - W, - epsDiffusionCoeff, - cfl, - useVelocityMagnitudeForDt, - compatibleEnergyEvolution, - evolveTotalEnergy, - XSPH, - correctVelocityGradient, - gradientType, - densityUpdate, - HUpdate, - epsTensile, - nTensile, - xmin, - xmax) - return -""" - -#------------------------------------------------------------------------------- -# Make 'em. -#------------------------------------------------------------------------------- -for dim in dims: - exec(GSPHHydroFactoryString % {"dim" : "%id" % dim, - "classname" : "GSPHHydro", - "smoothingScaleMethod" : "SPHSmoothingScale"}) - exec(GSPHHydroFactoryString % {"dim" : "%id" % dim, - "classname" : "AGSPHHydro", - "smoothingScaleMethod" : "ASPHSmoothingScale"}) - - exec(MFMHydroFactoryString % {"dim" : "%id" % dim, - "classname" : "MFMHydro", - "smoothingScaleMethod" : "SPHSmoothingScale"}) - exec(MFMHydroFactoryString % {"dim" : "%id" % dim, - "classname" : "AMFMHydro", - "smoothingScaleMethod" : "ASPHSmoothingScale"}) - #------------------------------------------------------------------------------- # GSPH convience wrapper function #------------------------------------------------------------------------------- @@ -155,10 +43,13 @@ def GSPH(dataBase, print(" which will result in fluid behaviour for those nodes.") raise RuntimeError("Cannot mix solid and fluid NodeLists.") + Constructor = eval("GSPHHydroBase%id" % ndim) + + # Smoothing scale update if ASPH: - Constructor = eval("AGSPHHydro%id" % ndim) + smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) else: - Constructor = eval("GSPHHydro%id" % ndim) + smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) if riemannSolver is None: waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) @@ -170,7 +61,9 @@ def GSPH(dataBase, xmin = (ndim,) + xmin xmax = (ndim,) + xmax - kwargs = {"riemannSolver" : riemannSolver, + kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, + "dataBase" : dataBase, + "riemannSolver" : riemannSolver, "W" : W, "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, "dataBase" : dataBase, @@ -180,7 +73,7 @@ def GSPH(dataBase, "evolveTotalEnergy" : evolveTotalEnergy, "XSPH" : XSPH, "correctVelocityGradient" : correctVelocityGradient, - "gradientType" : gradientType, + "gradType" : gradientType, "densityUpdate" : densityUpdate, "HUpdate" : HUpdate, "epsTensile" : epsTensile, @@ -191,8 +84,10 @@ def GSPH(dataBase, # Build and return the thing. result = Constructor(**kwargs) - return result + result._smoothingScaleMethod = smoothingScaleMethod + return result + #------------------------------------------------------------------------------- # MFM convience wrapper function #------------------------------------------------------------------------------- @@ -275,8 +170,7 @@ def MFM(dataBase, # Build and return the thing. result = Constructor(**kwargs) - #result._smoothingScaleMethod = smoothingScaleMethod - result.riemannSolver = riemannSolver + result._smoothingScaleMethod = smoothingScaleMethod return result @@ -364,8 +258,7 @@ def MFV(dataBase, # Build and return the thing. result = Constructor(**kwargs) - #result._smoothingScaleMethod = smoothingScaleMethod - #result.riemannSolver = riemannSolver + result._smoothingScaleMethod = smoothingScaleMethod return result diff --git a/src/GSPH/GSPHHydros2.py b/src/GSPH/GSPHHydros2.py deleted file mode 100644 index 85a52e3d3..000000000 --- a/src/GSPH/GSPHHydros2.py +++ /dev/null @@ -1,253 +0,0 @@ -from SpheralCompiledPackages import * - -from spheralDimensions import spheralDimensions -dims = spheralDimensions() - - -#------------------------------------------------------------------------------- -# GSPH convience wrapper function -#------------------------------------------------------------------------------- -def GSPH(dataBase, - W, - riemannSolver=None, - specificThermalEnergyDiffusionCoefficient = 0.0, - cfl = 0.25, - gradientType = HydroAccelerationGradient, - densityUpdate = IntegrateDensity, - useVelocityMagnitudeForDt = False, - compatibleEnergyEvolution = True, - evolveTotalEnergy = False, - XSPH = False, - correctVelocityGradient = False, - HUpdate = IdealH, - epsTensile = 0.0, - nTensile = 4.0, - damageRelieveRubble = False, - negativePressureInDamage = False, - strengthInDamage = False, - xmin = (-1e100, -1e100, -1e100), - xmax = ( 1e100, 1e100, 1e100), - ASPH = False, - RZ = False): - - - assert densityUpdate in (RigorousSumDensity,IntegrateDensity) - - # We use the provided DataBase to sniff out what sort of NodeLists are being - # used, and based on this determine which SPH object to build. - ndim = dataBase.nDim - nfluid = dataBase.numFluidNodeLists - nsolid = dataBase.numSolidNodeLists - if nsolid > 0 and nsolid != nfluid: - print("GSPH Error: you have provided both solid and fluid NodeLists, which is currently not supported.") - print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,") - print(" which will result in fluid behaviour for those nodes.") - raise RuntimeError("Cannot mix solid and fluid NodeLists.") - - Constructor = eval("GSPHHydroBase%id" % ndim) - - if riemannSolver is None: - waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) - slopeLimiter = eval("VanLeerLimiter%id()" % (ndim)) - linearReconstruction=True - riemannSolver = eval("HLLC%id(slopeLimiter,waveSpeedMethod,linearReconstruction)" % (ndim)) - - # Build the constructor arguments - xmin = (ndim,) + xmin - xmax = (ndim,) + xmax - - # Smoothing scale update - if ASPH: - smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) - else: - smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) - - kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, - "dataBase" : dataBase, - "riemannSolver" : riemannSolver, - "W" : W, - "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, - "cfl" : cfl, - "useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt, - "compatibleEnergyEvolution" : compatibleEnergyEvolution, - "evolveTotalEnergy" : evolveTotalEnergy, - "XSPH" : XSPH, - "correctVelocityGradient" : correctVelocityGradient, - "gradType" : gradientType, - "densityUpdate" : densityUpdate, - "HUpdate" : HUpdate, - "epsTensile" : epsTensile, - "nTensile" : nTensile, - "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), - "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} - - # Build and return the thing. - result = Constructor(**kwargs) - return result - -#------------------------------------------------------------------------------- -# MFM convience wrapper function -#------------------------------------------------------------------------------- -def MFM(dataBase, - W, - riemannSolver=None, - specificThermalEnergyDiffusionCoefficient = 0.0, - cfl = 0.25, - gradientType = HydroAccelerationGradient, - densityUpdate = IntegrateDensity, - useVelocityMagnitudeForDt = False, - compatibleEnergyEvolution = True, - evolveTotalEnergy = False, - XSPH = False, - correctVelocityGradient = False, - HUpdate = IdealH, - epsTensile = 0.0, - nTensile = 4.0, - damageRelieveRubble = False, - negativePressureInDamage = False, - strengthInDamage = False, - xmin = (-1e100, -1e100, -1e100), - xmax = ( 1e100, 1e100, 1e100), - ASPH = False, - RZ = False): - - # for now we'll just piggy back off this enum - assert densityUpdate in (RigorousSumDensity,IntegrateDensity) - - # We use the provided DataBase to sniff out what sort of NodeLists are being - # used, and based on this determine which SPH object to build. - ndim = dataBase.nDim - nfluid = dataBase.numFluidNodeLists - nsolid = dataBase.numSolidNodeLists - if nsolid > 0 and nsolid != nfluid: - print("MFM Error: you have provided both solid and fluid NodeLists, which is currently not supported.") - print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,") - print(" which will result in fluid behaviour for those nodes.") - raise RuntimeError("Cannot mix solid and fluid NodeLists.") - - Constructor = eval("MFMHydroBase%id" % ndim) - - if riemannSolver is None: - waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) - slopeLimiter = eval("VanLeerLimiter%id()" % (ndim)) - linearReconstruction=True - riemannSolver = eval("HLLC%id(slopeLimiter,waveSpeedMethod,linearReconstruction)" % (ndim)) - - # Build the constructor arguments - xmin = (ndim,) + xmin - xmax = (ndim,) + xmax - - # Smoothing scale update - if ASPH: - smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) - else: - smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) - - kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, - "dataBase" : dataBase, - "riemannSolver" : riemannSolver, - "W" : W, - "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, - "cfl" : cfl, - "useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt, - "compatibleEnergyEvolution" : compatibleEnergyEvolution, - "evolveTotalEnergy" : evolveTotalEnergy, - "XSPH" : XSPH, - "correctVelocityGradient" : correctVelocityGradient, - "gradType" : gradientType, - "densityUpdate" : densityUpdate, - "HUpdate" : HUpdate, - "epsTensile" : epsTensile, - "nTensile" : nTensile, - "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), - "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} - - - # Build and return the thing. - result = Constructor(**kwargs) - return result - - - -#------------------------------------------------------------------------------- -# MFM convience wrapper function -#------------------------------------------------------------------------------- -def MFV(dataBase, - W, - riemannSolver=None, - specificThermalEnergyDiffusionCoefficient = 0.0, - cfl = 0.25, - gradientType = HydroAccelerationGradient, - densityUpdate = IntegrateDensity, - useVelocityMagnitudeForDt = False, - compatibleEnergyEvolution = True, - evolveTotalEnergy = False, - XSPH = False, - correctVelocityGradient = False, - HUpdate = IdealH, - epsTensile = 0.0, - nTensile = 4.0, - damageRelieveRubble = False, - negativePressureInDamage = False, - strengthInDamage = False, - xmin = (-1e100, -1e100, -1e100), - xmax = ( 1e100, 1e100, 1e100), - ASPH = False, - RZ = False): - - # for now we'll just piggy back off this enum - assert densityUpdate in (RigorousSumDensity,IntegrateDensity) - - # We use the provided DataBase to sniff out what sort of NodeLists are being - # used, and based on this determine which SPH object to build. - ndim = dataBase.nDim - nfluid = dataBase.numFluidNodeLists - nsolid = dataBase.numSolidNodeLists - if nsolid > 0 and nsolid != nfluid: - print("MFV Error: you have provided both solid and fluid NodeLists, which is currently not supported.") - print(" If you want some fluids active, provide SolidNodeList without a strength option specfied,") - print(" which will result in fluid behaviour for those nodes.") - raise RuntimeError("Cannot mix solid and fluid NodeLists.") - - Constructor = eval("MFVHydroBase%id" % ndim) - - if riemannSolver is None: - waveSpeedMethod = eval("DavisWaveSpeed%id()" % (ndim)) - slopeLimiter = eval("VanLeerLimiter%id()" % (ndim)) - linearReconstruction=True - riemannSolver = eval("HLLC%id(slopeLimiter,waveSpeedMethod,linearReconstruction)" % (ndim)) - - # Build the constructor arguments - xmin = (ndim,) + xmin - xmax = (ndim,) + xmax - - # Smoothing scale update - if ASPH: - smoothingScaleMethod = eval("ASPHSmoothingScale%id()" % ndim) - else: - smoothingScaleMethod = eval("SPHSmoothingScale%id()" % ndim) - - kwargs = {"smoothingScaleMethod" : smoothingScaleMethod, - "dataBase" : dataBase, - "riemannSolver" : riemannSolver, - "W" : W, - "epsDiffusionCoeff" : specificThermalEnergyDiffusionCoefficient, - "cfl" : cfl, - "useVelocityMagnitudeForDt" : useVelocityMagnitudeForDt, - "compatibleEnergyEvolution" : compatibleEnergyEvolution, - "evolveTotalEnergy" : evolveTotalEnergy, - "XSPH" : XSPH, - "correctVelocityGradient" : correctVelocityGradient, - "gradType" : gradientType, - "densityUpdate" : densityUpdate, - "HUpdate" : HUpdate, - "epsTensile" : epsTensile, - "nTensile" : nTensile, - "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), - "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} - - - # Build and return the thing. - result = Constructor(**kwargs) - return result - diff --git a/src/PYB11/GSPH/GSPHHydroBase.py b/src/PYB11/GSPH/GSPHHydroBase.py index ec8c6d955..6942c98b7 100644 --- a/src/PYB11/GSPH/GSPHHydroBase.py +++ b/src/PYB11/GSPH/GSPHHydroBase.py @@ -7,6 +7,7 @@ @PYB11template("Dimension") @PYB11module("SpheralGSPH") +@PYB11dynamic_attr class GSPHHydroBase(GenericRiemannHydro): PYB11typedefs = """ diff --git a/src/PYB11/GSPH/GenericRiemannHydro.py b/src/PYB11/GSPH/GenericRiemannHydro.py index 6e1f373cc..ea9ea2a06 100644 --- a/src/PYB11/GSPH/GenericRiemannHydro.py +++ b/src/PYB11/GSPH/GenericRiemannHydro.py @@ -7,6 +7,7 @@ @PYB11template("Dimension") @PYB11module("SpheralGSPH") +@PYB11dynamic_attr class GenericRiemannHydro(Physics): PYB11typedefs = """ @@ -140,7 +141,7 @@ def enforceBoundaries(state = "State<%(Dimension)s>&", cfl = PYB11property("Scalar", "cfl", "cfl", doc="The Courant-Friedrichs-Lewy timestep limit multiplier") specificThermalEnergyDiffusionCoefficient = PYB11property("Scalar", "specificThermalEnergyDiffusionCoefficient", "specificThermalEnergyDiffusionCoefficient", doc="coefficient used to diffuse specificThermalEnergy amongst like nodes.") - riemannSolver = PYB11property("RiemannSolverBase<%(Dimension)s>&", "riemannSolver",returnpolicy="reference_internal",doc="The object defining the interface state construction.") + riemannSolver = PYB11property("RiemannSolverBase<%(Dimension)s>&", "riemannSolver", doc="The object defining the interface state construction.") kernel = PYB11property("const TableKernel<%(Dimension)s>&", "kernel", doc="The interpolation kernel") gradientType = PYB11property("GradientType", "gradientType", "gradientType", doc="Enum to selecting different gradients we can use") diff --git a/src/PYB11/GSPH/MFMHydroBase.py b/src/PYB11/GSPH/MFMHydroBase.py index 380d50dde..4f8874722 100644 --- a/src/PYB11/GSPH/MFMHydroBase.py +++ b/src/PYB11/GSPH/MFMHydroBase.py @@ -7,6 +7,7 @@ @PYB11template("Dimension") @PYB11module("SpheralGSPH") +@PYB11dynamic_attr class MFMHydroBase(GenericRiemannHydro): PYB11typedefs = """ diff --git a/src/PYB11/GSPH/MFVHydroBase.py b/src/PYB11/GSPH/MFVHydroBase.py index 21d8f8a9e..71aee15b1 100644 --- a/src/PYB11/GSPH/MFVHydroBase.py +++ b/src/PYB11/GSPH/MFVHydroBase.py @@ -7,6 +7,7 @@ @PYB11template("Dimension") @PYB11module("SpheralGSPH") +@PYB11dynamic_attr class MFVHydroBase(GenericRiemannHydro): PYB11typedefs = """ From 104f687543763e1adc7278a78abc3b8f319e9f95 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Mon, 19 Jun 2023 13:35:04 -0700 Subject: [PATCH 27/60] GSPH: adding BJ limiter --- src/GSPH/Limiters/BarthJespersenLimiter.cc | 40 +++++++++++++++++ src/GSPH/Limiters/BarthJespersenLimiter.hh | 44 +++++++++++++++++++ .../Limiters/BarthJespersenLimiterInst.cc.py | 11 +++++ 3 files changed, 95 insertions(+) create mode 100644 src/GSPH/Limiters/BarthJespersenLimiter.cc create mode 100644 src/GSPH/Limiters/BarthJespersenLimiter.hh create mode 100644 src/GSPH/Limiters/BarthJespersenLimiterInst.cc.py diff --git a/src/GSPH/Limiters/BarthJespersenLimiter.cc b/src/GSPH/Limiters/BarthJespersenLimiter.cc new file mode 100644 index 000000000..4c6259af5 --- /dev/null +++ b/src/GSPH/Limiters/BarthJespersenLimiter.cc @@ -0,0 +1,40 @@ +//---------------------------------Spheral++----------------------------------// +// BarthJespersenLimiter +// J. Barth, D. C. Jespersen, The design and application of upwind schemes +// on unstructured meshes, in: 27th Aerospace Sciences Meetings, AIAA Paper +// 89-0366, Reno, NV, 1989. doi:10.2514/6.1989-366 +// +// J.M. Pearl 2023 +//----------------------------------------------------------------------------// + +#include "BarthJespersenLimiter.hh" + +namespace Spheral { + +//------------------------------------------------------------------------------ +// Constructor +//------------------------------------------------------------------------------ +template +BarthJespersenLimiter:: +BarthJespersenLimiter(): + LimiterBase(true,true){ +} + +//------------------------------------------------------------------------------ +// Destructor +//------------------------------------------------------------------------------ +template +BarthJespersenLimiter:: +~BarthJespersenLimiter(){} + +//------------------------------------------------------------------------------ +// slope limiter +//------------------------------------------------------------------------------ +template +typename Dimension::Scalar +BarthJespersenLimiter:: +fluxLimiter(const typename Dimension::Scalar x) const { + return std::min(std::min(0.5*(x+1),2.0),2.0*x) ; +} + +} \ No newline at end of file diff --git a/src/GSPH/Limiters/BarthJespersenLimiter.hh b/src/GSPH/Limiters/BarthJespersenLimiter.hh new file mode 100644 index 000000000..ed4ea0f39 --- /dev/null +++ b/src/GSPH/Limiters/BarthJespersenLimiter.hh @@ -0,0 +1,44 @@ +//---------------------------------Spheral++----------------------------------// +// BarthJespersenLimiter +// J. Barth, D. C. Jespersen, The design and application of upwind schemes +// on unstructured meshes, in: 27th Aerospace Sciences Meetings, AIAA Paper +// 89-0366, Reno, NV, 1989. doi:10.2514/6.1989-366 +// +// J.M. Pearl 2023 +//----------------------------------------------------------------------------// + +#ifndef __Spheral_BarthJespersenLimiter_hh__ +#define __Spheral_BarthJespersenLimiter_hh__ + +#include "LimiterBase.hh" + +namespace Spheral { + +template +class BarthJespersenLimiter : public LimiterBase { + +public: + + typedef typename Dimension::Scalar Scalar; + + BarthJespersenLimiter(); + + ~BarthJespersenLimiter(); + + virtual + Scalar fluxLimiter(const Scalar) const override; + +}; + + +} + +#else + +// Forward declaration. +namespace Spheral { + template class BarthJespersenLimiter; +} + +#endif + diff --git a/src/GSPH/Limiters/BarthJespersenLimiterInst.cc.py b/src/GSPH/Limiters/BarthJespersenLimiterInst.cc.py new file mode 100644 index 000000000..b7ec5c8d8 --- /dev/null +++ b/src/GSPH/Limiters/BarthJespersenLimiterInst.cc.py @@ -0,0 +1,11 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "Geometry/Dimension.hh" +#include "GSPH/Limiters/BarthJespersenLimiter.cc" + +namespace Spheral { + template class BarthJespersenLimiter >; +} +""" From ddd179aa6e314480c439cb3e86ad4b7e4a189278 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Mon, 19 Jun 2023 13:37:06 -0700 Subject: [PATCH 28/60] GSPH policy to replace state w/ other state --- .../Policies/PureReplaceWithStateFieldList.cc | 148 ++++++++++++++++++ .../Policies/PureReplaceWithStateFieldList.hh | 62 ++++++++ .../PureReplaceWithStateFieldListInst.cc.py | 15 ++ 3 files changed, 225 insertions(+) create mode 100644 src/GSPH/Policies/PureReplaceWithStateFieldList.cc create mode 100644 src/GSPH/Policies/PureReplaceWithStateFieldList.hh create mode 100644 src/GSPH/Policies/PureReplaceWithStateFieldListInst.cc.py diff --git a/src/GSPH/Policies/PureReplaceWithStateFieldList.cc b/src/GSPH/Policies/PureReplaceWithStateFieldList.cc new file mode 100644 index 000000000..40c1f454d --- /dev/null +++ b/src/GSPH/Policies/PureReplaceWithStateFieldList.cc @@ -0,0 +1,148 @@ +//---------------------------------Spheral++----------------------------------// +// PureReplaceWithStateFieldList -- replaces one fieldlists values with +// a state field list specified by its key +// +// J.M. Pearl 2023 +//----------------------------------------------------------------------------// + +#include "GSPH/Policies/PureReplaceWithStateFieldList.hh" +#include "DataBase/IncrementFieldList.hh" +#include "DataBase/State.hh" +#include "DataBase/StateDerivatives.hh" +#include "Field/FieldList.hh" +#include "Utilities/DBC.hh" + +namespace Spheral { + +//------------------------------------------------------------------------------ +// Constructors. +//------------------------------------------------------------------------------ +template +PureReplaceWithStateFieldList:: +PureReplaceWithStateFieldList(const KeyType& derivFieldListKey): + FieldListUpdatePolicyBase(), + mReplaceKey(derivFieldListKey) { +} + +template +PureReplaceWithStateFieldList:: +PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, + const std::string& depend0): + FieldListUpdatePolicyBase(depend0), + mReplaceKey(derivFieldListKey) { +} + +template +PureReplaceWithStateFieldList:: +PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, + const std::string& depend0, + const std::string& depend1): + FieldListUpdatePolicyBase(depend0, depend1), + mReplaceKey(derivFieldListKey) { +} + +template +PureReplaceWithStateFieldList:: +PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, + const std::string& depend0, + const std::string& depend1, + const std::string& depend2): + FieldListUpdatePolicyBase(depend0, depend1, depend2), + mReplaceKey(derivFieldListKey) { +} + +template +PureReplaceWithStateFieldList:: +PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, + const std::string& depend0, + const std::string& depend1, + const std::string& depend2, + const std::string& depend3): + FieldListUpdatePolicyBase(depend0, depend1, depend2, depend3), + mReplaceKey(derivFieldListKey) { +} + +template +PureReplaceWithStateFieldList:: +PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, + const std::string& depend0, + const std::string& depend1, + const std::string& depend2, + const std::string& depend3, + const std::string& depend4): + FieldListUpdatePolicyBase(depend0, depend1, depend2, depend3, depend4), + mReplaceKey(derivFieldListKey) { +} + +template +PureReplaceWithStateFieldList:: +PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, + const std::string& depend0, + const std::string& depend1, + const std::string& depend2, + const std::string& depend3, + const std::string& depend4, + const std::string& depend5): + FieldListUpdatePolicyBase(depend0, depend1, depend2, depend3, depend4, depend5), + mReplaceKey(derivFieldListKey) { +} + +//------------------------------------------------------------------------------ +// Destructor. +//------------------------------------------------------------------------------ +template +PureReplaceWithStateFieldList:: +~PureReplaceWithStateFieldList() { +} + +//------------------------------------------------------------------------------ +// Update the field. +//------------------------------------------------------------------------------ +template +void +PureReplaceWithStateFieldList:: +update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double /*multiplier*/, + const double /*t*/, + const double /*dt*/) { + + // Get the field name portion of the key. + KeyType fieldKey, nodeListKey; + StateBase::splitFieldKey(key, fieldKey, nodeListKey); + CHECK(nodeListKey == UpdatePolicyBase::wildcard()); + + // Find the matching replacement FieldList from the StateDerivatives. + FieldList f = state.fields(fieldKey, Value()); + + // field we're replacing it with + const FieldList df = state.fields(mReplaceKey, Value()); + CHECK(f.size() == df.size()); + + // Loop over the internal values of the field. + const unsigned numNodeLists = f.size(); + for (unsigned k = 0; k != numNodeLists; ++k) { + const unsigned n = f[k]->numInternalElements(); + for (unsigned i = 0; i != n; ++i) { + f(k, i) = df(k, i); + } + } +} + + +//------------------------------------------------------------------------------ +// Equivalence operator. +//------------------------------------------------------------------------------ +template +bool +PureReplaceWithStateFieldList:: +operator==(const UpdatePolicyBase& rhs) const { + + // We're only equal if the other guy is also an replace operator. + const PureReplaceWithStateFieldList* rhsPtr = dynamic_cast*>(&rhs); + return rhsPtr != 0; +} + +} + diff --git a/src/GSPH/Policies/PureReplaceWithStateFieldList.hh b/src/GSPH/Policies/PureReplaceWithStateFieldList.hh new file mode 100644 index 000000000..88d46ea58 --- /dev/null +++ b/src/GSPH/Policies/PureReplaceWithStateFieldList.hh @@ -0,0 +1,62 @@ +//---------------------------------Spheral++----------------------------------// +// PureReplaceWithStateFieldList -- replaces one fieldlists values with +// a state field list specified by its key +// +// J.M. Pearl 2023 +//----------------------------------------------------------------------------// + +#ifndef __Spheral_PureReplaceWithStateFieldList_hh__ +#define __Spheral_PureReplaceWithStateFieldList_hh__ + +#include "DataBase/FieldListUpdatePolicyBase.hh" + +namespace Spheral { + +template +class PureReplaceWithStateFieldList: public FieldListUpdatePolicyBase { +public: + //--------------------------- Public Interface ---------------------------// + // Useful typedefs + typedef typename FieldListUpdatePolicyBase::KeyType KeyType; + + // Constructors, destructor. + + explicit PureReplaceWithStateFieldList(const KeyType& derivFieldListKey); + PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, const std::string& depend0); + PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, const std::string& depend0, const std::string& depend1); + PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, const std::string& depend0, const std::string& depend1, const std::string& depend2); + PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, const std::string& depend0, const std::string& depend1, const std::string& depend2, const std::string& depend3); + PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, const std::string& depend0, const std::string& depend1, const std::string& depend2, const std::string& depend3, const std::string& depend4); + PureReplaceWithStateFieldList(const KeyType& derivFieldListKey, const std::string& depend0, const std::string& depend1, const std::string& depend2, const std::string& depend3, const std::string& depend4, const std::string& depend5); + virtual ~PureReplaceWithStateFieldList(); + + // Overload the methods describing how to update FieldLists. + virtual void update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt) override; + + // Equivalence. + virtual bool operator==(const UpdatePolicyBase& rhs) const override; + +private: + //--------------------------- Private Interface ---------------------------// + const KeyType mReplaceKey; + + PureReplaceWithStateFieldList(); + PureReplaceWithStateFieldList(const PureReplaceWithStateFieldList& rhs); + PureReplaceWithStateFieldList& operator=(const PureReplaceWithStateFieldList& rhs); +}; + +} + +#else + +// Forward declaration. +namespace Spheral { + template class PureReplaceWithStateFieldList; +} + +#endif diff --git a/src/GSPH/Policies/PureReplaceWithStateFieldListInst.cc.py b/src/GSPH/Policies/PureReplaceWithStateFieldListInst.cc.py new file mode 100644 index 000000000..5fab47a31 --- /dev/null +++ b/src/GSPH/Policies/PureReplaceWithStateFieldListInst.cc.py @@ -0,0 +1,15 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "Geometry/Dimension.hh" +#include "GSPH/Policies/PureReplaceWithStateFieldList.cc" + +namespace Spheral { + template class PureReplaceWithStateFieldList, Dim< %(ndim)s >::Scalar>; + template class PureReplaceWithStateFieldList, Dim< %(ndim)s >::Vector>; + template class PureReplaceWithStateFieldList, Dim< %(ndim)s >::Vector3d>; + template class PureReplaceWithStateFieldList, Dim< %(ndim)s >::Tensor>; + template class PureReplaceWithStateFieldList, Dim< %(ndim)s >::SymTensor>; +} +""" From cee5e5ab83ec9a8435a6b96f07f1f43b98ff53a8 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Mon, 19 Jun 2023 13:45:47 -0700 Subject: [PATCH 29/60] GSPH addings DrhoDx to riemann solver --- src/GSPH/RiemannSolvers/HLLC.cc | 30 +++++++++++++------ src/GSPH/RiemannSolvers/HLLC.hh | 2 ++ src/GSPH/RiemannSolvers/RiemannSolverBase.cc | 2 ++ src/GSPH/RiemannSolvers/RiemannSolverBase.hh | 2 ++ .../SecondOrderArtificialViscosity.cc | 6 ++-- .../SecondOrderArtificialViscosity.hh | 2 ++ 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/GSPH/RiemannSolvers/HLLC.cc b/src/GSPH/RiemannSolvers/HLLC.cc index a925123ee..ad1982f01 100644 --- a/src/GSPH/RiemannSolvers/HLLC.cc +++ b/src/GSPH/RiemannSolvers/HLLC.cc @@ -1,6 +1,6 @@ //---------------------------------Spheral++----------------------------------// // HLLC -- approximate riemann solver -// Toro E.F., Spruce M., Speares W., (1994) "Restoration of the Contact +// Toro E.F., Spruce M., Speares W., (1994) "Restoration of the Contact // Surface in the HLL-Riemann Solver," Shock Waves, 4:25-34 // // J.M. Pearl 2021 @@ -57,14 +57,16 @@ interfaceState(const typename Dimension::Vector& ri, const typename Dimension::Scalar& Pj, const typename Dimension::Vector& vi, const typename Dimension::Vector& vj, + const typename Dimension::Vector& DrhoDxi, + const typename Dimension::Vector& DrhoDxj, const typename Dimension::Vector& DpDxi, const typename Dimension::Vector& DpDxj, const typename Dimension::Tensor& DvDxi, const typename Dimension::Tensor& DvDxj, typename Dimension::Scalar& Pstar, typename Dimension::Vector& vstar, - typename Dimension::Scalar& /*rhostari*/, - typename Dimension::Scalar& /*rhostarj*/) const{ + typename Dimension::Scalar& rhostari, + typename Dimension::Scalar& rhostarj) const{ Scalar Si, Sj; @@ -77,6 +79,8 @@ interfaceState(const typename Dimension::Vector& ri, vstar = 0.5*(vi+vj); Pstar = 0.5*(Pi+Pj); + rhostari = rhoi; + rhostarj = rhoj; if (ci > tiny or cj > tiny){ @@ -88,14 +92,19 @@ interfaceState(const typename Dimension::Vector& ri, auto p1i = Pi; auto p1j = Pj; + auto rho1i = rhoi; + auto rho1j = rhoj; + // linear reconstruction if(this->linearReconstruction()){ // gradients along line of action - this->linearReconstruction(ri,rj, Pi,Pj,DpDxi,DpDxj, //inputs - p1i,p1j); //outputs - this->linearReconstruction(ri,rj, vi,vj,DvDxi,DvDxj, //inputs - v1i,v1j); //outputs + this->linearReconstruction(ri,rj, rhoi,rhoj,DrhoDxi,DrhoDxj, //inputs + rho1i,rho1j); //outputs + this->linearReconstruction(ri,rj, Pi,Pj,DpDxi,DpDxj, //inputs + p1i,p1j); //outputs + this->linearReconstruction(ri,rj, vi,vj,DvDxi,DvDxj, //inputs + v1i,v1j); //outputs } @@ -104,8 +113,8 @@ interfaceState(const typename Dimension::Vector& ri, const auto wi = v1i - ui*rhatij; const auto wj = v1j - uj*rhatij; - waveSpeedObject.waveSpeed(rhoi,rhoj,ci,cj,ui,uj, //inputs - Si,Sj); //outputs + waveSpeedObject.waveSpeed(rho1i,rho1j,ci,cj,ui,uj, //inputs + Si,Sj); //outputs const auto denom = safeInv(Si - Sj); @@ -113,11 +122,14 @@ interfaceState(const typename Dimension::Vector& ri, const auto wstar = (Si*wi - Sj*wj)*denom; vstar = ustar*rhatij + wstar; Pstar = Sj * (ustar-uj) + p1j; + rhostari = rho1i;// * (Si - ui)*safeInv(Si-ustar); + rhostarj = rho1j;// * (Sj - uj)*safeInv(Sj-ustar); }else{ // if ci & cj too small punt to normal av const auto uij = std::min((vi-vj).dot(rhatij),0.0); Pstar += 0.25 * (rhoi+rhoj) * (uij*uij); } + }// Scalar interface class diff --git a/src/GSPH/RiemannSolvers/HLLC.hh b/src/GSPH/RiemannSolvers/HLLC.hh index 822bae67a..ea9526ee9 100644 --- a/src/GSPH/RiemannSolvers/HLLC.hh +++ b/src/GSPH/RiemannSolvers/HLLC.hh @@ -50,6 +50,8 @@ public: const Scalar& sigmaj, const Vector& vi, const Vector& vj, + const Vector& DrhoDxi, + const Vector& DrhoDxj, const Vector& DpDxi, const Vector& DpDxj, const Tensor& DvDxi, diff --git a/src/GSPH/RiemannSolvers/RiemannSolverBase.cc b/src/GSPH/RiemannSolvers/RiemannSolverBase.cc index 3c062bc62..6fe5490c5 100644 --- a/src/GSPH/RiemannSolvers/RiemannSolverBase.cc +++ b/src/GSPH/RiemannSolvers/RiemannSolverBase.cc @@ -165,6 +165,8 @@ interfaceState(const Vector& /*ri*/, const Scalar& /*Pj*/, const Vector& /*vi*/, const Vector& /*vj*/, + const Vector& /*DrhoDxi*/, + const Vector& /*DrhoDxj*/, const Vector& /*DpDxi*/, const Vector& /*DpDxj*/, const Tensor& /*DvDxi*/, diff --git a/src/GSPH/RiemannSolvers/RiemannSolverBase.hh b/src/GSPH/RiemannSolvers/RiemannSolverBase.hh index 0743bfb49..d1d031fa9 100644 --- a/src/GSPH/RiemannSolvers/RiemannSolverBase.hh +++ b/src/GSPH/RiemannSolvers/RiemannSolverBase.hh @@ -60,6 +60,8 @@ public: const Scalar& Pj, const Vector& vi, const Vector& vj, + const Vector& DrhoDxi, + const Vector& DrhoDxj, const Vector& DpDxi, const Vector& DpDxj, const Tensor& DvDxi, diff --git a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc index 43c0a2de8..5ffcabff6 100644 --- a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc @@ -65,8 +65,10 @@ interfaceState(const typename Dimension::Vector& ri, const typename Dimension::Scalar& Pj, const typename Dimension::Vector& vi, const typename Dimension::Vector& vj, - const typename Dimension::Vector& DpDxi, - const typename Dimension::Vector& DpDxj, + const typename Dimension::Vector& /*DrhoDxi*/, + const typename Dimension::Vector& /*DrhoDxj*/, + const typename Dimension::Vector& /*DpDxi*/, + const typename Dimension::Vector& /*DpDxj*/, const typename Dimension::Tensor& DvDxi, const typename Dimension::Tensor& DvDxj, typename Dimension::Scalar& Pstar, diff --git a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh index c99881ffe..96530258f 100644 --- a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh @@ -53,6 +53,8 @@ public: const Scalar& sigmaj, const Vector& vi, const Vector& vj, + const Vector& DrhoDxi, + const Vector& DrhoDxj, const Vector& DpDxi, const Vector& DpDxj, const Tensor& DvDxi, From 0f7cea81e08d77f141b444d7a407e30e7f8fe24f Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Mon, 19 Jun 2023 13:47:26 -0700 Subject: [PATCH 30/60] updating MFM and GSPH to new HLLC inputs --- src/GSPH/GSPHEvaluateDerivatives.cc | 27 ++++++++++++++++++++++++--- src/GSPH/MFMEvaluateDerivatives.cc | 27 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index 6ef7a6cfa..3569c2fd6 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -67,6 +67,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Derivative FieldLists. const auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + const auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto normalization = derivatives.fields(HydroFieldNames::normalization, 0.0); auto DxDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::position, Vector::zero); auto DrhoDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::massDensity, 0.0); @@ -83,6 +84,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + CHECK(DrhoDx.size() == numNodeLists); CHECK(M.size() == numNodeLists); CHECK(normalization.size() == numNodeLists); CHECK(DxDt.size() == numNodeLists); @@ -157,6 +159,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); + const auto& gradRhoi = DrhoDx(nodeListi,i); const auto& Mi = M(nodeListi,i); @@ -186,6 +189,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); + const auto& gradRhoj = DrhoDx(nodeListj,j); const auto& Mj = M(nodeListj,j); // Node displacement. @@ -245,6 +249,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, ci, cj, Peffi, Peffj, vi, vj, + gradRhoi, gradRhoj, gradPi, gradPj, gradVi, gradVj, Pstar, //output @@ -430,24 +435,26 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, const DataBase& dataBase, const State& state, StateDerivatives& derivatives) const { - // The kernels and such. const auto& W = this->kernel(); const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient or this->gradientType() == GradientType::SPHUncorrectedGradient); const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient); + // The connectivity. const auto& connectivityMap = dataBase.connectivityMap(); const auto& nodeLists = connectivityMap.nodeLists(); const auto numNodeLists = nodeLists.size(); // Get the state and derivative FieldLists. + const auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); const auto volume = state.fields(HydroFieldNames::volume, 0.0); const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); const auto pressure = state.fields(HydroFieldNames::pressure, 0.0); const auto position = state.fields(HydroFieldNames::position, Vector::zero); const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); + CHECK(massDensity.size() == numNodeLists); CHECK(volume.size() == numNodeLists); CHECK(velocity.size() == numNodeLists); CHECK(pressure.size() == numNodeLists); @@ -455,10 +462,12 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(H.size() == numNodeLists); auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); CHECK(M.size() == numNodeLists); + CHECK(DrhoDx.size() == numNodeLists); CHECK(newRiemannDpDx.size() == numNodeLists); CHECK(newRiemannDvDx.size() == numNodeLists); @@ -473,6 +482,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, typename SpheralThreads::FieldListStack threadStack; auto M_thread = M.threadCopy(threadStack); + auto DrhoDx_thread = DrhoDx.threadCopy(threadStack); auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); @@ -484,6 +494,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, nodeListj = pairs[kk].j_list; // Get the state for node i. + const auto& rhoi = massDensity(nodeListi, i); const auto& ri = position(nodeListi, i); const auto& voli = volume(nodeListi, i); const auto& Hi = H(nodeListi, i); @@ -492,8 +503,10 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(Hdeti > 0.0); auto& Mi = M_thread(nodeListi, i); + auto& DrhoDxi = DrhoDx_thread(nodeListi, i); // Get the state for node j + const auto& rhoj = massDensity(nodeListj, j); const auto& rj = position(nodeListj, j); const auto& volj = volume(nodeListj, j); const auto& Hj = H(nodeListj, j); @@ -502,6 +515,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(Hdetj > 0.0); auto& Mj = M_thread(nodeListj, j); + auto& DrhoDxj = DrhoDx_thread(nodeListj, j); const auto rij = ri - rj; @@ -527,6 +541,9 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi -= rij.dyad(gradPsii); Mj -= rij.dyad(gradPsij); + DrhoDxi -= (rhoi - rhoj) * gradPsii; + DrhoDxj -= (rhoi - rhoj) * gradPsij; + // // based on nodal values if (calcSpatialGradients){ @@ -534,6 +551,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, const auto& Pi = pressure(nodeListi, i); const auto& vj = velocity(nodeListj, j); const auto& Pj = pressure(nodeListj, j); + auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj, j); @@ -561,6 +579,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, for (auto i = 0u; i < ni; ++i) { const auto numNeighborsi = connectivityMap.numNeighborsForNode(nodeListi, i); auto& Mi = M(nodeListi, i); + auto& DrhoDxi = DrhoDx(nodeListi, i); const auto Mdeti = std::abs(Mi.Determinant()); @@ -569,11 +588,12 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi = ( goodM ? Mi.Inverse() : Tensor::one); - if (correctSpatialGradients){ + DrhoDxi = Mi.Transpose()*DrhoDxi; + if (correctSpatialGradients){ + auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); - newRiemannDpDxi = Mi.Transpose()*newRiemannDpDxi; newRiemannDvDxi = newRiemannDvDxi*Mi; @@ -589,6 +609,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, for (ConstBoundaryIterator boundItr = this->boundaryBegin(); boundItr != this->boundaryEnd(); ++boundItr){ + (*boundItr)->applyFieldListGhostBoundary(DrhoDx); (*boundItr)->applyFieldListGhostBoundary(newRiemannDpDx); (*boundItr)->applyFieldListGhostBoundary(newRiemannDvDx); } diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index 430235bb1..e0aaba2aa 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -66,6 +66,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Derivative FieldLists. const auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + const auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto normalization = derivatives.fields(HydroFieldNames::normalization, 0.0); auto DxDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::position, Vector::zero); auto DvolDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::volume, 0.0); @@ -82,6 +83,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + CHECK(DrhoDx.size() == numNodeLists); CHECK(M.size() == numNodeLists); CHECK(normalization.size() == numNodeLists); CHECK(DxDt.size() == numNodeLists); @@ -158,6 +160,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); const auto& Mi = M(nodeListi,i); + const auto& gradRhoi = DrhoDx(nodeListi,i); // Get the state for node j @@ -188,6 +191,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); const auto& Mj = M(nodeListj,j); + const auto& gradRhoj = DrhoDx(nodeListj,j); // Node displacement. const auto rij = ri - rj; @@ -246,6 +250,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, ci, cj, Peffi, Peffj, vi, vj, + gradRhoi, gradRhoj, gradPi, gradPj, gradVi, gradVj, Pstar, //output @@ -440,11 +445,14 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, const auto numNodeLists = nodeLists.size(); // Get the state and derivative FieldLists. + const auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); const auto volume = state.fields(HydroFieldNames::volume, 0.0); const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); const auto pressure = state.fields(HydroFieldNames::pressure, 0.0); const auto position = state.fields(HydroFieldNames::position, Vector::zero); const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); + + CHECK(massDensity.size() == numNodeLists); CHECK(volume.size() == numNodeLists); CHECK(velocity.size() == numNodeLists); CHECK(pressure.size() == numNodeLists); @@ -452,10 +460,12 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(H.size() == numNodeLists); auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); CHECK(M.size() == numNodeLists); + CHECK(DrhoDx.size() == numNodeLists); CHECK(newRiemannDpDx.size() == numNodeLists); CHECK(newRiemannDvDx.size() == numNodeLists); @@ -470,6 +480,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, typename SpheralThreads::FieldListStack threadStack; auto M_thread = M.threadCopy(threadStack); + auto DrhoDx_thread = DrhoDx.threadCopy(threadStack); auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); @@ -481,6 +492,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, nodeListj = pairs[kk].j_list; // Get the state for node i. + const auto& rhoi = massDensity(nodeListi, i); const auto& ri = position(nodeListi, i); const auto& voli = volume(nodeListi, i); const auto& Hi = H(nodeListi, i); @@ -488,9 +500,11 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(voli > 0.0); CHECK(Hdeti > 0.0); + auto& DrhoDxi = DrhoDx_thread(nodeListi, i); auto& Mi = M_thread(nodeListi, i); // Get the state for node j + const auto& rhoj = massDensity(nodeListj, j); const auto& rj = position(nodeListj, j); const auto& volj = volume(nodeListj, j); const auto& Hj = H(nodeListj, j); @@ -498,6 +512,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(volj > 0.0); CHECK(Hdetj > 0.0); + auto& DrhoDxj = DrhoDx_thread(nodeListj, j); auto& Mj = M_thread(nodeListj, j); const auto rij = ri - rj; @@ -523,12 +538,17 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi -= rij.dyad(gradPsii); Mj -= rij.dyad(gradPsij); + DrhoDxi -= (rhoi - rhoj) * gradPsii; + DrhoDxj -= (rhoi - rhoj) * gradPsij; + // // based on nodal values if (calcSpatialGradients){ + const auto& vi = velocity(nodeListi, i); const auto& Pi = pressure(nodeListi, i); const auto& vj = velocity(nodeListj, j); const auto& Pj = pressure(nodeListj, j); + auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj, j); @@ -539,6 +559,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, newRiemannDvDxi -= (vi-vj).dyad(gradPsii); newRiemannDvDxj -= (vi-vj).dyad(gradPsij); + } } // loop over pairs @@ -563,12 +584,17 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi = ( goodM ? Mi.Inverse() : Tensor::one); + auto& DrhoDxi = DrhoDx(nodeListi, i); + DrhoDxi = Mi.Transpose()*DrhoDxi; + if (correctSpatialGradients){ + auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); newRiemannDpDxi = Mi.Transpose()*newRiemannDpDxi; newRiemannDvDxi = newRiemannDvDxi*Mi; + } } @@ -582,6 +608,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, for (ConstBoundaryIterator boundItr = this->boundaryBegin(); boundItr != this->boundaryEnd(); ++boundItr){ + (*boundItr)->applyFieldListGhostBoundary(DrhoDx); (*boundItr)->applyFieldListGhostBoundary(newRiemannDpDx); (*boundItr)->applyFieldListGhostBoundary(newRiemannDvDx); } From 63d78ecccdf4c3aee4bde16f8fb55f86f2163145 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Mon, 19 Jun 2023 13:50:05 -0700 Subject: [PATCH 31/60] check point on an ALESPH MFV extension --- src/GSPH/CMakeLists.txt | 8 + src/GSPH/GSPHFieldNames.cc | 1 + src/GSPH/GSPHFieldNames.hh | 1 + src/GSPH/GSPHHydros.py | 6 +- src/GSPH/GenericRiemannHydro.cc | 8 +- src/GSPH/GenericRiemannHydro.hh | 2 + src/GSPH/GenericRiemannHydroInline.hh | 8 + src/GSPH/MFVEvaluateDerivatives.cc | 80 +++++--- src/GSPH/MFVHydroBase.cc | 87 ++++++++- src/GSPH/MFVHydroBase.hh | 41 +++- src/GSPH/MFVHydroBaseInline.hh | 29 +++ src/GSPH/Policies/ALEPositionPolicy.cc | 91 +++++++++ src/GSPH/Policies/ALEPositionPolicy.hh | 63 +++++++ src/GSPH/Policies/ALEPositionPolicyInst.cc.py | 11 ++ ...ompatibleALESpecificThermalEnergyPolicy.cc | 178 ++++++++++++++++++ ...ompatibleALESpecificThermalEnergyPolicy.hh | 84 +++++++++ ...leALESpecificThermalEnergyPolicyInst.cc.py | 11 ++ .../IncrementSpecificFromTotalPolicy.cc | 31 ++- src/GSPH/Policies/MassFluxPolicy.cc | 128 +++++++++++++ src/GSPH/Policies/MassFluxPolicy.hh | 69 +++++++ src/GSPH/Policies/MassFluxPolicyInst.cc.py | 11 ++ src/GSPH/Policies/PureReplaceFieldList.cc | 2 + ...leDifferenceSpecificThermalEnergyPolicy.cc | 8 +- src/PYB11/GSPH/GSPH_PYB11.py | 8 + src/PYB11/GSPH/Limiters.py | 28 +++ src/PYB11/GSPH/MFVHydroBase.py | 3 +- 26 files changed, 936 insertions(+), 61 deletions(-) create mode 100644 src/GSPH/Policies/ALEPositionPolicy.cc create mode 100644 src/GSPH/Policies/ALEPositionPolicy.hh create mode 100644 src/GSPH/Policies/ALEPositionPolicyInst.cc.py create mode 100644 src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.cc create mode 100644 src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.hh create mode 100644 src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicyInst.cc.py create mode 100644 src/GSPH/Policies/MassFluxPolicy.cc create mode 100644 src/GSPH/Policies/MassFluxPolicy.hh create mode 100644 src/GSPH/Policies/MassFluxPolicyInst.cc.py diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 37dad075d..35e9d4bd7 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -9,6 +9,9 @@ set(GSPH_inst GSPHHydroBase MFMHydroBase MFVHydroBase + Policies/MassFluxPolicy + Policies/ALEPositionPolicy + Policies/PureReplaceWithStateFieldList Policies/PureReplaceFieldList Policies/ReplaceWithRatioPolicy Policies/IncrementSpecificFromTotalPolicy @@ -18,6 +21,7 @@ set(GSPH_inst Limiters/MinModLimiter Limiters/VanAlbaLimiter Limiters/OspreLimiter + Limiters/BarthJespersenLimiter WaveSpeeds/WaveSpeedBase WaveSpeeds/AcousticWaveSpeed WaveSpeeds/DavisWaveSpeed @@ -39,6 +43,9 @@ set(GSPH_headers GSPHHydroBase.hh MFMHydroBase.hh MFVHydroBase.hh + Policies/MassFluxPolicy.hh + Policies/ALEPositionPolicy.hh + Policies/PureReplaceWithStateFieldList.hh Policies/PureReplaceFieldList.hh Policies/ReplaceWithRatioPolicy.hh Policies/IncrementSpecificFromTotalPolicy.hh @@ -48,6 +55,7 @@ set(GSPH_headers Limiters/MinModLimiter.hh Limiters/VanAlbaLimiter.hh Limiters/OspreLimiter.hh + Limiters/BarthJespersenLimiter.hh WaveSpeeds/WaveSpeedBase.hh WaveSpeeds/AcousticWaveSpeed.hh WaveSpeeds/DavisWaveSpeed.hh diff --git a/src/GSPH/GSPHFieldNames.cc b/src/GSPH/GSPHFieldNames.cc index 2aefe99c1..d8da418ed 100644 --- a/src/GSPH/GSPHFieldNames.cc +++ b/src/GSPH/GSPHFieldNames.cc @@ -6,6 +6,7 @@ #include "GSPHFieldNames.hh" +const std::string Spheral::GSPHFieldNames::nodalVelocity = "velocity of node"; const std::string Spheral::GSPHFieldNames::momentum = "momentum"; const std::string Spheral::GSPHFieldNames::thermalEnergy = "thermal energy"; const std::string Spheral::GSPHFieldNames::densityGradient = "density gradient"; diff --git a/src/GSPH/GSPHFieldNames.hh b/src/GSPH/GSPHFieldNames.hh index 776c037ff..0b653c8ad 100644 --- a/src/GSPH/GSPHFieldNames.hh +++ b/src/GSPH/GSPHFieldNames.hh @@ -12,6 +12,7 @@ namespace Spheral { struct GSPHFieldNames { + static const std::string nodalVelocity; static const std::string momentum; static const std::string thermalEnergy; static const std::string densityGradient; diff --git a/src/GSPH/GSPHHydros.py b/src/GSPH/GSPHHydros.py index 9023b5d44..9e10e906d 100644 --- a/src/GSPH/GSPHHydros.py +++ b/src/GSPH/GSPHHydros.py @@ -184,6 +184,7 @@ def MFV(dataBase, riemannSolver=None, specificThermalEnergyDiffusionCoefficient = 0.0, cfl = 0.25, + nodeMotionType = NodeMotionType.Lagrangian, gradientType = HydroAccelerationGradient, densityUpdate = IntegrateDensity, useVelocityMagnitudeForDt = False, @@ -247,6 +248,7 @@ def MFV(dataBase, "evolveTotalEnergy" : evolveTotalEnergy, "XSPH" : XSPH, "correctVelocityGradient" : correctVelocityGradient, + "nodeMotionType" : nodeMotionType, "gradType" : gradientType, "densityUpdate" : densityUpdate, "HUpdate" : HUpdate, @@ -255,10 +257,10 @@ def MFV(dataBase, "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} - + print(nodeMotionType) # Build and return the thing. result = Constructor(**kwargs) result._smoothingScaleMethod = smoothingScaleMethod - + print(result.nodeMotionType) return result diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 2ece0fafe..92deb2fe0 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -126,6 +126,7 @@ GenericRiemannHydro(const SmoothingScaleBase& smoothingScaleMethod, mDvDt(FieldStorageType::CopyFields), // move up one layer mDspecificThermalEnergyDt(FieldStorageType::CopyFields), // move up one layer mDHDt(FieldStorageType::CopyFields), + mDrhoDx(FieldStorageType::CopyFields), mDvDx(FieldStorageType::CopyFields), mRiemannDpDx(FieldStorageType::CopyFields), mRiemannDvDx(FieldStorageType::CopyFields), @@ -150,6 +151,7 @@ GenericRiemannHydro(const SmoothingScaleBase& smoothingScaleMethod, mDvDt = dataBase.newFluidFieldList(Vector::zero, HydroFieldNames::hydroAcceleration); mDspecificThermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy); mDHDt = dataBase.newFluidFieldList(SymTensor::zero, IncrementFieldList::prefix() + HydroFieldNames::H); + mDrhoDx = dataBase.newFluidFieldList(Vector::zero,GSPHFieldNames::densityGradient); mDvDx = dataBase.newFluidFieldList(Tensor::zero, HydroFieldNames::velocityGradient); mRiemannDpDx = dataBase.newFluidFieldList(Vector::zero,GSPHFieldNames::RiemannPressureGradient); mRiemannDvDx = dataBase.newFluidFieldList(Tensor::zero,GSPHFieldNames::RiemannVelocityGradient); @@ -220,8 +222,6 @@ GenericRiemannHydro:: registerState(DataBase& dataBase, State& state) { - //typedef typename State::PolicyPointer PolicyPointer; - VERIFY2(not (mCompatibleEnergyEvolution and mEvolveTotalEnergy), "SPH error : you cannot simultaneously use both compatibleEnergyEvolution and evolveTotalEnergy"); @@ -249,7 +249,7 @@ registerState(DataBase& dataBase, Hpolicy->push_back(new ReplaceBoundedState(hmaxInv, hminInv)); } } - //auto yieldStrengthPolicy = make_shared>() + auto positionPolicy = make_shared>(); auto pressurePolicy = make_shared>(); auto csPolicy = make_shared>(); @@ -323,6 +323,7 @@ registerDerivatives(DataBase& dataBase, dataBase.resizeFluidFieldList(mDspecificThermalEnergyDt, 0.0, IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, false); dataBase.resizeFluidFieldList(mDHDt, SymTensor::zero, IncrementFieldList::prefix() + HydroFieldNames::H, false); dataBase.resizeFluidFieldList(mDvDx, Tensor::zero, HydroFieldNames::velocityGradient, false); + dataBase.resizeFluidFieldList(mDrhoDx, Vector::zero, GSPHFieldNames::densityGradient, false); dataBase.resizeFluidFieldList(mM, Tensor::zero, HydroFieldNames::M_SPHCorrection, false); // Check if someone already registered DxDt. @@ -332,6 +333,7 @@ registerDerivatives(DataBase& dataBase, } // Check that no-one else is trying to control the hydro vote for DvDt. CHECK(not derivs.registered(mDvDt)); + derivs.enroll(mDrhoDx); derivs.enroll(mNewRiemannDpDx); derivs.enroll(mNewRiemannDvDx); derivs.enroll(mDvDt); diff --git a/src/GSPH/GenericRiemannHydro.hh b/src/GSPH/GenericRiemannHydro.hh index 894305bf8..446098c9c 100644 --- a/src/GSPH/GenericRiemannHydro.hh +++ b/src/GSPH/GenericRiemannHydro.hh @@ -204,6 +204,7 @@ public: const std::vector& pairAccelerations() const; const std::vector& pairDepsDt() const; + const FieldList& DrhoDx() const; const FieldList& riemannDpDx() const; const FieldList& riemannDvDx() const; const FieldList& newRiemannDpDx() const; @@ -264,6 +265,7 @@ private: FieldList mDspecificThermalEnergyDt; FieldList mDHDt; + FieldList mDrhoDx; FieldList mDvDx; FieldList mRiemannDpDx; FieldList mRiemannDvDx; diff --git a/src/GSPH/GenericRiemannHydroInline.hh b/src/GSPH/GenericRiemannHydroInline.hh index ab296c78f..e3264732a 100644 --- a/src/GSPH/GenericRiemannHydroInline.hh +++ b/src/GSPH/GenericRiemannHydroInline.hh @@ -643,6 +643,14 @@ specificThermalEnergyDiffusionCoefficient() const { } +template +inline +const FieldList& +GenericRiemannHydro:: +DrhoDx() const { + return mDrhoDx; +} + template inline const FieldList& diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index db6c60251..b007d701e 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -16,12 +16,12 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& smoothingScale = this->smoothingScaleMethod(); // A few useful constants we'll use in the following loop. - const auto tiny = std::numeric_limits::epsilon(); + //const auto tiny = std::numeric_limits::epsilon(); const auto xsph = this->XSPH(); const auto epsTensile = this->epsilonTensile(); //const auto epsDiffusionCoeff = this->specificThermalEnergyDiffusionCoefficient(); const auto compatibleEnergy = this->compatibleEnergyEvolution(); - const auto totalEnergy = this->evolveTotalEnergy(); + //const auto totalEnergy = this->evolveTotalEnergy(); const auto gradType = this->gradientType(); //const auto correctVelocityGradient = this->correctVelocityGradient(); @@ -43,6 +43,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto mass = state.fields(HydroFieldNames::mass, 0.0); const auto position = state.fields(HydroFieldNames::position, Vector::zero); const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); + const auto nodalVelocity = state.fields(GSPHFieldNames::nodalVelocity, Vector::zero); const auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); const auto volume = state.fields(HydroFieldNames::volume, 0.0); const auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); @@ -52,6 +53,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto riemannDpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); const auto riemannDvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + CHECK(nodalVelocity.size() == numNodeLists); CHECK(mass.size() == numNodeLists); CHECK(position.size() == numNodeLists); CHECK(velocity.size() == numNodeLists); @@ -66,11 +68,12 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Derivative FieldLists. const auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + const auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto normalization = derivatives.fields(HydroFieldNames::normalization, 0.0); auto DxDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::position, Vector::zero); auto DvolDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::volume, 0.0); - auto DvDt = derivatives.fields(HydroFieldNames::hydroAcceleration, Vector::zero); - auto DepsDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); + //auto DvDt = derivatives.fields(HydroFieldNames::hydroAcceleration, Vector::zero); + //auto DepsDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); auto DmDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, 0.0); auto DEDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, 0.0); auto DpDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::momentum, Vector::zero); @@ -85,12 +88,13 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + CHECK(DrhoDx.size() == numNodeLists); CHECK(M.size() == numNodeLists); CHECK(normalization.size() == numNodeLists); CHECK(DxDt.size() == numNodeLists); CHECK(DvolDt.size() == numNodeLists); - CHECK(DvDt.size() == numNodeLists); - CHECK(DepsDt.size() == numNodeLists); + //CHECK(DvDt.size() == numNodeLists); + //CHECK(DepsDt.size() == numNodeLists); CHECK(DEDt.size() == numNodeLists); CHECK(DpDt.size() == numNodeLists); CHECK(DvDx.size() == numNodeLists); @@ -118,10 +122,11 @@ evaluateDerivatives(const typename Dimension::Scalar time, Vector gradPsii, gradPsij, Ai, Aj, vstar; typename SpheralThreads::FieldListStack threadStack; - auto DvDt_thread = DvDt.threadCopy(threadStack); + //auto DvDt_thread = DvDt.threadCopy(threadStack); auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); //auto DepsDt_thread = DepsDt.threadCopy(threadStack); + auto DvolDt_thread = DvolDt.threadCopy(threadStack); auto DmDt_thread = DmDt.threadCopy(threadStack); auto DEDt_thread = DEDt.threadCopy(threadStack); auto DpDt_thread = DpDt.threadCopy(threadStack); @@ -139,6 +144,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, nodeListj = pairs[kk].j_list; // Get the state for node i. + const auto& ui = nodalVelocity(nodeListi,i); const auto& riemannDpDxi = riemannDpDx(nodeListi, i); const auto& riemannDvDxi = riemannDvDx(nodeListi, i); const auto& ri = position(nodeListi, i); @@ -157,21 +163,24 @@ evaluateDerivatives(const typename Dimension::Scalar time, CHECK(Hdeti > 0.0); auto& normi = normalization_thread(nodeListi,i); + //auto& DvDti = DvDt_thread(nodeListi, i); //auto& DepsDti = DepsDt_thread(nodeListi, i); + auto& DvolDti = DvolDt_thread(nodeListi,i); auto& DmDti = DmDt_thread(nodeListi, i); auto& DEDti = DEDt_thread(nodeListi, i); auto& DpDti = DpDt_thread(nodeListi, i); - auto& DvDti = DvDt_thread(nodeListi, i); auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); auto& DvDxi = DvDx_thread(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); + const auto& gradRhoi = DrhoDx(nodeListi, i); const auto& Mi = M(nodeListi,i); // Get the state for node j + const auto& uj = nodalVelocity(nodeListj,j); const auto& riemannDpDxj = riemannDpDx(nodeListj, j); const auto& riemannDvDxj = riemannDvDx(nodeListj, j); const auto& rj = position(nodeListj, j); @@ -190,8 +199,9 @@ evaluateDerivatives(const typename Dimension::Scalar time, CHECK(Hdetj > 0.0); auto& normj = normalization_thread(nodeListj,j); - auto& DvDtj = DvDt_thread(nodeListj, j); + //auto& DvDtj = DvDt_thread(nodeListj, j); //auto& DepsDtj = DepsDt_thread(nodeListj, j); + auto& DvolDtj = DvolDt_thread(nodeListj,j); auto& DmDtj = DmDt_thread(nodeListj, j); auto& DEDtj = DEDt_thread(nodeListj, j); auto& DpDtj = DpDt_thread(nodeListj, j); @@ -201,6 +211,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); + const auto& gradRhoj = DrhoDx(nodeListj, j); const auto& Mj = M(nodeListj,j); // Node displacement. @@ -264,12 +275,14 @@ evaluateDerivatives(const typename Dimension::Scalar time, gradVi = newRiemannDvDx(nodeListi,i); gradVj = newRiemannDvDx(nodeListj,j); } + // need grad rho and grad eps riemannSolver.interfaceState(ri, rj, Hi, Hj, rhoi, rhoj, ci, cj, Peffi, Peffj, vi, vj, + gradRhoi, gradRhoj, gradPi, gradPj, gradVi, gradVj, Pstar, //output @@ -278,7 +291,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, rhostarj); //output const auto fluxSwitch = 1; - const auto vflux = vstar-(vi+vj)/2.0; + const auto vframe = (ui+uj)*0.5; + const auto vflux = vstar-vframe; const auto fluxTowardsNodei = vflux.dot(rhatij) > 0; const auto rhostar = (fluxTowardsNodei ? rhostarj : rhostari); // we'll need to fix these later const auto epsstar = (fluxTowardsNodei ? epsj : epsi); // we'll need to fix these later @@ -303,6 +317,9 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar) - energyFlux; const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj) + energyFlux; + //DepsDti += deltaDepsDti/mi; + //DepsDtj += deltaDepsDtj/mj; + DEDti += deltaDepsDti; DEDtj += deltaDepsDtj; @@ -313,6 +330,11 @@ evaluateDerivatives(const typename Dimension::Scalar time, pairDepsDt[2*kk+1] = deltaDepsDtj*invmij; } + // volume change based on nodal velocity + //----------------------------------------------------- + DvolDti -= (ui-uj).dot(gradPsii); + DvolDtj -= (ui-uj).dot(gradPsij); + // gradients //------------------------------------------------------ const auto deltaDvDxi = 2.0*(vi-vstar).dyad(gradPsii); @@ -382,43 +404,44 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Get the state for node i. const auto& ri = position(nodeListi, i); - const auto& mi = mass(nodeListi, i); + //const auto& mi = mass(nodeListi, i); const auto& voli = volume(nodeListi,i); - const auto& vi = velocity(nodeListi, i); + //const auto& vi = velocity(nodeListi, i); + const auto& ui = nodalVelocity(nodeListi,i); const auto& Hi = H(nodeListi, i); const auto Hdeti = Hi.Determinant(); - CHECK(mi > 0.0); + //CHECK(mi > 0.0); CHECK(voli > 0.0); CHECK(Hdeti > 0.0); auto& normi = normalization(nodeListi, i); auto& DxDti = DxDt(nodeListi, i); auto& DvolDti = DvolDt(nodeListi, i); - auto& DvDti = DvDt(nodeListi, i); - auto& DepsDti = DepsDt(nodeListi, i); + //auto& DvDti = DvDt(nodeListi, i); // FIX THIS + //auto& DepsDti = DepsDt(nodeListi, i); auto& DvDxi = DvDx(nodeListi, i); auto& DHDti = DHDt(nodeListi, i); auto& Hideali = Hideal(nodeListi, i); - auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); + //auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); normi += voli*Hdeti*W0; - DvolDti = voli * DvDxi.Trace() ; + DvolDti *= voli; // If needed finish the total energy derivative. - if (totalEnergy) DepsDti = mi*(vi.dot(DvDti) + DepsDti); + //if (totalEnergy) DepsDti = mi*(vi.dot(DvDti) + DepsDti); // Complete the moments of the node distribution for use in the ideal H calculation. weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); massSecondMomenti /= Hdeti*Hdeti; // Determine the position evolution, based on whether we're doing XSPH or not. - DxDti = vi; - if (xsph){ - DxDti += XSPHDeltaVi/max(tiny, normi); - } + DxDti = ui; + // if (xsph){ + // DxDti += XSPHDeltaVi/max(tiny, normi); + // } // The H tensor evolution. DHDti = smoothingScale.smoothingScaleDerivative(Hi, @@ -470,11 +493,14 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, const auto numNodeLists = nodeLists.size(); // Get the state and derivative FieldLists. + const auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); const auto volume = state.fields(HydroFieldNames::volume, 0.0); const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); const auto pressure = state.fields(HydroFieldNames::pressure, 0.0); const auto position = state.fields(HydroFieldNames::position, Vector::zero); const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); + + CHECK(massDensity.size() == numNodeLists); CHECK(volume.size() == numNodeLists); CHECK(velocity.size() == numNodeLists); CHECK(pressure.size() == numNodeLists); @@ -482,10 +508,12 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(H.size() == numNodeLists); auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); CHECK(M.size() == numNodeLists); + CHECK(DrhoDx.size() == numNodeLists); CHECK(newRiemannDpDx.size() == numNodeLists); CHECK(newRiemannDvDx.size() == numNodeLists); @@ -500,6 +528,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, typename SpheralThreads::FieldListStack threadStack; auto M_thread = M.threadCopy(threadStack); + auto DrhoDx_thread = DrhoDx.threadCopy(threadStack); auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); @@ -511,6 +540,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, nodeListj = pairs[kk].j_list; // Get the state for node i. + const auto& rhoi = massDensity(nodeListi, i); const auto& ri = position(nodeListi, i); const auto& voli = volume(nodeListi, i); const auto& Hi = H(nodeListi, i); @@ -518,9 +548,11 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(voli > 0.0); CHECK(Hdeti > 0.0); + auto& DrhoDxi = DrhoDx_thread(nodeListi, i); auto& Mi = M_thread(nodeListi, i); // Get the state for node j + const auto& rhoj = massDensity(nodeListj, j); const auto& rj = position(nodeListj, j); const auto& volj = volume(nodeListj, j); const auto& Hj = H(nodeListj, j); @@ -528,6 +560,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(volj > 0.0); CHECK(Hdetj > 0.0); + auto& DrhoDxj = DrhoDx_thread(nodeListj, j); auto& Mj = M_thread(nodeListj, j); const auto rij = ri - rj; @@ -553,6 +586,9 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, Mi -= rij.dyad(gradPsii); Mj -= rij.dyad(gradPsij); + DrhoDxi -= (rhoi - rhoj) * gradPsii; + DrhoDxj -= (rhoi - rhoj) * gradPsij; + // // based on nodal values if (calcSpatialGradients){ const auto& vi = velocity(nodeListi, i); diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index 5d953b673..a70984242 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -1,11 +1,37 @@ //---------------------------------Spheral++----------------------------------// -// MFVHydroBase -- spheralized verions of "Meshless Finite Mass" +// MFVHydroBase -- This is an Arbitrary Eulerian-Lagrangian extension of the +// MFV approach of Hopkins 2015. Its got several node-motion +// approaches which promote more regular particle distributions. +// +// Each of the ALE options defines the velocity of the nodes +// differently then the flux then results from the difference +// between the nodes velocities and the fluid velocity. +// The velocities are defined as follows for the +// NodeMotionTypes: +// +// 1) Eulerian ---- static Nodes +// 2) Lagrangian -- nodal velocity = fluid velocity. (This is +// a spheralized version of MFV so there +// is some flux between nodes) +// 3) Fician ------ nodal velocity = fluid velocity + Fician +// PST correction +// 4) XSPH -------- nodal velocity = xsph velocity +// 5) BackgroundPressure -- nodal acceleration = fluid +// acceleration + Background pressure +// force to drive regularization. +// // Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic // Simulation Methods," MNRAS, 450(1):53-110 // -// J.M. Pearl 2022 +// J.M. Pearl 2023 //----------------------------------------------------------------------------// - +// TODO: +// 1 mass flux should be limited so we don't get issues with neg mass +// 2 need better timestep constraints +// 3 maybe seperate flux polies for all conserved variables +// similar to an advect step in ALE schemes. Might give better e-conserve +// 4 compatible energy for MFV +//---------------------------------------------------------------------------// #include "FileIO/FileIO.hh" #include "NodeList/SmoothingScaleBase.hh" #include "Hydro/HydroFieldNames.hh" @@ -28,8 +54,12 @@ #include "GSPH/GSPHFieldNames.hh" #include "GSPH/computeSumVolume.hh" #include "GSPH/computeMFMDensity.hh" +#include "GSPH/Policies/ALEPositionPolicy.hh" +#include "GSPH/Policies/MassFluxPolicy.hh" #include "GSPH/Policies/ReplaceWithRatioPolicy.hh" #include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" +#include "GSPH/Policies/PureReplaceFieldList.hh" +#include "GSPH/Policies/PureReplaceWithStateFieldList.hh" #include "GSPH/RiemannSolvers/RiemannSolverBase.hh" #ifdef _OPENMP @@ -60,6 +90,7 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, const bool evolveTotalEnergy, const bool XSPH, const bool correctVelocityGradient, + const NodeMotionType nodeMotionType, const GradientType gradType, const MassDensityType densityUpdate, const HEvolutionType HUpdate, @@ -85,10 +116,13 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, nTensile, xmin, xmax), + mNodeMotionType(nodeMotionType), + mNodalVelocity(FieldStorageType::CopyFields), mDmassDt(FieldStorageType::CopyFields), mDthermalEnergyDt(FieldStorageType::CopyFields), mDmomentumDt(FieldStorageType::CopyFields), mDvolumeDt(FieldStorageType::CopyFields){ + mNodalVelocity = dataBase.newFluidFieldList(Vector::zero, GSPHFieldNames::nodalVelocity); mDmassDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::mass); mDthermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); mDmomentumDt = dataBase.newFluidFieldList(Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum); @@ -122,15 +156,26 @@ MFVHydroBase:: registerState(DataBase& dataBase, State& state) { - typedef typename State::PolicyPointer PolicyPointer; - GenericRiemannHydro::registerState(dataBase,state); + //state.removePolicy(HydroFieldNames::position); + + dataBase.resizeFluidFieldList(mNodalVelocity, Vector::zero, GSPHFieldNames::nodalVelocity); + auto massDensity = dataBase.fluidMassDensity(); + + auto position = dataBase.fluidPosition();//state.fields(HydroFieldNames::position,Vector::zero); + auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); auto volume = state.fields(HydroFieldNames::volume, 0.0); auto mass = state.fields(HydroFieldNames::mass, 0.0); auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); + CHECK(position.numFields() == dataBase.numFluidNodeLists()); + CHECK(velocity.numFields() == dataBase.numFluidNodeLists()); + CHECK(volume.numFields() == dataBase.numFluidNodeLists()); + CHECK(mass.numFields() == dataBase.numFluidNodeLists()); + CHECK(specificThermalEnergy.numFields() == dataBase.numFluidNodeLists()); + std::shared_ptr > volumePolicy(new CompositeFieldListPolicy()); for (auto itr = dataBase.fluidNodeListBegin(); itr != dataBase.fluidNodeListEnd(); @@ -143,10 +188,10 @@ registerState(DataBase& dataBase, } auto rhoPolicy = std::make_shared>(HydroFieldNames::mass, - HydroFieldNames::volume, - HydroFieldNames::volume); + HydroFieldNames::volume, + HydroFieldNames::volume); - auto massPolicy = std::make_shared>(true); + auto massPolicy = std::make_shared>(GSPHFieldNames::momentumPolicy,GSPHFieldNames::thermalEnergyPolicy); auto momentumPolicy = std::make_shared>(HydroFieldNames::velocity, IncrementFieldList::prefix() + GSPHFieldNames::momentum); auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); @@ -154,6 +199,32 @@ registerState(DataBase& dataBase, state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); state.enroll(GSPHFieldNames::thermalEnergyPolicy,thermalEnergyPolicy); + switch (mNodeMotionType){ + case NodeMotionType::Eulerian: + { + std::cout <<"Eulerian" << std::endl; + state.enroll(mNodalVelocity); // Eulerian + } + break; + case NodeMotionType::Lagrangian: + { + std::cout <<"Lagrangian" << std::endl; + auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::velocity,HydroFieldNames::velocity); + state.enroll(mNodalVelocity, nodalVelocityPolicy); + } + break; + case NodeMotionType::XSPH: + { + std::cout <<"XSPH" << std::endl; + auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::XSPHDeltaV); + state.enroll(mNodalVelocity, nodalVelocityPolicy); + } + break; + default: + std::cout <<"default" << std::endl; + break; + } + // normal state variables state.enroll(mass, massPolicy); state.enroll(massDensity, rhoPolicy); diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 373f0ae8e..72228011e 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -1,9 +1,29 @@ //---------------------------------Spheral++----------------------------------// -// MFVHydroBase -- spheralized verions of "Meshless Finite Mass" +// MFVHydroBase -- This is an Arbitrary Eulerian-Lagrangian extension of the +// MFV approach of Hopkins 2015. Its got several node-motion +// approaches which promote more regular particle distributions. +// +// Each of the ALE options defines the velocity of the nodes +// differently then the flux then results from the difference +// between the nodes velocities and the fluid velocity. +// The velocities are defined as follows for the +// NodeMotionTypes: +// +// 1) Eulerian ---- static Nodes +// 2) Lagrangian -- nodal velocity = fluid velocity. (This is +// a spheralized version of MFV so there +// is some flux between nodes) +// 3) Fician ------ nodal velocity = fluid velocity + Fician +// PST correction +// 4) XSPH -------- nodal velocity = xsph velocity +// 5) BackgroundPressure -- nodal acceleration = fluid +// acceleration + Background pressure +// force to drive regularization. +// // Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic // Simulation Methods," MNRAS, 450(1):53-110 // -// J.M. Pearl 2022 +// J.M. Pearl 2023 //----------------------------------------------------------------------------// #ifndef __Spheral_MFVHydroBase_hh__ @@ -15,6 +35,14 @@ namespace Spheral { +enum class NodeMotionType { + Lagrangian = 0, + Eulerian = 1, + Fician = 2, + XSPH = 3, + BackgroundPressure = 4, +}; + template class State; template class StateDerivatives; template class SmoothingScaleBase; @@ -51,6 +79,7 @@ public: const bool evolveTotalEnergy, const bool XSPH, const bool correctVelocityGradient, + const NodeMotionType nodeMotionType, const GradientType gradType, const MassDensityType densityUpdate, const HEvolutionType HUpdate, @@ -123,6 +152,10 @@ public: void enforceBoundaries(State& state, StateDerivatives& derivs) override; + NodeMotionType nodeMotionType() const; + void nodeMotionType(NodeMotionType x); + + const FieldList& nodalVelocity() const; const FieldList& DmassDt() const; const FieldList& DthermalEnergyDt() const; const FieldList& DmomentumDt() const; @@ -135,6 +168,10 @@ public: virtual void restoreState(const FileIO& file, const std::string& pathName) override; //**************************************************************************** private: + + NodeMotionType mNodeMotionType; + + FieldList mNodalVelocity; FieldList mDmassDt; FieldList mDthermalEnergyDt; FieldList mDmomentumDt; diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index 8fd7c4d77..c57d788b3 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -1,7 +1,36 @@ namespace Spheral { + + +//------------------------------------------------------------------------------ +// set/get mesh motion type +//------------------------------------------------------------------------------ +template +inline +NodeMotionType +MFVHydroBase:: +nodeMotionType() const { + return mNodeMotionType; +} + +template +inline +void +MFVHydroBase:: +nodeMotionType(NodeMotionType x) { + mNodeMotionType=x; +} + //------------------------------------------------------------------------------ // The internal state field lists. //------------------------------------------------------------------------------ +template +inline +const FieldList& +MFVHydroBase:: +nodalVelocity() const { + return mNodalVelocity; +} + template inline const FieldList& diff --git a/src/GSPH/Policies/ALEPositionPolicy.cc b/src/GSPH/Policies/ALEPositionPolicy.cc new file mode 100644 index 000000000..f349e37cd --- /dev/null +++ b/src/GSPH/Policies/ALEPositionPolicy.cc @@ -0,0 +1,91 @@ +//---------------------------------Spheral++----------------------------------// +// ALEPositionPolicy -- This is basically a direct copy of the standard +// position policy but instead we're substituting in +// the nodal velocity as the derivative. +// +// J. M. Pearl 2023 +//----------------------------------------------------------------------------// + +#include "ALEPositionPolicy.hh" +#include "GSPH/GSPHFieldNames.hh" +#include "NodeList/FluidNodeList.hh" +#include "DataBase/FieldListUpdatePolicyBase.hh" +#include "DataBase/IncrementFieldList.hh" +#include "DataBase/ReplaceState.hh" +#include "DataBase/State.hh" +#include "DataBase/StateDerivatives.hh" +#include "Field/FieldList.hh" +#include "Utilities/DBC.hh" +#include "Geometry/Dimension.hh" + +namespace Spheral { + + +//------------------------------------------------------------------------------ +// Constructor. +//------------------------------------------------------------------------------ +template +ALEPositionPolicy:: +ALEPositionPolicy(): + IncrementFieldList() { +} + +//------------------------------------------------------------------------------ +// Destructor. +//------------------------------------------------------------------------------ +template +ALEPositionPolicy:: +~ALEPositionPolicy() { +} + +//------------------------------------------------------------------------------ +// Update the field. +//------------------------------------------------------------------------------ +template +void +ALEPositionPolicy:: +update(const KeyType& key, + State& state, + StateDerivatives& /*derivs*/, + const double multiplier, + const double /*t*/, + const double /*dt*/) { + KeyType fieldKey, nodeListKey; + StateBase::splitFieldKey(key, fieldKey, nodeListKey); + REQUIRE(fieldKey == HydroFieldNames::position and + nodeListKey == UpdatePolicyBase::wildcard()); + auto r = state.fields(fieldKey, Vector::zero); + const auto numFields = r.numFields(); + + // Get the velocity and acceleration fields. + const auto vel = state.fields(GSPHFieldNames::nodalVelocity, Vector::zero); + + std::cout << "ALE POSITION UPDATE" << std::endl; + // Walk the fields. + for (auto i = 0u; i != numFields; ++i) { + const auto n = r[i]->numInternalElements(); + for (auto j = 0u; j < n; ++j) { + r(i,j) += multiplier*vel(i,j); + } + } +} + +//------------------------------------------------------------------------------ +// Equivalence operator. +//------------------------------------------------------------------------------ +template +bool +ALEPositionPolicy:: +operator==(const UpdatePolicyBase& rhs) const { + + // We're only equal if the other guy is also an increment operator. + const ALEPositionPolicy* rhsPtr = dynamic_cast*>(&rhs); + if (rhsPtr == 0) { + return false; + } else { + return true; + } +} + +} + diff --git a/src/GSPH/Policies/ALEPositionPolicy.hh b/src/GSPH/Policies/ALEPositionPolicy.hh new file mode 100644 index 000000000..d85f8a8d7 --- /dev/null +++ b/src/GSPH/Policies/ALEPositionPolicy.hh @@ -0,0 +1,63 @@ +//---------------------------------Spheral++----------------------------------// +// ALEPositionPolicy -- This is basically a direct copy of the standard +// position policy but instead we're substituting in +// the nodal velocity as the derivative. +// +// J. M. Pearl 2023 +//----------------------------------------------------------------------------// +#ifndef __Spheral_ALEPositionPolicy_hh__ +#define __Spheral_ALEPositionPolicy_hh__ + +#include "DataBase/IncrementFieldList.hh" + +#include + +namespace Spheral { + +// Forward declarations. +template class State; +template class StateDerivatives; +template class FluidNodeList; +template class FieldList; + +template +class ALEPositionPolicy: + public IncrementFieldList { +public: + //--------------------------- Public Interface ---------------------------// + // Useful typedefs + typedef typename Dimension::Scalar Scalar; + typedef typename Dimension::Vector Vector; + typedef typename FieldListUpdatePolicyBase::KeyType KeyType; + + // Constructors, destructor. + ALEPositionPolicy(); + virtual ~ALEPositionPolicy(); + + // Overload the methods describing how to update Fields. + virtual void update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt); + + // Equivalence. + virtual bool operator==(const UpdatePolicyBase& rhs) const; + +private: + //--------------------------- Private Interface ---------------------------// + ALEPositionPolicy(const ALEPositionPolicy& rhs); + ALEPositionPolicy& operator=(const ALEPositionPolicy& rhs); +}; + +} + +#else + +// Forward declaration. +namespace Spheral { + template class ALEPositionPolicy; +} + +#endif diff --git a/src/GSPH/Policies/ALEPositionPolicyInst.cc.py b/src/GSPH/Policies/ALEPositionPolicyInst.cc.py new file mode 100644 index 000000000..a7f765ea6 --- /dev/null +++ b/src/GSPH/Policies/ALEPositionPolicyInst.cc.py @@ -0,0 +1,11 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "GSPH/Policies/ALEPositionPolicy.cc" +#include "Geometry/Dimension.hh" + +namespace Spheral { + template class ALEPositionPolicy >; +} +""" diff --git a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.cc b/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.cc new file mode 100644 index 000000000..037c307b1 --- /dev/null +++ b/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.cc @@ -0,0 +1,178 @@ +//---------------------------------Spheral++----------------------------------// +// CompatibleMFVSpecificThermalEnergyPolicy -- An implementation of +// UpdatePolicyBase specialized for the updating the specific thermal energy +// as a dependent quantity. +// +// This version is specialized for materials with different properties. A +// compatible energy discretization in which pairwise work allows for opposite +// sign pair-wise work. DepsDti and DepsDtj are used as weights and the +// difference between the conservative and consistent formulations is added +// back in. +//----------------------------------------------------------------------------// +#include "Hydro/CompatibleMFVSpecificThermalEnergyPolicy.hh" +#include "Hydro/HydroFieldNames.hh" +#include "NodeList/NodeList.hh" +#include "NodeList/FluidNodeList.hh" +#include "DataBase/DataBase.hh" +#include "DataBase/FieldUpdatePolicyBase.hh" +#include "DataBase/IncrementFieldList.hh" +#include "DataBase/ReplaceState.hh" +#include "DataBase/State.hh" +#include "DataBase/StateDerivatives.hh" +#include "Neighbor/ConnectivityMap.hh" +#include "Field/Field.hh" +#include "Field/FieldList.hh" +#include "Utilities/DBC.hh" +#include "Utilities/safeInv.hh" +#include "Utilities/SpheralFunctions.hh" + +#include +#include +using std::vector; +using std::numeric_limits; +using std::abs; +using std::min; +using std::max; + +namespace Spheral { + +//------------------------------------------------------------------------------ +// Constructor. +//------------------------------------------------------------------------------ +template +CompatibleMFVSpecificThermalEnergyPolicy:: +CompatibleMFVSpecificThermalEnergyPolicy(const DataBase& dataBase): + IncrementFieldList(), + mDataBasePtr(&dataBase) { +} + +//------------------------------------------------------------------------------ +// Destructor. +//------------------------------------------------------------------------------ +template +CompatibleMFVSpecificThermalEnergyPolicy:: +~CompatibleMFVSpecificThermalEnergyPolicy() { +} + +//------------------------------------------------------------------------------ +// Update the field. +//------------------------------------------------------------------------------ +template +void +CompatibleMFVSpecificThermalEnergyPolicy:: +update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double /*t*/, + const double /*dt*/) { + + KeyType fieldKey, nodeListKey; + StateBase::splitFieldKey(key, fieldKey, nodeListKey); + REQUIRE(fieldKey == HydroFieldNames::specificThermalEnergy and + nodeListKey == UpdatePolicyBase::wildcard()); + auto eps = state.fields(fieldKey, Scalar()); + const auto numFields = eps.numFields(); + + // constant we'll need for the weighting scheme + const auto tiny = numeric_limits::epsilon(); + + // Get the state fields. + const auto mass = state.fields(HydroFieldNames::mass, Scalar()); + const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); + const auto acceleration = derivs.fields(HydroFieldNames::hydroAcceleration, Vector::zero); + const auto& pairAccelerations = derivs.getAny(HydroFieldNames::pairAccelerations, vector()); + const auto& pairDepsDt = derivs.getAny(HydroFieldNames::pairWork, vector()); + const auto& connectivityMap = mDataBasePtr->connectivityMap(); + const auto& pairs = connectivityMap.nodePairList(); + const auto npairs = pairs.size(); + + CHECK(pairAccelerations.size() == npairs); + CHECK(pairDepsDt.size() == 2*npairs); + + auto DepsDt = derivs.fields(IncrementFieldList >::prefix() + GSPHFieldNames::thermalEnergy, 0.0); + DepsDt.Zero(); + + const auto hdt = 0.5*multiplier; + + // Walk all pairs and figure out the discrete work for each point +#pragma omp parallel + { + // Thread private variables + auto DepsDt_thread = DepsDt.threadCopy(); + +#pragma omp for + for (auto kk = 0u; kk < npairs; ++kk) { + const auto i = pairs[kk].i_node; + const auto j = pairs[kk].j_node; + const auto nodeListi = pairs[kk].i_list; + const auto nodeListj = pairs[kk].j_list; + + const auto& paccij = pairAccelerations[kk]; + const auto& DepsDt0i = pairDepsDt[2*kk]; + const auto& DepsDt0j = pairDepsDt[2*kk+1]; + + const auto mi = mass(nodeListi, i); + const auto& vi = velocity(nodeListi, i); + const auto& ai = acceleration(nodeListi, i); + + const auto mj = mass(nodeListj, j); + const auto& vj = velocity(nodeListj, j); + const auto& aj = acceleration(nodeListj, j); + + // half-step velocity + const auto vi12 = vi + ai*hdt; + const auto vj12 = vj + aj*hdt; + const auto vij = vi12 - vj12; + + // weighting scheme + const auto weighti = abs(DepsDt0i) + tiny; + const auto weightj = abs(DepsDt0j) + tiny; + const auto wi = weighti/(weighti+weightj); + + // difference between assessed derivs and conserative ones + const Scalar delta_duij = vij.dot(paccij)-DepsDt0i-DepsDt0j; + + CHECK(wi >= 0.0 and wi <= 1.0); + + // make conservative + DepsDt_thread(nodeListi, i) += mj*(wi*delta_duij+DepsDt0i); + DepsDt_thread(nodeListj, j) += mi*((1.0-wi)*delta_duij+DepsDt0j); + + } + +#pragma omp critical + { + DepsDt_thread.threadReduce(); + } + } + + // Now we can update the energy. + for (auto nodeListi = 0u; nodeListi < numFields; ++nodeListi) { + const auto n = eps[nodeListi]->numInternalElements(); +#pragma omp parallel for + for (auto i = 0u; i < n; ++i) { + eps(nodeListi, i) += DepsDt(nodeListi, i)*multiplier; + } + } +} + +//------------------------------------------------------------------------------ +// Equivalence operator. +//------------------------------------------------------------------------------ +template +bool +CompatibleMFVSpecificThermalEnergyPolicy:: +operator==(const UpdatePolicyBase& rhs) const { + + // We're only equal if the other guy is also an increment operator. + const CompatibleMFVSpecificThermalEnergyPolicy* rhsPtr = dynamic_cast*>(&rhs); + if (rhsPtr == 0) { + return false; + } else { + return true; + } +} + +} + diff --git a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.hh b/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.hh new file mode 100644 index 000000000..abd1b296c --- /dev/null +++ b/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.hh @@ -0,0 +1,84 @@ +//---------------------------------Spheral++----------------------------------// +// CompatibleDifferenceSpecificThermalEnergyPolicy -- An implementation of +// UpdatePolicyBase specialized for the updating the specific thermal energy +// as a dependent quantity. +// +// This version is specialized for the compatible energy discretization +// method. +//----------------------------------------------------------------------------// + +#ifndef __Spheral_CompatibleDifferenceSpecificThermalEnergyPolicy_hh__ +#define __Spheral_CompatibleDifferenceSpecificThermalEnergyPolicy_hh__ + +#include "DataBase/IncrementFieldList.hh" + +#include + +namespace Spheral { + +// Forward declarations. +template class State; +template class StateDerivatives; +template class FluidNodeList; +template class FieldList; +template class DataBase; + +template +class CompatibleDifferenceSpecificThermalEnergyPolicy: + public IncrementFieldList { +public: + //--------------------------- Public Interface ---------------------------// + // Useful typedefs + typedef typename Dimension::Scalar Scalar; + typedef typename Dimension::Vector Vector; + typedef typename FieldListUpdatePolicyBase::KeyType KeyType; + + // Constructors, destructor. + CompatibleDifferenceSpecificThermalEnergyPolicy(const DataBase& db); + virtual ~CompatibleDifferenceSpecificThermalEnergyPolicy(); + + // Overload the methods describing how to update Fields. + virtual void update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt); + + // If the derivative stored values for the pair-accelerations has not been updated, + // we need to just time advance normally. + virtual void updateAsIncrement(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt) { + IncrementFieldList::update(key, + state, + derivs, + multiplier, + t, + dt); + } + + // Equivalence. + virtual bool operator==(const UpdatePolicyBase& rhs) const; + +private: + //--------------------------- Private Interface ---------------------------// + const DataBase* mDataBasePtr; + + CompatibleDifferenceSpecificThermalEnergyPolicy(const CompatibleDifferenceSpecificThermalEnergyPolicy& rhs); + CompatibleDifferenceSpecificThermalEnergyPolicy& operator=(const CompatibleDifferenceSpecificThermalEnergyPolicy& rhs); +}; + +} + +#else + +// Forward declaration. +namespace Spheral { + template class CompatibleDifferenceSpecificThermalEnergyPolicy; +} + +#endif diff --git a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicyInst.cc.py b/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicyInst.cc.py new file mode 100644 index 000000000..bf94269cd --- /dev/null +++ b/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicyInst.cc.py @@ -0,0 +1,11 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "Geometry/Dimension.hh" +#include "Hydro/CompatibleMFVSpecificThermalEnergyPolicy.cc" + +namespace Spheral { + template class CompatibleMFVSpecificThermalEnergyPolicy >; +} +""" diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc index db60d636e..bf1f0d79d 100644 --- a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc +++ b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc @@ -1,6 +1,6 @@ //---------------------------------Spheral++----------------------------------// -// IncrementSpecificFromTotalPolicy -- replaces one fieldlist with the ratio of two -// fieldlists from the state. +// IncrementSpecificFromTotalPolicy -- replaces one fieldlist with the ratio +// of two fieldlists from the state. // // J.M. Pearl 2022 //----------------------------------------------------------------------------// @@ -23,7 +23,7 @@ namespace Spheral { template IncrementSpecificFromTotalPolicy:: IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivsKey): - FieldListUpdatePolicyBase(HydroFieldNames::mass), + FieldListUpdatePolicyBase(), mStateKey(stateKey), mDerivativeKey(derivsKey){ } @@ -31,7 +31,7 @@ IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& template IncrementSpecificFromTotalPolicy:: IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivsKey, const std::string& depend0): - FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0), + FieldListUpdatePolicyBase(depend0), mStateKey(stateKey), mDerivativeKey(derivsKey) { } @@ -42,7 +42,7 @@ IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivsKey, const std::string& depend0, const std::string& depend1): - FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1), + FieldListUpdatePolicyBase(depend0, depend1), mStateKey(stateKey), mDerivativeKey(derivsKey) { } @@ -54,7 +54,7 @@ IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& depend0, const std::string& depend1, const std::string& depend2): - FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1, depend2), + FieldListUpdatePolicyBase(depend0, depend1, depend2), mStateKey(stateKey), mDerivativeKey(derivsKey){ } @@ -67,7 +67,7 @@ IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& depend1, const std::string& depend2, const std::string& depend3): - FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1, depend2, depend3), + FieldListUpdatePolicyBase(depend0, depend1, depend2, depend3), mStateKey(stateKey), mDerivativeKey(derivsKey){ } @@ -81,7 +81,7 @@ IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& depend2, const std::string& depend3, const std::string& depend4): - FieldListUpdatePolicyBase(HydroFieldNames::mass, depend0, depend1, depend2, depend3, depend4), + FieldListUpdatePolicyBase(depend0, depend1, depend2, depend3, depend4), mStateKey(stateKey), mDerivativeKey(derivsKey){ } @@ -107,7 +107,7 @@ update(const KeyType& /*key*/, const double t, const double dt) { - const auto tiny = std::numeric_limits::epsilon(); + //const auto tiny = std::numeric_limits::epsilon(); const auto m = state.fields(HydroFieldNames::mass, Scalar()); auto q = state.fields(mStateKey, Value()); @@ -115,21 +115,14 @@ update(const KeyType& /*key*/, const auto DmDt = derivs.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, Scalar()); const auto DQDt = derivs.fields(mDerivativeKey, Value()); - - // Get the field name portion of the key. - //KeyType fieldKey, nodeListKey; - //StateBase::splitFieldKey(key, fieldKey, nodeListKey); - //CHECK(nodeListKey == UpdatePolicyBase::wildcard()); - - // Find the matching replacement FieldList from the StateDerivatives. - //FieldList f = state.fields(fieldKey, Value()); - // Loop over the internal values of the field. const unsigned numNodeLists = q.size(); for (unsigned k = 0; k != numNodeLists; ++k) { const unsigned n = q[k]->numInternalElements(); for (unsigned i = 0; i != n; ++i) { - q(k, i) += (DQDt(k, i) - DmDt(k, i)*q(k, i)) * multiplier/ (m(k,i)+DmDt(k,i)*multiplier); + //const auto m1 = m(k,i)+DmDt(k,i)*multiplier; + //q(k, i) = (DQDt(k, i) * multiplier + m(k,i)*q(k, i))*safeInv(m1); + q(k, i) += (DQDt(k, i) - DmDt(k, i)*q(k, i)) * multiplier * safeInv(m(k,i)+DmDt(k,i)*multiplier); } } } diff --git a/src/GSPH/Policies/MassFluxPolicy.cc b/src/GSPH/Policies/MassFluxPolicy.cc new file mode 100644 index 000000000..ffedc5df2 --- /dev/null +++ b/src/GSPH/Policies/MassFluxPolicy.cc @@ -0,0 +1,128 @@ +//---------------------------------Spheral++----------------------------------// +// MassFluxPolicy -- This is basically a direct copy of the standard +// position policy but instead we're substituting in +// the nodal velocity as the derivative. +// +// J. M. Pearl 2023 +//----------------------------------------------------------------------------// + +#include "MassFluxPolicy.hh" +#include "Hydro/HydroFieldNames.hh" +#include "NodeList/FluidNodeList.hh" +#include "DataBase/FieldListUpdatePolicyBase.hh" +#include "DataBase/IncrementFieldList.hh" +#include "DataBase/ReplaceState.hh" +#include "DataBase/State.hh" +#include "DataBase/StateDerivatives.hh" +#include "Field/FieldList.hh" +#include "Utilities/DBC.hh" +#include "Geometry/Dimension.hh" + +namespace Spheral { + + +//------------------------------------------------------------------------------ +// Constructor. +//------------------------------------------------------------------------------ +template +MassFluxPolicy:: +MassFluxPolicy(): + IncrementFieldList() { +} + +template +MassFluxPolicy:: +MassFluxPolicy(const std::string& depend0): + IncrementFieldList(depend0) { +} + +template +MassFluxPolicy:: +MassFluxPolicy(const std::string& depend0,const std::string& depend1): + IncrementFieldList(depend0,depend1) { +} + +template +MassFluxPolicy:: +MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2): + IncrementFieldList(depend0,depend1,depend2) { +} + +template +MassFluxPolicy:: +MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2,const std::string& depend3): + IncrementFieldList(depend0,depend1,depend2,depend3) { +} + +template +MassFluxPolicy:: +MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2,const std::string& depend3,const std::string& depend4): + IncrementFieldList(depend0,depend1,depend2,depend3,depend4) { +} + +template +MassFluxPolicy:: +MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2,const std::string& depend3,const std::string& depend4,const std::string& depend5): + IncrementFieldList(depend0,depend1,depend2,depend3,depend4,depend5) { +} + +//------------------------------------------------------------------------------ +// Destructor. +//------------------------------------------------------------------------------ +template +MassFluxPolicy:: +~MassFluxPolicy() { +} + +//------------------------------------------------------------------------------ +// Update the field. +//------------------------------------------------------------------------------ +template +void +MassFluxPolicy:: +update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double /*t*/, + const double /*dt*/) { + KeyType fieldKey, nodeListKey; + StateBase::splitFieldKey(key, fieldKey, nodeListKey); + REQUIRE(fieldKey == HydroFieldNames::mass and + nodeListKey == UpdatePolicyBase::wildcard()); + + // state + auto m = state.fields(fieldKey, 0.0); + const auto numFields = m.numFields(); + + // deriv + const auto dmdt = derivs.fields(IncrementFieldList::prefix() + fieldKey, 0.0); + + // Walk the fields. + for (auto i = 0u; i != numFields; ++i) { + const auto n = m[i]->numInternalElements(); + for (auto j = 0u; j < n; ++j) { + m(i,j) += std::max(multiplier*dmdt(i,j),-m(i,j)); + } + } +} + +//------------------------------------------------------------------------------ +// Equivalence operator. +//------------------------------------------------------------------------------ +template +bool +MassFluxPolicy:: +operator==(const UpdatePolicyBase& rhs) const { + + // We're only equal if the other guy is also an increment operator. + const MassFluxPolicy* rhsPtr = dynamic_cast*>(&rhs); + if (rhsPtr == 0) { + return false; + } else { + return true; + } +} + +} + diff --git a/src/GSPH/Policies/MassFluxPolicy.hh b/src/GSPH/Policies/MassFluxPolicy.hh new file mode 100644 index 000000000..8231a4c6c --- /dev/null +++ b/src/GSPH/Policies/MassFluxPolicy.hh @@ -0,0 +1,69 @@ +//---------------------------------Spheral++----------------------------------// +// MassFluxPolicy -- This is basically a direct copy of the standard +// position policy but instead we're substituting in +// the nodal velocity as the derivative. +// +// J. M. Pearl 2023 +//----------------------------------------------------------------------------// +#ifndef __Spheral_MassFluxPolicy_hh__ +#define __Spheral_MassFluxPolicy_hh__ + +#include "DataBase/IncrementFieldList.hh" + +#include + +namespace Spheral { + +// Forward declarations. +template class State; +template class StateDerivatives; +template class FluidNodeList; +template class FieldList; + +template +class MassFluxPolicy: + public IncrementFieldList { +public: + //--------------------------- Public Interface ---------------------------// + // Useful typedefs + typedef typename Dimension::Scalar Scalar; + typedef typename Dimension::Vector Vector; + typedef typename FieldListUpdatePolicyBase::KeyType KeyType; + + // Constructors, destructor. + MassFluxPolicy(); + MassFluxPolicy(const std::string& depend0); + MassFluxPolicy(const std::string& depend0,const std::string& depend1); + MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2); + MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2,const std::string& depend3); + MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2,const std::string& depend3,const std::string& depend4); + MassFluxPolicy(const std::string& depend0,const std::string& depend1,const std::string& depend2,const std::string& depend3,const std::string& depend4,const std::string& depend5); + virtual ~MassFluxPolicy(); + + // Overload the methods describing how to update Fields. + virtual void update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt); + + // Equivalence. + virtual bool operator==(const UpdatePolicyBase& rhs) const; + +private: + //--------------------------- Private Interface ---------------------------// + MassFluxPolicy(const MassFluxPolicy& rhs); + MassFluxPolicy& operator=(const MassFluxPolicy& rhs); +}; + +} + +#else + +// Forward declaration. +namespace Spheral { + template class MassFluxPolicy; +} + +#endif diff --git a/src/GSPH/Policies/MassFluxPolicyInst.cc.py b/src/GSPH/Policies/MassFluxPolicyInst.cc.py new file mode 100644 index 000000000..79a4346cb --- /dev/null +++ b/src/GSPH/Policies/MassFluxPolicyInst.cc.py @@ -0,0 +1,11 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "GSPH/Policies/MassFluxPolicy.cc" +#include "Geometry/Dimension.hh" + +namespace Spheral { + template class MassFluxPolicy >; +} +""" diff --git a/src/GSPH/Policies/PureReplaceFieldList.cc b/src/GSPH/Policies/PureReplaceFieldList.cc index 071f88175..bb054af95 100644 --- a/src/GSPH/Policies/PureReplaceFieldList.cc +++ b/src/GSPH/Policies/PureReplaceFieldList.cc @@ -115,6 +115,8 @@ update(const KeyType& key, // Find the matching replacement FieldList from the StateDerivatives. FieldList f = state.fields(fieldKey, Value()); + + // field we're replacing it with const FieldList df = derivs.fields(mReplaceKey, Value()); CHECK(f.size() == df.size()); diff --git a/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc b/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc index b00aba09e..e34a08934 100644 --- a/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc +++ b/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc @@ -1,12 +1,12 @@ //---------------------------------Spheral++----------------------------------// -// CompatibleDifferenceSpecificThermalEnergyPolicy -- An implementation of UpdatePolicyBase -// specialized for the updating the specific thermal energy as a dependent -// quantity. +// CompatibleDifferenceSpecificThermalEnergyPolicy -- An implementation of +// UpdatePolicyBase specialized for the updating the specific thermal energy +// as a dependent quantity. // // This version is specialized for materials with different properties. A // compatible energy discretization in which pairwise work allows for opposite // sign pair-wise work. DepsDti and DepsDtj are used as weights and the -// difference between the conservative and consistent formulations is added +// difference between the conservative and consistent formulations is added // back in. //----------------------------------------------------------------------------// #include "Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.hh" diff --git a/src/PYB11/GSPH/GSPH_PYB11.py b/src/PYB11/GSPH/GSPH_PYB11.py index e3c498c04..f753cae9b 100644 --- a/src/PYB11/GSPH/GSPH_PYB11.py +++ b/src/PYB11/GSPH/GSPH_PYB11.py @@ -34,6 +34,7 @@ '"GSPH/Limiters/VanAlbaLimiter.hh"', '"GSPH/Limiters/SuperbeeLimiter.hh"', '"GSPH/Limiters/OspreLimiter.hh"', + '"GSPH/Limiters/BarthJespersenLimiter.hh"', '"GSPH/RiemannSolvers/RiemannSolverBase.hh"', '"GSPH/RiemannSolvers/HLLC.hh"', '"GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh"', @@ -55,6 +56,12 @@ "SPHUncorrectedGradient", "NoGradient"), export_values = True) +NodeMotionType = PYB11enum(("Lagrangian", + "Eulerian", + "Fician", + "XSPH", + "BackgroundPressure"), export_values = False) + #------------------------------------------------------------------------------- # Instantiate our types #------------------------------------------------------------------------------- @@ -74,6 +81,7 @@ VanAlbaLimiter%(ndim)id = PYB11TemplateClass(VanAlbaLimiter, template_parameters="%(Dimension)s") SuperbeeLimiter%(ndim)id = PYB11TemplateClass(SuperbeeLimiter, template_parameters="%(Dimension)s") OspreLimiter%(ndim)id = PYB11TemplateClass(OspreLimiter, template_parameters="%(Dimension)s") +BarthJespersenLimiter%(ndim)id = PYB11TemplateClass(BarthJespersenLimiter, template_parameters="%(Dimension)s") RiemannSolverBase%(ndim)id = PYB11TemplateClass(RiemannSolverBase, template_parameters="%(Dimension)s") HLLC%(ndim)id = PYB11TemplateClass(HLLC, template_parameters="%(Dimension)s") SecondOrderArtificialViscosity%(ndim)id = PYB11TemplateClass(SecondOrderArtificialViscosity, template_parameters="%(Dimension)s") diff --git a/src/PYB11/GSPH/Limiters.py b/src/PYB11/GSPH/Limiters.py index d2cb8d647..b3e85d8f8 100644 --- a/src/PYB11/GSPH/Limiters.py +++ b/src/PYB11/GSPH/Limiters.py @@ -177,4 +177,32 @@ def fluxLimiter(self, "slope limiter from flux limiter." return "Scalar" +#------------------------------------------------------------------------------- +# Barth Jespersen limiter +#------------------------------------------------------------------------------- +@PYB11template("Dimension") +@PYB11module("SpheralGSPH") +class BarthJespersenLimiter(LimiterBase): + + PYB11typedefs = """ + typedef typename %(Dimension)s::Scalar Scalar; + """ + + def pyinit(): + "Barth Jespersen slope limiter constructor" + + @PYB11virtual + @PYB11const + def slopeLimiter(self, + x = "const Scalar"): + "slope limiter from flux limiter." + return "Scalar" + + @PYB11virtual + @PYB11const + def fluxLimiter(self, + x = "const Scalar"): + "slope limiter from flux limiter." + return "Scalar" + diff --git a/src/PYB11/GSPH/MFVHydroBase.py b/src/PYB11/GSPH/MFVHydroBase.py index 71aee15b1..175c79e4a 100644 --- a/src/PYB11/GSPH/MFVHydroBase.py +++ b/src/PYB11/GSPH/MFVHydroBase.py @@ -29,6 +29,7 @@ def pyinit(smoothingScaleMethod = "const SmoothingScaleBase<%(Dimension)s>&", evolveTotalEnergy = "const bool", XSPH = "const bool", correctVelocityGradient = "const bool", + nodeMotionType = "const NodeMotionType", gradType = "const GradientType", densityUpdate = "const MassDensityType", HUpdate = "const HEvolutionType", @@ -109,7 +110,7 @@ def enforceBoundaries(state = "State<%(Dimension)s>&", return "void" DvolumeDt = PYB11property("const FieldList<%(Dimension)s, Scalar>&", "DvolumeDt", returnpolicy="reference_internal") - + nodeMotionType = PYB11property("NodeMotionType","nodeMotionType","nodeMotionType") #------------------------------------------------------------------------------- # Inject methods #------------------------------------------------------------------------------- From 792f868ddeccec84f1ab0c6fcbd7cd87f4f4bbad Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Wed, 9 Aug 2023 22:43:40 -0700 Subject: [PATCH 32/60] generalized compatible energy scheme when there's some fluxing going on --- ...mpatibleMFVSpecificThermalEnergyPolicy.cc} | 59 +++++++++++++------ ...mpatibleMFVSpecificThermalEnergyPolicy.hh} | 18 +++--- ...eMFVSpecificThermalEnergyPolicyInst.cc.py} | 2 +- 3 files changed, 50 insertions(+), 29 deletions(-) rename src/GSPH/Policies/{CompatibleALESpecificThermalEnergyPolicy.cc => CompatibleMFVSpecificThermalEnergyPolicy.cc} (72%) rename src/GSPH/Policies/{CompatibleALESpecificThermalEnergyPolicy.hh => CompatibleMFVSpecificThermalEnergyPolicy.hh} (77%) rename src/GSPH/Policies/{CompatibleALESpecificThermalEnergyPolicyInst.cc.py => CompatibleMFVSpecificThermalEnergyPolicyInst.cc.py} (83%) diff --git a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.cc b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc similarity index 72% rename from src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.cc rename to src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc index 037c307b1..3c2ec5d44 100644 --- a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.cc +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc @@ -9,7 +9,8 @@ // difference between the conservative and consistent formulations is added // back in. //----------------------------------------------------------------------------// -#include "Hydro/CompatibleMFVSpecificThermalEnergyPolicy.hh" +#include "GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh" +#include "GSPH/GSPHFieldNames.hh" #include "Hydro/HydroFieldNames.hh" #include "NodeList/NodeList.hh" #include "NodeList/FluidNodeList.hh" @@ -80,17 +81,21 @@ update(const KeyType& key, // Get the state fields. const auto mass = state.fields(HydroFieldNames::mass, Scalar()); const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); - const auto acceleration = derivs.fields(HydroFieldNames::hydroAcceleration, Vector::zero); + const auto DmassDt = derivs.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, 0.0); + const auto DmomentumDt = derivs.fields(IncrementFieldList::prefix() + GSPHFieldNames::momentum, Vector::zero); const auto& pairAccelerations = derivs.getAny(HydroFieldNames::pairAccelerations, vector()); const auto& pairDepsDt = derivs.getAny(HydroFieldNames::pairWork, vector()); + const auto& pairMassFlux = derivs.getAny(GSPHFieldNames::pairMassFlux, vector()); + const auto& connectivityMap = mDataBasePtr->connectivityMap(); const auto& pairs = connectivityMap.nodePairList(); const auto npairs = pairs.size(); CHECK(pairAccelerations.size() == npairs); + CHECK(pairMassFlux.size() == npairs); CHECK(pairDepsDt.size() == 2*npairs); - auto DepsDt = derivs.fields(IncrementFieldList >::prefix() + GSPHFieldNames::thermalEnergy, 0.0); + auto DepsDt = derivs.fields(IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, 0.0); DepsDt.Zero(); const auto hdt = 0.5*multiplier; @@ -111,33 +116,48 @@ update(const KeyType& key, const auto& paccij = pairAccelerations[kk]; const auto& DepsDt0i = pairDepsDt[2*kk]; const auto& DepsDt0j = pairDepsDt[2*kk+1]; + const auto& massFlux = pairMassFlux[kk]; const auto mi = mass(nodeListi, i); - const auto& vi = velocity(nodeListi, i); - const auto& ai = acceleration(nodeListi, i); + const auto pi = mi*velocity(nodeListi, i); + const auto& DPDti = DmomentumDt(nodeListi, i); + const auto& DmDti = DmassDt(nodeListi,i); const auto mj = mass(nodeListj, j); - const auto& vj = velocity(nodeListj, j); - const auto& aj = acceleration(nodeListj, j); - - // half-step velocity - const auto vi12 = vi + ai*hdt; - const auto vj12 = vj + aj*hdt; - const auto vij = vi12 - vj12; - + const auto pj = mj*velocity(nodeListj, j); + const auto& DPDtj = DmomentumDt(nodeListj, j); + const auto& DmDtj = DmassDt(nodeListj,j); + + // half-step momenta + const auto pi12 = pi + DPDti*hdt; + const auto pj12 = pj + DPDtj*hdt; + //const auto pij = pi12 - pj12; + // weighting scheme const auto weighti = abs(DepsDt0i) + tiny; const auto weightj = abs(DepsDt0j) + tiny; const auto wi = weighti/(weighti+weightj); - // difference between assessed derivs and conserative ones - const Scalar delta_duij = vij.dot(paccij)-DepsDt0i-DepsDt0j; + // safeInv + const auto invmi0 = safeInv(mi); + const auto invmj0 = safeInv(mj); + const auto invmi1 = safeInv(mi+DmDti*multiplier); + const auto invmj1 = safeInv(mj+DmDtj*multiplier); + + const Scalar delta_duij = (pi12*invmi1 - pj12*invmj1).dot(paccij) + + (pj.dot(pj)*invmj0*invmj1 - pi.dot(pi)*invmi0*invmi1) * massFlux*0.5 + - DepsDt0i-DepsDt0j; CHECK(wi >= 0.0 and wi <= 1.0); + CHECK(invmi0 >= 0.0); + CHECK(invmj0 >= 1.0); + + const auto depsi = (wi *delta_duij+DepsDt0i); + const auto depsj = ((1.0-wi)*delta_duij+DepsDt0j); // make conservative - DepsDt_thread(nodeListi, i) += mj*(wi*delta_duij+DepsDt0i); - DepsDt_thread(nodeListj, j) += mi*((1.0-wi)*delta_duij+DepsDt0j); + DepsDt_thread(nodeListi, i) += depsi; + DepsDt_thread(nodeListj, j) += depsj; } @@ -147,12 +167,13 @@ update(const KeyType& key, } } - // Now we can update the energy. +// // Now we can update the energy. for (auto nodeListi = 0u; nodeListi < numFields; ++nodeListi) { const auto n = eps[nodeListi]->numInternalElements(); #pragma omp parallel for for (auto i = 0u; i < n; ++i) { - eps(nodeListi, i) += DepsDt(nodeListi, i)*multiplier; + const auto m1 = mass(nodeListi,i)+DmassDt(nodeListi,i)*multiplier; + if (m1 > tiny) eps(nodeListi, i) += (DepsDt(nodeListi, i) - DmassDt(nodeListi, i)*eps(nodeListi, i)) * multiplier * safeInv(m1); } } } diff --git a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.hh b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh similarity index 77% rename from src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.hh rename to src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh index abd1b296c..5bfe507a8 100644 --- a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicy.hh +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh @@ -1,5 +1,5 @@ //---------------------------------Spheral++----------------------------------// -// CompatibleDifferenceSpecificThermalEnergyPolicy -- An implementation of +// CompatibleMFVSpecificThermalEnergyPolicy -- An implementation of // UpdatePolicyBase specialized for the updating the specific thermal energy // as a dependent quantity. // @@ -7,8 +7,8 @@ // method. //----------------------------------------------------------------------------// -#ifndef __Spheral_CompatibleDifferenceSpecificThermalEnergyPolicy_hh__ -#define __Spheral_CompatibleDifferenceSpecificThermalEnergyPolicy_hh__ +#ifndef __Spheral_CompatibleMFVSpecificThermalEnergyPolicy_hh__ +#define __Spheral_CompatibleMFVSpecificThermalEnergyPolicy_hh__ #include "DataBase/IncrementFieldList.hh" @@ -24,7 +24,7 @@ template class FieldList; template class DataBase; template -class CompatibleDifferenceSpecificThermalEnergyPolicy: +class CompatibleMFVSpecificThermalEnergyPolicy: public IncrementFieldList { public: //--------------------------- Public Interface ---------------------------// @@ -34,8 +34,8 @@ public: typedef typename FieldListUpdatePolicyBase::KeyType KeyType; // Constructors, destructor. - CompatibleDifferenceSpecificThermalEnergyPolicy(const DataBase& db); - virtual ~CompatibleDifferenceSpecificThermalEnergyPolicy(); + CompatibleMFVSpecificThermalEnergyPolicy(const DataBase& db); + virtual ~CompatibleMFVSpecificThermalEnergyPolicy(); // Overload the methods describing how to update Fields. virtual void update(const KeyType& key, @@ -68,8 +68,8 @@ private: //--------------------------- Private Interface ---------------------------// const DataBase* mDataBasePtr; - CompatibleDifferenceSpecificThermalEnergyPolicy(const CompatibleDifferenceSpecificThermalEnergyPolicy& rhs); - CompatibleDifferenceSpecificThermalEnergyPolicy& operator=(const CompatibleDifferenceSpecificThermalEnergyPolicy& rhs); + CompatibleMFVSpecificThermalEnergyPolicy(const CompatibleMFVSpecificThermalEnergyPolicy& rhs); + CompatibleMFVSpecificThermalEnergyPolicy& operator=(const CompatibleMFVSpecificThermalEnergyPolicy& rhs); }; } @@ -78,7 +78,7 @@ private: // Forward declaration. namespace Spheral { - template class CompatibleDifferenceSpecificThermalEnergyPolicy; + template class CompatibleMFVSpecificThermalEnergyPolicy; } #endif diff --git a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicyInst.cc.py b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicyInst.cc.py similarity index 83% rename from src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicyInst.cc.py rename to src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicyInst.cc.py index bf94269cd..2559684fc 100644 --- a/src/GSPH/Policies/CompatibleALESpecificThermalEnergyPolicyInst.cc.py +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicyInst.cc.py @@ -3,7 +3,7 @@ // Explicit instantiation. //------------------------------------------------------------------------------ #include "Geometry/Dimension.hh" -#include "Hydro/CompatibleMFVSpecificThermalEnergyPolicy.cc" +#include "GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc" namespace Spheral { template class CompatibleMFVSpecificThermalEnergyPolicy >; From df6d91f69f71c8a8c31fb8bafa38a2411bca913b Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Wed, 9 Aug 2023 22:44:30 -0700 Subject: [PATCH 33/60] typo was causing unecessary template case to get built upon compilation --- src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc b/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc index e34a08934..899001e82 100644 --- a/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc +++ b/src/Hydro/CompatibleDifferenceSpecificThermalEnergyPolicy.cc @@ -90,7 +90,7 @@ update(const KeyType& key, CHECK(pairAccelerations.size() == npairs); CHECK(pairDepsDt.size() == 2*npairs); - auto DepsDt = derivs.fields(IncrementFieldList >::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); + auto DepsDt = derivs.fields(IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); DepsDt.Zero(); const auto hdt = 0.5*multiplier; From d90a4dbd84db0e888a2f8d4387b6bd579d24c8ec Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Wed, 9 Aug 2023 22:45:30 -0700 Subject: [PATCH 34/60] generalize HLLC zero check --- src/GSPH/RiemannSolvers/HLLC.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GSPH/RiemannSolvers/HLLC.cc b/src/GSPH/RiemannSolvers/HLLC.cc index ad1982f01..1db5b4b54 100644 --- a/src/GSPH/RiemannSolvers/HLLC.cc +++ b/src/GSPH/RiemannSolvers/HLLC.cc @@ -82,7 +82,7 @@ interfaceState(const typename Dimension::Vector& ri, rhostari = rhoi; rhostarj = rhoj; - if (ci > tiny or cj > tiny){ + if (rhoi*ci > tiny or rhoj*cj > tiny){ // default to nodal values From 93f372274a8426328b53400d92360f62ca8b56b3 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Wed, 9 Aug 2023 22:47:49 -0700 Subject: [PATCH 35/60] beta version of MFV up and running --- src/GSPH/CMakeLists.txt | 2 + src/GSPH/GSPHFieldNames.cc | 1 + src/GSPH/GSPHFieldNames.hh | 1 + src/GSPH/GenericRiemannHydro.cc | 2 +- src/GSPH/MFVEvaluateDerivatives.cc | 41 ++++--- src/GSPH/MFVHydroBase.cc | 110 ++++++++++++++---- src/GSPH/MFVHydroBase.hh | 6 +- src/GSPH/MFVHydroBaseInline.hh | 7 ++ .../IncrementSpecificFromTotalPolicy.cc | 8 +- 9 files changed, 131 insertions(+), 47 deletions(-) diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 35e9d4bd7..45259545c 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -15,6 +15,7 @@ set(GSPH_inst Policies/PureReplaceFieldList Policies/ReplaceWithRatioPolicy Policies/IncrementSpecificFromTotalPolicy + Policies/CompatibleMFVSpecificThermalEnergyPolicy Limiters/LimiterBase Limiters/VanLeerLimiter Limiters/SuperbeeLimiter @@ -49,6 +50,7 @@ set(GSPH_headers Policies/PureReplaceFieldList.hh Policies/ReplaceWithRatioPolicy.hh Policies/IncrementSpecificFromTotalPolicy.hh + Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh Limiters/LimiterBase.hh Limiters/VanLeerLimiter.hh Limiters/SuperbeeLimiter.hh diff --git a/src/GSPH/GSPHFieldNames.cc b/src/GSPH/GSPHFieldNames.cc index d8da418ed..a25d7bef5 100644 --- a/src/GSPH/GSPHFieldNames.cc +++ b/src/GSPH/GSPHFieldNames.cc @@ -15,6 +15,7 @@ const std::string Spheral::GSPHFieldNames::deviatoricStressTensorGradient = "dev const std::string Spheral::GSPHFieldNames::RiemannPressureGradient = "Riemann solvers pressure gradient"; const std::string Spheral::GSPHFieldNames::RiemannVelocityGradient = "Riemann solvers velocity gradient"; const std::string Spheral::GSPHFieldNames::RiemannDeviatoricStressTensorGradient = "Riemann solvers deviatoric stress tensor gradient"; +const std::string Spheral::GSPHFieldNames::pairMassFlux = "pairwise mass flux"; const std::string Spheral::GSPHFieldNames::momentumPolicy = "update policy momentum"; const std::string Spheral::GSPHFieldNames::thermalEnergyPolicy = "update policy thermal energy"; \ No newline at end of file diff --git a/src/GSPH/GSPHFieldNames.hh b/src/GSPH/GSPHFieldNames.hh index 0b653c8ad..d73e5f5c4 100644 --- a/src/GSPH/GSPHFieldNames.hh +++ b/src/GSPH/GSPHFieldNames.hh @@ -22,6 +22,7 @@ struct GSPHFieldNames { static const std::string RiemannVelocityGradient; static const std::string RiemannDeviatoricStressTensorGradient; + static const std::string pairMassFlux; static const std::string momentumPolicy; static const std::string thermalEnergyPolicy; }; diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 92deb2fe0..e84c671df 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -287,7 +287,7 @@ registerState(DataBase& dataBase, auto thermalEnergyPolicy = make_shared>(); auto velocityPolicy = make_shared>(HydroFieldNames::position, HydroFieldNames::specificThermalEnergy, - true) ; + true); state.enroll(specificThermalEnergy, thermalEnergyPolicy); state.enroll(velocity, velocityPolicy); diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index b007d701e..c903916fd 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -16,7 +16,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& smoothingScale = this->smoothingScaleMethod(); // A few useful constants we'll use in the following loop. - //const auto tiny = std::numeric_limits::epsilon(); + const auto tiny = std::numeric_limits::epsilon(); const auto xsph = this->XSPH(); const auto epsTensile = this->epsilonTensile(); //const auto epsDiffusionCoeff = this->specificThermalEnergyDiffusionCoefficient(); @@ -80,14 +80,15 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto DvDx = derivatives.fields(HydroFieldNames::velocityGradient, Tensor::zero); auto DHDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::H, SymTensor::zero); auto Hideal = derivatives.fields(ReplaceBoundedFieldList::prefix() + HydroFieldNames::H, SymTensor::zero); - auto& pairAccelerations = derivatives.getAny(HydroFieldNames::pairAccelerations, vector()); - auto& pairDepsDt = derivatives.getAny(HydroFieldNames::pairWork, vector()); auto XSPHDeltaV = derivatives.fields(HydroFieldNames::XSPHDeltaV, Vector::zero); auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + auto& pairAccelerations = derivatives.getAny(HydroFieldNames::pairAccelerations, vector()); + auto& pairDepsDt = derivatives.getAny(HydroFieldNames::pairWork, vector()); + auto& pairMassFlux = derivatives.getAny(GSPHFieldNames::pairMassFlux, vector()); CHECK(DrhoDx.size() == numNodeLists); CHECK(M.size() == numNodeLists); CHECK(normalization.size() == numNodeLists); @@ -109,6 +110,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, if (compatibleEnergy){ pairAccelerations.resize(npairs); pairDepsDt.resize(2*npairs); + pairMassFlux.resize(npairs); } this->computeMCorrection(time,dt,dataBase,state,derivatives); @@ -143,12 +145,16 @@ evaluateDerivatives(const typename Dimension::Scalar time, nodeListi = pairs[kk].i_list; nodeListj = pairs[kk].j_list; + const auto& mi = mass(nodeListi, i); + const auto& mj = mass(nodeListj, j); + + if( mi >tiny or mj > tiny){ + // Get the state for node i. const auto& ui = nodalVelocity(nodeListi,i); const auto& riemannDpDxi = riemannDpDx(nodeListi, i); const auto& riemannDvDxi = riemannDvDx(nodeListi, i); const auto& ri = position(nodeListi, i); - const auto& mi = mass(nodeListi, i); const auto& vi = velocity(nodeListi, i); const auto& rhoi = massDensity(nodeListi, i); const auto& voli = volume(nodeListi, i); @@ -157,7 +163,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& Hi = H(nodeListi, i); const auto& ci = soundSpeed(nodeListi, i); const auto Hdeti = Hi.Determinant(); - CHECK(mi > 0.0); + //CHECK(mi > 0.0); CHECK(voli > 0.0); CHECK(rhoi > 0.0); CHECK(Hdeti > 0.0); @@ -184,7 +190,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& riemannDpDxj = riemannDpDx(nodeListj, j); const auto& riemannDvDxj = riemannDvDx(nodeListj, j); const auto& rj = position(nodeListj, j); - const auto& mj = mass(nodeListj, j); + //const auto& mj = mass(nodeListj, j); const auto& vj = velocity(nodeListj, j); const auto& rhoj = massDensity(nodeListj, j); const auto& volj = volume(nodeListj, j); @@ -193,7 +199,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& Hj = H(nodeListj, j); const auto& cj = soundSpeed(nodeListj, j); const auto Hdetj = Hj.Determinant(); - CHECK(mj > 0.0); + //CHECK(mj > 0.0); CHECK(rhoj > 0.0); CHECK(volj > 0.0); CHECK(Hdetj > 0.0); @@ -324,10 +330,10 @@ evaluateDerivatives(const typename Dimension::Scalar time, DEDtj += deltaDepsDtj; if(compatibleEnergy){ - const auto invmij = 1.0/(mi*mj); - pairAccelerations[kk] = deltaDvDt*invmij; - pairDepsDt[2*kk] = deltaDepsDti*invmij; - pairDepsDt[2*kk+1] = deltaDepsDtj*invmij; + pairMassFlux[kk] = massFlux; + pairAccelerations[kk] = deltaDvDt; + pairDepsDt[2*kk] = deltaDepsDti; + pairDepsDt[2*kk+1] = deltaDepsDtj; } // volume change based on nodal velocity @@ -355,8 +361,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, case GradientType::HydroAccelerationGradient: // based on hydro accel for DpDx newRiemannDvDxi -= deltaDvDxi; newRiemannDvDxj -= deltaDvDxj; - newRiemannDpDxi += rhoi/mi*deltaDvDt; - newRiemannDpDxj -= rhoj/mj*deltaDvDt; + newRiemannDpDxi += deltaDvDt/voli; + newRiemannDpDxj -= deltaDvDt/volj; break; case GradientType::SPHGradient: // raw gradients newRiemannDvDxi -= (vi-vj).dyad(gradPsii); @@ -384,6 +390,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, normi += psii; normj += psij; + } //if statement } // loop over pairs threadReduceFieldLists(threadStack); @@ -422,7 +429,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& DvDxi = DvDx(nodeListi, i); auto& DHDti = DHDt(nodeListi, i); auto& Hideali = Hideal(nodeListi, i); - //auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); + auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); @@ -439,9 +446,9 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Determine the position evolution, based on whether we're doing XSPH or not. DxDti = ui; - // if (xsph){ - // DxDti += XSPHDeltaVi/max(tiny, normi); - // } + if (xsph){ + DxDti += XSPHDeltaVi/max(tiny, normi); + } // The H tensor evolution. DHDti = smoothingScale.smoothingScaleDerivative(Hi, diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index a70984242..82fdadc99 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -31,6 +31,8 @@ // 3 maybe seperate flux polies for all conserved variables // similar to an advect step in ALE schemes. Might give better e-conserve // 4 compatible energy for MFV +// +// 5 ADD DpDt and DmDt to the finalize bc application. //---------------------------------------------------------------------------// #include "FileIO/FileIO.hh" #include "NodeList/SmoothingScaleBase.hh" @@ -60,6 +62,7 @@ #include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" #include "GSPH/Policies/PureReplaceFieldList.hh" #include "GSPH/Policies/PureReplaceWithStateFieldList.hh" +#include "GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh" #include "GSPH/RiemannSolvers/RiemannSolverBase.hh" #ifdef _OPENMP @@ -121,12 +124,14 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, mDmassDt(FieldStorageType::CopyFields), mDthermalEnergyDt(FieldStorageType::CopyFields), mDmomentumDt(FieldStorageType::CopyFields), - mDvolumeDt(FieldStorageType::CopyFields){ + mDvolumeDt(FieldStorageType::CopyFields), + mPairMassFlux(){ mNodalVelocity = dataBase.newFluidFieldList(Vector::zero, GSPHFieldNames::nodalVelocity); mDmassDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::mass); mDthermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); mDmomentumDt = dataBase.newFluidFieldList(Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum); mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::volume); + mPairMassFlux.clear(); } //------------------------------------------------------------------------------ @@ -157,19 +162,19 @@ registerState(DataBase& dataBase, State& state) { GenericRiemannHydro::registerState(dataBase,state); - - //state.removePolicy(HydroFieldNames::position); dataBase.resizeFluidFieldList(mNodalVelocity, Vector::zero, GSPHFieldNames::nodalVelocity); - auto massDensity = dataBase.fluidMassDensity(); - - auto position = dataBase.fluidPosition();//state.fields(HydroFieldNames::position,Vector::zero); + auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); + auto position = state.fields(HydroFieldNames::position,Vector::zero); auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); auto volume = state.fields(HydroFieldNames::volume, 0.0); auto mass = state.fields(HydroFieldNames::mass, 0.0); auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); + // ensure we're not sure compat energy scheme for pure-lang methods + state.removePolicy(specificThermalEnergy); + CHECK(position.numFields() == dataBase.numFluidNodeLists()); CHECK(velocity.numFields() == dataBase.numFluidNodeLists()); CHECK(volume.numFields() == dataBase.numFluidNodeLists()); @@ -187,44 +192,70 @@ registerState(DataBase& dataBase, maxVolume)); } - auto rhoPolicy = std::make_shared>(HydroFieldNames::mass, - HydroFieldNames::volume, - HydroFieldNames::volume); - - auto massPolicy = std::make_shared>(GSPHFieldNames::momentumPolicy,GSPHFieldNames::thermalEnergyPolicy); - auto momentumPolicy = std::make_shared>(HydroFieldNames::velocity, IncrementFieldList::prefix() + GSPHFieldNames::momentum); - auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); + auto rhoPolicy = std::make_shared>(HydroFieldNames::mass, // numerator + HydroFieldNames::volume, // denominator + HydroFieldNames::mass, // depends on + HydroFieldNames::volume);// depends on + auto massPolicy = std::make_shared>(GSPHFieldNames::momentumPolicy, //depends on + GSPHFieldNames::thermalEnergyPolicy); //depends on + auto momentumPolicy = std::make_shared>(HydroFieldNames::velocity, + IncrementFieldList::prefix() + GSPHFieldNames::momentum, + HydroFieldNames::specificThermalEnergy); + // special policies to get velocity update from momentum deriv state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); - state.enroll(GSPHFieldNames::thermalEnergyPolicy,thermalEnergyPolicy); switch (mNodeMotionType){ case NodeMotionType::Eulerian: { - std::cout <<"Eulerian" << std::endl; + //std::cout <<"Eulerian" << std::endl; state.enroll(mNodalVelocity); // Eulerian } break; - case NodeMotionType::Lagrangian: + case NodeMotionType::Lagrangian: // pure MFV { - std::cout <<"Lagrangian" << std::endl; - auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::velocity,HydroFieldNames::velocity); + //std::cout <<"Lagrangian" << std::endl; + auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::velocity, + HydroFieldNames::velocity); // depends on state.enroll(mNodalVelocity, nodalVelocityPolicy); } break; case NodeMotionType::XSPH: - { - std::cout <<"XSPH" << std::endl; + { // this is currently wrong, its the delta not the full xsph velocity and time step delayed + //std::cout <<"XSPH" << std::endl; auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::XSPHDeltaV); state.enroll(mNodalVelocity, nodalVelocityPolicy); } break; default: - std::cout <<"default" << std::endl; + //std::cout <<"default" << std::endl; break; } + // conditional for energy method + if (this->compatibleEnergyEvolution()) { + //std::cout << "compatible MFV" << std::endl; + auto thermalEnergyPolicy = std::make_shared>(dataBase); + //auto velocityPolicy = std::make_shared>(HydroFieldNames::position,HydroFieldNames::specificThermalEnergy,true); + state.enroll(specificThermalEnergy, thermalEnergyPolicy); + //state.enroll(velocity, velocityPolicy); + + }else if (this->evolveTotalEnergy()) { + // warning not implemented yet + std::cout <<"evolve total energy not implemented for MFV" << std::endl; + //auto thermalEnergyPolicy = std::make_shared>(); + //auto velocityPolicy = std::make_shared>(HydroFieldNames::position,HydroFieldNames::specificThermalEnergy,true); + //state.enroll(specificThermalEnergy, thermalEnergyPolicy); + //state.enroll(velocity, velocityPolicy); + + } else { + auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); + auto velocityPolicy = std::make_shared>(HydroFieldNames::position,true); + state.enroll(GSPHFieldNames::thermalEnergyPolicy,thermalEnergyPolicy); + state.enroll(velocity, velocityPolicy); + } + // normal state variables state.enroll(mass, massPolicy); state.enroll(massDensity, rhoPolicy); @@ -248,6 +279,7 @@ registerDerivatives(DataBase& dataBase, derivs.enroll(mDthermalEnergyDt); derivs.enroll(mDmomentumDt); derivs.enroll(mDvolumeDt); + derivs.enrollAny(GSPHFieldNames::pairMassFlux, mPairMassFlux); } //------------------------------------------------------------------------------ @@ -262,7 +294,7 @@ preStepInitialize(const DataBase& dataBase, GenericRiemannHydro::preStepInitialize(dataBase,state,derivs); if(this->densityUpdate() == MassDensityType::RigorousSumDensity){ - // plop into an intialize volume function + const auto position = state.fields(HydroFieldNames::position, Vector::zero); const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); const auto mass = state.fields(HydroFieldNames::mass, 0.0); @@ -309,7 +341,21 @@ finalizeDerivatives(const typename Dimension::Scalar time, const DataBase& dataBase, const State& state, StateDerivatives& derivs) const { - GenericRiemannHydro::finalizeDerivatives(time,dt,dataBase,state,derivs); + // hackish solution and I should be ashamed. + if (this->compatibleEnergyEvolution()) { + auto DpDt = derivs.fields(IncrementFieldList::prefix() + GSPHFieldNames::momentum, Vector::zero); + auto DmDt = derivs.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, 0.0); + for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); + boundaryItr != this->boundaryEnd(); + ++boundaryItr){ + (*boundaryItr)->applyFieldListGhostBoundary(DpDt); + (*boundaryItr)->applyFieldListGhostBoundary(DmDt); + } + + for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); + boundaryItr != this->boundaryEnd(); + ++boundaryItr) (*boundaryItr)->finalizeGhostBoundary(); + } } //------------------------------------------------------------------------------ @@ -321,6 +367,14 @@ MFVHydroBase:: applyGhostBoundaries(State& state, StateDerivatives& derivs) { GenericRiemannHydro::applyGhostBoundaries(state,derivs); + + auto nodalVelocity = state.fields(GSPHFieldNames::nodalVelocity, Vector::zero); + + for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); + boundaryItr != this->boundaryEnd(); + ++boundaryItr) { + (*boundaryItr)->applyFieldListGhostBoundary(nodalVelocity); + } } //------------------------------------------------------------------------------ @@ -332,6 +386,14 @@ MFVHydroBase:: enforceBoundaries(State& state, StateDerivatives& derivs) { GenericRiemannHydro::enforceBoundaries(state,derivs); + + auto nodalVelocity = state.fields(GSPHFieldNames::nodalVelocity, Vector::zero); + + for (ConstBoundaryIterator boundaryItr = this->boundaryBegin(); + boundaryItr != this->boundaryEnd(); + ++boundaryItr) { + (*boundaryItr)->enforceFieldListBoundary(nodalVelocity); + } } @@ -343,6 +405,7 @@ void MFVHydroBase:: dumpState(FileIO& file, const string& pathName) const { GenericRiemannHydro::dumpState(file,pathName); + file.write(mNodalVelocity, pathName + "/nodalVelocity"); file.write(mDmassDt, pathName + "/DmassDt"); file.write(mDthermalEnergyDt, pathName + "/DthermalEnergyDt"); file.write(mDmomentumDt, pathName + "/DmomentumDt"); @@ -357,6 +420,7 @@ void MFVHydroBase:: restoreState(const FileIO& file, const string& pathName) { GenericRiemannHydro::restoreState(file,pathName); + file.read(mNodalVelocity, pathName + "/nodalVelocity"); file.read(mDmassDt, pathName + "/DmassDt"); file.read(mDthermalEnergyDt, pathName + "/DthermalEnergyDt"); file.read(mDmomentumDt, pathName + "/DmomentumDt"); diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 72228011e..e8e906d53 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -161,6 +161,8 @@ public: const FieldList& DmomentumDt() const; const FieldList& DvolumeDt() const; + const std::vector& pairMassFlux() const; + //**************************************************************************** // Methods required for restarting. virtual std::string label() const override { return "MFVHydroBase" ; } @@ -176,7 +178,9 @@ private: FieldList mDthermalEnergyDt; FieldList mDmomentumDt; FieldList mDvolumeDt; - + + std::vector mPairMassFlux; + // No default constructor, copying, or assignment. MFVHydroBase(); MFVHydroBase(const MFVHydroBase&); diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index c57d788b3..9e34201c8 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -59,4 +59,11 @@ MFVHydroBase:: DvolumeDt() const { return mDvolumeDt; } +template +inline +const std::vector& +MFVHydroBase:: +pairMassFlux() const { + return mPairMassFlux; +} } \ No newline at end of file diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc index bf1f0d79d..65aaed90e 100644 --- a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc +++ b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc @@ -107,7 +107,7 @@ update(const KeyType& /*key*/, const double t, const double dt) { - //const auto tiny = std::numeric_limits::epsilon(); + const auto tiny = std::numeric_limits::epsilon(); const auto m = state.fields(HydroFieldNames::mass, Scalar()); auto q = state.fields(mStateKey, Value()); @@ -120,14 +120,12 @@ update(const KeyType& /*key*/, for (unsigned k = 0; k != numNodeLists; ++k) { const unsigned n = q[k]->numInternalElements(); for (unsigned i = 0; i != n; ++i) { - //const auto m1 = m(k,i)+DmDt(k,i)*multiplier; - //q(k, i) = (DQDt(k, i) * multiplier + m(k,i)*q(k, i))*safeInv(m1); - q(k, i) += (DQDt(k, i) - DmDt(k, i)*q(k, i)) * multiplier * safeInv(m(k,i)+DmDt(k,i)*multiplier); + const auto m1 = m(k,i)+DmDt(k,i)*multiplier; + if (m1 > tiny) q(k, i) += (DQDt(k, i) - DmDt(k, i)*q(k, i)) * multiplier * safeInv(m1); } } } - //------------------------------------------------------------------------------ // Equivalence operator. //------------------------------------------------------------------------------ From 68f8de54abbe203fb15771a403afbe65098be507 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Wed, 9 Aug 2023 22:54:56 -0700 Subject: [PATCH 36/60] adding MFV to Noh --- .../Hydro/Noh/Noh-cylindrical-2d.py | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py index 0701c47c6..1de1278ee 100644 --- a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py +++ b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py @@ -68,6 +68,7 @@ fsisph = False, gsph = False, mfm = False, + mfv=False, asph = False, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. boolReduceViscosity = False, HopkinsConductivity = False, # For PSPH @@ -141,7 +142,7 @@ assert not(boolReduceViscosity and boolCullenViscosity) assert not((gsph or mfm) and (boolReduceViscosity or boolCullenViscosity)) assert not(fsisph and not solid) -assert sum([crksph,psph,fsisph,svph,gsph,mfm])<=1 +assert sum([crksph,psph,fsisph,svph,gsph,mfm,mfv])<=1 assert thetaFactor in (0.5, 1.0, 2.0) theta = thetaFactor * pi @@ -170,6 +171,8 @@ hydroname = "GSPH" elif mfm: hydroname = "MFM" +elif mfv: + hydroname = "MFV" elif psph: hydroname = "PSPH" else: @@ -343,7 +346,7 @@ cfl = cfl, interfaceMethod = ModulusInterface, sumDensityNodeLists=[nodes1], - densityStabilizationCoefficient = 0.00, + densityStabilizationCoefficient = 0.1, compatibleEnergyEvolution = compatibleEnergy, evolveTotalEnergy = evolveTotalEnergy, correctVelocityGradient = correctVelocityGradient, @@ -362,7 +365,7 @@ evolveTotalEnergy = evolveTotalEnergy, XSPH = XSPH, ASPH = asph, - gradientType = RiemannGradient, + gradientType = SPHSameTimeGradient, densityUpdate=densityUpdate, HUpdate = HUpdate, epsTensile = epsilonTensile, @@ -381,7 +384,28 @@ evolveTotalEnergy = evolveTotalEnergy, XSPH = XSPH, ASPH = asph, - gradientType = RiemannGradient, + gradientType = HydroAccelerationGradient, + densityUpdate=densityUpdate, + HUpdate = HUpdate, + epsTensile = epsilonTensile, + nTensile = nTensile) + +elif mfv: + limiter = VanLeerLimiter() + waveSpeed = DavisWaveSpeed() + solver = HLLC(limiter,waveSpeed,True) + hydro = MFV(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + nodeMotionType=NodeMotionType.Lagrangian, + specificThermalEnergyDiffusionCoefficient = 0.00, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = XSPH, + ASPH = asph, + gradientType = SPHSameTimeGradient, densityUpdate=densityUpdate, HUpdate = HUpdate, epsTensile = epsilonTensile, @@ -414,7 +438,7 @@ #------------------------------------------------------------------------------- # Set the artificial viscosity parameters. #------------------------------------------------------------------------------- -if not (gsph or mfm): +if not (gsph or mfm or mfv): q = hydro.Q if Cl: q.Cl = Cl @@ -720,7 +744,11 @@ comparisonFile = os.path.join(dataDir, comparisonFile) import filecmp assert filecmp.cmp(outputFile, comparisonFile) + + +Masserror = (control.conserve.massHistory[-1] - control.conserve.massHistory[0])/max(1.0e-30, control.conserve.massHistory[0]) Eerror = (control.conserve.EHistory[-1] - control.conserve.EHistory[0])/max(1.0e-30, control.conserve.EHistory[0]) +print("Total mass error: %g" % Masserror) print("Total energy error: %g" % Eerror) if compatibleEnergy and abs(Eerror) > 1e-13: raise ValueError("Energy error outside allowed bounds.") From f54651a8b018306cfb48f3d619d0fa523bd779f8 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Wed, 9 Aug 2023 22:58:45 -0700 Subject: [PATCH 37/60] bugfix cmake GSPH --- src/GSPH/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 45259545c..a75fe2bb8 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -10,7 +10,6 @@ set(GSPH_inst MFMHydroBase MFVHydroBase Policies/MassFluxPolicy - Policies/ALEPositionPolicy Policies/PureReplaceWithStateFieldList Policies/PureReplaceFieldList Policies/ReplaceWithRatioPolicy @@ -45,7 +44,6 @@ set(GSPH_headers MFMHydroBase.hh MFVHydroBase.hh Policies/MassFluxPolicy.hh - Policies/ALEPositionPolicy.hh Policies/PureReplaceWithStateFieldList.hh Policies/PureReplaceFieldList.hh Policies/ReplaceWithRatioPolicy.hh From 7bb42c18bd6c511d7226a044db4b011e4d83e22f Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Sun, 13 Aug 2023 22:54:00 -0700 Subject: [PATCH 38/60] MFV playing with new Ngb smoothing length method --- src/GSPH/MFVEvaluateDerivatives.cc | 111 +++++++++++++++++++++-------- src/GSPH/MFVHydroBase.cc | 6 +- src/GSPH/MFVHydroBase.hh | 4 +- src/GSPH/MFVHydroBaseInline.hh | 7 ++ 4 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index c903916fd..c25b38249 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -83,6 +83,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto XSPHDeltaV = derivatives.fields(HydroFieldNames::XSPHDeltaV, Vector::zero); auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); + auto XSPHHfield = derivatives.fields("XSPHHfield", SymTensor::zero); + auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); @@ -127,6 +129,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, //auto DvDt_thread = DvDt.threadCopy(threadStack); auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); + auto XSPHHfield_thread = XSPHHfield.threadCopy(threadStack); //auto DepsDt_thread = DepsDt.threadCopy(threadStack); auto DvolDt_thread = DvolDt.threadCopy(threadStack); auto DmDt_thread = DmDt.threadCopy(threadStack); @@ -180,6 +183,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& DvDxi = DvDx_thread(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); + auto& XSPHHfieldi = XSPHHfield_thread(nodeListi,i); auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); const auto& gradRhoi = DrhoDx(nodeListi, i); const auto& Mi = M(nodeListi,i); @@ -216,12 +220,14 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& DvDxj = DvDx_thread(nodeListj, j); auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); + auto& XSPHHfieldj = XSPHHfield_thread(nodeListj,j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); const auto& gradRhoj = DrhoDx(nodeListj, j); const auto& Mj = M(nodeListj,j); // Node displacement. const auto rij = ri - rj; + const auto rMagij = rij.magnitude2(); const auto rhatij =rij.unitVector(); const auto vij = vi - vj; const auto etai = Hi*rij; @@ -251,12 +257,12 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Zero'th and second moment of the node distribution -- used for the // ideal H calculation. - const auto rij2 = rij.magnitude2(); - const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); + //const auto rij2 = rij.magnitude2(); + //const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); weightedNeighborSumi += std::abs(gWi); weightedNeighborSumj += std::abs(gWj); - massSecondMomenti += gradWi.magnitude2()*thpt; - massSecondMomentj += gradWj.magnitude2()*thpt; + massSecondMomenti -= voli*rij.selfdyad()*gWi/rMagij;//.magnitude2()*thpt; + massSecondMomentj -= volj*rij.selfdyad()*gWj/rMagij;//.magnitude2()*thpt; // Determine an effective pressure including a term to fight the tensile instability. //const auto fij = epsTensile*pow(Wi/(Hdeti*WnPerh), nTensile); @@ -384,10 +390,13 @@ evaluateDerivatives(const typename Dimension::Scalar time, // XSPH //----------------------------------------------------------- if (xsph) { - XSPHDeltaVi -= psii*(vi-vstar); - XSPHDeltaVj -= psij*(vj-vstar); + XSPHDeltaVi -= psii*(vi-vj); + XSPHDeltaVj -= psij*(vj-vi); } + XSPHHfieldi += psii*Hj; + XSPHHfieldj += psij*Hi; + normi += psii; normj += psij; } //if statement @@ -404,8 +413,9 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto hmax = nodeList.hmax(); const auto hminratio = nodeList.hminratio(); const auto nPerh = nodeList.nodesPerSmoothingScale(); - + const auto kernelExtent = nodeList.neighbor().kernelExtent(); const auto ni = nodeList.numInternalNodes(); + #pragma omp parallel for for (auto i = 0u; i < ni; ++i) { @@ -432,8 +442,11 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); + auto& XSPHHfieldi = XSPHHfield(nodeListi, i); normi += voli*Hdeti*W0; + XSPHHfieldi += voli*Hi*Hdeti*W0; + XSPHHfieldi /= max(normi,tiny); DvolDti *= voli; @@ -441,8 +454,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, //if (totalEnergy) DepsDti = mi*(vi.dot(DvDti) + DepsDti); // Complete the moments of the node distribution for use in the ideal H calculation. - weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); - massSecondMomenti /= Hdeti*Hdeti; + //weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); // Determine the position evolution, based on whether we're doing XSPH or not. DxDti = ui; @@ -451,29 +463,66 @@ evaluateDerivatives(const typename Dimension::Scalar time, } // The H tensor evolution. - DHDti = smoothingScale.smoothingScaleDerivative(Hi, - ri, - DvDxi, - hmin, - hmax, - hminratio, - nPerh); - Hideali = smoothingScale.newSmoothingScale(Hi, - ri, - weightedNeighborSumi, - massSecondMomenti, - W, - hmin, - hmax, - hminratio, - nPerh, - connectivityMap, - nodeListi, - i); + // DHDti = smoothingScale.smoothingScaleDerivative(Hi, + // ri, + // DvDxi, + // hmin, + // hmax, + // hminratio, + // nPerh); + + // DHDti = 0.3*std::min(std::max((Ngb - 16.0),-1.0),1.0)/16.0 * Hi / dt; + // Hideali = smoothingScale.newSmoothingScale(Hi, + // ri, + // weightedNeighborSumi, + // massSecondMomenti, + // W, + // hmin, + // hmax, + // hminratio, + // nPerh, + // connectivityMap, + // nodeListi, + // i); + + const auto detMSM = massSecondMomenti.Determinant(); + weightedNeighborSumi = XSPHHfieldi.Determinant()/Hdeti; + if(abs(detMSM) > 1e-10){ + massSecondMomenti /= Dimension::rootnu(detMSM); + const auto Ngb_target = (Dimension::nDim == 3 ? 60 : + (Dimension::nDim == 2 ? 20 : + 5)); + const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : + (Dimension::nDim == 2 ? 3.1415 : + 1.0)); + const auto stretchFactor = 0.25; + const auto circlerFactor = 0.30; + const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + ((1.00-stretchFactor-circlerFactor)*SymTensor::one + + stretchFactor*massSecondMomenti)*Hi; + const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + DHDti = 0.25*(Hideali-Hi)/dt; + } else{ + const auto Ngb_target = (Dimension::nDim == 3 ? 60 : + (Dimension::nDim == 2 ? 20 : + 5)); + const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : + (Dimension::nDim == 2 ? 3.1415 : + 1.0)); + const auto stretchFactor = 0.00; + const auto circlerFactor = 0.3; + const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; + const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + DHDti = 0.25*(Hideali-Hi)/dt; + } } // nodes loop - } // nodeLists loop - -} // eval derivs method + } // nodeLists loop +} // eval derivs method //------------------------------------------------------------------------------ diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index 82fdadc99..5a551f572 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -125,12 +125,14 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, mDthermalEnergyDt(FieldStorageType::CopyFields), mDmomentumDt(FieldStorageType::CopyFields), mDvolumeDt(FieldStorageType::CopyFields), + mXSPHHfield(FieldStorageType::CopyFields), mPairMassFlux(){ mNodalVelocity = dataBase.newFluidFieldList(Vector::zero, GSPHFieldNames::nodalVelocity); mDmassDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::mass); mDthermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); mDmomentumDt = dataBase.newFluidFieldList(Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum); mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::volume); + mXSPHHfield = dataBase.newFluidFieldList(SymTensor::zero, "XSPHHfield"); mPairMassFlux.clear(); } @@ -163,7 +165,7 @@ registerState(DataBase& dataBase, GenericRiemannHydro::registerState(dataBase,state); - dataBase.resizeFluidFieldList(mNodalVelocity, Vector::zero, GSPHFieldNames::nodalVelocity); + dataBase.resizeFluidFieldList(mNodalVelocity, Vector::zero, GSPHFieldNames::nodalVelocity,false); auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); auto position = state.fields(HydroFieldNames::position,Vector::zero); @@ -275,10 +277,12 @@ registerDerivatives(DataBase& dataBase, dataBase.resizeFluidFieldList(mDthermalEnergyDt, 0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, false); dataBase.resizeFluidFieldList(mDmomentumDt, Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum, false); dataBase.resizeFluidFieldList(mDvolumeDt, 0.0, IncrementFieldList::prefix() + HydroFieldNames::volume, false); + dataBase.resizeFluidFieldList(mXSPHHfield,SymTensor::zero, "XSPHHfield", false); derivs.enroll(mDmassDt); derivs.enroll(mDthermalEnergyDt); derivs.enroll(mDmomentumDt); derivs.enroll(mDvolumeDt); + derivs.enroll(mXSPHHfield); derivs.enrollAny(GSPHFieldNames::pairMassFlux, mPairMassFlux); } diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index e8e906d53..7b24d4ab1 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -160,6 +160,7 @@ public: const FieldList& DthermalEnergyDt() const; const FieldList& DmomentumDt() const; const FieldList& DvolumeDt() const; + const FieldList& xsphHfield() const; const std::vector& pairMassFlux() const; @@ -178,7 +179,8 @@ private: FieldList mDthermalEnergyDt; FieldList mDmomentumDt; FieldList mDvolumeDt; - + FieldList mXSPHHfield; + std::vector mPairMassFlux; // No default constructor, copying, or assignment. diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index 9e34201c8..79c49c74a 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -66,4 +66,11 @@ MFVHydroBase:: pairMassFlux() const { return mPairMassFlux; } +template +inline +const FieldList& +MFVHydroBase:: +xsphHfield() const { + return mXSPHHfield; +} } \ No newline at end of file From 4375f8543bf1f786b4896416e8640933f0e946d3 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Sun, 13 Aug 2023 22:55:24 -0700 Subject: [PATCH 39/60] MFV: updating Noh --- .../Hydro/Noh/Noh-cylindrical-2d.py | 103 ++++++++++-------- .../functional/Hydro/Noh/Noh-spherical-3d.py | 30 ++++- 2 files changed, 83 insertions(+), 50 deletions(-) diff --git a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py index 1de1278ee..791c05dd1 100644 --- a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py +++ b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py @@ -25,24 +25,27 @@ # # W.F. Noh 1987, JCP, 72, 78-120. #------------------------------------------------------------------------------- -import os, shutil +import os, shutil, mpi, sys from math import * + from SolidSpheral2d import * from SpheralTestUtilities import * from GenerateNodeDistribution2d import * from CubicNodeGenerator import GenerateSquareNodeDistribution from CentroidalVoronoiRelaxation import * -import mpi -import DistributeNodes +if mpi.procs > 1: + from VoronoiDistributeNodes import distributeNodes2d + #from PeanoHilbertDistributeNodes import distributeNodes2d +else: + from DistributeNodes import distributeNodes2d title("2-D integrated hydro test -- cylindrical Noh problem") #------------------------------------------------------------------------------- # Generic problem parameters #------------------------------------------------------------------------------- -commandLine(order = 5, - seed = "constantDTheta", +commandLine(seed = "constantDTheta", thetaFactor = 0.5, azimuthalOffsetFraction = 0.0, @@ -50,7 +53,6 @@ nTheta = 50, rmin = 0.0, rmax = 1.0, - nPerh = 2.01, rho0 = 1.0, eps0 = 0.0, smallPressure = False, @@ -60,23 +62,50 @@ gamma = 5.0/3.0, mu = 1.0, + # hydro type (only one!) + svph = False, + crksph = False, # high order conservative formulation of SPH + psph = False, # pressure-based formulation of SPH + fsisph = False, # formulation for multimaterial problems + gsph = False, # godunov SPH + mfm = False, # moving finite mass of Hopkins 2015 + mfv=False, # moving finite volume of Hopkins 2015 + asph = False, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. solid = False, # If true, use the fluid limit of the solid hydro option - svph = False, - crksph = False, - psph = False, - fsisph = False, - gsph = False, - mfm = False, - mfv=False, - asph = False, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. - boolReduceViscosity = False, + # general hydro options + densityUpdate = RigorousSumDensity, # (IntegrateDensity) + evolveTotalEnergy = False, # evolve total rather than specific energy + compatibleEnergy = True, # evolve specific in a energy conserving manner + gradhCorrection = True, # only for SPH, PSPH (correction for time evolution of h) + correctVelocityGradient = True, # linear gradient correction + XSPH = False, # monaghan's xsph -- move w/ averaged velocity + epsilonTensile = 0.0, # coefficient for the tensile correction + nTensile = 8, # exponent for tensile correction + filter = 0.0, + + # PSPH options HopkinsConductivity = False, # For PSPH + + #CRKSPH options + correctionOrder = LinearOrder, + volumeType = RKSumVolume, + + # artificial viscosity + Cl = None, + Cq = None, + linearInExpansion = None, + Qlimiter = None, + balsaraCorrection = None, + epsilon2 = None, + + boolReduceViscosity = False, # morris-monaghan reducing AV nhQ = 5.0, nhL = 10.0, aMin = 0.1, aMax = 2.0, - boolCullenViscosity = False, + + boolCullenViscosity = False, # cullen dehnen AV limiter alphMax = 2.0, alphMin = 0.02, betaC = 0.7, @@ -86,22 +115,18 @@ boolHopkinsCorrection = True, linearConsistent = False, - Cl = None, - Cq = None, - linearInExpansion = None, - Qlimiter = None, - balsaraCorrection = None, - epsilon2 = None, + # kernel options + KernelConstructor = NBSplineKernel, #(NBSplineKernel,WendlandC2Kernel,WendlandC4Kernel,WendlandC6Kernel) + nPerh = 1.00, + HUpdate = IdealH, + order = 3, hmin = 0.0001, hmax = 0.5, hminratio = 0.1, - cfl = 0.25, - XSPH = False, - epsilonTensile = 0.0, - nTensile = 8, - filter = 0.0, + # integrator options IntegratorConstructor = CheapSynchronousRK2Integrator, + cfl = 0.07, goalTime = 0.6, steps = None, vizCycle = None, @@ -113,19 +138,11 @@ maxSteps = None, statsStep = 10, smoothIters = 0, - HUpdate = IdealH, - correctionOrder = LinearOrder, - volumeType = RKSumVolume, domainIndependent = False, rigorousBoundaries = False, dtverbose = False, - densityUpdate = RigorousSumDensity, # VolumeScaledDensity, - evolveTotalEnergy = False, # Only for SPH variants -- evolve total rather than specific energy - compatibleEnergy = True, - gradhCorrection = True, - correctVelocityGradient = True, - + # output options useVoronoiOutput = True, clearDirectories = False, vizDerivs = False, @@ -202,7 +219,6 @@ #------------------------------------------------------------------------------- # Check if the necessary output directories exist. If not, create them. #------------------------------------------------------------------------------- -import os, sys if mpi.rank == 0: if clearDirectories and os.path.exists(dataDir): shutil.rmtree(dataDir) @@ -220,7 +236,10 @@ #------------------------------------------------------------------------------- # Interpolation kernels. #------------------------------------------------------------------------------- -WT = TableKernel(NBSplineKernel(order), 1000) +if KernelConstructor==NBSplineKernel: + WT = TableKernel(KernelConstructor(order), 1000) +else: + WT = TableKernel(KernelConstructor(), 1000) output("WT") kernelExtent = WT.kernelExtent @@ -271,12 +290,6 @@ nNodePerh = nPerh, SPH = not asph) -if mpi.procs > 1: - from VoronoiDistributeNodes import distributeNodes2d - #from PeanoHilbertDistributeNodes import distributeNodes2d -else: - from DistributeNodes import distributeNodes2d - distributeNodes2d((nodes1, generator)) output("mpi.reduce(nodes1.numInternalNodes, mpi.MIN)") output("mpi.reduce(nodes1.numInternalNodes, mpi.MAX)") @@ -405,7 +418,7 @@ evolveTotalEnergy = evolveTotalEnergy, XSPH = XSPH, ASPH = asph, - gradientType = SPHSameTimeGradient, + gradientType = RiemannGradient, densityUpdate=densityUpdate, HUpdate = HUpdate, epsTensile = epsilonTensile, diff --git a/tests/functional/Hydro/Noh/Noh-spherical-3d.py b/tests/functional/Hydro/Noh/Noh-spherical-3d.py index 4a8ffb8e6..5275e1107 100644 --- a/tests/functional/Hydro/Noh/Noh-spherical-3d.py +++ b/tests/functional/Hydro/Noh/Noh-spherical-3d.py @@ -22,7 +22,7 @@ #------------------------------------------------------------------------------- # Generic problem parameters #------------------------------------------------------------------------------- -commandLine(order = 5, +commandLine(order = 3, seed = "lattice", nx = 50, @@ -37,7 +37,7 @@ z1 = 1.0, rmin = 0.0, rmax = 1.0, - nPerh = 2.01, + nPerh = 1.00, rho0 = 1.0, eps0 = 0.0, smallPressure = False, @@ -55,6 +55,7 @@ fsisph = False, gsph = False, mfm = False, + mfv = False, asph = False, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. boolReduceViscosity = False, @@ -144,8 +145,10 @@ hydroname = "FSISPH" elif gsph: hydroname = "GSPH" -elif gsph: +elif mfm: hydroname = "MFM" +elif mfv: + hydroname = "MFV" else: hydroname = "SPH" if asph: @@ -328,6 +331,23 @@ HUpdate = IdealH, epsTensile = epsilonTensile, nTensile = nTensile) +elif mfv: + limiter = VanLeerLimiter() + waveSpeed = DavisWaveSpeed() + solver = HLLC(limiter,waveSpeed,True) + hydro = MFV(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient=correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + XSPH = XSPH, + gradientType = RiemannGradient, + densityUpdate=densityUpdate, + HUpdate = IdealH, + epsTensile = epsilonTensile, + nTensile = nTensile) elif psph: hydro = PSPH(dataBase = db, W = WT, @@ -361,7 +381,7 @@ output("hydro.cfl") output("hydro.compatibleEnergyEvolution") output("hydro.HEvolution") -if not (gsph or fsisph): +if not (gsph or mfm or mfv or fsisph): output("hydro.PiKernel") if not fsisph: output("hydro.densityUpdate") @@ -371,7 +391,7 @@ #------------------------------------------------------------------------------- # Set the artificial viscosity parameters. #------------------------------------------------------------------------------- -if not (gsph or mfm): +if not (gsph or mfm or mfv): q = hydro.Q if Cl: q.Cl = Cl From 140480f0efb0ac33e828088226908aded085b5e4 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Mon, 14 Aug 2023 18:14:06 -0700 Subject: [PATCH 40/60] updates to sedov --- src/GSPH/MFVEvaluateDerivatives.cc | 58 +++++++-------- .../Hydro/Sedov/Sedov-cylindrical-2d.py | 71 +++++++++++++++---- 2 files changed, 82 insertions(+), 47 deletions(-) diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index c25b38249..97b8ef3d2 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -484,41 +484,35 @@ evaluateDerivatives(const typename Dimension::Scalar time, // connectivityMap, // nodeListi, // i); - + const auto Ngb_target = (Dimension::nDim == 3 ? 32 : + (Dimension::nDim == 2 ? 16 : + 4)); + const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : + (Dimension::nDim == 2 ? 3.1415 : + 1.0)); const auto detMSM = massSecondMomenti.Determinant(); - weightedNeighborSumi = XSPHHfieldi.Determinant()/Hdeti; + weightedNeighborSumi = detMSM;//XSPHHfieldi.Determinant()/Hdeti; if(abs(detMSM) > 1e-10){ - massSecondMomenti /= Dimension::rootnu(detMSM); - const auto Ngb_target = (Dimension::nDim == 3 ? 60 : - (Dimension::nDim == 2 ? 20 : - 5)); - const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : - (Dimension::nDim == 2 ? 3.1415 : - 1.0)); - const auto stretchFactor = 0.25; - const auto circlerFactor = 0.30; - const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - ((1.00-stretchFactor-circlerFactor)*SymTensor::one + - stretchFactor*massSecondMomenti)*Hi; - const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; - DHDti = 0.25*(Hideali-Hi)/dt; + massSecondMomenti /= Dimension::rootnu(detMSM); + + const auto stretchFactor = 0.25; + const auto circlerFactor = 0.30; + const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + ((1.00-stretchFactor-circlerFactor)*SymTensor::one + + stretchFactor*massSecondMomenti)*Hi; + const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + DHDti = 0.25*(Hideali-Hi)/dt; } else{ - const auto Ngb_target = (Dimension::nDim == 3 ? 60 : - (Dimension::nDim == 2 ? 20 : - 5)); - const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : - (Dimension::nDim == 2 ? 3.1415 : - 1.0)); - const auto stretchFactor = 0.00; - const auto circlerFactor = 0.3; - const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; - const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; - DHDti = 0.25*(Hideali-Hi)/dt; + const auto stretchFactor = 0.00; + const auto circlerFactor = 0.3; + const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; + const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + DHDti = 0.25*(Hideali-Hi)/dt; } } // nodes loop } // nodeLists loop diff --git a/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py b/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py index 9b137163e..378b308df 100644 --- a/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py +++ b/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py @@ -1,14 +1,19 @@ #------------------------------------------------------------------------------- # The cylindrical Sedov test case (2-D). #------------------------------------------------------------------------------- -import os, sys, shutil +import os, sys, shutil, mpi from Spheral2d import * from SpheralTestUtilities import * -from SpheralGnuPlotUtilities import * +#from SpheralGnuPlotUtilities import * from GenerateNodeDistribution2d import * from CubicNodeGenerator import GenerateSquareNodeDistribution -import mpi +if mpi.procs > 1: + from VoronoiDistributeNodes import distributeNodes2d + #from PeanoHilbertDistributeNodes import distributeNodes2d +else: + from DistributeNodes import distributeNodes2d + title("2-D integrated hydro test -- planar Sedov problem") #------------------------------------------------------------------------------- @@ -22,8 +27,8 @@ nTheta = 50, rmin = 0.0, rmax = 1.0, - nPerh = 1.51, - order = 5, + nPerh = 1.00, + order = 3, rho0 = 1.0, eps0 = 0.0, @@ -46,6 +51,8 @@ psph = False, fsisph = False, gsph = False, + mfm = False, + mfv = False, # hydro options solid = False, @@ -64,7 +71,7 @@ # gsph options RiemannGradientType = RiemannGradient, # (RiemannGradient,SPHGradient,HydroAccelerationGradient,OnlyDvDxGradient,MixedMethodGradient) - linearReconstruction = True, + linearReconstruction = False, # Artifical Viscosity boolReduceViscosity = False, @@ -95,6 +102,7 @@ statsStep = 1, smoothIters = 0, useVelocityMagnitudeForDt = False, + dtverbose = False, # IO vizCycle = None, @@ -117,7 +125,7 @@ assert not(boolReduceViscosity and boolCullenViscosity) assert thetaFactor in (0.5, 1.0, 2.0) -assert not(gsph and (boolReduceViscosity or boolCullenViscosity)) +assert not((gsph or mfm or mfv) and (boolReduceViscosity or boolCullenViscosity)) assert not(fsisph and not solid) theta = thetaFactor * pi @@ -154,6 +162,10 @@ hydroname = "FSISPH" elif gsph: hydroname = "GSPH" +elif mfm: + hydroname = "MFM" +elif mfv: + hydroname = "MFV" else: hydroname = "SPH" if asph: @@ -175,7 +187,6 @@ #------------------------------------------------------------------------------- # Check if the necessary output directories exist. If not, create them. #------------------------------------------------------------------------------- -import os, sys if mpi.rank == 0: if clearDirectories and os.path.exists(dataDir): shutil.rmtree(dataDir) @@ -249,12 +260,6 @@ nNodePerh = nPerh, SPH = (not ASPH)) -if mpi.procs > 1: - from VoronoiDistributeNodes import distributeNodes2d - #from PeanoHilbertDistributeNodes import distributeNodes2d -else: - from DistributeNodes import distributeNodes2d - distributeNodes2d((nodes1, generator)) output("mpi.reduce(nodes1.numInternalNodes, mpi.MIN)") output("mpi.reduce(nodes1.numInternalNodes, mpi.MAX)") @@ -350,6 +355,41 @@ compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, + gradientType = SPHGradient, + XSPH = XSPH, + ASPH = asph, + densityUpdate=densityUpdate, + HUpdate = HUpdate) +elif mfm: + limiter = VanLeerLimiter() + waveSpeed = DavisWaveSpeed() + solver = HLLC(limiter,waveSpeed,linearReconstruction) + hydro = MFM(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + specificThermalEnergyDiffusionCoefficient = 0.00, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + gradientType = RiemannGradient, + XSPH = XSPH, + ASPH = asph, + densityUpdate=densityUpdate, + HUpdate = HUpdate) +elif mfv: + limiter = VanLeerLimiter() + waveSpeed = DavisWaveSpeed() + solver = HLLC(limiter,waveSpeed,linearReconstruction) + hydro = MFV(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + specificThermalEnergyDiffusionCoefficient = 0.00, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + evolveTotalEnergy = evolveTotalEnergy, + gradientType = SPHSameTimeGradient, XSPH = XSPH, ASPH = asph, densityUpdate=densityUpdate, @@ -389,7 +429,7 @@ output("hydro.densityUpdate") output("hydro.HEvolution") -if not gsph: +if not (gsph or mfm or mfv): q = hydro.Q output("q") output("q.Cl") @@ -436,6 +476,7 @@ if dtMax: integrator.dtMax = dtMax integrator.dtGrowth = dtGrowth +integrator.verbose = dtverbose integrator.allowDtCheck = True output("integrator") output("integrator.havePhysicsPackage(hydro)") From a6be56c2b4096d7b5377843a266bb2aafdc3c43a Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Tue, 26 Sep 2023 19:41:51 -0700 Subject: [PATCH 41/60] checkpoint --- src/GSPH/MFMEvaluateDerivatives.cc | 37 ++++- src/GSPH/MFVEvaluateDerivatives.cc | 156 ++++++++++++------ src/GSPH/RiemannSolvers/HLLC.cc | 16 +- src/NodeGenerators/CubicNodeGenerator.py | 6 +- .../Hydro/Noh/Noh-cylindrical-2d.py | 4 +- tests/functional/Hydro/Noh/Noh-planar-1d.py | 16 +- .../Hydro/Sedov/Sedov-cylindrical-2d.py | 59 ++++--- 7 files changed, 189 insertions(+), 105 deletions(-) diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index e0aaba2aa..be780250e 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -196,6 +196,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Node displacement. const auto rij = ri - rj; const auto rhatij =rij.unitVector(); + const auto rMagij = rij.magnitude2(); const auto vij = vi - vj; const auto etai = Hi*rij; const auto etaj = Hj*rij; @@ -222,7 +223,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, weightedNeighborSumj += std::abs(gWj); massSecondMomenti += gradWi.magnitude2()*thpt; massSecondMomentj += gradWj.magnitude2()*thpt; - + //massSecondMomenti -= voli*rij.selfdyad()*gWi/rMagij;//.magnitude2()*thpt; + //massSecondMomentj -= volj*rij.selfdyad()*gWj/rMagij;//.magnitude2()*thpt; // Determine an effective pressure including a term to fight the tensile instability. //const auto fij = epsTensile*pow(Wi/(Hdeti*WnPerh), nTensile); const auto fij = epsTensile*FastMath::pow4(Wi/(Hdeti*WnPerh)); @@ -350,7 +352,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto hmax = nodeList.hmax(); const auto hminratio = nodeList.hminratio(); const auto nPerh = nodeList.nodesPerSmoothingScale(); - + const auto kernelExtent = nodeList.neighbor().kernelExtent(); const auto ni = nodeList.numInternalNodes(); #pragma omp parallel for for (auto i = 0u; i < ni; ++i) { @@ -403,6 +405,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, hmax, hminratio, nPerh); + Hideali = smoothingScale.newSmoothingScale(Hi, ri, weightedNeighborSumi, @@ -415,6 +418,36 @@ evaluateDerivatives(const typename Dimension::Scalar time, connectivityMap, nodeListi, i); + // const auto Ngb_target = (Dimension::nDim == 3 ? 32 : + // (Dimension::nDim == 2 ? 16 : + // 4)); + // const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : + // (Dimension::nDim == 2 ? 3.1415 : + // 1.0)); + // const auto detMSM = massSecondMomenti.Determinant(); + // weightedNeighborSumi = detMSM;//XSPHHfieldi.Determinant()/Hdeti; + // if(abs(detMSM) > 1e-10){ + // massSecondMomenti /= Dimension::rootnu(detMSM); + + // const auto stretchFactor = 0.25; + // const auto circlerFactor = 0.30; + // const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + // const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + // ((1.00-stretchFactor-circlerFactor)*SymTensor::one + + // stretchFactor*massSecondMomenti)*Hi; + // const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + // Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + // DHDti = 0.25*(Hideali-Hi)/dt; + // } else{ + // const auto stretchFactor = 0.00; + // const auto circlerFactor = 0.3; + // const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + // const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + // ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; + // const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + // Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + // DHDti = 0.25*(Hideali-Hi)/dt; + // } } // nodes loop } // nodeLists loop diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index 97b8ef3d2..c7406ac46 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -182,7 +182,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); auto& DvDxi = DvDx_thread(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); - auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); + auto& massSecondMomenti = massSecondMoment(nodeListi, i); auto& XSPHHfieldi = XSPHHfield_thread(nodeListi,i); auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); const auto& gradRhoi = DrhoDx(nodeListi, i); @@ -219,7 +219,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& newRiemannDvDxj = newRiemannDvDx_thread(nodeListj,j); auto& DvDxj = DvDx_thread(nodeListj, j); auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); - auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); + auto& massSecondMomentj = massSecondMoment(nodeListj, j); auto& XSPHHfieldj = XSPHHfield_thread(nodeListj,j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); const auto& gradRhoj = DrhoDx(nodeListj, j); @@ -227,7 +227,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Node displacement. const auto rij = ri - rj; - const auto rMagij = rij.magnitude2(); + const auto rMagij = rij.magnitude(); + const auto rMagij2 = rij.magnitude2(); const auto rhatij =rij.unitVector(); const auto vij = vi - vj; const auto etai = Hi*rij; @@ -257,12 +258,18 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Zero'th and second moment of the node distribution -- used for the // ideal H calculation. - //const auto rij2 = rij.magnitude2(); - //const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); + const auto rij2 = rij.magnitude2(); + const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); weightedNeighborSumi += std::abs(gWi); weightedNeighborSumj += std::abs(gWj); - massSecondMomenti -= voli*rij.selfdyad()*gWi/rMagij;//.magnitude2()*thpt; - massSecondMomentj -= volj*rij.selfdyad()*gWj/rMagij;//.magnitude2()*thpt; + massSecondMomenti += gradWi.magnitude2()*thpt; + massSecondMomentj += gradWj.magnitude2()*thpt; + //const auto rij2 = rij.magnitude2(); + //const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); + //weightedNeighborSumi += std::abs(gWi); + //weightedNeighborSumj += std::abs(gWj); + // massSecondMomenti -= voli*rij.selfdyad()*gWi/rMagij;//.magnitude2()*thpt; + // massSecondMomentj -= volj*rij.selfdyad()*gWj/rMagij;//.magnitude2()*thpt; // Determine an effective pressure including a term to fight the tensile instability. //const auto fij = epsTensile*pow(Wi/(Hdeti*WnPerh), nTensile); @@ -394,9 +401,12 @@ evaluateDerivatives(const typename Dimension::Scalar time, XSPHDeltaVj -= psij*(vj-vi); } - XSPHHfieldi += psii*Hj; - XSPHHfieldj += psij*Hi; - + //if (sameMatij and diffuseEnergy){ + //linearReconstruction(ri,rj,epsi,epsj,DepsDxi,DepsDxj,epsLineari,epsLinearj); + //const auto cijEff = max(min(cij + (vi-vj).dot(rhatij), cij),0.0); + //const auto diffusion = epsDiffusionCoeff*cijEff*(Hi-Hj)*etaij.dot(gradPsii)/(etaMagij*etaMagij+tiny); + //XSPHHfieldi += psii*(massSecondMomentj);//ci*(Hi-Hj)*etai.dot(gradPsii)/(etaMagi*etaMagi+tiny); + //XSPHHfieldj += psij*(massSecondMomenti);//cj*(Hj-Hi)*etaj.dot(gradPsij)/(etaMagj*etaMagj+tiny);i normi += psii; normj += psij; } //if statement @@ -443,10 +453,12 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); auto& XSPHHfieldi = XSPHHfield(nodeListi, i); - + normi += voli*Hdeti*W0; - XSPHHfieldi += voli*Hi*Hdeti*W0; - XSPHHfieldi /= max(normi,tiny); + + XSPHHfieldi += voli*Hdeti*W0*massSecondMomenti; + //XSPHHfieldi /= max(normi,tiny); + XSPHHfieldi /= Dimension::rootnu(std::max(XSPHHfieldi.Determinant(),tiny)); DvolDti *= voli; @@ -462,63 +474,86 @@ evaluateDerivatives(const typename Dimension::Scalar time, DxDti += XSPHDeltaVi/max(tiny, normi); } + if(true){ // The H tensor evolution. - // DHDti = smoothingScale.smoothingScaleDerivative(Hi, - // ri, - // DvDxi, - // hmin, - // hmax, - // hminratio, - // nPerh); + // Complete the moments of the node distribution for use in the ideal H calculation. + weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); + massSecondMomenti /= Hdeti*Hdeti; + DHDti = smoothingScale.smoothingScaleDerivative(Hi, + ri, + DvDxi, + hmin, + hmax, + hminratio, + nPerh); - // DHDti = 0.3*std::min(std::max((Ngb - 16.0),-1.0),1.0)/16.0 * Hi / dt; - // Hideali = smoothingScale.newSmoothingScale(Hi, - // ri, - // weightedNeighborSumi, - // massSecondMomenti, - // W, - // hmin, - // hmax, - // hminratio, - // nPerh, - // connectivityMap, - // nodeListi, - // i); + //DHDti = 0.3*std::min(std::max((Ngb - 16.0),-1.0),1.0)/16.0 * Hi / dt; + Hideali = smoothingScale.newSmoothingScale(Hi, + ri, + weightedNeighborSumi, + massSecondMomenti, + W, + hmin, + hmax, + hminratio, + nPerh, + connectivityMap, + nodeListi, + i); + }else{ const auto Ngb_target = (Dimension::nDim == 3 ? 32 : (Dimension::nDim == 2 ? 16 : 4)); const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : (Dimension::nDim == 2 ? 3.1415 : 1.0)); - const auto detMSM = massSecondMomenti.Determinant(); - weightedNeighborSumi = detMSM;//XSPHHfieldi.Determinant()/Hdeti; - if(abs(detMSM) > 1e-10){ - massSecondMomenti /= Dimension::rootnu(detMSM); + // const auto detMSM = massSecondMomenti.Determinant(); + // weightedNeighborSumi = detMSM;//abs(XSPHHfieldi.Determinant()/max(Hdeti,tiny)); + // //const auto weightH = std::min(100*std::abs(weightedNeighborSumi),1.0); + // //const auto Heffi = Hi ; + // //if(abs(detMSM) > 1e-10){ + // massSecondMomenti /= Dimension::rootnu(detMSM); + - const auto stretchFactor = 0.25; - const auto circlerFactor = 0.30; - const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - ((1.00-stretchFactor-circlerFactor)*SymTensor::one + - stretchFactor*massSecondMomenti)*Hi; - const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; - DHDti = 0.25*(Hideali-Hi)/dt; - } else{ - const auto stretchFactor = 0.00; - const auto circlerFactor = 0.3; + // control that shape poopsie + const auto circlerFactor = 0.00;//std::max(std::min(1.0,500.0*weightedNeighborSumi),0.05);//min(weightH,0.3); + const auto stretchFactor = 0.4; + const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; + //const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + //const auto Hstretch = ((1.00-stretchFactor)* SymTensor::one + + // stretchFactor * XSPHHfieldi)*Hi; const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + Hideali = std::min(std::max(scaleFactor,0.8),1.2) * Hi; + // scale to enforce hmin/hmax DHDti = 0.25*(Hideali-Hi)/dt; - } + } + + + const auto C2 = (Dimension::nDim == 3 ? 1.33333*3.1415 : + (Dimension::nDim == 2 ? 3.1415 : + 1.0)); + weightedNeighborSumi = C2 /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + // } else{ + // const auto stretchFactor = 0.00; + // const auto circlerFactor = 0.3; + // const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + // const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + + // ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; + // const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + // Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; + // DHDti = 0.25*(Hideali-Hi)/dt; + // } } // nodes loop } // nodeLists loop } // eval derivs method - +//Ngb = 3.1415/(Hdeti*sum(Wi)) +//dNdh = -3.1415/voliHdeti^2 dHdetidh - 3.1415/HdetiVoli^2 dVolidh +// Ngb = C h ^nu sum (W) +// dNdh = -N/h +//Hdeti = h3 +//3h^2 //------------------------------------------------------------------------------ // EvalDerivs subroutine for spatial derivs //------------------------------------------------------------------------------ @@ -561,6 +596,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); + auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); CHECK(M.size() == numNodeLists); CHECK(DrhoDx.size() == numNodeLists); @@ -581,7 +617,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, auto DrhoDx_thread = DrhoDx.threadCopy(threadStack); auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); - + auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); #pragma omp for for (auto kk = 0u; kk < npairs; ++kk) { i = pairs[kk].i_node; @@ -598,6 +634,7 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(voli > 0.0); CHECK(Hdeti > 0.0); + auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); auto& DrhoDxi = DrhoDx_thread(nodeListi, i); auto& Mi = M_thread(nodeListi, i); @@ -610,10 +647,12 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(volj > 0.0); CHECK(Hdetj > 0.0); + auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); auto& DrhoDxj = DrhoDx_thread(nodeListj, j); auto& Mj = M_thread(nodeListj, j); const auto rij = ri - rj; + const auto rMagij = safeInv(rij.magnitude()); const auto etai = Hi*rij; const auto etaj = Hj*rij; @@ -639,6 +678,9 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, DrhoDxi -= (rhoi - rhoj) * gradPsii; DrhoDxj -= (rhoi - rhoj) * gradPsij; + //massSecondMomenti -= voli*rij.selfdyad()*gWi*rMagij;//.magnitude2()*thpt; + //massSecondMomentj -= volj*rij.selfdyad()*gWj*rMagij;//.magnitude2()*thpt; + // // based on nodal values if (calcSpatialGradients){ const auto& vi = velocity(nodeListi, i); @@ -671,6 +713,10 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, for (auto i = 0u; i < ni; ++i) { const auto numNeighborsi = connectivityMap.numNeighborsForNode(nodeListi, i); auto& Mi = M(nodeListi, i); + //auto& massSecondMomenti = massSecondMoment(nodeListi,i); + + //const auto detMSM = massSecondMomenti.Determinant(); + //massSecondMomenti /= Dimension::rootnu(detMSM); const auto Mdeti = std::abs(Mi.Determinant()); diff --git a/src/GSPH/RiemannSolvers/HLLC.cc b/src/GSPH/RiemannSolvers/HLLC.cc index 1db5b4b54..17d824199 100644 --- a/src/GSPH/RiemannSolvers/HLLC.cc +++ b/src/GSPH/RiemannSolvers/HLLC.cc @@ -82,7 +82,7 @@ interfaceState(const typename Dimension::Vector& ri, rhostari = rhoi; rhostarj = rhoj; - if (rhoi*ci > tiny or rhoj*cj > tiny){ + if (ci > tiny or cj > tiny){ // default to nodal values @@ -92,15 +92,15 @@ interfaceState(const typename Dimension::Vector& ri, auto p1i = Pi; auto p1j = Pj; - auto rho1i = rhoi; - auto rho1j = rhoj; + //auto rho1i = rhoi; + //auto rho1j = rhoj; // linear reconstruction if(this->linearReconstruction()){ // gradients along line of action - this->linearReconstruction(ri,rj, rhoi,rhoj,DrhoDxi,DrhoDxj, //inputs - rho1i,rho1j); //outputs + //this->linearReconstruction(ri,rj, rhoi,rhoj,DrhoDxi,DrhoDxj, //inputs + // rho1i,rho1j); //outputs this->linearReconstruction(ri,rj, Pi,Pj,DpDxi,DpDxj, //inputs p1i,p1j); //outputs this->linearReconstruction(ri,rj, vi,vj,DvDxi,DvDxj, //inputs @@ -113,7 +113,7 @@ interfaceState(const typename Dimension::Vector& ri, const auto wi = v1i - ui*rhatij; const auto wj = v1j - uj*rhatij; - waveSpeedObject.waveSpeed(rho1i,rho1j,ci,cj,ui,uj, //inputs + waveSpeedObject.waveSpeed(rhoi,rhoj,ci,cj,ui,uj, //inputs Si,Sj); //outputs const auto denom = safeInv(Si - Sj); @@ -122,8 +122,8 @@ interfaceState(const typename Dimension::Vector& ri, const auto wstar = (Si*wi - Sj*wj)*denom; vstar = ustar*rhatij + wstar; Pstar = Sj * (ustar-uj) + p1j; - rhostari = rho1i;// * (Si - ui)*safeInv(Si-ustar); - rhostarj = rho1j;// * (Sj - uj)*safeInv(Sj-ustar); + //rhostari = rho1i;// * (Si - ui)*safeInv(Si-ustar); + //rhostarj = rho1j;// * (Sj - uj)*safeInv(Sj-ustar); }else{ // if ci & cj too small punt to normal av const auto uij = std::min((vi-vj).dot(rhatij),0.0); diff --git a/src/NodeGenerators/CubicNodeGenerator.py b/src/NodeGenerators/CubicNodeGenerator.py index b7cca64ae..56edacbfb 100644 --- a/src/NodeGenerators/CubicNodeGenerator.py +++ b/src/NodeGenerators/CubicNodeGenerator.py @@ -59,9 +59,9 @@ def __init__(self, assert nxdomains * nydomains == mpi.procs # The number of nodes per domain. - nxperdomain = nx / nxdomains + nxperdomain = nx // nxdomains nxremainder = nx % nxdomains - nyperdomain = ny / nydomains + nyperdomain = ny // nydomains nyremainder = ny % nydomains assert nxremainder < nxdomains assert nyremainder < nydomains @@ -84,7 +84,7 @@ def __init__(self, # Compute our domain indicies. ixdomain = mpi.rank % nxdomains - iydomain = mpi.rank / nxdomains + iydomain = mpi.rank // nxdomains ixmin = nodeindex(ixdomain, nxperdomain, nxremainder) ixmax = nodeindex(ixdomain + 1, nxperdomain, nxremainder) iymin = nodeindex(iydomain, nyperdomain, nyremainder) diff --git a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py index 791c05dd1..cc32dc554 100644 --- a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py +++ b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py @@ -275,8 +275,8 @@ generator = GenerateSquareNodeDistribution(nRadial, nTheta, rho0, - xmin, - xmax, + xmin=xmin, + xmax=xmax, nNodePerh = nPerh, SPH = not asph) else: diff --git a/tests/functional/Hydro/Noh/Noh-planar-1d.py b/tests/functional/Hydro/Noh/Noh-planar-1d.py index bbbb2d9fa..aa0f468bc 100644 --- a/tests/functional/Hydro/Noh/Noh-planar-1d.py +++ b/tests/functional/Hydro/Noh/Noh-planar-1d.py @@ -50,17 +50,17 @@ # # GSPH # -#ATS:t500 = test( SELF, "--gsph True --gsphReconstructionGradient=RiemannGradient --graphics None --clearDirectories True --checkError True --restartStep 20", label="Planar Noh problem with GSPH and RiemannGradient -- 1-D (serial)") -#ATS:t501 = testif(t500, SELF, "--gsph True --gsphReconstructionGradient=RiemannGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with GSPH and RiemannGradient -- 1-D (serial) RESTART CHECK") -#ATS:t502 = test( SELF, "--gsph True --gsphReconstructionGradient=HydroAccelerationGradient --graphics None --clearDirectories True --checkError True --restartStep 20", label="Planar Noh problem with GSPH and and HydroAccelerationGradient -- 1-D (serial)") -#ATS:t503 = testif(t502, SELF, "--gsph True --gsphReconstructionGradient=HydroAccelerationGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with GSPH and HydroAccelerationGradient -- 1-D (serial) RESTART CHECK") -#ATS:t504 = test( SELF, "--gsph True --gsphReconstructionGradient=SPHGradient --graphics None --clearDirectories True --checkError True --restartStep 20", label="Planar Noh problem with GSPH and SPHGradient -- 1-D (serial)") -#ATS:t505 = testif(t504, SELF, "--gsph True --gsphReconstructionGradient=SPHGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with GSPH and SPHGradient -- 1-D (serial) RESTART CHECK") +#ATS:t500 = test( SELF, "--gsph True --gsphReconstructionGradient RiemannGradient --graphics None --clearDirectories True --checkError True --restartStep 20", label="Planar Noh problem with GSPH and RiemannGradient -- 1-D (serial)") +#ATS:t501 = testif(t500, SELF, "--gsph True --gsphReconstructionGradient RiemannGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with GSPH and RiemannGradient -- 1-D (serial) RESTART CHECK") +#ATS:t502 = test( SELF, "--gsph True --gsphReconstructionGradient HydroAccelerationGradient --graphics None --clearDirectories True --checkError True --restartStep 20", label="Planar Noh problem with GSPH and and HydroAccelerationGradient -- 1-D (serial)") +#ATS:t503 = testif(t502, SELF, "--gsph True --gsphReconstructionGradient HydroAccelerationGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with GSPH and HydroAccelerationGradient -- 1-D (serial) RESTART CHECK") +#ATS:t504 = test( SELF, "--gsph True --gsphReconstructionGradient SPHGradient --graphics None --clearDirectories True --checkError True --restartStep 20", label="Planar Noh problem with GSPH and SPHGradient -- 1-D (serial)") +#ATS:t505 = testif(t504, SELF, "--gsph True --gsphReconstructionGradient SPHGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with GSPH and SPHGradient -- 1-D (serial) RESTART CHECK") # # MFM # -#ATS:t600 = test( SELF, "--mfm True --gsphReconstructionGradient=RiemannGradient --graphics None --clearDirectories True --checkError False --restartStep 20", label="Planar Noh problem with MFM -- 1-D (serial)") -#ATS:t601 = testif(t600, SELF, "--mfm True --gsphReconstructionGradient=RiemannGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with MFM -- 1-D (serial) RESTART CHECK") +#ATS:t600 = test( SELF, "--mfm True --gsphReconstructionGradient RiemannGradient --graphics None --clearDirectories True --checkError False --restartStep 20", label="Planar Noh problem with MFM -- 1-D (serial)") +#ATS:t601 = testif(t600, SELF, "--mfm True --gsphReconstructionGradient RiemannGradient --graphics None --clearDirectories False --checkError False --restartStep 20 --restoreCycle 20 --steps 20 --checkRestart True", label="Planar Noh problem with MFM -- 1-D (serial) RESTART CHECK") import os, shutil, sys from SolidSpheral1d import * diff --git a/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py b/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py index 378b308df..fe4bb456e 100644 --- a/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py +++ b/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py @@ -70,8 +70,8 @@ volumeType = RKSumVolume, # gsph options - RiemannGradientType = RiemannGradient, # (RiemannGradient,SPHGradient,HydroAccelerationGradient,OnlyDvDxGradient,MixedMethodGradient) - linearReconstruction = False, + RiemannGradientType = SPHSameTimeGradient, # (RiemannGradient,SPHGradient,HydroAccelerationGradient,OnlyDvDxGradient,MixedMethodGradient) + linearReconstruction = True, # Artifical Viscosity boolReduceViscosity = False, @@ -106,6 +106,7 @@ # IO vizCycle = None, + vizDerivs = False, vizTime = 0.1, restoreCycle = -1, restartStep = 1000, @@ -355,7 +356,7 @@ compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, - gradientType = SPHGradient, + gradientType = RiemannGradientType, XSPH = XSPH, ASPH = asph, densityUpdate=densityUpdate, @@ -372,7 +373,7 @@ compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, - gradientType = RiemannGradient, + gradientType = RiemannGradientType, XSPH = XSPH, ASPH = asph, densityUpdate=densityUpdate, @@ -389,7 +390,7 @@ compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, - gradientType = SPHSameTimeGradient, + gradientType = RiemannGradientType, XSPH = XSPH, ASPH = asph, densityUpdate=densityUpdate, @@ -431,6 +432,8 @@ if not (gsph or mfm or mfv): q = hydro.Q + q.Cq = 2 + q.Cl = 2 output("q") output("q.Cl") output("q.Cq") @@ -501,6 +504,7 @@ restoreCycle = restoreCycle, vizMethod = vizMethod, vizBaseName = "Sedov-cylindrical-2d-%ix%i" % (nRadial, nTheta), + vizDerivs=vizDerivs, vizDir = vizDir, vizStep = vizCycle, vizTime = vizTime, @@ -623,6 +627,7 @@ # Plot the final state. #------------------------------------------------------------------------------- if graphics: + from SpheralMatplotlib import * rPlot = plotNodePositions2d(db, colorNodeLists=0, colorDomains=1) rhoPlot, velPlot, epsPlot, PPlot, HPlot = plotRadialState(db) plotAnswer(answer, control.time(), @@ -635,30 +640,30 @@ (HPlot, "Sedov-cylindrical-h.png")] # Plot the specific entropy. - AsimData = Gnuplot.Data(xprof, A, - with_ = "points", - title = "Simulation", - inline = True) - AansData = Gnuplot.Data(xprof, Aans, - with_ = "lines", - title = "Solution", - inline = True) + # AsimData = Gnuplot.Data(xprof, A, + # with_ = "points", + # title = "Simulation", + # inline = True) + # AansData = Gnuplot.Data(xprof, Aans, + # with_ = "lines", + # title = "Solution", + # inline = True) - Aplot = generateNewGnuPlot() - Aplot.plot(AsimData) - Aplot.replot(AansData) - Aplot.title("Specific entropy") - Aplot.refresh() - plots.append((Aplot, "Sedov-cylindrical-entropy.png")) - - if boolCullenViscosity: - cullAlphaPlot = plotFieldList(q.ClMultiplier(), - xFunction = "%s.magnitude()", - plotStyle = "points", - winTitle = "Cullen alpha") - plots += [(cullAlphaPlot, "Sedov-planar-Cullen-alpha.png")] + # Aplot = generateNewGnuPlot() + # Aplot.plot(AsimData) + # Aplot.replot(AansData) + # Aplot.title("Specific entropy") + # Aplot.refresh() + # plots.append((Aplot, "Sedov-cylindrical-entropy.png")) + + # if boolCullenViscosity: + # cullAlphaPlot = plotFieldList(q.ClMultiplier(), + # xFunction = "%s.magnitude()", + # plotStyle = "points", + # winTitle = "Cullen alpha") + # plots += [(cullAlphaPlot, "Sedov-planar-Cullen-alpha.png")] # Make hardcopies of the plots. for p, filename in plots: - p.hardcopy(os.path.join(dataDir, filename), terminal="png") + p.figure.savefig(os.path.join(dataDir, filename)) From 7fcf32dde8e867c2add98aa37595a1753529d97d Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Thu, 28 Sep 2023 13:23:50 -0700 Subject: [PATCH 42/60] GSPH: removing uneccessary policy --- src/GSPH/Policies/ALEPositionPolicy.cc | 91 ------------------- src/GSPH/Policies/ALEPositionPolicy.hh | 63 ------------- src/GSPH/Policies/ALEPositionPolicyInst.cc.py | 11 --- 3 files changed, 165 deletions(-) delete mode 100644 src/GSPH/Policies/ALEPositionPolicy.cc delete mode 100644 src/GSPH/Policies/ALEPositionPolicy.hh delete mode 100644 src/GSPH/Policies/ALEPositionPolicyInst.cc.py diff --git a/src/GSPH/Policies/ALEPositionPolicy.cc b/src/GSPH/Policies/ALEPositionPolicy.cc deleted file mode 100644 index f349e37cd..000000000 --- a/src/GSPH/Policies/ALEPositionPolicy.cc +++ /dev/null @@ -1,91 +0,0 @@ -//---------------------------------Spheral++----------------------------------// -// ALEPositionPolicy -- This is basically a direct copy of the standard -// position policy but instead we're substituting in -// the nodal velocity as the derivative. -// -// J. M. Pearl 2023 -//----------------------------------------------------------------------------// - -#include "ALEPositionPolicy.hh" -#include "GSPH/GSPHFieldNames.hh" -#include "NodeList/FluidNodeList.hh" -#include "DataBase/FieldListUpdatePolicyBase.hh" -#include "DataBase/IncrementFieldList.hh" -#include "DataBase/ReplaceState.hh" -#include "DataBase/State.hh" -#include "DataBase/StateDerivatives.hh" -#include "Field/FieldList.hh" -#include "Utilities/DBC.hh" -#include "Geometry/Dimension.hh" - -namespace Spheral { - - -//------------------------------------------------------------------------------ -// Constructor. -//------------------------------------------------------------------------------ -template -ALEPositionPolicy:: -ALEPositionPolicy(): - IncrementFieldList() { -} - -//------------------------------------------------------------------------------ -// Destructor. -//------------------------------------------------------------------------------ -template -ALEPositionPolicy:: -~ALEPositionPolicy() { -} - -//------------------------------------------------------------------------------ -// Update the field. -//------------------------------------------------------------------------------ -template -void -ALEPositionPolicy:: -update(const KeyType& key, - State& state, - StateDerivatives& /*derivs*/, - const double multiplier, - const double /*t*/, - const double /*dt*/) { - KeyType fieldKey, nodeListKey; - StateBase::splitFieldKey(key, fieldKey, nodeListKey); - REQUIRE(fieldKey == HydroFieldNames::position and - nodeListKey == UpdatePolicyBase::wildcard()); - auto r = state.fields(fieldKey, Vector::zero); - const auto numFields = r.numFields(); - - // Get the velocity and acceleration fields. - const auto vel = state.fields(GSPHFieldNames::nodalVelocity, Vector::zero); - - std::cout << "ALE POSITION UPDATE" << std::endl; - // Walk the fields. - for (auto i = 0u; i != numFields; ++i) { - const auto n = r[i]->numInternalElements(); - for (auto j = 0u; j < n; ++j) { - r(i,j) += multiplier*vel(i,j); - } - } -} - -//------------------------------------------------------------------------------ -// Equivalence operator. -//------------------------------------------------------------------------------ -template -bool -ALEPositionPolicy:: -operator==(const UpdatePolicyBase& rhs) const { - - // We're only equal if the other guy is also an increment operator. - const ALEPositionPolicy* rhsPtr = dynamic_cast*>(&rhs); - if (rhsPtr == 0) { - return false; - } else { - return true; - } -} - -} - diff --git a/src/GSPH/Policies/ALEPositionPolicy.hh b/src/GSPH/Policies/ALEPositionPolicy.hh deleted file mode 100644 index d85f8a8d7..000000000 --- a/src/GSPH/Policies/ALEPositionPolicy.hh +++ /dev/null @@ -1,63 +0,0 @@ -//---------------------------------Spheral++----------------------------------// -// ALEPositionPolicy -- This is basically a direct copy of the standard -// position policy but instead we're substituting in -// the nodal velocity as the derivative. -// -// J. M. Pearl 2023 -//----------------------------------------------------------------------------// -#ifndef __Spheral_ALEPositionPolicy_hh__ -#define __Spheral_ALEPositionPolicy_hh__ - -#include "DataBase/IncrementFieldList.hh" - -#include - -namespace Spheral { - -// Forward declarations. -template class State; -template class StateDerivatives; -template class FluidNodeList; -template class FieldList; - -template -class ALEPositionPolicy: - public IncrementFieldList { -public: - //--------------------------- Public Interface ---------------------------// - // Useful typedefs - typedef typename Dimension::Scalar Scalar; - typedef typename Dimension::Vector Vector; - typedef typename FieldListUpdatePolicyBase::KeyType KeyType; - - // Constructors, destructor. - ALEPositionPolicy(); - virtual ~ALEPositionPolicy(); - - // Overload the methods describing how to update Fields. - virtual void update(const KeyType& key, - State& state, - StateDerivatives& derivs, - const double multiplier, - const double t, - const double dt); - - // Equivalence. - virtual bool operator==(const UpdatePolicyBase& rhs) const; - -private: - //--------------------------- Private Interface ---------------------------// - ALEPositionPolicy(const ALEPositionPolicy& rhs); - ALEPositionPolicy& operator=(const ALEPositionPolicy& rhs); -}; - -} - -#else - -// Forward declaration. -namespace Spheral { - template class ALEPositionPolicy; -} - -#endif diff --git a/src/GSPH/Policies/ALEPositionPolicyInst.cc.py b/src/GSPH/Policies/ALEPositionPolicyInst.cc.py deleted file mode 100644 index a7f765ea6..000000000 --- a/src/GSPH/Policies/ALEPositionPolicyInst.cc.py +++ /dev/null @@ -1,11 +0,0 @@ -text = """ -//------------------------------------------------------------------------------ -// Explicit instantiation. -//------------------------------------------------------------------------------ -#include "GSPH/Policies/ALEPositionPolicy.cc" -#include "Geometry/Dimension.hh" - -namespace Spheral { - template class ALEPositionPolicy >; -} -""" From 5a429c3c2237f32ed65bd553a709739f9e685ef7 Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Sun, 15 Oct 2023 09:02:32 -0700 Subject: [PATCH 43/60] stowing for a pull --- src/GSPH/GSPHEvaluateDerivatives.cc | 3 +- src/GSPH/GenericRiemannHydro.hh | 6 + src/GSPH/MFVEvaluateDerivatives.cc | 261 ++++++++++++---------------- src/GSPH/MFVHydroBase.cc | 52 ++---- src/GSPH/MFVHydroBase.hh | 23 ++- src/GSPH/MFVHydroBaseInline.hh | 4 +- 6 files changed, 156 insertions(+), 193 deletions(-) diff --git a/src/GSPH/GSPHEvaluateDerivatives.cc b/src/GSPH/GSPHEvaluateDerivatives.cc index 3569c2fd6..bf8b81f57 100644 --- a/src/GSPH/GSPHEvaluateDerivatives.cc +++ b/src/GSPH/GSPHEvaluateDerivatives.cc @@ -277,10 +277,9 @@ evaluateDerivatives(const typename Dimension::Scalar time, //------------------------------------------------------ const auto deltaDepsDti = 2.0*Pstar*Ai.dot(vi-vstar); const auto deltaDepsDtj = 2.0*Pstar*Aj.dot(vstar-vj); - DepsDti += deltaDepsDti/mi; DepsDtj += deltaDepsDtj/mj; - + if(compatibleEnergy){ const auto invmij = 1.0/(mi*mj); pairAccelerations[kk] = deltaDvDt*invmij; diff --git a/src/GSPH/GenericRiemannHydro.hh b/src/GSPH/GenericRiemannHydro.hh index 446098c9c..5e02c3b7a 100644 --- a/src/GSPH/GenericRiemannHydro.hh +++ b/src/GSPH/GenericRiemannHydro.hh @@ -25,6 +25,12 @@ enum class GradientType { NoGradient = 6 }; +enum class GSPHEvolutionType { + IdealH = 0, + IntegrateH = 1, + constantNeighborCount = 2 +}; + template class State; template class StateDerivatives; template class SmoothingScaleBase; diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index c7406ac46..e641c78b0 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -1,15 +1,28 @@ namespace Spheral { + +template +void +MFVHydroBase:: +evaluateDerivatives(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const { + this->firstDerivativesLoop(time,dt,dataBase,state,derivatives); + this->secondDerivativesLoop(time,dt,dataBase,state,derivatives); + //this->setH(time,dt,dataBase,state,derivatves) +} //------------------------------------------------------------------------------ // Determine the principle derivatives. //------------------------------------------------------------------------------ template void MFVHydroBase:: -evaluateDerivatives(const typename Dimension::Scalar time, - const typename Dimension::Scalar dt, - const DataBase& dataBase, - const State& state, - StateDerivatives& derivatives) const { +secondDerivativesLoop(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const { const auto& riemannSolver = this->riemannSolver(); @@ -72,8 +85,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto normalization = derivatives.fields(HydroFieldNames::normalization, 0.0); auto DxDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::position, Vector::zero); auto DvolDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::volume, 0.0); - //auto DvDt = derivatives.fields(HydroFieldNames::hydroAcceleration, Vector::zero); - //auto DepsDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy, 0.0); auto DmDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, 0.0); auto DEDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, 0.0); auto DpDt = derivatives.fields(IncrementFieldList::prefix() + GSPHFieldNames::momentum, Vector::zero); @@ -83,21 +94,18 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto XSPHDeltaV = derivatives.fields(HydroFieldNames::XSPHDeltaV, Vector::zero); auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); - auto XSPHHfield = derivatives.fields("XSPHHfield", SymTensor::zero); - + auto HStretchTensor = derivatives.fields("HStretchTensor", SymTensor::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - auto& pairAccelerations = derivatives.getAny(HydroFieldNames::pairAccelerations, vector()); auto& pairDepsDt = derivatives.getAny(HydroFieldNames::pairWork, vector()); auto& pairMassFlux = derivatives.getAny(GSPHFieldNames::pairMassFlux, vector()); + CHECK(DrhoDx.size() == numNodeLists); CHECK(M.size() == numNodeLists); CHECK(normalization.size() == numNodeLists); CHECK(DxDt.size() == numNodeLists); CHECK(DvolDt.size() == numNodeLists); - //CHECK(DvDt.size() == numNodeLists); - //CHECK(DepsDt.size() == numNodeLists); CHECK(DEDt.size() == numNodeLists); CHECK(DpDt.size() == numNodeLists); CHECK(DvDx.size() == numNodeLists); @@ -106,6 +114,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, CHECK(XSPHDeltaV.size() == numNodeLists); CHECK(weightedNeighborSum.size() == numNodeLists); CHECK(massSecondMoment.size() == numNodeLists); + CHECK(HStretchTensor.size() == numNodeLists); CHECK(newRiemannDpDx.size() == numNodeLists); CHECK(newRiemannDvDx.size() == numNodeLists); @@ -115,8 +124,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, pairMassFlux.resize(npairs); } - this->computeMCorrection(time,dt,dataBase,state,derivatives); - // Walk all the interacting pairs. #pragma omp parallel { @@ -126,11 +133,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, Vector gradPsii, gradPsij, Ai, Aj, vstar; typename SpheralThreads::FieldListStack threadStack; - //auto DvDt_thread = DvDt.threadCopy(threadStack); auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); - auto XSPHHfield_thread = XSPHHfield.threadCopy(threadStack); - //auto DepsDt_thread = DepsDt.threadCopy(threadStack); auto DvolDt_thread = DvolDt.threadCopy(threadStack); auto DmDt_thread = DmDt.threadCopy(threadStack); auto DEDt_thread = DEDt.threadCopy(threadStack); @@ -140,7 +144,14 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); auto XSPHDeltaV_thread = XSPHDeltaV.threadCopy(threadStack); auto normalization_thread = normalization.threadCopy(threadStack); - + auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); + + // this is kind of criminal and should be fixed, but for testing purposes + // I'm going to stay its allowable. We're going to zero out the thread + // copy of the Hstretch Tensor so that we can zero it out then replace + // the original with the smoothed version. + HStretchTensor_thread.Zero(); + #pragma omp for for (auto kk = 0u; kk < npairs; ++kk) { i = pairs[kk].i_node; @@ -166,14 +177,11 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& Hi = H(nodeListi, i); const auto& ci = soundSpeed(nodeListi, i); const auto Hdeti = Hi.Determinant(); - //CHECK(mi > 0.0); CHECK(voli > 0.0); CHECK(rhoi > 0.0); CHECK(Hdeti > 0.0); auto& normi = normalization_thread(nodeListi,i); - //auto& DvDti = DvDt_thread(nodeListi, i); - //auto& DepsDti = DepsDt_thread(nodeListi, i); auto& DvolDti = DvolDt_thread(nodeListi,i); auto& DmDti = DmDt_thread(nodeListi, i); auto& DEDti = DEDt_thread(nodeListi, i); @@ -183,7 +191,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& DvDxi = DvDx_thread(nodeListi, i); auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi, i); - auto& XSPHHfieldi = XSPHHfield_thread(nodeListi,i); auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); const auto& gradRhoi = DrhoDx(nodeListi, i); const auto& Mi = M(nodeListi,i); @@ -194,7 +201,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& riemannDpDxj = riemannDpDx(nodeListj, j); const auto& riemannDvDxj = riemannDvDx(nodeListj, j); const auto& rj = position(nodeListj, j); - //const auto& mj = mass(nodeListj, j); const auto& vj = velocity(nodeListj, j); const auto& rhoj = massDensity(nodeListj, j); const auto& volj = volume(nodeListj, j); @@ -203,14 +209,11 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto& Hj = H(nodeListj, j); const auto& cj = soundSpeed(nodeListj, j); const auto Hdetj = Hj.Determinant(); - //CHECK(mj > 0.0); CHECK(rhoj > 0.0); CHECK(volj > 0.0); CHECK(Hdetj > 0.0); auto& normj = normalization_thread(nodeListj,j); - //auto& DvDtj = DvDt_thread(nodeListj, j); - //auto& DepsDtj = DepsDt_thread(nodeListj, j); auto& DvolDtj = DvolDt_thread(nodeListj,j); auto& DmDtj = DmDt_thread(nodeListj, j); auto& DEDtj = DEDt_thread(nodeListj, j); @@ -220,7 +223,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, auto& DvDxj = DvDx_thread(nodeListj, j); auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); auto& massSecondMomentj = massSecondMoment(nodeListj, j); - auto& XSPHHfieldj = XSPHHfield_thread(nodeListj,j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); const auto& gradRhoj = DrhoDx(nodeListj, j); const auto& Mj = M(nodeListj,j); @@ -256,21 +258,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto Astar = voli*gradPsii + volj*gradPsij; - // Zero'th and second moment of the node distribution -- used for the - // ideal H calculation. - const auto rij2 = rij.magnitude2(); - const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); - weightedNeighborSumi += std::abs(gWi); - weightedNeighborSumj += std::abs(gWj); - massSecondMomenti += gradWi.magnitude2()*thpt; - massSecondMomentj += gradWj.magnitude2()*thpt; - //const auto rij2 = rij.magnitude2(); - //const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); - //weightedNeighborSumi += std::abs(gWi); - //weightedNeighborSumj += std::abs(gWj); - // massSecondMomenti -= voli*rij.selfdyad()*gWi/rMagij;//.magnitude2()*thpt; - // massSecondMomentj -= volj*rij.selfdyad()*gWj/rMagij;//.magnitude2()*thpt; - // Determine an effective pressure including a term to fight the tensile instability. //const auto fij = epsTensile*pow(Wi/(Hdeti*WnPerh), nTensile); const auto fij = epsTensile*FastMath::pow4(Wi/(Hdeti*WnPerh)); @@ -336,9 +323,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto deltaDepsDti = Pstar*Astar.dot(vi-vstar) - energyFlux; const auto deltaDepsDtj = Pstar*Astar.dot(vstar-vj) + energyFlux; - //DepsDti += deltaDepsDti/mi; - //DepsDtj += deltaDepsDtj/mj; - DEDti += deltaDepsDti; DEDtj += deltaDepsDtj; @@ -374,8 +358,8 @@ evaluateDerivatives(const typename Dimension::Scalar time, case GradientType::HydroAccelerationGradient: // based on hydro accel for DpDx newRiemannDvDxi -= deltaDvDxi; newRiemannDvDxj -= deltaDvDxj; - newRiemannDpDxi += deltaDvDt/voli; - newRiemannDpDxj -= deltaDvDt/volj; + newRiemannDpDxi += Pstar*Astar/voli; + newRiemannDpDxj -= Pstar*Astar/volj; break; case GradientType::SPHGradient: // raw gradients newRiemannDvDxi -= (vi-vj).dyad(gradPsii); @@ -391,7 +375,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, break; default: break; - // do nada } // XSPH @@ -401,16 +384,10 @@ evaluateDerivatives(const typename Dimension::Scalar time, XSPHDeltaVj -= psij*(vj-vi); } - //if (sameMatij and diffuseEnergy){ - //linearReconstruction(ri,rj,epsi,epsj,DepsDxi,DepsDxj,epsLineari,epsLinearj); - //const auto cijEff = max(min(cij + (vi-vj).dot(rhatij), cij),0.0); - //const auto diffusion = epsDiffusionCoeff*cijEff*(Hi-Hj)*etaij.dot(gradPsii)/(etaMagij*etaMagij+tiny); - //XSPHHfieldi += psii*(massSecondMomentj);//ci*(Hi-Hj)*etai.dot(gradPsii)/(etaMagi*etaMagi+tiny); - //XSPHHfieldj += psij*(massSecondMomenti);//cj*(Hj-Hi)*etaj.dot(gradPsij)/(etaMagj*etaMagj+tiny);i normi += psii; normj += psij; - } //if statement + } //if statement } // loop over pairs threadReduceFieldLists(threadStack); } // OpenMP parallel region @@ -424,148 +401,105 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto hminratio = nodeList.hminratio(); const auto nPerh = nodeList.nodesPerSmoothingScale(); const auto kernelExtent = nodeList.neighbor().kernelExtent(); - const auto ni = nodeList.numInternalNodes(); + const auto ni = nodeList.numInternalNodes(); #pragma omp parallel for for (auto i = 0u; i < ni; ++i) { // Get the state for node i. const auto& ri = position(nodeListi, i); - //const auto& mi = mass(nodeListi, i); const auto& voli = volume(nodeListi,i); - //const auto& vi = velocity(nodeListi, i); const auto& ui = nodalVelocity(nodeListi,i); const auto& Hi = H(nodeListi, i); const auto Hdeti = Hi.Determinant(); - //CHECK(mi > 0.0); CHECK(voli > 0.0); CHECK(Hdeti > 0.0); auto& normi = normalization(nodeListi, i); auto& DxDti = DxDt(nodeListi, i); auto& DvolDti = DvolDt(nodeListi, i); - //auto& DvDti = DvDt(nodeListi, i); // FIX THIS - //auto& DepsDti = DepsDt(nodeListi, i); auto& DvDxi = DvDx(nodeListi, i); auto& DHDti = DHDt(nodeListi, i); auto& Hideali = Hideal(nodeListi, i); auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); - auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); - auto& massSecondMomenti = massSecondMoment(nodeListi, i); - auto& XSPHHfieldi = XSPHHfield(nodeListi, i); + const auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); + const auto& massSecondMomenti = massSecondMoment(nodeListi, i); + const auto& HStretchTensori = HStretchTensor(nodeListi, i); normi += voli*Hdeti*W0; - XSPHHfieldi += voli*Hdeti*W0*massSecondMomenti; - //XSPHHfieldi /= max(normi,tiny); - XSPHHfieldi /= Dimension::rootnu(std::max(XSPHHfieldi.Determinant(),tiny)); - DvolDti *= voli; // If needed finish the total energy derivative. //if (totalEnergy) DepsDti = mi*(vi.dot(DvDti) + DepsDti); - // Complete the moments of the node distribution for use in the ideal H calculation. - //weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); - // Determine the position evolution, based on whether we're doing XSPH or not. DxDti = ui; if (xsph){ DxDti += XSPHDeltaVi/max(tiny, normi); } - if(true){ - // The H tensor evolution. - // Complete the moments of the node distribution for use in the ideal H calculation. - weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); - massSecondMomenti /= Hdeti*Hdeti; - DHDti = smoothingScale.smoothingScaleDerivative(Hi, + if(false){ + DHDti = smoothingScale.smoothingScaleDerivative(Hi, ri, DvDxi, hmin, hmax, hminratio, nPerh); - - //DHDti = 0.3*std::min(std::max((Ngb - 16.0),-1.0),1.0)/16.0 * Hi / dt; - Hideali = smoothingScale.newSmoothingScale(Hi, - ri, - weightedNeighborSumi, - massSecondMomenti, - W, - hmin, - hmax, - hminratio, - nPerh, - connectivityMap, - nodeListi, - i); + Hideali = smoothingScale.newSmoothingScale(Hi, // Hi + ri, // ri + weightedNeighborSumi, // ? + massSecondMomenti, // Hstretch tensor + W, // W + hmin, // hmin + hmax, // hmax + hminratio, // hminratio + nPerh, // Ngb + connectivityMap, // connectivityMap + nodeListi, // nodeListi + i); // i }else{ - const auto Ngb_target = (Dimension::nDim == 3 ? 32 : + // smoothing scale construction + const auto Ngb_target = (Dimension::nDim == 3 ? 32 : (Dimension::nDim == 2 ? 16 : 4)); - const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : - (Dimension::nDim == 2 ? 3.1415 : - 1.0)); - // const auto detMSM = massSecondMomenti.Determinant(); - // weightedNeighborSumi = detMSM;//abs(XSPHHfieldi.Determinant()/max(Hdeti,tiny)); - // //const auto weightH = std::min(100*std::abs(weightedNeighborSumi),1.0); - // //const auto Heffi = Hi ; - // //if(abs(detMSM) > 1e-10){ - // massSecondMomenti /= Dimension::rootnu(detMSM); - - - // control that shape poopsie - const auto circlerFactor = 0.00;//std::max(std::min(1.0,500.0*weightedNeighborSumi),0.05);//min(weightH,0.3); - const auto stretchFactor = 0.4; + const auto stretchFactor = 0.25; + // set on construction + const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : + (Dimension::nDim == 2 ? 3.1415 : + 1.0)); + + // pass const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - //const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - //const auto Hstretch = ((1.00-stretchFactor)* SymTensor::one + - // stretchFactor * XSPHHfieldi)*Hi; + + const auto Hstretch = ((1.00-stretchFactor)* SymTensor::one + + stretchFactor * HStretchTensori)*Hi; + const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - Hideali = std::min(std::max(scaleFactor,0.8),1.2) * Hi; - // scale to enforce hmin/hmax + Hideali = std::min(std::max(scaleFactor,0.8),1.2) * Hstretch; + DHDti = 0.25*(Hideali-Hi)/dt; - } - - - const auto C2 = (Dimension::nDim == 3 ? 1.33333*3.1415 : - (Dimension::nDim == 2 ? 3.1415 : - 1.0)); - weightedNeighborSumi = C2 /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - // } else{ - // const auto stretchFactor = 0.00; - // const auto circlerFactor = 0.3; - // const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - // const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - // ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; - // const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - // Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; - // DHDti = 0.25*(Hideali-Hi)/dt; - // } + } } // nodes loop } // nodeLists loop } // eval derivs method -//Ngb = 3.1415/(Hdeti*sum(Wi)) -//dNdh = -3.1415/voliHdeti^2 dHdetidh - 3.1415/HdetiVoli^2 dVolidh -// Ngb = C h ^nu sum (W) -// dNdh = -N/h -//Hdeti = h3 -//3h^2 //------------------------------------------------------------------------------ // EvalDerivs subroutine for spatial derivs //------------------------------------------------------------------------------ template void MFVHydroBase:: -computeMCorrection(const typename Dimension::Scalar /*time*/, - const typename Dimension::Scalar /*dt*/, - const DataBase& dataBase, - const State& state, - StateDerivatives& derivatives) const { +firstDerivativesLoop(const typename Dimension::Scalar /*time*/, + const typename Dimension::Scalar /*dt*/, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const { + const auto tiny = std::numeric_limits::epsilon(); + const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient or this->gradientType() == GradientType::SPHUncorrectedGradient); const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient); @@ -597,11 +531,15 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); - + auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); + auto HStretchTensor = derivatives.fields("HStretchTensor", SymTensor::zero); CHECK(M.size() == numNodeLists); CHECK(DrhoDx.size() == numNodeLists); CHECK(newRiemannDpDx.size() == numNodeLists); CHECK(newRiemannDvDx.size() == numNodeLists); + CHECK(massSecondMoment.size() == numNodeLists) + CHECK(weightedNeighborSum.size() == numNodeLists) + CHECK(HStretchTensor.size() == numNodeLists) // The set of interacting node pairs. const auto& pairs = connectivityMap.nodePairList(); @@ -618,6 +556,9 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); + auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); + auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); + #pragma omp for for (auto kk = 0u; kk < npairs; ++kk) { i = pairs[kk].i_node; @@ -634,6 +575,8 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(voli > 0.0); CHECK(Hdeti > 0.0); + auto& HStretchTensori = HStretchTensor_thread(nodeListi,i); + auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi,i); auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); auto& DrhoDxi = DrhoDx_thread(nodeListi, i); auto& Mi = M_thread(nodeListi, i); @@ -647,6 +590,8 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, CHECK(volj > 0.0); CHECK(Hdetj > 0.0); + auto& HStretchTensorj = HStretchTensor_thread(nodeListj,j); + auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj,j); auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); auto& DrhoDxj = DrhoDx_thread(nodeListj, j); auto& Mj = M_thread(nodeListj, j); @@ -672,14 +617,24 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, const auto gradPsii = voli*gradWi; const auto gradPsij = volj*gradWj; + weightedNeighborSumi += std::abs(gWi); + weightedNeighborSumj += std::abs(gWj); + + HStretchTensori -= voli*rij.selfdyad()*gWi*rMagij; + HStretchTensorj -= volj*rij.selfdyad()*gWj*rMagij; + + const auto rij2 = rij.magnitude2(); + const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); + massSecondMomenti += gradWi.magnitude2()*thpt; + massSecondMomentj += gradWj.magnitude2()*thpt; + + Mi -= rij.dyad(gradPsii); Mj -= rij.dyad(gradPsij); DrhoDxi -= (rhoi - rhoj) * gradPsii; DrhoDxj -= (rhoi - rhoj) * gradPsij; - //massSecondMomenti -= voli*rij.selfdyad()*gWi*rMagij;//.magnitude2()*thpt; - //massSecondMomentj -= volj*rij.selfdyad()*gWj*rMagij;//.magnitude2()*thpt; // // based on nodal values if (calcSpatialGradients){ @@ -709,17 +664,25 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { const auto& nodeList = M[nodeListi]->nodeList(); const auto ni = nodeList.numInternalNodes(); + #pragma omp parallel for for (auto i = 0u; i < ni; ++i) { - const auto numNeighborsi = connectivityMap.numNeighborsForNode(nodeListi, i); - auto& Mi = M(nodeListi, i); - //auto& massSecondMomenti = massSecondMoment(nodeListi,i); - //const auto detMSM = massSecondMomenti.Determinant(); - //massSecondMomenti /= Dimension::rootnu(detMSM); + const auto numNeighborsi = connectivityMap.numNeighborsForNode(nodeListi, i); + const auto& Hi = H(nodeListi, i); + const auto Hdeti = Hi.Determinant(); + + auto& Mi = M(nodeListi, i); + auto& massSecondMomenti = massSecondMoment(nodeListi,i); + auto& weightedNeighborSumi = weightedNeighborSum(nodeListi,i); + auto& HStretchTensori = HStretchTensor(nodeListi,i); const auto Mdeti = std::abs(Mi.Determinant()); + weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); + HStretchTensori /= Dimension::rootnu(max(HStretchTensori.Determinant(),tiny)); + massSecondMomenti /= Hdeti*Hdeti; + const auto enoughNeighbors = numNeighborsi > Dimension::pownu(2); const auto goodM = (Mdeti > 1e-2 and enoughNeighbors); @@ -738,7 +701,9 @@ computeMCorrection(const typename Dimension::Scalar /*time*/, for (ConstBoundaryIterator boundItr = this->boundaryBegin(); boundItr != this->boundaryEnd(); - ++boundItr)(*boundItr)->applyFieldListGhostBoundary(M); + ++boundItr){ + (*boundItr)->applyFieldListGhostBoundary(M); + } if (calcSpatialGradients){ for (ConstBoundaryIterator boundItr = this->boundaryBegin(); diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index 5a551f572..1de276f41 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -18,7 +18,9 @@ // 4) XSPH -------- nodal velocity = xsph velocity // 5) BackgroundPressure -- nodal acceleration = fluid // acceleration + Background pressure -// force to drive regularization. +// force to drive regularization. We'll +// probably also need some decay time +// to get back to u = v. // // Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic // Simulation Methods," MNRAS, 450(1):53-110 @@ -26,14 +28,12 @@ // J.M. Pearl 2023 //----------------------------------------------------------------------------// // TODO: -// 1 mass flux should be limited so we don't get issues with neg mass -// 2 need better timestep constraints -// 3 maybe seperate flux polies for all conserved variables -// similar to an advect step in ALE schemes. Might give better e-conserve -// 4 compatible energy for MFV -// -// 5 ADD DpDt and DmDt to the finalize bc application. +// 1 backpressure and fician particle shifting +// 2 Eulerian model will still crash on the Noh implosion due to void particles +// 3 Good implementation of Ngb update +// 4 treatment for material interfaces //---------------------------------------------------------------------------// + #include "FileIO/FileIO.hh" #include "NodeList/SmoothingScaleBase.hh" #include "Hydro/HydroFieldNames.hh" @@ -56,7 +56,6 @@ #include "GSPH/GSPHFieldNames.hh" #include "GSPH/computeSumVolume.hh" #include "GSPH/computeMFMDensity.hh" -#include "GSPH/Policies/ALEPositionPolicy.hh" #include "GSPH/Policies/MassFluxPolicy.hh" #include "GSPH/Policies/ReplaceWithRatioPolicy.hh" #include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" @@ -125,14 +124,14 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, mDthermalEnergyDt(FieldStorageType::CopyFields), mDmomentumDt(FieldStorageType::CopyFields), mDvolumeDt(FieldStorageType::CopyFields), - mXSPHHfield(FieldStorageType::CopyFields), + mHStretchTensor(FieldStorageType::CopyFields), mPairMassFlux(){ mNodalVelocity = dataBase.newFluidFieldList(Vector::zero, GSPHFieldNames::nodalVelocity); mDmassDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::mass); mDthermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); mDmomentumDt = dataBase.newFluidFieldList(Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum); mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::volume); - mXSPHHfield = dataBase.newFluidFieldList(SymTensor::zero, "XSPHHfield"); + mHStretchTensor = dataBase.newFluidFieldList(SymTensor::zero, "HStretchTensor"); mPairMassFlux.clear(); } @@ -174,7 +173,7 @@ registerState(DataBase& dataBase, auto mass = state.fields(HydroFieldNames::mass, 0.0); auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); - // ensure we're not sure compat energy scheme for pure-lang methods + // We use the thermal energy to update the specific thermal energy state.removePolicy(specificThermalEnergy); CHECK(position.numFields() == dataBase.numFluidNodeLists()); @@ -205,52 +204,37 @@ registerState(DataBase& dataBase, IncrementFieldList::prefix() + GSPHFieldNames::momentum, HydroFieldNames::specificThermalEnergy); - // special policies to get velocity update from momentum deriv - state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); + switch (mNodeMotionType){ - case NodeMotionType::Eulerian: + case NodeMotionType::Eulerian: // Eulerian { - //std::cout <<"Eulerian" << std::endl; - state.enroll(mNodalVelocity); // Eulerian + state.enroll(mNodalVelocity); } break; case NodeMotionType::Lagrangian: // pure MFV { - //std::cout <<"Lagrangian" << std::endl; auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::velocity, HydroFieldNames::velocity); // depends on state.enroll(mNodalVelocity, nodalVelocityPolicy); } break; case NodeMotionType::XSPH: - { // this is currently wrong, its the delta not the full xsph velocity and time step delayed - //std::cout <<"XSPH" << std::endl; + { auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::XSPHDeltaV); state.enroll(mNodalVelocity, nodalVelocityPolicy); } break; default: - //std::cout <<"default" << std::endl; break; } - // conditional for energy method if (this->compatibleEnergyEvolution()) { - //std::cout << "compatible MFV" << std::endl; auto thermalEnergyPolicy = std::make_shared>(dataBase); - //auto velocityPolicy = std::make_shared>(HydroFieldNames::position,HydroFieldNames::specificThermalEnergy,true); state.enroll(specificThermalEnergy, thermalEnergyPolicy); - //state.enroll(velocity, velocityPolicy); }else if (this->evolveTotalEnergy()) { - // warning not implemented yet std::cout <<"evolve total energy not implemented for MFV" << std::endl; - //auto thermalEnergyPolicy = std::make_shared>(); - //auto velocityPolicy = std::make_shared>(HydroFieldNames::position,HydroFieldNames::specificThermalEnergy,true); - //state.enroll(specificThermalEnergy, thermalEnergyPolicy); - //state.enroll(velocity, velocityPolicy); - } else { auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); auto velocityPolicy = std::make_shared>(HydroFieldNames::position,true); @@ -258,6 +242,8 @@ registerState(DataBase& dataBase, state.enroll(velocity, velocityPolicy); } + state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); + // normal state variables state.enroll(mass, massPolicy); state.enroll(massDensity, rhoPolicy); @@ -277,12 +263,12 @@ registerDerivatives(DataBase& dataBase, dataBase.resizeFluidFieldList(mDthermalEnergyDt, 0.0, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy, false); dataBase.resizeFluidFieldList(mDmomentumDt, Vector::zero, IncrementFieldList::prefix() + GSPHFieldNames::momentum, false); dataBase.resizeFluidFieldList(mDvolumeDt, 0.0, IncrementFieldList::prefix() + HydroFieldNames::volume, false); - dataBase.resizeFluidFieldList(mXSPHHfield,SymTensor::zero, "XSPHHfield", false); + dataBase.resizeFluidFieldList(mHStretchTensor,SymTensor::zero, "HStretchTensor", false); derivs.enroll(mDmassDt); derivs.enroll(mDthermalEnergyDt); derivs.enroll(mDmomentumDt); derivs.enroll(mDvolumeDt); - derivs.enroll(mXSPHHfield); + derivs.enroll(mHStretchTensor); derivs.enrollAny(GSPHFieldNames::pairMassFlux, mPairMassFlux); } diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 7b24d4ab1..03f433aaa 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -128,12 +128,19 @@ public: const State& state, StateDerivatives& derivatives) const override; void - computeMCorrection(const typename Dimension::Scalar time, - const typename Dimension::Scalar dt, - const DataBase& dataBase, - const State& state, - StateDerivatives& derivatives) const; - + firstDerivativesLoop(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const; + + void + secondDerivativesLoop(const typename Dimension::Scalar time, + const typename Dimension::Scalar dt, + const DataBase& dataBase, + const State& state, + StateDerivatives& derivatives) const; + // Finalize the derivatives. virtual void finalizeDerivatives(const Scalar time, @@ -160,7 +167,7 @@ public: const FieldList& DthermalEnergyDt() const; const FieldList& DmomentumDt() const; const FieldList& DvolumeDt() const; - const FieldList& xsphHfield() const; + const FieldList& HStretchTensor() const; const std::vector& pairMassFlux() const; @@ -179,7 +186,7 @@ private: FieldList mDthermalEnergyDt; FieldList mDmomentumDt; FieldList mDvolumeDt; - FieldList mXSPHHfield; + FieldList mHStretchTensor; std::vector mPairMassFlux; diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index 79c49c74a..48bc18695 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -70,7 +70,7 @@ template inline const FieldList& MFVHydroBase:: -xsphHfield() const { - return mXSPHHfield; +HStretchTensor() const { + return mHStretchTensor; } } \ No newline at end of file From 2404729f566c4dec00bf7cfc74e44f9b0228879d Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Tue, 9 Jan 2024 17:06:42 -0800 Subject: [PATCH 44/60] update GSPH branch for the bigmerge --- src/GSPH/GSPHHydros.py | 6 +- src/GSPH/GenericRiemannHydro.cc | 4 +- src/GSPH/MFMEvaluateDerivatives.cc | 30 ---- src/GSPH/MFVEvaluateDerivatives.cc | 204 +++++++++++++++---------- src/GSPH/MFVHydroBase.cc | 53 ++++--- src/GSPH/MFVHydroBase.hh | 6 + src/GSPH/MFVHydroBaseInline.hh | 18 +++ src/GSPH/initializeGradients.cc | 46 +++--- src/GSPH/initializeGradients.hh | 1 + src/GSPH/initializeGradientsInst.cc.py | 1 + src/PYB11/GSPH/MFVHydroBase.py | 3 + 11 files changed, 213 insertions(+), 159 deletions(-) diff --git a/src/GSPH/GSPHHydros.py b/src/GSPH/GSPHHydros.py index 9e10e906d..31166132b 100644 --- a/src/GSPH/GSPHHydros.py +++ b/src/GSPH/GSPHHydros.py @@ -184,6 +184,7 @@ def MFV(dataBase, riemannSolver=None, specificThermalEnergyDiffusionCoefficient = 0.0, cfl = 0.25, + nodeMotionCoefficient = 0.2, nodeMotionType = NodeMotionType.Lagrangian, gradientType = HydroAccelerationGradient, densityUpdate = IntegrateDensity, @@ -248,6 +249,7 @@ def MFV(dataBase, "evolveTotalEnergy" : evolveTotalEnergy, "XSPH" : XSPH, "correctVelocityGradient" : correctVelocityGradient, + "nodeMotionCoefficient" : nodeMotionCoefficient, "nodeMotionType" : nodeMotionType, "gradType" : gradientType, "densityUpdate" : densityUpdate, @@ -257,10 +259,10 @@ def MFV(dataBase, "xmin" : eval("Vector%id(%g, %g, %g)" % xmin), "xmax" : eval("Vector%id(%g, %g, %g)" % xmax)} - print(nodeMotionType) + #print(nodeMotionType) # Build and return the thing. result = Constructor(**kwargs) result._smoothingScaleMethod = smoothingScaleMethod - print(result.nodeMotionType) + #print(result.nodeMotionType) return result diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index e84c671df..f0dbad7aa 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -178,6 +178,7 @@ void GenericRiemannHydro:: initializeProblemStartup(DataBase& dataBase) { + const auto& connectivityMap = dataBase.connectivityMap(); auto mass = dataBase.fluidMass(); auto massDensity = dataBase.fluidMassDensity(); auto position = dataBase.fluidPosition(); @@ -200,13 +201,14 @@ initializeProblemStartup(DataBase& dataBase) { boundaryItr != this->boundaryEnd(); ++boundaryItr) (*boundaryItr)->finalizeGhostBoundary(); - initializeGradients(dataBase.connectivityMap(), + initializeGradients(connectivityMap, this->kernel(), position, H, mVolume, mPressure, velocity, + mM, mRiemannDpDx, mRiemannDvDx); diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index be780250e..c82ec35ce 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -418,36 +418,6 @@ evaluateDerivatives(const typename Dimension::Scalar time, connectivityMap, nodeListi, i); - // const auto Ngb_target = (Dimension::nDim == 3 ? 32 : - // (Dimension::nDim == 2 ? 16 : - // 4)); - // const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : - // (Dimension::nDim == 2 ? 3.1415 : - // 1.0)); - // const auto detMSM = massSecondMomenti.Determinant(); - // weightedNeighborSumi = detMSM;//XSPHHfieldi.Determinant()/Hdeti; - // if(abs(detMSM) > 1e-10){ - // massSecondMomenti /= Dimension::rootnu(detMSM); - - // const auto stretchFactor = 0.25; - // const auto circlerFactor = 0.30; - // const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - // const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - // ((1.00-stretchFactor-circlerFactor)*SymTensor::one + - // stretchFactor*massSecondMomenti)*Hi; - // const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - // Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; - // DHDti = 0.25*(Hideali-Hi)/dt; - // } else{ - // const auto stretchFactor = 0.00; - // const auto circlerFactor = 0.3; - // const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - // const auto Hstretch = circlerFactor * Dimension::rootnu(Hdeti)*SymTensor::one + - // ((1.00-stretchFactor-circlerFactor)*SymTensor::one)*Hi; - // const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - // Hideali = std::min(std::max(scaleFactor,0.9),1.1) * Hstretch; - // DHDti = 0.25*(Hideali-Hi)/dt; - // } } // nodes loop } // nodeLists loop diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index e641c78b0..9cb919a88 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -25,14 +25,11 @@ secondDerivativesLoop(const typename Dimension::Scalar time, StateDerivatives& derivatives) const { const auto& riemannSolver = this->riemannSolver(); - const auto& smoothingScale = this->smoothingScaleMethod(); // A few useful constants we'll use in the following loop. const auto tiny = std::numeric_limits::epsilon(); - const auto xsph = this->XSPH(); const auto epsTensile = this->epsilonTensile(); - //const auto epsDiffusionCoeff = this->specificThermalEnergyDiffusionCoefficient(); const auto compatibleEnergy = this->compatibleEnergyEvolution(); //const auto totalEnergy = this->evolveTotalEnergy(); const auto gradType = this->gradientType(); @@ -49,14 +46,14 @@ secondDerivativesLoop(const typename Dimension::Scalar time, // kernel const auto& W = this->kernel(); const auto WnPerh = W(1.0/nPerh, 1.0); - const auto W0 = W(0.0, 1.0); + //const auto W0 = W(0.0, 1.0); // Get the state and derivative FieldLists. // State FieldLists. const auto mass = state.fields(HydroFieldNames::mass, 0.0); const auto position = state.fields(HydroFieldNames::position, Vector::zero); const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); - const auto nodalVelocity = state.fields(GSPHFieldNames::nodalVelocity, Vector::zero); + //const auto nodalVelocity = state.fields(GSPHFieldNames::nodalVelocity, Vector::zero); const auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); const auto volume = state.fields(HydroFieldNames::volume, 0.0); const auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); @@ -66,7 +63,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, const auto riemannDpDx = state.fields(GSPHFieldNames::RiemannPressureGradient,Vector::zero); const auto riemannDvDx = state.fields(GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); - CHECK(nodalVelocity.size() == numNodeLists); + //CHECK(nodalVelocity.size() == numNodeLists); CHECK(mass.size() == numNodeLists); CHECK(position.size() == numNodeLists); CHECK(velocity.size() == numNodeLists); @@ -111,7 +108,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, CHECK(DvDx.size() == numNodeLists); CHECK(DHDt.size() == numNodeLists); CHECK(Hideal.size() == numNodeLists); - CHECK(XSPHDeltaV.size() == numNodeLists); + //CHECK(XSPHDeltaV.size() == numNodeLists); CHECK(weightedNeighborSum.size() == numNodeLists); CHECK(massSecondMoment.size() == numNodeLists); CHECK(HStretchTensor.size() == numNodeLists); @@ -129,12 +126,12 @@ secondDerivativesLoop(const typename Dimension::Scalar time, { // Thread private scratch variables int i, j, nodeListi, nodeListj; - Scalar psii,psij, Wi, gWi, Wj, gWj, Pstar, rhostari, rhostarj; - Vector gradPsii, gradPsij, Ai, Aj, vstar; + Scalar Wi, Wj, gWi, gWj, Pstar, rhostari, rhostarj; + Vector vstar; typename SpheralThreads::FieldListStack threadStack; - auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); - auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); + //auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); + //auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); auto DvolDt_thread = DvolDt.threadCopy(threadStack); auto DmDt_thread = DmDt.threadCopy(threadStack); auto DEDt_thread = DEDt.threadCopy(threadStack); @@ -143,14 +140,14 @@ secondDerivativesLoop(const typename Dimension::Scalar time, auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); auto XSPHDeltaV_thread = XSPHDeltaV.threadCopy(threadStack); - auto normalization_thread = normalization.threadCopy(threadStack); - auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); + //auto normalization_thread = normalization.threadCopy(threadStack); + //auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); // this is kind of criminal and should be fixed, but for testing purposes // I'm going to stay its allowable. We're going to zero out the thread // copy of the Hstretch Tensor so that we can zero it out then replace // the original with the smoothed version. - HStretchTensor_thread.Zero(); + // HStretchTensor_thread.Zero(); #pragma omp for for (auto kk = 0u; kk < npairs; ++kk) { @@ -165,7 +162,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, if( mi >tiny or mj > tiny){ // Get the state for node i. - const auto& ui = nodalVelocity(nodeListi,i); + //const auto& ui = nodalVelocity(nodeListi,i); const auto& riemannDpDxi = riemannDpDx(nodeListi, i); const auto& riemannDvDxi = riemannDvDx(nodeListi, i); const auto& ri = position(nodeListi, i); @@ -181,23 +178,24 @@ secondDerivativesLoop(const typename Dimension::Scalar time, CHECK(rhoi > 0.0); CHECK(Hdeti > 0.0); - auto& normi = normalization_thread(nodeListi,i); + //auto& normi = normalization_thread(nodeListi,i); auto& DvolDti = DvolDt_thread(nodeListi,i); auto& DmDti = DmDt_thread(nodeListi, i); auto& DEDti = DEDt_thread(nodeListi, i); auto& DpDti = DpDt_thread(nodeListi, i); + const auto& DxDti = DxDt(nodeListi,i); auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); auto& DvDxi = DvDx_thread(nodeListi, i); - auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); - auto& massSecondMomenti = massSecondMoment(nodeListi, i); + //auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi, i); + //auto& massSecondMomenti = massSecondMoment(nodeListi, i); auto& XSPHDeltaVi = XSPHDeltaV_thread(nodeListi,i); const auto& gradRhoi = DrhoDx(nodeListi, i); const auto& Mi = M(nodeListi,i); // Get the state for node j - const auto& uj = nodalVelocity(nodeListj,j); + //const auto& uj = nodalVelocity(nodeListj,j); const auto& riemannDpDxj = riemannDpDx(nodeListj, j); const auto& riemannDvDxj = riemannDvDx(nodeListj, j); const auto& rj = position(nodeListj, j); @@ -213,24 +211,25 @@ secondDerivativesLoop(const typename Dimension::Scalar time, CHECK(volj > 0.0); CHECK(Hdetj > 0.0); - auto& normj = normalization_thread(nodeListj,j); + //auto& normj = normalization_thread(nodeListj,j); auto& DvolDtj = DvolDt_thread(nodeListj,j); auto& DmDtj = DmDt_thread(nodeListj, j); auto& DEDtj = DEDt_thread(nodeListj, j); auto& DpDtj = DpDt_thread(nodeListj, j); + const auto& DxDtj = DxDt(nodeListj,j); auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj,j); auto& newRiemannDvDxj = newRiemannDvDx_thread(nodeListj,j); auto& DvDxj = DvDx_thread(nodeListj, j); - auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); - auto& massSecondMomentj = massSecondMoment(nodeListj, j); + //auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj, j); + //auto& massSecondMomentj = massSecondMoment(nodeListj, j); auto& XSPHDeltaVj = XSPHDeltaV_thread(nodeListj,j); const auto& gradRhoj = DrhoDx(nodeListj, j); const auto& Mj = M(nodeListj,j); // Node displacement. const auto rij = ri - rj; - const auto rMagij = rij.magnitude(); - const auto rMagij2 = rij.magnitude2(); + //const auto rMagij = rij.magnitude(); + //const auto rMagij2 = rij.magnitude2(); const auto rhatij =rij.unitVector(); const auto vij = vi - vj; const auto etai = Hi*rij; @@ -251,10 +250,8 @@ secondDerivativesLoop(const typename Dimension::Scalar time, const auto Hetaj = Hj*etaj.unitVector(); const auto gradWj = gWj*Hetaj; - psii = voli*Wi; - psij = volj*Wj; - gradPsii = voli * Mi.Transpose()*gradWi; - gradPsij = volj * Mj.Transpose()*gradWj; + const auto gradPsii = voli * Mi.Transpose()*gradWi; + const auto gradPsij = volj * Mj.Transpose()*gradWj; const auto Astar = voli*gradPsii + volj*gradPsij; @@ -296,8 +293,8 @@ secondDerivativesLoop(const typename Dimension::Scalar time, rhostari, //output rhostarj); //output - const auto fluxSwitch = 1; - const auto vframe = (ui+uj)*0.5; + const auto fluxSwitch = 1.0;//(nodeListi==nodeListj ? 1.0 : 0.0); + const auto vframe = (DxDti+DxDtj)*0.5; const auto vflux = vstar-vframe; const auto fluxTowardsNodei = vflux.dot(rhatij) > 0; const auto rhostar = (fluxTowardsNodei ? rhostarj : rhostari); // we'll need to fix these later @@ -335,14 +332,17 @@ secondDerivativesLoop(const typename Dimension::Scalar time, // volume change based on nodal velocity //----------------------------------------------------- - DvolDti -= (ui-uj).dot(gradPsii); - DvolDtj -= (ui-uj).dot(gradPsij); + DvolDti -= (DxDti-DxDtj).dot(gradPsii); + DvolDtj -= (DxDti-DxDtj).dot(gradPsij); // gradients //------------------------------------------------------ const auto deltaDvDxi = 2.0*(vi-vstar).dyad(gradPsii); const auto deltaDvDxj = 2.0*(vstar-vj).dyad(gradPsij); + XSPHDeltaVi -= voli*gradWi; + XSPHDeltaVj += volj*gradWj; + // based on riemann soln DvDxi -= deltaDvDxi; DvDxj -= deltaDvDxj; @@ -377,16 +377,6 @@ secondDerivativesLoop(const typename Dimension::Scalar time, break; } - // XSPH - //----------------------------------------------------------- - if (xsph) { - XSPHDeltaVi -= psii*(vi-vj); - XSPHDeltaVj -= psij*(vj-vi); - } - - normi += psii; - normj += psij; - } //if statement } // loop over pairs threadReduceFieldLists(threadStack); @@ -409,14 +399,16 @@ secondDerivativesLoop(const typename Dimension::Scalar time, // Get the state for node i. const auto& ri = position(nodeListi, i); const auto& voli = volume(nodeListi,i); - const auto& ui = nodalVelocity(nodeListi,i); + //const auto& ui = nodalVelocity(nodeListi,i); + //const auto& vi = velocity(nodeListi,i); + //const auto& ci = soundSpeed(nodeListi,i); const auto& Hi = H(nodeListi, i); const auto Hdeti = Hi.Determinant(); CHECK(voli > 0.0); CHECK(Hdeti > 0.0); - auto& normi = normalization(nodeListi, i); - auto& DxDti = DxDt(nodeListi, i); + //auto& normi = normalization(nodeListi, i); + //auto& DxDti = DxDt(nodeListi, i); auto& DvolDti = DvolDt(nodeListi, i); auto& DvDxi = DvDx(nodeListi, i); auto& DHDti = DHDt(nodeListi, i); @@ -425,21 +417,19 @@ secondDerivativesLoop(const typename Dimension::Scalar time, const auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); const auto& massSecondMomenti = massSecondMoment(nodeListi, i); const auto& HStretchTensori = HStretchTensor(nodeListi, i); - - normi += voli*Hdeti*W0; + XSPHDeltaVi /= Dimension::rootnu(Hdeti); DvolDti *= voli; // If needed finish the total energy derivative. //if (totalEnergy) DepsDti = mi*(vi.dot(DvDti) + DepsDti); - // Determine the position evolution, based on whether we're doing XSPH or not. - DxDti = ui; - if (xsph){ - DxDti += XSPHDeltaVi/max(tiny, normi); - } - - if(false){ + // ----------------------------------------------- + // TODO: + // this makes ui be vi from the previous timestep. We might need a special update method for hthis + // We culd also just take care of these in the primary loop and make the node velocity a deriv + // ----------------------------------------------- + if(true){ DHDti = smoothingScale.smoothingScaleDerivative(Hi, ri, DvDxi, @@ -464,7 +454,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, const auto Ngb_target = (Dimension::nDim == 3 ? 32 : (Dimension::nDim == 2 ? 16 : 4)); - const auto stretchFactor = 0.25; + const auto stretchFactor = 0.00; // set on construction const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : @@ -499,19 +489,33 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, StateDerivatives& derivatives) const { const auto tiny = std::numeric_limits::epsilon(); - + const auto epsTensile = this->epsilonTensile(); + const auto nodeMotionCoeff = this->nodeMotionCoefficient(); + const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient or this->gradientType() == GradientType::SPHUncorrectedGradient); const auto correctSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient); - // The kernels and such. - const auto& W = this->kernel(); + + const auto nodeMotion = this->nodeMotionType(); + const auto xsphMotion = (nodeMotion == NodeMotionType::XSPH); + const auto ficianMotion = (nodeMotion == NodeMotionType::Fician); + const auto noMotion = (nodeMotion == NodeMotionType::Eulerian); // The connectivity. const auto& connectivityMap = dataBase.connectivityMap(); const auto& nodeLists = connectivityMap.nodeLists(); - const auto numNodeLists = nodeLists.size(); + const auto numNodeLists = nodeLists.size(); + const auto& pairs = connectivityMap.nodePairList(); + const auto npairs = pairs.size(); + const auto nPerh = nodeLists[0]->nodesPerSmoothingScale(); + + // kernel + const auto& W = this->kernel(); + const auto WnPerh = W(1.0/nPerh, 1.0); + const auto W0 = W(0.0, 1.0); // Get the state and derivative FieldLists. + const auto soundSpeed = state.fields(HydroFieldNames::soundSpeed, 0.0); const auto massDensity = state.fields(HydroFieldNames::massDensity, 0.0); const auto volume = state.fields(HydroFieldNames::volume, 0.0); const auto velocity = state.fields(HydroFieldNames::velocity, Vector::zero); @@ -519,6 +523,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, const auto position = state.fields(HydroFieldNames::position, Vector::zero); const auto H = state.fields(HydroFieldNames::H, SymTensor::zero); + CHECK(soundSpeed.size() == numNodeLists); CHECK(massDensity.size() == numNodeLists); CHECK(volume.size() == numNodeLists); CHECK(velocity.size() == numNodeLists); @@ -527,37 +532,41 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, CHECK(H.size() == numNodeLists); auto M = derivatives.fields(HydroFieldNames::M_SPHCorrection, Tensor::zero); + auto DxDt = derivatives.fields(IncrementFieldList::prefix() + HydroFieldNames::position, Vector::zero); auto DrhoDx = derivatives.fields(GSPHFieldNames::densityGradient, Vector::zero); auto newRiemannDpDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceFieldList::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); auto HStretchTensor = derivatives.fields("HStretchTensor", SymTensor::zero); + auto normalization = derivatives.fields(HydroFieldNames::normalization, 0.0); + CHECK(M.size() == numNodeLists); CHECK(DrhoDx.size() == numNodeLists); + CHECK(DxDt.size() == numNodeLists); CHECK(newRiemannDpDx.size() == numNodeLists); CHECK(newRiemannDvDx.size() == numNodeLists); CHECK(massSecondMoment.size() == numNodeLists) CHECK(weightedNeighborSum.size() == numNodeLists) + CHECK(normalization.size() == numNodeLists) CHECK(HStretchTensor.size() == numNodeLists) - // The set of interacting node pairs. - const auto& pairs = connectivityMap.nodePairList(); - const auto npairs = pairs.size(); - #pragma omp parallel { // Thread private scratch variables int i, j, nodeListi, nodeListj; + Scalar Wi, Wj, gWi, gWj; typename SpheralThreads::FieldListStack threadStack; auto M_thread = M.threadCopy(threadStack); auto DrhoDx_thread = DrhoDx.threadCopy(threadStack); auto newRiemannDpDx_thread = newRiemannDpDx.threadCopy(threadStack); auto newRiemannDvDx_thread = newRiemannDvDx.threadCopy(threadStack); + auto DxDt_thread = DxDt.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); + auto normalization_thread = normalization.threadCopy(threadStack); #pragma omp for for (auto kk = 0u; kk < npairs; ++kk) { @@ -567,6 +576,9 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, nodeListj = pairs[kk].j_list; // Get the state for node i. + const auto& vi = velocity(nodeListi, i); + const auto& Pi = pressure(nodeListi, i); + const auto& ci = soundSpeed(nodeListi, i); const auto& rhoi = massDensity(nodeListi, i); const auto& ri = position(nodeListi, i); const auto& voli = volume(nodeListi, i); @@ -575,13 +587,20 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, CHECK(voli > 0.0); CHECK(Hdeti > 0.0); + auto& DxDti = DxDt_thread(nodeListi,i); auto& HStretchTensori = HStretchTensor_thread(nodeListi,i); auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi,i); auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); + auto& normi = normalization(nodeListi,i); auto& DrhoDxi = DrhoDx_thread(nodeListi, i); + auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); + auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); auto& Mi = M_thread(nodeListi, i); // Get the state for node j + const auto& vj = velocity(nodeListj, j); + const auto& Pj = pressure(nodeListj, j); + const auto& cj = soundSpeed(nodeListj, j); const auto& rhoj = massDensity(nodeListj, j); const auto& rj = position(nodeListj, j); const auto& volj = volume(nodeListj, j); @@ -590,10 +609,14 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, CHECK(volj > 0.0); CHECK(Hdetj > 0.0); + auto& DxDtj = DxDt_thread(nodeListj,j); auto& HStretchTensorj = HStretchTensor_thread(nodeListj,j); auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj,j); auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); + auto& normj = normalization(nodeListj,j); auto& DrhoDxj = DrhoDx_thread(nodeListj, j); + auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj, j); + auto& newRiemannDvDxj = newRiemannDvDx_thread(nodeListj, j); auto& Mj = M_thread(nodeListj, j); const auto rij = ri - rj; @@ -606,14 +629,16 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, CHECK(etaMagi >= 0.0); CHECK(etaMagj >= 0.0); - const auto gWi = W.gradValue(etaMagi, Hdeti); + W.kernelAndGradValue(etaMagi, Hdeti, Wi, gWi); const auto Hetai = Hi*etai.unitVector(); const auto gradWi = gWi*Hetai; - const auto gWj = W.gradValue(etaMagj, Hdetj); + W.kernelAndGradValue(etaMagj, Hdetj, Wj, gWj); const auto Hetaj = Hj*etaj.unitVector(); const auto gradWj = gWj*Hetaj; + const auto psii = voli*Wi; + const auto psij = volj*Wj; const auto gradPsii = voli*gradWi; const auto gradPsij = volj*gradWj; @@ -628,31 +653,39 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, massSecondMomenti += gradWi.magnitude2()*thpt; massSecondMomentj += gradWj.magnitude2()*thpt; - + // gradients Mi -= rij.dyad(gradPsii); Mj -= rij.dyad(gradPsij); DrhoDxi -= (rhoi - rhoj) * gradPsii; DrhoDxj -= (rhoi - rhoj) * gradPsij; - - // // based on nodal values if (calcSpatialGradients){ - const auto& vi = velocity(nodeListi, i); - const auto& Pi = pressure(nodeListi, i); - const auto& vj = velocity(nodeListj, j); - const auto& Pj = pressure(nodeListj, j); - auto& newRiemannDpDxi = newRiemannDpDx_thread(nodeListi, i); - auto& newRiemannDvDxi = newRiemannDvDx_thread(nodeListi, i); - auto& newRiemannDpDxj = newRiemannDpDx_thread(nodeListj, j); - auto& newRiemannDvDxj = newRiemannDvDx_thread(nodeListj, j); - newRiemannDpDxi -= (Pi-Pj)*gradPsii; newRiemannDpDxj -= (Pi-Pj)*gradPsij; newRiemannDvDxi -= (vi-vj).dyad(gradPsii); newRiemannDvDxj -= (vi-vj).dyad(gradPsij); } + + // node motion relative to fluid + //----------------------------------------------------------- + if (xsphMotion) { + const auto cij = 0.5*(ci+cj); + const auto wij = cij * safeInv(max(10*(vi-vj).magnitude(),cij)); + DxDti -= wij*psii*(vi-vj); + DxDtj -= wij*psij*(vj-vi); + } + if(ficianMotion){ + //const auto fi = FastMath::pow4(Wi/(Hdeti*WnPerh)); + //const auto fj = FastMath::pow4(Wj/(Hdetj*WnPerh)); + DxDti -= -rij*psii; + DxDtj += -rij*psij; + } + + normi += psii;//voli*gradWi.magnitude(); + normj += psij;//volj*gradWj.magnitude(); + } // loop over pairs // Reduce the thread values to the master. @@ -670,15 +703,21 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, const auto numNeighborsi = connectivityMap.numNeighborsForNode(nodeListi, i); + const auto& ci = soundSpeed(nodeListi,i); + const auto& vi = velocity(nodeListi,i); + const auto& voli = volume(nodeListi,i); const auto& Hi = H(nodeListi, i); const auto Hdeti = Hi.Determinant(); + auto& DxDti = DxDt(nodeListi,i); auto& Mi = M(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi,i); auto& weightedNeighborSumi = weightedNeighborSum(nodeListi,i); auto& HStretchTensori = HStretchTensor(nodeListi,i); + auto& normi = normalization(nodeListi, i); const auto Mdeti = std::abs(Mi.Determinant()); + normi += voli*Hdeti*W0; weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); HStretchTensori /= Dimension::rootnu(max(HStretchTensori.Determinant(),tiny)); massSecondMomenti /= Hdeti*Hdeti; @@ -691,10 +730,17 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, if (correctSpatialGradients){ auto& newRiemannDpDxi = newRiemannDpDx(nodeListi, i); auto& newRiemannDvDxi = newRiemannDvDx(nodeListi, i); + auto& DrhoDxi = DrhoDx(nodeListi,i); + DrhoDxi = Mi.Transpose()*DrhoDxi; newRiemannDpDxi = Mi.Transpose()*newRiemannDpDxi; newRiemannDvDxi = newRiemannDvDxi*Mi; } + + if (xsphMotion) DxDti *= nodeMotionCoeff/max(tiny, normi); + if(ficianMotion) DxDti *= nodeMotionCoeff * ci * ci * Dimension::rootnu(Hdeti) * + safeInv( max(10.0*DxDti.magnitude(),ci)); + if(!noMotion) DxDti += vi; } } @@ -703,12 +749,14 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, boundItr != this->boundaryEnd(); ++boundItr){ (*boundItr)->applyFieldListGhostBoundary(M); + (*boundItr)->applyFieldListGhostBoundary(DxDt); } if (calcSpatialGradients){ for (ConstBoundaryIterator boundItr = this->boundaryBegin(); boundItr != this->boundaryEnd(); ++boundItr){ + (*boundItr)->applyFieldListGhostBoundary(DrhoDx); (*boundItr)->applyFieldListGhostBoundary(newRiemannDpDx); (*boundItr)->applyFieldListGhostBoundary(newRiemannDvDx); } @@ -719,4 +767,4 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, } -} // spheral namespace +} // spheral namespace \ No newline at end of file diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index 1de276f41..27996def8 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -92,6 +92,7 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, const bool evolveTotalEnergy, const bool XSPH, const bool correctVelocityGradient, + const double nodeMotionCoefficient, const NodeMotionType nodeMotionType, const GradientType gradType, const MassDensityType densityUpdate, @@ -118,6 +119,7 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, nTensile, xmin, xmax), + mNodeMotionCoefficient(nodeMotionCoefficient), mNodeMotionType(nodeMotionType), mNodalVelocity(FieldStorageType::CopyFields), mDmassDt(FieldStorageType::CopyFields), @@ -206,28 +208,35 @@ registerState(DataBase& dataBase, - switch (mNodeMotionType){ - case NodeMotionType::Eulerian: // Eulerian - { - state.enroll(mNodalVelocity); - } - break; - case NodeMotionType::Lagrangian: // pure MFV - { - auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::velocity, - HydroFieldNames::velocity); // depends on - state.enroll(mNodalVelocity, nodalVelocityPolicy); - } - break; - case NodeMotionType::XSPH: - { - auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::XSPHDeltaV); - state.enroll(mNodalVelocity, nodalVelocityPolicy); - } - break; - default: - break; - } + // switch (mNodeMotionType){ + // case NodeMotionType::Eulerian: // Eulerian + // { + // state.enroll(mNodalVelocity); + // } + // break; + // case NodeMotionType::Lagrangian: // pure MFV + // { + // auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::velocity, + // HydroFieldNames::velocity); // depends on + // state.enroll(mNodalVelocity, nodalVelocityPolicy); + // } + // break; + // case NodeMotionType::XSPH: + // { + // auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::XSPHDeltaV); + // state.enroll(mNodalVelocity, nodalVelocityPolicy); + // } + // break; + // case NodeMotionType::Fician: + // { + // auto nodalVelocityPolicy = std::make_shared>(HydroFieldNames::XSPHDeltaV, + // HydroFieldNames::velocity); + // state.enroll(mNodalVelocity, nodalVelocityPolicy); + // } + // break; + // default: + // break; + // } if (this->compatibleEnergyEvolution()) { auto thermalEnergyPolicy = std::make_shared>(dataBase); diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 03f433aaa..61f8f921b 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -79,6 +79,7 @@ public: const bool evolveTotalEnergy, const bool XSPH, const bool correctVelocityGradient, + const double nodeMotionCoefficient, const NodeMotionType nodeMotionType, const GradientType gradType, const MassDensityType densityUpdate, @@ -159,6 +160,9 @@ public: void enforceBoundaries(State& state, StateDerivatives& derivs) override; + Scalar nodeMotionCoefficient() const; + void nodeMotionCoefficient(const Scalar x); + NodeMotionType nodeMotionType() const; void nodeMotionType(NodeMotionType x); @@ -179,6 +183,8 @@ public: //**************************************************************************** private: + Scalar mNodeMotionCoefficient; + NodeMotionType mNodeMotionType; FieldList mNodalVelocity; diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index 48bc18695..569bbdd34 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -1,6 +1,24 @@ namespace Spheral { +//------------------------------------------------------------------------------ +// set/get for mesh motion coefficient +//------------------------------------------------------------------------------ +template +inline +typename Dimension::Scalar +MFVHydroBase::nodeMotionCoefficient() const { + return mNodeMotionCoefficient; +} + +template +inline +void +MFVHydroBase:: +nodeMotionCoefficient(typename Dimension::Scalar x) { + mNodeMotionCoefficient = x; +} + //------------------------------------------------------------------------------ // set/get mesh motion type //------------------------------------------------------------------------------ diff --git a/src/GSPH/initializeGradients.cc b/src/GSPH/initializeGradients.cc index 7d29af523..0aa0c309c 100644 --- a/src/GSPH/initializeGradients.cc +++ b/src/GSPH/initializeGradients.cc @@ -19,6 +19,7 @@ initializeGradients(const ConnectivityMap& connectivityMap, const FieldList& volume, const FieldList& pressure, const FieldList& velocity, + FieldList& M, FieldList& DpDx, FieldList& DvDx) { @@ -37,13 +38,7 @@ initializeGradients(const ConnectivityMap& connectivityMap, REQUIRE(DpDx.size() == numNodeLists); REQUIRE(DvDx.size() == numNodeLists); - - // Prepare the kernel sum correction field. - FieldList M(FieldStorageType::CopyFields); - for (auto nodeListi = 0u; nodeListi != numNodeLists; ++nodeListi) { - M.appendNewField("temporary linear correction matrix M", volume[nodeListi]->nodeList(), Tensor::zero); - } - + REQUIRE(M.size() == numNodeLists); #pragma omp parallel { @@ -63,6 +58,8 @@ initializeGradients(const ConnectivityMap& connectivityMap, nodeListj = pairs[kk].j_list; // Get the state for node i. + const auto& vi = velocity(nodeListi, i); + const auto& Pi = pressure(nodeListi, i); const auto& ri = position(nodeListi, i); const auto& voli = volume(nodeListi, i); const auto& Hi = H(nodeListi, i); @@ -71,9 +68,13 @@ initializeGradients(const ConnectivityMap& connectivityMap, CHECK(voli > 0.0); CHECK(Hdeti > 0.0); - auto& Mi = M_thread(nodeListi, i); + auto& DpDxi = DpDx(nodeListi, i); + auto& DvDxi = DvDx(nodeListi, i); + auto& Mi = M(nodeListi, i); // Get the state for node j + const auto& vj = velocity(nodeListj, j); + const auto& Pj = pressure(nodeListj, j); const auto& rj = position(nodeListj, j); const auto& volj = volume(nodeListj, j); const auto& Hj = H(nodeListj, j); @@ -82,9 +83,13 @@ initializeGradients(const ConnectivityMap& connectivityMap, CHECK(volj > 0.0); CHECK(Hdetj > 0.0); - auto& Mj = M_thread(nodeListj, j); + auto& DpDxj = DpDx(nodeListj, j); + auto& DvDxj = DvDx(nodeListj, j); + auto& Mj = M(nodeListj, j); const auto rij = ri - rj; + const auto vij = vi - vj; + const auto Pij = Pi - Pj; const auto etai = Hi*rij; const auto etaj = Hj*rij; @@ -105,33 +110,22 @@ initializeGradients(const ConnectivityMap& connectivityMap, const auto gradPsii = volj*gradWi; const auto gradPsij = voli*gradWj; - // Linear gradient correction term. Mi -= rij.dyad(gradPsii); Mj -= rij.dyad(gradPsij); - // // based on nodal values - const auto& vi = velocity(nodeListi, i); - const auto& Pi = pressure(nodeListi, i); - const auto& vj = velocity(nodeListj, j); - const auto& Pj = pressure(nodeListj, j); - auto& DpDxi = DpDx_thread(nodeListi, i); - auto& DvDxi = DvDx_thread(nodeListi, i); - auto& DpDxj = DpDx_thread(nodeListj, j); - auto& DvDxj = DvDx_thread(nodeListj, j); + DpDxi -= Pij*gradPsii; + DpDxj -= Pij*gradPsij; - DpDxi -= (Pi-Pj)*gradPsii; - DpDxj -= (Pi-Pj)*gradPsij; - - DvDxi -= (vi-vj).dyad(gradPsii); - DvDxj -= (vi-vj).dyad(gradPsij); + DvDxi -= vij.dyad(gradPsii); + DvDxj -= vij.dyad(gradPsij); } // loop over pairs - // Reduce the thread values to the master. threadReduceFieldLists(threadStack); - } // OpenMP parallel region + std::cout << "this loop" << std::endl; + // Finish up the spatial gradient calculation for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { const auto& nodeList = volume[nodeListi]->nodeList(); diff --git a/src/GSPH/initializeGradients.hh b/src/GSPH/initializeGradients.hh index 46a7aa666..dacd90fb6 100644 --- a/src/GSPH/initializeGradients.hh +++ b/src/GSPH/initializeGradients.hh @@ -25,6 +25,7 @@ initializeGradients(const ConnectivityMap& connectivityMap, const FieldList& volume, const FieldList& pressure, const FieldList& velocity, + FieldList& M, FieldList& DpDx, FieldList& DvDx); diff --git a/src/GSPH/initializeGradientsInst.cc.py b/src/GSPH/initializeGradientsInst.cc.py index 42d25b736..d27852d9d 100644 --- a/src/GSPH/initializeGradientsInst.cc.py +++ b/src/GSPH/initializeGradientsInst.cc.py @@ -15,6 +15,7 @@ const FieldList, Dim< %(ndim)s >::Scalar>&, const FieldList, Dim< %(ndim)s >::Scalar>&, const FieldList, Dim< %(ndim)s >::Vector>&, + FieldList, Dim< %(ndim)s >::Tensor>&, FieldList, Dim< %(ndim)s >::Vector>&, FieldList, Dim< %(ndim)s >::Tensor>&); } diff --git a/src/PYB11/GSPH/MFVHydroBase.py b/src/PYB11/GSPH/MFVHydroBase.py index 175c79e4a..61b857f06 100644 --- a/src/PYB11/GSPH/MFVHydroBase.py +++ b/src/PYB11/GSPH/MFVHydroBase.py @@ -29,6 +29,7 @@ def pyinit(smoothingScaleMethod = "const SmoothingScaleBase<%(Dimension)s>&", evolveTotalEnergy = "const bool", XSPH = "const bool", correctVelocityGradient = "const bool", + nodeMotionCoefficient = "const double", nodeMotionType = "const NodeMotionType", gradType = "const GradientType", densityUpdate = "const MassDensityType", @@ -110,7 +111,9 @@ def enforceBoundaries(state = "State<%(Dimension)s>&", return "void" DvolumeDt = PYB11property("const FieldList<%(Dimension)s, Scalar>&", "DvolumeDt", returnpolicy="reference_internal") + nodeMotionCoefficient = PYB11property("double", "nodeMotionCoefficient", "nodeMotionCoefficient",doc="multiplier for XSPH and Fician node motion schemes.") nodeMotionType = PYB11property("NodeMotionType","nodeMotionType","nodeMotionType") + #------------------------------------------------------------------------------- # Inject methods #------------------------------------------------------------------------------- From 320b365d01f3a7d2fc3613b40fb798404fcef9cd Mon Sep 17 00:00:00 2001 From: Jason Pearl Date: Tue, 9 Jan 2024 17:07:52 -0800 Subject: [PATCH 45/60] updating some tests to add MFV and bugfix --- .../KelvinHelmholtz/KelvinHelmholtz-2d.py | 48 ++++++++++++++----- .../Hydro/Noh/Noh-cylindrical-2d.py | 10 ++-- .../Hydro/Sedov/Sedov-cylindrical-2d.py | 3 +- 3 files changed, 44 insertions(+), 17 deletions(-) diff --git a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py index ec5d2ebe6..2aaee637e 100644 --- a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py +++ b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py @@ -8,7 +8,7 @@ from math import * from Spheral2d import * from SpheralTestUtilities import * -from SpheralGnuPlotUtilities import * +#from SpheralGnuPlotUtilities import * from findLastRestart import * from GenerateNodeDistribution2d import * from CompositeNodeDistribution import * @@ -28,9 +28,9 @@ # Generic problem parameters #------------------------------------------------------------------------------- commandLine(nx1 = 100, - ny1 = 50, + ny1 = 50, nx2 = 100, - ny2 = 50, + ny2 = 50, rho1 = 2.0, rho2 = 1.0, @@ -52,8 +52,8 @@ # kernel HUpdate = IdealH, nPerh = 1.51, - KernelConstructor = BSplineKernel, - order = 5, + KernelConstructor = NBSplineKernel, + order = 3, hmin = 0.0001, hmax = 0.5, hminratio = 0.1, @@ -65,6 +65,7 @@ fsisph = False, gsph = False, mfm = False, + mfv = False, # hydro options solid = False, # fluid limit of the solid hydro @@ -92,11 +93,12 @@ fsiInterfaceMethod = HLLCInterface, # (HLLCInterface, ModulusInterface) fsiKernelMethod = NeverAverageKernels, # (NeverAverageKernels, AlwaysAverageKernels, AverageInterfaceKernels) - # GSPH/MFM parameters + # GSPH/MFM/MFV parameters gsphEpsDiffuseCoeff = 0.0, gsphLinearCorrect = True, LimiterConstructor = VanLeerLimiter, WaveSpeedConstructor = DavisWaveSpeed, + nodeMotionCoefficient = 0.2, # artificial viscosity Qconstructor = LimitedMonaghanGingoldViscosity, @@ -118,7 +120,7 @@ arCondAlpha = 0.5, # integrator - cfl = 0.5, + cfl = 0.25, IntegratorConstructor = CheapSynchronousRK2Integrator, goalTime = 2.0, steps = None, @@ -156,7 +158,7 @@ assert not (compatibleEnergy and evolveTotalEnergy) assert sum([fsisph,psph,gsph,crksph,svph,mfm])<=1 assert not (fsisph and not solid) -assert not ((mfm or gsph) and (boolCullenViscosity or boolReduceViscosity)) +assert not ((mfm or gsph or mfv) and ( boolReduceViscosity)) # Decide on our hydro algorithm. hydroname = 'SPH' @@ -177,6 +179,9 @@ elif mfm: hydroname = "MFM" useArtificialViscosity=False +elif mfv: + hydroname = "MFV" + useArtificialViscosity=False if asph: hydorname = "A"+hydroname if solid: @@ -224,14 +229,12 @@ #------------------------------------------------------------------------------- # Interpolation kernels. #------------------------------------------------------------------------------- -if KernelConstructor=="NBSplineKernel": +if KernelConstructor == NBSplineKernel: WT = TableKernel(NBSplineKernel(order), 1000) - WTPi = TableKernel(NBSplineKernel(order), 1000, Qhmult) else: WT = TableKernel(KernelConstructor(), 1000) - WTPi = TableKernel(KernelConstructor(), 1000, Qhmult) output("WT") -output("WTPi") + kernelExtent = WT.kernelExtent #------------------------------------------------------------------------------- @@ -409,6 +412,7 @@ def vy(ri): correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, densityUpdate=densityUpdate, + gradientType = SPHSameTimeGradient, XSPH = xsph, ASPH = asph, epsTensile = epsilonTensile, @@ -424,6 +428,26 @@ def vy(ri): compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, + gradientType = SPHSameTimeGradient, + densityUpdate=densityUpdate, + XSPH = xsph, + ASPH = asph, + epsTensile = epsilonTensile, + nTensile = nTensile) +elif mfv: + limiter = LimiterConstructor() + waveSpeed = WaveSpeedConstructor() + solver = HLLC(limiter,waveSpeed,gsphLinearCorrect) + hydro = MFV(dataBase = db, + riemannSolver = solver, + W = WT, + cfl=cfl, + compatibleEnergyEvolution = compatibleEnergy, + correctVelocityGradient= correctVelocityGradient, + nodeMotionCoefficient = nodeMotionCoefficient, + nodeMotionType = NodeMotionType.Fician, + gradientType = SPHSameTimeGradient, + evolveTotalEnergy = evolveTotalEnergy, densityUpdate=densityUpdate, XSPH = xsph, ASPH = asph, diff --git a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py index cc32dc554..d191a20fd 100644 --- a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py +++ b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py @@ -49,8 +49,8 @@ thetaFactor = 0.5, azimuthalOffsetFraction = 0.0, - nRadial = 50, - nTheta = 50, + nRadial = 100, + nTheta = 100, rmin = 0.0, rmax = 1.0, rho0 = 1.0, @@ -73,6 +73,7 @@ asph = False, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. solid = False, # If true, use the fluid limit of the solid hydro option + nodeMotion = NodeMotionType.Lagrangian, # general hydro options densityUpdate = RigorousSumDensity, # (IntegrateDensity) evolveTotalEnergy = False, # evolve total rather than specific energy @@ -206,6 +207,7 @@ "compatibleEnergy=%s" % compatibleEnergy, "Cullen=%s" % boolCullenViscosity, "filter=%f" % filter, + "%s" % nodeMotion, "nrad=%i_ntheta=%i" % (nRadial, nTheta)) restartDir = os.path.join(dataDir, "restarts") restartBaseName = os.path.join(restartDir, "Noh-cylindrical-2d-%ix%i" % (nRadial, nTheta)) @@ -411,14 +413,14 @@ riemannSolver = solver, W = WT, cfl=cfl, - nodeMotionType=NodeMotionType.Lagrangian, + nodeMotionType=nodeMotion, specificThermalEnergyDiffusionCoefficient = 0.00, compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, XSPH = XSPH, ASPH = asph, - gradientType = RiemannGradient, + gradientType = SPHSameTimeGradient, densityUpdate=densityUpdate, HUpdate = HUpdate, epsTensile = epsilonTensile, diff --git a/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py b/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py index fe4bb456e..ba1d546ea 100644 --- a/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py +++ b/tests/functional/Hydro/Sedov/Sedov-cylindrical-2d.py @@ -70,7 +70,7 @@ volumeType = RKSumVolume, # gsph options - RiemannGradientType = SPHSameTimeGradient, # (RiemannGradient,SPHGradient,HydroAccelerationGradient,OnlyDvDxGradient,MixedMethodGradient) + RiemannGradientType = SPHGradient, # (RiemannGradient,SPHGradient,HydroAccelerationGradient,OnlyDvDxGradient,MixedMethodGradient) linearReconstruction = True, # Artifical Viscosity @@ -391,6 +391,7 @@ correctVelocityGradient= correctVelocityGradient, evolveTotalEnergy = evolveTotalEnergy, gradientType = RiemannGradientType, + nodeMotionType=NodeMotionType.Fician, XSPH = XSPH, ASPH = asph, densityUpdate=densityUpdate, From b76b4b9080e35223849351093c2113d3935515d1 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 10 Jan 2024 00:30:30 -0800 Subject: [PATCH 46/60] more merge sorting --- src/GSPH/CMakeLists.txt | 8 +-- src/GSPH/GenericRiemannHydro.cc | 27 +++------ src/GSPH/MFVHydroBase.cc | 59 ++++++++----------- ...ompatibleMFVSpecificThermalEnergyPolicy.cc | 54 +++++++++++++---- ...ompatibleMFVSpecificThermalEnergyPolicy.hh | 30 +++++----- .../IncrementSpecificFromTotalPolicy.cc | 43 +++++++------- .../IncrementSpecificFromTotalPolicy.hh | 16 +++-- src/GSPH/Policies/MassFluxPolicy.cc | 20 ++----- src/GSPH/Policies/MassFluxPolicy.hh | 12 ++-- src/GSPH/Policies/ReplaceWithRatioPolicy.hh | 2 +- .../KelvinHelmholtz/KelvinHelmholtz-2d.py | 4 +- 11 files changed, 142 insertions(+), 133 deletions(-) diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 44d64c954..9269c365a 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -10,8 +10,8 @@ set(GSPH_inst MFMHydroBase MFVHydroBase Policies/MassFluxPolicy - Policies/PureReplaceWithStateFieldList - Policies/PureReplaceFieldList + #Policies/PureReplaceWithStateFieldList + #Policies/PureReplaceFieldList Policies/ReplaceWithRatioPolicy Policies/IncrementSpecificFromTotalPolicy Policies/CompatibleMFVSpecificThermalEnergyPolicy @@ -44,8 +44,8 @@ set(GSPH_headers MFMHydroBase.hh MFVHydroBase.hh Policies/MassFluxPolicy.hh - Policies/PureReplaceWithStateFieldList.hh - Policies/PureReplaceFieldList.hh + #Policies/PureReplaceWithStateFieldList.hh + #Policies/PureReplaceFieldList.hh Policies/ReplaceWithRatioPolicy.hh Policies/IncrementSpecificFromTotalPolicy.hh Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 46f3f21d4..a5d887ed1 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -14,7 +14,7 @@ #include "DataBase/StateDerivatives.hh" #include "DataBase/IncrementState.hh" #include "DataBase/ReplaceState.hh" -#include "DataBase/PureReplaceState.hh"j +#include "DataBase/PureReplaceState.hh" #include "DataBase/IncrementBoundedState.hh" #include "DataBase/ReplaceBoundedState.hh" @@ -24,7 +24,6 @@ #include "Hydro/SpecificThermalEnergyPolicy.hh" #include "Hydro/PressurePolicy.hh" #include "Hydro/SoundSpeedPolicy.hh" -#include "DataBase/PureReplaceState.hh" #include "Field/FieldList.hh" #include "Field/NodeIterators.hh" @@ -148,8 +147,8 @@ GenericRiemannHydro(const SmoothingScaleBase& smoothingScaleMethod, mM = dataBase.newFluidFieldList(Tensor::zero, HydroFieldNames::M_SPHCorrection); mDxDt = dataBase.newFluidFieldList(Vector::zero, IncrementState::prefix() + HydroFieldNames::position); mDvDt = dataBase.newFluidFieldList(Vector::zero, HydroFieldNames::hydroAcceleration); - mDspecificThermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementFieldList::prefix() + HydroFieldNames::specificThermalEnergy); - mDHDt = dataBase.newFluidFieldList(SymTensor::zero, IncrementFieldList::prefix() + HydroFieldNames::H); + mDspecificThermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementState::prefix() + HydroFieldNames::specificThermalEnergy); + mDHDt = dataBase.newFluidFieldList(SymTensor::zero, IncrementState::prefix() + HydroFieldNames::H); mDrhoDx = dataBase.newFluidFieldList(Vector::zero,GSPHFieldNames::densityGradient); mDvDx = dataBase.newFluidFieldList(Tensor::zero, HydroFieldNames::velocityGradient); mRiemannDpDx = dataBase.newFluidFieldList(Vector::zero,GSPHFieldNames::RiemannPressureGradient); @@ -261,18 +260,19 @@ registerState(DataBase& dataBase, auto positionPolicy = make_shared>(); auto pressurePolicy = make_shared>(); auto csPolicy = make_shared>(); - auto pressureGradientPolicy = make_shared>(ReplaceState::prefix() + GSPHFieldNames::RiemannPressureGradient); - auto velocityGradientPolicy = make_shared>(ReplaceState::prefix() + GSPHFieldNames::RiemannVelocityGradient); + auto pressureGradientPolicy = make_shared>(); + auto velocityGradientPolicy = make_shared>(); + auto velocityPolicy = make_policy>({HydroFieldNames::position,HydroFieldNames::specificThermalEnergy},true); // normal state variables state.enroll(mTimeStepMask); state.enroll(mVolume); state.enroll(mass); state.enroll(massDensity); - state.enroll(Hfield, Hpolicy); state.enroll(position, positionPolicy); state.enroll(mPressure, pressurePolicy); state.enroll(mSoundSpeed, csPolicy); + state.enroll(velocity, velocityPolicy); if (mRiemannSolver.linearReconstruction()){ state.enroll(mRiemannDpDx, pressureGradientPolicy); @@ -285,26 +285,13 @@ registerState(DataBase& dataBase, // conditional for energy method if (mCompatibleEnergyEvolution) { auto thermalEnergyPolicy = make_shared>(dataBase); - auto velocityPolicy = make_shared>({HydroFieldNames::position, - HydroFieldNames::specificThermalEnergy}, - true); state.enroll(specificThermalEnergy, thermalEnergyPolicy); - state.enroll(velocity, velocityPolicy); - }else if (mEvolveTotalEnergy) { auto thermalEnergyPolicy = make_shared>(); - auto velocityPolicy = make_shared>({HydroFieldNames::position, - HydroFieldNames::specificThermalEnergy}, - true); state.enroll(specificThermalEnergy, thermalEnergyPolicy); - state.enroll(velocity, velocityPolicy); - } else { auto thermalEnergyPolicy = make_shared>(); - auto velocityPolicy = make_shared>({HydroFieldNames::position}, - true); state.enroll(specificThermalEnergy, thermalEnergyPolicy); - state.enroll(velocity, velocityPolicy); } } diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index aa0075db5..f7dd75067 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -41,12 +41,11 @@ #include "DataBase/DataBase.hh" #include "DataBase/State.hh" #include "DataBase/StateDerivatives.hh" -#include "DataBase/IncrementFieldList.hh" -#include "DataBase/ReplaceFieldList.hh" +#include "DataBase/IncrementState.hh" +#include "DataBase/ReplaceState.hh" #include "DataBase/PureReplaceState.hh" -#include "DataBase/ReplaceBoundedFieldList.hh" +#include "DataBase/ReplaceBoundedState.hh" #include "DataBase/IncrementBoundedState.hh" -#include "DataBase/CompositeFieldListPolicy.hh" #include "Field/FieldList.hh" #include "Field/NodeIterators.hh" @@ -182,48 +181,40 @@ registerState(DataBase& dataBase, CHECK(volume.numFields() == dataBase.numFluidNodeLists()); CHECK(mass.numFields() == dataBase.numFluidNodeLists()); CHECK(specificThermalEnergy.numFields() == dataBase.numFluidNodeLists()); - - std::shared_ptr > volumePolicy(new CompositeFieldListPolicy()); + + auto nodeListi = 0u; for (auto itr = dataBase.fluidNodeListBegin(); - itr != dataBase.fluidNodeListEnd(); - ++itr) { - auto massi = (*itr)->mass(); - auto minVolume = massi.min()/(*itr)->rhoMax(); - auto maxVolume = massi.max()/(*itr)->rhoMin(); - volumePolicy->push_back(new IncrementBoundedState(minVolume, - maxVolume)); + itr < dataBase.fluidNodeListEnd(); + ++itr, ++nodeListi) { + auto& massi = (*itr)->mass(); + auto minVolume = massi.min()/(*itr)->rhoMax(); + auto maxVolume = massi.max()/(*itr)->rhoMin(); + state.enroll(*volume[nodeListi], make_policy>(minVolume, + maxVolume)); } - auto rhoPolicy = std::make_shared>(HydroFieldNames::mass, // numerator - HydroFieldNames::volume, // denominator - HydroFieldNames::mass, // depends on - HydroFieldNames::volume);// depends on + state.enroll(massDensity, make_policy>(HydroFieldNames::mass, + HydroFieldNames::volume)); + + state.enroll(mass, make_policy>()); - auto massPolicy = std::make_shared>(GSPHFieldNames::momentumPolicy, //depends on - GSPHFieldNames::thermalEnergyPolicy); //depends on - auto momentumPolicy = std::make_shared>(HydroFieldNames::velocity, - IncrementFieldList::prefix() + GSPHFieldNames::momentum, - HydroFieldNames::specificThermalEnergy); + state.enroll(GSPHFieldNames::momentumPolicy, + make_policy>(HydroFieldNames::velocity, + IncrementState::prefix() + GSPHFieldNames::momentum)); if (this->compatibleEnergyEvolution()) { - auto thermalEnergyPolicy = std::make_shared>(dataBase); + auto thermalEnergyPolicy = make_policy>(dataBase); state.enroll(specificThermalEnergy, thermalEnergyPolicy); - }else if (this->evolveTotalEnergy()) { std::cout <<"evolve total energy not implemented for MFV" << std::endl; } else { - auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, IncrementFieldList::prefix() + GSPHFieldNames::thermalEnergy); - auto velocityPolicy = std::make_shared>(HydroFieldNames::position,true); + auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, + IncrementState::prefix() + GSPHFieldNames::thermalEnergy); state.enroll(GSPHFieldNames::thermalEnergyPolicy,thermalEnergyPolicy); - state.enroll(velocity, velocityPolicy); } - state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); - - // normal state variables - state.enroll(mass, massPolicy); - state.enroll(massDensity, rhoPolicy); - state.enroll(volume, volumePolicy); + //state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); + // massPolicy); } //------------------------------------------------------------------------------ @@ -236,7 +227,7 @@ registerDerivatives(DataBase& dataBase, StateDerivatives& derivs) { GenericRiemannHydro::registerDerivatives(dataBase,derivs); dataBase.resizeFluidFieldList(mDmassDt, 0.0, IncrementState::prefix() + HydroFieldNames::mass, false); - dataBase.resizeFluidFieldList(mDthermalEnergyDt, 0.0, IncrementStateDimension, Scalar>::prefix() + GSPHFieldNames::thermalEnergy, false); + dataBase.resizeFluidFieldList(mDthermalEnergyDt, 0.0, IncrementState::prefix() + GSPHFieldNames::thermalEnergy, false); dataBase.resizeFluidFieldList(mDmomentumDt, Vector::zero, IncrementState::prefix() + GSPHFieldNames::momentum, false); dataBase.resizeFluidFieldList(mDvolumeDt, 0.0, IncrementState::prefix() + HydroFieldNames::volume, false); dataBase.resizeFluidFieldList(mHStretchTensor,SymTensor::zero, "HStretchTensor", false); diff --git a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc index a08b6fa3a..993ec6f61 100644 --- a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc @@ -13,16 +13,22 @@ //----------------------------------------------------------------------------// #include "GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh" #include "GSPH/GSPHFieldNames.hh" + #include "Hydro/HydroFieldNames.hh" + #include "NodeList/NodeList.hh" -#include "DataBase/DataBase.hh" -#include "DataBase/FieldUpdatePolicyBase.hh" +#include "NodeList/FluidNodeList.hh" + #include "DataBase/IncrementState.hh" +#include "DataBase/DataBase.hh" #include "DataBase/State.hh" #include "DataBase/StateDerivatives.hh" + #include "Neighbor/ConnectivityMap.hh" + #include "Field/Field.hh" #include "Field/FieldList.hh" + #include "Utilities/DBC.hh" #include "Utilities/safeInv.hh" #include "Utilities/SpheralFunctions.hh" @@ -42,8 +48,9 @@ namespace Spheral { //------------------------------------------------------------------------------ template CompatibleMFVSpecificThermalEnergyPolicy:: -CompatibleMFVSpecificThermalEnergyPolicy(): - IncrementFieldList(){ +CompatibleMFVSpecificThermalEnergyPolicy(const DataBase& dataBase): + UpdatePolicyBase(), + mDataBasePtr(&dataBase){ } //------------------------------------------------------------------------------ @@ -177,6 +184,37 @@ update(const KeyType& key, } } + + +//------------------------------------------------------------------------------ +// Update the field using increments +//------------------------------------------------------------------------------ +template +void +CompatibleMFVSpecificThermalEnergyPolicy:: +updateAsIncrement(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt) { + + KeyType fieldKey, nodeListKey; + StateBase::splitFieldKey(key, fieldKey, nodeListKey); + REQUIRE(fieldKey == HydroFieldNames::specificThermalEnergy and + nodeListKey == UpdatePolicyBase::wildcard()); + auto eps = state.fields(fieldKey, Scalar()); + + // Build an increment policy to use. + IncrementState fpolicy; + + // Do the deed for each of our Fields. + for (auto fptr: eps) { + fpolicy.updateAsIncrement(State::key(*fptr), + state, derivs, multiplier, t, dt); + } +} + //------------------------------------------------------------------------------ // Equivalence operator. //------------------------------------------------------------------------------ @@ -186,12 +224,8 @@ CompatibleMFVSpecificThermalEnergyPolicy:: operator==(const UpdatePolicyBase& rhs) const { // We're only equal if the other guy is also an increment operator. - const CompatibleMFVSpecificThermalEnergyPolicy* rhsPtr = dynamic_cast*>(&rhs); - if (rhsPtr == 0) { - return false; - } else { - return true; - } + const auto* rhsPtr = dynamic_cast*>(&rhs); + return rhsPtr != nullptr; } } diff --git a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh index 8a03cc4e1..0072ec9b2 100644 --- a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh @@ -7,12 +7,14 @@ // method. // // J.M. Pearl 2023 +// +// //----------------------------------------------------------------------------// #ifndef __Spheral_CompatibleMFVSpecificThermalEnergyPolicy_hh__ #define __Spheral_CompatibleMFVSpecificThermalEnergyPolicy_hh__ -#include "DataBase/IncrementFieldList.hh" +#include "DataBase/UpdatePolicyBase.hh" #include @@ -21,21 +23,22 @@ namespace Spheral { // Forward declarations. template class State; template class StateDerivatives; +template class FluidNodeList; template class FieldList; template class DataBase; template class CompatibleMFVSpecificThermalEnergyPolicy: - public IncrementFieldList { + public UpdatePolicyBase { public: //--------------------------- Public Interface ---------------------------// // Useful typedefs - typedef typename Dimension::Scalar Scalar; - typedef typename Dimension::Vector Vector; - typedef typename FieldListUpdatePolicyBase::KeyType KeyType; + using Scalar = typename Dimension::Scalar; + using Vector = typename Dimension::Vector; + using KeyType = typename UpdatePolicyBase::KeyType; // Constructors, destructor. - CompatibleMFVSpecificThermalEnergyPolicy(); + CompatibleMFVSpecificThermalEnergyPolicy(const DataBase& db); virtual ~CompatibleMFVSpecificThermalEnergyPolicy(); // Overload the methods describing how to update Fields. @@ -44,7 +47,7 @@ public: StateDerivatives& derivs, const double multiplier, const double t, - const double dt); + const double dt) override; // If the derivative stored values for the pair-accelerations has not been updated, // we need to just time advance normally. @@ -53,20 +56,15 @@ public: StateDerivatives& derivs, const double multiplier, const double t, - const double dt) { - IncrementFieldList::update(key, - state, - derivs, - multiplier, - t, - dt); - } + const double dt) override; // Equivalence. - virtual bool operator==(const UpdatePolicyBase& rhs) const; + virtual bool operator==(const UpdatePolicyBase& rhs) const override; private: //--------------------------- Private Interface ---------------------------// + const DataBase* mDataBasePtr; + CompatibleMFVSpecificThermalEnergyPolicy(const CompatibleMFVSpecificThermalEnergyPolicy& rhs); CompatibleMFVSpecificThermalEnergyPolicy& operator=(const CompatibleMFVSpecificThermalEnergyPolicy& rhs); }; diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc index 502c1c7d8..50edd005a 100644 --- a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc +++ b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc @@ -6,7 +6,7 @@ //----------------------------------------------------------------------------// #include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" -#include "DataBase/IncrementFieldList.hh" +#include "DataBase/IncrementState.hh" #include "DataBase/State.hh" #include "DataBase/StateDerivatives.hh" #include "Field/Field.hh" @@ -16,27 +16,23 @@ #include namespace Spheral { - //------------------------------------------------------------------------------ // Constructors. //------------------------------------------------------------------------------ template IncrementSpecificFromTotalPolicy:: -IncrementSpecificFromTotalPolicy(const std::string& stateKey, - const std::string& derivsKey): - FieldListUpdatePolicyBase(), +IncrementSpecificFromTotalPolicy(std::initializer_list depends,const std::string& stateKey, const std::string& derivKey): + UpdatePolicyBase(depends), mStateKey(stateKey), - mDerivativeKey(derivsKey) { + mDerivativeKey(derivKey){ } template IncrementSpecificFromTotalPolicy:: -IncrementSpecificFromTotalPolicy(std::initializer_list depends, - const std::string& stateKey, - const std::string& derivsKey): - FieldListUpdatePolicyBase(depends), +IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey): + UpdatePolicyBase(), mStateKey(stateKey), - mDerivativeKey(derivsKey) { + mDerivativeKey(derivKey){ } //------------------------------------------------------------------------------ @@ -53,7 +49,7 @@ IncrementSpecificFromTotalPolicy:: template void IncrementSpecificFromTotalPolicy:: -update(const KeyType& /*key*/, +update(const KeyType& key, State& state, StateDerivatives& derivs, const double multiplier, @@ -62,18 +58,25 @@ update(const KeyType& /*key*/, const auto tiny = std::numeric_limits::epsilon(); - const auto m = state.fields(HydroFieldNames::mass, Scalar()); - auto q = state.fields(mStateKey, Value()); + KeyType fieldKey, nodeListKey; + StateBase::splitFieldKey(key, fieldKey, nodeListKey); + + const auto massKey = StateBase::buildFieldKey(HydroFieldNames::mass, nodeListKey); + const auto stateFieldKey = StateBase::buildFieldKey(mStateKey, nodeListKey); + const auto derivFieldKey = StateBase::buildFieldKey(mDerivativeKey, nodeListKey); + + const auto m = state.field(massKey, Scalar()); + auto q = state.field(stateFieldKey, Value()); - const auto DmDt = derivs.fields(IncrementFieldList::prefix() + HydroFieldNames::mass, Scalar()); - const auto DQDt = derivs.fields(mDerivativeKey, Value()); + const auto DmDt = derivs.field(prefix() + massKey, Scalar()); + const auto DQDt = derivs.field(derivFieldKey, Value()); // Loop over the internal values of the field. const auto n = m.numInternalElements(); #pragma omp parallel for for (unsigned i = 0; i != n; ++i) { - const auto m1 = m(k,i)+DmDt(k,i)*multiplier; - if (m1 > tiny) q(k, i) += (DQDt(k, i) - DmDt(k, i)*q(k, i)) * multiplier * safeInv(m1); + const auto m1 = m(i)+DmDt(i)*multiplier; + if (m1 > tiny) q(i) += (DQDt(i) - DmDt(i)*q(i)) * multiplier * safeInv(m1); } } @@ -86,8 +89,8 @@ IncrementSpecificFromTotalPolicy:: operator==(const UpdatePolicyBase& rhs) const { // We're only equal if the other guy is also an replace operator. - const IncrementSpecificFromTotalPolicy* rhsPtr = dynamic_cast*>(&rhs); - return rhsPtr != 0; + const auto* rhsPtr = dynamic_cast*>(&rhs); + return rhsPtr != nullptr; } } diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh index d12388d77..a31b5fde3 100644 --- a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh +++ b/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh @@ -8,22 +8,24 @@ #ifndef __Spheral_IncrementSpecificFromTotalPolicy_hh__ #define __Spheral_IncrementSpecificFromTotalPolicy_hh__ -#include "DataBase/FieldListUpdatePolicyBase.hh" +#include "DataBase/UpdatePolicyBase.hh" + +#include namespace Spheral { template -class IncrementSpecificFromTotalPolicy: public FieldListUpdatePolicyBase { +class IncrementSpecificFromTotalPolicy: public UpdatePolicyBase { public: //--------------------------- Public Interface ---------------------------// // Useful typedefs - typedef typename FieldListUpdatePolicyBase::KeyType KeyType; - typedef typename Dimension::Scalar Scalar; - typedef typename Dimension::Vector Vector; + using Scalar = typename Dimension::Scalar; + using Vector = typename Dimension::Vector; + using KeyType = typename UpdatePolicyBase::KeyType; // Constructors, destructor. - IncrementSpecificFromTotalPolicy(std::initializer_list depends = {}, const std::string& stateKey, const std::string& derivKey); + IncrementSpecificFromTotalPolicy(std::initializer_list depends, const std::string& stateKey, const std::string& derivKey); IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey); ~IncrementSpecificFromTotalPolicy(); @@ -38,6 +40,8 @@ public: // Equivalence. virtual bool operator==(const UpdatePolicyBase& rhs) const override; + static const std::string prefix() { return "delta "; } + private: const std::string mStateKey; diff --git a/src/GSPH/Policies/MassFluxPolicy.cc b/src/GSPH/Policies/MassFluxPolicy.cc index 13e6d2685..1a57bcb5e 100644 --- a/src/GSPH/Policies/MassFluxPolicy.cc +++ b/src/GSPH/Policies/MassFluxPolicy.cc @@ -8,7 +8,7 @@ #include "MassFluxPolicy.hh" #include "Hydro/HydroFieldNames.hh" -#include "DataBase/IncrementFieldList.hh" +#include "DataBase/IncrementState.hh" #include "DataBase/State.hh" #include "DataBase/StateDerivatives.hh" #include "Field/Field.hh" @@ -46,21 +46,17 @@ update(const KeyType& key, const double multiplier, const double /*t*/, const double /*dt*/) { - KeyType fieldKey, nodeListKey; - StateBase::splitFieldKey(key, fieldKey, nodeListKey); - REQUIRE(fieldKey == HydroFieldNames::mass and - nodeListKey == UpdatePolicyBase::wildcard()); // state - auto m = state.field(fieldKey, 0.0); + auto m = state.field(key, 0.0); // deriv - const auto dmdt = derivs.field(IncrementState::prefix() + fieldKey, 0.0); + const auto dmdt = derivs.field(this->prefix() + key, 0.0); // Loop over the internal values of the field. const auto n = m.numInternalElements(); #pragma omp parallel for - for (auto j = 0u; j < n; ++j) { + for (auto i = 0u; i < n; ++i) { m(i) += std::max(multiplier*dmdt(i),-m(i)); } } @@ -74,12 +70,8 @@ MassFluxPolicy:: operator==(const UpdatePolicyBase& rhs) const { // We're only equal if the other guy is also an increment operator. - const MassFluxPolicy* rhsPtr = dynamic_cast*>(&rhs); - if (rhsPtr == 0) { - return false; - } else { - return true; - } + const auto* rhsPtr = dynamic_cast*>(&rhs); + return rhsPtr != nullptr; } } diff --git a/src/GSPH/Policies/MassFluxPolicy.hh b/src/GSPH/Policies/MassFluxPolicy.hh index a778bf53b..4aece14c5 100644 --- a/src/GSPH/Policies/MassFluxPolicy.hh +++ b/src/GSPH/Policies/MassFluxPolicy.hh @@ -20,13 +20,13 @@ template class FieldList; template class MassFluxPolicy: - public IncrementFieldList { + public IncrementState { public: //--------------------------- Public Interface ---------------------------// // Useful typedefs - typedef typename Dimension::Scalar Scalar; - typedef typename Dimension::Vector Vector; - typedef typename FieldListUpdatePolicyBase::KeyType KeyType; + using Scalar = typename Dimension::Scalar; + using Vector = typename Dimension::Vector; + using KeyType = typename IncrementState::KeyType; // Constructors, destructor. MassFluxPolicy(std::initializer_list depends = {}); @@ -38,10 +38,10 @@ public: StateDerivatives& derivs, const double multiplier, const double t, - const double dt); + const double dt) override; // Equivalence. - virtual bool operator==(const UpdatePolicyBase& rhs) const; + virtual bool operator==(const UpdatePolicyBase& rhs) const override; private: //--------------------------- Private Interface ---------------------------// diff --git a/src/GSPH/Policies/ReplaceWithRatioPolicy.hh b/src/GSPH/Policies/ReplaceWithRatioPolicy.hh index 405807019..5b08f33e8 100644 --- a/src/GSPH/Policies/ReplaceWithRatioPolicy.hh +++ b/src/GSPH/Policies/ReplaceWithRatioPolicy.hh @@ -20,7 +20,7 @@ public: // Constructors, destructor. ReplaceWithRatioPolicy(const KeyType& numerator, const KeyType& denomator); - ReplaceWithRatioPolicy(std::initializer_list depends = {}, + ReplaceWithRatioPolicy(std::initializer_list depends, const KeyType& numerator, const KeyType& denomator); virtual ~ReplaceWithRatioPolicy(); diff --git a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py index aaa664e82..5a1e7ae2e 100644 --- a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py +++ b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py @@ -51,8 +51,8 @@ # kernel HUpdate = IdealH, - nPerh = 1.51, - KernelConstructor = NBSplineKernel, + nPerh = 2.0, + KernelConstructor = WendlandC2Kernel, order = 3, hmin = 0.0001, hmax = 0.5, From 087fa337346529fb0c8041827590010634d999cb Mon Sep 17 00:00:00 2001 From: jmpearl Date: Wed, 10 Jan 2024 11:34:09 -0800 Subject: [PATCH 47/60] updating MFV for the big merge --- src/GSPH/CMakeLists.txt | 10 +- src/GSPH/MFVHydroBase.cc | 27 +++--- ...ompatibleMFVSpecificThermalEnergyPolicy.cc | 15 +-- ...ompatibleMFVSpecificThermalEnergyPolicy.hh | 11 +-- ...FVIncrementSpecificThermalEnergyPolicy.cc} | 53 +++++------ ...FVIncrementSpecificThermalEnergyPolicy.hh} | 26 +++--- ...mentSpecificThermalEnergyPolicyInst.cc.py} | 5 +- .../Policies/MFVIncrementVelocityPolicy.cc | 93 +++++++++++++++++++ .../Policies/MFVIncrementVelocityPolicy.hh | 63 +++++++++++++ .../MFVIncrementVelocityPolicyInst.cc.py | 11 +++ src/GSPH/Policies/MassFluxPolicy.cc | 27 ++++-- src/GSPH/Policies/MassFluxPolicy.hh | 4 +- .../KelvinHelmholtz/KelvinHelmholtz-2d.py | 5 +- 13 files changed, 253 insertions(+), 97 deletions(-) rename src/GSPH/Policies/{IncrementSpecificFromTotalPolicy.cc => MFVIncrementSpecificThermalEnergyPolicy.cc} (56%) rename src/GSPH/Policies/{IncrementSpecificFromTotalPolicy.hh => MFVIncrementSpecificThermalEnergyPolicy.hh} (55%) rename src/GSPH/Policies/{IncrementSpecificFromTotalPolicyInst.cc.py => MFVIncrementSpecificThermalEnergyPolicyInst.cc.py} (51%) create mode 100644 src/GSPH/Policies/MFVIncrementVelocityPolicy.cc create mode 100644 src/GSPH/Policies/MFVIncrementVelocityPolicy.hh create mode 100644 src/GSPH/Policies/MFVIncrementVelocityPolicyInst.cc.py diff --git a/src/GSPH/CMakeLists.txt b/src/GSPH/CMakeLists.txt index 9269c365a..09d04055b 100644 --- a/src/GSPH/CMakeLists.txt +++ b/src/GSPH/CMakeLists.txt @@ -10,10 +10,9 @@ set(GSPH_inst MFMHydroBase MFVHydroBase Policies/MassFluxPolicy - #Policies/PureReplaceWithStateFieldList - #Policies/PureReplaceFieldList Policies/ReplaceWithRatioPolicy - Policies/IncrementSpecificFromTotalPolicy + Policies/MFVIncrementVelocityPolicy + Policies/MFVIncrementSpecificThermalEnergyPolicy Policies/CompatibleMFVSpecificThermalEnergyPolicy Limiters/LimiterBase Limiters/VanLeerLimiter @@ -44,10 +43,9 @@ set(GSPH_headers MFMHydroBase.hh MFVHydroBase.hh Policies/MassFluxPolicy.hh - #Policies/PureReplaceWithStateFieldList.hh - #Policies/PureReplaceFieldList.hh Policies/ReplaceWithRatioPolicy.hh - Policies/IncrementSpecificFromTotalPolicy.hh + Policies/MFVIncrementVelocityPolicy.hh + Policies/MFVIncrementSpecificThermalEnergyPolicy.hh Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh Limiters/LimiterBase.hh Limiters/VanLeerLimiter.hh diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index f7dd75067..1fe4b36e7 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -58,7 +58,8 @@ #include "GSPH/computeMFMDensity.hh" #include "GSPH/Policies/MassFluxPolicy.hh" #include "GSPH/Policies/ReplaceWithRatioPolicy.hh" -#include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" +#include "GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh" +#include "GSPH/Policies/MFVIncrementVelocityPolicy.hh" #include "GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh" #include "GSPH/RiemannSolvers/RiemannSolverBase.hh" @@ -174,7 +175,7 @@ registerState(DataBase& dataBase, auto specificThermalEnergy = state.fields(HydroFieldNames::specificThermalEnergy, 0.0); // We use the thermal energy to update the specific thermal energy - state.removePolicy(specificThermalEnergy); + state.removePolicy(specificThermalEnergy,false); CHECK(position.numFields() == dataBase.numFluidNodeLists()); CHECK(velocity.numFields() == dataBase.numFluidNodeLists()); @@ -193,28 +194,30 @@ registerState(DataBase& dataBase, maxVolume)); } - state.enroll(massDensity, make_policy>(HydroFieldNames::mass, + + state.enroll(massDensity, make_policy>({HydroFieldNames::mass, + HydroFieldNames::volume}, + HydroFieldNames::mass, HydroFieldNames::volume)); - state.enroll(mass, make_policy>()); + state.enroll(mass, make_policy>({GSPHFieldNames::momentumPolicy, + GSPHFieldNames::thermalEnergyPolicy})); - state.enroll(GSPHFieldNames::momentumPolicy, - make_policy>(HydroFieldNames::velocity, - IncrementState::prefix() + GSPHFieldNames::momentum)); + state.enroll(velocity, + make_policy>({GSPHFieldNames::thermalEnergyPolicy, + HydroFieldNames::specificThermalEnergy})); + if (this->compatibleEnergyEvolution()) { auto thermalEnergyPolicy = make_policy>(dataBase); state.enroll(specificThermalEnergy, thermalEnergyPolicy); }else if (this->evolveTotalEnergy()) { std::cout <<"evolve total energy not implemented for MFV" << std::endl; } else { - auto thermalEnergyPolicy = std::make_shared>(HydroFieldNames::specificThermalEnergy, - IncrementState::prefix() + GSPHFieldNames::thermalEnergy); - state.enroll(GSPHFieldNames::thermalEnergyPolicy,thermalEnergyPolicy); + auto thermalEnergyPolicy = make_policy>(); + state.enroll(specificThermalEnergy,thermalEnergyPolicy); } - //state.enroll(GSPHFieldNames::momentumPolicy,momentumPolicy); - // massPolicy); } //------------------------------------------------------------------------------ diff --git a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc index 993ec6f61..0a704d9d8 100644 --- a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc @@ -1,13 +1,7 @@ //---------------------------------Spheral++----------------------------------// -// CompatibleMFVSpecificThermalEnergyPolicy -- An implementation of -// UpdatePolicyBase specialized for the updating the specific thermal energy -// as a dependent quantity. -// -// This version is specialized for materials with different properties. A -// compatible energy discretization in which pairwise work allows for opposite -// sign pair-wise work. DepsDti and DepsDtj are used as weights and the -// difference between the conservative and consistent formulations is added -// back in. +// CompatibleMFVSpecificThermalEnergyPolicy -- This is a generalization of the +// Lagrangian compatible energy scheme to ALE based scheme with mass flux +// between nodes. // // J.M. Pearl 2023 //----------------------------------------------------------------------------// @@ -182,9 +176,8 @@ update(const KeyType& key, if (m1 > tiny) eps(nodeListi, i) += (DepsDt(nodeListi, i) - DmassDt(nodeListi, i)*eps(nodeListi, i)) * multiplier * safeInv(m1); } } -} - +} //------------------------------------------------------------------------------ // Update the field using increments diff --git a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh index 0072ec9b2..57e53af13 100644 --- a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh @@ -1,14 +1,9 @@ //---------------------------------Spheral++----------------------------------// -// CompatibleMFVSpecificThermalEnergyPolicy -- An implementation of -// UpdatePolicyBase specialized for the updating the specific thermal energy -// as a dependent quantity. -// -// This version is specialized for the compatible energy discretization -// method. +// CompatibleMFVSpecificThermalEnergyPolicy -- This is a generalization of the +// Lagrangian compatible energy scheme to ALE based scheme with mass flux +// between nodes. // // J.M. Pearl 2023 -// -// //----------------------------------------------------------------------------// #ifndef __Spheral_CompatibleMFVSpecificThermalEnergyPolicy_hh__ diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc similarity index 56% rename from src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc rename to src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc index 50edd005a..180fcde8d 100644 --- a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.cc +++ b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc @@ -1,11 +1,12 @@ //---------------------------------Spheral++----------------------------------// -// IncrementSpecificFromTotalPolicy -- replaces one fieldlist with the ratio +// MFVIncrementSpecificThermalEnergyPolicy -- replaces one fieldlist with the ratio // of two fieldlists from the state. // // J.M. Pearl 2022 //----------------------------------------------------------------------------// -#include "GSPH/Policies/IncrementSpecificFromTotalPolicy.hh" +#include "GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh" +#include "GSPH/GSPHFieldNames.hh" #include "DataBase/IncrementState.hh" #include "DataBase/State.hh" #include "DataBase/StateDerivatives.hh" @@ -19,36 +20,26 @@ namespace Spheral { //------------------------------------------------------------------------------ // Constructors. //------------------------------------------------------------------------------ -template -IncrementSpecificFromTotalPolicy:: -IncrementSpecificFromTotalPolicy(std::initializer_list depends,const std::string& stateKey, const std::string& derivKey): - UpdatePolicyBase(depends), - mStateKey(stateKey), - mDerivativeKey(derivKey){ -} - -template -IncrementSpecificFromTotalPolicy:: -IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey): - UpdatePolicyBase(), - mStateKey(stateKey), - mDerivativeKey(derivKey){ +template +MFVIncrementSpecificThermalEnergyPolicy:: +MFVIncrementSpecificThermalEnergyPolicy(std::initializer_list depends): + FieldUpdatePolicy(depends){ } //------------------------------------------------------------------------------ // Destructor. //------------------------------------------------------------------------------ -template -IncrementSpecificFromTotalPolicy:: -~IncrementSpecificFromTotalPolicy() { +template +MFVIncrementSpecificThermalEnergyPolicy:: +~MFVIncrementSpecificThermalEnergyPolicy() { } //------------------------------------------------------------------------------ // Update the field. //------------------------------------------------------------------------------ -template +template void -IncrementSpecificFromTotalPolicy:: +MFVIncrementSpecificThermalEnergyPolicy:: update(const KeyType& key, State& state, StateDerivatives& derivs, @@ -62,34 +53,34 @@ update(const KeyType& key, StateBase::splitFieldKey(key, fieldKey, nodeListKey); const auto massKey = StateBase::buildFieldKey(HydroFieldNames::mass, nodeListKey); - const auto stateFieldKey = StateBase::buildFieldKey(mStateKey, nodeListKey); - const auto derivFieldKey = StateBase::buildFieldKey(mDerivativeKey, nodeListKey); + const auto derivFieldKey = StateBase::buildFieldKey(prefix() + GSPHFieldNames::thermalEnergy, nodeListKey); - const auto m = state.field(massKey, Scalar()); - auto q = state.field(stateFieldKey, Value()); + const auto& m = state.field(massKey, Scalar()); + auto& eps = state.field(key, Scalar()); - const auto DmDt = derivs.field(prefix() + massKey, Scalar()); - const auto DQDt = derivs.field(derivFieldKey, Value()); + const auto& DmDt = derivs.field(prefix() + massKey, Scalar()); + const auto& DmepsDt = derivs.field(derivFieldKey, Scalar()); // Loop over the internal values of the field. const auto n = m.numInternalElements(); #pragma omp parallel for for (unsigned i = 0; i != n; ++i) { const auto m1 = m(i)+DmDt(i)*multiplier; - if (m1 > tiny) q(i) += (DQDt(i) - DmDt(i)*q(i)) * multiplier * safeInv(m1); + if (m1 > tiny) eps(i) += (DmepsDt(i) - DmDt(i)*eps(i)) * multiplier * safeInv(m1); } + } //------------------------------------------------------------------------------ // Equivalence operator. //------------------------------------------------------------------------------ -template +template bool -IncrementSpecificFromTotalPolicy:: +MFVIncrementSpecificThermalEnergyPolicy:: operator==(const UpdatePolicyBase& rhs) const { // We're only equal if the other guy is also an replace operator. - const auto* rhsPtr = dynamic_cast*>(&rhs); + const auto* rhsPtr = dynamic_cast*>(&rhs); return rhsPtr != nullptr; } diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh similarity index 55% rename from src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh rename to src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh index a31b5fde3..10cac5711 100644 --- a/src/GSPH/Policies/IncrementSpecificFromTotalPolicy.hh +++ b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh @@ -1,33 +1,32 @@ //---------------------------------Spheral++----------------------------------// -// IncrementSpecificFromTotalPolicy -- policy to update the velocity from the +// MFVIncrementSpecificThermalEnergyPolicy -- policy to update the velocity from the // momentum time derivative // // J.M. Pearl 2022 //----------------------------------------------------------------------------// -#ifndef __Spheral_IncrementSpecificFromTotalPolicy_hh__ -#define __Spheral_IncrementSpecificFromTotalPolicy_hh__ +#ifndef __Spheral_MFVIncrementSpecificThermalEnergyPolicy_hh__ +#define __Spheral_MFVIncrementSpecificThermalEnergyPolicy_hh__ -#include "DataBase/UpdatePolicyBase.hh" +#include "DataBase/FieldUpdatePolicy.hh" #include namespace Spheral { -template -class IncrementSpecificFromTotalPolicy: public UpdatePolicyBase { +template +class MFVIncrementSpecificThermalEnergyPolicy: public FieldUpdatePolicy { public: //--------------------------- Public Interface ---------------------------// // Useful typedefs using Scalar = typename Dimension::Scalar; using Vector = typename Dimension::Vector; - using KeyType = typename UpdatePolicyBase::KeyType; + using KeyType = typename FieldUpdatePolicy::KeyType; // Constructors, destructor. - IncrementSpecificFromTotalPolicy(std::initializer_list depends, const std::string& stateKey, const std::string& derivKey); - IncrementSpecificFromTotalPolicy(const std::string& stateKey, const std::string& derivKey); - ~IncrementSpecificFromTotalPolicy(); + MFVIncrementSpecificThermalEnergyPolicy(std::initializer_list depends={}); + ~MFVIncrementSpecificThermalEnergyPolicy(); // Overload the methods describing how to update FieldLists. virtual void update(const KeyType& key, @@ -48,9 +47,8 @@ private: const std::string mDerivativeKey; //--------------------------- Private Interface ---------------------------// - IncrementSpecificFromTotalPolicy(); - IncrementSpecificFromTotalPolicy(const IncrementSpecificFromTotalPolicy& rhs); - IncrementSpecificFromTotalPolicy& operator=(const IncrementSpecificFromTotalPolicy& rhs); + MFVIncrementSpecificThermalEnergyPolicy(const MFVIncrementSpecificThermalEnergyPolicy& rhs); + MFVIncrementSpecificThermalEnergyPolicy& operator=(const MFVIncrementSpecificThermalEnergyPolicy& rhs); }; } @@ -59,7 +57,7 @@ private: // Forward declaration. namespace Spheral { - template class IncrementSpecificFromTotalPolicy; + template class MFVIncrementSpecificThermalEnergyPolicy; } #endif diff --git a/src/GSPH/Policies/IncrementSpecificFromTotalPolicyInst.cc.py b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicyInst.cc.py similarity index 51% rename from src/GSPH/Policies/IncrementSpecificFromTotalPolicyInst.cc.py rename to src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicyInst.cc.py index 0b4c30002..975b8a38b 100644 --- a/src/GSPH/Policies/IncrementSpecificFromTotalPolicyInst.cc.py +++ b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicyInst.cc.py @@ -3,10 +3,9 @@ // Explicit instantiation. //------------------------------------------------------------------------------ #include "Geometry/Dimension.hh" -#include "GSPH/Policies/IncrementSpecificFromTotalPolicy.cc" +#include "GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc" namespace Spheral { - template class IncrementSpecificFromTotalPolicy, Dim< %(ndim)s >::Scalar>; - template class IncrementSpecificFromTotalPolicy, Dim< %(ndim)s >::Vector>; + template class MFVIncrementSpecificThermalEnergyPolicy>; } """ diff --git a/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc new file mode 100644 index 000000000..06536d995 --- /dev/null +++ b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc @@ -0,0 +1,93 @@ +//---------------------------------Spheral++----------------------------------// +// MFVIncrementVelocityPolicy -- specialized policy for hydros that allow for mass +// flux between nodes. The momentum time derivative +// is used to update the velocity. The "hydro acceleration" +// is also added in to be compatible w/ phys packages +// that apply a pure acceleration. +// +// J.M. Pearl 2023 +//----------------------------------------------------------------------------// + +#include "GSPH/Policies/MFVIncrementVelocityPolicy.hh" +#include "GSPH/GSPHFieldNames.hh" +#include "DataBase/IncrementState.hh" +#include "DataBase/State.hh" +#include "DataBase/StateDerivatives.hh" +#include "Field/Field.hh" +#include "Utilities/DBC.hh" +#include "Hydro/HydroFieldNames.hh" + +#include + +namespace Spheral { +//------------------------------------------------------------------------------ +// Constructors. +//------------------------------------------------------------------------------ +template +MFVIncrementVelocityPolicy:: +MFVIncrementVelocityPolicy(std::initializer_list depends): + FieldUpdatePolicy(depends){ +} + +//------------------------------------------------------------------------------ +// Destructor. +//------------------------------------------------------------------------------ +template +MFVIncrementVelocityPolicy:: +~MFVIncrementVelocityPolicy() { +} + +//------------------------------------------------------------------------------ +// Update the field. +//------------------------------------------------------------------------------ +template +void +MFVIncrementVelocityPolicy:: +update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt) { + + const auto tiny = std::numeric_limits::epsilon(); + + KeyType fieldKey, nodeListKey; + StateBase::splitFieldKey(key, fieldKey, nodeListKey); + + const auto massKey = StateBase::buildFieldKey(HydroFieldNames::mass, nodeListKey); + const auto momDerivFieldKey = StateBase::buildFieldKey(prefix() + GSPHFieldNames::momentum, nodeListKey); + const auto accDerivFieldKey = StateBase::buildFieldKey(HydroFieldNames::hydroAcceleration, nodeListKey); + + const auto& m = state.field(massKey, Scalar()); + auto& v = state.field(key, Vector()); + + const auto& DmDt = derivs.field(prefix() + massKey, Scalar()); + const auto& DpDt = derivs.field(momDerivFieldKey, Vector()); + const auto& DvDt = derivs.field(accDerivFieldKey, Vector()); + +// Loop over the internal values of the field. + const auto n = m.numInternalElements(); +#pragma omp parallel for + for (unsigned i = 0; i != n; ++i) { + const auto m1 = m(i)+DmDt(i)*multiplier; + const auto DpDti = DpDt(i); + if (m1 > tiny) v(i) += (DpDti - DmDt(i)*v(i)) * multiplier * safeInv(m1); + } +} + +//------------------------------------------------------------------------------ +// Equivalence operator. +//------------------------------------------------------------------------------ +template +bool +MFVIncrementVelocityPolicy:: +operator==(const UpdatePolicyBase& rhs) const { + + // We're only equal if the other guy is also an replace operator. + const auto* rhsPtr = dynamic_cast*>(&rhs); + return rhsPtr != nullptr; +} + +} + diff --git a/src/GSPH/Policies/MFVIncrementVelocityPolicy.hh b/src/GSPH/Policies/MFVIncrementVelocityPolicy.hh new file mode 100644 index 000000000..31e966200 --- /dev/null +++ b/src/GSPH/Policies/MFVIncrementVelocityPolicy.hh @@ -0,0 +1,63 @@ +//---------------------------------Spheral++----------------------------------// +// MFVIncrementVelocityPolicy -- specialized policy for hydros that allow for mass +// mass flux between nodes. The momentum time derivative +// is used to update the velocity. The "hydro acceleration" +// is also added in to be compatible w/ phys packages +// that apply a pure acceleration. +// +// J.M. Pearl 2023 +//----------------------------------------------------------------------------// + +#ifndef __Spheral_MFVIncrementVelocityPolicy_hh__ +#define __Spheral_MFVIncrementVelocityPolicy_hh__ + +#include "DataBase/FieldUpdatePolicy.hh" + +#include + +namespace Spheral { + +template +class MFVIncrementVelocityPolicy: public FieldUpdatePolicy { +public: + + //--------------------------- Public Interface ---------------------------// + // Useful typedefs + using Scalar = typename Dimension::Scalar; + using Vector = typename Dimension::Vector; + using KeyType = typename FieldUpdatePolicy::KeyType; + + // Constructors, destructor. + MFVIncrementVelocityPolicy(std::initializer_list depends={}); + ~MFVIncrementVelocityPolicy(); + + // Overload the methods describing how to update FieldLists. + virtual void update(const KeyType& key, + State& state, + StateDerivatives& derivs, + const double multiplier, + const double t, + const double dt) override; + + // Equivalence. + virtual bool operator==(const UpdatePolicyBase& rhs) const override; + + static const std::string prefix() { return "delta "; } + +private: + + //--------------------------- Private Interface ---------------------------// + MFVIncrementVelocityPolicy(const MFVIncrementVelocityPolicy& rhs); + MFVIncrementVelocityPolicy& operator=(const MFVIncrementVelocityPolicy& rhs); +}; + +} + +#else + +// Forward declaration. +namespace Spheral { + template class MFVIncrementVelocityPolicy; +} + +#endif diff --git a/src/GSPH/Policies/MFVIncrementVelocityPolicyInst.cc.py b/src/GSPH/Policies/MFVIncrementVelocityPolicyInst.cc.py new file mode 100644 index 000000000..76a744576 --- /dev/null +++ b/src/GSPH/Policies/MFVIncrementVelocityPolicyInst.cc.py @@ -0,0 +1,11 @@ +text = """ +//------------------------------------------------------------------------------ +// Explicit instantiation. +//------------------------------------------------------------------------------ +#include "Geometry/Dimension.hh" +#include "GSPH/Policies/MFVIncrementVelocityPolicy.cc" + +namespace Spheral { + template class MFVIncrementVelocityPolicy>; +} +""" diff --git a/src/GSPH/Policies/MassFluxPolicy.cc b/src/GSPH/Policies/MassFluxPolicy.cc index 1a57bcb5e..ac09f2a41 100644 --- a/src/GSPH/Policies/MassFluxPolicy.cc +++ b/src/GSPH/Policies/MassFluxPolicy.cc @@ -1,7 +1,6 @@ //---------------------------------Spheral++----------------------------------// -// MassFluxPolicy -- This is basically a direct copy of the standard -// position policy but instead we're substituting in -// the nodal velocity as the derivative. +// MassFluxPolicy -- update method for ALE - based hydro schemes that allow +// for mass flux between nodes. // // J. M. Pearl 2023 //----------------------------------------------------------------------------// @@ -46,19 +45,29 @@ update(const KeyType& key, const double multiplier, const double /*t*/, const double /*dt*/) { - + //std::cout<< "beginMASFLUX" << std::endl; // state - auto m = state.field(key, 0.0); - + auto& m = state.field(key, 0.0); + // deriv - const auto dmdt = derivs.field(this->prefix() + key, 0.0); - + const auto& dmdt = derivs.field(this->prefix() + key, 0.0); + //std::cout << key << " " << this->prefix()+key<< std::endl; // Loop over the internal values of the field. const auto n = m.numInternalElements(); #pragma omp parallel for for (auto i = 0u; i < n; ++i) { - m(i) += std::max(multiplier*dmdt(i),-m(i)); + // std::cout << dmdt(i) << std::endl; + // std::cout << " " << std::endl; + // std::cout << m(i) << std::endl; + const auto mi = m(i); + m(i) += multiplier*(dmdt(i)); + // std::cout << multiplier*(dmdt(i)) << std::endl; + // std::cout << multiplier*dmdt(i) << std::endl; + // std::cout << std::max(multiplier*dmdt(i), -m(i)) << std::endl; + // std::cout << m(i) - mi << std::endl; } + + //std::cout<< "endMASFLUX" << std::endl; } //------------------------------------------------------------------------------ diff --git a/src/GSPH/Policies/MassFluxPolicy.hh b/src/GSPH/Policies/MassFluxPolicy.hh index 4aece14c5..5cf4a3ce3 100644 --- a/src/GSPH/Policies/MassFluxPolicy.hh +++ b/src/GSPH/Policies/MassFluxPolicy.hh @@ -1,8 +1,10 @@ //---------------------------------Spheral++----------------------------------// -// MassFluxPolicy -- +// MassFluxPolicy -- update method for ALE - based hydro schemes that allow +// for mass flux between nodes. // // J. M. Pearl 2023 //----------------------------------------------------------------------------// + #ifndef __Spheral_MassFluxPolicy_hh__ #define __Spheral_MassFluxPolicy_hh__ diff --git a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py index 5a1e7ae2e..51d7ae2ed 100644 --- a/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py +++ b/tests/functional/Hydro/KelvinHelmholtz/KelvinHelmholtz-2d.py @@ -51,7 +51,7 @@ # kernel HUpdate = IdealH, - nPerh = 2.0, + nPerh = 3.0, KernelConstructor = WendlandC2Kernel, order = 3, hmin = 0.0001, @@ -445,7 +445,7 @@ def vy(ri): compatibleEnergyEvolution = compatibleEnergy, correctVelocityGradient= correctVelocityGradient, nodeMotionCoefficient = nodeMotionCoefficient, - nodeMotionType = NodeMotionType.Fician, + nodeMotionType = NodeMotionType.Lagrangian, gradientType = SPHSameTimeGradient, evolveTotalEnergy = evolveTotalEnergy, densityUpdate=densityUpdate, @@ -540,6 +540,7 @@ def vy(ri): # import SpheralPointmeshSiloDump # vizMethod = SpheralPointmeshSiloDump.dumpPhysicsState control = SpheralController(integrator, WT, + initializeDerivatives=True, statsStep = statsStep, restartStep = restartStep, restartBaseName = restartBaseName, From bdbfe8a8509a08c8819707adcb641d2bd3c87da7 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Thu, 11 Jan 2024 03:16:40 -0800 Subject: [PATCH 48/60] GSPH: making some comments more descriptive --- src/GSPH/GSPHFieldNames.cc | 5 +---- src/GSPH/GSPHFieldNames.hh | 3 --- src/GSPH/GSPHHydroBase.cc | 5 ++++- src/GSPH/GSPHHydroBase.hh | 5 ++++- src/GSPH/GenericRiemannHydro.hh | 2 +- src/GSPH/MFVHydroBase.cc | 7 +------ src/GSPH/MFVHydroBase.hh | 11 +++++++---- .../CompatibleMFVSpecificThermalEnergyPolicy.cc | 3 ++- .../CompatibleMFVSpecificThermalEnergyPolicy.hh | 4 ++-- .../MFVIncrementSpecificThermalEnergyPolicy.cc | 12 +++++++++--- .../MFVIncrementSpecificThermalEnergyPolicy.hh | 11 +++++++++-- src/GSPH/Policies/MFVIncrementVelocityPolicy.cc | 3 ++- src/GSPH/Policies/MFVIncrementVelocityPolicy.hh | 4 +++- src/GSPH/Policies/MassFluxPolicy.cc | 17 ++--------------- src/GSPH/computeMFMDensity.cc | 2 ++ src/GSPH/computeMFMDensity.hh | 2 ++ src/GSPH/computeSPHVolume.cc | 2 ++ src/GSPH/computeSPHVolume.hh | 2 ++ src/GSPH/computeSumVolume.cc | 7 ++++++- src/GSPH/computeSumVolume.hh | 7 ++++++- src/GSPH/initializeGradients.cc | 7 ++++--- src/GSPH/initializeGradients.hh | 2 ++ 22 files changed, 73 insertions(+), 50 deletions(-) diff --git a/src/GSPH/GSPHFieldNames.cc b/src/GSPH/GSPHFieldNames.cc index a25d7bef5..5b7d9dbdb 100644 --- a/src/GSPH/GSPHFieldNames.cc +++ b/src/GSPH/GSPHFieldNames.cc @@ -15,7 +15,4 @@ const std::string Spheral::GSPHFieldNames::deviatoricStressTensorGradient = "dev const std::string Spheral::GSPHFieldNames::RiemannPressureGradient = "Riemann solvers pressure gradient"; const std::string Spheral::GSPHFieldNames::RiemannVelocityGradient = "Riemann solvers velocity gradient"; const std::string Spheral::GSPHFieldNames::RiemannDeviatoricStressTensorGradient = "Riemann solvers deviatoric stress tensor gradient"; -const std::string Spheral::GSPHFieldNames::pairMassFlux = "pairwise mass flux"; - -const std::string Spheral::GSPHFieldNames::momentumPolicy = "update policy momentum"; -const std::string Spheral::GSPHFieldNames::thermalEnergyPolicy = "update policy thermal energy"; \ No newline at end of file +const std::string Spheral::GSPHFieldNames::pairMassFlux = "pairwise mass flux"; \ No newline at end of file diff --git a/src/GSPH/GSPHFieldNames.hh b/src/GSPH/GSPHFieldNames.hh index d73e5f5c4..c5262d8b4 100644 --- a/src/GSPH/GSPHFieldNames.hh +++ b/src/GSPH/GSPHFieldNames.hh @@ -21,10 +21,7 @@ struct GSPHFieldNames { static const std::string RiemannPressureGradient; static const std::string RiemannVelocityGradient; static const std::string RiemannDeviatoricStressTensorGradient; - static const std::string pairMassFlux; - static const std::string momentumPolicy; - static const std::string thermalEnergyPolicy; }; } diff --git a/src/GSPH/GSPHHydroBase.cc b/src/GSPH/GSPHHydroBase.cc index 3a7a2c518..8a97eb380 100644 --- a/src/GSPH/GSPHHydroBase.cc +++ b/src/GSPH/GSPHHydroBase.cc @@ -1,5 +1,8 @@ //---------------------------------Spheral++----------------------------------// -// GSPHHydroBase -- The Godunov SPH hydrodynamic package for Spheral++. +// GSPHHydroBase -- A Riemann-solver-based implementation of SPH. Compared to +// MFM/MFV this approach requires a larger neighbor set. 2.5 +// nodes per kernel extent instead of 2-2.25 for MFM/MFV but +// does perform better on certain tests (Noh implosion) // // J.M. Pearl 2021 //----------------------------------------------------------------------------// diff --git a/src/GSPH/GSPHHydroBase.hh b/src/GSPH/GSPHHydroBase.hh index 76e1ac4f1..6e22bf2a5 100644 --- a/src/GSPH/GSPHHydroBase.hh +++ b/src/GSPH/GSPHHydroBase.hh @@ -1,5 +1,8 @@ //---------------------------------Spheral++----------------------------------// -// GSPHHydroBase -- The Godunov SPH hydrodynamic package for Spheral++. +// GSPHHydroBase -- A Riemann-solver-based implementation of SPH. Compared to +// MFM/MFV this approach requires a larger neighbor set. 2.5 +// nodes per kernel extent instead of 2-2.25 for MFM/MFV but +// does perform better on certain tests (Noh implosion) // // J.M. Pearl 2021 //----------------------------------------------------------------------------// diff --git a/src/GSPH/GenericRiemannHydro.hh b/src/GSPH/GenericRiemannHydro.hh index 5e02c3b7a..b77252a59 100644 --- a/src/GSPH/GenericRiemannHydro.hh +++ b/src/GSPH/GenericRiemannHydro.hh @@ -1,6 +1,6 @@ //---------------------------------Spheral++----------------------------------// // GenericRiemannHydro -- pure virtual class for hydros using a Riemann -// solver +// solver // // J.M. Pearl 2022 //----------------------------------------------------------------------------// diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index 1fe4b36e7..533aa14a0 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -4,7 +4,7 @@ // approaches which promote more regular particle distributions. // // Each of the ALE options defines the velocity of the nodes -// differently then the flux then results from the difference +// differently. The flux that results from the difference // between the nodes velocities and the fluid velocity. // The velocities are defined as follows for the // NodeMotionTypes: @@ -16,11 +16,6 @@ // 3) Fician ------ nodal velocity = fluid velocity + Fician // PST correction // 4) XSPH -------- nodal velocity = xsph velocity -// 5) BackgroundPressure -- nodal acceleration = fluid -// acceleration + Background pressure -// force to drive regularization. We'll -// probably also need some decay time -// to get back to u = v. // // Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic // Simulation Methods," MNRAS, 450(1):53-110 diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 61f8f921b..3660f866b 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -4,7 +4,7 @@ // approaches which promote more regular particle distributions. // // Each of the ALE options defines the velocity of the nodes -// differently then the flux then results from the difference +// differently. The flux that results from the difference // between the nodes velocities and the fluid velocity. // The velocities are defined as follows for the // NodeMotionTypes: @@ -16,15 +16,18 @@ // 3) Fician ------ nodal velocity = fluid velocity + Fician // PST correction // 4) XSPH -------- nodal velocity = xsph velocity -// 5) BackgroundPressure -- nodal acceleration = fluid -// acceleration + Background pressure -// force to drive regularization. // // Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic // Simulation Methods," MNRAS, 450(1):53-110 // // J.M. Pearl 2023 //----------------------------------------------------------------------------// +// TODO: +// 1 backpressure and fician particle shifting +// 2 Eulerian model will still crash on the Noh implosion due to void particles +// 3 Good implementation of Ngb update +// 4 treatment for material interfaces +//---------------------------------------------------------------------------// #ifndef __Spheral_MFVHydroBase_hh__ #define __Spheral_MFVHydroBase_hh__ diff --git a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc index 0a704d9d8..eb7a33a27 100644 --- a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.cc @@ -1,10 +1,11 @@ //---------------------------------Spheral++----------------------------------// // CompatibleMFVSpecificThermalEnergyPolicy -- This is a generalization of the -// Lagrangian compatible energy scheme to ALE based scheme with mass flux +// Lagrangian compatible energy scheme to ALE-based scheme with mass flux // between nodes. // // J.M. Pearl 2023 //----------------------------------------------------------------------------// + #include "GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh" #include "GSPH/GSPHFieldNames.hh" diff --git a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh index 57e53af13..2165468cd 100644 --- a/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh +++ b/src/GSPH/Policies/CompatibleMFVSpecificThermalEnergyPolicy.hh @@ -1,9 +1,9 @@ //---------------------------------Spheral++----------------------------------// // CompatibleMFVSpecificThermalEnergyPolicy -- This is a generalization of the -// Lagrangian compatible energy scheme to ALE based scheme with mass flux +// Lagrangian compatible energy scheme to ALE-based scheme with mass flux // between nodes. // -// J.M. Pearl 2023 +// J.M. Pearl 2024 //----------------------------------------------------------------------------// #ifndef __Spheral_CompatibleMFVSpecificThermalEnergyPolicy_hh__ diff --git a/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc index 180fcde8d..27c56c44b 100644 --- a/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc +++ b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc @@ -1,9 +1,16 @@ //---------------------------------Spheral++----------------------------------// -// MFVIncrementSpecificThermalEnergyPolicy -- replaces one fieldlist with the ratio -// of two fieldlists from the state. +// MFVIncrementSpecificThermalEnergyPolicy -- This is a specialized increment +// policy for the specific thermal energy for schemes that allow +// for flux between nodes. The specific thermal energy is updated +// based on the time derivative of thermal energy. The mass and +// time derivative are needed to got from thermal to specific +// thermal. // // J.M. Pearl 2022 //----------------------------------------------------------------------------// +// TODO: the edge case handing for m->0 needs to be improved to robustly +// handle void when full Eulerian. +//----------------------------------------------------------------------------// #include "GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh" #include "GSPH/GSPHFieldNames.hh" @@ -61,7 +68,6 @@ update(const KeyType& key, const auto& DmDt = derivs.field(prefix() + massKey, Scalar()); const auto& DmepsDt = derivs.field(derivFieldKey, Scalar()); -// Loop over the internal values of the field. const auto n = m.numInternalElements(); #pragma omp parallel for for (unsigned i = 0; i != n; ++i) { diff --git a/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh index 10cac5711..703237b7b 100644 --- a/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh +++ b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.hh @@ -1,9 +1,16 @@ //---------------------------------Spheral++----------------------------------// -// MFVIncrementSpecificThermalEnergyPolicy -- policy to update the velocity from the -// momentum time derivative +// MFVIncrementSpecificThermalEnergyPolicy -- This is a specialized increment +// policy for the specific thermal energy for schemes that allow +// for flux between nodes. The specific thermal energy is updated +// based on the time derivative of thermal energy. The mass and +// time derivative are needed to got from thermal to specific +// thermal. // // J.M. Pearl 2022 //----------------------------------------------------------------------------// +// TODO: the edge case handing for m->0 needs to be improved to robustly +// handle void when full Eulerian. +//----------------------------------------------------------------------------// #ifndef __Spheral_MFVIncrementSpecificThermalEnergyPolicy_hh__ #define __Spheral_MFVIncrementSpecificThermalEnergyPolicy_hh__ diff --git a/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc index 06536d995..99889a9eb 100644 --- a/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc +++ b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc @@ -7,6 +7,8 @@ // // J.M. Pearl 2023 //----------------------------------------------------------------------------// +// TODO : HydroAcceleration needs to be added in +//----------------------------------------------------------------------------// #include "GSPH/Policies/MFVIncrementVelocityPolicy.hh" #include "GSPH/GSPHFieldNames.hh" @@ -66,7 +68,6 @@ update(const KeyType& key, const auto& DpDt = derivs.field(momDerivFieldKey, Vector()); const auto& DvDt = derivs.field(accDerivFieldKey, Vector()); -// Loop over the internal values of the field. const auto n = m.numInternalElements(); #pragma omp parallel for for (unsigned i = 0; i != n; ++i) { diff --git a/src/GSPH/Policies/MFVIncrementVelocityPolicy.hh b/src/GSPH/Policies/MFVIncrementVelocityPolicy.hh index 31e966200..979499cbf 100644 --- a/src/GSPH/Policies/MFVIncrementVelocityPolicy.hh +++ b/src/GSPH/Policies/MFVIncrementVelocityPolicy.hh @@ -1,12 +1,14 @@ //---------------------------------Spheral++----------------------------------// // MFVIncrementVelocityPolicy -- specialized policy for hydros that allow for mass -// mass flux between nodes. The momentum time derivative +// flux between nodes. The momentum time derivative // is used to update the velocity. The "hydro acceleration" // is also added in to be compatible w/ phys packages // that apply a pure acceleration. // // J.M. Pearl 2023 //----------------------------------------------------------------------------// +// TODO : HydroAcceleration needs to be added in +//----------------------------------------------------------------------------// #ifndef __Spheral_MFVIncrementVelocityPolicy_hh__ #define __Spheral_MFVIncrementVelocityPolicy_hh__ diff --git a/src/GSPH/Policies/MassFluxPolicy.cc b/src/GSPH/Policies/MassFluxPolicy.cc index ac09f2a41..039179ffb 100644 --- a/src/GSPH/Policies/MassFluxPolicy.cc +++ b/src/GSPH/Policies/MassFluxPolicy.cc @@ -45,29 +45,16 @@ update(const KeyType& key, const double multiplier, const double /*t*/, const double /*dt*/) { - //std::cout<< "beginMASFLUX" << std::endl; - // state + auto& m = state.field(key, 0.0); - - // deriv const auto& dmdt = derivs.field(this->prefix() + key, 0.0); - //std::cout << key << " " << this->prefix()+key<< std::endl; -// Loop over the internal values of the field. + const auto n = m.numInternalElements(); #pragma omp parallel for for (auto i = 0u; i < n; ++i) { - // std::cout << dmdt(i) << std::endl; - // std::cout << " " << std::endl; - // std::cout << m(i) << std::endl; const auto mi = m(i); m(i) += multiplier*(dmdt(i)); - // std::cout << multiplier*(dmdt(i)) << std::endl; - // std::cout << multiplier*dmdt(i) << std::endl; - // std::cout << std::max(multiplier*dmdt(i), -m(i)) << std::endl; - // std::cout << m(i) - mi << std::endl; } - - //std::cout<< "endMASFLUX" << std::endl; } //------------------------------------------------------------------------------ diff --git a/src/GSPH/computeMFMDensity.cc b/src/GSPH/computeMFMDensity.cc index 41e1c0a6c..c617172aa 100644 --- a/src/GSPH/computeMFMDensity.cc +++ b/src/GSPH/computeMFMDensity.cc @@ -1,5 +1,7 @@ //---------------------------------Spheral++----------------------------------// // Compute the density from m/V +// +// J.M. Pearl 2022 //----------------------------------------------------------------------------// #include "GSPH/computeMFMDensity.hh" diff --git a/src/GSPH/computeMFMDensity.hh b/src/GSPH/computeMFMDensity.hh index ebfc8fae2..99f25822d 100644 --- a/src/GSPH/computeMFMDensity.hh +++ b/src/GSPH/computeMFMDensity.hh @@ -1,5 +1,7 @@ //---------------------------------Spheral++----------------------------------// // Compute the density from m/V +// +// J.M. Pearl 2022 //----------------------------------------------------------------------------// #ifndef __Spheral__computeMFMDensity__ diff --git a/src/GSPH/computeSPHVolume.cc b/src/GSPH/computeSPHVolume.cc index 0fba6577a..ce803c322 100644 --- a/src/GSPH/computeSPHVolume.cc +++ b/src/GSPH/computeSPHVolume.cc @@ -1,5 +1,7 @@ //---------------------------------Spheral++----------------------------------// // Compute the volume from m/rho +// +// J.M. Pearl 2022 //----------------------------------------------------------------------------// #include "GSPH/computeSPHVolume.hh" diff --git a/src/GSPH/computeSPHVolume.hh b/src/GSPH/computeSPHVolume.hh index c0c856faa..536101c43 100644 --- a/src/GSPH/computeSPHVolume.hh +++ b/src/GSPH/computeSPHVolume.hh @@ -1,5 +1,7 @@ //---------------------------------Spheral++----------------------------------// // Compute the volume from m/rho +// +// J.M. Pearl 2022 //----------------------------------------------------------------------------// #ifndef __Spheral__computeSPHVolume__ diff --git a/src/GSPH/computeSumVolume.cc b/src/GSPH/computeSumVolume.cc index 60e527051..5dd4126dc 100644 --- a/src/GSPH/computeSumVolume.cc +++ b/src/GSPH/computeSumVolume.cc @@ -1,5 +1,10 @@ //---------------------------------Spheral++----------------------------------// -// Compute volume from inverse of the kernel summation +// Compute volume from inverse of the kernel summation. +// +// Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic +// Simulation Methods," MNRAS, 450(1):53-110 +// +// J.M. Pearl 2022 //----------------------------------------------------------------------------// #include "GSPH/computeSumVolume.hh" diff --git a/src/GSPH/computeSumVolume.hh b/src/GSPH/computeSumVolume.hh index 1eec78308..283a3e19f 100644 --- a/src/GSPH/computeSumVolume.hh +++ b/src/GSPH/computeSumVolume.hh @@ -1,5 +1,10 @@ //---------------------------------Spheral++----------------------------------// -// Compute volume from inverse of the kernel summation +// Compute volume from inverse of the kernel summation. +// +// Hopkins P.F. (2015) "A New Class of Accurate, Mesh-Free Hydrodynamic +// Simulation Methods," MNRAS, 450(1):53-110 +// +// J.M. Pearl 2022 //----------------------------------------------------------------------------// #ifndef __Spheral__computeSumVolume__ diff --git a/src/GSPH/initializeGradients.cc b/src/GSPH/initializeGradients.cc index 0aa0c309c..baced1087 100644 --- a/src/GSPH/initializeGradients.cc +++ b/src/GSPH/initializeGradients.cc @@ -1,5 +1,8 @@ //---------------------------------Spheral++----------------------------------// -// Compute volume from inverse of the kernel summation +// initializes the pressure and velocity gradients for Riemann solver - based +// SPH varients +// +// J.M. Pearl 2023 //----------------------------------------------------------------------------// #include "GSPH/initializeGradients.hh" @@ -124,8 +127,6 @@ initializeGradients(const ConnectivityMap& connectivityMap, threadReduceFieldLists(threadStack); } // OpenMP parallel region - std::cout << "this loop" << std::endl; - // Finish up the spatial gradient calculation for (auto nodeListi = 0u; nodeListi < numNodeLists; ++nodeListi) { const auto& nodeList = volume[nodeListi]->nodeList(); diff --git a/src/GSPH/initializeGradients.hh b/src/GSPH/initializeGradients.hh index dacd90fb6..8930dd563 100644 --- a/src/GSPH/initializeGradients.hh +++ b/src/GSPH/initializeGradients.hh @@ -1,6 +1,8 @@ //---------------------------------Spheral++----------------------------------// // initializes the pressure and velocity gradients for Riemann solver - based // SPH varients +// +// J.M. Pearl 2023 //----------------------------------------------------------------------------// #ifndef __Spheral__initializeGradients__ From 1983d031005fd9ef6179c7cfe43230212b37f794 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Mon, 15 Jan 2024 09:36:16 -0800 Subject: [PATCH 49/60] bugfix MFV update policies --- src/GSPH/MFVHydroBase.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index 533aa14a0..154ca98d3 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -195,12 +195,11 @@ registerState(DataBase& dataBase, HydroFieldNames::mass, HydroFieldNames::volume)); - state.enroll(mass, make_policy>({GSPHFieldNames::momentumPolicy, - GSPHFieldNames::thermalEnergyPolicy})); + state.enroll(mass, make_policy>({HydroFieldNames::velocity, + HydroFieldNames::specificThermalEnergy})); state.enroll(velocity, - make_policy>({GSPHFieldNames::thermalEnergyPolicy, - HydroFieldNames::specificThermalEnergy})); + make_policy>({HydroFieldNames::specificThermalEnergy})); if (this->compatibleEnergyEvolution()) { From 329372588a377c988673f9b994cd36261ef948a9 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Fri, 1 Mar 2024 13:08:15 -0800 Subject: [PATCH 50/60] GSPH clean up post merge --- src/GSPH/GenericRiemannHydro.cc | 5 +++-- .../RiemannSolvers/SecondOrderArtificialViscosity.cc | 2 +- .../RiemannSolvers/SecondOrderArtificialViscosity.hh | 10 +++++++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/GSPH/GenericRiemannHydro.cc b/src/GSPH/GenericRiemannHydro.cc index 6b9cde916..b072e6f04 100644 --- a/src/GSPH/GenericRiemannHydro.cc +++ b/src/GSPH/GenericRiemannHydro.cc @@ -179,12 +179,13 @@ initializeProblemStartupDependencies(DataBase& dataBase, State& state, StateDerivatives& derivs) { + const auto& connectivityMap = dataBase.connectivityMap(); const auto mass = dataBase.fluidMass(); const auto massDensity = dataBase.fluidMassDensity(); - const auto velocity = dataBase.fluidVelocity(); const auto position = dataBase.fluidPosition(); const auto H = dataBase.fluidHfield(); - + auto velocity = dataBase.fluidVelocity(); + updateStateFields(HydroFieldNames::pressure, state, derivs); updateStateFields(HydroFieldNames::soundSpeed, state, derivs); diff --git a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc index 5ffcabff6..a67dbfd26 100644 --- a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.cc @@ -1,5 +1,5 @@ //---------------------------------Spheral++----------------------------------// -// SecondOrderArtificialViscosity -- approximate riemann solver +// SecondOrderArtificialViscosity // Frontiere, Raskin, Owen (2017) "CRKSPH:- A Conservative Reproducing Kernel // Smoothed Particle Hydrodynamics Scheme," J. Comp. Phys. // diff --git a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh index 00c58d80a..3b7d91a0b 100644 --- a/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh +++ b/src/GSPH/RiemannSolvers/SecondOrderArtificialViscosity.hh @@ -1,7 +1,11 @@ //---------------------------------Spheral++----------------------------------// -// SecondOrderArtificialViscosity -- approximate riemann solver -// Toro E.F., Spruce M., Speares W., (1994) "Restoration of the Contact Surface in -// the HLL-Riemann Solver," Shock Waves, 4:25-34 +// SecondOrderArtificialViscosity +// Frontiere, Raskin, Owen (2017) "CRKSPH:- A Conservative Reproducing Kernel +// Smoothed Particle Hydrodynamics Scheme," J. Comp. Phys. +// +// This is a reimplementation of the LimitedArtificialViscosity class as a +// derivative of RiemannSolverBase so it can be used with GSPH derived +// classes // // J.M. Pearl 2021 //----------------------------------------------------------------------------// From b338d84bcb9373f0becad4a9f72cf395c0127cb0 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Mon, 13 May 2024 18:58:56 -0700 Subject: [PATCH 51/60] GSPH: commenting out unused variables --- src/GSPH/MFVEvaluateDerivatives.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index 9d15aeb28..4228da226 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -489,7 +489,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, StateDerivatives& derivatives) const { const auto tiny = std::numeric_limits::epsilon(); - const auto epsTensile = this->epsilonTensile(); + //const auto epsTensile = this->epsilonTensile(); const auto nodeMotionCoeff = this->nodeMotionCoefficient(); const auto calcSpatialGradients = (this->gradientType() == GradientType::SPHSameTimeGradient @@ -507,11 +507,11 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, const auto numNodeLists = nodeLists.size(); const auto& pairs = connectivityMap.nodePairList(); const auto npairs = pairs.size(); - const auto nPerh = nodeLists[0]->nodesPerSmoothingScale(); + //const auto nPerh = nodeLists[0]->nodesPerSmoothingScale(); // kernel const auto& W = this->kernel(); - const auto WnPerh = W(1.0/nPerh, 1.0); + //const auto WnPerh = W(1.0/nPerh, 1.0); const auto W0 = W(0.0, 1.0); // Get the state and derivative FieldLists. From 321fdbc7ec62ac9491adf51a24a907deffe2f6fc Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 14 May 2024 06:27:21 -0700 Subject: [PATCH 52/60] GSPH: cleaning up unusued vars and punting H algo til after Mike's update to H --- src/GSPH/MFMEvaluateDerivatives.cc | 4 +-- src/GSPH/MFVEvaluateDerivatives.cc | 40 +++++++++++++++--------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/GSPH/MFMEvaluateDerivatives.cc b/src/GSPH/MFMEvaluateDerivatives.cc index 202ac833b..4e5098708 100644 --- a/src/GSPH/MFMEvaluateDerivatives.cc +++ b/src/GSPH/MFMEvaluateDerivatives.cc @@ -196,7 +196,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, // Node displacement. const auto rij = ri - rj; const auto rhatij =rij.unitVector(); - const auto rMagij = rij.magnitude2(); + //const auto rMagij = rij.magnitude2(); const auto vij = vi - vj; const auto etai = Hi*rij; const auto etaj = Hj*rij; @@ -352,7 +352,7 @@ evaluateDerivatives(const typename Dimension::Scalar time, const auto hmax = nodeList.hmax(); const auto hminratio = nodeList.hminratio(); const auto nPerh = nodeList.nodesPerSmoothingScale(); - const auto kernelExtent = nodeList.neighbor().kernelExtent(); + //const auto kernelExtent = nodeList.neighbor().kernelExtent(); const auto ni = nodeList.numInternalNodes(); #pragma omp parallel for for (auto i = 0u; i < ni; ++i) { diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index 4228da226..5c0f362da 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -429,7 +429,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, // this makes ui be vi from the previous timestep. We might need a special update method for hthis // We culd also just take care of these in the primary loop and make the node velocity a deriv // ----------------------------------------------- - if(true){ + //if(true){ DHDti = smoothingScale.smoothingScaleDerivative(Hi, ri, DvDxi, @@ -449,29 +449,29 @@ secondDerivativesLoop(const typename Dimension::Scalar time, connectivityMap, // connectivityMap nodeListi, // nodeListi i); // i - }else{ - // smoothing scale construction - const auto Ngb_target = (Dimension::nDim == 3 ? 32 : - (Dimension::nDim == 2 ? 16 : - 4)); - const auto stretchFactor = 0.00; - - // set on construction - const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : - (Dimension::nDim == 2 ? 3.1415 : - 1.0)); + // }else{ + // // smoothing scale construction + // const auto Ngb_target = (Dimension::nDim == 3 ? 32 : + // (Dimension::nDim == 2 ? 16 : + // 4)); + // const auto stretchFactor = 0.00; + + // // set on construction + // const auto C = (Dimension::nDim == 3 ? 1.33333*3.1415 : + // (Dimension::nDim == 2 ? 3.1415 : + // 1.0)); - // pass - const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); + // // pass + // const auto Ngb = C /(Hdeti*voli) * pow(kernelExtent,Dimension::nDim); - const auto Hstretch = ((1.00-stretchFactor)* SymTensor::one + - stretchFactor * HStretchTensori)*Hi; + // const auto Hstretch = ((1.00-stretchFactor)* SymTensor::one + + // stretchFactor * HStretchTensori)*Hi; - const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); - Hideali = std::min(std::max(scaleFactor,0.8),1.2) * Hstretch; + // const auto scaleFactor = (1.0+0.5*(Ngb - Ngb_target)/Ngb_target); + // Hideali = std::min(std::max(scaleFactor,0.8),1.2) * Hstretch; - DHDti = 0.25*(Hideali-Hi)/dt; - } + // DHDti = 0.25*(Hideali-Hi)/dt; + // } } // nodes loop } // nodeLists loop } // eval derivs method From e49d6ef067bf1b6849626188d2a47bb7861b27db Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 14 May 2024 06:36:37 -0700 Subject: [PATCH 53/60] GSPH: removing HstretchTensor and more unused vars only commenting out the Hstretch stuff b/c I'll want to create a H evolution phys package after mike's update which recreates what Hopkins did in his 2015 paper --- src/GSPH/MFVEvaluateDerivatives.cc | 30 +++++++++++++++--------------- src/GSPH/MFVHydroBase.cc | 8 ++++---- src/GSPH/MFVHydroBase.hh | 4 ++-- src/GSPH/MFVHydroBaseInline.hh | 14 +++++++------- 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/GSPH/MFVEvaluateDerivatives.cc b/src/GSPH/MFVEvaluateDerivatives.cc index 5c0f362da..f2a5efc6a 100644 --- a/src/GSPH/MFVEvaluateDerivatives.cc +++ b/src/GSPH/MFVEvaluateDerivatives.cc @@ -91,7 +91,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, auto XSPHDeltaV = derivatives.fields(HydroFieldNames::XSPHDeltaV, Vector::zero); auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); - auto HStretchTensor = derivatives.fields("HStretchTensor", SymTensor::zero); + //auto HStretchTensor = derivatives.fields("HStretchTensor", SymTensor::zero); auto newRiemannDpDx = derivatives.fields(ReplaceState::prefix() + GSPHFieldNames::RiemannPressureGradient,Vector::zero); auto newRiemannDvDx = derivatives.fields(ReplaceState::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); auto& pairAccelerations = derivatives.getAny(HydroFieldNames::pairAccelerations, vector()); @@ -111,7 +111,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, //CHECK(XSPHDeltaV.size() == numNodeLists); CHECK(weightedNeighborSum.size() == numNodeLists); CHECK(massSecondMoment.size() == numNodeLists); - CHECK(HStretchTensor.size() == numNodeLists); + //CHECK(HStretchTensor.size() == numNodeLists); CHECK(newRiemannDpDx.size() == numNodeLists); CHECK(newRiemannDvDx.size() == numNodeLists); @@ -144,7 +144,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, //auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); // this is kind of criminal and should be fixed, but for testing purposes - // I'm going to stay its allowable. We're going to zero out the thread + // I'm going to say its allowable. We're going to zero out the thread // copy of the Hstretch Tensor so that we can zero it out then replace // the original with the smoothed version. // HStretchTensor_thread.Zero(); @@ -390,7 +390,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, const auto hmax = nodeList.hmax(); const auto hminratio = nodeList.hminratio(); const auto nPerh = nodeList.nodesPerSmoothingScale(); - const auto kernelExtent = nodeList.neighbor().kernelExtent(); + //const auto kernelExtent = nodeList.neighbor().kernelExtent(); const auto ni = nodeList.numInternalNodes(); #pragma omp parallel for @@ -416,7 +416,7 @@ secondDerivativesLoop(const typename Dimension::Scalar time, auto& XSPHDeltaVi = XSPHDeltaV(nodeListi, i); const auto& weightedNeighborSumi = weightedNeighborSum(nodeListi, i); const auto& massSecondMomenti = massSecondMoment(nodeListi, i); - const auto& HStretchTensori = HStretchTensor(nodeListi, i); + //const auto& HStretchTensori = HStretchTensor(nodeListi, i); XSPHDeltaVi /= Dimension::rootnu(Hdeti); DvolDti *= voli; @@ -538,7 +538,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, auto newRiemannDvDx = derivatives.fields(ReplaceState::prefix() + GSPHFieldNames::RiemannVelocityGradient,Tensor::zero); auto massSecondMoment = derivatives.fields(HydroFieldNames::massSecondMoment, SymTensor::zero); auto weightedNeighborSum = derivatives.fields(HydroFieldNames::weightedNeighborSum, 0.0); - auto HStretchTensor = derivatives.fields("HStretchTensor", SymTensor::zero); + //auto HStretchTensor = derivatives.fields("HStretchTensor", SymTensor::zero); auto normalization = derivatives.fields(HydroFieldNames::normalization, 0.0); CHECK(M.size() == numNodeLists); @@ -549,7 +549,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, CHECK(massSecondMoment.size() == numNodeLists) CHECK(weightedNeighborSum.size() == numNodeLists) CHECK(normalization.size() == numNodeLists) - CHECK(HStretchTensor.size() == numNodeLists) + //CHECK(HStretchTensor.size() == numNodeLists) #pragma omp parallel { @@ -565,7 +565,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, auto DxDt_thread = DxDt.threadCopy(threadStack); auto massSecondMoment_thread = massSecondMoment.threadCopy(threadStack); auto weightedNeighborSum_thread = weightedNeighborSum.threadCopy(threadStack); - auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); + //auto HStretchTensor_thread = HStretchTensor.threadCopy(threadStack); auto normalization_thread = normalization.threadCopy(threadStack); #pragma omp for @@ -588,7 +588,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, CHECK(Hdeti > 0.0); auto& DxDti = DxDt_thread(nodeListi,i); - auto& HStretchTensori = HStretchTensor_thread(nodeListi,i); + //auto& HStretchTensori = HStretchTensor_thread(nodeListi,i); auto& weightedNeighborSumi = weightedNeighborSum_thread(nodeListi,i); auto& massSecondMomenti = massSecondMoment_thread(nodeListi, i); auto& normi = normalization(nodeListi,i); @@ -610,7 +610,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, CHECK(Hdetj > 0.0); auto& DxDtj = DxDt_thread(nodeListj,j); - auto& HStretchTensorj = HStretchTensor_thread(nodeListj,j); + //auto& HStretchTensorj = HStretchTensor_thread(nodeListj,j); auto& weightedNeighborSumj = weightedNeighborSum_thread(nodeListj,j); auto& massSecondMomentj = massSecondMoment_thread(nodeListj, j); auto& normj = normalization(nodeListj,j); @@ -620,7 +620,7 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, auto& Mj = M_thread(nodeListj, j); const auto rij = ri - rj; - const auto rMagij = safeInv(rij.magnitude()); + //const auto rMagij = safeInv(rij.magnitude()); const auto etai = Hi*rij; const auto etaj = Hj*rij; @@ -645,8 +645,8 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, weightedNeighborSumi += std::abs(gWi); weightedNeighborSumj += std::abs(gWj); - HStretchTensori -= voli*rij.selfdyad()*gWi*rMagij; - HStretchTensorj -= volj*rij.selfdyad()*gWj*rMagij; + //HStretchTensori -= voli*rij.selfdyad()*gWi*rMagij; + //HStretchTensorj -= volj*rij.selfdyad()*gWj*rMagij; const auto rij2 = rij.magnitude2(); const auto thpt = rij.selfdyad()*safeInvVar(rij2*rij2*rij2); @@ -713,13 +713,13 @@ firstDerivativesLoop(const typename Dimension::Scalar /*time*/, auto& Mi = M(nodeListi, i); auto& massSecondMomenti = massSecondMoment(nodeListi,i); auto& weightedNeighborSumi = weightedNeighborSum(nodeListi,i); - auto& HStretchTensori = HStretchTensor(nodeListi,i); + //auto& HStretchTensori = HStretchTensor(nodeListi,i); auto& normi = normalization(nodeListi, i); const auto Mdeti = std::abs(Mi.Determinant()); normi += voli*Hdeti*W0; weightedNeighborSumi = Dimension::rootnu(max(0.0, weightedNeighborSumi/Hdeti)); - HStretchTensori /= Dimension::rootnu(max(HStretchTensori.Determinant(),tiny)); + //HStretchTensori /= Dimension::rootnu(max(HStretchTensori.Determinant(),tiny)); massSecondMomenti /= Hdeti*Hdeti; const auto enoughNeighbors = numNeighborsi > Dimension::pownu(2); diff --git a/src/GSPH/MFVHydroBase.cc b/src/GSPH/MFVHydroBase.cc index 154ca98d3..f2da58ce8 100644 --- a/src/GSPH/MFVHydroBase.cc +++ b/src/GSPH/MFVHydroBase.cc @@ -120,14 +120,14 @@ MFVHydroBase(const SmoothingScaleBase& smoothingScaleMethod, mDthermalEnergyDt(FieldStorageType::CopyFields), mDmomentumDt(FieldStorageType::CopyFields), mDvolumeDt(FieldStorageType::CopyFields), - mHStretchTensor(FieldStorageType::CopyFields), + //mHStretchTensor(FieldStorageType::CopyFields), mPairMassFlux(){ mNodalVelocity = dataBase.newFluidFieldList(Vector::zero, GSPHFieldNames::nodalVelocity); mDmassDt = dataBase.newFluidFieldList(0.0, IncrementState::prefix() + HydroFieldNames::mass); mDthermalEnergyDt = dataBase.newFluidFieldList(0.0, IncrementState::prefix() + GSPHFieldNames::thermalEnergy); mDmomentumDt = dataBase.newFluidFieldList(Vector::zero, IncrementState::prefix() + GSPHFieldNames::momentum); mDvolumeDt = dataBase.newFluidFieldList(0.0, IncrementState::prefix() + HydroFieldNames::volume); - mHStretchTensor = dataBase.newFluidFieldList(SymTensor::zero, "HStretchTensor"); + //mHStretchTensor = dataBase.newFluidFieldList(SymTensor::zero, "HStretchTensor"); mPairMassFlux.clear(); } @@ -227,12 +227,12 @@ registerDerivatives(DataBase& dataBase, dataBase.resizeFluidFieldList(mDthermalEnergyDt, 0.0, IncrementState::prefix() + GSPHFieldNames::thermalEnergy, false); dataBase.resizeFluidFieldList(mDmomentumDt, Vector::zero, IncrementState::prefix() + GSPHFieldNames::momentum, false); dataBase.resizeFluidFieldList(mDvolumeDt, 0.0, IncrementState::prefix() + HydroFieldNames::volume, false); - dataBase.resizeFluidFieldList(mHStretchTensor,SymTensor::zero, "HStretchTensor", false); + //dataBase.resizeFluidFieldList(mHStretchTensor,SymTensor::zero, "HStretchTensor", false); derivs.enroll(mDmassDt); derivs.enroll(mDthermalEnergyDt); derivs.enroll(mDmomentumDt); derivs.enroll(mDvolumeDt); - derivs.enroll(mHStretchTensor); + //derivs.enroll(mHStretchTensor); derivs.enrollAny(GSPHFieldNames::pairMassFlux, mPairMassFlux); } diff --git a/src/GSPH/MFVHydroBase.hh b/src/GSPH/MFVHydroBase.hh index 3660f866b..593fde4bf 100644 --- a/src/GSPH/MFVHydroBase.hh +++ b/src/GSPH/MFVHydroBase.hh @@ -174,7 +174,7 @@ public: const FieldList& DthermalEnergyDt() const; const FieldList& DmomentumDt() const; const FieldList& DvolumeDt() const; - const FieldList& HStretchTensor() const; + //const FieldList& HStretchTensor() const; const std::vector& pairMassFlux() const; @@ -195,7 +195,7 @@ private: FieldList mDthermalEnergyDt; FieldList mDmomentumDt; FieldList mDvolumeDt; - FieldList mHStretchTensor; + //FieldList mHStretchTensor; std::vector mPairMassFlux; diff --git a/src/GSPH/MFVHydroBaseInline.hh b/src/GSPH/MFVHydroBaseInline.hh index 569bbdd34..7e945fa09 100644 --- a/src/GSPH/MFVHydroBaseInline.hh +++ b/src/GSPH/MFVHydroBaseInline.hh @@ -84,11 +84,11 @@ MFVHydroBase:: pairMassFlux() const { return mPairMassFlux; } -template -inline -const FieldList& -MFVHydroBase:: -HStretchTensor() const { - return mHStretchTensor; -} +// template +// inline +// const FieldList& +// MFVHydroBase:: +// HStretchTensor() const { +// return mHStretchTensor; +// } } \ No newline at end of file From b1417465b160a401601ab3a9843cab55ff4ea230 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 14 May 2024 08:46:15 -0700 Subject: [PATCH 54/60] GSPH : remove unused var from massfluxpolicy --- src/GSPH/Policies/MassFluxPolicy.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/GSPH/Policies/MassFluxPolicy.cc b/src/GSPH/Policies/MassFluxPolicy.cc index 039179ffb..448be74e1 100644 --- a/src/GSPH/Policies/MassFluxPolicy.cc +++ b/src/GSPH/Policies/MassFluxPolicy.cc @@ -52,7 +52,6 @@ update(const KeyType& key, const auto n = m.numInternalElements(); #pragma omp parallel for for (auto i = 0u; i < n; ++i) { - const auto mi = m(i); m(i) += multiplier*(dmdt(i)); } } From 5a033f08499699602874aef6107c7e76d762a787 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 14 May 2024 10:14:17 -0700 Subject: [PATCH 55/60] GSPH: unused var in the MFVIncrementVelocityPolicy --- src/GSPH/Policies/MFVIncrementVelocityPolicy.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc index 99889a9eb..d7aa29e05 100644 --- a/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc +++ b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc @@ -59,14 +59,14 @@ update(const KeyType& key, const auto massKey = StateBase::buildFieldKey(HydroFieldNames::mass, nodeListKey); const auto momDerivFieldKey = StateBase::buildFieldKey(prefix() + GSPHFieldNames::momentum, nodeListKey); - const auto accDerivFieldKey = StateBase::buildFieldKey(HydroFieldNames::hydroAcceleration, nodeListKey); + //const auto accDerivFieldKey = StateBase::buildFieldKey(HydroFieldNames::hydroAcceleration, nodeListKey); const auto& m = state.field(massKey, Scalar()); auto& v = state.field(key, Vector()); const auto& DmDt = derivs.field(prefix() + massKey, Scalar()); const auto& DpDt = derivs.field(momDerivFieldKey, Vector()); - const auto& DvDt = derivs.field(accDerivFieldKey, Vector()); + //const auto& DvDt = derivs.field(accDerivFieldKey, Vector()); const auto n = m.numInternalElements(); #pragma omp parallel for From 46395f2ec0b1348f49742542717cc6dd952873c8 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 14 May 2024 11:38:06 -0700 Subject: [PATCH 56/60] GSPH: blueos didn't like the for loop --- src/GSPH/Policies/MFVIncrementVelocityPolicy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc index d7aa29e05..1083c332e 100644 --- a/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc +++ b/src/GSPH/Policies/MFVIncrementVelocityPolicy.cc @@ -70,7 +70,7 @@ update(const KeyType& key, const auto n = m.numInternalElements(); #pragma omp parallel for - for (unsigned i = 0; i != n; ++i) { + for (auto i = 0u; i < n; ++i) { const auto m1 = m(i)+DmDt(i)*multiplier; const auto DpDti = DpDt(i); if (m1 > tiny) v(i) += (DpDti - DmDt(i)*v(i)) * multiplier * safeInv(m1); From 6af3f39c435e4707b7dc377772e0c22a3f23f034 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 14 May 2024 14:28:31 -0700 Subject: [PATCH 57/60] GSPH: another omp incompatible loop --- src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc index 27c56c44b..1d240cede 100644 --- a/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc +++ b/src/GSPH/Policies/MFVIncrementSpecificThermalEnergyPolicy.cc @@ -70,7 +70,7 @@ update(const KeyType& key, const auto n = m.numInternalElements(); #pragma omp parallel for - for (unsigned i = 0; i != n; ++i) { + for (auto i = 0u; i < n; ++i) { const auto m1 = m(i)+DmDt(i)*multiplier; if (m1 > tiny) eps(i) += (DmepsDt(i) - DmDt(i)*eps(i)) * multiplier * safeInv(m1); } From e3cbdd7cd32901379adcf8f1c233d3e5b4657c2b Mon Sep 17 00:00:00 2001 From: jmpearl Date: Mon, 3 Jun 2024 20:05:19 -0700 Subject: [PATCH 58/60] GSPH: updating tests for merge --- .../Hydro/AcousticWave/AcousticWave-1d.py | 223 +++++------------- .../Hydro/Noh/Noh-cylindrical-2d.py | 14 +- .../functional/Hydro/Noh/Noh-spherical-3d.py | 4 +- .../functional/Hydro/RayleighTaylor/RT-2d.py | 2 - .../Hydro/RayleighTaylor/RT-2d_Hopkins.py | 4 - 5 files changed, 68 insertions(+), 179 deletions(-) diff --git a/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py b/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py index 0428fd08c..e9318205f 100644 --- a/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py +++ b/tests/functional/Hydro/AcousticWave/AcousticWave-1d.py @@ -11,7 +11,6 @@ from SpheralTestUtilities import * import mpi import numpy as np -from DistributeNodes import distributeNodesInRange1d #import matplotlib.pyplot as plt def smooth(x,window_len=11,window='hanning'): @@ -36,75 +35,44 @@ def smooth(x,window_len=11,window='hanning'): #------------------------------------------------------------------------------- # Generic problem parameters #------------------------------------------------------------------------------- -commandLine(# problem geometry - nx1 = 100, +commandLine(nx1 = 100, x0 = 0.0, x1 = 1.0, - # problem I.C.s rho1 = 1.0, - #eps1 = 1.0, + eps1 = 1.0, A = 1.0e-6, kfreq = 1.0, + cs2 = 1.0, mu = 1.0, - gamma1 = 5.0/3.0, - # Kernel properties - KernelConstructor = WendlandC2Kernel, - nPerh = 2.5, - HUpdate = IntegrateH, - hmin = 1.0e-10, - hmax = 0.25, - order = 3, - - #hydros (out different solvers) - svph = False, - crksph = False, - psph = False, - fsisph = False, - gsph = False, - mfm = False, + nPerh = 3.01, - # general hydro options - solid = False, + Cl = 1.0, + Cq = 2.0, + linearInExpansion = False, + Qlimiter = False, + epsilon2 = 1e-30, + hmin = 1.0e-10, + hmax = 0.1, + cfl = 0.25, XSPH = False, epsilonTensile = 0.0, nTensile = 4, filter = 0.0, - densityUpdate = IntegrateDensity, - correctVelocityGradient=True, - compatibleEnergy = True, - evolveTotalEnergy = False, - - # Default SPH options - gradhCorrection = True, + KernelConstructor = WendlandC2Kernel, + order = 5, - # CRKSPH options + svph = False, + crksph = False, + psph = False, + fsisph = False, + solid = False, + IntegratorConstructor = CheapSynchronousRK2Integrator, correctionOrder = LinearOrder, - - # SVPH options - linearConsistent = False, - - # MFM/GSPH options - WaveSpeedConstructor = DavisWaveSpeed, # Davis, Einfeldt, Acoustic - LimiterConstructor = VanLeerLimiter, # VanLeer, Opsre, MinMod, VanAlba, Superbee - riemannLinearReconstruction = True, # True - second order, False - first order - riemannGradientType = HydroAccelerationGradient, # HydroAccelerationGradient, SPHGradient, RiemannGradient, MixedMethodGradient, SPHSameTimeGradient - gsphRiemannSolver = "HLLC", # HLLC / ArtificialViscosity - - # Artificial Viscosity - Cl = 1.0, - Cq = 1.0, - linearInExpansion = False, - Qlimiter = False, - epsilon2 = 1e-30, - - # integrator options - IntegratorConstructor = VerletIntegrator,#CheapSynchronousRK2Integrator, - cfl = 0.35, steps = None, - goalTime = 1.0, + goalTime = 5.0, dt = 1.0e-10, dtMin = 1.0e-10, dtMax = 0.1, @@ -114,17 +82,21 @@ def smooth(x,window_len=11,window='hanning'): maxSteps = None, statsStep = 1, smoothIters = 0, - - # outputs + HUpdate = IntegrateH, + densityUpdate = RigorousSumDensity, + compatibleEnergy = True, + gradhCorrection = True, + linearConsistent = False, + restoreCycle = None, restartStep = 10000, clearDirectories = True, dataDirBase = "dumps-planar-AcousticWave-1d", outputFile = "AcousticWave-planar-1d.gnu", - normOutputFile = "_asciiDump.dat", + normOutputFile = "Limited_asciiDump.dat", writeOutputLabel = True, - graphics = False,#"gnu", + graphics = "gnu", checkReversibility = False, ) @@ -137,28 +109,9 @@ def smooth(x,window_len=11,window='hanning'): hydroname = "PSPH" elif fsisph: hydroname = "FSISPH" -elif mfm: - hydroname = "MFM" -elif gsph: - hydroname = "GSPH" else: hydroname = "SPH" - -normOutputFile = str(riemannGradientType)+"_"+normOutputFile -if LimiterConstructor==VanLeerLimiter: - normOutputFile = "vanLeer_"+normOutputFile -elif LimiterConstructor==VanAlbaLimiter: - normOutputFile = "vanalba_"+normOutputFile -elif LimiterConstructor==OspreLimiter: - normOutputFile = "opsre_"+normOutputFile -elif LimiterConstructor==MinModLimiter: - normOutputFile = "MinMod_"+normOutputFile -elif LimiterConstructor==SuperbeeLimiter: - normOutputFile = "Superbee_"+normOutputFile -normOutputFile = str(densityUpdate)+"_"+normOutputFile -normOutputFile = hydroname+"_"+gsphRiemannSolver+"_"+normOutputFile - -print normOutputFile +normOutputFile = hydroname+"_"+normOutputFile dataDir = os.path.join(dataDirBase, hydroname, "nx=%i" % nx1) @@ -178,15 +131,15 @@ def smooth(x,window_len=11,window='hanning'): #------------------------------------------------------------------------------- # Material properties. #------------------------------------------------------------------------------- -#eos = IsothermalEquationOfStateMKS(cs2, mu) -eos = GammaLawGasMKS(gamma1, mu) +eos = IsothermalEquationOfStateMKS(cs2, mu) + #------------------------------------------------------------------------------- # Interpolation kernels. #------------------------------------------------------------------------------- if KernelConstructor==NBSplineKernel: - WT = TableKernel(NBSplineKernel(order), 100000) + WT = TableKernel(NBSplineKernel(order), 10000) else: - WT = TableKernel(KernelConstructor(), 100000) + WT = TableKernel(KernelConstructor(), 10000) output("WT") kernelExtent = WT.kernelExtent output("WT") @@ -211,6 +164,7 @@ def smooth(x,window_len=11,window='hanning'): #------------------------------------------------------------------------------- # Set the node properties. #------------------------------------------------------------------------------- +from DistributeNodes import distributeNodesInRange1d distributeNodesInRange1d([(nodes1, nx1, rho1, (x0, x1))], nPerh = nPerh) nNodesThisDomain1 = nodes1.numInternalNodes @@ -249,15 +203,14 @@ def __call__(self, x): vel = nodes1.velocity() rho = nodes1.massDensity() mass = nodes1.mass() -eps = nodes1.specificThermalEnergy() H = nodes1.Hfield() dx = (x1 - x0)/nx1 xi = x0 for i in range(nodes1.numInternalNodes): func0 = MassFunctor(max(0.0, Mi[i] - mi)) func1 = MassFunctor(Mi[i]) - xi0 = newtonRaphsonFindRoot(func0, xi, xi + 2.0*dx, 1.0e-35, 1.0e-35) - xi1 = newtonRaphsonFindRoot(func1, xi, xi + 2.0*dx, 1.0e-35, 1.0e-35) + xi0 = newtonRaphsonFindRoot(func0, xi, xi + 2.0*dx, 1.0e-18, 1.0e-18) + xi1 = newtonRaphsonFindRoot(func1, xi, xi + 2.0*dx, 1.0e-18, 1.0e-18) rhoi0 = rho1*(1.0 + A*sin(twopi*kfreq*(xi0 - x0)/(x1 - x0))) rhoi1 = rho1*(1.0 + A*sin(twopi*kfreq*(xi1 - x0)/(x1 - x0))) xi = x0 + (x1 - x0)*(rhoi0*xi0 + rhoi1*xi1)/(rhoi0 + rhoi1) @@ -265,10 +218,6 @@ def __call__(self, x): vel[i].x = A*cs*sin(twopi*kfreq*(xi - x0)/(x1 - x0)) rho[i] = rho1*(1.0 + A*sin(twopi*kfreq*(xi - x0)/(x1 - x0))) mass[i] = rho1*((xi1 - xi0) - A/(twopi*kfreq)*(cos(twopi*kfreq*xi1) - cos(twopi*kfreq*xi0))) - Pi = P1+A*sin(twopi*kfreq*(xi - x0)/(x1 - x0)) - eps[i] = Pi/((gamma1 - 1.0)*rho[i]) - print A/(twopi*kfreq)*(cos(twopi*kfreq*xi1) - cos(twopi*kfreq*xi0)) - print("%3.16e" % mass[i]) H[i] *= rho[i]/rho1 # xi0 = 0.0 # dx0 = (x1 - x0)/nx1 @@ -291,11 +240,7 @@ def __call__(self, x): print("Compute analytic rho scaling of %16.12e." % rhoscale) for i in range(nodes1.numInternalNodes): mass[i] *= rhoscale - #print 1.0-rhoscale - #print rho[i] - #print mass[i] -#print(mass.max()) -#print(mass.min()) + #------------------------------------------------------------------------------- # Construct a DataBase to hold our node list #------------------------------------------------------------------------------- @@ -338,71 +283,21 @@ def __call__(self, x): HUpdate = HUpdate, XSPH = XSPH) elif fsisph: - if densityUpdate == RigorousSumDensity: - sumDensityNodeLists = [nodes1] - else: - sumDensityNodeLists = [] hydro = FSISPH(dataBase = db, W = WT, cfl = cfl, - sumDensityNodeLists = sumDensityNodeLists, + sumDensityNodeLists = [nodes1], compatibleEnergyEvolution = compatibleEnergy, epsTensile = epsilonTensile) -elif gsph: - limiter = LimiterConstructor() - waveSpeed = WaveSpeedConstructor() - if gsphRiemannSolver == "HLLC": - solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) - elif gsphRiemannSolver == "ArtificialViscosity": - solver = SecondOrderArtificialViscosity(Cl,Cq,limiter,waveSpeed,riemannLinearReconstruction) - else: - raise ValueError, "WRONG!" - hydro = GSPH(dataBase = db, - riemannSolver = solver, - W = WT, - cfl=cfl, - gradientType = riemannGradientType, - compatibleEnergyEvolution = compatibleEnergy, - correctVelocityGradient=correctVelocityGradient, - evolveTotalEnergy = evolveTotalEnergy, - XSPH = XSPH, - densityUpdate=densityUpdate, - HUpdate = IdealH, - epsTensile = epsilonTensile, - nTensile = nTensile) -elif mfm: - limiter = LimiterConstructor() - waveSpeed = WaveSpeedConstructor() - if gsphRiemannSolver == "HLLC": - solver = HLLC(limiter,waveSpeed,riemannLinearReconstruction) - elif gsphRiemannSolver == "ArtificialViscosity": - solver = SecondOrderArtificialViscosity(Cl,Cq,limiter,waveSpeed,riemannLinearReconstruction) - else: - raise ValueError, "WRONG!" - - hydro = MFM(dataBase = db, - riemannSolver = solver, - W = WT, - cfl=cfl, - gradientType = riemannGradientType, - compatibleEnergyEvolution = compatibleEnergy, - correctVelocityGradient=correctVelocityGradient, - evolveTotalEnergy = evolveTotalEnergy, - XSPH = XSPH, - densityUpdate=densityUpdate, - HUpdate = IdealH, - epsTensile = epsilonTensile, - nTensile = nTensile) else: - Q = MonaghanGingoldViscosity(Cl,Cq,linearInExpansion) hydro = SPH(dataBase = db, - Q = Q, + #Q=MonaghanGingoldViscosity(Cl,Cq), W = WT, cfl = cfl, compatibleEnergyEvolution = compatibleEnergy, gradhCorrection = gradhCorrection, XSPH = XSPH, - correctVelocityGradient=correctVelocityGradient, + correctVelocityGradient=False, densityUpdate = densityUpdate, HUpdate = HUpdate, epsTensile = epsilonTensile, @@ -412,17 +307,16 @@ def __call__(self, x): #------------------------------------------------------------------------------- # Construct the artificial viscosity. #------------------------------------------------------------------------------- -if not (mfm or gsph): - q = hydro.Q - q.Cl = Cl - q.Cq = Cq - q.epsilon2 = epsilon2 - q.limiter = Qlimiter - output("q") - output("q.Cl") - output("q.Cq") - output("q.epsilon2") - output("q.limiter") +q = hydro.Q +q.Cl = Cl +q.Cq = Cq +q.epsilon2 = epsilon2 +q.limiter = Qlimiter +output("q") +output("q.Cl") +output("q.Cq") +output("q.epsilon2") +output("q.limiter") #------------------------------------------------------------------------------- # Create boundary conditions. @@ -488,7 +382,6 @@ def printTotalEnergy(cycle,time,dt): control = SpheralController(integrator, WT, statsStep = statsStep, restartStep = restartStep, - vizTime=1.0, restartBaseName = restartBaseName, restoreCycle = restoreCycle, periodicWork=[(printTotalEnergy,1)]) @@ -624,11 +517,11 @@ def printTotalEnergy(cycle,time,dt): ("h ", hprof, hans)]: assert len(data) == len(ans) error = [data[i] - ans[i] for i in range(len(data))] - #Pn = Pnorm.Pnorm(error, xprof) - L1 = sum([abs(data[i] - ans[i]) for i in range(len(data))])/len(data)#Pn.pnorm(1, xmin, xmax) - L2 = (sum([abs(data[i] - ans[i])**2.0 for i in range(len(data))]))**(1.0/2.0)/len(data) - Linf = (sum([abs(data[i] - ans[i])**100.0 for i in range(len(data))]))**(1.0/100.0)/len(data) - print "\t%s \t\t%g \t\t%g \t\t%g" % (name, L1, L2, Linf) + Pn = Pnorm.Pnorm(error, xprof) + L1 = Pn.gridpnorm(1, xmin, xmax) + L2 = Pn.gridpnorm(2, xmin, xmax) + Linf = Pn.gridpnorm("inf", xmin, xmax) + print("\t%s \t\t%g \t\t%g \t\t%g" % (name, L1, L2, Linf)) if normOutputFile != "None": f.write((3*"%16.12e ") % (L1, L2, Linf)) # if name == "Mass Density": @@ -654,8 +547,8 @@ def printTotalEnergy(cycle,time,dt): # pickle.dump(data,f) -if compatibleEnergy and abs(Eerror) > 1e-4: - raise ValueError, "Energy error outside allowed bounds." +if compatibleEnergy and abs(Eerror) > 1e-5: + raise ValueError("Energy error outside allowed bounds.") diff --git a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py index 76826e861..b11576f72 100644 --- a/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py +++ b/tests/functional/Hydro/Noh/Noh-cylindrical-2d.py @@ -49,8 +49,8 @@ thetaFactor = 0.5, azimuthalOffsetFraction = 0.0, - nRadial = 100, - nTheta = 100, + nRadial = 50, + nTheta = 50, rmin = 0.0, rmax = 1.0, rho0 = 1.0, @@ -73,7 +73,6 @@ asph = False, # This just chooses the H algorithm -- you can use this with CRKSPH for instance. solid = False, # If true, use the fluid limit of the solid hydro option - nodeMotion = NodeMotionType.Lagrangian, # general hydro options densityUpdate = RigorousSumDensity, # (IntegrateDensity) evolveTotalEnergy = False, # evolve total rather than specific energy @@ -92,6 +91,9 @@ correctionOrder = LinearOrder, volumeType = RKSumVolume, + # MFV + nodeMotion = NodeMotionType.Lagrangian, + # artificial viscosity Cl = None, Cq = None, @@ -118,16 +120,16 @@ # kernel options KernelConstructor = NBSplineKernel, #(NBSplineKernel,WendlandC2Kernel,WendlandC4Kernel,WendlandC6Kernel) - nPerh = 1.00, + nPerh = 2.01, HUpdate = IdealH, - order = 3, + order = 5, hmin = 0.0001, hmax = 0.5, hminratio = 0.1, # integrator options IntegratorConstructor = CheapSynchronousRK2Integrator, - cfl = 0.07, + cfl = 0.25, goalTime = 0.6, steps = None, vizCycle = None, diff --git a/tests/functional/Hydro/Noh/Noh-spherical-3d.py b/tests/functional/Hydro/Noh/Noh-spherical-3d.py index 87d61b8fb..43226af1a 100644 --- a/tests/functional/Hydro/Noh/Noh-spherical-3d.py +++ b/tests/functional/Hydro/Noh/Noh-spherical-3d.py @@ -22,7 +22,7 @@ #------------------------------------------------------------------------------- # Generic problem parameters #------------------------------------------------------------------------------- -commandLine(order = 3, +commandLine(order = 5, seed = "lattice", nx = 50, @@ -37,7 +37,7 @@ z1 = 1.0, rmin = 0.0, rmax = 1.0, - nPerh = 1.00, + nPerh = 2.01, rho0 = 1.0, eps0 = 0.0, smallPressure = False, diff --git a/tests/functional/Hydro/RayleighTaylor/RT-2d.py b/tests/functional/Hydro/RayleighTaylor/RT-2d.py index 62d55513b..c0203ce2e 100644 --- a/tests/functional/Hydro/RayleighTaylor/RT-2d.py +++ b/tests/functional/Hydro/RayleighTaylor/RT-2d.py @@ -171,13 +171,11 @@ def __call__(self, r): ) -assert not svph assert not (compatibleEnergy and evolveTotalEnergy) assert sum([fsisph,psph,gsph,crksph,svph,mfm])<=1 assert not (fsisph and not solid) assert not ((mfm or gsph) and (boolReduceViscosity)) - # Decide on our hydro algorithm. hydroname = 'SPH' useArtificialViscosity=True diff --git a/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py b/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py index 4d305a06c..3175acd48 100644 --- a/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py +++ b/tests/functional/Hydro/RayleighTaylor/RT-2d_Hopkins.py @@ -166,16 +166,12 @@ def __call__(self, r): arCondAlpha = 0.5, ) - - -assert not svph assert not (compatibleEnergy and evolveTotalEnergy) assert sum([fsisph,psph,gsph,crksph,svph,mfm])<=1 assert not (fsisph and not solid) assert not ((mfm or gsph) and (boolReduceViscosity or boolReduceViscosity)) assert not(boolReduceViscosity and boolCullenViscosity) - hydroname = 'SPH' useArtificialViscosity=True From 5f3fa7340d2835cc5ff2ac4bad846556f8f765bd Mon Sep 17 00:00:00 2001 From: jmpearl Date: Mon, 3 Jun 2024 20:16:06 -0700 Subject: [PATCH 59/60] GSPH updating release notes --- RELEASE_NOTES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fe35d2250..ea2435e59 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,6 +6,7 @@ Version vYYYY.MM.p -- Release date YYYY-MM-DD Notable changes include: * New features/ API changes: + * added MFV hydro from Hopkins 2015 with extension for ALE options * Build changes / improvements: * tpl-manager.py will no longer use generic x86_64 configs for non LC systems. Users will be required to supply their own configs for pointing spack at external packages. From 22b202d9e342b5b092e3e09c652a253e90b25eb6 Mon Sep 17 00:00:00 2001 From: jmpearl Date: Tue, 4 Jun 2024 20:55:54 -0700 Subject: [PATCH 60/60] GSPH updating Yee to remove llyod --- .../Hydro/YeeVortex/LlyodsAlgorithm.py | 89 ------------------- tests/functional/Hydro/YeeVortex/YeeVortex.py | 37 -------- 2 files changed, 126 deletions(-) delete mode 100755 tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py diff --git a/tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py b/tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py deleted file mode 100755 index 7b282545e..000000000 --- a/tests/functional/Hydro/YeeVortex/LlyodsAlgorithm.py +++ /dev/null @@ -1,89 +0,0 @@ -import mpi -from Spheral import computeVoronoiVolume, HydroFieldNames - -def LlyodsAlgorithm(db,hydro,inDomain,rhoAtmo,nPerh,nRelaxIters): -#=============================================================================== -# inputs: -# db ---------- database containing nodeLists for mass correction -# hydro ------- hydro obj used to access the boundary conditions -# inDomain ---- logic function returns true if point is inside domain false otherwise -# rhoAtmo ----- function specifying the density profile -# nPerh ------- nodes per smoothing length (implementation hack) -# nRelaxIters - number of centroidal relaxation steps (0 for simple voronoi volume correction) -#=============================================================================== - - # multiplication factor for centroid relaxation delta - assert db.nDim in (2,3) - - # geometry specific functions - exec('from Spheral{0}d import SymTensor, IntFieldList, Vector, vector_of_Vector, FacetedVolumeFieldList, vector_of_CellFaceFlagFieldList, vector_of_FacetedVolume, vector_of_Boundary, ScalarFieldList, SymTensorFieldList, vector_of_vector_of_FacetedVolume, vector_of_FacetedVolume'.format(db.nDim)) - - # Fields we need to create for the voronoi volumme calculation function - faceted_bounds = vector_of_FacetedVolume() - bounds = vector_of_Boundary() # Bounds enforced by inDomain function - weight = ScalarFieldList() # No weights - damage = SymTensorFieldList() # No damage - holes = vector_of_vector_of_FacetedVolume([vector_of_FacetedVolume()]) - surfacePoint = IntFieldList() # db.newFluidIntFieldList(0, HydroFieldNames.surfacePoint) - vol = db.newFluidScalarFieldList(0.0, HydroFieldNames.volume) - deltaMedian = db.newFluidVectorFieldList(Vector.zero, "centroidal delta") - etaVoidPoints = db.newFluidvector_of_VectorFieldList(vector_of_Vector(), "eta void points") - cells = FacetedVolumeFieldList()#db.newFluidFacetedVolumeFieldList(FacetedVolume(), "cells") - cellFaceFlags = vector_of_CellFaceFlagFieldList()#db.newFluidvector_of_CellFaceFlagFieldList(vector_of_int(), "face flags") - - - - # get the bcs from hydro and add in parallel domain bcs if appropriate - bcs = hydro.boundaryConditions() - - # loop through nodeLists and zero out nPerh to - # circumvent computeVoronoiVolumes void point feature - fluidNodeLists = db.fluidNodeLists() - #for nodes in fluidNodeLists: - - print(db.numFluidNodeLists,db.numSolidNodeLists) - for j in range(nRelaxIters): # centroidal relax n times - print('centroidal relaxation: iteration {0}'.format(j)) - - # centroidal relaxation - #print(' relax...') - for k in range(db.numFluidNodeLists): - for i in range(fluidNodeLists[k].numInternalNodes): - if inDomain(db.fluidPosition(k,i)): # I used this to handle constant BC - db.fluidPosition[k][i] = db.fluidPosition(k,i)+deltaMedian(k,i) # move to centroid - - for nodes in fluidNodeLists: - nodes.numGhostNodes=0 - - #print(' bcs...') - for bc in bcs: - bc.setAllGhostNodes(db) # generate all the ghost nodes - bc.finalizeGhostBoundary() # hit the finalize for bcs that need that - - #print(' connectivity...') - db.reinitializeNeighbors() # update neighbors - db.updateConnectivityMap(False,False) # update connectivity - #(False,False) - # 1) dont compute connectivity for ghosts - # 2) dont compute overlap connectivity - - #print(' volume...') - computeVoronoiVolume(db.fluidPosition, - db.fluidHfield, - db.connectivityMap(), - damage, # believe this is inactive? - faceted_bounds, # specify domain extent - holes, # polygonal/polyhedral holes in region - bounds, # boundaries - weight, # weighting function - surfacePoint, # between substances - vol, # those volumes we want - deltaMedian, # distance from centroid - etaVoidPoints, # void nodes - cells, # polygon/polyhedron object - cellFaceFlags) - for k in range(db.numFluidNodeLists): - fluidNodeLists[k].nodesPerSmoothingScale = nPerh - - - \ No newline at end of file diff --git a/tests/functional/Hydro/YeeVortex/YeeVortex.py b/tests/functional/Hydro/YeeVortex/YeeVortex.py index ddbce9426..0f7b51829 100644 --- a/tests/functional/Hydro/YeeVortex/YeeVortex.py +++ b/tests/functional/Hydro/YeeVortex/YeeVortex.py @@ -14,7 +14,6 @@ from GenerateNodeDistribution2d import * from CubicNodeGenerator import GenerateSquareNodeDistribution from CentroidalVoronoiRelaxation import * -from LlyodsAlgorithm import LlyodsAlgorithm import DistributeNodes class YeeDensity: @@ -69,7 +68,6 @@ def __call__(self, r): # Resolution and node seeding. nRadial = 64, seed = "constantDTheta", - numLlyodIters = 4, # kernel options KernelConstructor = WendlandC2Kernel, @@ -586,41 +584,6 @@ def __call__(self, r): skipInitialPeriodicWork = svph) output("control") -if numLlyodIters>0: - - def inDomain(pos): - if pos.magnitude() < rmax: - return True - else: - return False - - LlyodsAlgorithm(db,hydro,inDomain,YeeDensity(xc,yc,gamma,beta,temp_inf),nPerh,numLlyodIters) - - vel = nodes.velocity() - eps = nodes.specificThermalEnergy() - pos = nodes.positions() - rho = nodes.massDensity() - mass = nodes.mass() - #vol = hydro.volume[0] - - # for i in xrange(nodes.numInternalNodes): - # xi, yi = pos[i] - # xci = (xi-xc) - # yci = (yi-yc) - # r2=xci*xci+yci*yci - # velx = vel_infx-yci*exp((1.0-r2)*0.5)*beta/(2.0*pi) - # vely = vel_infy+xci*exp((1.0-r2)*0.5)*beta/(2.0*pi) - # rhoNew = YeeDensityFunc(pos[i]) - # mass[i] = rhoNew*mass[i]*rho[i] - # rho[i] = rhoNew - # vel[i] = Vector(velx,vely) - # eps[i] = pow(rho[i],(gamma-1.0))/(gamma-1.0) - # packages = integrator.physicsPackages() - # state = State2d(db, packages) - # integrator.setGhostNodes() - # derivs = StateDerivatives2d(db, packages) - # integrator.applyGhostBoundaries(state, derivs) - # integrator.finalizeGhostBoundaries() #------------------------------------------------------------------------------- # Advance to the end time. #-------------------------------------------------------------------------------