diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/Make/files b/applications/solvers/multiphase/compressibleInterIsoFoam/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..3e4ec6e8991149ab5852470eba69923f64fff96d --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/Make/files @@ -0,0 +1,3 @@ +compressibleInterIsoFoam.C + +EXE = $(FOAM_APPBIN)/compressibleInterIsoFoam diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/Make/options b/applications/solvers/multiphase/compressibleInterIsoFoam/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..9a2c766179fb8e7af91a785db146d9556fecd15c --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/Make/options @@ -0,0 +1,39 @@ +EXE_INC = \ + -I. \ + -I../VoF \ + -I../compressibleInterFoam \ + -I$(FOAM_SOLVERS)/multiphase/compressibleInterFoam/twoPhaseMixtureThermo \ + -I$(FOAM_SOLVERS)/multiphase/compressibleInterFoam/VoFphaseCompressibleTurbulenceModels \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/dynamicMesh/lnInclude \ + -I$(LIB_SRC)/dynamicFvMesh/lnInclude \ + -I$(LIB_SRC)/transportModels/compressible/lnInclude \ + -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ + -I$(LIB_SRC)/transportModels/twoPhaseMixture/lnInclude \ + -I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \ + -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ + -I$(LIB_SRC)/TurbulenceModels/compressible/lnInclude \ + -I$(LIB_SRC)/TurbulenceModels/phaseCompressible/lnInclude \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lfvOptions \ + -lsurfMesh \ + -lmeshTools \ + -ldynamicMesh \ + -ldynamicFvMesh \ + -ltwoPhaseMixtureThermo \ + -ltwoPhaseSurfaceTension \ + -lcompressibleTransportModels \ + -lfluidThermophysicalModels \ + -lspecie \ + -ltwoPhaseMixture \ + -ltwoPhaseProperties \ + -linterfaceProperties \ + -lturbulenceModels \ + -lcompressibleTurbulenceModels \ + -lVoFphaseCompressibleTurbulenceModels \ + -lgeometricVoF diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/alphaControls.H b/applications/solvers/multiphase/compressibleInterIsoFoam/alphaControls.H new file mode 100644 index 0000000000000000000000000000000000000000..2e94f34d752b7465f8eade4425fb76d9d84ab880 --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/alphaControls.H @@ -0,0 +1,3 @@ +const dictionary& alphaControls = mesh.solverDict(alpha1.name()); + +label nAlphaSubCycles(alphaControls.get<label>("nAlphaSubCycles")); diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/alphaEqn.H b/applications/solvers/multiphase/compressibleInterIsoFoam/alphaEqn.H new file mode 100644 index 0000000000000000000000000000000000000000..5ded2e30c0f130884b2b63a3b2f4be693ca46fc5 --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/alphaEqn.H @@ -0,0 +1,15 @@ +// Update alpha1 +#include "alphaSuSp.H" +advector.advect(Sp,(Su + divU*min(alpha1(), scalar(1)))()); + +// Update rhoPhi +rhoPhi = advector.getRhoPhi(rho1, rho2); +alphaPhi10 = advector.alphaPhi(); + +alpha2 = 1.0 - alpha1; + +Info<< "Phase-1 volume fraction = " + << alpha1.weightedAverage(mesh.Vsc()).value() + << " Min(" << alpha1.name() << ") = " << min(alpha1).value() + << " Max(" << alpha1.name() << ") - 1 = " << max(alpha1).value() - 1 + << endl; diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/alphaSuSp.H b/applications/solvers/multiphase/compressibleInterIsoFoam/alphaSuSp.H new file mode 100644 index 0000000000000000000000000000000000000000..65c5750ff94f1acf7549bd16e29b171ff6f308d4 --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/alphaSuSp.H @@ -0,0 +1,43 @@ +volScalarField::Internal Sp +( + IOobject + ( + "Sp", + runTime.timeName(), + mesh + ), + mesh, + dimensionedScalar(dgdt.dimensions(), Zero) +); + +volScalarField::Internal Su +( + IOobject + ( + "Su", + runTime.timeName(), + mesh + ), + mesh, + dimensionedScalar(dgdt.dimensions(), Zero) +); + +forAll(dgdt, celli) +{ + if (dgdt[celli] > 0.0) + { + Sp[celli] -= dgdt[celli]/max(1.0 - alpha1[celli], 1e-4); + Su[celli] += dgdt[celli]/max(1.0 - alpha1[celli], 1e-4); + } + else if (dgdt[celli] < 0.0) + { + Sp[celli] += dgdt[celli]/max(alpha1[celli], 1e-4); + } +} + +volScalarField::Internal divU +( + mesh.moving() + ? fvc::div(phi + mesh.phi()) + : fvc::div(phi) +); diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/compressibleAlphaEqnSubCycle.H b/applications/solvers/multiphase/compressibleInterIsoFoam/compressibleAlphaEqnSubCycle.H new file mode 100644 index 0000000000000000000000000000000000000000..5fda0912c58c090016a887d6f67090a517c7b44e --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/compressibleAlphaEqnSubCycle.H @@ -0,0 +1,70 @@ +if (pimple.nCorrPIMPLE() > 1) +{ + if (!pimple.firstIter()) + { + // Resetting alpha1 to value before advection in first PIMPLE + // iteration. + alpha1 = alpha1.oldTime(); + } +} +tmp<surfaceScalarField> talphaPhi1(alphaPhi10); + +if (nAlphaSubCycles > 1) +{ + dimensionedScalar totalDeltaT = runTime.deltaT(); + + talphaPhi1 = new surfaceScalarField + ( + IOobject + ( + "alphaPhi1", + runTime.timeName(), + mesh + ), + mesh, + dimensionedScalar(alphaPhi10.dimensions(), Zero) + ); + + surfaceScalarField rhoPhiSum + ( + IOobject + ( + "rhoPhiSum", + runTime.timeName(), + mesh + ), + mesh, + dimensionedScalar(rhoPhi.dimensions(), Zero) + ); + + for + ( + subCycle<volScalarField> alphaSubCycle(alpha1, nAlphaSubCycles); + !(++alphaSubCycle).end(); + ) + { + #include "alphaEqn.H" + talphaPhi1.ref() += (runTime.deltaT()/totalDeltaT)*alphaPhi10; + rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi; + } + + rhoPhi = rhoPhiSum; +} +else +{ + #include "alphaEqn.H" +} + +rho == alpha1*rho1 + alpha2*rho2; + +const surfaceScalarField& alphaPhi1 = talphaPhi1(); +surfaceScalarField alphaPhi2("alphaPhi2", phi - alphaPhi1); + +volScalarField::Internal contErr +( + ( + fvc::ddt(rho) + fvc::div(rhoPhi) + - (fvOptions(alpha1, mixture.thermo1().rho())&rho1) + - (fvOptions(alpha2, mixture.thermo2().rho())&rho2) + )() +); diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/compressibleInterIsoFoam.C b/applications/solvers/multiphase/compressibleInterIsoFoam/compressibleInterIsoFoam.C new file mode 100644 index 0000000000000000000000000000000000000000..59edb5702a757fa1ca805d685db408038b8f3fdd --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/compressibleInterIsoFoam.C @@ -0,0 +1,203 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 OpenCFD Ltd. + Copyright (C) 2020 Johan Roenby + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + compressibleInterFlow + +Description + Solver derived from interFoam for two compressible, immiscible + fluids using the isoAdvector phase-fraction based interface capturing + approach, with optional mesh motion and mesh topology changes including + adaptive re-meshing. + + Reference: + \verbatim + Roenby, J., Bredmose, H. and Jasak, H. (2016). + A computational method for sharp interface advection + Royal Society Open Science, 3 + doi 10.1098/rsos.160405 + \endverbatim + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "dynamicFvMesh.H" +#include "CMULES.H" +#include "EulerDdtScheme.H" +#include "localEulerDdtScheme.H" +#include "CrankNicolsonDdtScheme.H" +#include "subCycle.H" +#include "compressibleInterPhaseTransportModel.H" +#include "pimpleControl.H" +#include "fvOptions.H" +#include "CorrectPhi.H" +#include "fvcSmooth.H" +#include "dynamicRefineFvMesh.H" +#include "isoAdvection.H" +#include "twoPhaseMixtureThermo.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + argList::addNote + ( + "Solver for two compressible, non-isothermal immiscible fluids" + " using VOF phase-fraction based interface capturing.\n" + "With optional mesh motion and mesh topology changes including" + " adaptive re-meshing." + ); + + #include "postProcess.H" + + #include "setRootCaseLists.H" + #include "createTime.H" + #include "createDynamicFvMesh.H" + #include "initContinuityErrs.H" + #include "createDyMControls.H" + #include "createFields.H" + #include "createUf.H" + #include "CourantNo.H" + #include "setInitialDeltaT.H" + + volScalarField& p = mixture.p(); + volScalarField& T = mixture.T(); + const volScalarField& psi1 = mixture.thermo1().psi(); + const volScalarField& psi2 = mixture.thermo2().psi(); + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + Info<< "\nStarting time loop\n" << endl; + + while (runTime.run()) + { + #include "readDyMControls.H" + + // Store divU and divUp from the previous mesh so that it can be mapped + // and used in correctPhi to ensure the corrected phi has the + // same divergence + volScalarField divU("divU0", fvc::div(fvc::absolute(phi, U))); + + #include "CourantNo.H" + #include "alphaCourantNo.H" + #include "setDeltaT.H" + + + ++runTime; + + Info<< "Time = " << runTime.timeName() << nl << endl; + + // --- Pressure-velocity PIMPLE corrector loop + while (pimple.loop()) + { + if (pimple.firstIter() || moveMeshOuterCorrectors) + { + scalar timeBeforeMeshUpdate = runTime.elapsedCpuTime(); + + if (isA<dynamicRefineFvMesh>(mesh)) + { + advector.surf().reconstruct(); + } + + mesh.update(); + + if (mesh.changing()) + { + gh = (g & mesh.C()) - ghRef; + ghf = (g & mesh.Cf()) - ghRef; + + if (isA<dynamicRefineFvMesh>(mesh)) + { + advector.surf().mapAlphaField(); + alpha2 = 1.0 - alpha1; + alpha2.correctBoundaryConditions(); + rho == alpha1*rho1 + alpha2*rho2; + rho.correctBoundaryConditions(); + rho.oldTime() = rho; + alpha2.oldTime() = alpha2; + } + + MRF.update(); + + Info<< "Execution time for mesh.update() = " + << runTime.elapsedCpuTime() - timeBeforeMeshUpdate + << " s" << endl; + + } + + if ((mesh.changing() && correctPhi)) + { + // Calculate absolute flux from the mapped surface velocity + phi = mesh.Sf() & Uf; + + #include "correctPhi.H" + + // Make the fluxes relative to the mesh motion + fvc::makeRelative(phi, U); + + mixture.correct(); + } + + if (mesh.changing() && checkMeshCourantNo) + { + #include "meshCourantNo.H" + } + } + + #include "alphaControls.H" + #include "compressibleAlphaEqnSubCycle.H" + + turbulence.correctPhasePhi(); + + #include "UEqn.H" + volScalarField divUp("divUp", fvc::div(fvc::absolute(phi, U), p)); + #include "TEqn.H" + + // --- Pressure corrector loop + while (pimple.correct()) + { + #include "pEqn.H" + } + + if (pimple.turbCorr()) + { + turbulence.correct(); + } + } + + runTime.write(); + + runTime.printExecutionTime(Info); + } + + Info<< "End\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/correctPhi.H b/applications/solvers/multiphase/compressibleInterIsoFoam/correctPhi.H new file mode 100644 index 0000000000000000000000000000000000000000..ad73a951ff220bfc14c8e9de9afc393515f2fcbd --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/correctPhi.H @@ -0,0 +1,13 @@ +CorrectPhi +( + U, + phi, + p, + dimensionedScalar("rAUf", dimTime/rho.dimensions(), 1), + divU, + pimple +); + +//***HGW phi.oldTime() = phi; + +#include "continuityErrs.H" diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/createFields.H b/applications/solvers/multiphase/compressibleInterIsoFoam/createFields.H new file mode 100644 index 0000000000000000000000000000000000000000..4725a8356da967e410e7c38bff04ab96a062c124 --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/createFields.H @@ -0,0 +1,110 @@ +#include "createRDeltaT.H" + +Info<< "Reading field p_rgh\n" << endl; +volScalarField p_rgh +( + IOobject + ( + "p_rgh", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh +); + +Info<< "Reading field U\n" << endl; +volVectorField U +( + IOobject + ( + "U", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh +); + +#include "createPhi.H" + +Info<< "Constructing twoPhaseMixtureThermo\n" << endl; +twoPhaseMixtureThermo mixture(U, phi); + + +volScalarField& alpha1(mixture.alpha1()); +volScalarField& alpha2(mixture.alpha2()); + +Info<< "Reading thermophysical properties\n" << endl; + +const volScalarField& rho1 = mixture.thermo1().rho(); +const volScalarField& rho2 = mixture.thermo2().rho(); + +volScalarField rho +( + IOobject + ( + "rho", + runTime.timeName(), + mesh, + IOobject::READ_IF_PRESENT, + IOobject::AUTO_WRITE + ), + alpha1*rho1 + alpha2*rho2 +); + + +dimensionedScalar pMin +( + "pMin", + dimPressure, + mixture +); + +mesh.setFluxRequired(p_rgh.name()); +mesh.setFluxRequired(alpha1.name()); + + +#include "readGravitationalAcceleration.H" +#include "readhRef.H" +#include "gh.H" + + +// Mass flux +// Initialisation does not matter because rhoPhi is reset after the +// alpha1 solution before it is used in the U equation. +surfaceScalarField rhoPhi +( + IOobject + ( + "rhoPhi", + runTime.timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + fvc::interpolate(rho)*phi +); + +volScalarField dgdt(alpha1*fvc::div(phi)); + +#include "createAlphaFluxes.H" + +Foam::isoAdvection advector(alpha1,phi,U); +// Construct compressible turbulence model +compressibleInterPhaseTransportModel turbulence +( + rho, + U, + phi, + rhoPhi, + alphaPhi10, + mixture +); + +#include "createK.H" + +#include "createMRF.H" +#include "createFvOptions.H" diff --git a/applications/solvers/multiphase/compressibleInterIsoFoam/pEqn.H b/applications/solvers/multiphase/compressibleInterIsoFoam/pEqn.H new file mode 100644 index 0000000000000000000000000000000000000000..f3fc5b546c46cb659cac43eddbc7601613202cb4 --- /dev/null +++ b/applications/solvers/multiphase/compressibleInterIsoFoam/pEqn.H @@ -0,0 +1,169 @@ +{ + volScalarField rAU("rAU", 1.0/UEqn.A()); + surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU)); + volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p_rgh)); + surfaceScalarField phiHbyA + ( + "phiHbyA", + fvc::flux(HbyA) + + MRF.zeroFilter(fvc::interpolate(rho*rAU)*fvc::ddtCorr(U, Uf)) + ); + MRF.makeRelative(phiHbyA); + + surfaceScalarField phig + ( + ( + mixture.surfaceTensionForce() + - ghf*fvc::snGrad(rho) + )*rAUf*mesh.magSf() + ); + + phiHbyA += phig; + + // Update the pressure BCs to ensure flux consistency + constrainPressure(p_rgh, U, phiHbyA, rAUf, MRF); + + // Make the fluxes relative to the mesh motion + fvc::makeRelative(phiHbyA, U); + + tmp<fvScalarMatrix> p_rghEqnComp1; + tmp<fvScalarMatrix> p_rghEqnComp2; + + if (pimple.transonic()) + { + #include "rhofs.H" + + surfaceScalarField phid1("phid1", fvc::interpolate(psi1)*phi); + surfaceScalarField phid2("phid2", fvc::interpolate(psi2)*phi); + + p_rghEqnComp1 = + ( + ( + fvc::ddt(alpha1, rho1) + fvc::div(alphaPhi1*rho1f) + - (fvOptions(alpha1, mixture.thermo1().rho())&rho1) + )/rho1 + - fvc::ddt(alpha1) - fvc::div(alphaPhi1) + + (alpha1/rho1) + *correction + ( + psi1*fvm::ddt(p_rgh) + + fvm::div(phid1, p_rgh) - fvm::Sp(fvc::div(phid1), p_rgh) + ) + ); + p_rghEqnComp1.ref().relax(); + + p_rghEqnComp2 = + ( + ( + fvc::ddt(alpha2, rho2) + fvc::div(alphaPhi2*rho2f) + - (fvOptions(alpha2, mixture.thermo2().rho())&rho2) + )/rho2 + - fvc::ddt(alpha2) - fvc::div(alphaPhi2) + + (alpha2/rho2) + *correction + ( + psi2*fvm::ddt(p_rgh) + + fvm::div(phid2, p_rgh) - fvm::Sp(fvc::div(phid2), p_rgh) + ) + ); + p_rghEqnComp2.ref().relax(); + } + else + { + #include "rhofs.H" + + p_rghEqnComp1 = + pos(alpha1) + *( + ( + fvc::ddt(alpha1, rho1) + fvc::div(alphaPhi1*rho1f) + - (fvOptions(alpha1, mixture.thermo1().rho())&rho1) + )/rho1 + - fvc::ddt(alpha1) - fvc::div(alphaPhi1) + + (alpha1*psi1/rho1)*correction(fvm::ddt(p_rgh)) + ); + + p_rghEqnComp2 = + pos(alpha2) + *( + ( + fvc::ddt(alpha2, rho2) + fvc::div(alphaPhi2*rho2f) + - (fvOptions(alpha2, mixture.thermo2().rho())&rho2) + )/rho2 + - fvc::ddt(alpha2) - fvc::div(alphaPhi2) + + (alpha2*psi2/rho2)*correction(fvm::ddt(p_rgh)) + ); + } + + if (mesh.moving()) + { + p_rghEqnComp1.ref() += fvc::div(mesh.phi())*alpha1; + p_rghEqnComp2.ref() += fvc::div(mesh.phi())*alpha2; + } + + p_rghEqnComp1.ref() *= pos(alpha1); + p_rghEqnComp2.ref() *= pos(alpha2); + + if (pimple.transonic()) + { + p_rghEqnComp1.ref().relax(); + p_rghEqnComp2.ref().relax(); + } + + // Cache p_rgh prior to solve for density update + volScalarField p_rgh_0(p_rgh); + + while (pimple.correctNonOrthogonal()) + { + fvScalarMatrix p_rghEqnIncomp + ( + fvc::div(phiHbyA) + - fvm::laplacian(rAUf, p_rgh) + ); + + solve + ( + p_rghEqnComp1() + p_rghEqnComp2() + p_rghEqnIncomp, + mesh.solver(p_rgh.select(pimple.finalInnerIter())) + ); + + if (pimple.finalNonOrthogonalIter()) + { + p = max(p_rgh + (alpha1*rho1 + alpha2*rho2)*gh, pMin); + p_rgh = p - (alpha1*rho1 + alpha2*rho2)*gh; + + dgdt = + ( + alpha1*(p_rghEqnComp2 & p_rgh) + - alpha2*(p_rghEqnComp1 & p_rgh) + ); + + phi = phiHbyA + p_rghEqnIncomp.flux(); + + U = HbyA + + rAU*fvc::reconstruct((phig + p_rghEqnIncomp.flux())/rAUf); + U.correctBoundaryConditions(); + fvOptions.correct(U); + } + } + + // Correct Uf if the mesh is moving + { + Uf = fvc::interpolate(U); + surfaceVectorField n(mesh.Sf()/mesh.magSf()); + Uf += n*(fvc::absolute(phi, U)/mesh.magSf() - (n & Uf)); + } + + + // Update densities from change in p_rgh + mixture.thermo1().correctRho(psi1*(p_rgh - p_rgh_0)); + mixture.thermo2().correctRho(psi2*(p_rgh - p_rgh_0)); + + rho = alpha1*rho1 + alpha2*rho2; + + // Correct p_rgh for consistency with p and the updated densities + p_rgh = p - rho*gh; + p_rgh.correctBoundaryConditions(); + + K = 0.5*magSqr(U); +} diff --git a/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/Make/options b/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/Make/options index 0a7adfbd0409a5342a0f174b97b65cfd1c8386f0..740a55f4a0d7f2473908203fe6e9858c28094895 100644 --- a/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/Make/options +++ b/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/Make/options @@ -7,7 +7,8 @@ EXE_INC = \ -I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/solidSpecie/lnInclude \ - -I$(LIB_SRC)/transportModels/compressible/lnInclude + -I$(LIB_SRC)/transportModels/compressible/lnInclude \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude LIB_LIBS = \ -lfiniteVolume \ @@ -15,4 +16,5 @@ LIB_LIBS = \ -lfluidThermophysicalModels \ -lreactionThermophysicalModels \ -lsolidThermo \ - -lsolidSpecie + -lsolidSpecie \ + -lgeometricVoF diff --git a/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/interfaceHeatResistance/interfaceHeatResistance.C b/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/interfaceHeatResistance/interfaceHeatResistance.C index 32f1145a2d4a33182c110dc09c0ebb601d417e5a..4374ac40a873ba93c6ba142a944bfc410278d9dd 100644 --- a/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/interfaceHeatResistance/interfaceHeatResistance.C +++ b/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/interfaceHeatResistance/interfaceHeatResistance.C @@ -28,7 +28,7 @@ License #include "interfaceHeatResistance.H" #include "constants.H" -#include "isoCutCell.H" +#include "cutCellIso.H" #include "volPointInterpolation.H" #include "wallPolyPatch.H" #include "fvcSmooth.H" @@ -52,7 +52,7 @@ interfaceHeatResistance<Thermo, OtherThermo> volPointInterpolation::New(mesh).interpolate(alpha) ); - isoCutCell cutCell(mesh, ap); + cutCellIso cutCell(mesh, ap); forAll(interfaceArea_, celli) { @@ -61,7 +61,7 @@ interfaceHeatResistance<Thermo, OtherThermo> if (status == 0) // cell is cut { interfaceArea_[celli] = - mag(cutCell.isoFaceArea())/mesh.V()[celli]; + mag(cutCell.faceArea())/mesh.V()[celli]; } } diff --git a/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/kineticGasEvaporation/kineticGasEvaporation.C b/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/kineticGasEvaporation/kineticGasEvaporation.C index 252e9bbc6028c264363cacabba4f05096347a172..3325fa786d7ca042f93626b132d86939e9224ed6 100644 --- a/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/kineticGasEvaporation/kineticGasEvaporation.C +++ b/applications/solvers/multiphase/icoReactingMultiphaseInterFoam/massTransferModels/kineticGasEvaporation/kineticGasEvaporation.C @@ -27,7 +27,7 @@ License #include "kineticGasEvaporation.H" #include "constants.H" -#include "isoCutCell.H" +#include "cutCellIso.H" #include "volPointInterpolation.H" #include "wallPolyPatch.H" #include "fvcSmooth.H" @@ -50,7 +50,7 @@ void Foam::meltingEvaporationModels::kineticGasEvaporation<Thermo, OtherThermo> volPointInterpolation::New(mesh).interpolate(alpha) ); - isoCutCell cutCell(mesh, ap); + cutCellIso cutCell(mesh, ap); forAll(interfaceArea_, celli) { @@ -59,7 +59,7 @@ void Foam::meltingEvaporationModels::kineticGasEvaporation<Thermo, OtherThermo> if (status == 0) // cell is cut { interfaceArea_[celli] = - mag(cutCell.isoFaceArea())/mesh.V()[celli]; + mag(cutCell.faceArea())/mesh.V()[celli]; } } diff --git a/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/Make/options b/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/Make/options index 4a85a0ae9f3df278ee724f0e46e2e8025c8f6c82..98ce2f94772fc20cbc8f241bb106cb6bfaec799d 100644 --- a/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/Make/options +++ b/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/Make/options @@ -1,16 +1,17 @@ - EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ - -I$(LIB_SRC)/transportModels/twoPhaseMixture/lnInclude \ -I$(LIB_SRC)/transportModels \ + -I$(LIB_SRC)/transportModels/twoPhaseMixture/lnInclude \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude \ -I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \ - -I$(LIB_SRC)/transportModels/incompressible/lnInclude \ - -I$(LIB_SRC)/finiteVolume/lnInclude + -I$(LIB_SRC)/transportModels/incompressible/lnInclude LIB_LIBS = \ + -lfiniteVolume \ + -lgeometricVoF \ -ltwoPhaseMixture \ -linterfaceProperties \ -ltwoPhaseProperties \ -lincompressibleTransportModels \ - -lfiniteVolume \ -lfluidThermophysicalModels diff --git a/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/interfaceHeatResistance/interfaceHeatResistance.C b/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/interfaceHeatResistance/interfaceHeatResistance.C index 598d66a243e980ef67bc0d950e873f377577ce07..368ee3dfdb9ae94d5ee8921b62df7c35737779f8 100644 --- a/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/interfaceHeatResistance/interfaceHeatResistance.C +++ b/applications/solvers/multiphase/interCondensatingEvaporatingFoam/temperaturePhaseChangeTwoPhaseMixtures/interfaceHeatResistance/interfaceHeatResistance.C @@ -29,7 +29,7 @@ License #include "interfaceHeatResistance.H" #include "addToRunTimeSelectionTable.H" #include "twoPhaseMixtureEThermo.H" -#include "isoCutCell.H" +#include "cutCellIso.H" #include "volPointInterpolation.H" #include "calculatedFvPatchFields.H" #include "wallPolyPatch.H" @@ -342,7 +342,7 @@ updateInterface() volPointInterpolation::New(mesh_).interpolate(mixture_.alpha1()) ); - isoCutCell cutCell(mesh_, ap); + cutCellIso cutCell(mesh_, ap); forAll(interfaceArea_, celli) { @@ -351,7 +351,7 @@ updateInterface() if (status == 0) // cell is cut { interfaceArea_[celli] = - mag(cutCell.isoFaceArea())/mesh_.V()[celli]; + mag(cutCell.faceArea())/mesh_.V()[celli]; } } diff --git a/applications/solvers/multiphase/interIsoFoam/Make/options b/applications/solvers/multiphase/interIsoFoam/Make/options index 30a64e1962a9dd68f4a09377f58fafc9ffb6781c..71e17b49628eb622c95a9a8b5931f7d70f47b7d9 100644 --- a/applications/solvers/multiphase/interIsoFoam/Make/options +++ b/applications/solvers/multiphase/interIsoFoam/Make/options @@ -1,19 +1,26 @@ EXE_INC = \ + -I../VoF \ + -I../interFoam \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/sampling/lnInclude \ -I$(LIB_SRC)/dynamicFvMesh/lnInclude \ + -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/transportModels \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude \ -I$(LIB_SRC)/transportModels/twoPhaseMixture/lnInclude \ -I$(LIB_SRC)/transportModels/incompressible/lnInclude \ -I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \ -I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \ - -I$(LIB_SRC)/transportModels/immiscibleIncompressibleTwoPhaseMixture/lnInclude + -I$(LIB_SRC)/transportModels/immiscibleIncompressibleTwoPhaseMixture/lnInclude \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude EXE_LIBS = \ -lfiniteVolume \ -lfvOptions \ + -lsurfMesh \ -lmeshTools \ -lsampling \ -ldynamicFvMesh \ @@ -22,4 +29,5 @@ EXE_LIBS = \ -limmiscibleIncompressibleTwoPhaseMixture \ -lturbulenceModels \ -lincompressibleTurbulenceModels \ - -lwaveModels + -lwaveModels \ + -lgeometricVoF diff --git a/applications/solvers/multiphase/interIsoFoam/UEqn.H b/applications/solvers/multiphase/interIsoFoam/UEqn.H deleted file mode 100644 index 77d1dcd83e8c665fa8127bfadb8d59a94222bc61..0000000000000000000000000000000000000000 --- a/applications/solvers/multiphase/interIsoFoam/UEqn.H +++ /dev/null @@ -1,33 +0,0 @@ - MRF.correctBoundaryVelocity(U); - - fvVectorMatrix UEqn - ( - fvm::ddt(rho, U) + fvm::div(rhoPhi, U) - + MRF.DDt(rho, U) - + turbulence->divDevRhoReff(rho, U) - == - fvOptions(rho, U) - ); - - UEqn.relax(); - - fvOptions.constrain(UEqn); - - if (pimple.momentumPredictor()) - { - solve - ( - UEqn - == - fvc::reconstruct - ( - ( - mixture.surfaceTensionForce() - - ghf*fvc::snGrad(rho) - - fvc::snGrad(p_rgh) - ) * mesh.magSf() - ) - ); - - fvOptions.correct(U); - } diff --git a/applications/solvers/multiphase/interIsoFoam/alphaEqn.H b/applications/solvers/multiphase/interIsoFoam/alphaEqn.H index 8de0ac016121dd1c1e1cc8a93d54e2d4f2d96399..b6f8aecb2f8a209141374939784b0d6fbd99b7f7 100644 --- a/applications/solvers/multiphase/interIsoFoam/alphaEqn.H +++ b/applications/solvers/multiphase/interIsoFoam/alphaEqn.H @@ -6,7 +6,8 @@ } // Updating alpha1 - advector.advect(); + #include "alphaSuSp.H" + advector.advect(Sp, Su); // Making U absolute again after advection step if (mesh.moving()) diff --git a/applications/solvers/multiphase/interIsoFoam/correctPhi.H b/applications/solvers/multiphase/interIsoFoam/correctPhi.H deleted file mode 100644 index fcb5020587cb43e4bdf191ee8d64e8981d53b21b..0000000000000000000000000000000000000000 --- a/applications/solvers/multiphase/interIsoFoam/correctPhi.H +++ /dev/null @@ -1,11 +0,0 @@ -CorrectPhi -( - U, - phi, - p_rgh, - surfaceScalarField("rAUf", fvc::interpolate(rAU())), - geometricZeroField(), - pimple -); - -#include "continuityErrs.H" diff --git a/applications/solvers/multiphase/interIsoFoam/initCorrectPhi.H b/applications/solvers/multiphase/interIsoFoam/initCorrectPhi.H deleted file mode 100644 index 03eb7fd7fdf55b40f0fddf841c027491901a372b..0000000000000000000000000000000000000000 --- a/applications/solvers/multiphase/interIsoFoam/initCorrectPhi.H +++ /dev/null @@ -1,34 +0,0 @@ -tmp<volScalarField> rAU; - -if (correctPhi) -{ - rAU = new volScalarField - ( - IOobject - ( - "rAU", - runTime.timeName(), - mesh, - IOobject::READ_IF_PRESENT, - IOobject::AUTO_WRITE - ), - mesh, - dimensionedScalar("rAU", dimTime/dimDensity, 1) - ); - - #include "correctPhi.H" -} -else -{ - CorrectPhi - ( - U, - phi, - p_rgh, - dimensionedScalar("rAUf", dimTime/rho.dimensions(), 1), - geometricZeroField(), - pimple - ); - - #include "continuityErrs.H" -} diff --git a/applications/solvers/multiphase/interIsoFoam/interIsoFoam.C b/applications/solvers/multiphase/interIsoFoam/interIsoFoam.C index 8b0523fc040e6ceeb091d9cb587e018dfbe2a261..6a694e4a814a34aefc070066688256af156db9e0 100644 --- a/applications/solvers/multiphase/interIsoFoam/interIsoFoam.C +++ b/applications/solvers/multiphase/interIsoFoam/interIsoFoam.C @@ -9,6 +9,7 @@ Copyright (C) 2016 DHI Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2018 Johan Roenby + Copyright (C) 2019-2020 DLR ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -63,6 +64,7 @@ Description #include "fvOptions.H" #include "CorrectPhi.H" #include "fvcSmooth.H" +#include "dynamicRefineFvMesh.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -113,14 +115,29 @@ int main(int argc, char *argv[]) { if (pimple.firstIter() || moveMeshOuterCorrectors) { + if (isA<dynamicRefineFvMesh>(mesh)) + { + advector.surf().reconstruct(); + } + mesh.update(); if (mesh.changing()) { - gh = (g & mesh.C()) - ghRef; ghf = (g & mesh.Cf()) - ghRef; + if (isA<dynamicRefineFvMesh>(mesh)) + { + advector.surf().mapAlphaField(); + alpha2 = 1.0 - alpha1; + alpha2.correctBoundaryConditions(); + rho == alpha1*rho1 + alpha2*rho2; + rho.correctBoundaryConditions(); + rho.oldTime() = rho; + alpha2.oldTime() = alpha2; + } + MRF.update(); if (correctPhi) diff --git a/applications/solvers/multiphase/interIsoFoam/pEqn.H b/applications/solvers/multiphase/interIsoFoam/pEqn.H deleted file mode 100644 index e443f269848af443a24bff674a839ac86e245ad3..0000000000000000000000000000000000000000 --- a/applications/solvers/multiphase/interIsoFoam/pEqn.H +++ /dev/null @@ -1,89 +0,0 @@ -{ - if (correctPhi) - { - rAU.ref() = 1.0/UEqn.A(); - } - else - { - rAU = 1.0/UEqn.A(); - } - - surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU())); - volVectorField HbyA(constrainHbyA(rAU()*UEqn.H(), U, p_rgh)); - surfaceScalarField phiHbyA - ( - "phiHbyA", - fvc::flux(HbyA) - + MRF.zeroFilter(fvc::interpolate(rho*rAU())*fvc::ddtCorr(U, phi, Uf)) - ); - MRF.makeRelative(phiHbyA); - - if (p_rgh.needReference()) - { - fvc::makeRelative(phiHbyA, U); - adjustPhi(phiHbyA, U, p_rgh); - fvc::makeAbsolute(phiHbyA, U); - } - - surfaceScalarField phig - ( - ( - mixture.surfaceTensionForce() - - ghf*fvc::snGrad(rho) - )*rAUf*mesh.magSf() - ); - - phiHbyA += phig; - - // Update the pressure BCs to ensure flux consistency - constrainPressure(p_rgh, U, phiHbyA, rAUf, MRF); - - while (pimple.correctNonOrthogonal()) - { - fvScalarMatrix p_rghEqn - ( - fvm::laplacian(rAUf, p_rgh) == fvc::div(phiHbyA) - ); - - p_rghEqn.setReference(pRefCell, getRefCellValue(p_rgh, pRefCell)); - - p_rghEqn.solve(mesh.solver(p_rgh.select(pimple.finalInnerIter()))); - - if (pimple.finalNonOrthogonalIter()) - { - phi = phiHbyA - p_rghEqn.flux(); - - p_rgh.relax(); - - U = HbyA + rAU()*fvc::reconstruct((phig - p_rghEqn.flux())/rAUf); - U.correctBoundaryConditions(); - fvOptions.correct(U); - } - } - - #include "continuityErrs.H" - - // Correct Uf if the mesh is moving - fvc::correctUf(Uf, U, phi); - - // Make the fluxes relative to the mesh motion - fvc::makeRelative(phi, U); - - p == p_rgh + rho*gh; - - if (p_rgh.needReference()) - { - p += dimensionedScalar - ( - "p", - p.dimensions(), - pRefValue - getRefCellValue(p, pRefCell) - ); - p_rgh = p - rho*gh; - } - - if (!correctPhi) - { - rAU.clear(); - } -} diff --git a/applications/solvers/multiphase/interIsoFoam/rhofs.H b/applications/solvers/multiphase/interIsoFoam/rhofs.H deleted file mode 100644 index 5949bf1e0a60d21934f09e1fbe8780c5cf7e43d5..0000000000000000000000000000000000000000 --- a/applications/solvers/multiphase/interIsoFoam/rhofs.H +++ /dev/null @@ -1,2 +0,0 @@ -const dimensionedScalar& rho1f(rho1); -const dimensionedScalar& rho2f(rho2); diff --git a/applications/test/leastSquareGrad/Make/files b/applications/test/leastSquareGrad/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..f72004ebd5e4bac4db15dd26125b8719420281e3 --- /dev/null +++ b/applications/test/leastSquareGrad/Make/files @@ -0,0 +1,3 @@ +Test-leastSquareGrad.C + +EXE = $(FOAM_USER_APPBIN)/Test-leastSquareGrad diff --git a/applications/test/leastSquareGrad/Make/options b/applications/test/leastSquareGrad/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..b4ad3d8bdff2f2475467775f28a6c62effa80575 --- /dev/null +++ b/applications/test/leastSquareGrad/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -lsampling diff --git a/applications/test/leastSquareGrad/Test-leastSquareGrad.C b/applications/test/leastSquareGrad/Test-leastSquareGrad.C new file mode 100644 index 0000000000000000000000000000000000000000..ae68fc24cc16fd6f24b2fe00eaa9286cd7b982a4 --- /dev/null +++ b/applications/test/leastSquareGrad/Test-leastSquareGrad.C @@ -0,0 +1,101 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + Test-leastSquareGrad + +Description + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "leastSquareGrad.H" +#include "labelVector.H" +#include "Field.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + labelVector geomDim(1,1,-1); + + leastSquareGrad<scalar> lsGrad("polyDegree1", geomDim); + + List<vector> pos + ({ + {0,0,0}, + {1,0,0}, + {-1,0,0}, + {0,1,0}, + {0,-1,0}, + // {1,1,0} + }); + + List<scalar> values + ({ + 0, 1, -1, 1, -1 + //, 2 + }); + + + Map<List<vector>> posMap; + + posMap.insert(0, pos); + posMap.insert(1, pos); + posMap.insert(2, pos); + + Map<List<scalar>> valMap; + + valMap.insert(0, values); + valMap.insert(1, values); + valMap.insert(2, values); + + Info<< lsGrad.grad(posMap, valMap) << nl; + + + leastSquareGrad<vector> lsGradVec("polyDegree1", geomDim); + + List<vector> valuesVec + ({ + {0,0,0}, + {1,0,0}, + {-1,0,0}, + {1,0,0}, + {-1,0,0} + }); + + Map<List<vector>> valMapVec; + + valMapVec.insert(0, valuesVec); + valMapVec.insert(1, valuesVec); + valMapVec.insert(2, valuesVec); + + Info<< lsGradVec.grad(posMap,valMapVec) << nl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/multiDimPolyFitter/Make/files b/applications/test/multiDimPolyFitter/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..d5b957d1bdc74e9947ba45b84e62929d9923ec6f --- /dev/null +++ b/applications/test/multiDimPolyFitter/Make/files @@ -0,0 +1,3 @@ +Test-multiDimPolyFitter.C + +EXE = $(FOAM_USER_APPBIN)/Test-multiDimPolyFitter diff --git a/applications/test/multiDimPolyFitter/Make/options b/applications/test/multiDimPolyFitter/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..b4ad3d8bdff2f2475467775f28a6c62effa80575 --- /dev/null +++ b/applications/test/multiDimPolyFitter/Make/options @@ -0,0 +1,9 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -lsampling diff --git a/applications/test/multiDimPolyFitter/Test-multiDimPolyFitter.C b/applications/test/multiDimPolyFitter/Test-multiDimPolyFitter.C new file mode 100644 index 0000000000000000000000000000000000000000..77de98ab181e7ff1f4b12c1755caf262950a40ba --- /dev/null +++ b/applications/test/multiDimPolyFitter/Test-multiDimPolyFitter.C @@ -0,0 +1,113 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + Test-multiDimPolyFitter + +Description + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "multiDimPolyFitter.H" +#include "labelVector.H" +#include "Field.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + labelVector test(1,-1,-1); + + autoPtr<multiDimPolyFunctions> polyFunc + = multiDimPolyFunctions::New("polyDegree1", test); + + vector vec(1,2,3); + + Info<< "polyFunc" << nl + << " nTerms " << polyFunc->nTerms() << nl + << " coeffs " << polyFunc->coeffs() << nl + << " termValues " << polyFunc->termValues(vec) << nl; + + multiDimPolyFitter<scalar> polyFitter("polyDegree1",test); + + List<vector> pos + ({ + {0,0,0}, + {1,0,0}, + {-1,0,0} + }); + + List<scalar> values + ({ + 1, 2, 0 + }); + + Info<< "pos " << pos << nl + << "values " << values << nl; + + scalarField fitData = polyFitter.fitData(pos, values); + + Info<< "fitData " << fitData << nl; + + autoPtr<multiDimPolyFunctions> polyFuncDeg2 + = multiDimPolyFunctions::New("polyDegree2", labelVector(1,1,-1)); + + //vector vec(1,2,3); + + Info<< "polyFunc" << nl + << " nTerms" << polyFuncDeg2->nTerms() << nl + // << " coeffs " << polyFunc->coeffs() << nl + << " termValues " << polyFuncDeg2->termValues(vector(1,1,0)) << nl; + + List<vector> pos2 + ({ + {0,0,0}, + {1,0,0}, + {-1,0,0}, + {0,1,0}, + {0,-1,0}, + {1,1,0} + }); + + List<scalar> values2 + ({ + 0, 1, 1, 1, 1, 2 + }); + + multiDimPolyFitter<scalar> polyFitter2 + { + "polyDegree2", labelVector(1,1,-1) + }; + + scalarField fitData2 = polyFitter2.fitData(pos2, values2); + + Info<< "fitData " << fitData2 << nl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/Make/files b/applications/test/reconstructedDistanceFunction/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..5ebed6989897e2d321e32ebaf6164571d41d56c3 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/Make/files @@ -0,0 +1,3 @@ +Test-reconstructedDistanceFunction.C + +EXE = $(FOAM_USER_APPBIN)/Test-reconstructedDistanceFunction diff --git a/applications/test/reconstructedDistanceFunction/Make/options b/applications/test/reconstructedDistanceFunction/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..c2d01bb839c31916921da3f0af09d140daf1aa42 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/Make/options @@ -0,0 +1,11 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -lsampling \ + -lgeometricVoF diff --git a/applications/test/reconstructedDistanceFunction/Test-reconstructedDistanceFunction.C b/applications/test/reconstructedDistanceFunction/Test-reconstructedDistanceFunction.C new file mode 100755 index 0000000000000000000000000000000000000000..612419f6fd56842f1ca2291b63f5456730a40526 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/Test-reconstructedDistanceFunction.C @@ -0,0 +1,139 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + +Description + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "reconstructionSchemes.H" +#include "reconstructedDistanceFunction.H" +#include "Field.H" +#include "DynamicField.H" +#include "zoneDistribute.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + #include "setRootCase.H" + #include "createTime.H" + #include "createMesh.H" + + Info<< "Reading field alpha1\n" << endl; + + volScalarField alpha1 + ( + IOobject + ( + "alpha1", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ); + + Info<< "Reading field U\n" << endl; + volVectorField U + ( + IOobject + ( + "U", + runTime.timeName(), + mesh, + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ); + + Info<< "create field phi\n" << endl; + surfaceScalarField phi = fvc::interpolate(U) & mesh.Sf(); + + dictionary dict = mesh.solverDict(alpha1.name()); + + autoPtr<reconstructionSchemes> surf = + reconstructionSchemes::New(alpha1,phi,U,dict); + + ++runTime; + + const volVectorField& centre = surf->centre(); + const volVectorField& normal = surf->normal(); + + + //pointField centres(0); + //vectorField normals(0); + DynamicField<point> centres(1000); + DynamicField<vector> normals(1000); + + surf->reconstruct(); + + zoneDistribute exchangeFields_(mesh); + + exchangeFields_.setUpCommforZone(surf->interfaceCell()); + + Map<Field<vector>> mapCentres = + exchangeFields_.getFields(surf->interfaceCell(),centre); + + Map<Field<vector>> mapNormal = + exchangeFields_.getFields(surf->interfaceCell(),normal); + + forAll(surf->centre(),celli) + { + if (surf->interfaceCell()[celli]) + { + centres.append(surf->centre()[celli]); + normals.append(surf->normal()[celli]); + } + } + + reconstructedDistanceFunction distFunc(mesh); + + { + runTime.cpuTimeIncrement(); + + Info<< "Time " << runTime.cpuTimeIncrement() << endl; + + distFunc.constructRDF + ( + surf->interfaceCell(), + surf->centre(), + surf->normal(), + 2, + exchangeFields_ + ); + } + + runTime.write(); + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/0.orig/U b/applications/test/reconstructedDistanceFunction/case1/0.orig/U new file mode 100644 index 0000000000000000000000000000000000000000..e4f09a7872265013c05bfc12b6098bca919d0691 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/0.orig/U @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + walls + { + type zeroGradient; + } + front + { + type empty; + } + back + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/0.orig/alpha1 b/applications/test/reconstructedDistanceFunction/case1/0.orig/alpha1 new file mode 100644 index 0000000000000000000000000000000000000000..f0e458d11403adb3b6496f7c6d4deb87247afd3e --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/0.orig/alpha1 @@ -0,0 +1,39 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object alpha1; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + walls + { + type zeroGradient; + } + front + { + type empty; + } + back + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/0.orig/markedCells b/applications/test/reconstructedDistanceFunction/case1/0.orig/markedCells new file mode 100644 index 0000000000000000000000000000000000000000..853cae3a1610f9d3a3d211c1ca92669dd0c439e8 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/0.orig/markedCells @@ -0,0 +1,40 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object markedCells; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + walls + { + type calculated; + value uniform 0; + } + front + { + type empty; + } + back + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/Allclean b/applications/test/reconstructedDistanceFunction/case1/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..a3bdf96f3e768b7c7bacfecd4f367573ff368e62 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/Allclean @@ -0,0 +1,9 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase0 +rm -rf AlphaInit/ + +#------------------------------------------------------------------------------ diff --git a/applications/test/reconstructedDistanceFunction/case1/Allrun b/applications/test/reconstructedDistanceFunction/case1/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..404ed9ae3170bdd3ad794cba2d0aec4b1e7c1c37 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/Allrun @@ -0,0 +1,13 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +restore0Dir +touch Test-reconDistFunc.foam + +runApplication blockMesh +runApplication setAlphaField +runApplication Test-reconstructedDistanceFunction + +#------------------------------------------------------------------------------ diff --git a/applications/test/reconstructedDistanceFunction/case1/constant/g b/applications/test/reconstructedDistanceFunction/case1/constant/g new file mode 100644 index 0000000000000000000000000000000000000000..9dc396fe907e3e59d01707c76ff74e0c938664f1 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/constant/g @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; +value ( 0 -9.81 0 ); + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/constant/transportProperties b/applications/test/reconstructedDistanceFunction/case1/constant/transportProperties new file mode 100644 index 0000000000000000000000000000000000000000..3793e29ae781039ab302ca1bbb212b2f0bd13680 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/constant/transportProperties @@ -0,0 +1,64 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object transportProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +DT [ 0 2 -1 0 0 0 0 ] 0; + +sigma [ 1 0 -2 0 0 0 0 ] 0; + +phase1 +{ + transportModel Newtonian; + nu [ 0 2 -1 0 0 0 0 ] 0; + rho [ 1 -3 0 0 0 0 0 ] 1000; + BirdCarreauCoeffs + { + nu0 [ 0 2 -1 0 0 0 0 ] 0.0142515; + nuInf [ 0 2 -1 0 0 0 0 ] 1e-06; + k [ 0 0 1 0 0 0 0 ] 99.6; + n [ 0 0 0 0 0 0 0 ] 0.1003; + } + CrossPowerLawCoeffs + { + nu0 [ 0 2 -1 0 0 0 0 ] 1e-06; + nuInf [ 0 2 -1 0 0 0 0 ] 1e-06; + m [ 0 0 1 0 0 0 0 ] 1; + n [ 0 0 0 0 0 0 0 ] 0; + } +} + +phase2 +{ + transportModel Newtonian; + nu [ 0 2 -1 0 0 0 0 ] 0; + rho [ 1 -3 0 0 0 0 0 ] 1; + BirdCarreauCoeffs + { + nu0 [ 0 2 -1 0 0 0 0 ] 0.0142515; + nuInf [ 0 2 -1 0 0 0 0 ] 1e-06; + k [ 0 0 1 0 0 0 0 ] 99.6; + n [ 0 0 0 0 0 0 0 ] 0.1003; + } + CrossPowerLawCoeffs + { + nu0 [ 0 2 -1 0 0 0 0 ] 1e-06; + nuInf [ 0 2 -1 0 0 0 0 ] 1e-06; + m [ 0 0 1 0 0 0 0 ] 1; + n [ 0 0 0 0 0 0 0 ] 0; + } +} + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/constant/turbulenceProperties b/applications/test/reconstructedDistanceFunction/case1/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..7fcefa3b6020ad30b27b2ce2ffdbc88bcf8a80cd --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/constant/turbulenceProperties @@ -0,0 +1,20 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/blockMeshDict b/applications/test/reconstructedDistanceFunction/case1/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..01380af7b406e57716d9f2dbd3d43aeed7f902b0 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/blockMeshDict @@ -0,0 +1,89 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 1; + +L 1; +n 3; + +y1 0; +y2 1; + +H 0.1; + + +vertices +( + (0 $y1 0) + ($L $y1 0) + ($L $y2 0) + (0 $y2 0) + (0 $y1 $H) + ($L $y1 $H) + ($L $y2 $H) + (0 $y2 $H) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (100 100 1) simpleGrading (1 1 1) +); + +edges +( +); + +boundary +( + walls + { + type patch; + faces + ( + (4 5 6 7) + (0 4 7 3) + (1 2 6 5) + (0 3 2 1) + // (2 3 7 6) + // (0 1 5 4) + ); + } + + front + { + type empty; + faces + ( + (2 3 7 6) + ); + } + + back + { + type empty; + faces + ( + (0 1 5 4) + ); + } + +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/changeDictionaryDict b/applications/test/reconstructedDistanceFunction/case1/system/changeDictionaryDict new file mode 100644 index 0000000000000000000000000000000000000000..4d3e9219fbe5e49f8a4457681dc5f8d6c652f842 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/changeDictionaryDict @@ -0,0 +1,30 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object changeDictionaryDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +boundary +{ + front + { + type empty; + } + + back + { + type empty; + } +} + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/controlDict b/applications/test/reconstructedDistanceFunction/case1/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..be6485fa83170d9662fd97f5727a696ab0eb5250 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/controlDict @@ -0,0 +1,59 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application Test-reconstructedDistanceFunction; + +startFrom startTime; + +startTime 0.0; + +stopAt writeNow; + +endTime 4; + +writeControl adjustableRunTime; + +writeInterval 0.1; + +deltaT 1e-3; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 14; + +writeCompression no; + +timeFormat general; + +timePrecision 14; + +graphFormat raw; + +runTimeModifiable no; + +adjustTimeStep yes; + +maxCo 1e6; + +maxAlphaCo 0.5; + +maxDeltaT 1e6; + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/decomposeParDict b/applications/test/reconstructedDistanceFunction/case1/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..143cc870cb8505bff903e33c686bbd6fd8e4f1c2 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/decomposeParDict @@ -0,0 +1,27 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 4; + +method simple; + +coeffs +{ + n (2 2 1); +} + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/fvSchemes b/applications/test/reconstructedDistanceFunction/case1/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..a84a63acf7e81bc8d903a6b09c60eee2cc185e60 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/fvSchemes @@ -0,0 +1,62 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + //default Gauss linear; + default pointCellsLeastSquares; +} + +divSchemes +{ + div(rho*phi,U) Gauss limitedLinearV 1; + div(phi,alpha) Gauss vanLeer; + div(phi,alpha1) Gauss HRIC; + div(phirb,alpha) Gauss interfaceCompression; + div((muEff*dev(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + +fluxRequired +{ + default no; + p_rgh; + pcorr; + alpha1; +} + + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/fvSolution b/applications/test/reconstructedDistanceFunction/case1/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..869c25da627a2791f961755be0d2f09a8b8b7423 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/fvSolution @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + alpha1 + { + + reconstructionScheme isoAlpha; + vof2IsoTol 1e-8; + surfCellTol 1e-8; + writeVTK false; + } +} + + +PIMPLE +{ + momentumPredictor no; + nCorrectors -1; + nNonOrthogonalCorrectors -1; + nAlphaCorr 1; + nAlphaSubCycles 1; + cAlpha 1; + pRefCell 0; + pRefValue 0; +} + +SIMPLE +{ + nNonOrthogonalCorrectors 0; +} + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/isoSurfDict b/applications/test/reconstructedDistanceFunction/case1/system/isoSurfDict new file mode 100644 index 0000000000000000000000000000000000000000..a7a3c3634ba97d2c99fc81010f3c7971c9e102f9 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/isoSurfDict @@ -0,0 +1,23 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +field "alpha1"; +type sphere; +centre (0.51 0.51 0.51); +radius 0.25; + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/setAlphaFieldDict b/applications/test/reconstructedDistanceFunction/case1/system/setAlphaFieldDict new file mode 100644 index 0000000000000000000000000000000000000000..df664627655d3ef3472515413388b953af78cc1e --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/setAlphaFieldDict @@ -0,0 +1,23 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +field "alpha1"; +type plane; +origin (0.485 0.0 0.0); +normal (-1 0 0); + +// ************************************************************************* // diff --git a/applications/test/reconstructedDistanceFunction/case1/system/topoSetDict b/applications/test/reconstructedDistanceFunction/case1/system/topoSetDict new file mode 100644 index 0000000000000000000000000000000000000000..2c27834951037f58bd56cd17dc2208999f51de59 --- /dev/null +++ b/applications/test/reconstructedDistanceFunction/case1/system/topoSetDict @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object topoSetDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +actions +( + { + name c0; + type cellSet; + action new; + source boxToCell; + box (-1e10 -1e10 -1e10) (1e10 0 1e10); + } + + { + name c0; + type cellSet; + action invert; + } +); + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/0.orig/T b/applications/test/setAlphaField/case1/0.orig/T new file mode 100644 index 0000000000000000000000000000000000000000..21b16adb6a273c08f5358893fcf39591dd9a2f21 --- /dev/null +++ b/applications/test/setAlphaField/case1/0.orig/T @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + walls + { + type zeroGradient; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/0.orig/U b/applications/test/setAlphaField/case1/0.orig/U new file mode 100644 index 0000000000000000000000000000000000000000..00c303e2562e3c3237bfbd1ec92d462d00037d9f --- /dev/null +++ b/applications/test/setAlphaField/case1/0.orig/U @@ -0,0 +1,33 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + walls + { + type noSlip; + } + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/0.orig/alpha.water b/applications/test/setAlphaField/case1/0.orig/alpha.water new file mode 100644 index 0000000000000000000000000000000000000000..fa7e6861d029e4d41f0ecac1ce9c17965d9084ca --- /dev/null +++ b/applications/test/setAlphaField/case1/0.orig/alpha.water @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object alpha.water; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + walls + { + type zeroGradient; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/0.orig/p b/applications/test/setAlphaField/case1/0.orig/p new file mode 100644 index 0000000000000000000000000000000000000000..a7ee2ed31c529e5aed5aac42a37ce89dbf219f08 --- /dev/null +++ b/applications/test/setAlphaField/case1/0.orig/p @@ -0,0 +1,35 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + walls + { + type calculated; + value uniform 1e5; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/0.orig/p_rgh b/applications/test/setAlphaField/case1/0.orig/p_rgh new file mode 100644 index 0000000000000000000000000000000000000000..c7db9671d503f9abd5bf8efddca9d8d1926f9a1d --- /dev/null +++ b/applications/test/setAlphaField/case1/0.orig/p_rgh @@ -0,0 +1,35 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p_rgh; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + walls + { + type fixedFluxPressure; + value uniform 1e5; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/Allclean b/applications/test/setAlphaField/case1/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..9ba118456fe15932258ba950129513d3c53332ff --- /dev/null +++ b/applications/test/setAlphaField/case1/Allclean @@ -0,0 +1,10 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase0 +rm -rf processor* +rm -r AlphaInit/ + +#------------------------------------------------------------------------------ diff --git a/applications/test/setAlphaField/case1/Allrun b/applications/test/setAlphaField/case1/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..4e37f5339841278319ab27af2296b7b052105786 --- /dev/null +++ b/applications/test/setAlphaField/case1/Allrun @@ -0,0 +1,15 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +runApplication blockMesh +#runApplication refineMesh -overwrite +touch test-initAlphaField.foam +restore0Dir +runApplication setAlphaField +#runApplication decomposePar +#runParallel $(getApplication) +#runApplication reconstructPar + +#------------------------------------------------------------------------------ diff --git a/applications/test/setAlphaField/case1/constant/g b/applications/test/setAlphaField/case1/constant/g new file mode 100644 index 0000000000000000000000000000000000000000..e986fa078f05d07a6b5d1e847320c9124df73806 --- /dev/null +++ b/applications/test/setAlphaField/case1/constant/g @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; +value (0 -9.81 0); + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/constant/thermophysicalProperties b/applications/test/setAlphaField/case1/constant/thermophysicalProperties new file mode 100644 index 0000000000000000000000000000000000000000..97199ca415d59d3326cd274950f23aead4eb3f8b --- /dev/null +++ b/applications/test/setAlphaField/case1/constant/thermophysicalProperties @@ -0,0 +1,24 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +phases (water air); + +pMin 10000; + +sigma 0.07; + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/constant/thermophysicalProperties.air b/applications/test/setAlphaField/case1/constant/thermophysicalProperties.air new file mode 100644 index 0000000000000000000000000000000000000000..5c77a504431c915a7a4e441b5a9a1dcbcde4da2c --- /dev/null +++ b/applications/test/setAlphaField/case1/constant/thermophysicalProperties.air @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState perfectGas; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 28.9; + } + thermodynamics + { + Cp 1007; + Hf 0; + } + transport + { + mu 1.84e-05; + Pr 0.7; + } +} + + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/constant/thermophysicalProperties.water b/applications/test/setAlphaField/case1/constant/thermophysicalProperties.water new file mode 100644 index 0000000000000000000000000000000000000000..175e31bdf955911abef2b2ed520c1fe66b634412 --- /dev/null +++ b/applications/test/setAlphaField/case1/constant/thermophysicalProperties.water @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState perfectFluid; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 18.0; + } + equationOfState + { + R 3000; + rho0 1027; + } + thermodynamics + { + Cp 4195; + Hf 0; + } + transport + { + mu 3.645e-4; + Pr 2.289; + } +} + + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/constant/turbulenceProperties b/applications/test/setAlphaField/case1/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..fbd1e3c277c13766d96341f6214f8c833ed4b691 --- /dev/null +++ b/applications/test/setAlphaField/case1/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/system/blockMeshDict b/applications/test/setAlphaField/case1/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..7b2d728f7092d3cc65525bccdc92b66314908a58 --- /dev/null +++ b/applications/test/setAlphaField/case1/system/blockMeshDict @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 1; + +vertices +( + (0 0 0) + (1 0 0) + (1 2 0) + (0 2 0) + (0 0 1) + (1 0 1) + (1 2 1) + (0 2 1) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (20 40 20) simpleGrading (1 1 1) +); + +boundary +( + walls + { + type wall; + faces + ( + (3 7 6 2) + (0 4 7 3) + (2 6 5 1) + (1 5 4 0) + (0 3 2 1) + (4 5 6 7) + ); + } +); + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/system/controlDict b/applications/test/setAlphaField/case1/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..0e4d411571e1313fede92404ee783a494bde1cc0 --- /dev/null +++ b/applications/test/setAlphaField/case1/system/controlDict @@ -0,0 +1,55 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application setAlphaField; + +startFrom latestTime; + +startTime 0; + +stopAt endTime; + +endTime 0.1; + +deltaT 0.0001; + +writeControl adjustableRunTime; + +writeInterval 0.01; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 8; + +writeCompression off; + +timeFormat general; + +timePrecision 10; + +runTimeModifiable yes; + +adjustTimeStep yes; + +maxCo 0.5; +maxAlphaCo 0.5; +maxDeltaT 1; + + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/system/decomposeParDict b/applications/test/setAlphaField/case1/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..c2de1601afe27da4bf126daedf9a5fbca93d893d --- /dev/null +++ b/applications/test/setAlphaField/case1/system/decomposeParDict @@ -0,0 +1,33 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 64; + +method scotch; + +coeffs +{ + n (1 4 1); + //delta 0.001; // default=0.001 + //order xyz; // default=xzy +} + +distributed no; + +roots ( ); + + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/system/fvSchemes b/applications/test/setAlphaField/case1/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..c65082c8d9fe57e8bf1f8afad1d51efa0d3dad74 --- /dev/null +++ b/applications/test/setAlphaField/case1/system/fvSchemes @@ -0,0 +1,57 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; +} + +divSchemes +{ + div(phi,alpha) Gauss vanLeer; + div(phirb,alpha) Gauss linear; + + div(rhoPhi,U) Gauss upwind; + div(rhoPhi,T) Gauss upwind; + div(rhoPhi,K) Gauss upwind; + div(phi,p) Gauss upwind; + div(phi,k) Gauss upwind; + + div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear uncorrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default uncorrected; +} + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/system/fvSolution b/applications/test/setAlphaField/case1/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..d366acd51493efe784b5b604b047afa1c6d05190 --- /dev/null +++ b/applications/test/setAlphaField/case1/system/fvSolution @@ -0,0 +1,108 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + "alpha.water.*" + { + nAlphaCorr 1; + nAlphaSubCycles 2; + cAlpha 1; + + MULESCorr no; + nLimiterIter 5; + + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-8; + relTol 0; + } + + "pcorr.*" + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-05; + relTol 0; + smoother DICGaussSeidel; + } + tolerance 1e-05; + relTol 0; + maxIter 100; + } + + ".*(rho|rhoFinal)" + { + solver diagonal; + } + + p_rgh + { + solver GAMG; + tolerance 1e-07; + relTol 0.01; + smoother DIC; + } + + p_rghFinal + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-07; + relTol 0; + nVcycles 2; + smoother DICGaussSeidel; + nPreSweeps 2; + } + tolerance 1e-07; + relTol 0; + maxIter 20; + } + + U + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-06; + relTol 0; + nSweeps 1; + } + + "(T|k|B|nuTilda).*" + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-08; + relTol 0; + } +} + +PIMPLE +{ + momentumPredictor no; + transonic no; + nOuterCorrectors 1; + nCorrectors 2; + nNonOrthogonalCorrectors 0; +} + + +// ************************************************************************* // diff --git a/applications/test/setAlphaField/case1/system/setAlphaFieldDict b/applications/test/setAlphaField/case1/system/setAlphaFieldDict new file mode 100644 index 0000000000000000000000000000000000000000..28481221e2068a44ff407fb7270dcf6a3d97e700 --- /dev/null +++ b/applications/test/setAlphaField/case1/system/setAlphaFieldDict @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +field "alpha.water"; + +type composedFunction; +mode minDist; +composedFunctions +{ + plane + { + type plane; + origin (0 1. 0); + normal (0 -1 0); + } + + sphere + { + type sphere; + radius 0.4; + origin (0.5 1.5 0.5); + scale 1; + } + + sphere2 + { + type sphere; + radius 0.4; + origin (0.5 0.5 0.5); + scale -1; + } +} + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/Make/files b/applications/test/zoneDistribute/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..6eb2483e218587e9a72ab8fbd3b5ec08e71a9586 --- /dev/null +++ b/applications/test/zoneDistribute/Make/files @@ -0,0 +1,3 @@ +Test-zoneDistribute.C + +EXE = $(FOAM_USER_APPBIN)/Test-zoneDistribute diff --git a/applications/test/zoneDistribute/Make/options b/applications/test/zoneDistribute/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..5413c0b3bac8c3ab3b299ab1bf06518bb7e2fa41 --- /dev/null +++ b/applications/test/zoneDistribute/Make/options @@ -0,0 +1,13 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lfileFormats \ + -lsurfMesh \ + -lmeshTools \ + -lsampling diff --git a/applications/test/zoneDistribute/Test-zoneDistribute.C b/applications/test/zoneDistribute/Test-zoneDistribute.C new file mode 100644 index 0000000000000000000000000000000000000000..00505735b6356f606804d241a05d7dc8fc5b2abb --- /dev/null +++ b/applications/test/zoneDistribute/Test-zoneDistribute.C @@ -0,0 +1,121 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Application + Test-zoneDistribute + +Description + Test of zoneDistribute validated with mapDistribute + + Original code supplied by Henning Scheufler, DLR (2019) + +\*---------------------------------------------------------------------------*/ + +#include "fvCFD.H" +#include "centredCPCCellToCellStencilObject.H" +#include "zoneDistribute.H" + +#include "SortableList.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + #include "setRootCase.H" + #include "createTime.H" + #include "createMesh.H" + + const extendedCentredCellToCellStencil& stencil = + centredCPCCellToCellStencilObject::New(mesh); + + const List<List<label>>& stencilAddr = stencil.stencil(); + + List<List<vector>> stencilCentre(mesh.nCells()); + + stencil.collectData + ( + mesh.C(), + stencilCentre + ); + + zoneDistribute exchangeFields(mesh); + + + boolList interfaceCell(mesh.nCells(),true); + exchangeFields.setUpCommforZone(interfaceCell); + + + const labelListList& stencil_zoneDist = exchangeFields.getStencil(); + const globalIndex& gblNumbering = exchangeFields.globalNumbering(); + + Map<vectorField> mapCC(exchangeFields.getFields(interfaceCell,mesh.C())); + + // compare stencils + Pout<< "size of the stencil match " + << (stencilAddr.size() == stencil_zoneDist.size()) << endl; + + label stencilMatch = 0; + + forAll(stencilAddr,celli) + { + const vectorField& neiCC = mapCC[celli]; + if (neiCC.size() != stencilCentre[celli].size()) + { + continue; + } + + bool foundAllLabel = true; + for (const vector& cc : neiCC) + { + if (!stencilCentre[celli].found(cc)) + { + foundAllLabel = false; + break; + } + } + + if (foundAllLabel) + { + ++stencilMatch; + } + + } + + if (stencilMatch == mesh.nCells()) + { + Pout << "all Values are identical " << endl; + } + else + { + Pout << "values did not match in : " << stencilMatch << " of " + << mesh.nCells() << " cases" << endl; + } + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/Allclean b/applications/test/zoneDistribute/case1/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..36d26d8799bdd6993df3b51e33e675d5c4f90a66 --- /dev/null +++ b/applications/test/zoneDistribute/case1/Allclean @@ -0,0 +1,15 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase0 + +rm -f ./flange ./*.obj + +# Remove surface and features +rm -f constant/triSurface/flange.stl.gz +rm -f constant/triSurface/flange.eMesh +rm -rf constant/extendedFeatureEdgeMesh + +#------------------------------------------------------------------------------ diff --git a/applications/test/zoneDistribute/case1/Allrun b/applications/test/zoneDistribute/case1/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..444a182a12a99c0d571e7a94d401c3158a647a31 --- /dev/null +++ b/applications/test/zoneDistribute/case1/Allrun @@ -0,0 +1,13 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +touch test-zoneDistribute.foam +runApplication blockMesh +#runApplication surfaceFeatureExtract +runApplication snappyHexMesh -overwrite +runApplication decomposePar +runParallel test-zoneDistribute + +#------------------------------------------------------------------------------ diff --git a/applications/test/zoneDistribute/case1/constant/triSurface/README b/applications/test/zoneDistribute/case1/constant/triSurface/README new file mode 100644 index 0000000000000000000000000000000000000000..de3f29cc01268a637d915dc6d9b8fb98400e9906 --- /dev/null +++ b/applications/test/zoneDistribute/case1/constant/triSurface/README @@ -0,0 +1,4 @@ +Directory to house tri-surfaces + +The Allrun script copies the surface from the $FOAM_TUTORIALS/resources/geometry +directory diff --git a/applications/test/zoneDistribute/case1/system/blockMeshDict b/applications/test/zoneDistribute/case1/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..749b1e36299665adc384df9f0b278a267ff10ef3 --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/blockMeshDict @@ -0,0 +1,57 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 1; + +vertices +( + ( -1 -1 -1) + ( 1 -1 -1) + ( 1 1 -1) + ( -1 1 -1) + ( -1 -1 1) + ( 1 -1 1) + ( 1 1 1) + ( -1 1 1) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (10 10 10) simpleGrading (1 1 1) +); + +edges +( +); + +boundary +( + allBoundary + { + type patch; + faces + ( + (3 7 6 2) + (0 4 7 3) + (2 6 5 1) + (1 5 4 0) + (0 3 2 1) + (4 5 6 7) + ); + } +); + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/system/controlDict b/applications/test/zoneDistribute/case1/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..ff0a7ebf7ae14f7e172177b2fbf4effd59eda844 --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/controlDict @@ -0,0 +1,49 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application snappyHexMesh; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 50; + +deltaT 1; + +writeControl timeStep; + +writeInterval 20; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression off; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable yes; + + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/system/decomposeParDict b/applications/test/zoneDistribute/case1/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..bc2087dad0c4527f6f6a4790938e49a6cd788632 --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/decomposeParDict @@ -0,0 +1,27 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 8; + +method simple; + +coeffs +{ + n (4 2 1); +} + + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/system/fvSchemes b/applications/test/zoneDistribute/case1/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..34da6be2ea1b3c4c2e26a44290eb1b35a6ad2b83 --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/fvSchemes @@ -0,0 +1,30 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +gradSchemes +{ +} + +divSchemes +{ +} + +laplacianSchemes +{ +} + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/system/fvSolution b/applications/test/zoneDistribute/case1/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..97b46fe07e433f49b5665f44377aac1a9d7ebf51 --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/fvSolution @@ -0,0 +1,18 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/system/meshQualityDict b/applications/test/zoneDistribute/case1/system/meshQualityDict new file mode 100644 index 0000000000000000000000000000000000000000..c91a7d24784bad61468ca922133db475fa207c9d --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/meshQualityDict @@ -0,0 +1,22 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object meshQualityDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Include defaults parameters from master dictionary +#includeEtc "caseDicts/meshQualityDict" + + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/system/snappyHexMeshDict b/applications/test/zoneDistribute/case1/system/snappyHexMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..033d15ed48faf632ad547a4eb40e4b8e4e8556a9 --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/snappyHexMeshDict @@ -0,0 +1,310 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object snappyHexMeshDict; +} + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Which of the steps to run +castellatedMesh true; +snap true; +addLayers false; + + +// Geometry. Definition of all surfaces. All surfaces are of class +// searchableSurface. +// Surfaces are used +// - to specify refinement for any mesh cell intersecting it +// - to specify refinement for any mesh cell inside/outside/near +// - to 'snap' the mesh boundary to the surface +geometry +{ + + //- Refine a bit extra around the small centre hole + sphere + { + type sphere; + origin (0 0 -0.00); + radius 0.99; + } +} + + +// Settings for the castellatedMesh generation. +castellatedMeshControls +{ + + // Refinement parameters + // ~~~~~~~~~~~~~~~~~~~~~ + + // If local number of cells is >= maxLocalCells on any processor + // switches from from refinement followed by balancing + // (current method) to (weighted) balancing before refinement. + maxLocalCells 100000; + + // Overall cell limit (approximately). Refinement will stop immediately + // upon reaching this number so a refinement level might not complete. + // Note that this is the number of cells before removing the part which + // is not 'visible' from the keepPoint. The final number of cells might + // actually be a lot less. + maxGlobalCells 2000000; + + // The surface refinement loop might spend lots of iterations refining just a + // few cells. This setting will cause refinement to stop if <= minimumRefine + // are selected for refinement. Note: it will at least do one iteration + // (unless the number of cells to refine is 0) + minRefinementCells 0; + + // Number of buffer layers between different levels. + // 1 means normal 2:1 refinement restriction, larger means slower + // refinement. + nCellsBetweenLevels 1; + + + + // Explicit feature edge refinement + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Specifies a level for any cell intersected by its edges. + // This is a featureEdgeMesh, read from constant/triSurface for now. + features + ( + + ); + + + + // Surface based refinement + // ~~~~~~~~~~~~~~~~~~~~~~~~ + + // Specifies two levels for every surface. The first is the minimum level, + // every cell intersecting a surface gets refined up to the minimum level. + // The second level is the maximum level. Cells that 'see' multiple + // intersections where the intersections make an + // angle > resolveFeatureAngle get refined up to the maximum level. + + refinementSurfaces + { + sphere + { + // Surface-wise min and max refinement level + level (2 2); + } + } + + resolveFeatureAngle 30; + + + // Region-wise refinement + // ~~~~~~~~~~~~~~~~~~~~~~ + + // Specifies refinement level for cells in relation to a surface. One of + // three modes + // - distance. 'levels' specifies per distance to the surface the + // wanted refinement level. The distances need to be specified in + // descending order. + // - inside. 'levels' is only one entry and only the level is used. All + // cells inside the surface get refined up to the level. The surface + // needs to be closed for this to be possible. + // - outside. Same but cells outside. + + refinementRegions + { + // refineHole + // { + // mode inside; + // levels ((1E15 3)); + // } + } + + + // Mesh selection + // ~~~~~~~~~~~~~~ + + // After refinement patches get added for all refinementSurfaces and + // all cells intersecting the surfaces get put into these patches. The + // section reachable from the locationInMesh is kept. + // NOTE: This point should never be on a face, always inside a cell, even + // after refinement. + // This is an outside point locationInMesh (-0.033 -0.033 0.0033); + locationInMesh (0 0 0); // Inside point + + // Whether any faceZones (as specified in the refinementSurfaces) + // are only on the boundary of corresponding cellZones or also allow + // free-standing zone faces. Not used if there are no faceZones. + allowFreeStandingZoneFaces true; +} + + + +// Settings for the snapping. +snapControls +{ + //- Number of patch smoothing iterations before finding correspondence + // to surface + nSmoothPatch 3; + + //- Relative distance for points to be attracted by surface feature point + // or edge. True distance is this factor times local + // maximum edge length. + tolerance 1.0; + + //- Number of mesh displacement relaxation iterations. + nSolveIter 300; + + //- Maximum number of snapping relaxation iterations. Should stop + // before upon reaching a correct mesh. + nRelaxIter 5; + + // Feature snapping + + //- Number of feature edge snapping iterations. + // Leave out altogether to disable. + nFeatureSnapIter 10; + + //- Detect (geometric) features by sampling the surface + implicitFeatureSnap false; + + //- Use castellatedMeshControls::features + explicitFeatureSnap true; + + //- Detect features between multiple surfaces + // (only for explicitFeatureSnap, default = false) + multiRegionFeatureSnap true; +} + + + +// Settings for the layer addition. +addLayersControls +{ + // Are the thickness parameters below relative to the undistorted + // size of the refined cell outside layer (true) or absolute sizes (false). + relativeSizes true; + + // Per final patch (so not geometry!) the layer information + layers + { + "flange_.*" + { + nSurfaceLayers 1; + } + } + + // Expansion factor for layer mesh + expansionRatio 1.0; + + + // Wanted thickness of final added cell layer. If multiple layers + // is the thickness of the layer furthest away from the wall. + // Relative to undistorted size of cell outside layer. + // See relativeSizes parameter. + finalLayerThickness 0.3; + + // Minimum thickness of cell layer. If for any reason layer + // cannot be above minThickness do not add layer. + // See relativeSizes parameter. + minThickness 0.25; + + // If points get not extruded do nGrow layers of connected faces that are + // also not grown. This helps convergence of the layer addition process + // close to features. + nGrow 0; + + + // Advanced settings + + // When not to extrude surface. 0 is flat surface, 90 is when two faces + // are perpendicular + featureAngle 30; + + // Maximum number of snapping relaxation iterations. Should stop + // before upon reaching a correct mesh. + nRelaxIter 5; + + // Number of smoothing iterations of surface normals + nSmoothSurfaceNormals 1; + + // Number of smoothing iterations of interior mesh movement direction + nSmoothNormals 3; + + // Smooth layer thickness over surface patches + nSmoothThickness 10; + + // Stop layer growth on highly warped cells + maxFaceThicknessRatio 0.5; + + // Reduce layer growth where ratio thickness to medial + // distance is large + maxThicknessToMedialRatio 0.3; + + // Angle used to pick up medial axis points + minMedialAxisAngle 90; + + // Create buffer region for new layer terminations + nBufferCellsNoExtrude 0; + + + // Overall max number of layer addition iterations. The mesher will exit + // if it reaches this number of iterations; possibly with an illegal + // mesh. + nLayerIter 50; + + // Max number of iterations after which relaxed meshQuality controls + // get used. Up to nRelaxIter it uses the settings in meshQualityControls, + // after nRelaxIter it uses the values in meshQualityControls::relaxed. + nRelaxedIter 20; +} + + + +// Generic mesh quality settings. At any undoable phase these determine +// where to undo. +meshQualityControls +{ + #include "meshQualityDict" + + // Optional : some meshing phases allow usage of relaxed rules. + // See e.g. addLayersControls::nRelaxedIter. + relaxed + { + //- Maximum non-orthogonality allowed. Set to 180 to disable. + maxNonOrtho 75; + } + + // Advanced + + //- Number of error distribution iterations + nSmoothScale 4; + //- Amount to scale back displacement at error points + errorReduction 0.75; +} + + +// Advanced + +// Write flags +writeFlags +( + scalarLevels // write volScalarField with cellLevel for postprocessing + layerSets // write cellSets, faceSets of faces in layer + layerFields // write volScalarField for layer coverage +); + + +// Merge tolerance. Is fraction of overall bounding box of initial mesh. +// Note: the write tolerance needs to be higher than this. +mergeTolerance 1E-6; + + +// ************************************************************************* // diff --git a/applications/test/zoneDistribute/case1/system/surfaceFeatureExtractDict b/applications/test/zoneDistribute/case1/system/surfaceFeatureExtractDict new file mode 100644 index 0000000000000000000000000000000000000000..e074b996d4e9e25fa49b13261f0a2e44660bb4c7 --- /dev/null +++ b/applications/test/zoneDistribute/case1/system/surfaceFeatureExtractDict @@ -0,0 +1,35 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object surfaceFeatureExtractDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +flange.stl +{ + // How to obtain raw features (extractFromFile || extractFromSurface) + extractionMethod extractFromSurface; + + // Mark edges whose adjacent surface normals are at an angle less + // than includedAngle as features + // - 0 : selects no edges + // - 180: selects all edges + includedAngle 150; + + // Write options + + // Write features to obj format for postprocessing + writeObj yes; +} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/Allwclean b/applications/utilities/preProcessing/setAlphaField/Allwclean new file mode 100755 index 0000000000000000000000000000000000000000..bb9e648f9d96a5770ee45b02833053cccff110d5 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/Allwclean @@ -0,0 +1,7 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory + +wclean libso alphaFieldFunctions +wclean + +#------------------------------------------------------------------------------ diff --git a/applications/utilities/preProcessing/setAlphaField/Allwmake b/applications/utilities/preProcessing/setAlphaField/Allwmake new file mode 100755 index 0000000000000000000000000000000000000000..7c7aa843d103d4d8cde33e401c82c2f6032924dd --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/Allwmake @@ -0,0 +1,10 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments + +#------------------------------------------------------------------------------ + +wmake $targetType alphaFieldFunctions +wmake $targetType + +#------------------------------------------------------------------------------ diff --git a/applications/utilities/preProcessing/setAlphaField/Make/options b/applications/utilities/preProcessing/setAlphaField/Make/options index b4ad3d8bdff2f2475467775f28a6c62effa80575..8f9558bba0fda95af9b546f74b2eb42c8cf06293 100644 --- a/applications/utilities/preProcessing/setAlphaField/Make/options +++ b/applications/utilities/preProcessing/setAlphaField/Make/options @@ -1,9 +1,17 @@ EXE_INC = \ + -IalphaFieldFunctions/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ - -I$(LIB_SRC)/sampling/lnInclude + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/sampling/lnInclude \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude EXE_LIBS = \ -lfiniteVolume \ + -lfileFormats \ + -lsurfMesh \ -lmeshTools \ - -lsampling + -lsampling \ + -lgeometricVoF \ + -lalphaFieldFunctions diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/Make/files b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..b7585a9d1a83bd804c8e71f22e69a6674cd45ffd --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/Make/files @@ -0,0 +1,11 @@ +/* Run-time selectable implicitFunctions */ +implicitFunctions/implicitFunction.C +implicitFunctions/sphere/sphereImplicitFunction.C +implicitFunctions/sin/sinImplicitFunction.C +implicitFunctions/ellipsoid/ellipsoidImplicitFunction.C +implicitFunctions/paraboloid/paraboloidImplicitFunction.C +implicitFunctions/plane/planeImplicitFunction.C +implicitFunctions/cylinder/cylinderImplicitFunction.C +implicitFunctions/composedFunction/composedFunctionImplicitFunction.C + +LIB = $(FOAM_LIBBIN)/libalphaFieldFunctions diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/Make/options b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..6b8588463d9782589e3443f8bb381f736ff3ddfa --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* LIB_LIBS = */ diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/composedFunction/composedFunctionImplicitFunction.C b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/composedFunction/composedFunctionImplicitFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..900188e5e2c56bcefd4d67e6c7828680a90f7ff8 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/composedFunction/composedFunctionImplicitFunction.C @@ -0,0 +1,207 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "composedFunctionImplicitFunction.H" +#include "scalarField.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + namespace implicitFunctions + { + defineTypeNameAndDebug(composedFunctionImplicitFunction, 0); + addToRunTimeSelectionTable + ( + implicitFunction, + composedFunctionImplicitFunction, + dict + ); + } +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +const Foam::Enum +< + Foam::implicitFunctions::composedFunctionImplicitFunction::modeType +> +Foam::implicitFunctions::composedFunctionImplicitFunction::modeTypeNames +({ + { modeType::ADD, "add" }, + { modeType::SUBTRACT, "subtract" }, + { modeType::MINDIST, "minDist" }, + { modeType::INTERSECT, "intersect" }, +}); + + +Foam::label +Foam::implicitFunctions::composedFunctionImplicitFunction::selectFunction +( + const scalarField& values +) const +{ + switch (mode_) + { + case modeType::MINDIST: + { + scalarField absVal(mag(values)); + return findMin(absVal); + } + case modeType::ADD: + { + return findMax(values); + } + case modeType::SUBTRACT: + { + // Note: start at the second entry + const label idx = findMin(values, 1); + + if (values[idx] < values[0] && pos(values[0])) + { + return idx; + } + else + { + return 0; + } + } + case modeType::INTERSECT: + { + return findMin(values); + } + default: + { + FatalErrorInFunction + << "This mode is not supported only " << nl + << "Supported modes are: " << nl + << modeTypeNames + << abort(FatalError); + } + } + + return -1; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::implicitFunctions::composedFunctionImplicitFunction:: +composedFunctionImplicitFunction +( + const dictionary& dict +) +: + functions_(), + mode_(modeTypeNames.get("mode", dict)), + values_() +{ + const dictionary& funcDict = dict.subDict("composedFunction"); + + functions_.resize(funcDict.size()); + values_.resize(funcDict.size(), Zero); + + label funci = 0; + + for (const entry& dEntry : funcDict) + { + const word& key = dEntry.keyword(); + + if (!dEntry.isDict()) + { + FatalIOErrorInFunction(funcDict) + << "Entry " << key << " is not a dictionary" << endl + << exit(FatalError); + } + + const dictionary& subdict = dEntry.dict(); + + functions_.set + ( + funci, + implicitFunction::New(subdict.get<word>("type"), subdict) + ); + + ++funci; + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::scalar Foam::implicitFunctions::composedFunctionImplicitFunction::value +( + const vector& p +) const +{ + forAll(values_,i) + { + values_[i] = functions_[i].value(p); + } + + const label idx = selectFunction(values_); + + return values_[idx]; +} + + +Foam::vector Foam::implicitFunctions::composedFunctionImplicitFunction::grad +( + const vector& p +) const +{ + forAll(values_,i) + { + values_[i] = mag(functions_[i].value(p)); + } + + const label minIdx = findMin(values_); + + return functions_[minIdx].grad(p); +} + + +Foam::scalar +Foam::implicitFunctions::composedFunctionImplicitFunction::distanceToSurfaces +( + const vector& p +) const +{ + forAll(values_,i) + { + values_[i] = mag(functions_[i].value(p)); + } + + const label minIdx = findMin(values_); + + return functions_[minIdx].distanceToSurfaces(p); +} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/composedFunction/composedFunctionImplicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/composedFunction/composedFunctionImplicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..f75da2a97be1038b3c1f8137f1a76cf7e5f0f77b --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/composedFunction/composedFunctionImplicitFunction.H @@ -0,0 +1,169 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunctions::composedFunctionImplicitFunction + +Description + Handles multiple implicit functions and offers multiple ways to combine + them + +Usage + Example of function object partial specification: + \verbatim + function composedFunctionImplicitFunction; + mode minDist; + // following mode are available: + // "add" "subtract" "minDist" "intersect" + composedFunctionImplicitFunctions + { + plane + { + function plane; + origin (0 1. 0); + normal (0 1 0); + } + + sphere + { + function sphere; + radius 0.4; + origin (0.5 1.5 0.5); + scale 1; + } + + sphere2 + { + function sphere; + radius 0.4; + origin (0.5 0.5 0.5); + scale -1; + } + } + \endverbatim + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + composedFunctionImplicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunctions_composedFunctionImplicitFunction_H +#define implicitFunctions_composedFunctionImplicitFunction_H + +#include "implicitFunction.H" +#include "scalarField.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace implicitFunctions +{ + +/*---------------------------------------------------------------------------*\ + Class composedFunctionImplicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class composedFunctionImplicitFunction +: + public implicitFunction +{ + // Private Member Data + + //- Enumeration defining the valid actions + enum class modeType + { + ADD, + SUBTRACT, + MINDIST, + INTERSECT + }; + + //- The setActions text representations + static const Enum<modeType> modeTypeNames; + + //- Stores the functions + PtrList<implicitFunction> functions_; + + //- Mode + modeType mode_; + + //- Needed for finding the closest function. + // Note: avoid creation every call + mutable scalarField values_; + + + // Private Member Functions + + label selectFunction(const scalarField& values) const; + + //- No copy construct + composedFunctionImplicitFunction + ( + const composedFunctionImplicitFunction& + ) = delete; + + //- No copy assignment + void operator=(const composedFunctionImplicitFunction&) = delete; + + +public: + + //- Runtime type information + TypeName("composedFunction"); + + + // Constructors + + //- Construct from dictionary + explicit composedFunctionImplicitFunction(const dictionary& dict); + + + //- Destructor + virtual ~composedFunctionImplicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const; + + virtual vector grad(const vector& p) const; + + virtual scalar distanceToSurfaces(const vector& p) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +} // End namespace implicitFunctions +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/cylinder/cylinderImplicitFunction.C b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/cylinder/cylinderImplicitFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..909087e47329de5e75d1039b03ddd524262cc463 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/cylinder/cylinderImplicitFunction.C @@ -0,0 +1,82 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cylinderImplicitFunction.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + namespace implicitFunctions + { + defineTypeNameAndDebug(cylinderImplicitFunction, 0); + addToRunTimeSelectionTable + ( + implicitFunction, + cylinderImplicitFunction, + dict + ); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::implicitFunctions::cylinderImplicitFunction::cylinderImplicitFunction +( + const point& origin, + const scalar radius, + const scalar scale, + const vector& direction +) +: + origin_(origin), + radius_(radius), + scale_(scale), + direction_(normalised(direction)), + project_(tensor::I - direction_*direction_) // outer product +{} + + +Foam::implicitFunctions::cylinderImplicitFunction::cylinderImplicitFunction +( + const dictionary& dict +) +: + cylinderImplicitFunction + ( + dict.get<point>("origin"), + dict.get<scalar>("radius"), + dict.getOrDefault<scalar>("scale", 1), + dict.get<vector>("direction") + ) +{} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/cylinder/cylinderImplicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/cylinder/cylinderImplicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..65de539668fee65783b3f413d94726b9c653bbc0 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/cylinder/cylinderImplicitFunction.H @@ -0,0 +1,132 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunctions::cylinderImplicitFunction + +Description + creates a infintite long cylinderImplicitFunction + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + cylinderImplicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunction_cylinderImplicitFunction_H +#define implicitFunction_cylinderImplicitFunction_H + +#include "implicitFunction.H" +#include "point.H" +#include "tensor.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace implicitFunctions +{ + +/*---------------------------------------------------------------------------*\ + Class cylinderImplicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class cylinderImplicitFunction +: + public implicitFunction +{ +private: + + // Private Data + + //- Origin point + const point origin_; + + //- Radius + const scalar radius_; + + const scalar scale_; + + const vector direction_; + + const tensor project_; + + +public: + + //- Runtime type information + TypeName("cylinder"); + + + // Constructors + + //- Construct from components + cylinderImplicitFunction + ( + const point& origin, + const scalar radius, + const scalar scale, + const vector& direction + ); + + //- Construct from dictionary + explicit cylinderImplicitFunction(const dictionary& dict); + + + //- Destructor + virtual ~cylinderImplicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const + { + return (-mag(project_ & (p - origin_)) + radius_)*scale_; + } + + virtual vector grad(const vector& p) const + { + return -(project_ & (p - origin_))*scale_; + } + + virtual scalar distanceToSurfaces(const vector& p) const + { + return mag(mag(project_ & (p - origin_)) - radius_)*scale_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace implicitFunctions +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/ellipsoid/ellipsoidImplicitFunction.C b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/ellipsoid/ellipsoidImplicitFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..2732db3136aa745d64e374b9067dbe4e90fd2064 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/ellipsoid/ellipsoidImplicitFunction.C @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "ellipsoidImplicitFunction.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + namespace implicitFunctions + { + defineTypeNameAndDebug(ellipsoidImplicitFunction, 0); + addToRunTimeSelectionTable + ( + implicitFunction, + ellipsoidImplicitFunction, + dict + ); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::implicitFunctions::ellipsoidImplicitFunction::ellipsoidImplicitFunction +( + const vector& semiAxis +) +: + semiAxis_(semiAxis), + origin_(Zero) +{} + + +Foam::implicitFunctions::ellipsoidImplicitFunction::ellipsoidImplicitFunction +( + const dictionary& dict +) +: + ellipsoidImplicitFunction + ( + dict.get<vector>("semiAxis") + ) +{} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/ellipsoid/ellipsoidImplicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/ellipsoid/ellipsoidImplicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..a383c8b8a850fa393292c0c9dae10b3c433cd055 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/ellipsoid/ellipsoidImplicitFunction.H @@ -0,0 +1,131 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunctions::ellipsoidImplicitFunction + +Description + creates an ellipsoidImplicitFunction + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + ellipsoidImplicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunction_ellipsoidImplicitFunction_H +#define implicitFunction_ellipsoidImplicitFunction_H + +#include "implicitFunction.H" +#include "mathematicalConstants.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace implicitFunctions +{ + +/*---------------------------------------------------------------------------*\ + Class ellipsoidImplicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class ellipsoidImplicitFunction +: + public implicitFunction +{ + // Private Member Data + + //- Axis + const vector semiAxis_; + + //- Origin point + const vector origin_; + + +public: + + //- Runtime type information + TypeName("ellipsoidImplicitFunction"); + + + // Constructors + + //- Construct from components + explicit ellipsoidImplicitFunction(const vector& semiAxis); + + //- Construct from dictionary + explicit ellipsoidImplicitFunction(const dictionary& dict); + + + //- Destructor + virtual ~ellipsoidImplicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const + { + return + -sqrt + ( + sqr((p.x() - origin_.x())/semiAxis_.x()) + + sqr((p.y() - origin_.y())/semiAxis_.y()) + + sqr((p.z() - origin_.z())/semiAxis_.z()) + ) + 1; + } + + + virtual vector grad(const vector& p) const + { + // normal_ has the length of one + return vector + ( + 2*(p.x() - origin_.x())/sqr(semiAxis_.x()), + 2*(p.y() - origin_.y())/sqr(semiAxis_.y()), + 2*(p.z() - origin_.z())/sqr(semiAxis_.z()) + ); + } + + virtual scalar distanceToSurfaces(const vector& p) const + { + NotImplemented; + return GREAT; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace implicitFunctions +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/implicitFunction.C b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/implicitFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..fb5e1220f67ff2073d2c000d0484611344b8a401 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/implicitFunction.C @@ -0,0 +1,66 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "implicitFunction.H" +#include "error.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(implicitFunction, 0); + defineRunTimeSelectionTable(implicitFunction, dict); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::implicitFunction> Foam::implicitFunction::New +( + const word& implicitFunctionType, + const dictionary& dict +) +{ + auto cstrIter = dictConstructorTablePtr_->cfind(implicitFunctionType); + + if (!cstrIter.found()) + { + FatalIOErrorInLookup + ( + dict, + "implicitFunction", + implicitFunctionType, + *dictConstructorTablePtr_ + ) << exit(FatalIOError); + } + + return autoPtr<implicitFunction>(cstrIter()(dict)); +} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/implicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/implicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..14111622d9b28061d967317387caefce79455577 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/implicitFunction.H @@ -0,0 +1,122 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunction + +Description + Base class for implicit functions + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + implicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunction_H +#define implicitFunction_H + +#include "autoPtr.H" +#include "dictionary.H" +#include "vector.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class implicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class implicitFunction +{ +public: + + //- Runtime type information + TypeName("implicitFunction"); + + //- Declare run-time constructor selection table + declareRunTimeSelectionTable + ( + autoPtr, + implicitFunction, + dict, + ( + const dictionary& dict + ), + (dict) + ); + + + // Constructors + + //- Default construct + implicitFunction() = default; + + + //- Return a reference to the selected implicitFunction + static autoPtr<implicitFunction> New + ( + const word& implicitFunctionType, + const dictionary& dict + ); + + + //- Destructor + virtual ~implicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const + { + return GREAT; + } + + virtual vector grad(const vector& p) const + { + return vector::max; + } + + virtual scalar distanceToSurfaces(const vector& p) const + { + return GREAT; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/solvers/multiphase/interIsoFoam/setDeltaT.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/paraboloid/paraboloidImplicitFunction.C similarity index 59% rename from applications/solvers/multiphase/interIsoFoam/setDeltaT.H rename to applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/paraboloid/paraboloidImplicitFunction.C index ac59647e7e84d66600d81e06cefa8e5a9bd237e9..f2aae0fadd3ff35e18dd148b35e7a1976784ca34 100644 --- a/applications/solvers/multiphase/interIsoFoam/setDeltaT.H +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/paraboloid/paraboloidImplicitFunction.C @@ -5,7 +5,8 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2011-2017 OpenFOAM Foundation + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019 DLR ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -23,33 +24,50 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. -Global - setDeltaT +\*---------------------------------------------------------------------------*/ -Description - Reset the timestep to maintain a constant maximum courant Number. - Reduction of time-step is immediate, but increase is damped to avoid - unstable oscillations. +#include "paraboloidImplicitFunction.H" +#include "addToRunTimeSelectionTable.H" -\*---------------------------------------------------------------------------*/ +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // -if (adjustTimeStep) +namespace Foam { - scalar maxDeltaTFact = - min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL)); + namespace implicitFunctions + { + defineTypeNameAndDebug(paraboloidImplicitFunction, 0); + addToRunTimeSelectionTable + ( + implicitFunction, + paraboloidImplicitFunction, + dict + ); + } + +} - scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2); - runTime.setDeltaT +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::implicitFunctions::paraboloidImplicitFunction::paraboloidImplicitFunction +( + const vector& coeffs +) +: + coeffs_(coeffs) +{} + + +Foam::implicitFunctions::paraboloidImplicitFunction::paraboloidImplicitFunction +( + const dictionary& dict +) +: + paraboloidImplicitFunction ( - min - ( - deltaTFact*runTime.deltaTValue(), - maxDeltaT - ) - ); + dict.get<vector>("coeffs") + ) +{} - Info<< "deltaT = " << runTime.deltaTValue() << endl; -} // ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/paraboloid/paraboloidImplicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/paraboloid/paraboloidImplicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..a25d908f3d38df07cd713e7a82a17ff64b994896 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/paraboloid/paraboloidImplicitFunction.H @@ -0,0 +1,120 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunctions::paraboloidImplicitFunction + +Description + creates a paraboloid + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + paraboloidImplicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunction_paraboloidImplicitFunction_H +#define implicitFunction_paraboloidImplicitFunction_H + +#include "implicitFunction.H" +#include "mathematicalConstants.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace implicitFunctions +{ + +/*---------------------------------------------------------------------------*\ + Class paraboloidImplicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class paraboloidImplicitFunction +: + public implicitFunction +{ + // Private Data + + //- Coefficients of ax^2 + bx*y + cy^2 + const vector coeffs_; + + +public: + + //- Runtime type information + TypeName("paraboloid"); + + + // Constructors + + //- Construct from components + explicit paraboloidImplicitFunction(const vector& coeffs); + + //- Construct from dictionary + explicit paraboloidImplicitFunction(const dictionary& dict); + + + //- Destructor + virtual ~paraboloidImplicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const + { + return + coeffs_.x()*sqr(p.x()) + + coeffs_.y()*p.x()*p.y() + + coeffs_.z()*sqr(p.y()) + - p.z(); + } + + virtual vector grad(const vector& p) const + { + NotImplemented; + return Zero; + } + + virtual scalar distanceToSurfaces(const vector& p) const + { + NotImplemented; + return 0; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace implicitFunctions +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/plane/planeImplicitFunction.C b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/plane/planeImplicitFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..d1bb0afac4accb66a878a662a72eb18e33683330 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/plane/planeImplicitFunction.C @@ -0,0 +1,75 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "planeImplicitFunction.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + namespace implicitFunctions + { + defineTypeNameAndDebug(planeImplicitFunction, 0); + addToRunTimeSelectionTable + ( + implicitFunction, + planeImplicitFunction, + dict + ); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::implicitFunctions::planeImplicitFunction::planeImplicitFunction +( + const vector& origin, + const vector& normal +) +: + origin_(origin), + normal_(normalised(normal)) +{} + + +Foam::implicitFunctions::planeImplicitFunction::planeImplicitFunction +( + const dictionary& dict +) +: + planeImplicitFunction + ( + dict.get<vector>("origin"), + dict.get<vector>("normal") + ) +{} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/plane/planeImplicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/plane/planeImplicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..a89f603cb5cd3534e949e3f3b3b7484e8c1fa568 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/plane/planeImplicitFunction.H @@ -0,0 +1,120 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunctions::planeImplicitFunction + +Description + creates a plane + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + planeImplicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunction_planeImplicitFunction_H +#define implicitFunction_planeImplicitFunction_H + +#include "implicitFunction.H" +#include "mathematicalConstants.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace implicitFunctions +{ + +/*---------------------------------------------------------------------------*\ + Class planeImplicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class planeImplicitFunction +: + public implicitFunction +{ + // Private Data + + //- Reference point + const vector origin_; + + //- Unit-normal vector + const vector normal_; + + +public: + + //- Runtime type information + TypeName("plane"); + + + // Constructors + + //- Construct from components + planeImplicitFunction(const vector& origin, const vector& normal); + + //- Construct from dictionary (used by implicitFunctions) + explicit planeImplicitFunction(const dictionary& dict); + + + //- Destructor + virtual ~planeImplicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const + { + return -normal_ & (origin_ - p); + } + + virtual vector grad(const vector& p) const + { + // normal_ has the length of one + return normal_; + } + + virtual scalar distanceToSurfaces(const vector& p) const + { + // normal_ has the length of one + return mag((p - origin_) & -normal_); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace implicitFunctions +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sin/sinImplicitFunction.C b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sin/sinImplicitFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..a193d2b663b36f9d49a4cd3b4a2f66840ccf615e --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sin/sinImplicitFunction.C @@ -0,0 +1,87 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "sinImplicitFunction.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + namespace implicitFunctions + { + defineTypeNameAndDebug(sinImplicitFunction, 0); + addToRunTimeSelectionTable + ( + implicitFunction, + sinImplicitFunction, + dict + ); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::implicitFunctions::sinImplicitFunction::sinImplicitFunction +( + const scalar period, + const scalar phase, + const scalar amplitude, + const vector& direction, + const vector& up, + const vector& origin +) +: + period_(period), + phase_(phase), + amplitude_(amplitude), + up_(normalised(up)), + direction_(normalised(direction)), + origin_(origin) +{} + + +Foam::implicitFunctions::sinImplicitFunction::sinImplicitFunction +( + const dictionary& dict +) +: + sinImplicitFunction + ( + dict.get<scalar>("period"), + dict.getOrDefault<scalar>("phase", 0), + dict.get<scalar>("amplitude"), + dict.get<vector>("direction"), + dict.get<vector>("up"), + dict.get<vector>("origin") + ) +{} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sin/sinImplicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sin/sinImplicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..588c20d5e98993266c771164bdd77464dcf131d2 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sin/sinImplicitFunction.H @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunctions::sinImplicitFunction + +Description + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + sinImplicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunction_sinImplicitFunction_H +#define implicitFunction_sinImplicitFunction_H + +#include "implicitFunction.H" +#include "mathematicalConstants.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace implicitFunctions +{ + +/*---------------------------------------------------------------------------*\ + Class sinImplicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class sinImplicitFunction +: + public implicitFunction +{ +private: + + // Private Data + + //- Origin point + const scalar period_; + + //- Radius + const scalar phase_; + + const scalar amplitude_; + + const vector up_; + + const vector direction_; + + const vector origin_; + + +public: + + //- Runtime type information + TypeName("sin"); + + + // Constructors + + //- Construct from components + sinImplicitFunction + ( + const scalar period, + const scalar phase, + const scalar amplitude, + const vector& direction, + const vector& up, + const vector& origin + ); + + //- Construct from dictionary (used by implicitFunctions) + explicit sinImplicitFunction(const dictionary& dict); + + + //- Destructor + virtual ~sinImplicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const + { + const scalar x = (p - origin_) & direction_; + const scalar z = (p - origin_) & -up_; + + return + z + - amplitude_ + *Foam::sin(2*constant::mathematical::pi*x/period_ + phase_); + } + + virtual vector grad(const vector& p) const + { + NotImplemented; + return Zero; + } + + virtual scalar distanceToSurfaces(const vector& p) const + { + NotImplemented; + return 0; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace implicitFunctions +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sphere/sphereImplicitFunction.C b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sphere/sphereImplicitFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..48a26c3b383753005ab654428e97de9f8d453496 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sphere/sphereImplicitFunction.C @@ -0,0 +1,78 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "sphereImplicitFunction.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + namespace implicitFunctions + { + defineTypeNameAndDebug(sphereImplicitFunction, 0); + addToRunTimeSelectionTable + ( + implicitFunction, + sphereImplicitFunction, + dict + ); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::implicitFunctions::sphereImplicitFunction::sphereImplicitFunction +( + const point& origin, + const scalar radius, + const scalar scale +) +: + origin_(origin), + radius_(radius), + scale_(scale) +{} + + +Foam::implicitFunctions::sphereImplicitFunction::sphereImplicitFunction +( + const dictionary& dict +) +: + sphereImplicitFunction + ( + dict.get<point>("origin"), + dict.get<scalar>("radius"), + dict.getOrDefault<scalar>("scale", 1) + ) +{} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sphere/sphereImplicitFunction.H b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sphere/sphereImplicitFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..93ee773d3d4c393aa552f96447d233322698a69e --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/alphaFieldFunctions/implicitFunctions/sphere/sphereImplicitFunction.H @@ -0,0 +1,124 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::implicitFunctions::sphereImplicitFunction + +Description + Creates a sphere + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + sphereImplicitFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef implicitFunction_sphereImplicitFunction_H +#define implicitFunction_sphereImplicitFunction_H + +#include "implicitFunction.H" +#include "point.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace implicitFunctions +{ + +/*---------------------------------------------------------------------------*\ + Class sphereImplicitFunction Declaration +\*---------------------------------------------------------------------------*/ + +class sphereImplicitFunction +: + public implicitFunction +{ + // Private Data + + //- Origin point + const point origin_; + + //- Radius + const scalar radius_; + + const scalar scale_; + + +public: + + //- Runtime type information + TypeName("sphere"); + + + // Constructors + + //- Construct from components + sphereImplicitFunction + ( + const point&, + const scalar radius, + const scalar scale + ); + + //- Construct from dictionary + explicit sphereImplicitFunction(const dictionary& dict); + + + //- Destructor + virtual ~sphereImplicitFunction() = default; + + + // Member Functions + + virtual scalar value(const vector& p) const + { + return (-mag(p - origin_) + radius_)*scale_; + } + + virtual vector grad(const vector& p) const + { + return (origin_ - p)*scale_; + } + + virtual scalar distanceToSurfaces(const vector& p) const + { + return mag(mag(p - origin_) - radius_)*scale_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace implicitFunctions +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setAlphaField/setAlphaField.C b/applications/utilities/preProcessing/setAlphaField/setAlphaField.C index dc343ab657e18a302078f83b18fb2c00c79f8158..82e37fac64827a79d924a934484c9059582539aa 100644 --- a/applications/utilities/preProcessing/setAlphaField/setAlphaField.C +++ b/applications/utilities/preProcessing/setAlphaField/setAlphaField.C @@ -7,6 +7,7 @@ ------------------------------------------------------------------------------- Copyright (C) 2016-2017 DHI Copyright (C) 2017-2020 OpenCFD Ltd. + Copyright (c) 2017-2020, German Aerospace Center (DLR) ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,86 +29,94 @@ Application setAlphaField Description - Uses isoCutCell to create a volume fraction field from either a cylinder, + Uses cutCellIso to create a volume fraction field from either a cylinder, a sphere or a plane. Original code supplied by Johan Roenby, DHI (2016) + Modification Henning Scheufler, DLR (2019) \*---------------------------------------------------------------------------*/ #include "fvCFD.H" -#include "isoCutFace.H" -#include "isoCutCell.H" -#include "Enum.H" -#include "mathematicalConstants.H" -using namespace Foam::constant; +#include "triSurface.H" +#include "triSurfaceTools.H" + +#include "implicitFunction.H" + +#include "cutCellIso.H" +#include "OBJstream.H" + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -class shapeSelector +void isoFacesToFile +( + const DynamicList<List<point>>& faces, + const word& fileName +) { - public: + // Writing isofaces to OBJ file for inspection in paraview + OBJstream os(fileName + ".obj"); - enum class shapeType - { - PLANE, - SPHERE, - CYLINDER, - SIN - }; - - static const Foam::Enum<shapeType> shapeTypeNames; -}; + if (Pstream::parRun()) + { + // Collect points from all the processors + List<DynamicList<List<point>>> allProcFaces(Pstream::nProcs()); + allProcFaces[Pstream::myProcNo()] = faces; + Pstream::gatherList(allProcFaces); + if (Pstream::master()) + { + Info<< "Writing file: " << fileName << endl; + + for (const DynamicList<List<point>>& procFaces : allProcFaces) + { + for (const List<point>& facePts : procFaces) + { + os.write(face(identity(facePts.size())), facePts); + } + } + } + } + else + { + Info<< "Writing file: " << fileName << endl; -const Foam::Enum -< - shapeSelector::shapeType -> -shapeSelector::shapeTypeNames -({ - { shapeSelector::shapeType::PLANE, "plane" }, - { shapeSelector::shapeType::SPHERE, "sphere" }, - { shapeSelector::shapeType::CYLINDER, "cylinder" }, - { shapeSelector::shapeType::SIN, "sin" }, -}); + for (const List<point>& facePts : faces) + { + os.write(face(identity(facePts.size())), facePts); + } + } +} int main(int argc, char *argv[]) { argList::addNote ( - "Uses isoCutCell to create a volume fraction field from a" - " cylinder, sphere or a plane." + "Uses cutCellIso to create a volume fraction field from an " + "implicit function." ); + #include "addDictOption.H" + #include "addRegionOption.H" #include "setRootCase.H" #include "createTime.H" #include "createNamedMesh.H" - Info<< "Reading setAlphaFieldDict\n" << endl; + const word dictName("setAlphaFieldDict"); + #include "setSystemMeshDictionaryIO.H" - IOdictionary dict - ( - IOobject - ( - "setAlphaFieldDict", - runTime.system(), - mesh, - IOobject::MUST_READ, - IOobject::NO_WRITE - ) - ); + IOdictionary setAlphaFieldDict(dictIO); - const shapeSelector::shapeType surfType - ( - shapeSelector::shapeTypeNames.get("type", dict) - ); - const vector origin(dict.getCompat<vector>("origin", {{"centre", 1806}})); - const word fieldName(dict.get<word>("field")); + Info<< "Reading " << setAlphaFieldDict.name() << endl; + + const word fieldName = setAlphaFieldDict.get<word>("field"); + const bool invert = setAlphaFieldDict.getOrDefault("invert", false); + const bool writeOBJ = setAlphaFieldDict.getOrDefault("writeOBJ", false); - Info<< "Reading field " << fieldName << "\n" << endl; + Info<< "Reading field " << fieldName << nl << endl; volScalarField alpha1 ( IOobject @@ -121,85 +130,76 @@ int main(int argc, char *argv[]) mesh ); - scalar f0 = 0; - scalarField f(mesh.points().size()); + autoPtr<implicitFunction> func = implicitFunction::New + ( + setAlphaFieldDict.get<word>("type"), + setAlphaFieldDict + ); - Info<< "Processing type '" << shapeSelector::shapeTypeNames[surfType] - << "'" << endl; + scalarField f(mesh.nPoints(), Zero); - switch (surfType) + forAll(f, pi) { - case shapeSelector::shapeType::PLANE: - { - const vector direction(dict.get<vector>("direction")); + f[pi] = func->value(mesh.points()[pi]); + }; - f = -(mesh.points() - origin) & (direction/mag(direction)); - f0 = 0; - break; - } - case shapeSelector::shapeType::SPHERE: - { - const scalar radius(dict.get<scalar>("radius")); + cutCellIso cutCell(mesh, f); + + DynamicList<List<point>> facePts; + + DynamicList<triSurface> surface; + + surfaceScalarField cellToCellDist(mag(mesh.delta())); - f = -mag(mesh.points() - origin); - f0 = -radius; - break; + forAll(alpha1, cellI) + { + label cellStatus = cutCell.calcSubCell(cellI, 0.0); + + if (cellStatus == -1) + { + alpha1[cellI] = 1; } - case shapeSelector::shapeType::CYLINDER: + else if (cellStatus == 1) { - const scalar radius(dict.get<scalar>("radius")); - const vector direction(dict.get<vector>("direction")); - - f = -sqrt - ( - sqr(mag(mesh.points() - origin)) - - sqr(mag((mesh.points() - origin) & direction)) - ); - f0 = -radius; - break; + alpha1[cellI] = 0; } - case shapeSelector::shapeType::SIN: + else if (cellStatus == 0) { - const scalar period(dict.get<scalar>("period")); - const scalar amplitude(dict.get<scalar>("amplitude")); - const vector up(dict.get<vector>("up")); - const vector direction(dict.get<vector>("direction")); - - const scalarField xx - ( - (mesh.points() - origin) & direction/mag(direction) - ); - const scalarField zz((mesh.points() - origin) & up/mag(up)); - - f = amplitude*Foam::sin(2*mathematical::pi*xx/period) - zz; - f0 = 0; - break; + if (mag(cutCell.faceArea()) != 0) + { + alpha1[cellI] = max(min(cutCell.VolumeOfFluid(), 1), 0); + if (writeOBJ && (mag(cutCell.faceArea()) >= 1e-14)) + { + facePts.append(cutCell.facePoints()); + } + } } } + if (writeOBJ) + { + isoFacesToFile(facePts, fieldName + "0"); + } - // Define function on mesh points and isovalue - - // Calculating alpha1 volScalarField from f = f0 isosurface - isoCutCell icc(mesh, f); - icc.volumeOfFluid(alpha1, f0); + ISstream::defaultPrecision(18); - if (dict.getOrDefault("invertAlpha", false)) + if (invert) { - alpha1 = 1 - alpha1; + alpha1 = scalar(1) - alpha1; } - // Writing volScalarField alpha1 - ISstream::defaultPrecision(18); + alpha1.correctBoundaryConditions(); + + Info<< "Writing new alpha field " << alpha1.name() << endl; alpha1.write(); - Info<< nl << "Phase-1 volume fraction = " - << alpha1.weightedAverage(mesh.Vsc()).value() - << " Min(" << alpha1.name() << ") = " << min(alpha1).value() - << " Max(" << alpha1.name() << ") - 1 = " << max(alpha1).value() - 1 - << nl << endl; + const scalarField& alpha = alpha1.internalField(); + + Info<< "sum(alpha*V):" << gSum(mesh.V()*alpha) + << ", 1-max(alpha1): " << 1 - gMax(alpha) + << " min(alpha1): " << gMin(alpha) << endl; - Info<< "End\n" << endl; + Info<< "\nEnd\n" << endl; return 0; } diff --git a/applications/utilities/preProcessing/setAlphaField/setAlphaFieldDict b/applications/utilities/preProcessing/setAlphaField/setAlphaFieldDict new file mode 100644 index 0000000000000000000000000000000000000000..dcd253a205a0e6a0d7c4d4039ceac4b84ac08169 --- /dev/null +++ b/applications/utilities/preProcessing/setAlphaField/setAlphaFieldDict @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +field "alpha.water"; + +type composedFunction; +mode add; +composedFunctions +{ + plane + { + type plane; + centre (0 1. 0); + normal (0 1 0); + } + + sphere + { + type sphere; + radius 0.4; + centre (0.5 0.8 0.5); + scale 1; + } + + sphere2 + { + type sphere; + radius 0.4; + centre (0.5 0.5 0.5); + } +} + + +// ************************************************************************* // diff --git a/src/Allwmake b/src/Allwmake index c2baebc1cae14eefe1630fb340a44e8948f29bd1..57fae7ae8fefa92d570a93153bb3886f99c49899 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -71,12 +71,13 @@ parallel/Allwmake $targetType $* wmake $targetType dynamicFvMesh wmake $targetType topoChangerFvMesh +transportModels/Allwmake $targetType $* wmake $targetType sampling randomProcesses/Allwmake $targetType $* wmake $targetType ODE -transportModels/Allwmake $targetType $* + thermophysicalModels/Allwmake $targetType $* TurbulenceModels/Allwmake $targetType $* wmake $targetType combustionModels diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files index eef2fd9473fac9a45f8e4b7dcd0a782e9ab4af73..6a0bf5c8fa791c11e0ff223eab504b82fb343f96 100644 --- a/src/finiteVolume/Make/files +++ b/src/finiteVolume/Make/files @@ -93,6 +93,10 @@ $(faceToCell)/extendedFaceToCellStencil.C $(faceToCell)/extendedCentredFaceToCellStencil.C $(faceToCell)/MeshObjects/centredCFCFaceToCellStencilObject.C +fvMesh/zoneDistribute/zoneStencils/zoneCellStencils.C +fvMesh/zoneDistribute/zoneStencils/zoneCPCStencil.C +fvMesh/zoneDistribute/zoneDistribute.C + functionObjects/fvMeshFunctionObject/fvMeshFunctionObject.C functionObjects/volRegion/volRegion.C functionObjects/fieldSelections/fieldSelection/fieldSelection.C @@ -286,11 +290,13 @@ $(fieldExpr)/pointPatchFields/exprValuePointPatchFields.C fvMatrices/fvMatrices.C fvMatrices/fvScalarMatrix/fvScalarMatrix.C fvMatrices/solvers/MULES/MULES.C -fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.C -fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.C -fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C +fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/multiDimPolyFunctions.C +fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/polyDegree1.C +fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFitter.C +fvMatrices/solvers/multiDimPolyFitter/leastSquareGrad.C + interpolation = interpolation/interpolation $(interpolation)/interpolation/interpolations.C diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C deleted file mode 100644 index 5a57e54a17feb7c56a94ba7b436dce997e9db101..0000000000000000000000000000000000000000 --- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C +++ /dev/null @@ -1,1041 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2016-2017 DHI - Copyright (C) 2016-2020 OpenCFD Ltd. - Copyright (C) 2019 Johan Roenby -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "isoAdvection.H" -#include "volFields.H" -#include "interpolationCellPoint.H" -#include "volPointInterpolation.H" -#include "fvcSurfaceIntegrate.H" -#include "fvcGrad.H" -#include "upwind.H" -#include "cellSet.H" -#include "meshTools.H" -#include "OBJstream.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -namespace Foam -{ - defineTypeNameAndDebug(isoAdvection, 0); -} - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::isoAdvection::isoAdvection -( - volScalarField& alpha1, - const surfaceScalarField& phi, - const volVectorField& U -) -: - // General data - mesh_(alpha1.mesh()), - dict_(mesh_.solverDict(alpha1.name())), - alpha1_(alpha1), - alpha1In_(alpha1.ref()), - phi_(phi), - U_(U), - dVf_ - ( - IOobject - ( - "dVf_", - mesh_.time().timeName(), - mesh_, - IOobject::NO_READ, - IOobject::NO_WRITE - ), - mesh_, - dimensionedScalar(dimVol, Zero) - ), - advectionTime_(0), - - // Interpolation data - ap_(mesh_.nPoints()), - - // Tolerances and solution controls - nAlphaBounds_(dict_.getOrDefault<label>("nAlphaBounds", 3)), - isoFaceTol_(dict_.getOrDefault<scalar>("isoFaceTol", 1e-8)), - surfCellTol_(dict_.getOrDefault<scalar>("surfCellTol", 1e-8)), - gradAlphaBasedNormal_(dict_.getOrDefault("gradAlphaNormal", false)), - writeIsoFacesToFile_(dict_.getOrDefault("writeIsoFaces", false)), - - // Cell cutting data - surfCells_(label(0.2*mesh_.nCells())), - isoCutCell_(mesh_, ap_), - isoCutFace_(mesh_, ap_), - cellIsBounded_(mesh_.nCells(), false), - checkBounding_(mesh_.nCells(), false), - bsFaces_(label(0.2*mesh_.nBoundaryFaces())), - bsx0_(bsFaces_.size()), - bsn0_(bsFaces_.size()), - bsUn0_(bsFaces_.size()), - bsf0_(bsFaces_.size()), - - // Parallel run data - procPatchLabels_(mesh_.boundary().size()), - surfaceCellFacesOnProcPatches_(0) -{ - isoCutCell::debug = debug; - isoCutFace::debug = debug; - - // Prepare lists used in parallel runs - if (Pstream::parRun()) - { - // Force calculation of required demand driven data (else parallel - // communication may crash) - mesh_.cellCentres(); - mesh_.cellVolumes(); - mesh_.faceCentres(); - mesh_.faceAreas(); - mesh_.magSf(); - mesh_.boundaryMesh().patchID(); - mesh_.cellPoints(); - mesh_.cellCells(); - mesh_.cells(); - - // Get boundary mesh and resize the list for parallel comms - const polyBoundaryMesh& patches = mesh_.boundaryMesh(); - - surfaceCellFacesOnProcPatches_.resize(patches.size()); - - // Append all processor patch labels to the list - forAll(patches, patchi) - { - if - ( - isA<processorPolyPatch>(patches[patchi]) - && patches[patchi].size() > 0 - ) - { - procPatchLabels_.append(patchi); - } - } - } -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void Foam::isoAdvection::timeIntegratedFlux() -{ - // Get time step - const scalar dt = mesh_.time().deltaTValue(); - - // Create object for interpolating velocity to isoface centres - interpolationCellPoint<vector> UInterp(U_); - - // For each downwind face of each surface cell we "isoadvect" to find dVf - label nSurfaceCells = 0; - - // Clear out the data for re-use and reset list containing information - // whether cells could possibly need bounding - clearIsoFaceData(); - - // Get necessary references - const scalarField& phiIn = phi_.primitiveField(); - const scalarField& magSfIn = mesh_.magSf().primitiveField(); - scalarField& dVfIn = dVf_.primitiveFieldRef(); - - // Get necessary mesh data - const cellList& cellFaces = mesh_.cells(); - const labelList& own = mesh_.faceOwner(); - const labelList& nei = mesh_.faceNeighbour(); - const labelListList& cellCells = mesh_.cellCells(); - - // Calculate alpha vertex values, ap_, or cell normals (used to get - // interface-vertex distance function if gradAlphaBasedNormal_) - volVectorField cellNormals("cellN", fvc::grad(alpha1_)); - if (gradAlphaBasedNormal_) - { - // Calculate gradient of alpha1 and normalise and smoothen it. - normaliseAndSmooth(cellNormals); - } - else - { - // Interpolating alpha1 cell centre values to mesh points (vertices) - ap_ = volPointInterpolation::New(mesh_).interpolate(alpha1_); - } - - // Storage for isoFace points. Only used if writeIsoFacesToFile_ - DynamicList<List<point>> isoFacePts; - - // Loop through all cells - forAll(alpha1In_, celli) - { - // If not a surface cell continue to next cell - if (!isASurfaceCell(celli)) continue; - - // This is a surface cell, increment counter, append and mark cell - // Note: We also have the cellStatus below where the cell might not have - // an isoface. So maybe the counter and append should be put there. - nSurfaceCells++; - surfCells_.append(celli); - checkBounding_[celli] = true; - - DebugInfo - << "\n------------ Cell " << celli << " with alpha1 = " - << alpha1In_[celli] << " and 1-alpha1 = " - << 1.0 - alpha1In_[celli] << " ------------" - << endl; - - if (gradAlphaBasedNormal_) - { - vectorField& cellNormalsIn = cellNormals.primitiveFieldRef(); - setCellVertexValues(celli, cellNormalsIn); - } - - // Calculate isoFace centre x0, normal n0 at time t - - // Calculate cell status (-1: cell is fully below the isosurface, 0: - // cell is cut, 1: cell is fully above the isosurface) - label maxIter = 100; // NOTE: make it a debug switch - label cellStatus = isoCutCell_.vofCutCell - ( - celli, - alpha1In_[celli], - isoFaceTol_, - maxIter - ); - - // If cell is not cut move on to next cell - if (cellStatus != 0) continue; - - // If cell is cut calculate isoface unit normal - const scalar f0(isoCutCell_.isoValue()); - const point& x0(isoCutCell_.isoFaceCentre()); - vector n0(isoCutCell_.isoFaceArea()); - n0 /= (mag(n0)); - - if (writeIsoFacesToFile_ && mesh_.time().writeTime()) - { - isoFacePts.append(isoCutCell_.isoFacePoints()); - } - - // Get the speed of the isoface by interpolating velocity and - // dotting it with isoface unit normal - const scalar Un0 = UInterp.interpolate(x0, celli) & n0; - - DebugInfo - << "calcIsoFace gives initial surface: \nx0 = " << x0 - << ", \nn0 = " << n0 << ", \nf0 = " << f0 << ", \nUn0 = " - << Un0 << endl; - - // Estimate time integrated flux through each downwind face - // Note: looping over all cell faces - in reduced-D, some of - // these faces will be on empty patches - const cell& celliFaces = cellFaces[celli]; - forAll(celliFaces, fi) - { - const label facei = celliFaces[fi]; - - if (mesh_.isInternalFace(facei)) - { - bool isDownwindFace = false; - label otherCell = -1; - - if (celli == own[facei]) - { - if (phiIn[facei] > 10*SMALL) - { - isDownwindFace = true; - } - - otherCell = nei[facei]; - } - else - { - if (phiIn[facei] < -10*SMALL) - { - isDownwindFace = true; - } - - otherCell = own[facei]; - } - - if (isDownwindFace) - { - dVfIn[facei] = isoCutFace_.timeIntegratedFaceFlux - ( - facei, - x0, - n0, - Un0, - f0, - dt, - phiIn[facei], - magSfIn[facei] - ); - } - - // We want to check bounding of neighbour cells to - // surface cells as well: - checkBounding_[otherCell] = true; - - // Also check neighbours of neighbours. - // Note: consider making it a run time selectable - // extension level (easily done with recursion): - // 0 - only neighbours - // 1 - neighbours of neighbours - // 2 - ... - // Note: We will like all point neighbours to interface cells to - // be checked. Especially if the interface leaves a cell during - // a time step, it may enter a point neighbour which should also - // be treated like a surface cell. Its interface normal should - // somehow be inherrited from its upwind cells from which it - // receives the interface. - const labelList& nNeighbourCells = cellCells[otherCell]; - forAll(nNeighbourCells, ni) - { - checkBounding_[nNeighbourCells[ni]] = true; - } - } - else - { - bsFaces_.append(facei); - bsx0_.append(x0); - bsn0_.append(n0); - bsUn0_.append(Un0); - bsf0_.append(f0); - - // Note: we must not check if the face is on the - // processor patch here. - } - } - } - - // Get references to boundary fields - const polyBoundaryMesh& boundaryMesh = mesh_.boundaryMesh(); - const surfaceScalarField::Boundary& phib = phi_.boundaryField(); - const surfaceScalarField::Boundary& magSfb = mesh_.magSf().boundaryField(); - surfaceScalarField::Boundary& dVfb = dVf_.boundaryFieldRef(); - const label nInternalFaces = mesh_.nInternalFaces(); - - // Loop through boundary surface faces - forAll(bsFaces_, i) - { - // Get boundary face index (in the global list) - const label facei = bsFaces_[i]; - const label patchi = boundaryMesh.patchID()[facei - nInternalFaces]; - const label start = boundaryMesh[patchi].start(); - - if (phib[patchi].size()) - { - const label patchFacei = facei - start; - const scalar phiP = phib[patchi][patchFacei]; - - if (phiP > 10*SMALL) - { - const scalar magSf = magSfb[patchi][patchFacei]; - - dVfb[patchi][patchFacei] = isoCutFace_.timeIntegratedFaceFlux - ( - facei, - bsx0_[i], - bsn0_[i], - bsUn0_[i], - bsf0_[i], - dt, - phiP, - magSf - ); - - // Check if the face is on processor patch and append it to - // the list if necessary - checkIfOnProcPatch(facei); - } - } - } - - // Synchronize processor patches - syncProcPatches(dVf_, phi_); - - writeIsoFaces(isoFacePts); - - Info<< "Number of isoAdvector surface cells = " - << returnReduce(nSurfaceCells, sumOp<label>()) << endl; -} - - -void Foam::isoAdvection::setCellVertexValues -( - const label celli, - const vectorField& cellNormalsIn -) -{ - const labelListList& cellPoints = mesh_.cellPoints(); - const vectorField& cellCentres = mesh_.cellCentres(); - const pointField& points = mesh_.points(); - const labelList& cp = cellPoints[celli]; - const point& cellCentre = cellCentres[celli]; - forAll(cp, vi) - { - const point& vertex = points[cp[vi]]; - ap_[cp[vi]] = (vertex - cellCentre) & cellNormalsIn[celli]; - } -} - - -void Foam::isoAdvection::normaliseAndSmooth -( - volVectorField& cellN -) -{ - const labelListList& cellPoints = mesh_.cellPoints(); - const vectorField& cellCentres = mesh_.cellCentres(); - const pointField& points = mesh_.points(); - - vectorField& cellNIn = cellN.primitiveFieldRef(); - cellNIn /= (mag(cellNIn) + SMALL); - vectorField vertexN(mesh_.nPoints(), Zero); - vertexN = volPointInterpolation::New(mesh_).interpolate(cellN); - vertexN /= (mag(vertexN) + SMALL); - // Interpolate vertex normals back to cells - forAll(cellNIn, celli) - { - const labelList& cp = cellPoints[celli]; - vector cellNi(Zero); - const point& cellCentre = cellCentres[celli]; - forAll(cp, pointI) - { - point vertex = points[cp[pointI]]; - scalar w = 1.0/mag(vertex - cellCentre); - cellNi += w*vertexN[cp[pointI]]; - } - cellNIn[celli] = cellNi/(mag(cellNi) + SMALL); - } -} - - -void Foam::isoAdvection::setDownwindFaces -( - const label celli, - DynamicLabelList& downwindFaces -) const -{ - DebugInFunction << endl; - - // Get necessary mesh data and cell information - const labelList& own = mesh_.faceOwner(); - const cellList& cells = mesh_.cells(); - const cell& c = cells[celli]; - - downwindFaces.clear(); - - // Check all faces of the cell - forAll(c, fi) - { - // Get face and corresponding flux - const label facei = c[fi]; - const scalar phi = faceValue(phi_, facei); - - if (own[facei] == celli) - { - if (phi > 10*SMALL) - { - downwindFaces.append(facei); - } - } - else if (phi < -10*SMALL) - { - downwindFaces.append(facei); - } - } - - downwindFaces.shrink(); -} - - -void Foam::isoAdvection::limitFluxes() -{ - DebugInFunction << endl; - - // Get time step size - const scalar dt = mesh_.time().deltaT().value(); - - volScalarField alphaNew(alpha1_ - fvc::surfaceIntegrate(dVf_)); - const scalar aTol = 1.0e-12; // Note: tolerances - scalar maxAlphaMinus1 = gMax(alphaNew) - 1; // max(alphaNew - 1); - scalar minAlpha = gMin(alphaNew); // min(alphaNew); - const label nUndershoots = 20; // sum(neg0(alphaNew + aTol)); - const label nOvershoots = 20; // sum(pos0(alphaNew - 1 - aTol)); - cellIsBounded_ = false; - - Info << "isoAdvection: Before conservative bounding: min(alpha) = " - << minAlpha << ", max(alpha) = 1 + " << maxAlphaMinus1 << endl; - - // Loop number of bounding steps - for (label n = 0; n < nAlphaBounds_; n++) - { - if (maxAlphaMinus1 > aTol) // Note: tolerances - { - DebugInfo << "Bound from above... " << endl; - -// scalarField& dVfcorrected = dVf_.primitiveFieldRef(); - - surfaceScalarField dVfcorrected("dVfcorrected", dVf_); - DynamicList<label> correctedFaces(3*nOvershoots); - boundFromAbove(alpha1In_, dVfcorrected, correctedFaces); - - forAll(correctedFaces, fi) - { - label facei = correctedFaces[fi]; - - // Change to treat boundaries consistently - setFaceValue(dVf_, facei, faceValue(dVfcorrected, facei)); - } - - syncProcPatches(dVf_, phi_); - } - - if (minAlpha < -aTol) // Note: tolerances - { - DebugInfo << "Bound from below... " << endl; - - scalarField alpha2(1.0 - alpha1In_); - surfaceScalarField dVfcorrected - ( - "dVfcorrected", - phi_*dimensionedScalar("dt", dimTime, dt) - dVf_ - ); -// dVfcorrected -= dVf_; // phi_ and dVf_ have same sign and dVf_ is - // the portion of phi_*dt that is water. - // If phi_ > 0 then dVf_ > 0 and mag(phi_*dt-dVf_) < mag(phi_*dt) as - // it should. - // If phi_ < 0 then dVf_ < 0 and mag(phi_*dt-dVf_) < mag(phi_*dt) as - // it should. - DynamicList<label> correctedFaces(3*nUndershoots); - boundFromAbove(alpha2, dVfcorrected, correctedFaces); - forAll(correctedFaces, fi) - { - label facei = correctedFaces[fi]; - - // Change to treat boundaries consistently - scalar phi = faceValue(phi_, facei); - scalar dVcorr = faceValue(dVfcorrected, facei); - setFaceValue(dVf_, facei, phi*dt - dVcorr); - } - - syncProcPatches(dVf_, phi_); - } - - if (debug) - { - // Check if still unbounded - scalarField alphaNew(alpha1In_ - fvc::surfaceIntegrate(dVf_)()); - label maxAlphaMinus1 = max(alphaNew - 1); - scalar minAlpha = min(alphaNew); - label nUndershoots = sum(neg0(alphaNew + aTol)); - label nOvershoots = sum(pos0(alphaNew - 1 - aTol)); - Info<< "After bounding number " << n + 1 << " of time " - << mesh_.time().value() << ":" << endl; - Info<< "nOvershoots = " << nOvershoots << " with max(alphaNew-1) = " - << maxAlphaMinus1 << " and nUndershoots = " << nUndershoots - << " with min(alphaNew) = " << minAlpha << endl; - } - } -} - - -void Foam::isoAdvection::boundFromAbove -( - const scalarField& alpha1, - surfaceScalarField& dVf, - DynamicList<label>& correctedFaces -) -{ - DebugInFunction << endl; - - correctedFaces.clear(); - scalar aTol = 10*SMALL; // Note: tolerances - - const scalarField& meshV = mesh_.cellVolumes(); - const scalar dt = mesh_.time().deltaTValue(); - - DynamicList<label> downwindFaces(10); - DynamicList<label> facesToPassFluidThrough(downwindFaces.size()); - DynamicList<scalar> dVfmax(downwindFaces.size()); - DynamicList<scalar> phi(downwindFaces.size()); - - // Loop through alpha cell centred field - forAll(alpha1, celli) - { - if (checkBounding_.test(celli)) - { - const scalar Vi = meshV[celli]; - scalar alpha1New = alpha1[celli] - netFlux(dVf, celli)/Vi; - scalar alphaOvershoot = alpha1New - 1.0; - scalar fluidToPassOn = alphaOvershoot*Vi; - label nFacesToPassFluidThrough = 1; - - bool firstLoop = true; - - // First try to pass surplus fluid on to neighbour cells that are - // not filled and to which dVf < phi*dt - while (alphaOvershoot > aTol && nFacesToPassFluidThrough > 0) - { - DebugInfo - << "\n\nBounding cell " << celli - << " with alpha overshooting " << alphaOvershoot - << endl; - - facesToPassFluidThrough.clear(); - dVfmax.clear(); - phi.clear(); - - cellIsBounded_.set(celli); - - // Find potential neighbour cells to pass surplus phase to - setDownwindFaces(celli, downwindFaces); - - scalar dVftot = 0; - nFacesToPassFluidThrough = 0; - - forAll(downwindFaces, fi) - { - const label facei = downwindFaces[fi]; - const scalar phif = faceValue(phi_, facei); - const scalar dVff = faceValue(dVf, facei); - const scalar maxExtraFaceFluidTrans = mag(phif*dt - dVff); - - // dVf has same sign as phi and so if phi>0 we have - // mag(phi_[facei]*dt) - mag(dVf[facei]) = phi_[facei]*dt - // - dVf[facei] - // If phi < 0 we have mag(phi_[facei]*dt) - - // mag(dVf[facei]) = -phi_[facei]*dt - (-dVf[facei]) > 0 - // since mag(dVf) < phi*dt - DebugInfo - << "downwindFace " << facei - << " has maxExtraFaceFluidTrans = " - << maxExtraFaceFluidTrans << endl; - - if (maxExtraFaceFluidTrans/Vi > aTol) - { -// if (maxExtraFaceFluidTrans/Vi > aTol && -// mag(dVfIn[facei])/Vi > aTol) //Last condition may be -// important because without this we will flux through uncut -// downwind faces - facesToPassFluidThrough.append(facei); - phi.append(phif); - dVfmax.append(maxExtraFaceFluidTrans); - dVftot += mag(phif*dt); - } - } - - DebugInfo - << "\nfacesToPassFluidThrough: " - << facesToPassFluidThrough << ", dVftot = " - << dVftot << " m3 corresponding to dalpha = " - << dVftot/Vi << endl; - - forAll(facesToPassFluidThrough, fi) - { - const label facei = facesToPassFluidThrough[fi]; - scalar fluidToPassThroughFace = - fluidToPassOn*mag(phi[fi]*dt)/dVftot; - - nFacesToPassFluidThrough += - pos0(dVfmax[fi] - fluidToPassThroughFace); - - fluidToPassThroughFace = - min(fluidToPassThroughFace, dVfmax[fi]); - - scalar dVff = faceValue(dVf, facei); - dVff += sign(phi[fi])*fluidToPassThroughFace; - setFaceValue(dVf, facei, dVff); - - if (firstLoop) - { - checkIfOnProcPatch(facei); - correctedFaces.append(facei); - } - } - - firstLoop = false; - alpha1New = alpha1[celli] - netFlux(dVf, celli)/Vi; - alphaOvershoot = alpha1New - 1.0; - fluidToPassOn = alphaOvershoot*Vi; - - DebugInfo - << "\nNew alpha for cell " << celli << ": " - << alpha1New << endl; - } - } - } - - DebugInfo << "correctedFaces = " << correctedFaces << endl; -} - - -Foam::scalar Foam::isoAdvection::netFlux -( - const surfaceScalarField& dVf, - const label celli -) const -{ - scalar dV = 0; - - // Get face indices - const cell& c = mesh_.cells()[celli]; - - // Get mesh data - const labelList& own = mesh_.faceOwner(); - - forAll(c, fi) - { - const label facei = c[fi]; - const scalar dVff = faceValue(dVf, facei); - - if (own[facei] == celli) - { - dV += dVff; - } - else - { - dV -= dVff; - } - } - - return dV; -} - - -void Foam::isoAdvection::syncProcPatches -( - surfaceScalarField& dVf, - const surfaceScalarField& phi -) -{ - const polyBoundaryMesh& patches = mesh_.boundaryMesh(); - - if (Pstream::parRun()) - { - PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking); - - // Send - forAll(procPatchLabels_, i) - { - const label patchi = procPatchLabels_[i]; - - const processorPolyPatch& procPatch = - refCast<const processorPolyPatch>(patches[patchi]); - - UOPstream toNbr(procPatch.neighbProcNo(), pBufs); - const scalarField& pFlux = dVf.boundaryField()[patchi]; - - const List<label>& surfCellFacesOnProcPatch = - surfaceCellFacesOnProcPatches_[patchi]; - - const UIndirectList<scalar> dVfPatch - ( - pFlux, - surfCellFacesOnProcPatch - ); - - toNbr << surfCellFacesOnProcPatch << dVfPatch; - } - - pBufs.finishedSends(); - - - // Receive and combine - forAll(procPatchLabels_, patchLabeli) - { - const label patchi = procPatchLabels_[patchLabeli]; - - const processorPolyPatch& procPatch = - refCast<const processorPolyPatch>(patches[patchi]); - - UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs); - List<label> faceIDs; - List<scalar> nbrdVfs; - - fromNeighb >> faceIDs >> nbrdVfs; - - if (debug) - { - Pout<< "Received at time = " << mesh_.time().value() - << ": surfCellFacesOnProcPatch = " << faceIDs << nl - << "Received at time = " << mesh_.time().value() - << ": dVfPatch = " << nbrdVfs << endl; - } - - // Combine fluxes - scalarField& localFlux = dVf.boundaryFieldRef()[patchi]; - - forAll(faceIDs, i) - { - const label facei = faceIDs[i]; - localFlux[facei] = - nbrdVfs[i]; - if (debug && mag(localFlux[facei] + nbrdVfs[i]) > 10*SMALL) - { - Pout<< "localFlux[facei] = " << localFlux[facei] - << " and nbrdVfs[i] = " << nbrdVfs[i] - << " for facei = " << facei << endl; - } - } - } - - if (debug) - { - // Write out results for checking - forAll(procPatchLabels_, patchLabeli) - { - const label patchi = procPatchLabels_[patchLabeli]; - const scalarField& localFlux = dVf.boundaryField()[patchi]; - Pout<< "time = " << mesh_.time().value() << ": localFlux = " - << localFlux << endl; - } - } - - // Reinitialising list used for minimal parallel communication - forAll(surfaceCellFacesOnProcPatches_, patchi) - { - surfaceCellFacesOnProcPatches_[patchi].clear(); - } - } -} - - -void Foam::isoAdvection::checkIfOnProcPatch(const label facei) -{ - if (!mesh_.isInternalFace(facei)) - { - const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); - const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()]; - - if (isA<processorPolyPatch>(pbm[patchi]) && pbm[patchi].size()) - { - const label patchFacei = pbm[patchi].whichFace(facei); - surfaceCellFacesOnProcPatches_[patchi].append(patchFacei); - } - } -} - - -void Foam::isoAdvection::advect() -{ - DebugInFunction << endl; - - scalar advectionStartTime = mesh_.time().elapsedCpuTime(); - - // Initialising dVf with upwind values - // i.e. phi[facei]*alpha1[upwindCell[facei]]*dt - dVf_ = upwind<scalar>(mesh_, phi_).flux(alpha1_)*mesh_.time().deltaT(); - - // Do the isoAdvection on surface cells - timeIntegratedFlux(); - - // Adjust alpha for mesh motion - if (mesh_.moving()) - { - alpha1In_ *= (mesh_.Vsc0()/mesh_.Vsc()); - } - - // Adjust dVf for unbounded cells - limitFluxes(); - - // Advect the free surface - alpha1_ -= fvc::surfaceIntegrate(dVf_); - alpha1_.correctBoundaryConditions(); - - scalar maxAlphaMinus1 = gMax(alpha1In_) - 1; - scalar minAlpha = gMin(alpha1In_); - Info << "isoAdvection: After conservative bounding: min(alpha) = " - << minAlpha << ", max(alpha) = 1 + " << maxAlphaMinus1 << endl; - - // Apply non-conservative bounding mechanisms (clipping and snapping) - // Note: We should be able to write out alpha before this is done! - applyBruteForceBounding(); - - // Write surface cell set and bound cell set if required by user - writeSurfaceCells(); - writeBoundedCells(); - - advectionTime_ += (mesh_.time().elapsedCpuTime() - advectionStartTime); - Info << "isoAdvection: time consumption = " - << label(100*advectionTime_/(mesh_.time().elapsedCpuTime() + SMALL)) - << "%" << endl; -} - - -void Foam::isoAdvection::applyBruteForceBounding() -{ - bool alpha1Changed = false; - - scalar snapAlphaTol = dict_.getOrDefault<scalar>("snapTol", 0); - if (snapAlphaTol > 0) - { - alpha1_ = - alpha1_ - *pos0(alpha1_ - snapAlphaTol) - *neg0(alpha1_ - (1.0 - snapAlphaTol)) - + pos0(alpha1_ - (1.0 - snapAlphaTol)); - - alpha1Changed = true; - } - - if (dict_.getOrDefault("clip", true)) - { - alpha1_ = min(scalar(1), max(scalar(0), alpha1_)); - alpha1Changed = true; - } - - if (alpha1Changed) - { - alpha1_.correctBoundaryConditions(); - } -} - - -void Foam::isoAdvection::writeSurfaceCells() const -{ - if (!mesh_.time().writeTime()) return; - - if (dict_.getOrDefault("writeSurfCells", false)) - { - cellSet cSet - ( - IOobject - ( - "surfCells", - mesh_.time().timeName(), - mesh_, - IOobject::NO_READ - ) - ); - - cSet.insert(surfCells_); - - cSet.write(); - } -} - - -void Foam::isoAdvection::writeBoundedCells() const -{ - if (!mesh_.time().writeTime()) return; - - if (dict_.getOrDefault("writeBoundedCells", false)) - { - cellSet cSet - ( - IOobject - ( - "boundedCells", - mesh_.time().timeName(), - mesh_, - IOobject::NO_READ - ) - ); - - for (const label celli : cellIsBounded_) - { - cSet.insert(celli); - } - - cSet.write(); - } -} - - -void Foam::isoAdvection::writeIsoFaces -( - const DynamicList<List<point>>& faces -) const -{ - - if (!writeIsoFacesToFile_ || !mesh_.time().writeTime()) return; - - // Writing isofaces to obj file for inspection, e.g. in paraview - const fileName outputFile - ( - mesh_.time().globalPath() - / "isoFaces" - / word::printf("isoFaces_%012d.obj", mesh_.time().timeIndex()) - ); - - if (Pstream::parRun()) - { - // Collect points from all the processors - List<DynamicList<List<point>>> allProcFaces(Pstream::nProcs()); - allProcFaces[Pstream::myProcNo()] = faces; - Pstream::gatherList(allProcFaces); - - if (Pstream::master()) - { - mkDir(outputFile.path()); - OBJstream os(outputFile); - Info<< nl << "isoAdvection: writing iso faces to file: " - << os.name() << nl << endl; - - face f; - forAll(allProcFaces, proci) - { - const DynamicList<List<point>>& procFacePts = - allProcFaces[proci]; - - forAll(procFacePts, i) - { - const List<point>& facePts = procFacePts[i]; - - if (facePts.size() != f.size()) - { - f = face(identity(facePts.size())); - } - - os.write(f, facePts, false); - } - } - } - } - else - { - mkDir(outputFile.path()); - OBJstream os(outputFile); - Info<< nl << "isoAdvection: writing iso faces to file: " - << os.name() << nl << endl; - - face f; - forAll(faces, i) - { - const List<point>& facePts = faces[i]; - - if (facePts.size() != f.size()) - { - f = face(identity(facePts.size())); - } - - os.write(f, facePts, false); - } - } -} - - -// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvectionTemplates.C b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvectionTemplates.C deleted file mode 100644 index e8c506deff8686afcc71b0b5c013fdd23967d9bb..0000000000000000000000000000000000000000 --- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvectionTemplates.C +++ /dev/null @@ -1,111 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2016-2017 DHI - Copyright (C) 2016-2017 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "isoAdvection.H" - -// ************************************************************************* // - -template<typename Type> -Type Foam::isoAdvection::faceValue -( - const GeometricField<Type, fvsPatchField, surfaceMesh>& f, - const label facei -) const -{ - if (mesh_.isInternalFace(facei)) - { - return f.primitiveField()[facei]; - } - else - { - const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); - - // Boundary face. Find out which face of which patch - const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()]; - - if (patchi < 0 || patchi >= pbm.size()) - { - FatalErrorInFunction - << "Cannot find patch for face " << facei - << abort(FatalError); - } - - // Handle empty patches - const polyPatch& pp = pbm[patchi]; - if (isA<emptyPolyPatch>(pp) || pp.empty()) - { - return pTraits<Type>::zero; - } - - const label patchFacei = pp.whichFace(facei); - return f.boundaryField()[patchi][patchFacei]; - } -} - - -template<typename Type> -void Foam::isoAdvection::setFaceValue -( - GeometricField<Type, fvsPatchField, surfaceMesh>& f, - const label facei, - const Type& value -) const -{ - if (mesh_.isInternalFace(facei)) - { - f.primitiveFieldRef()[facei] = value; - } - else - { - const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); - - // Boundary face. Find out which face of which patch - const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()]; - - if (patchi < 0 || patchi >= pbm.size()) - { - FatalErrorInFunction - << "Cannot find patch for face " << facei - << abort(FatalError); - } - - // Handle empty patches - const polyPatch& pp = pbm[patchi]; - if (isA<emptyPolyPatch>(pp) || pp.empty()) - { - return; - } - - const label patchFacei = pp.whichFace(facei); - - f.boundaryFieldRef()[patchi][patchFacei] = value; - } -} - - -// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.C b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.C deleted file mode 100644 index 80e10d80f65c892c5e4455d8e7107912adc64ddd..0000000000000000000000000000000000000000 --- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.C +++ /dev/null @@ -1,725 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2016-2017 DHI - Copyright (C) 2018 Johan Roenby - Copyright (C) 2016-2019 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "isoCutCell.H" -#include "scalarMatrices.H" -#include "volFields.H" -#include "surfaceFields.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -int Foam::isoCutCell::debug = 0; - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::isoCutCell::isoCutCell(const fvMesh& mesh, scalarField& f) -: - mesh_(mesh), - cellI_(-1), - f_(f), - isoValue_(0), - isoCutFace_(isoCutFace(mesh_, f_)), - isoCutFaces_(10), - isoCutFacePoints_(10), - isoCutFaceCentres_(10), - isoCutFaceAreas_(10), - isoFaceEdges_(10), - isoFacePoints_(10), - isoFaceCentre_(Zero), - isoFaceArea_(Zero), - subCellCentre_(Zero), - subCellVolume_(-10), - VOF_(-10), - fullySubFaces_(10), - cellStatus_(-1), - subCellCentreAndVolumeCalculated_(false), - isoFaceCentreAndAreaCalculated_(false) -{ - clearStorage(); -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -void Foam::isoCutCell::calcSubCellCentreAndVolume() -{ - if (cellStatus_ == 0) - { - subCellCentre_ = vector::zero; - subCellVolume_ = 0.0; - - // Estimate the approximate cell centre as the average of face centres - label nCellFaces(1 + isoCutFaceCentres_.size() + fullySubFaces_.size()); - vector cEst = isoFaceCentre_ + sum(isoCutFaceCentres_); - forAll(fullySubFaces_, facei) - { - cEst += mesh_.faceCentres()[fullySubFaces_[facei]]; - } - cEst /= scalar(nCellFaces); - - - // Contribution to subcell centre and volume from isoface - const scalar pyr3Vol0 = - max(mag(isoFaceArea_ & (isoFaceCentre_ - cEst)), VSMALL); - - // Calculate face-pyramid centre - const vector pc0 = 0.75*isoFaceCentre_ + 0.25*cEst; - - // Accumulate volume-weighted face-pyramid centre - subCellCentre_ += pyr3Vol0*pc0; - - // Accumulate face-pyramid volume - subCellVolume_ += pyr3Vol0; - - // Contribution to subcell centre and volume from cut faces - forAll(isoCutFaceCentres_, facei) - { - // Calculate 3*face-pyramid volume - scalar pyr3Vol = - max - ( - mag - ( - isoCutFaceAreas_[facei] - & (isoCutFaceCentres_[facei] - cEst) - ), - VSMALL - ); - - // Calculate face-pyramid centre - vector pc = 0.75*isoCutFaceCentres_[facei] + 0.25*cEst; - - // Accumulate volume-weighted face-pyramid centre - subCellCentre_ += pyr3Vol*pc; - - // Accumulate face-pyramid volume - subCellVolume_ += pyr3Vol; - } - - // Contribution to subcell centre and volume from fully submerged faces - forAll(fullySubFaces_, i) - { - const label facei = fullySubFaces_[i]; - const point& fCentre = mesh_.faceCentres()[facei]; - const vector& fArea = mesh_.faceAreas()[facei]; - - // Calculate 3*face-pyramid volume - scalar pyr3Vol = max(mag(fArea & (fCentre - cEst)), VSMALL); - - // Calculate face-pyramid centre - vector pc = 0.75*fCentre + 0.25*cEst; - - // Accumulate volume-weighted face-pyramid centre - subCellCentre_ += pyr3Vol*pc; - - // Accumulate face-pyramid volume - subCellVolume_ += pyr3Vol; - } - - subCellCentre_ /= subCellVolume_; - subCellVolume_ /= scalar(3); - VOF_ = subCellVolume_/mesh_.cellVolumes()[cellI_]; - - subCellCentreAndVolumeCalculated_ = true; - - if (debug) - { - vector sumSf = isoFaceArea_; - scalar sumMagSf = mag(isoFaceArea_); - forAll(isoCutFaceCentres_, facei) - { - sumSf += isoCutFaceAreas_[facei]; - sumMagSf += mag(isoCutFaceAreas_[facei]); - } - forAll(fullySubFaces_, facei) - { - sumSf += mesh_.faceAreas()[fullySubFaces_[facei]]; - sumMagSf += mag(isoCutFaceAreas_[facei]); - } - if (mag(sumSf) > 1e-10) - { - Pout<< "Warninig: mag(sumSf)/magSumSf = " - << mag(sumSf)/sumMagSf << " for surface cell" - << cellI_ << endl; - } - } - } - else if (cellStatus_ == 1) - { - // Cell fully above isosurface - subCellCentre_ = vector::zero; - subCellVolume_ = 0; - VOF_ = 0; - } - else if (cellStatus_ == -1) - { - // Cell fully below isosurface - subCellCentre_ = mesh_.cellCentres()[cellI_]; - subCellVolume_ = mesh_.cellVolumes()[cellI_]; - VOF_ = 1; - } -} - - -void Foam::isoCutCell::calcIsoFaceCentreAndArea() -{ - // Initial guess of face centre from edge points - point fCentre(Zero); - label nEdgePoints(0); - forAll(isoFaceEdges_, ei) - { - DynamicList<point>& edgePoints = isoFaceEdges_[ei]; - forAll(edgePoints, pi) - { - fCentre += edgePoints[pi]; - nEdgePoints++; - } - } - - if (nEdgePoints > 0) - { - fCentre /= nEdgePoints; - } - else - { - DebugPout << "Warning: nEdgePoints = 0 for cell " << cellI_ << endl; - } - - vector sumN(Zero); - scalar sumA(0); - vector sumAc(Zero); - - forAll(isoFaceEdges_, ei) - { - const DynamicList<point>& edgePoints = isoFaceEdges_[ei]; - const label nPoints = edgePoints.size(); - for (label pi = 0; pi < nPoints-1; pi++) - { - const point& nextPoint = edgePoints[pi + 1]; - - vector c = edgePoints[pi] + nextPoint + fCentre; - vector n = (nextPoint - edgePoints[pi])^(fCentre - edgePoints[pi]); - scalar a = mag(n); - - // Edges may have different orientation - sumN += Foam::sign(n & sumN)*n; - sumA += a; - sumAc += a*c; - } - } - - // This is to deal with zero-area faces. Mark very small faces - // to be detected in e.g., processorPolyPatch. - if (sumA < ROOTVSMALL) - { - isoFaceCentre_ = fCentre; - isoFaceArea_ = vector::zero; - } - else - { - isoFaceCentre_ = sumAc/sumA/scalar(3); - isoFaceArea_ = 0.5*sumN; - } - - - // Check isoFaceArea_ direction and change if not pointing out of subcell - if ((isoFaceArea_ & (isoFaceCentre_ - subCellCentre())) < 0) - { - isoFaceArea_ *= (-1); - } - - isoFaceCentreAndAreaCalculated_ = true; -} - - -void Foam::isoCutCell::calcIsoFacePointsFromEdges() -{ - DebugPout - << "Enter calcIsoFacePointsFromEdges() with isoFaceArea_ = " - << isoFaceArea_ << " and isoFaceCentre_ = " << isoFaceCentre_ - << " and isoFaceEdges_ = " << isoFaceEdges_ << endl; - - // Defining local coordinates with zhat along isoface normal and xhat from - // isoface centre to first point in isoFaceEdges_ - const vector zhat = normalised(isoFaceArea_); - vector xhat = isoFaceEdges_[0][0] - isoFaceCentre_; - xhat = (xhat - (xhat & zhat)*zhat); - xhat.normalise(); - vector yhat = normalised(zhat ^ xhat); - - DebugPout << "Calculated local coordinates" << endl; - - // Calculating isoface point angles in local coordinates - DynamicList<point> unsortedIsoFacePoints(3*isoFaceEdges_.size()); - DynamicList<scalar> unsortedIsoFacePointAngles(3*isoFaceEdges_.size()); - forAll(isoFaceEdges_, ei) - { - const DynamicList<point>& edgePoints = isoFaceEdges_[ei]; - forAll(edgePoints, pi) - { - const point& p = edgePoints[pi]; - unsortedIsoFacePoints.append(p); - unsortedIsoFacePointAngles.append - ( - Foam::atan2 - ( - ((p - isoFaceCentre_) & yhat), - ((p - isoFaceCentre_) & xhat) - ) - ); - } - } - - DebugPout<< "Calculated isoFace point angles" << endl; - - // Sorting isoface points by angle and inserting into isoFacePoints_ - labelList order(sortedOrder(unsortedIsoFacePointAngles)); - isoFacePoints_.append(unsortedIsoFacePoints[order[0]]); - for (label pi = 1; pi < order.size(); pi++) - { - if - ( - mag - ( - unsortedIsoFacePointAngles[order[pi]] - -unsortedIsoFacePointAngles[order[pi-1]] - ) > 1e-8 - ) - { - isoFacePoints_.append(unsortedIsoFacePoints[order[pi]]); - } - } - - DebugPout<< "Sorted isoface points by angle" << endl; -} - - -Foam::label Foam::isoCutCell::calcSubCell -( - const label celli, - const scalar isoValue -) -{ - // Populate isoCutFaces_, isoCutFacePoints_, fullySubFaces_, isoFaceCentre_ - // and isoFaceArea_. - - clearStorage(); - cellI_ = celli; - isoValue_ = isoValue; - const cell& c = mesh_.cells()[celli]; - - forAll(c, fi) - { - const label facei = c[fi]; - - const label faceStatus = isoCutFace_.calcSubFace(facei, isoValue_); - - if (faceStatus == 0) - { - // Face is cut - isoCutFacePoints_.append(isoCutFace_.subFacePoints()); - isoCutFaceCentres_.append(isoCutFace_.subFaceCentre()); - isoCutFaceAreas_.append(isoCutFace_.subFaceArea()); - isoFaceEdges_.append(isoCutFace_.surfacePoints()); - } - else if (faceStatus == -1) - { - // Face fully below - fullySubFaces_.append(facei); - } - } - - if (isoCutFacePoints_.size()) - { - // Cell cut at least at one face - cellStatus_ = 0; - calcIsoFaceCentreAndArea(); - - // In the rare but occurring cases where a cell is only touched at a - // point or a line the isoFaceArea_ will have zero length and here the - // cell should be treated as either completely empty or full. - if (mag(isoFaceArea_) < 10*SMALL) - { - if (fullySubFaces_.empty()) - { - // Cell fully above isosurface - cellStatus_ = 1; - } - else - { - // Cell fully below isosurface - cellStatus_ = -1; - } - } - } - else if (fullySubFaces_.empty()) - { - // Cell fully above isosurface - cellStatus_ = 1; - } - else - { - // Cell fully below isosurface - cellStatus_ = -1; - } - - return cellStatus_; -} - - -const Foam::point& Foam::isoCutCell::subCellCentre() -{ - if (!subCellCentreAndVolumeCalculated_) - { - calcSubCellCentreAndVolume(); - } - - return subCellCentre_; -} - - -Foam::scalar Foam::isoCutCell::subCellVolume() -{ - if (!subCellCentreAndVolumeCalculated_) - { - calcSubCellCentreAndVolume(); - } - - return subCellVolume_; -} - - -const Foam::DynamicList<Foam::point>& Foam::isoCutCell::isoFacePoints() -{ - if (cellStatus_ == 0 && isoFacePoints_.size() == 0) - { - calcIsoFacePointsFromEdges(); - } - - return isoFacePoints_; -} - - -const Foam::point& Foam::isoCutCell::isoFaceCentre() -{ - if (!isoFaceCentreAndAreaCalculated_) - { - calcIsoFaceCentreAndArea(); - } - - return isoFaceCentre_; -} - - -const Foam::vector& Foam::isoCutCell::isoFaceArea() -{ - if (!isoFaceCentreAndAreaCalculated_) - { - calcIsoFaceCentreAndArea(); - } - - return isoFaceArea_; -} - - -Foam::scalar Foam::isoCutCell::volumeOfFluid() -{ - if (!subCellCentreAndVolumeCalculated_) - { - calcSubCellCentreAndVolume(); - } - - return VOF_; -} - - -Foam::scalar Foam::isoCutCell::isoValue() const -{ - return isoValue_; -} - - -void Foam::isoCutCell::clearStorage() -{ - cellI_ = -1; - isoValue_ = 0; - isoCutFace_.clearStorage(); - isoCutFaces_.clear(); - isoCutFacePoints_.clear(); - isoCutFaceCentres_.clear(); - isoCutFaceAreas_.clear(); - isoFaceEdges_.clear(); - isoFacePoints_.clear(); - isoFaceCentre_ = vector::zero; - isoFaceArea_ = vector::zero; - subCellCentre_ = vector::zero; - subCellVolume_ = -10; - VOF_ = -10; - fullySubFaces_.clear(); - cellStatus_ = -1; - subCellCentreAndVolumeCalculated_ = false; - isoFaceCentreAndAreaCalculated_ = false; -} - - -Foam::label Foam::isoCutCell::vofCutCell -( - const label celli, - const scalar alpha1, - const scalar tol, - const label maxIter -) -{ - DebugInFunction - << "vofCutCell for cell " << celli << " with alpha1 = " - << alpha1 << " ------" << endl; - - // Finding cell vertex extremum values - const labelList& pLabels = mesh_.cellPoints(celli); - scalarField fvert(pLabels.size()); - forAll(pLabels, pi) - { - fvert[pi] = f_[pLabels[pi]]; - } - labelList order(sortedOrder(fvert)); - scalar f1 = fvert[order.first()]; - scalar f2 = fvert[order.last()]; - - DebugPout << "fvert = " << fvert << ", and order = " << order << endl; - - // Handling special case where method is handed an almost full/empty cell - if (alpha1 < tol) - { - return calcSubCell(celli, f2); - } - else if (1 - alpha1 < tol) - { - return calcSubCell(celli, f1); - } - - // Finding the two vertices inbetween which the isovalue giving alpha1 lies - label L1 = 0; - label L2 = fvert.size() - 1; - scalar a1 = 1; - scalar a2 = 0; - scalar L3, f3, a3; - - while (L2 - L1 > 1) - { - L3 = round(0.5*(L1 + L2)); - f3 = fvert[order[L3]]; - calcSubCell(celli, f3); - a3 = volumeOfFluid(); - if (a3 > alpha1) - { - L1 = L3; f1 = f3; a1 = a3; - } - else if (a3 < alpha1) - { - L2 = L3; f2 = f3; a2 = a3; - } - } - - if (mag(f1 - f2) < 10*SMALL) - { - DebugPout<< "Warning: mag(f1 - f2) < 10*SMALL" << endl; - return calcSubCell(celli, f1); - } - - if (mag(a1 - a2) < tol) - { - DebugPout<< "Warning: mag(a1 - a2) < tol for cell " << celli << endl; - return calcSubCell(celli, 0.5*(f1 + f2)); - } - - // Now we know that a(f) = alpha1 is to be found on the f interval - // [f1, f2], i.e. alpha1 will be in the interval [a2,a1] - DebugPout - << "L1 = " << L1 << ", f1 = " << f1 << ", a1 = " << a1 << nl - << "L2 = " << L2 << ", f2 = " << f2 << ", a2 = " << a2 << endl; - - - // Finding coefficients in 3 deg polynomial alpha(f) from 4 solutions - - // Finding 2 additional points on 3 deg polynomial - f3 = f1 + (f2 - f1)/scalar(3); - calcSubCell(celli, f3); - a3 = volumeOfFluid(); - - scalar f4 = f1 + (f2 - f1)*scalar(2)/scalar(3); - calcSubCell(celli, f4); - scalar a4 = volumeOfFluid(); - - // Building and solving Vandermonde matrix equation - scalarField a(4), f(4), C(4); - { - a[0] = a1, f[0] = 0; - a[1] = a3, f[1] = (f3 - f1)/(f2 - f1); - a[2] = a4, f[2] = (f4 - f1)/(f2 - f1); - a[3] = a2, f[3] = 1; - scalarSquareMatrix M(4); - forAll(f, i) - { - forAll(f, j) - { - M[i][j] = pow(f[i], 3 - j); - } - } - - // C holds the 4 polynomial coefficients - C = a; - LUsolve(M, C); - } - - // Finding root with Newton method - f3 = f[1]; a3 = a[1]; - label nIter = 0; - scalar res = mag(a3 - alpha1); - while (res > tol && nIter < 10*maxIter) - { - f3 -= - (C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3] - alpha1) - /(3*C[0]*sqr(f3) + 2*C[1]*f3 + C[2]); - a3 = C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3]; - res = mag(a3 - alpha1); - nIter++; - } - // Scaling back to original range - f3 = f3*(f2 - f1) + f1; - - // Check result - calcSubCell(celli, f3); - const scalar VOF = volumeOfFluid(); - res = mag(VOF - alpha1); - - if (res > tol) - { - DebugPout - << "Newton obtained f3 = " << f3 << " and a3 = " << a3 - << " with mag(a3-alpha1) = " << mag(a3-alpha1) - << " but calcSubCell(celli,f3) gives VOF = " << VOF << nl - << "M(f)*C = a with " << nl - << "f_scaled = " << f << nl - << "f = " << f*(f2 - f1) + f1 << nl - << "a = " << a << nl - << "C = " << C << endl; - } - else - { - DebugPout<< "Newton did the job" << endl; - return cellStatus_; - } - - // If tolerance not met use the secant method with f3 as a hopefully very - // good initial guess to crank res the last piece down below tol - // Note: This is expensive because subcell is recalculated every iteration - scalar x2 = f3; - scalar g2 = VOF - alpha1; - scalar x1 = max(1e-3*(f2 - f1), 100*SMALL); - x1 = min(max(x1, f1), f2); - calcSubCell(celli, x1); - scalar g1 = volumeOfFluid() - alpha1; - - nIter = 0; - scalar g0(0), x0(0); - while (res > tol && nIter < maxIter && g1 != g2) - { - x0 = (x2*g1 - x1*g2)/(g1 - g2); - calcSubCell(celli, x0); - g0 = volumeOfFluid() - alpha1; - res = mag(g0); - x2 = x1; g2 = g1; - x1 = x0; g1 = g0; - nIter++; - } - - if (debug) - { - if (res < tol) - { - Pout<< "Bisection finished the job in " << nIter << " iterations." - << endl; - } - else - { - Pout<< "Warning: Bisection not converged " << endl; - Pout<< "Leaving vofCutCell with f3 = " << f3 << " giving a3 = " - << a3 << " so alpha1 - a3 = " << alpha1 - a3 << endl; - } - } - - return cellStatus_; -} - - -void Foam::isoCutCell::volumeOfFluid -( - volScalarField& alpha1, - const scalar f0 -) -{ - // Setting internal field - scalarField& alphaIn = alpha1; - forAll(alphaIn, celli) - { - const label cellStatus = calcSubCell(celli, f0); - if (cellStatus != 1) - { - // If cell not entirely above isosurface - alphaIn[celli] = volumeOfFluid(); - } - } - - // Setting boundary alpha1 values - forAll(mesh_.boundary(), patchi) - { - if (mesh_.boundary()[patchi].size() > 0) - { - const label start = mesh_.boundary()[patchi].patch().start(); - scalarField& alphap = alpha1.boundaryFieldRef()[patchi]; - const scalarField& magSfp = mesh_.magSf().boundaryField()[patchi]; - - forAll(alphap, patchFacei) - { - const label facei = patchFacei + start; - const label faceStatus = isoCutFace_.calcSubFace(facei, f0); - - if (faceStatus != 1) - { - // Face not entirely above isosurface - alphap[patchFacei] = - mag(isoCutFace_.subFaceArea())/magSfp[patchFacei]; - } - } - } - } -} - - -// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.C b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.C deleted file mode 100644 index 6e5586946512fa2eef9ef94c3081492aa3ab593c..0000000000000000000000000000000000000000 --- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.C +++ /dev/null @@ -1,773 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2016-2017 DHI - Copyright (C) 2018 Johan Roenby - Copyright (C) 2016-2019 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -\*---------------------------------------------------------------------------*/ - -#include "isoCutFace.H" - -// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // - -int Foam::isoCutFace::debug = 0; - -// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // - -Foam::isoCutFace::isoCutFace -( - const fvMesh& mesh, - scalarField& f -) -: - mesh_(mesh), - f_(f), - firstEdgeCut_(-1), - lastEdgeCut_(-1), - firstFullySubmergedPoint_(-1), - nFullySubmergedPoints_(0), - subFaceCentre_(Zero), - subFaceArea_(Zero), - subFacePoints_(10), - surfacePoints_(4), - subFaceCentreAndAreaIsCalculated_(false) -{ - clearStorage(); -} - - -// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // - -void Foam::isoCutFace::calcSubFaceCentreAndArea() -{ - const label nPoints = subFacePoints_.size(); - - // If the face is a triangle, do a direct calculation for efficiency - // and to avoid round-off error-related problems - if (nPoints == 3) - { - subFaceCentre_ = sum(subFacePoints_)/scalar(3); - subFaceArea_ = - 0.5 - *( - (subFacePoints_[1] - subFacePoints_[0]) - ^(subFacePoints_[2] - subFacePoints_[0]) - ); - } - else if (nPoints > 0) - { - vector sumN(Zero); - scalar sumA(0.0); - vector sumAc(Zero); - const point fCentre = sum(subFacePoints_)/scalar(nPoints); - - for (label pi = 0; pi < nPoints; pi++) - { - const point& nextPoint = subFacePoints_[subFacePoints_.fcIndex(pi)]; - - vector c = subFacePoints_[pi] + nextPoint + fCentre; - vector n = - (nextPoint - subFacePoints_[pi])^(fCentre - subFacePoints_[pi]); - scalar a = magSqr(n); - - sumN += n; - sumA += a; - sumAc += a*c; - } - - // This is to deal with zero-area faces. Mark very small faces - // to be detected in e.g., processorPolyPatch. - if (sumA < ROOTVSMALL) - { - subFaceCentre_ = fCentre; - subFaceArea_ = vector::zero; - } - else - { - subFaceCentre_ = (1.0/3.0)*sumAc/sumA; - subFaceArea_ = 0.5*sumN; - } - } - - subFaceCentreAndAreaIsCalculated_ = true; -} - - -Foam::label Foam::isoCutFace::calcSubFace -( - const scalar isoValue, - const pointField& points, - const scalarField& f, - const labelList& pLabels -) -{ - // Face status set to one of the values: - // -1: face is fully below the isosurface - // 0: face is cut, i.e. has values larger and smaller than isoValue - // +1: face is fully above the isosurface - label faceStatus; - - scalar f1 = f[pLabels[0]]; - - // If vertex values are very close to isoValue lift them slightly to avoid - // dealing with the many special cases of a face being touched either at a - // single point, along an edge, or the entire face being on the surface. - if (mag(f1 - isoValue) < 10*SMALL) - { - f1 += sign(f1 - isoValue)*10*SMALL; - } - - // Finding cut edges, the point along them where they are cut, and all fully - // submerged face points. - forAll(pLabels, pi) - { - label pl2 = pLabels[pLabels.fcIndex(pi)]; - scalar f2 = f[pl2]; - if (mag(f2 - isoValue) < 10*SMALL) - { - f2 += sign(f2 - isoValue)*10*SMALL; - } - - if (f1 > isoValue) - { - nFullySubmergedPoints_ += 1; - - if (f2 < isoValue) - { - lastEdgeCut_ = (isoValue - f1)/(f2 - f1); - } - } - else if (f1 < isoValue && f2 > isoValue) - { - if (firstFullySubmergedPoint_ == -1) - { - firstFullySubmergedPoint_ = pLabels.fcIndex(pi); - - firstEdgeCut_ = (isoValue - f1)/(f2 - f1); - } - else - { - if (debug) - { - const face fl(pLabels); - - WarningInFunction - << "More than two face cuts for face " << fl - << endl; - - Pout<< "Face values: f-isoValue = " << endl; - forAll(fl, fpi) - { - Pout<< f[fl[fpi]] - isoValue << " "; - } - Pout<< " " << endl; - } - } - } - f1 = f2; - } - - if (firstFullySubmergedPoint_ != -1) - { - // Face is cut - faceStatus = 0; - subFacePoints(points, pLabels); - } - else if (f1 < isoValue) - { - // Face entirely above isosurface - faceStatus = 1; - } - else - { - // Face entirely below isosurface - faceStatus = -1; - } - - return faceStatus; -} - - -void Foam::isoCutFace::subFacePoints -( - const pointField& points, - const labelList& pLabels -) -{ - const label nPoints = pLabels.size(); - - surfacePoints(points, pLabels); - - forAll(surfacePoints_, pi) - { - subFacePoints_.append(surfacePoints_[pi]); - } - - for (label pi = 0; pi < nFullySubmergedPoints_; pi++) - { - subFacePoints_.append - ( - points[pLabels[(firstFullySubmergedPoint_ + pi) % nPoints]] - ); - } -} - - -void Foam::isoCutFace::surfacePoints -( - const pointField& points, - const labelList& pLabels -) -{ - const label nPoints = pLabels.size(); - - const label n = firstFullySubmergedPoint_ + nFullySubmergedPoints_; - - label pl1 = pLabels[(n - 1) % nPoints]; - - label pl2 = pLabels[n % nPoints]; - - surfacePoints_.append - ( - points[pl1] + lastEdgeCut_*(points[pl2] - points[pl1]) - ); - - pl1 = pLabels[(firstFullySubmergedPoint_ - 1 + nPoints) % nPoints]; - pl2 = pLabels[firstFullySubmergedPoint_]; - - surfacePoints_.append - ( - points[pl1] + firstEdgeCut_*(points[pl2] - points[pl1]) - ); -} - - -// * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * * // - -Foam::label Foam::isoCutFace::calcSubFace -( - const label faceI, - const scalar isoValue -) -{ - clearStorage(); - const labelList& pLabels = mesh_.faces()[faceI]; - const pointField& points = mesh_.points(); - return calcSubFace(isoValue, points, f_, pLabels); -} - - -Foam::label Foam::isoCutFace::calcSubFace -( - const pointField& points, - const scalarField& f, - const scalar isoValue -) -{ - clearStorage(); - const labelList pLabels(identity(f.size())); - return calcSubFace(isoValue, points, f, pLabels); -} - - -const Foam::point& Foam::isoCutFace::subFaceCentre() -{ - if (!subFaceCentreAndAreaIsCalculated_) - { - calcSubFaceCentreAndArea(); - } - return subFaceCentre_; -} - - -const Foam::vector& Foam::isoCutFace::subFaceArea() -{ - if (!subFaceCentreAndAreaIsCalculated_) - { - calcSubFaceCentreAndArea(); - } - return subFaceArea_; -} - - -const Foam::DynamicList<Foam::point>& Foam::isoCutFace::subFacePoints() const -{ - return subFacePoints_; -} - - -const Foam::DynamicList<Foam::point>& Foam::isoCutFace::surfacePoints() const -{ - return surfacePoints_; -} - - -void Foam::isoCutFace::clearStorage() -{ - firstEdgeCut_ = -1; - lastEdgeCut_ = -1; - firstFullySubmergedPoint_ = -1; - nFullySubmergedPoints_ = 0; - subFaceCentre_ = vector::zero; - subFaceArea_ = vector::zero; - subFacePoints_.clear(); - surfacePoints_.clear(); - subFaceCentreAndAreaIsCalculated_ = false; -} - - -Foam::scalar Foam::isoCutFace::timeIntegratedFaceFlux -( - const label facei, - const vector& x0, - const vector& n0, - const scalar Un0, - const scalar f0, - const scalar dt, - const scalar phi, - const scalar magSf -) -{ -/* Temporarily taken out - // Treating rare cases where isoface normal is not calculated properly - if (mag(n0) < 0.5) - { - scalar alphaf = 0; - scalar waterInUpwindCell = 0; - - if (phi > 10*SMALL || !mesh_.isInternalFace(facei)) - { - const label upwindCell = mesh_.faceOwner()[facei]; - alphaf = alpha1In_[upwindCell]; - waterInUpwindCell = alphaf*mesh_.cellVolumes()[upwindCell]; - } - else - { - const label upwindCell = mesh_.faceNeighbour()[facei]; - alphaf = alpha1In_[upwindCell]; - waterInUpwindCell = alphaf*mesh_.cellVolumes()[upwindCell]; - } - - if (debug) - { - WarningInFunction - << "mag(n0) = " << mag(n0) - << " so timeIntegratedFlux calculates dVf from upwind" - << " cell alpha value: " << alphaf << endl; - } - - return min(alphaf*phi*dt, waterInUpwindCell); - } -*/ - - // Find sorted list of times where the isoFace will arrive at face points - // given initial position x0 and velocity Un0*n0 - - // Get points for this face - const face& f = mesh_.faces()[facei]; - const pointField fPts(f.points(mesh_.points())); - const label nPoints = fPts.size(); - - scalarField pTimes(fPts.size()); - if (mag(Un0) > 10*SMALL) // Note: tolerances - { - // Here we estimate time of arrival to the face points from their normal - // distance to the initial surface and the surface normal velocity - - pTimes = ((fPts - x0) & n0)/Un0; - - scalar dVf = 0; - - // Check if pTimes changes direction more than twice when looping face - label nShifts = 0; - forAll(pTimes, pi) - { - const label oldEdgeSign = - sign(pTimes[(pi + 1) % nPoints] - pTimes[pi]); - const label newEdgeSign = - sign(pTimes[(pi + 2) % nPoints] - pTimes[(pi + 1) % nPoints]); - - if (newEdgeSign != oldEdgeSign) - { - nShifts++; - } - } - - if (nShifts == 2) - { - dVf = phi/magSf*timeIntegratedArea(fPts, pTimes, dt, magSf, Un0); - } - else if (nShifts > 2) - { - // Triangle decompose the face - pointField fPts_tri(3); - scalarField pTimes_tri(3); - fPts_tri[0] = mesh_.faceCentres()[facei]; - pTimes_tri[0] = ((fPts_tri[0] - x0) & n0)/Un0; - for (label pi = 0; pi < nPoints; pi++) - { - fPts_tri[1] = fPts[pi]; - pTimes_tri[1] = pTimes[pi]; - fPts_tri[2] = fPts[(pi + 1) % nPoints]; - pTimes_tri[2] = pTimes[(pi + 1) % nPoints]; - const scalar magSf_tri = - mag - ( - 0.5 - *(fPts_tri[2] - fPts_tri[0]) - ^(fPts_tri[1] - fPts_tri[0]) - ); - const scalar phi_tri = phi*magSf_tri/magSf; - dVf += phi_tri/magSf_tri - *timeIntegratedArea - ( - fPts_tri, - pTimes_tri, - dt, - magSf_tri, - Un0 - ); - } - } - else - { - if (debug) - { - WarningInFunction - << "Warning: nShifts = " << nShifts << " on face " << facei - << " with pTimes = " << pTimes << " owned by cell " - << mesh_.faceOwner()[facei] << endl; - } - } - - return dVf; - } - else - { - // Un0 is almost zero and isoFace is treated as stationary - calcSubFace(facei, f0); - const scalar alphaf = mag(subFaceArea()/magSf); - - if (debug) - { - WarningInFunction - << "Un0 is almost zero (" << Un0 - << ") - calculating dVf on face " << facei - << " using subFaceFraction giving alphaf = " << alphaf - << endl; - } - - return phi*dt*alphaf; - } -} - - -Foam::scalar Foam::isoCutFace::timeIntegratedArea -( - const pointField& fPts, - const scalarField& pTimes, - const scalar dt, - const scalar magSf, - const scalar Un0 -) -{ - // Initialise time integrated area returned by this function - scalar tIntArea = 0.0; - - // Finding ordering of vertex points - labelList order(sortedOrder(pTimes)); - const scalar firstTime = pTimes[order.first()]; - const scalar lastTime = pTimes[order.last()]; - - // Dealing with case where face is not cut by surface during time interval - // [0,dt] because face was already passed by surface - if (lastTime <= 0) - { - // If all face cuttings were in the past and cell is filling up (Un0>0) - // then face must be full during whole time interval - tIntArea = magSf*dt*pos0(Un0); - return tIntArea; - } - - // Dealing with case where face is not cut by surface during time interval - // [0, dt] because dt is too small for surface to reach closest face point - if (firstTime >= dt) - { - // If all cuttings are in the future but non of them within [0,dt] then - // if cell is filling up (Un0 > 0) face must be empty during whole time - // interval - tIntArea = magSf*dt*(1 - pos0(Un0)); - return tIntArea; - } - - // If we reach this point in the code some part of the face will be swept - // during [tSmall, dt-tSmall]. However, it may be the case that there are no - // vertex times within the interval. This will happen sometimes for small - // time steps where both the initial and the final face-interface - // intersection line (FIIL) will be along the same two edges. - - // Face-interface intersection line (FIIL) to be swept across face - DynamicList<point> FIIL(3); - // Submerged area at beginning of each sub time interval time - scalar initialArea = 0.0; - //Running time keeper variable for the integration process - scalar time = 0.0; - - // Special treatment of first sub time interval - if (firstTime > 0) - { - // If firstTime > 0 the face is uncut in the time interval - // [0, firstTime] and hence fully submerged in fluid A or B. - // If Un0 > 0 cell is filling up and it must initially be empty. - // If Un0 < 0 cell must initially be full(y immersed in fluid A). - time = firstTime; - initialArea = magSf*(1.0 - pos0(Un0)); - tIntArea = initialArea*time; - cutPoints(fPts, pTimes, time, FIIL); - } - else - { - // If firstTime <= 0 then face is initially cut and we must - // calculate the initial submerged area and FIIL: - time = 0.0; - // Note: calcSubFace assumes well-defined 2-point FIIL!!!! - calcSubFace(fPts, -sign(Un0)*pTimes, time); - initialArea = mag(subFaceArea()); - cutPoints(fPts, pTimes, time, FIIL); - } - - // Making sorted array of all vertex times that are between max(0,firstTime) - // and dt and further than tSmall from the previous time. - DynamicList<scalar> sortedTimes(pTimes.size()); - { - scalar prevTime = time; - const scalar tSmall = max(1e-6*dt, 10*SMALL); - forAll(order, ti) - { - const scalar timeI = pTimes[order[ti]]; - if ( timeI > prevTime + tSmall && timeI <= dt) - { - sortedTimes.append(timeI); - prevTime = timeI; - } - } - } - - // Sweeping all quadrilaterals corresponding to the intervals defined above - forAll(sortedTimes, ti) - { - const scalar newTime = sortedTimes[ti]; - // New face-interface intersection line - DynamicList<point> newFIIL(3); - cutPoints(fPts, pTimes, newTime, newFIIL); - - // quadrilateral area coefficients - scalar alpha = 0, beta = 0; - quadAreaCoeffs(FIIL, newFIIL, alpha, beta); - // Integration of area(t) = A*t^2+B*t from t = 0 to 1 - tIntArea += (newTime - time)* - (initialArea + sign(Un0)*(alpha/3.0 + 0.5*beta)); - // Adding quad area to submerged area - initialArea += sign(Un0)*(alpha + beta); - - FIIL = newFIIL; - time = newTime; - } - - // Special treatment of last time interval - if (lastTime > dt) - { - // FIIL will end up cutting the face at dt - // New face-interface intersection line - DynamicList<point> newFIIL(3); - cutPoints(fPts, pTimes, dt, newFIIL); - - // quadrilateral area coefficients - scalar alpha = 0, beta = 0; - quadAreaCoeffs(FIIL, newFIIL, alpha, beta); - // Integration of area(t) = A*t^2+B*t from t = 0 to 1 - tIntArea += (dt - time)* - (initialArea + sign(Un0)*(alpha/3.0 + 0.5*beta)); - } - else - { - // FIIL will leave the face at lastTime and face will be fully in fluid - // A or fluid B in the time interval from lastTime to dt. - tIntArea += magSf*(dt - lastTime)*pos0(Un0); - } - - return tIntArea; -} - - -void Foam::isoCutFace::cutPoints -( - const pointField& pts, - const scalarField& f, - const scalar f0, - DynamicList<point>& cutPoints -) -{ - const label nPoints = pts.size(); - scalar f1(f[0]); - - // Snapping vertex value to f0 if very close (needed for 2D cases) - if (mag(f1 - f0) < 10*SMALL) - { - f1 = f0; - } - - forAll(pts, pi) - { - label pi2 = (pi + 1) % nPoints; - scalar f2 = f[pi2]; - - // Snapping vertex value - if (mag(f2 - f0) < 10*SMALL) - { - f2 = f0; - } - - if ((f1 < f0 && f2 > f0) || (f1 > f0 && f2 < f0)) - { - const scalar s = (f0 - f1)/(f2 - f1); - cutPoints.append(pts[pi] + s*(pts[pi2] - pts[pi])); - } - else if (f1 == f0) - { - cutPoints.append(pts[pi]); - } - f1 = f2; - } - - if (cutPoints.size() > 2) - { - WarningInFunction << "cutPoints = " << cutPoints << " for pts = " << pts - << ", f - f0 = " << f - f0 << " and f0 = " << f0 << endl; - } -} - - -void Foam::isoCutFace::quadAreaCoeffs -( - const DynamicList<point>& pf0, - const DynamicList<point>& pf1, - scalar& alpha, - scalar& beta -) const -{ - // Number of points in provided face-interface intersection lines - const label np0 = pf0.size(); - const label np1 = pf1.size(); - - // quad area coeffs such that area(t) = alpha*t^2 + beta*t. - // With time interval normalised, we have full quadArea = alpha + beta - // and time integrated quad area = alpha/3 + beta/2; - alpha = 0.0; - beta = 0.0; - - if (np0 && np1) - { - // Initialising quadrilateral vertices A, B, C and D - vector A(pf0[0]); - vector C(pf1[0]); - vector B(pf0[0]); - vector D(pf1[0]); - - if (np0 == 2) - { - B = pf0[1]; - } - else if (np0 > 2) - { - WarningInFunction << "Vertex face was cut at pf0 = " << pf0 << endl; - } - - if (np1 == 2) - { - D = pf1[1]; - } - else if (np1 > 2) - { - WarningInFunction << "Vertex face was cut at pf1 = " << pf1 << endl; - } - - // Swapping pf1 points if pf0 and pf1 point in same general direction - // (because we want a quadrilateral ABCD where pf0 = AB and pf1 = CD) - if (((B - A) & (D - C)) > 0) - { - vector tmp = D; - D = C; - C = tmp; - } - - // Defining local coordinates (xhat, yhat) for area integration of swept - // quadrilateral ABCD such that A = (0,0), B = (Bx,0), C = (Cx,Cy) and - // D = (Dx,Dy) with Cy = 0 and Dy > 0. - - const scalar Bx = mag(B - A); - - vector xhat(Zero); - if (Bx > 10*SMALL) - { - // If |AB| > 0 ABCD we use AB to define xhat - xhat = normalised(B - A); - } - else if (mag(C - D) > 10*SMALL) - { - // If |AB| ~ 0 ABCD is a triangle ACD and we use CD for xhat - xhat = normalised(C - D); - } - else - { - return; - } - - // Defining vertical axis in local coordinates - vector yhat = D - A; - yhat -= ((yhat & xhat)*xhat); - - if (mag(yhat) > 10*SMALL) - { - yhat /= mag(yhat); - - const scalar Cx = (C - A) & xhat; - const scalar Cy = mag((C - A) & yhat); - const scalar Dx = (D - A) & xhat; - const scalar Dy = mag((D - A) & yhat); - - // area = ((Cx - Bx)*Dy - Dx*Cy)/6.0 + 0.25*Bx*(Dy + Cy); - alpha = 0.5*((Cx - Bx)*Dy - Dx*Cy); - beta = 0.5*Bx*(Dy + Cy); - } - } - else - { - WarningInFunction - << "Vertex face was cut at " << pf0 << " and at " << pf1 << endl; - } -} - - -// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.H b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.H deleted file mode 100644 index 56c2b6f22f68498f7e51f24fba4126b559761c33..0000000000000000000000000000000000000000 --- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.H +++ /dev/null @@ -1,215 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2016-2017 DHI - Copyright (C) 2016-2017 OpenCFD Ltd. - Copyright (C) 2018 Johan Roenby -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. - -Class - Foam::isoCutFace - -Description - Class for cutting a face, faceI, of an fvMesh, mesh_, at its intersection - with an isosurface defined by the mesh point values f_ and the isovalue, - isoValue_. - - Reference: - \verbatim - Roenby, J., Bredmose, H. and Jasak, H. (2016). - A computational method for sharp interface advection - Royal Society Open Science, 3 - doi 10.1098/rsos.160405 - \endverbatim - - Original code supplied by Johan Roenby, DHI (2016) - -SourceFiles - isoCutFace.C - -\*---------------------------------------------------------------------------*/ - -#ifndef isoCutFace_H -#define isoCutFace_H - -#include "fvMesh.H" - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -namespace Foam -{ - -/*---------------------------------------------------------------------------*\ - Class isoCutFaces Declaration -\*---------------------------------------------------------------------------*/ - -class isoCutFace -{ - // Private data - - //- Mesh whose cells and faces to cut at their intersection with an - // isoface - const fvMesh& mesh_; - - //- Isofunction values at mesh points. f_size() = mesh_.nPoints() - scalarField& f_; - - //- Point along first cut edge where isosurface cuts edge - scalar firstEdgeCut_; - - //- Point along last cut edge where isosurface cuts edge - scalar lastEdgeCut_; - - //- Index in mesh_.faces()[faceI_] of first fully submerged (f > f0) - // face point - label firstFullySubmergedPoint_; - - //- Index in mesh_.faces()[faceI_] of last fully submerged (f > f0) - // face point - label nFullySubmergedPoints_; - - //- Storage for centre of subface - point subFaceCentre_; - - //- Storage for area vector of subface - vector subFaceArea_; - - //- Storage for subFacePoints - DynamicList<point> subFacePoints_; - - //- Storage for subFacePoints - DynamicList<point> surfacePoints_; - - //- Boolean telling if subface centre and area have been calculated - bool subFaceCentreAndAreaIsCalculated_; - - - // Private Member Functions - - void calcSubFaceCentreAndArea(); - - //- Calculate cut points along edges of face with values f[pLabels] - // Returns the face status, where: - // -1: face is fully below the isosurface - // 0: face is cut, i.e. has values larger and smaller than isoValue - // +1: face is fully above the isosurface - label calcSubFace - ( - const scalar isoValue, - const pointField& points, - const scalarField& f, - const labelList& pLabels - ); - - void subFacePoints(const pointField& points, const labelList& pLabels); - - void surfacePoints(const pointField& points, const labelList& pLabels); - - -public: - - // Constructors - - //- Construct from fvMesh and a scalarField - // Length of scalarField should equal number of mesh points - isoCutFace(const fvMesh& mesh, scalarField& f); - - // Static data - - static int debug; - - - // Member functions - - //- Calculate cut points along edges of faceI - label calcSubFace(const label faceI, const scalar isoValue); - - //- Calculate cut points along edges of face with values f - label calcSubFace - ( - const pointField& points, - const scalarField& f, - const scalar isoValue - ); - - const point& subFaceCentre(); - - const vector& subFaceArea(); - - const DynamicList<point>& subFacePoints() const; - - const DynamicList<point>& surfacePoints() const; - - void clearStorage(); - - //- Calculate volumetric face transport during dt given the isoFace - // data provided as input for face facei - scalar timeIntegratedFaceFlux - ( - const label facei, - const vector& x0, - const vector& n0, - const scalar Un0, - const scalar f0, - const scalar dt, - const scalar phi, - const scalar magSf - ); - - //- Calculate time integrated area for a face - scalar timeIntegratedArea - ( - const pointField& fPts, - const scalarField& pTimes, - const scalar dt, - const scalar magSf, - const scalar Un0 - ); - - void cutPoints - ( - const pointField& pts, - const scalarField& f, - const scalar f0, - DynamicList<point>& cutPoints - ); - - - void quadAreaCoeffs - ( - const DynamicList<point>& pf0, - const DynamicList<point>& pf1, - scalar& alpha, - scalar& beta - ) const; -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/leastSquareGrad.C b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/leastSquareGrad.C new file mode 100644 index 0000000000000000000000000000000000000000..2f0e00787e3876fc3314dce9649eefaad82e7df2 --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/leastSquareGrad.C @@ -0,0 +1,168 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "leastSquareGrad.H" +#include "emptyPolyPatch.H" +#include "processorPolyPatch.H" +#include "wedgePolyPatch.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class T> +Foam::leastSquareGrad<T>::leastSquareGrad +( + const word& functionName, + const labelVector& geomDir +) +: + polyFitter_(functionName,geomDir), + geomDir_(geomDir), + nDims_(0) +{ + // Compute number of dimensions + for (const label dirn : geomDir_) + { + if (dirn == 1) + { + ++nDims_; + } + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class T> +typename Foam::outerProduct<Foam::vector, T>::type +Foam::leastSquareGrad<T>::grad +( + const List<vector>& positions, + const List<T>& listValue +) +{ + typedef typename outerProduct<vector, T>::type GradType; + + List<T> fitData = polyFitter_.fitData + ( + positions, + listValue + ); + + if (nDims_ == 3) + { + return GradType(fitData[1],fitData[2],fitData[3]); + } + + + label dimCounter = 0; + + GradType ret(Zero); + + forAll(geomDir_,i) + { + if (geomDir_[i] == 1) + { + ++dimCounter; + ret[i] = fitData[dimCounter]; + } + } + + return ret; +} + + +namespace Foam // needed g++ bug +{ + template<> + tensor leastSquareGrad<vector>::grad + ( + const List<vector>& positions, + const List<vector>& listValue + ) + { + typedef tensor GradType; + + List<vector> fitData = polyFitter_.fitData + ( + positions, + listValue + ); + + if (nDims_ == 3) + { + return GradType(fitData[1],fitData[2],fitData[3]); + } + + label dimCounter = 0; + + GradType ret(Zero); + + forAll(geomDir_,i) + { + if (geomDir_[i] == 1) + { + ++dimCounter; + ret.row(i, fitData[dimCounter]); + } + } + + return ret; + } +} + + +template<class T> +Foam::Map<typename Foam::outerProduct<Foam::vector, T>::type> +Foam::leastSquareGrad<T>::grad +( + const Map<List<vector>>& positions, + const Map<List<T>>& listValue +) +{ + typedef typename outerProduct<vector, T>::type GradType; + + Map<GradType> gradMap(positions.capacity()); + + forAllConstIters(positions, iter) + { + const label key = iter.key(); + const List<vector>& positions = iter.val(); + + GradType grad(this->grad(positions, listValue[key])); + + gradMap.insert(key, grad); + } + + return gradMap; +} + + +template class Foam::leastSquareGrad<Foam::scalar>; +template class Foam::leastSquareGrad<Foam::vector>; + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/leastSquareGrad.H b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/leastSquareGrad.H new file mode 100644 index 0000000000000000000000000000000000000000..9587879ecfa3397dd6c94abc59c4cb1ef910628e --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/leastSquareGrad.H @@ -0,0 +1,101 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::leastSquareGrad + +Description + Estimates the gradient with a least square scheme in a cell + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + leastSquareGrad.C + +\*---------------------------------------------------------------------------*/ + +#ifndef leastSquareGrad_H +#define leastSquareGrad_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "OFstream.H" +#include "multiDimPolyFitter.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class leastSquareGrad Declaration +\*---------------------------------------------------------------------------*/ +template<class T> +class leastSquareGrad +{ + // Private Data + + multiDimPolyFitter<T> polyFitter_; + + labelVector geomDir_; + + label nDims_; + + +public: + + // Constructors + + //- Construct from components + leastSquareGrad(const word& functionName, const labelVector& geomDir); + + + // Member Functions + + //- Return the gradient of the cell + typename outerProduct<vector, T>::type grad + ( + const List<vector>& positions, + const List<T>& listValue + ); + + Map<typename outerProduct<vector, T>::type> grad + ( + const Map<List<vector>>& positions, + const Map<List<T>>& listValue + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFitter.C b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFitter.C new file mode 100644 index 0000000000000000000000000000000000000000..8a03b5ff5cd53932d7426f0eef615cb6581f7a16 --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFitter.C @@ -0,0 +1,375 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "multiDimPolyFitter.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template<class T> +Foam::multiDimPolyFitter<T>::multiDimPolyFitter +( + const word& polyFunctionName, + const labelVector& geomDirs +) +: + polyFunc_(multiDimPolyFunctions::New(polyFunctionName,geomDirs)), + A_(polyFunc_->nTerms(), scalar(0), Zero) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template<class T> +void Foam::multiDimPolyFitter<T>::resetMatrix() +{ + for (label i=0;i<A_.size();i++) + { + A_.data()[i] = Zero; + } + A_.source() = Zero; +} + + +template<class T> +void Foam::multiDimPolyFitter<T>::fillMatrix +( + const scalarField& polyTerms, + const T& value +) +{ + const label size = A_.n(); + + // simple matrix is a square + + for (label i=0; i<size; ++i) // col + { + A_.source()[i] += polyTerms[i]*value; + scalar* luMatrixi = A_[i]; + const scalar tmpValue = polyTerms[i]; + + for (label j=0; j<size; ++j) // row + { + luMatrixi[j] += tmpValue*polyTerms[j]; + } + } +} + + +template<class T> +void Foam::multiDimPolyFitter<T>::fillMatrix +( + const scalarField& polyTerms, + const T& value, + const scalar weight +) +{ + const label size = A_.n(); + + //simple matrix is a square + + for (label i=0; i<size; ++i) // col + { + A_.source()[i] += polyTerms[i]*value*weight; + scalar* __restrict luMatrixi = A_[i]; + const scalar tmpValue = polyTerms[i]; + + for (label j=0; j<size; j++) // row + { + luMatrixi[j] += tmpValue*polyTerms[j]*weight; + } + } +} + + +template<class T> +void Foam::multiDimPolyFitter<T>::fillMatrix +( + const scalarField& polyTerms, + scalarSymmetricSquareMatrix& A +) +{ + const label size = A.n(); + + // simple matrix is a square + for (label i=0; i<size; ++i) + { + for (label j=0; j<size; ++j) + { + A[i][j] += polyTerms[i]*polyTerms[j]; + } + } +} + + +template<class T> +Foam::Field<T> Foam::multiDimPolyFitter<T>::fitData +( + const List<scalarField>& listPolyTerms, + const List<T>& listValue +) +{ + // operator= does not work + resetMatrix(); + if (listPolyTerms.size() == listValue.size()) + { + forAll(listPolyTerms,i) + { + fillMatrix + ( + listPolyTerms[i], + listValue[i] + ); + } + // Solve the matrix using Gaussian elimination with pivoting + return A_.LUsolve(); + } + else + { + FatalErrorInFunction + << "size of listPolyTerms: " << listPolyTerms.size() + << "size of listValues is: " << listValue.size() + << " they must match!" << nl + << exit(FatalError); + return Field<T>(); + } +} + + +template<class T> +Foam::Field<T> Foam::multiDimPolyFitter<T>::fitData +( + const List<scalarField>& listPolyTerms, + const List<T>& listValue, + const List<scalar>& listWeight +) +{ + // operator= does not work + resetMatrix(); + if (listPolyTerms.size() == listValue.size()) + { + forAll(listPolyTerms, i) + { + fillMatrix + ( + listPolyTerms[i], + listValue[i], + listWeight[i] + ); + } + + // Solve the matrix using Gaussian elimination with pivoting + return A_.LUsolve(); + } + else + { + FatalErrorInFunction + << "size of listPolyTerms: " << listPolyTerms.size() + << "size of listValues is:" << listValue.size() + << "they have to match" + << exit(FatalError); + + return Field<T>(); + } +} + + +template<class T> +Foam::scalarSymmetricSquareMatrix Foam::multiDimPolyFitter<T>::computeInverse +( + const List<scalarField>& listPolyTerms +) +{ + // operator= does not work + scalarSymmetricSquareMatrix symMatrix(A_.n(), Zero); + forAll(listPolyTerms,i) + { + fillMatrix + ( + listPolyTerms[i], + symMatrix + ); + } + + return inv(symMatrix); +} + + +template<class T> +Foam::Field<T> Foam::multiDimPolyFitter<T>::computeMatrixSource +( + const List<scalarField>& listPolyTerms, + const List<T>& listValue +) +{ + if (listPolyTerms.size() != listValue.size()) + { + FatalErrorInFunction + << "size of listPolyTerms: " << listPolyTerms.size() + << "size of listValues is:" << listValue.size() + << "they have to match" + << exit(FatalError); + } + + Field<T> source(listPolyTerms.size(), Zero); + + forAll(source, i) + { + forAll(listPolyTerms[i], j) + { + source[i] += listPolyTerms[i][j]*listValue[i]; + } + } + + return source; +} + + +template<class T> +Foam::Field<T> Foam::multiDimPolyFitter<T>::fitData +( + const List<vector>& positions, + const List<T>& listValue +) +{ + // operator= does not work + if (positions.size() != listValue.size()) + { + FatalErrorInFunction + << "size of positions and listValues don't match" << nl + << "size of positions is: " << positions.size() << nl + << "size of listValues is: " << listValue.size() << nl + << exit(FatalError); + } + + resetMatrix(); + + forAll(positions, i) + { + fillMatrix + ( + polyFunc_->termValues(positions[i]), + listValue[i] + ); + } + + // Solve the matrix using Gaussian elimination with pivoting + return A_.LUsolve(); +} + + +template<class T> +Foam::Field<T> Foam::multiDimPolyFitter<T>::fitData +( + const List<vector>& positions, + const List<T>& listValue, + const List<scalar>& listWeight +) +{ + // operator= does not work + if (positions.size() != listValue.size()) + { + FatalErrorInFunction + << "size of positions and listValues don't match" << nl + << "size of positions is: " << positions.size() << nl + << "size of listValues is: " << listValue.size() << nl + << exit(FatalError); + } + + resetMatrix(); + + forAll(positions, i) + { + fillMatrix + ( + polyFunc_->termValues(positions[i]), + listValue[i], + listWeight[i] + ); + } + + // Solve the matrix using Gaussian elimination with pivoting + return A_.LUsolve(); +} + + +template<class T> +Foam::scalarSymmetricSquareMatrix Foam::multiDimPolyFitter<T>::computeInverse +( + const List<vector>& positions +) +{ + // operator= does not work + scalarSymmetricSquareMatrix symMatrix(A_.n(), Zero); + forAll(positions, i) + { + fillMatrix + ( + polyFunc_->termValues(positions[i]), + symMatrix + ); + } + + return inv(symMatrix); +} + + +template<class T> +Foam::Field<T> Foam::multiDimPolyFitter<T>::computeMatrixSource +( + const List<vector>& positions, + const List<T>& listValue +) +{ + if (positions.size() != listValue.size()) + { + FatalErrorInFunction + << "size of positions: " << positions.size() + << "size of listValues is:" << listValue.size() + << "they have to match" + << exit(FatalError); + } + + Field<T> source(polyFunc_->nTerms(), Zero); + + forAll(source, i) + { + scalarField polyTerms = polyFunc_->termValues(positions[i]); + forAll(polyTerms, j) + { + source[i] += polyTerms[j]*listValue[i]; + } + } + + return source; +} + + +template class Foam::multiDimPolyFitter<Foam::scalar>; +template class Foam::multiDimPolyFitter<Foam::vector>; + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFitter.H b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFitter.H new file mode 100644 index 0000000000000000000000000000000000000000..60874e6d415bda317209a765ac7b23934ab5c8ef --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFitter.H @@ -0,0 +1,170 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::multiDimPolyFitter + +Description + Fit a polynominal function with the help of multiDimPolyFunction + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + multiDimPolyFitter.C + +\*---------------------------------------------------------------------------*/ + +#ifndef multiDimPolyFitter_H +#define multiDimPolyFitter_H + +#include "simpleMatrix.H" +#include "multiDimPolyFunctions.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class multiDimPolyFitter Declaration +\*---------------------------------------------------------------------------*/ + +template<class T> +class multiDimPolyFitter +{ + // Private Data + + autoPtr<multiDimPolyFunctions> polyFunc_; + + simpleMatrix<T> A_; + + +public: + + // Constructors + + //- Construct from components + multiDimPolyFitter + ( + const word& polyFunctionName, + const labelVector& geomDirs + ); + + + // Member Functions + + void resetMatrix(); + + label nCoeffs() const + { + return A_.n(); + } + + void fillMatrix + ( + const scalarField& polyTerms, + const T& value + ); + + void fillMatrix + ( + const scalarField& polyTerms, + const T& value, + const scalar weight + ); + + void fillMatrix + ( + const scalarField& polyTerms, + scalarSymmetricSquareMatrix& A + ); + + //- Fit data + Field<T> fitData + ( + const List<scalarField>& listPolyTerms, + const List<T>& listValue + ); + + //- Fit data + Field<T> fitData + ( + const List<scalarField>& listPolyTerms, + const List<T>& listValue, + const List<scalar>& listWeight + ); + + //- Compute inverse + scalarSymmetricSquareMatrix computeInverse + ( + const List<scalarField>& listPolyTerms + ); + + //- Compute source + Field<T> computeMatrixSource + ( + const List<scalarField>& listPolyTerms, + const List<T>& listValue + ); + + //- Fit data + Field<T> fitData + ( + const List<vector>& positions, + const List<T>& listValue + ); + + //- Fit data + Field<T> fitData + ( + const List<vector>& positions, + const List<T>& listValue, + const List<scalar>& listWeight + ); + + //- Compute inverse + scalarSymmetricSquareMatrix computeInverse + ( + const List<vector>& positions + ); + + //- Compute source + Field<T> computeMatrixSource + ( + const List<vector>& positions, + const List<T>& listValue + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/multiDimPolyFunctions.C b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/multiDimPolyFunctions.C new file mode 100644 index 0000000000000000000000000000000000000000..07df3230b5a2e5edf13939b33669a9185473333d --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/multiDimPolyFunctions.C @@ -0,0 +1,76 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "multiDimPolyFunctions.H" +#include "error.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(multiDimPolyFunctions, 0); + defineRunTimeSelectionTable(multiDimPolyFunctions, word); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::multiDimPolyFunctions> Foam::multiDimPolyFunctions::New +( + const word& multiDimPolyFunctionsType, + const labelVector& dirs +) +{ + auto cstrIter = wordConstructorTablePtr_->cfind(multiDimPolyFunctionsType); + + if (!cstrIter.found()) + { + FatalErrorInLookup + ( + "multiDimPolyFunction", + multiDimPolyFunctionsType, + *wordConstructorTablePtr_ + ) << exit(FatalError); + } + + return autoPtr<multiDimPolyFunctions>(cstrIter()(dirs)); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::multiDimPolyFunctions::multiDimPolyFunctions(const labelVector& dirs) +: + nTerms_(-1), + geomDir_(dirs), + geomCorrection_(pos0(dirs.x()), pos0(dirs.y()), pos0(dirs.z())), + coeffs_(), + termValues_() +{} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/multiDimPolyFunctions.H b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/multiDimPolyFunctions.H new file mode 100644 index 0000000000000000000000000000000000000000..6e33daf6a516bd21b34f24ec14e5f4f9b25a4675 --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/multiDimPolyFunctions.H @@ -0,0 +1,141 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::multiDimPolyFunctions + +Description + base class for polynomial functions + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + multiDimPolyFunctions.C + +\*---------------------------------------------------------------------------*/ + +#ifndef multiDimPolyFunctions_H +#define multiDimPolyFunctions_H + +#include "vector.H" +#include "vector2D.H" +#include "labelVector.H" +#include "scalarField.H" +#include "runTimeSelectionTables.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class multiDimPolyFunctions Declaration +\*---------------------------------------------------------------------------*/ + +class multiDimPolyFunctions +{ +protected: + + // Protected Data + + //- Number of polynomial term + label nTerms_; + + const labelVector geomDir_; + + vector geomCorrection_; + + scalarField coeffs_; + + scalarField termValues_; + + +public: + + //- Runtime type information + TypeName("multiDimPolyFunctions"); + + // Declare run-time constructor selection table + + // For the dictionary constructor + declareRunTimeSelectionTable + ( + autoPtr, + multiDimPolyFunctions, + word, + ( + const Vector<label> dirs + ), + (dirs) + ); + + + // Constructors + + //- Construct with directions + explicit multiDimPolyFunctions(const labelVector& dirs); + + + // Selectors + + //- Select a multiDimPolyFunctions + static autoPtr<multiDimPolyFunctions> New + ( + const word& multiDimPolyFunctionsType, + const labelVector& dirs + ); + + + //- Destructor + virtual ~multiDimPolyFunctions() = default; + + + // Member Functions + + virtual scalar value(const vector& vec) = 0; + + virtual const scalarField& termValues(const vector& vec) = 0; + + label& nTerms() + { + return nTerms_; + } + + scalarField& coeffs() + { + return coeffs_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/polyDegree1.C b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/polyDegree1.C new file mode 100644 index 0000000000000000000000000000000000000000..865ec216c133c5b6e1d889ea5910850a8b6f1bf5 --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/polyDegree1.C @@ -0,0 +1,98 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "polyDegree1.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(polyDegree1, 0); + addToRunTimeSelectionTable(multiDimPolyFunctions, polyDegree1, word); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::polyDegree1::polyDegree1 +( + const labelVector& dirs +) +: + multiDimPolyFunctions(dirs) +{ + nTerms_ = 1; + forAll(geomDir_,i) + { + if (geomDir_[i] == 1) + { + ++nTerms_; + } + } + coeffs_.resize(nTerms_, Zero); + termValues_.resize(nTerms_, Zero); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::scalar Foam::polyDegree1::value(const vector& vec) +{ + // size has to be 4 + scalar value = coeffs_[0]; + forAll(geomDir_,i) + { + if (geomDir_[i] == 1) + { + value += coeffs_[i+1]*vec[i]; + } + } + + return value; +} + + +const Foam::scalarField& Foam::polyDegree1::termValues(const vector& vec) +{ + termValues_[0] = 1; + + label dimCounter = 0; + forAll(geomDir_,i) + { + if (geomDir_[i] == 1) + { + ++dimCounter; + termValues_[dimCounter] = vec[i]; + } + } + + return termValues_; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/polyDegree1.H b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/polyDegree1.H new file mode 100644 index 0000000000000000000000000000000000000000..dfbe1ad4c50b20c2c6f6df1634d14fe5d43a57f1 --- /dev/null +++ b/src/finiteVolume/fvMatrices/solvers/multiDimPolyFitter/multiDimPolyFunctions/polyDegree1.H @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::polyDegree1 + +Description + First degree polynominal function + + \verbatim + c0 + c1*x + c2*y + c3*z + \endverbatim + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + polyDegree1.C + +\*---------------------------------------------------------------------------*/ + +#ifndef polyDegree1_H +#define polyDegree1_H + +#include "vector.H" +#include "vector2D.H" +#include "scalarField.H" +#include "multiDimPolyFunctions.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class polyDegree1 Declaration +\*---------------------------------------------------------------------------*/ + +class polyDegree1 +: + public multiDimPolyFunctions +{ +public: + + //- Runtime type information + TypeName("polyDegree1"); + + + // Constructors + + //- Construct from nTerms + explicit polyDegree1(const labelVector& dirs); + + + //- Destructor + virtual ~polyDegree1() = default; + + + // Member Functions + + virtual scalar value(const vector& vec); + + virtual const scalarField& termValues(const vector& vec); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.C b/src/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.C new file mode 100644 index 0000000000000000000000000000000000000000..3194c5ae6d121ab29e5b25cf59b24fa8039f38fd --- /dev/null +++ b/src/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.C @@ -0,0 +1,204 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "zoneDistribute.H" +#include "dummyTransform.H" +#include "emptyPolyPatch.H" +#include "processorPolyPatch.H" +#include "syncTools.H" +#include "wedgePolyPatch.H" + +#include "globalPoints.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(zoneDistribute, 0); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::autoPtr<Foam::indirectPrimitivePatch> +Foam::zoneDistribute::coupledFacesPatch() const +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + label nCoupled = 0; + + for (const polyPatch& pp : patches) + { + if (isA<processorPolyPatch>(pp)) + { + nCoupled += pp.size(); + } + } + labelList coupledFaces(nCoupled); + nCoupled = 0; + + for (const polyPatch& pp : patches) + { + if (isA<processorPolyPatch>(pp)) + { + label facei = pp.start(); + + forAll(pp, i) + { + coupledFaces[nCoupled++] = facei++; + } + } + } + + return autoPtr<indirectPrimitivePatch>::New + ( + IndirectList<face> + ( + mesh_.faces(), + coupledFaces + ), + mesh_.points() + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::zoneDistribute::zoneDistribute(const fvMesh& mesh) +: + MeshObject<fvMesh, Foam::UpdateableMeshObject, zoneDistribute>(mesh), + stencil_(mesh), + coupledBoundaryPoints_(coupledFacesPatch()().meshPoints()), + send_(Pstream::nProcs()) +{ +} + + +// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * // + +Foam::zoneDistribute& Foam::zoneDistribute::New(const fvMesh& mesh) +{ + zoneDistribute* ptr = mesh.thisDb().getObjectPtr<zoneDistribute> + ( + zoneDistribute::typeName + ); + + if (!ptr) + { + ptr = new zoneDistribute(mesh); + + regIOobject::store(ptr); + } + + return *ptr; +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::zoneDistribute::updateStencil(const boolList& zone) +{ + stencil_.updateStencil(zone); +} + + +void Foam::zoneDistribute::setUpCommforZone +( + const boolList& zone, + bool updateStencil +) +{ + if (updateStencil) + { + stencil_.updateStencil(zone); + } + + const labelHashSet comms = stencil_.needsComm(); + + List<labelHashSet> needed_(Pstream::nProcs()); + + if (Pstream::parRun()) + { + for (const label celli : comms) + { + if (zone[celli]) + { + for (const label gblIdx : stencil_[celli]) + { + if (!globalNumbering().isLocal(gblIdx)) + { + const label procID = + globalNumbering().whichProcID(gblIdx); + needed_[procID].insert(gblIdx); + } + } + } + } + + PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking); + + // Stream data into buffer + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + if (domain != Pstream::myProcNo()) + { + // Put data into send buffer + UOPstream toDomain(domain, pBufs); + + toDomain << needed_[domain]; + } + } + + // wait until everything is written. + pBufs.finishedSends(); + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + send_[domain].clear(); + + if (domain != Pstream::myProcNo()) + { + // get data from send buffer + UIPstream fromDomain(domain, pBufs); + + fromDomain >> send_[domain]; + } + } + } +} + + +void Foam::zoneDistribute::updateMesh(const mapPolyMesh& mpm) +{ + if (mesh_.topoChanging()) + { + coupledBoundaryPoints_ = coupledFacesPatch()().meshPoints(); + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.H b/src/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.H new file mode 100644 index 0000000000000000000000000000000000000000..dc432c774593c97a8a98915d159d738ed74b2941 --- /dev/null +++ b/src/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.H @@ -0,0 +1,193 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::zoneDistribute + +Description + Class for parallel communication in a narrow band. It either provides a Map + with the neighbouring values of the selected region or returns a Map of the + required values in global addressing. Also holds a reference to the stencil + Before the data transfer the communation has to be set up: + exchangeFields_.setUpCommforZone(interfaceCell_); + Is used in the plicRDF + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + zoneDistribute.C + +\*---------------------------------------------------------------------------*/ + +#ifndef zoneDistribute_H +#define zoneDistribute_H + +#include "fvMesh.H" +#include "globalIndex.H" +#include "volFields.H" + +#include "zoneCPCStencil.H" +#include "IOobject.H" +#include "MeshObject.H" + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class zoneDistribute Declaration +\*---------------------------------------------------------------------------*/ + +class zoneDistribute +: + public MeshObject<fvMesh, UpdateableMeshObject, zoneDistribute> +{ + // Private Data + + //- cell-point-cell stencil elements are in global addressing + zoneCPCStencil stencil_; + + //- labels of the points on coupled patches + labelList coupledBoundaryPoints_; + + //- storage of the addressing for processor-to-processor comms + List<labelHashSet> send_; + + //- Return patch of all coupled faces. + autoPtr<indirectPrimitivePatch> coupledFacesPatch() const; + + + //- Gives patchNumber and patchFaceNumber for a given + //- Geometric volume field + template<typename Type> + Type getLocalValue + ( + const GeometricField<Type, fvPatchField, volMesh>& phi, + const label localIdx + ) const; + + + //- Gives patchNumber and patchFaceNumber for a given + //- Geometric volume field + template<typename Type> + Type faceValue + ( + const GeometricField<Type, fvPatchField, volMesh>& phi, + const label localIdx + ) const; + + +public: + + //- Runtime information + TypeName("zoneDistribute"); + + + // Constructors + + //- Construct from fvMesh + explicit zoneDistribute(const fvMesh&); + + + // Selectors + + static zoneDistribute& New(const fvMesh&); + + + // Member Functions + + //- Update stencil with boolList the size has to match mesh nCells + void setUpCommforZone(const boolList& zone, bool updateStencil=true); + + //- Updates stencil with boolList the size has to match mesh nCells + void updateStencil(const boolList& zone); + + //- Stencil reference + const labelListList& getStencil() + { + return stencil_; + } + + //- Addressing reference + const globalIndex& globalNumbering() const + { + return stencil_.globalNumbering(); + } + + //- Gives patchNumber and patchFaceNumber for a given + //- Geometric volume field + template<typename Type> + Type getValue + ( + const GeometricField<Type, fvPatchField, volMesh>& phi, + const Map<Type>& valuesFromOtherProc, + const label gblIdx + ) const; + + //- Returns stencil and provides a Map with globalNumbering + template<typename Type> + Map<Field<Type>> getFields + ( + const boolList& zone, + const GeometricField<Type, fvPatchField, volMesh>& phi + ); + + //- Returns stencil and provides a Map with globalNumbering + template<typename Type> + Map<Type> getDatafromOtherProc + ( + const boolList& zone, + const GeometricField<Type, fvPatchField, volMesh>& phi + ); + + virtual void updateMesh(const mapPolyMesh& mpm); + + virtual bool movePoints() + { + // do nothing + return false; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +#include "zoneDistributeI.H" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/zoneDistribute/zoneDistributeI.H b/src/finiteVolume/fvMesh/zoneDistribute/zoneDistributeI.H new file mode 100644 index 0000000000000000000000000000000000000000..2289be2509fbe8f9ae429f34743715f94c4dc267 --- /dev/null +++ b/src/finiteVolume/fvMesh/zoneDistribute/zoneDistributeI.H @@ -0,0 +1,221 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "zoneDistribute.H" +#include "DynamicField.H" +#include "syncTools.H" + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +template<typename Type> +Type Foam::zoneDistribute::getLocalValue +( + const GeometricField<Type, fvPatchField, volMesh>& phi, + const label localIdx +) const +{ + if (localIdx < mesh_.nCells()) // internal: cellI + { + return phi[localIdx]; + } + else + { + return faceValue(phi,localIdx); + } + +} + + +template<typename Type> +Type Foam::zoneDistribute::faceValue +( + const GeometricField<Type, fvPatchField, volMesh>& phi, + const label localIdx +) const +{ + const label faceI = localIdx + mesh_.nInternalFaces() - mesh_.nCells(); + + const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); + + // Boundary face. Find out which face of which patch + const label patchI = pbm.whichPatch(faceI); + + if (patchI < 0 || patchI >= pbm.size()) + { + FatalErrorInFunction + << "Cannot find patch for face " << faceI + << abort(FatalError); + } + + const polyPatch& pp = pbm[patchI]; + + const label patchFaceI = pp.whichFace(faceI); + + return phi.boundaryField()[patchI][patchFaceI]; +} + + +template<typename Type> +Type Foam::zoneDistribute::getValue +( + const GeometricField<Type, fvPatchField, volMesh>& phi, + const Map<Type>& valuesFromOtherProc, + const label gblIdx +) const +{ + if (globalNumbering().isLocal(gblIdx)) + { + const label idx = globalNumbering().toLocal(gblIdx); + return getLocalValue(phi,idx); + } + else // from other proc + { + return valuesFromOtherProc[gblIdx]; + } +} + + +template<typename Type> +Foam::Map<Foam::Field<Type>> Foam::zoneDistribute::getFields +( + const boolList& zone, + const GeometricField<Type, fvPatchField, volMesh>& phi +) +{ + if (zone.size() != phi.size()) + { + FatalErrorInFunction + << "size of zone: " << zone.size() + << "size of phi:" << phi.size() + << "do not match. Did the mesh change?" + << exit(FatalError); + + return Map<Field<Type>>(); + } + + + // Get values from other proc + Map<Type> neiValues = getDatafromOtherProc(zone, phi); + + Map<Field<Type>> stencilWithValues; + + DynamicField<Type> tmpField(100); + + forAll(zone,celli) + { + if (zone[celli]) + { + tmpField.clearStorage(); + + for (const label gblIdx : stencil_[celli]) + { + tmpField.append(getValue(phi,neiValues,gblIdx)); + } + + stencilWithValues.insert(celli,tmpField); + } + } + + return stencilWithValues; +} + + +template<typename Type> +Foam::Map<Type> Foam::zoneDistribute::getDatafromOtherProc +( + const boolList& zone, + const GeometricField<Type, fvPatchField, volMesh>& phi +) +{ + if (zone.size() != phi.size()) + { + FatalErrorInFunction + << "size of zone: " << zone.size() + << "size of phi:" << phi.size() + << "do not match. Did the mesh change?" + << exit(FatalError); + + return Map<Type>(); + } + + + // Get values from other proc + Map<Type> neiValues; + List<Map<Type>> sendValues(Pstream::nProcs()); + + if (Pstream::parRun()) + { + forAll(send_, domaini) + { + for (const label sendIdx : send_[domaini]) + { + sendValues[domaini].insert + ( + sendIdx, + getLocalValue(phi,globalNumbering().toLocal(sendIdx)) + ); + } + } + + PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking); + + // Stream data into buffer + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + if (domain != Pstream::myProcNo()) + { + // Put data into send buffer + UOPstream toDomain(domain, pBufs); + + toDomain << sendValues[domain]; + } + } + + // Wait until everything is written. + pBufs.finishedSends(); + + Map<Type> tmpValue; + + for (label domain = 0; domain < Pstream::nProcs(); domain++) + { + if (domain != Pstream::myProcNo()) + { + // Get data from send buffer + UIPstream fromDomain(domain, pBufs); + + fromDomain >> tmpValue; + + neiValues += tmpValue; + } + } + } + + return neiValues; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCPCStencil.C b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCPCStencil.C new file mode 100644 index 0000000000000000000000000000000000000000..1c91f5478aed90121336c673f6eec25a08cee168 --- /dev/null +++ b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCPCStencil.C @@ -0,0 +1,242 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "zoneCPCStencil.H" +#include "syncTools.H" +#include "ListOps.H" +#include "dummyTransform.H" +#include "emptyPolyPatch.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(zoneCPCStencil, 0); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::Map<bool> Foam::zoneCPCStencil::syncCoupledBoundaryPoints +( + const boolList& zone, + const labelList& boundaryPoints +) const +{ + const labelListList& pCells = mesh_.pointCells(); + + Map<bool> syncPoints; + + for (const label pointi : boundaryPoints) + { + bool updatePoint = false; + + // Check if point needs to be updated + for (const label celli : pCells[pointi]) + { + if (zone[celli]) + { + updatePoint = true; + break; + } + } + + if (updatePoint) + { + syncPoints.insert(pointi, true); + } + } + + syncTools::syncPointMap + ( + mesh_, + syncPoints, + orEqOp<bool>(), + Foam::dummyTransform() + ); + + return syncPoints; +} + + +void Foam::zoneCPCStencil::calcPointBoundaryData +( + const boolList& zone, + const boolList& isValidBFace, + const labelList& boundaryPoints, + Map<labelList>& neiGlobal +) const +{ + neiGlobal.resize(2*boundaryPoints.size()); + + labelHashSet pointGlobals; + + for (const label pointi : boundaryPoints) + { + neiGlobal.insert + ( + pointi, + calcFaceCells + ( + isValidBFace, + mesh_.pointFaces()[pointi], + pointGlobals + ) + ); + } + + syncTools::syncPointMap + ( + mesh_, + neiGlobal, + ListOps::unionEqOp(), + Foam::dummyTransform() + ); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::zoneCPCStencil::zoneCPCStencil(const fvMesh& mesh) +: + zoneCellStencils(mesh), + nonEmptyBoundaryPoints_(nonEmptyFacesPatch()().meshPoints()), + uptodate_(mesh.nCells(), false) +{ + // Mark boundary faces to be included in stencil (i.e. not coupled or empty) + validBoundaryFaces(isValidBFace_); +} + + +void Foam::zoneCPCStencil::calculateStencil +( + const boolList& zone, + labelListList& globalCellCells +) +{ + // Swap pointCells for coupled points + Map<bool> syncPoints = syncCoupledBoundaryPoints + ( + zone, + nonEmptyBoundaryPoints_ + ); + + labelList boundaryPoints(syncPoints.toc()); + + Map<labelList> neiGlobal; + calcPointBoundaryData + ( + zone, + isValidBFace_, + boundaryPoints, + neiGlobal + ); + + // add boundary Points first + + for (const label pointi : boundaryPoints) + { + const labelList& pGlobals = neiGlobal[pointi]; + + // Distribute to all pointCells + const labelList& pCells = mesh_.pointCells(pointi); + + for (const label celli : pCells) + { + // Insert pGlobals into globalCellCells + if (zone[celli] && !uptodate_[celli]) + { + merge + ( + globalNumbering().toGlobal(celli), + pGlobals, + globalCellCells[celli] + ); + + for (const label gblIdx : globalCellCells[celli]) + { + if (!globalNumbering().isLocal(gblIdx)) + { + needComm_.insert(celli); + } + } + } + } + } + + + neiGlobal.clear(); + + // Do remaining points cells + const labelListList& cPoints = mesh_.cellPoints(); + + forAll(zone,celli) + { + if (zone[celli] && !uptodate_[celli]) + { + for (const label pointi : cPoints[celli]) + { + labelList pCells = mesh_.pointCells(pointi); + + for (label& neiCelli : pCells) + { + neiCelli = globalNumbering().toGlobal(neiCelli); + } + + if (!uptodate_[celli]) + { + merge + ( + globalNumbering().toGlobal(celli), + pCells, + globalCellCells[celli] + ); + } + } + + uptodate_[celli] = true; + } + } +} + + +void Foam::zoneCPCStencil::updateMesh(const mapPolyMesh& mpm) +{ + if (mesh_.topoChanging()) + { + // resize map and globalIndex + zoneCellStencils::updateMesh(mpm); + + nonEmptyBoundaryPoints_ = nonEmptyFacesPatch()().meshPoints(); + uptodate_.resize(mesh_.nCells()); + uptodate_ = false; + validBoundaryFaces(isValidBFace_); + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCPCStencil.H b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCPCStencil.H new file mode 100644 index 0000000000000000000000000000000000000000..318fa38d9757ef3465873854424a09e3305b81bc --- /dev/null +++ b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCPCStencil.H @@ -0,0 +1,130 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::zoneCPCStencil + +Description + computes a cell point cell stencil in a narrow band. resizes in case + of topological change + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + zoneCPCStencil.C + +\*---------------------------------------------------------------------------*/ + +#ifndef zoneCPCStencil_H +#define zoneCPCStencil_H + +#include "zoneCellStencils.H" +#include "boolList.H" +#include "HashSet.H" +#include "Map.H" +#include "indirectPrimitivePatch.H" +#include "fvMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class zoneCPCStencil Declaration +\*---------------------------------------------------------------------------*/ + +class zoneCPCStencil +: + public zoneCellStencils +{ + // Private Data + + labelList nonEmptyBoundaryPoints_; + + //- is valid boundaryface ? + //- non valid face are on empty, wedge and processor patches + boolList isValidBFace_; + + //- cell is already uptodate + boolList uptodate_; + + + // Private Member Functions + + //- Sync boundary points + Map<bool> syncCoupledBoundaryPoints + ( + const boolList& zone, + const labelList& boundaryPoints + ) const; + + //- Calculates per point the neighbour data (= pointCells) + void calcPointBoundaryData + ( + const boolList& zone, + const boolList& isValidBFace, + const labelList& boundaryPoints, + Map<labelList>& neiGlobal + ) const; + + //- Calculate stencil + void calculateStencil + ( + const boolList& zone, + labelListList& globalCellCells + ); + + +public: + + //- Runtime information + TypeName("zoneCPCStencil"); + + + // Constructors + + //- Construct from all cells and boundary faces + explicit zoneCPCStencil(const fvMesh&); + + + // Member Functions + + //- Calculates per cell the neighbour data + //- (= cell or boundary in global numbering). + //- First element is always cell itself! + virtual void updateMesh(const mapPolyMesh& mpm); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCellStencils.C b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCellStencils.C new file mode 100644 index 0000000000000000000000000000000000000000..a397e036ab08d710a6abafee4e7a47078abda0a1 --- /dev/null +++ b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCellStencils.C @@ -0,0 +1,283 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "zoneCellStencils.H" +#include "syncTools.H" +#include "dummyTransform.H" +#include "emptyPolyPatch.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(zoneCellStencils, 0); +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +Foam::autoPtr<Foam::indirectPrimitivePatch> +Foam::zoneCellStencils::nonEmptyFacesPatch() const +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + label nNonEmpty = 0; + + for (const polyPatch& pp : patches) + { + if (!isA<emptyPolyPatch>(pp)) + { + nNonEmpty += pp.size(); + } + } + labelList nonEmptyFaces(nNonEmpty); + nNonEmpty = 0; + + for (const polyPatch& pp : patches) + { + if (!isA<emptyPolyPatch>(pp)) + { + label facei = pp.start(); + + forAll(pp, i) + { + nonEmptyFaces[nNonEmpty++] = facei++; + } + } + } + + return autoPtr<indirectPrimitivePatch>::New + ( + IndirectList<face> + ( + mesh_.faces(), + nonEmptyFaces + ), + mesh_.points() + ); +} + + +Foam::autoPtr<Foam::indirectPrimitivePatch> +Foam::zoneCellStencils::allCoupledFacesPatch() const +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + label nCoupled = 0; + + for (const polyPatch& pp : patches) + { + if (pp.coupled()) + { + nCoupled += pp.size(); + } + } + labelList coupledFaces(nCoupled); + nCoupled = 0; + + for (const polyPatch& pp : patches) + { + if (pp.coupled()) + { + label facei = pp.start(); + + forAll(pp, i) + { + coupledFaces[nCoupled++] = facei++; + } + } + } + + return autoPtr<indirectPrimitivePatch>::New + ( + IndirectList<face> + ( + mesh_.faces(), + coupledFaces + ), + mesh_.points() + ); +} + + +void Foam::zoneCellStencils::validBoundaryFaces(boolList& isValidBFace) const +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + isValidBFace.setSize(mesh_.nBoundaryFaces()); + + isValidBFace = true; + + for (const polyPatch& pp : patches) + { + if (pp.coupled() || isA<emptyPolyPatch>(pp)) + { + label bFacei = pp.start()-mesh_.nInternalFaces(); + forAll(pp, i) + { + isValidBFace[bFacei++] = false; + } + } + } +} + + +void Foam::zoneCellStencils::merge +( + const label globalI, + const labelList& pGlobals, + labelList& cCells +) +{ + labelHashSet set; + for (const label celli : cCells) + { + if (celli != globalI) + { + set.insert(celli); + } + } + + for (const label celli : pGlobals) + { + if (celli != globalI) + { + set.insert(celli); + } + } + + cCells.setSize(set.size()+1); + label n = 0; + cCells[n++] = globalI; + + for (const label seti : set) + { + cCells[n++] = seti; + } +} + + +void Foam::zoneCellStencils::insertFaceCells +( + const label exclude0, + const label exclude1, + const boolList& isValidBFace, + const labelList& faceLabels, + labelHashSet& globals +) const +{ + const labelList& own = mesh_.faceOwner(); + const labelList& nei = mesh_.faceNeighbour(); + + forAll(faceLabels, i) + { + label facei = faceLabels[i]; + + label globalOwn = globalNumbering().toGlobal(own[facei]); + if (globalOwn != exclude0 && globalOwn != exclude1) + { + globals.insert(globalOwn); + } + + if (mesh_.isInternalFace(facei)) + { + label globalNei = globalNumbering().toGlobal(nei[facei]); + if (globalNei != exclude0 && globalNei != exclude1) + { + globals.insert(globalNei); + } + } + else + { + const label bFacei = facei-mesh_.nInternalFaces(); + + if (isValidBFace[bFacei]) + { + label globalI = globalNumbering().toGlobal + ( + mesh_.nCells() + bFacei + ); + + if (globalI != exclude0 && globalI != exclude1) + { + globals.insert(globalI); + } + } + } + } +} + + +Foam::labelList Foam::zoneCellStencils::calcFaceCells +( + const boolList& isValidBFace, + const labelList& faceLabels, + labelHashSet& globals +) const +{ + globals.clear(); + + insertFaceCells + ( + -1, + -1, + isValidBFace, + faceLabels, + globals + ); + + return globals.toc(); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::zoneCellStencils::zoneCellStencils(const fvMesh& mesh) +: + MeshObject<fvMesh, Foam::UpdateableMeshObject, zoneCellStencils>(mesh), + labelListList(mesh.nCells()), + needComm_(), + globalNumbering_(mesh_.nCells() + mesh_.nBoundaryFaces()) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::zoneCellStencils::updateMesh(const mapPolyMesh& mpm) +{ + if (mesh_.topoChanging()) + { + globalNumbering_ = + globalIndex(mesh_.nCells() + mesh_.nBoundaryFaces()); + + static_cast<labelListList&>(*this) = labelListList(mesh_.nCells()); + needComm_.clear(); + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCellStencils.H b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCellStencils.H new file mode 100644 index 0000000000000000000000000000000000000000..16a1cde11b81c5700e8001099bf5fc7a72643127 --- /dev/null +++ b/src/finiteVolume/fvMesh/zoneDistribute/zoneStencils/zoneCellStencils.H @@ -0,0 +1,171 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::zoneCellStencils + +Description + base class for cell stencil in a narrow band + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + zoneCellStencils.C + +\*---------------------------------------------------------------------------*/ + +#ifndef zoneCellStencils_H +#define zoneCellStencils_H + +#include "boolList.H" +#include "HashSet.H" +#include "Map.H" +#include "indirectPrimitivePatch.H" +#include "MeshObject.H" +#include "fvMesh.H" +#include "globalIndex.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class zoneCellStencils Declaration +\*---------------------------------------------------------------------------*/ + +class zoneCellStencils +: + public MeshObject<fvMesh, UpdateableMeshObject, zoneCellStencils>, + public labelListList +{ +protected: + + // Protected Members + + labelHashSet needComm_; + + globalIndex globalNumbering_; + + + // Protected Member Functions + + //- Return patch of all coupled faces. + autoPtr<indirectPrimitivePatch> nonEmptyFacesPatch() const; + + //- Return patch of all coupled faces. + autoPtr<indirectPrimitivePatch> allCoupledFacesPatch() const; + + //- Valid boundary faces (not empty and not coupled) + void validBoundaryFaces(boolList& isValidBFace) const; + + //- Merge two lists and guarantee globalI is first. + static void merge + ( + const label globalI, + const labelList& pGlobals, + labelList& cCells + ); + + //- Collect cell neighbours of faces in global numbering + void insertFaceCells + ( + const label exclude0, + const label exclude1, + const boolList& nonEmptyFace, + const labelList& faceLabels, + labelHashSet& globals + ) const; + + //- Collect cell neighbours of faces in global numbering + labelList calcFaceCells + ( + const boolList& nonEmptyFace, + const labelList& faceLabels, + labelHashSet& globals + ) const; + + virtual void calculateStencil + ( + const boolList& zone, + labelListList& globalCellCells + ) = 0; + + +public: + + // Declare name of the class and its debug switch + TypeName("zoneCellStencils"); + + + // Constructors + + //- Construct from all cells and boundary faces + explicit zoneCellStencils(const fvMesh&); + + + // Member Functions + + //- Calculates per cell the neighbour data + // (= cell or boundary in global numbering). + // First element is always cell itself! + void updateStencil + ( + const boolList& zone + ) + { + calculateStencil(zone,*this); + } + + const labelHashSet& needsComm() + { + return needComm_; + } + + //- Global numbering for cells and boundary faces + const globalIndex& globalNumbering() const + { + return globalNumbering_; + } + + virtual void updateMesh(const mapPolyMesh& mpm); + + virtual bool movePoints() + { + // Do nothing + return false; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/sampling/Make/files b/src/sampling/Make/files index 2d2796dcca52bc16d6a55b397d4a345b5350d1a2..b3bd62acc9a9770decd1f542f3a7218ca8b27c8a 100644 --- a/src/sampling/Make/files +++ b/src/sampling/Make/files @@ -50,6 +50,7 @@ sampledSurface/sampledSurface/sampledSurface.C sampledSurface/sampledSurface/sampledSurfaceRegister.C sampledSurface/sampledSurfaces/sampledSurfaces.C sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C +sampledSurface/sampledInterface/sampledInterface.C readers = sampledSurface/readers diff --git a/src/sampling/Make/options b/src/sampling/Make/options index 6a8180f0ff1f90ef461bb00f52dcf69a1440a4b7..e0aa051f1526822c1c0308c14539cbead0f881c5 100644 --- a/src/sampling/Make/options +++ b/src/sampling/Make/options @@ -4,7 +4,8 @@ EXE_INC = \ -I$(LIB_SRC)/surfMesh/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ - -I$(LIB_SRC)/lagrangian/basic/lnInclude + -I$(LIB_SRC)/lagrangian/basic/lnInclude \ + -I$(LIB_SRC)/transportModels/geometricVoF/lnInclude LIB_LIBS = \ -lfiniteVolume \ @@ -12,4 +13,5 @@ LIB_LIBS = \ -lsurfMesh \ -lmeshTools \ -ldynamicMesh \ - -llagrangian + -llagrangian \ + -lgeometricVoF diff --git a/src/sampling/sampledSurface/sampledInterface/sampledInterface.C b/src/sampling/sampledSurface/sampledInterface/sampledInterface.C new file mode 100644 index 0000000000000000000000000000000000000000..5763a701975c2dc8fce6c16bd8d65aa25eeb205d --- /dev/null +++ b/src/sampling/sampledSurface/sampledInterface/sampledInterface.C @@ -0,0 +1,271 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "sampledInterface.H" +#include "dictionary.H" +#include "volFields.H" +#include "volPointInterpolation.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(sampledInterface, 0); + addNamedToRunTimeSelectionTable + ( + sampledSurface, + sampledInterface, + word, + interface + ); +} + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + + +bool Foam::sampledInterface::updateGeometry() const +{ + const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); + + // No update needed + if (fvm.time().timeIndex() == prevTimeIndex_) + { + return false; + } + + // Get any subMesh + if (!subMeshPtr_ && zoneID_.index() != -1) + { + const cellZone& cz = mesh().cellZones()[zoneID_.index()]; + + const polyBoundaryMesh& patches = mesh().boundaryMesh(); + + // Patch to put exposed internal faces into + const label exposedPatchi = patches.findPatchID(exposedPatchName_); + + DebugInfo + << "Allocating subset of size " << cz.size() + << " with exposed faces into patch " + << patches[exposedPatchi].name() << endl; + + subMeshPtr_.reset(new fvMeshSubset(fvm, cz, exposedPatchi)); + } + + + prevTimeIndex_ = fvm.time().timeIndex(); + + // Clear any stored topo + surfPtr_.clear(); + + // Clear derived data + clearGeom(); + + surfPtr_.reset + ( + new reconstructionSchemes::interface + ( + fvm.lookupObjectRef<reconstructionSchemes> + ( + "reconstructionScheme" + ).surface() + ) + ); + + return true; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::sampledInterface::sampledInterface +( + const word& name, + const polyMesh& mesh, + const dictionary& dict +) +: + sampledSurface(name, mesh, dict), + zoneID_(dict.getOrDefault<word>("zone", word::null), mesh.cellZones()), + exposedPatchName_(word::null), + surfPtr_(nullptr), + prevTimeIndex_(-1), + subMeshPtr_(nullptr) +{ + if (zoneID_.index() != -1) + { + dict.readEntry("exposedPatchName", exposedPatchName_); + + if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1) + { + FatalIOErrorInFunction(dict) + << "Cannot find patch " << exposedPatchName_ + << " in which to put exposed faces." << endl + << "Valid patches are " << mesh.boundaryMesh().names() + << exit(FatalIOError); + } + + DebugInfo + << "Restricting to cellZone " << zoneID_.name() + << " with exposed internal faces into patch " + << exposedPatchName_ << endl; + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::sampledInterface::needsUpdate() const +{ + const fvMesh& fvm = static_cast<const fvMesh&>(mesh()); + + return fvm.time().timeIndex() != prevTimeIndex_; +} + + +bool Foam::sampledInterface::expire() +{ + surfPtr_.clear(); + subMeshPtr_.clear(); + + // Clear derived data + clearGeom(); + + // Already marked as expired + if (prevTimeIndex_ == -1) + { + return false; + } + + // Force update + prevTimeIndex_ = -1; + return true; +} + + +bool Foam::sampledInterface::update() +{ + return updateGeometry(); +} + + +Foam::tmp<Foam::scalarField> Foam::sampledInterface::sample +( + const interpolation<scalar>& sampler +) const +{ + return sampleOnFaces(sampler); +} + + +Foam::tmp<Foam::vectorField> Foam::sampledInterface::sample +( + const interpolation<vector>& sampler +) const +{ + return sampleOnFaces(sampler); +} + + +Foam::tmp<Foam::sphericalTensorField> Foam::sampledInterface::sample +( + const interpolation<sphericalTensor>& sampler +) const +{ + return sampleOnFaces(sampler); +} + + +Foam::tmp<Foam::symmTensorField> Foam::sampledInterface::sample +( + const interpolation<symmTensor>& sampler +) const +{ + return sampleOnFaces(sampler); +} + + +Foam::tmp<Foam::tensorField> Foam::sampledInterface::sample +( + const interpolation<tensor>& sampler +) const +{ + return sampleOnFaces(sampler); +} + + +Foam::tmp<Foam::scalarField> Foam::sampledInterface::interpolate +( + const interpolation<scalar>& interpolator +) const +{ + return sampleOnPoints(interpolator); +} + + +Foam::tmp<Foam::vectorField> Foam::sampledInterface::interpolate +( + const interpolation<vector>& interpolator +) const +{ + return sampleOnPoints(interpolator); +} + +Foam::tmp<Foam::sphericalTensorField> Foam::sampledInterface::interpolate +( + const interpolation<sphericalTensor>& interpolator +) const +{ + return sampleOnPoints(interpolator); +} + + +Foam::tmp<Foam::symmTensorField> Foam::sampledInterface::interpolate +( + const interpolation<symmTensor>& interpolator +) const +{ + return sampleOnPoints(interpolator); +} + + +Foam::tmp<Foam::tensorField> Foam::sampledInterface::interpolate +( + const interpolation<tensor>& interpolator +) const +{ + return sampleOnPoints(interpolator); +} + + +void Foam::sampledInterface::print(Ostream& os) const +{ + os << "sampledInterface: " << name(); +} + + +// ************************************************************************* // diff --git a/src/sampling/sampledSurface/sampledInterface/sampledInterface.H b/src/sampling/sampledSurface/sampledInterface/sampledInterface.H new file mode 100644 index 0000000000000000000000000000000000000000..c77ecafb551039c6a7615cdeb34cef4f210ef259 --- /dev/null +++ b/src/sampling/sampledSurface/sampledInterface/sampledInterface.H @@ -0,0 +1,287 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::sampledInterface + +Description + A sampledSurface that calculates the PLIC interface in VoF simulations + Only works in combination with isoAdvector and a reconstruction scheme + + This is often embedded as part of a sampled surfaces function object. + +Usage + Example of function object partial specification: + \verbatim + surfaces + { + freeSurf + { + type interface; + interpolate false; + } + } + \endverbatim + + Where the sub-entries comprise: + \table + Property | Description | Required | Default + type | interface | yes | + \endtable + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + sampledInterface.C + +\*---------------------------------------------------------------------------*/ + +#ifndef sampledInterface_H +#define sampledInterface_H + +#include "sampledSurface.H" +#include "ZoneIDs.H" +#include "fvMeshSubset.H" +#include "reconstructionSchemes.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class sampledInterface Declaration +\*---------------------------------------------------------------------------*/ + +class sampledInterface +: + public sampledSurface +{ + // Private Data + + //- Zone name/index (if restricted to zones) + mutable cellZoneID zoneID_; + + //- For zones: patch to put exposed faces into + mutable word exposedPatchName_; + + mutable autoPtr<reconstructionSchemes::interface> surfPtr_; + + // Recreated for every interface + + //- Time at last call, also track if surface needs an update + mutable label prevTimeIndex_; + + //- Cached submesh + mutable autoPtr<fvMeshSubset> subMeshPtr_; + + + // Private Member Functions + + //- Create iso surface (if time has changed) + // Do nothing (and return false) if no update was needed + bool updateGeometry() const; + + //- Sample volume field onto surface faces + template<class Type> + tmp<Field<Type>> sampleOnFaces + ( + const interpolation<Type>& sampler + ) const; + + //- Interpolate volume field onto surface points + template<class Type> + tmp<Field<Type>> sampleOnPoints + ( + const interpolation<Type>& interpolator + ) const; + + +public: + + //- Runtime type information + TypeName("sampledInterface"); + + + // Constructors + + //- Construct from dictionary + sampledInterface + ( + const word& name, + const polyMesh& mesh, + const dictionary& dict + ); + + + //- Destructor + virtual ~sampledInterface() = default; + + + // Member Functions + + const reconstructionSchemes::interface& surface() const + { + return surfPtr_(); + } + + //- Does the surface need an update? + virtual bool needsUpdate() const; + + //- Mark the surface as needing an update. + // May also free up unneeded data. + // Return false if surface was already marked as expired. + virtual bool expire(); + + //- Update the surface as required. + // Do nothing (and return false) if no update was needed + virtual bool update(); + + + //- Points of surface + virtual const pointField& points() const + { + return surface().points(); + } + + //- Faces of surface + virtual const faceList& faces() const + { + return surface().surfFaces(); + } + + //- Const access to per-face zone/region information + virtual const labelList& zoneIds() const + { + return labelList::null(); + } + + //- Face area magnitudes + virtual const vectorField& Sf() const + { + return surface().Sf(); + } + + //- Face area magnitudes + virtual const scalarField& magSf() const + { + return surface().magSf(); + } + + //- Face centres + virtual const vectorField& Cf() const + { + return surface().Cf(); + } + + + // Sample + + //- Sample volume field onto surface faces + virtual tmp<scalarField> sample + ( + const interpolation<scalar>& sampler + ) const; + + //- Sample volume field onto surface faces + virtual tmp<vectorField> sample + ( + const interpolation<vector>& sampler + ) const; + + //- Sample volume field onto surface faces + virtual tmp<sphericalTensorField> sample + ( + const interpolation<sphericalTensor>& sampler + ) const; + + //- Sample volume field onto surface faces + virtual tmp<symmTensorField> sample + ( + const interpolation<symmTensor>& sampler + ) const; + + //- Sample volume field onto surface faces + virtual tmp<tensorField> sample + ( + const interpolation<tensor>& sampler + ) const; + + + // Interpolate + + //- Interpolate volume field onto surface points + virtual tmp<scalarField> interpolate + ( + const interpolation<scalar>& interpolator + ) const; + + //- Interpolate volume field onto surface points + virtual tmp<vectorField> interpolate + ( + const interpolation<vector>& interpolator + ) const; + + //- Interpolate volume field onto surface points + virtual tmp<sphericalTensorField> interpolate + ( + const interpolation<sphericalTensor>& interpolator + ) const; + + //- Interpolate volume field onto surface points + virtual tmp<symmTensorField> interpolate + ( + const interpolation<symmTensor>& interpolator + ) const; + + //- Interpolate volume field onto surface points + virtual tmp<tensorField> interpolate + ( + const interpolation<tensor>& interpolator + ) const; + + + // Output + + //- Write + virtual void print(Ostream&) const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "sampledInterfaceTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/applications/solvers/multiphase/interIsoFoam/alphaCourantNo.H b/src/sampling/sampledSurface/sampledInterface/sampledInterfaceTemplates.C similarity index 60% rename from applications/solvers/multiphase/interIsoFoam/alphaCourantNo.H rename to src/sampling/sampledSurface/sampledInterface/sampledInterfaceTemplates.C index cc05c618fe2f765a82b7f1ce822580770180b63c..a39ef1697f57f27dce441839eb86772177d9086b 100644 --- a/applications/solvers/multiphase/interIsoFoam/alphaCourantNo.H +++ b/src/sampling/sampledSurface/sampledInterface/sampledInterfaceTemplates.C @@ -5,7 +5,8 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2011-2017 OpenFOAM Foundation + Copyright (C) 2019-2019 OpenCFD Ltd. + Copyright (C) 2019-2020 DLR ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -23,37 +24,48 @@ License You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. -Global - alphaCourantNo +\*---------------------------------------------------------------------------*/ -Description - Calculates and outputs the mean and maximum Courant Numbers. +#include "sampledInterface.H" +#include "volFieldsFwd.H" +#include "pointFields.H" +#include "volPointInterpolation.H" -\*---------------------------------------------------------------------------*/ +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // -scalar maxAlphaCo +template<class Type> +Foam::tmp<Foam::Field<Type>> +Foam::sampledInterface::sampleOnFaces ( - runTime.controlDict().get<scalar>("maxAlphaCo") -); + const interpolation<Type>& sampler +) const +{ + updateGeometry(); // Recreate geometry if time has changed + + return sampledSurface::sampleOnFaces + ( + sampler, + surface().meshCells(), + surface(), + points() + ); +} -scalar alphaCoNum = 0.0; -scalar meanAlphaCoNum = 0.0; -if (mesh.nInternalFaces()) +template<class Type> +Foam::tmp<Foam::Field<Type>> +Foam::sampledInterface::sampleOnPoints +( + const interpolation<Type>& interpolator +) const { - scalarField sumPhi + notImplemented ( - mixture.nearInterface()().primitiveField() - *fvc::surfaceSum(mag(phi))().primitiveField() + "interpolation on points values currently not implemented" ); - alphaCoNum = 0.5*gMax(sumPhi/mesh.V().field())*runTime.deltaTValue(); - - meanAlphaCoNum = - 0.5*(gSum(sumPhi)/gSum(mesh.V().field()))*runTime.deltaTValue(); + return nullptr; } -Info<< "Interface Courant Number mean: " << meanAlphaCoNum - << " max: " << alphaCoNum << endl; // ************************************************************************* // diff --git a/src/transportModels/Allwmake b/src/transportModels/Allwmake index c0e9865b7b87a58a2051683f455ac7676723dba6..0249ae4823f5810b7eb2a1a5d643417574433785 100755 --- a/src/transportModels/Allwmake +++ b/src/transportModels/Allwmake @@ -10,5 +10,6 @@ wmake $targetType twoPhaseProperties wmake $targetType incompressible wmake $targetType compressible wmake $targetType immiscibleIncompressibleTwoPhaseMixture +wmake $targetType geometricVoF #------------------------------------------------------------------------------ diff --git a/src/transportModels/geometricVoF/Make/files b/src/transportModels/geometricVoF/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..a2c382a1ed7105d3c1fcc5c6ce8d9e964665c540 --- /dev/null +++ b/src/transportModels/geometricVoF/Make/files @@ -0,0 +1,22 @@ +cellCuts/cutCell/cutCell.C +cellCuts/cutCell/cutCellPLIC.C +cellCuts/cutCell/cutCellIso.C +cellCuts/cutFace/cutFace.C +cellCuts/cutFace/cutFacePLIC.C +cellCuts/cutFace/cutFaceAdvect.C +cellCuts/cutFace/cutFaceIso.C +surfaceIterators/surfaceIteratorPLIC.C +surfaceIterators/surfaceIteratorIso.C + +reconstructedDistanceFunction/reconstructedDistanceFunction.C + +reconstructionSchemes/reconstructionSchemesNew.C +reconstructionSchemes/reconstructionSchemes.C +reconstructionSchemes/isoSchemes/isoAlpha/isoAlpha.C + +reconstructionSchemes/plicSchemes/gradAlpha/gradAlpha.C +reconstructionSchemes/plicSchemes/plicRDF/plicRDF.C + +advectionSchemes/isoAdvection/isoAdvection.C + +LIB = $(FOAM_LIBBIN)/libgeometricVoF diff --git a/src/transportModels/geometricVoF/Make/options b/src/transportModels/geometricVoF/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..31ded987a140d92d9bfcf61c4f142c11e2c6d380 --- /dev/null +++ b/src/transportModels/geometricVoF/Make/options @@ -0,0 +1,15 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/fileFormats/lnInclude \ + -I$(LIB_SRC)/surfMesh/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude \ + -I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \ + -I$(LIB_SRC)/transportModels/twoPhaseProperties/lnInclude + +LIB_LIBS = \ + -lfiniteVolume \ + -lfileFormats \ + -lsurfMesh \ + -lmeshTools \ + -ltwoPhaseMixture \ + -ltwoPhaseProperties diff --git a/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvection.C b/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvection.C new file mode 100644 index 0000000000000000000000000000000000000000..e64d80dbee32875973654adabf0403b51c093c2c --- /dev/null +++ b/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvection.C @@ -0,0 +1,643 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Modified code Copyright (C) 2016-2017 OpenCFD Ltd. + Modified code Copyright (C) 2019 Johan Roenby + Modified code Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "isoAdvection.H" +#include "volFields.H" +#include "interpolationCellPoint.H" +#include "volPointInterpolation.H" +#include "fvcSurfaceIntegrate.H" +#include "fvcGrad.H" +#include "upwind.H" +#include "cellSet.H" +#include "meshTools.H" +#include "OBJstream.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(isoAdvection, 0); +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::isoAdvection::isoAdvection +( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U +) +: + mesh_(alpha1.mesh()), + dict_(mesh_.solverDict(alpha1.name())), + alpha1_(alpha1), + alpha1In_(alpha1.ref()), + phi_(phi), + U_(U), + dVf_ + ( + IOobject + ( + "dVf_", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + dimensionedScalar(dimVol, Zero) + ), + alphaPhi_ + ( + IOobject + ( + "alphaPhi_", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh_, + dimensionedScalar(dimVol/dimTime, Zero) + ), + advectionTime_(0), + + // Tolerances and solution controls + nAlphaBounds_(dict_.getOrDefault<label>("nAlphaBounds", 3)), + isoFaceTol_(dict_.getOrDefault<scalar>("isoFaceTol", 1e-8)), + surfCellTol_(dict_.getOrDefault<scalar>("surfCellTol", 1e-8)), + writeIsoFacesToFile_(dict_.getOrDefault("writeIsoFaces", false)), + + // Cell cutting data + surfCells_(label(0.2*mesh_.nCells())), + surf_(reconstructionSchemes::New(alpha1_, phi_, U_, dict_)), + advectFace_(alpha1.mesh(), alpha1), + bsFaces_(label(0.2*mesh_.nBoundaryFaces())), + bsx0_(bsFaces_.size()), + bsn0_(bsFaces_.size()), + bsUn0_(bsFaces_.size()), + + // Parallel run data + procPatchLabels_(mesh_.boundary().size()), + surfaceCellFacesOnProcPatches_(0) +{ + cutFaceAdvect::debug = debug; + + // Prepare lists used in parallel runs + if (Pstream::parRun()) + { + // Force calculation of required demand driven data (else parallel + // communication may crash) + mesh_.cellCentres(); + mesh_.cellVolumes(); + mesh_.faceCentres(); + mesh_.faceAreas(); + mesh_.magSf(); + mesh_.boundaryMesh().patchID(); + mesh_.cellPoints(); + mesh_.cellCells(); + mesh_.cells(); + + // Get boundary mesh and resize the list for parallel comms + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + surfaceCellFacesOnProcPatches_.resize(patches.size()); + + // Append all processor patch labels to the list + forAll(patches, patchi) + { + if + ( + isA<processorPolyPatch>(patches[patchi]) + && patches[patchi].size() > 0 + ) + { + procPatchLabels_.append(patchi); + } + } + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::isoAdvection::timeIntegratedFlux() +{ + // Get time step + const scalar dt = mesh_.time().deltaTValue(); + + // Create object for interpolating velocity to isoface centres + interpolationCellPoint<vector> UInterp(U_); + + // For each downwind face of each surface cell we "isoadvect" to find dVf + label nSurfaceCells = 0; + + // Clear out the data for re-use and reset list containing information + // whether cells could possibly need bounding + clearIsoFaceData(); + + // Get necessary references + const scalarField& phiIn = phi_.primitiveField(); + const scalarField& magSfIn = mesh_.magSf().primitiveField(); + scalarField& dVfIn = dVf_.primitiveFieldRef(); + + // Get necessary mesh data + const cellList& cellFaces = mesh_.cells(); + const labelList& own = mesh_.faceOwner(); + + + // Storage for isoFace points. Only used if writeIsoFacesToFile_ + DynamicList<List<point>> isoFacePts; + const DynamicField<label>& interfaceLabels = surf_->interfaceLabels(); + + // Loop through cells + forAll(interfaceLabels, i) + { + const label celli = interfaceLabels[i]; + if (mag(surf_->normal()[celli]) != 0) + { + + // This is a surface cell, increment counter, append and mark cell + nSurfaceCells++; + surfCells_.append(celli); + + DebugInfo + << "\n------------ Cell " << celli << " with alpha1 = " + << alpha1In_[celli] << " and 1-alpha1 = " + << 1.0 - alpha1In_[celli] << " ------------" + << endl; + + // Cell is cut + const point x0 = surf_->centre()[celli]; + vector n0 = -surf_->normal()[celli]; + n0 /= (mag(n0)); + + // Get the speed of the isoface by interpolating velocity and + // dotting it with isoface unit normal + const scalar Un0 = UInterp.interpolate(x0, celli) & n0; + + DebugInfo + << "calcIsoFace gives initial surface: \nx0 = " << x0 + << ", \nn0 = " << n0 << ", \nUn0 = " + << Un0 << endl; + + // Estimate time integrated flux through each downwind face + // Note: looping over all cell faces - in reduced-D, some of + // these faces will be on empty patches + const cell& celliFaces = cellFaces[celli]; + forAll(celliFaces, fi) + { + const label facei = celliFaces[fi]; + + if (mesh_.isInternalFace(facei)) + { + bool isDownwindFace = false; + + if (celli == own[facei]) + { + if (phiIn[facei] >= 0) + { + isDownwindFace = true; + } + } + else + { + if (phiIn[facei] < 0) + { + isDownwindFace = true; + } + } + + if (isDownwindFace) + { + dVfIn[facei] = advectFace_.timeIntegratedFaceFlux + ( + facei, + x0, + n0, + Un0, + dt, + phiIn[facei], + magSfIn[facei] + ); + } + + } + else + { + bsFaces_.append(facei); + bsx0_.append(x0); + bsn0_.append(n0); + bsUn0_.append(Un0); + + // Note: we must not check if the face is on the + // processor patch here. + } + } + } + } + + // Get references to boundary fields + const polyBoundaryMesh& boundaryMesh = mesh_.boundaryMesh(); + const surfaceScalarField::Boundary& phib = phi_.boundaryField(); + const surfaceScalarField::Boundary& magSfb = mesh_.magSf().boundaryField(); + surfaceScalarField::Boundary& dVfb = dVf_.boundaryFieldRef(); + const label nInternalFaces = mesh_.nInternalFaces(); + + // Loop through boundary surface faces + forAll(bsFaces_, i) + { + // Get boundary face index (in the global list) + const label facei = bsFaces_[i]; + const label patchi = boundaryMesh.patchID()[facei - nInternalFaces]; + const label start = boundaryMesh[patchi].start(); + + if (phib[patchi].size()) + { + const label patchFacei = facei - start; + const scalar phiP = phib[patchi][patchFacei]; + + if (phiP >= 0) + { + const scalar magSf = magSfb[patchi][patchFacei]; + + dVfb[patchi][patchFacei] = advectFace_.timeIntegratedFaceFlux + ( + facei, + bsx0_[i], + bsn0_[i], + bsUn0_[i], + dt, + phiP, + magSf + ); + + // Check if the face is on processor patch and append it to + // the list if necessary + checkIfOnProcPatch(facei); + } + } + } + + // Synchronize processor patches + syncProcPatches(dVf_, phi_); + + writeIsoFaces(isoFacePts); + + DebugInfo << "Number of isoAdvector surface cells = " + << returnReduce(nSurfaceCells, sumOp<label>()) << endl; +} + + +void Foam::isoAdvection::setDownwindFaces +( + const label celli, + DynamicLabelList& downwindFaces +) const +{ + DebugInFunction << endl; + + // Get necessary mesh data and cell information + const labelList& own = mesh_.faceOwner(); + const cellList& cells = mesh_.cells(); + const cell& c = cells[celli]; + + downwindFaces.clear(); + + // Check all faces of the cell + forAll(c, fi) + { + // Get face and corresponding flux + const label facei = c[fi]; + const scalar phi = faceValue(phi_, facei); + + if (own[facei] == celli) + { + if (phi >= 0) + { + downwindFaces.append(facei); + } + } + else if (phi < 0) + { + downwindFaces.append(facei); + } + } + + downwindFaces.shrink(); +} + + +Foam::scalar Foam::isoAdvection::netFlux +( + const surfaceScalarField& dVf, + const label celli +) const +{ + scalar dV = 0; + + // Get face indices + const cell& c = mesh_.cells()[celli]; + + // Get mesh data + const labelList& own = mesh_.faceOwner(); + + forAll(c, fi) + { + const label facei = c[fi]; + const scalar dVff = faceValue(dVf, facei); + + if (own[facei] == celli) + { + dV += dVff; + } + else + { + dV -= dVff; + } + } + + return dV; +} + + +Foam::DynamicList<Foam::label> Foam::isoAdvection::syncProcPatches +( + surfaceScalarField& dVf, + const surfaceScalarField& phi, + bool returnSyncedFaces +) +{ + DynamicLabelList syncedFaces(0); + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + if (Pstream::parRun()) + { + PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking); + + // Send + forAll(procPatchLabels_, i) + { + const label patchi = procPatchLabels_[i]; + + const processorPolyPatch& procPatch = + refCast<const processorPolyPatch>(patches[patchi]); + + UOPstream toNbr(procPatch.neighbProcNo(), pBufs); + const scalarField& pFlux = dVf.boundaryField()[patchi]; + + const List<label>& surfCellFacesOnProcPatch = + surfaceCellFacesOnProcPatches_[patchi]; + + const UIndirectList<scalar> dVfPatch + ( + pFlux, + surfCellFacesOnProcPatch + ); + + toNbr << surfCellFacesOnProcPatch << dVfPatch; + } + + pBufs.finishedSends(); + + + // Receive and combine + forAll(procPatchLabels_, patchLabeli) + { + const label patchi = procPatchLabels_[patchLabeli]; + + const processorPolyPatch& procPatch = + refCast<const processorPolyPatch>(patches[patchi]); + + UIPstream fromNeighb(procPatch.neighbProcNo(), pBufs); + List<label> faceIDs; + List<scalar> nbrdVfs; + + fromNeighb >> faceIDs >> nbrdVfs; + if (returnSyncedFaces) + { + List<label> syncedFaceI(faceIDs); + for (label& faceI : syncedFaceI) + { + faceI += procPatch.start(); + } + syncedFaces.append(syncedFaceI); + } + + if (debug) + { + Pout<< "Received at time = " << mesh_.time().value() + << ": surfCellFacesOnProcPatch = " << faceIDs << nl + << "Received at time = " << mesh_.time().value() + << ": dVfPatch = " << nbrdVfs << endl; + } + + // Combine fluxes + scalarField& localFlux = dVf.boundaryFieldRef()[patchi]; + + forAll(faceIDs, i) + { + const label facei = faceIDs[i]; + localFlux[facei] = - nbrdVfs[i]; + if (debug && mag(localFlux[facei] + nbrdVfs[i]) > 10*SMALL) + { + Pout<< "localFlux[facei] = " << localFlux[facei] + << " and nbrdVfs[i] = " << nbrdVfs[i] + << " for facei = " << facei << endl; + } + } + } + + if (debug) + { + // Write out results for checking + forAll(procPatchLabels_, patchLabeli) + { + const label patchi = procPatchLabels_[patchLabeli]; + const scalarField& localFlux = dVf.boundaryField()[patchi]; + Pout<< "time = " << mesh_.time().value() << ": localFlux = " + << localFlux << endl; + } + } + + // Reinitialising list used for minimal parallel communication + forAll(surfaceCellFacesOnProcPatches_, patchi) + { + surfaceCellFacesOnProcPatches_[patchi].clear(); + } + } + + return syncedFaces; +} + + +void Foam::isoAdvection::checkIfOnProcPatch(const label facei) +{ + if (!mesh_.isInternalFace(facei)) + { + const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); + const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()]; + + if (isA<processorPolyPatch>(pbm[patchi]) && pbm[patchi].size()) + { + const label patchFacei = pbm[patchi].whichFace(facei); + surfaceCellFacesOnProcPatches_[patchi].append(patchFacei); + } + } +} + + + + +void Foam::isoAdvection::applyBruteForceBounding() +{ + bool alpha1Changed = false; + + const scalar snapAlphaTol = dict_.getOrDefault<scalar>("snapTol", 0); + if (snapAlphaTol > 0) + { + alpha1_ = + alpha1_ + *pos0(alpha1_ - snapAlphaTol) + *neg0(alpha1_ - (1.0 - snapAlphaTol)) + + pos0(alpha1_ - (1.0 - snapAlphaTol)); + + alpha1Changed = true; + } + + if (dict_.getOrDefault("clip", true)) + { + alpha1_ = min(scalar(1), max(scalar(0), alpha1_)); + alpha1Changed = true; + } + + if (alpha1Changed) + { + alpha1_.correctBoundaryConditions(); + } +} + + +void Foam::isoAdvection::writeSurfaceCells() const +{ + if (!mesh_.time().writeTime()) return; + + if (dict_.getOrDefault("writeSurfCells", false)) + { + cellSet cSet + ( + IOobject + ( + "surfCells", + mesh_.time().timeName(), + mesh_, + IOobject::NO_READ + ) + ); + + cSet.insert(surfCells_); + + cSet.write(); + } +} + +void Foam::isoAdvection::writeIsoFaces +( + const DynamicList<List<point>>& faces +) const +{ + if (!writeIsoFacesToFile_ || !mesh_.time().writeTime()) return; + + // Writing isofaces to obj file for inspection, e.g. in paraview + const fileName outputFile + ( + mesh_.time().globalPath() + / "isoFaces" + / word::printf("isoFaces_%012d.obj", mesh_.time().timeIndex()) + ); + + if (Pstream::parRun()) + { + // Collect points from all the processors + List<DynamicList<List<point>>> allProcFaces(Pstream::nProcs()); + allProcFaces[Pstream::myProcNo()] = faces; + Pstream::gatherList(allProcFaces); + + if (Pstream::master()) + { + mkDir(outputFile.path()); + OBJstream os(outputFile); + Info<< nl << "isoAdvection: writing iso faces to file: " + << os.name() << nl << endl; + + face f; + forAll(allProcFaces, proci) + { + const DynamicList<List<point>>& procFacePts = + allProcFaces[proci]; + + forAll(procFacePts, i) + { + const List<point>& facePts = procFacePts[i]; + + if (facePts.size() != f.size()) + { + f = face(identity(facePts.size())); + } + + os.write(f, facePts, false); + } + } + } + } + else + { + mkDir(outputFile.path()); + OBJstream os(outputFile); + Info<< nl << "isoAdvection: writing iso faces to file: " + << os.name() << nl << endl; + + face f; + forAll(faces, i) + { + const List<point>& facePts = faces[i]; + + if (facePts.size() != f.size()) + { + f = face(identity(facePts.size())); + } + + os.write(f, facePts, false); + } + } +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.H b/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvection.H similarity index 79% rename from src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.H rename to src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvection.H index 7f71959b1f7dd6dc5c8952757a69a8d97ebf3a95..41743a30a208fa651c6260f5685d0841fc5cc74a 100644 --- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.H +++ b/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvection.H @@ -6,8 +6,9 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2016-2017 DHI - Copyright (C) 2018 Johan Roenby - Copyright (C) 2016-2017, 2019 OpenCFD Ltd. + Modified code Copyright (C) 2016-2019 OpenCFD Ltd. + Modified code Copyright (C) 2018 Johan Roenby + Modified code Copyright (C) 2019 DLR ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -37,14 +38,15 @@ Description isosurfaces. Reference: - \verbatim - Roenby, J., Bredmose, H. and Jasak, H. (2016). - A computational method for sharp interface advection - Royal Society Open Science, 3 - doi 10.1098/rsos.160405 - \endverbatim + \verbatim + Roenby, J., Bredmose, H. and Jasak, H. (2016). + A computational method for sharp interface advection + Royal Society Open Science, 3 + doi 10.1098/rsos.160405 + \endverbatim Original code supplied by Johan Roenby, DHI (2016) + Modified Henning Scheufler, DLR SourceFiles isoAdvection.C @@ -58,10 +60,12 @@ SourceFiles #include "fvMesh.H" #include "volFieldsFwd.H" #include "surfaceFields.H" +#include "fvc.H" #include "className.H" -#include "isoCutCell.H" -#include "isoCutFace.H" +#include "reconstructionSchemes.H" +#include "cutFaceAdvect.H" #include "bitSet.H" +#include "zeroField.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -105,16 +109,13 @@ class isoAdvection //- Face volumetric water transport surfaceScalarField dVf_; + //- Face volumetric transport + surfaceScalarField alphaPhi_; + //- Time spent performing interface advection scalar advectionTime_; - // Point interpolation data - - //- VOF field interpolated to mesh points - scalarField ap_; - - // Switches and tolerances. Tolerances need to go into toleranceSwitches //- Number of alpha bounding steps @@ -127,12 +128,6 @@ class isoAdvection // Those with surfCellTol_ < alpha1 < 1 - surfCellTol_ scalar surfCellTol_; - //- Switch controlling whether to use isoface normals for interface - // orientation (default corresponding to false) to base it on - // a smoothed gradient of alpha calculation (giving better results - // on tri on tet meshes). - bool gradAlphaBasedNormal_; - //- Print isofaces in a <case>/isoFaces/isoFaces_#N.vtk files. // Intended for debugging bool writeIsoFacesToFile_; @@ -142,17 +137,11 @@ class isoAdvection //- List of surface cells DynamicLabelList surfCells_; - //- Cell cutting object - isoCutCell isoCutCell_; + //- Pointer to reconstruction scheme + autoPtr<reconstructionSchemes> surf_; - //- Face cutting object - isoCutFace isoCutFace_; - - //- Cells that have been touched by the bounding step - bitSet cellIsBounded_; - - //- True for all surface cells and their neighbours - bitSet checkBounding_; + //- An isoCutFace object to get access to its face cutting functionality + cutFaceAdvect advectFace_; //- Storage for boundary faces downwind to a surface cell DynamicLabelList bsFaces_; @@ -166,8 +155,6 @@ class isoAdvection //- Storage for boundary surface iso face speed DynamicScalarList bsUn0_; - //- Storage for boundary surface iso value - DynamicScalarList bsf0_; // Additional data for parallel runs @@ -195,21 +182,6 @@ class isoAdvection //- For each face calculate volumetric face transport during dt void timeIntegratedFlux(); - //- Set ap_ values of celli's vertices in accordance with the - // unit normal of celli as obtained from cellNoramlsIn. - void setCellVertexValues - ( - const label celli, - const vectorField& cellNormalsIn - ); - - //- Function used to normalise and smoothen grad(alpha) in case - // gradAlphaBasedNormal_ is true. - void normaliseAndSmooth - ( - volVectorField& cellN - ); - //- For a given cell return labels of faces fluxing out of this cell // (based on sign of phi) void setDownwindFaces @@ -218,15 +190,23 @@ class isoAdvection DynamicLabelList& downwindFaces ) const; - // Limit fluxes - void limitFluxes(); + // LimitFluxes + template < class SpType, class SuType > + void limitFluxes + ( + const SpType& Sp, + const SuType& Su + ); // Bound fluxes - void boundFromAbove + template < class SpType, class SuType > + void boundFlux ( const scalarField& alpha1, - surfaceScalarField& dVfcorrected, - DynamicLabelList& correctedFaces + surfaceScalarField& dVfcorrectionValues, + DynamicLabelList& correctedFaces, + const SpType& Sp, + const SuType& Su ); //- Given the face volume transport dVf calculates the total volume @@ -256,17 +236,6 @@ class isoAdvection bsx0_.clear(); bsn0_.clear(); bsUn0_.clear(); - bsf0_.clear(); - - if (mesh_.topoChanging()) - { - // Introduced resizing to cope with changing meshes - checkBounding_.resize(mesh_.nCells()); - cellIsBounded_.resize(mesh_.nCells()); - ap_.resize(mesh_.nPoints()); - } - checkBounding_ = false; - cellIsBounded_ = false; } @@ -294,10 +263,11 @@ class isoAdvection // Parallel run handling functions //- Synchronize dVf across processor boundaries using upwind value - void syncProcPatches + DynamicList<label> syncProcPatches ( surfaceScalarField& dVf, - const surfaceScalarField& phi + const surfaceScalarField& phi, + bool returnSyncedFaces=false ); //- Check if the face is on processor patch and append it to the @@ -330,13 +300,20 @@ public: //- Advect the free surface. Updates alpha field, taking into account // multiple calls within a single time step. - void advect(); + template < class SpType, class SuType > + void advect(const SpType& Sp, const SuType& Su); //- Apply the bounding based on user inputs void applyBruteForceBounding(); // Access functions + //- Return reconstructionSchemes + reconstructionSchemes& surf() + { + return surf_(); + } + //- Return alpha field const volScalarField& alpha() const { @@ -352,9 +329,6 @@ public: //- Return cellSet of surface cells void writeSurfaceCells() const; - //- Return cellSet of bounded cells - void writeBoundedCells() const; - //- Return mass flux tmp<surfaceScalarField> getRhoPhi ( @@ -372,6 +346,31 @@ public: ); } + //- Return mass flux + tmp<surfaceScalarField> getRhoPhi + ( + const volScalarField& rho1, + const volScalarField& rho2 + ) + { + return tmp<surfaceScalarField> + ( + new surfaceScalarField + ( + "rhoPhi", + fvc::interpolate(rho1 - rho2)*alphaPhi_ + + fvc::interpolate(rho2)*phi_ + ) + ); + } + + //- reference to alphaPhi + const surfaceScalarField& alphaPhi() const + { + return alphaPhi_; + } + + //- time spend in the advection step scalar advectionTime() const { return advectionTime_; diff --git a/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvectionTemplates.C b/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvectionTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..82bb1e2fae043982bdb0a659ba0906382ec11f7e --- /dev/null +++ b/src/transportModels/geometricVoF/advectionSchemes/isoAdvection/isoAdvectionTemplates.C @@ -0,0 +1,430 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Modified code Copyright (C) 2016-2017 OpenCFD Ltd. + Modified code Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "isoAdvection.H" +#include "fvcSurfaceIntegrate.H" +#include "upwind.H" + +// ************************************************************************* // + +template<typename Type> +Type Foam::isoAdvection::faceValue +( + const GeometricField<Type, fvsPatchField, surfaceMesh>& f, + const label facei +) const +{ + if (mesh_.isInternalFace(facei)) + { + return f.primitiveField()[facei]; + } + else + { + const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); + + // Boundary face. Find out which face of which patch + const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()]; + + if (patchi < 0 || patchi >= pbm.size()) + { + FatalErrorInFunction + << "Cannot find patch for face " << facei + << abort(FatalError); + } + + // Handle empty patches + const polyPatch& pp = pbm[patchi]; + if (isA<emptyPolyPatch>(pp) || pp.empty()) + { + return pTraits<Type>::zero; + } + + const label patchFacei = pp.whichFace(facei); + return f.boundaryField()[patchi][patchFacei]; + } +} + + +template<typename Type> +void Foam::isoAdvection::setFaceValue +( + GeometricField<Type, fvsPatchField, surfaceMesh>& f, + const label facei, + const Type& value +) const +{ + if (mesh_.isInternalFace(facei)) + { + f.primitiveFieldRef()[facei] = value; + } + else + { + const polyBoundaryMesh& pbm = mesh_.boundaryMesh(); + + // Boundary face. Find out which face of which patch + const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()]; + + if (patchi < 0 || patchi >= pbm.size()) + { + FatalErrorInFunction + << "Cannot find patch for face " << facei + << abort(FatalError); + } + + // Handle empty patches + const polyPatch& pp = pbm[patchi]; + if (isA<emptyPolyPatch>(pp) || pp.empty()) + { + return; + } + + const label patchFacei = pp.whichFace(facei); + + f.boundaryFieldRef()[patchi][patchFacei] = value; + } +} + + +template<class SpType, class SuType> +void Foam::isoAdvection::limitFluxes +( + const SpType& Sp, + const SuType& Su +) +{ + DebugInFunction << endl; + + const scalar aTol = 1.0e-12; // Note: tolerances + scalar maxAlphaMinus1 = gMax(alpha1_) - 1; // max(alphaNew - 1); + scalar minAlpha = gMin(alpha1_); // min(alphaNew); + const label nOvershoots = 20; // sum(pos0(alphaNew - 1 - aTol)); + + const labelList& owner = mesh_.faceOwner(); + const labelList& neighbour = mesh_.faceNeighbour(); + + DebugInfo + << "isoAdvection: Before conservative bounding: min(alpha) = " + << minAlpha << ", max(alpha) = 1 + " << maxAlphaMinus1 << endl; + + surfaceScalarField dVfcorrectionValues("dVfcorrectionValues", dVf_*0.0); + + + // Loop number of bounding steps + for (label n = 0; n < nAlphaBounds_; n++) + { + if (maxAlphaMinus1 > aTol || minAlpha < -aTol) // Note: tolerances + { + DebugInfo << "boundAlpha... " << endl; + + DynamicList<label> correctedFaces(3*nOvershoots); + dVfcorrectionValues = dimensionedScalar(dimVolume, Zero); + boundFlux(alpha1In_, dVfcorrectionValues, correctedFaces,Sp,Su); + + correctedFaces.append + ( + syncProcPatches(dVfcorrectionValues, phi_,true) + ); + + labelHashSet alreadyUpdated; + forAll(correctedFaces, fi) + { + label facei = correctedFaces[fi]; + if (alreadyUpdated.insert(facei)) + { + checkIfOnProcPatch(facei); + const label own = owner[facei]; + + alpha1_[own] += + -faceValue(dVfcorrectionValues, facei)/mesh_.V()[own]; + if (mesh_.isInternalFace(facei)) + { + const label nei = neighbour[facei]; + alpha1_[nei] -= + -faceValue(dVfcorrectionValues, facei)/mesh_.V()[nei]; + } + + // Change to treat boundaries consistently + scalar corrVf = + faceValue(dVf_, facei) + + faceValue(dVfcorrectionValues, facei); + + setFaceValue(dVf_, facei, corrVf); + } + } + syncProcPatches(dVf_, phi_); + } + else + { + break; + } + + maxAlphaMinus1 = gMax(alpha1_) - 1; // max(alphaNew - 1); + minAlpha = gMin(alpha1_); // min(alphaNew); + + if (debug) + { + // Check if still unbounded + //scalarField alphaNew(alpha1In_ - fvc::surfaceIntegrate(dVf_)()); + label maxAlphaMinus1 = max(alpha1_.primitiveField() - 1); + scalar minAlpha = min(alpha1_.primitiveField()); + label nUndershoots = sum(neg0(alpha1_.primitiveField() + aTol)); + label nOvershoots = sum(pos0(alpha1_.primitiveField() - 1 - aTol)); + + Info<< "After bounding number " << n + 1 << " of time " + << mesh_.time().value() << ":" << nl + << "nOvershoots = " << nOvershoots << " with max(alpha1_-1) = " + << maxAlphaMinus1 << " and nUndershoots = " << nUndershoots + << " with min(alpha1_) = " << minAlpha << endl; + } + } + + alpha1_.correctBoundaryConditions(); + +} + + +template<class SpType, class SuType> +void Foam::isoAdvection::boundFlux +( + const scalarField& alpha1, + surfaceScalarField& dVfcorrectionValues, + DynamicList<label>& correctedFaces, + const SpType& Sp, + const SuType& Su +) +{ + DebugInFunction << endl; + scalar rDeltaT = 1/mesh_.time().deltaTValue(); + + correctedFaces.clear(); + scalar aTol = 10*SMALL; // Note: tolerances + + const scalarField& meshV = mesh_.cellVolumes(); + const scalar dt = mesh_.time().deltaTValue(); + + DynamicList<label> downwindFaces(10); + DynamicList<label> facesToPassFluidThrough(downwindFaces.size()); + DynamicList<scalar> dVfmax(downwindFaces.size()); + DynamicList<scalar> phi(downwindFaces.size()); + const volScalarField& alphaOld = alpha1_.oldTime(); + + // Loop through alpha cell centred field + forAll(alpha1, celli) + { + if (alpha1[celli] < -aTol || alpha1[celli] > 1 + aTol) + { + const scalar Vi = meshV[celli]; + scalar alphaOvershoot = pos0(alpha1[celli]-1)*(alpha1[celli]-1) + + neg0(alpha1[celli])*alpha1[celli]; + scalar fluidToPassOn = alphaOvershoot*Vi; + label nFacesToPassFluidThrough = 1; + + bool firstLoop = true; + + // First try to pass surplus fluid on to neighbour cells that are + // not filled and to which dVf < phi*dt + while (mag(alphaOvershoot) > aTol && nFacesToPassFluidThrough > 0) + { + DebugInfo + << "\n\nBounding cell " << celli + << " with alpha overshooting " << alphaOvershoot + << endl; + + facesToPassFluidThrough.clear(); + dVfmax.clear(); + phi.clear(); + + // Find potential neighbour cells to pass surplus phase to + setDownwindFaces(celli, downwindFaces); + + scalar dVftot = 0; + nFacesToPassFluidThrough = 0; + + forAll(downwindFaces, fi) + { + const label facei = downwindFaces[fi]; + const scalar phif = faceValue(phi_, facei); + + const scalar dVff = + faceValue(dVf_, facei) + + faceValue(dVfcorrectionValues, facei); + + const scalar maxExtraFaceFluidTrans = + mag(pos0(fluidToPassOn)*phif*dt - dVff); + + // dVf has same sign as phi and so if phi>0 we have + // mag(phi_[facei]*dt) - mag(dVf[facei]) = phi_[facei]*dt + // - dVf[facei] + // If phi < 0 we have mag(phi_[facei]*dt) - + // mag(dVf[facei]) = -phi_[facei]*dt - (-dVf[facei]) > 0 + // since mag(dVf) < phi*dt + DebugInfo + << "downwindFace " << facei + << " has maxExtraFaceFluidTrans = " + << maxExtraFaceFluidTrans << endl; + + if (maxExtraFaceFluidTrans/Vi > aTol) + { +// if (maxExtraFaceFluidTrans/Vi > aTol && +// mag(dVfIn[facei])/Vi > aTol) //Last condition may be +// important because without this we will flux through uncut +// downwind faces + facesToPassFluidThrough.append(facei); + phi.append(phif); + dVfmax.append(maxExtraFaceFluidTrans); + dVftot += mag(phif*dt); + } + } + + DebugInfo + << "\nfacesToPassFluidThrough: " + << facesToPassFluidThrough << ", dVftot = " + << dVftot << " m3 corresponding to dalpha = " + << dVftot/Vi << endl; + + forAll(facesToPassFluidThrough, fi) + { + const label facei = facesToPassFluidThrough[fi]; + scalar fluidToPassThroughFace = + mag(fluidToPassOn)*mag(phi[fi]*dt)/dVftot; + + nFacesToPassFluidThrough += + pos0(dVfmax[fi] - fluidToPassThroughFace); + + fluidToPassThroughFace = + min(fluidToPassThroughFace, dVfmax[fi]); + + scalar dVff = faceValue(dVfcorrectionValues, facei); + + dVff += + sign(phi[fi])*fluidToPassThroughFace*sign(fluidToPassOn); + + setFaceValue(dVfcorrectionValues, facei, dVff); + + if (firstLoop) + { + checkIfOnProcPatch(facei); + correctedFaces.append(facei); + } + } + + firstLoop = false; + + scalar alpha1New = + ( + alphaOld[celli]*rDeltaT + Su[celli] + - netFlux(dVf_, celli)/Vi*rDeltaT + - netFlux(dVfcorrectionValues, celli)/Vi*rDeltaT + ) + / + (rDeltaT - Sp[celli]); + + alphaOvershoot = + pos0(alpha1New-1)*(alpha1New-1) + + neg0(alpha1New)*alpha1New; + + fluidToPassOn = alphaOvershoot*Vi; + + DebugInfo + << "\nNew alpha for cell " << celli << ": " + << alpha1New << endl; + } + } + } + + DebugInfo << "correctedFaces = " << correctedFaces << endl; +} + + +template<class SpType, class SuType> +void Foam::isoAdvection::advect(const SpType& Sp, const SuType& Su) +{ + DebugInFunction << endl; + + scalar advectionStartTime = mesh_.time().elapsedCpuTime(); + + scalar rDeltaT = 1/mesh_.time().deltaTValue(); + + // reconstruct the interface + surf_->reconstruct(); + + // Initialising dVf with upwind values + // i.e. phi[facei]*alpha1[upwindCell[facei]]*dt + dVf_ = upwind<scalar>(mesh_, phi_).flux(alpha1_)*mesh_.time().deltaT(); + + // Do the isoAdvection on surface cells + timeIntegratedFlux(); + + // Adjust alpha for mesh motion + if (mesh_.moving()) + { + alpha1In_ *= (mesh_.Vsc0()/mesh_.Vsc()); + } + + // Advect the free surface + alpha1_.primitiveFieldRef() = + ( + alpha1_.oldTime().primitiveField()*rDeltaT + + Su.field() + - fvc::surfaceIntegrate(dVf_)().primitiveField()*rDeltaT + )/(rDeltaT - Sp.field()); + + alpha1_.correctBoundaryConditions(); + + // Adjust dVf for unbounded cells + limitFluxes + ( + Sp, + Su + ); + + scalar maxAlphaMinus1 = gMax(alpha1In_) - 1; + scalar minAlpha = gMin(alpha1In_); + + Info<< "isoAdvection: After conservative bounding: min(alpha) = " + << minAlpha << ", max(alpha) = 1 + " << maxAlphaMinus1 << endl; + + // Apply non-conservative bounding mechanisms (clipping and snapping) + // Note: We should be able to write out alpha before this is done! + applyBruteForceBounding(); + + // Write surface cell set and bound cell set if required by user + writeSurfaceCells(); + + advectionTime_ += (mesh_.time().elapsedCpuTime() - advectionStartTime); + DebugInfo + << "isoAdvection: time consumption = " + << label(100*advectionTime_/(mesh_.time().elapsedCpuTime() + SMALL)) + << "%" << endl; + + alphaPhi_ = dVf_/mesh_.time().deltaT(); +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutCell/cutCell.C b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCell.C new file mode 100644 index 0000000000000000000000000000000000000000..05dbc8677fa51086d6dddd283924c0142958a1b5 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCell.C @@ -0,0 +1,206 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 OpenCFD Ltd. + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cutCell.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +int Foam::cutCell::debug = 0; + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cutCell::cutCell(const fvMesh&) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::cutCell::calcCellData +( + const DynamicList<point>& cutFaceCentres, + const DynamicList<vector>& cutFaceAreas, + vector& subCellCentre, scalar& subCellVolume +) +{ + // Clear the fields for accumulation + subCellCentre = Zero; + subCellVolume = Zero; + + // first estimate the approximate cell centre as the average of + // face centres + + vector cEst = average(cutFaceCentres); + + // Contribution to subcell centre and volume from cut faces + forAll(cutFaceCentres, facei) + { + // Calculate 3*face-pyramid volume + scalar pyr3Vol = max( + mag(cutFaceAreas[facei] & (cutFaceCentres[facei] - cEst)), VSMALL); + + // Calculate face-pyramid centre + vector pc = 0.75 * cutFaceCentres[facei] + 0.25 * cEst; + + // Accumulate volume-weighted face-pyramid centre + subCellCentre += pyr3Vol * pc; + + // Accumulate face-pyramid volume + subCellVolume += pyr3Vol; + } + + subCellCentre /= subCellVolume; + subCellVolume /= 3; // formula of pyramid +} + + +void Foam::cutCell::calcGeomDataCutFace +( + const DynamicList<DynamicList<point>>& faceEdges, + const vector& subCellCentre, + vector& faceArea, + vector& faceCentre +) +{ + // Initial guess of face centre from edge points + point fCentre{Zero}; + label nEdgePoints{0}; + for (const DynamicList<point>& edgePoints : faceEdges) + { + for (const point& p : edgePoints) + { + fCentre += p; + nEdgePoints++; + } + } + if (nEdgePoints > 0) + { + fCentre /= nEdgePoints; + } + + vector sumN{Zero}; + scalar sumA{0}; + vector sumAc{Zero}; + + // calculate area and centre + forAll(faceEdges, ei) + { + const DynamicList<point>& edgePoints = faceEdges[ei]; + const label nPoints = edgePoints.size(); + for (label pi = 0; pi < nPoints - 1; pi++) + { + const point& nextPoint = edgePoints[pi + 1]; + + vector c = edgePoints[pi] + nextPoint + fCentre; + vector n = + (nextPoint - edgePoints[pi]) ^ (fCentre - edgePoints[pi]); + scalar a = mag(n); + + // Edges may have different orientation + sumN += Foam::sign(n & sumN) * n; + sumA += a; + sumAc += a * c; + } + } + + // This is to deal with zero-area faces. Mark very small faces + // to be detected in e.g., processorPolyPatch. + if (sumA < ROOTVSMALL) + { + faceCentre = fCentre; + faceArea = Zero; + } + else + { + faceCentre = (1.0/3.0)*sumAc/sumA; + faceArea = 0.5*sumN; + } + + // Check faceArea direction and change if not pointing in the subcell + if ((faceArea & (faceCentre - subCellCentre)) >= 0) + { + faceArea *= (-1); + } +} + + +void Foam::cutCell::calcIsoFacePointsFromEdges +( + const vector& faceArea, + const vector& faceCentre, + const DynamicList<DynamicList<point>>& faceEdges, + DynamicList<point>& facePoints +) +{ + const vector zhat = normalised(faceArea); + vector xhat = faceEdges[0][0] - faceCentre; + xhat = (xhat - (xhat & zhat)*zhat); + xhat.normalise(); + vector yhat = normalised(zhat ^ xhat); + + // Calculating all intersection points + DynamicList<point> unsortedFacePoints(3 * faceEdges.size()); + DynamicList<scalar> unsortedFacePointAngles(3 * faceEdges.size()); + for (const DynamicList<point>& edgePoints : faceEdges) + { + for (const point& p : edgePoints) + { + unsortedFacePoints.append(p); + unsortedFacePointAngles.append + ( + Foam::atan2 + ( + ((p - faceCentre) & yhat), + ((p - faceCentre) & xhat) + ) + ); + } + } + + // Sorting face points by angle and inserting into facePoints + labelList order(Foam::sortedOrder(unsortedFacePointAngles)); + facePoints.append(unsortedFacePoints[order[0]]); + for (label pi = 1; pi < order.size(); ++pi) + { + if + ( + mag + ( + unsortedFacePointAngles[order[pi]] + - unsortedFacePointAngles[order[pi - 1]] + ) > 1e-8) + { + facePoints.append(unsortedFacePoints[order[pi]]); + } + } +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutCell/cutCell.H b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCell.H new file mode 100644 index 0000000000000000000000000000000000000000..5376ffda25670ba71c1b8e560aa172479af76ba3 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCell.H @@ -0,0 +1,114 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cutCell + +Description + Service routines for cutting a cell, celli, of an fvMesh, mesh_, + at its intersection with a surface + + Original code supplied by + Johan Roenby, DHI (2016) + Henning Scheufler, DLR (2019) + +SourceFiles + cutCell.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cutCell_H +#define cutCell_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cutCell Declaration +\*---------------------------------------------------------------------------*/ + +class cutCell +{ +protected: + + // Protected Member Functions + + //- Calculates volume and centre of the cutted cell + static void calcCellData + ( + const DynamicList<point>& cutFaceCentres, + const DynamicList<vector>& cutFaceAreas, + vector& subCellCentre, + scalar& subCellVolume + ); + + //- Calculates area and centre of the cutting face + static void calcGeomDataCutFace + ( + const DynamicList<DynamicList<point> >& faceEdges, + const vector& subCellCentre, + vector& faceArea, + vector& faceCentre + ); + + //- Calculates the point of the cutting face + static void calcIsoFacePointsFromEdges + ( + const vector& faceArea, + const vector& faceCentre, + const DynamicList<DynamicList<point>> & faceEdges, + DynamicList<point>& facePoints + ); + +public: + + // Static Data + static int debug; + + + // Constructors + + //- Construct from fvMesh + explicit cutCell(const fvMesh& unused); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellIso.C b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellIso.C new file mode 100644 index 0000000000000000000000000000000000000000..feb54df002ae870649b77918b6734d294a04f36e --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellIso.C @@ -0,0 +1,250 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cutCellIso.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cutCellIso::cutCellIso(const fvMesh& mesh, scalarField& f) +: + cutCell(mesh), + mesh_(mesh), + cellI_(-1), + f_(f), + cutValue_(0), + cutFace_(cutFaceIso(mesh_, f_)), + cutFaceCentres_(10), + cutFaceAreas_(10), + isoFaceEdges_(10), + facePoints_(10), + faceCentre_(Zero), + faceArea_(Zero), + subCellCentre_(Zero), + subCellVolume_(-10), + VOF_(-10), + cellStatus_(-1) +{ + clearStorage(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::cutCellIso::calcSubCell +( + const label cellI, + const scalar cutValue +) +{ + // resets data members + clearStorage(); + cellI_ = cellI; + cutValue_ = cutValue; + const cell& c = mesh_.cells()[cellI_]; + + bool fullyBelow = true; + bool fullyAbove = true; + + label nFaceBelowInterface = 0; + + // loop over cell faces + for (const label facei : c) + { + const label faceStatus = cutFace_.calcSubFace(facei, cutValue_); + + if (faceStatus == 0) // face is cut + { + cutFaceCentres_.append(cutFace_.subFaceCentre()); + cutFaceAreas_.append(cutFace_.subFaceArea()); + isoFaceEdges_.append(cutFace_.surfacePoints()); + fullyBelow = false; + fullyAbove = false; + } + else if (faceStatus == -1) // face fully below + { + cutFaceCentres_.append(cutFace_.subFaceCentre()); + cutFaceAreas_.append(cutFace_.subFaceArea()); + fullyAbove = false; + nFaceBelowInterface++; + } + else + { + fullyBelow = false; + } + } + + if (!fullyBelow && !fullyAbove) // cell cut at least at one face + { + cellStatus_ = 0; + + // calc faceArea and faceCentre + calcGeomDataCutFace + ( + isoFaceEdges_, + average(cutFaceCentres_), + faceArea_, + faceCentre_ + ); + + // In the rare but occuring cases where a cell is only touched at a + // point or a line the isoFaceArea_ will have zero length and here the + // cell should be treated as either completely empty or full. + if (mag(faceArea_) < 10*SMALL) + { + if (nFaceBelowInterface == 0) + { + // Cell fully above isosurface + cellStatus_ = 1; + subCellCentre_ = Zero; + subCellVolume_ = 0; + VOF_ = 0; + return cellStatus_; + } + else + { + // Cell fully below isosurface + cellStatus_ = -1; + subCellCentre_ = mesh_.C()[cellI_]; + subCellVolume_ = mesh_.V()[cellI_]; + VOF_ = 1; + return cellStatus_; + } + } + + cutFaceCentres_.append(faceCentre_); + cutFaceAreas_.append(faceArea_); + + // calc volume and sub cell centre + calcCellData + ( + cutFaceCentres_, + cutFaceAreas_, + subCellCentre_, + subCellVolume_ + ); + + VOF_ = subCellVolume_ / mesh_.V()[cellI_]; + } + else if (fullyAbove) // cell fully above isosurface + { + cellStatus_ = 1; + subCellCentre_ = Zero; + subCellVolume_ = 0; + VOF_ = 0; + } + else if (fullyBelow) // cell fully below isosurface + { + cellStatus_ = -1; + subCellCentre_ = mesh_.C()[cellI_]; + subCellVolume_ = mesh_.V()[cellI_]; + VOF_ = 1; + } + + return cellStatus_; +} + + +const Foam::point& Foam::cutCellIso::subCellCentre() const +{ + return subCellCentre_; +} + + +Foam::scalar Foam::cutCellIso::subCellVolume() const +{ + return subCellVolume_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutCellIso::facePoints() +{ + if (facePoints_.size() == 0) + { + // get face points in sorted order + calcIsoFacePointsFromEdges + ( + faceArea_, + faceCentre_, + isoFaceEdges_, + facePoints_ + ); + } + + return facePoints_; +} + + +const Foam::point& Foam::cutCellIso::faceCentre() const +{ + return faceCentre_; +} + + +const Foam::vector& Foam::cutCellIso::faceArea() const +{ + return faceArea_; +} + + +Foam::label Foam::cutCellIso::cellStatus() const +{ + return cellStatus_; +} + + +Foam::scalar Foam::cutCellIso::VolumeOfFluid() const +{ + return VOF_; +} + + +Foam::scalar Foam::cutCellIso::cutValue() const +{ + return cutValue_; +} + + +void Foam::cutCellIso::clearStorage() +{ + cellI_ = -1; + cutValue_ = 0; + cutFaceCentres_.clear(); + cutFaceAreas_.clear(); + isoFaceEdges_.clear(); + facePoints_.clear(); + faceCentre_ = Zero; + faceArea_ = Zero; + subCellCentre_ = Zero; + subCellVolume_ = -10; + VOF_ = -10; + cellStatus_ = -1; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.H b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellIso.H similarity index 57% rename from src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.H rename to src/transportModels/geometricVoF/cellCuts/cutCell/cutCellIso.H index a3c707aab73176ba4b1887d32236477e835d302a..3e905ff70cd9a8a99a052446552814a95bdcc19e 100644 --- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.H +++ b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellIso.H @@ -8,6 +8,7 @@ Copyright (C) 2016-2017 DHI Copyright (C) 2016-2017 OpenCFD Ltd. Copyright (C) 2018 Johan Roenby + Copyright (c) 2017-2019, German Aerospace Center (DLR) ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,34 +27,43 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Class - Foam::isoCutCell + Foam::cutCellIso Description Class for cutting a cell, celli, of an fvMesh, mesh_, at its intersection - with an isosurface defined by the mesh point values f_ and the isovalue, + with an isosurface defined by the mesh point values f_ and the cutValue, isoValue_. Reference: - \verbatim - Roenby, J., Bredmose, H. and Jasak, H. (2016). - A computational method for sharp interface advection - Royal Society Open Science, 3 - doi 10.1098/rsos.160405 - \endverbatim + \verbatim + Roenby, J., Bredmose, H. and Jasak, H. (2016). + A computational method for sharp interface advection + Royal Society Open Science, 3 + doi 10.1098/rsos.160405 + + Henning Scheufler, Johan Roenby, + Accurate and efficient surface reconstruction from volume + fraction data on general meshes, + Journal of Computational Physics, 2019, + doi 10.1016/j.jcp.2019.01.009 + + \endverbatim Original code supplied by Johan Roenby, DHI (2016) SourceFiles - isoCutCell.C + cutCellIso.C \*---------------------------------------------------------------------------*/ -#ifndef isoCutCell_H -#define isoCutCell_H +#ifndef cutCellIso_H +#define cutCellIso_H +#include "cutCell.H" +#include "cutFaceIso.H" #include "fvMesh.H" -#include "volFieldsFwd.H" -#include "isoCutFace.H" +#include "surfaceFields.H" +#include "volFields.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -61,12 +71,14 @@ namespace Foam { /*---------------------------------------------------------------------------*\ - Class isoCutCell Declaration + Class cutCellIso Declaration \*---------------------------------------------------------------------------*/ -class isoCutCell +class cutCellIso +: + public cutCell { - // Private data + // Private Data //- Mesh whose cells and faces to cut at their intersection with an // isosurface. @@ -78,36 +90,30 @@ class isoCutCell //- Isofunction values at mesh points. f_size() = mesh_.nPoints(). scalarField& f_; - //- Isovalue used to cut cell - scalar isoValue_; - - //- An isoCutFace object to get access to its face cutting functionality - isoCutFace isoCutFace_; - - //- List of face labels of isoCutFaces - DynamicList<label> isoCutFaces_; + //- Cutvalue used to cut cell + scalar cutValue_; - //- List of point lists each defining an isoCutFace - DynamicList<DynamicList<point>> isoCutFacePoints_; + //- An cutFaceIso object to get access to its face cutting functionality + cutFaceIso cutFace_; - //- List of face centres for isoCutFaces - DynamicList<point> isoCutFaceCentres_; + //- List of face centres for CutFaces + DynamicList<point> cutFaceCentres_; //- List of face area vectors for isoCutFaces - DynamicList<vector> isoCutFaceAreas_; + DynamicList<vector> cutFaceAreas_; //- Storage for subFace edges belonging to isoFace DynamicList<DynamicList<point>> isoFaceEdges_; //- Points constituting the cell-isosurface intersection (isoface) - DynamicList<point> isoFacePoints_; + DynamicList<point> facePoints_; - //- Face centre of the isoface - point isoFaceCentre_; + //- Face centre of the cutFace + point faceCentre_; //- Face normal of the isoface by convention pointing from high to low // values (i.e. opposite of the gradient vector). - vector isoFaceArea_; + vector faceArea_; //- Cell centre of the subcell of celli which is "fully submerged", i.e. // where the function value is higher than the isoValue_ @@ -116,80 +122,59 @@ class isoCutCell //- Volume of fully submerged subcell scalar subCellVolume_; - //- Volume of Fluid for celli (subCellVolume_/mesh_.V()[celli]) + //- Volume of Fluid for cellI (subCellVolume_/mesh_.V()[cellI]) scalar VOF_; - //- List of fully submerged faces - DynamicList<label> fullySubFaces_; - //- A cell status label taking one of the values: // - // - -1: cell is fully below the isosurface - // - 0: cell is cut - // - +1: cell is fully above the isosurface + // -1: cell is fully below the isosurface + // 0: cell is cut + // +1: cell is fully above the isosurface label cellStatus_; - //- Boolean telling if subcell centre and volume have been calculated - bool subCellCentreAndVolumeCalculated_; - - //- Boolean telling if isoface centre and area have been calculated - bool isoFaceCentreAndAreaCalculated_; - - - // Private Member Functions - void calcSubCellCentreAndVolume(); - - void calcIsoFaceCentreAndArea(); - - void calcIsoFacePointsFromEdges(); - - -public: + public: // Constructors //- Construct from fvMesh and a scalarField // Length of scalarField should equal number of mesh points - isoCutCell(const fvMesh&, scalarField&); + cutCellIso(const fvMesh& mesh, scalarField& f); - // Static data - static int debug; + // Member Functions + //- Sets internal values and returns face status + label calcSubCell(const label cellI, const scalar cutValue); - // Member functions + //- Returns subCellCentre + const point& subCellCentre() const; - label calcSubCell(const label celli, const scalar isoValue); + //- Returns subCellVolume + scalar subCellVolume() const; - const point& subCellCentre(); + //- Returns the points of the cutting isoface + const DynamicList<point>& facePoints(); - scalar subCellVolume(); + //- Returns the centre of the cutting isoface + const point& faceCentre() const; - const DynamicList<point>& isoFacePoints(); + //- Returns the area normal vector of the cutting isoface + const vector& faceArea() const; - const point& isoFaceCentre(); + //- Returns cellStatus + label cellStatus() const; - const vector& isoFaceArea(); + //- Returns volume of fluid value + scalar VolumeOfFluid() const; - scalar volumeOfFluid(); - - scalar isoValue() const; + //- Returns cutValue + scalar cutValue() const; + //- Resets internal values void clearStorage(); - - label vofCutCell - ( - const label celli, - const scalar alpha1, - const scalar tol, - const label maxIter - ); - - void volumeOfFluid(volScalarField& alpha1, const scalar f0); }; - // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // } // End namespace Foam diff --git a/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellPLIC.C b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellPLIC.C new file mode 100644 index 0000000000000000000000000000000000000000..ca5fcd9f8fe9b19c51d6d533f4533343e6404552 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellPLIC.C @@ -0,0 +1,252 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cutCellPLIC.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cutCellPLIC::cutCellPLIC(const fvMesh& mesh) +: + cutCell(mesh), + mesh_(mesh), + cellI_(-1), + normal_(Zero), + cutValue_(0), + cutFace_(mesh_), + cutFaceCentres_(10), + cutFaceAreas_(10), + plicFaceEdges_(10), + facePoints_(10), + faceCentre_(Zero), + faceArea_(Zero), + subCellCentre_(Zero), + subCellVolume_(-10), + VOF_(-10), + cellStatus_(-1) +{ + clearStorage(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::cutCellPLIC::calcSubCell +( + const label celli, + const scalar cutValue, + const vector& normal +) +{ + clearStorage(); + normal_ = normal; + cellI_ = celli; + cutValue_ = cutValue; + const cell& c = mesh_.cells()[celli]; + + vector base = mesh_.C()[cellI_] + normal_ * cutValue_; + bool fullyBelow = true; + bool fullyAbove = true; + + label nFaceBelowInterface = 0; + + // loop over all cell faces + for (const label faceI : c) + { + const label faceStatus = cutFace_.calcSubFace(faceI, normal_, base); + + if (faceStatus == 0) // face is cut + { + cutFaceCentres_.append(cutFace_.subFaceCentre()); + cutFaceAreas_.append(cutFace_.subFaceArea()); + plicFaceEdges_.append(cutFace_.surfacePoints()); + fullyBelow = false; + fullyAbove = false; + } + else if (faceStatus == -1) // face fully below + { + cutFaceCentres_.append(cutFace_.subFaceCentre()); + cutFaceAreas_.append(cutFace_.subFaceArea()); + fullyAbove = false; + nFaceBelowInterface++; + } + else + { + fullyBelow = false; + } + } + + if (!fullyBelow && !fullyAbove) // cell cut at least at one face + { + cellStatus_ = 0; + + // calc faceArea and faceCentre + calcGeomDataCutFace + ( + plicFaceEdges_, + average(cutFaceCentres_), + faceArea_, + faceCentre_ + ); + + // In the rare but occuring cases where a cell is only touched at a + // point or a line the isoFaceArea_ will have zero length and here the + // cell should be treated as either completely empty or full. + if (mag(faceArea_) < 10*SMALL) + { + if (nFaceBelowInterface == 0) + { + // Cell fully above isosurface + cellStatus_ = 1; + subCellCentre_ = Zero; + subCellVolume_ = 0; + VOF_ = 0; + return cellStatus_; + } + else + { + // Cell fully below isosurface + cellStatus_ = -1; + subCellCentre_ = mesh_.C()[cellI_]; + subCellVolume_ = mesh_.V()[cellI_]; + VOF_ = 1; + return cellStatus_; + } + } + + cutFaceCentres_.append(faceCentre_); + cutFaceAreas_.append(faceArea_); + + // calc volume and sub cell centre + calcCellData + ( + cutFaceCentres_, + cutFaceAreas_, + subCellCentre_, + subCellVolume_ + ); + + VOF_ = subCellVolume_ / mesh_.V()[cellI_]; + } + else if (fullyAbove) // cell fully above isosurface + { + cellStatus_ = 1; + subCellCentre_ = Zero; + subCellVolume_ = 0; + VOF_ = 0; + } + else if (fullyBelow) // cell fully below isosurface + { + cellStatus_ = -1; + subCellCentre_ = mesh_.C()[cellI_]; + subCellVolume_ = mesh_.V()[cellI_]; + VOF_ = 1; + } + + return cellStatus_; +} + + +const Foam::point& Foam::cutCellPLIC::subCellCentre() const +{ + return subCellCentre_; +} + + +Foam::scalar Foam::cutCellPLIC::subCellVolume() const +{ + return subCellVolume_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutCellPLIC::facePoints() +{ + if (facePoints_.size() == 0) + { + // get face points in sorted order + calcIsoFacePointsFromEdges + ( + faceArea_, + faceCentre_, + plicFaceEdges_, + facePoints_ + ); + } + + return facePoints_; +} + + +const Foam::point& Foam::cutCellPLIC::faceCentre() const +{ + return faceCentre_; +} + + +const Foam::vector& Foam::cutCellPLIC::faceArea() const +{ + return faceArea_; +} + + +Foam::scalar Foam::cutCellPLIC::VolumeOfFluid() const +{ + return VOF_; +} + + +Foam::label Foam::cutCellPLIC::cellStatus() const +{ + return cellStatus_; +} + + +Foam::scalar Foam::cutCellPLIC::cutValue() const +{ + return cutValue_; +} + + +void Foam::cutCellPLIC::clearStorage() +{ + cellI_ = -1; + cutValue_ = 0; + cutFaceCentres_.clear(); + cutFaceAreas_.clear(); + plicFaceEdges_.clear(); + facePoints_.clear(); + faceCentre_ = Zero; + faceArea_ = Zero; + subCellCentre_ = Zero; + subCellVolume_ = -10; + VOF_ = -10; + cellStatus_ = -1; +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellPLIC.H b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellPLIC.H new file mode 100644 index 0000000000000000000000000000000000000000..c5aadab2f92c64ae86ce3a206b7cad3dbfb2f61e --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutCell/cutCellPLIC.H @@ -0,0 +1,186 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cutCellPLIC + +Description + Class for cutting a cell, cellI, of an fvMesh, mesh_, at its intersection + with an surface defined by a normal and cutValue_ (defined as distance to + the cell centre). + + Reference: + \verbatim + Henning Scheufler, Johan Roenby, + Accurate and efficient surface reconstruction from volume + fraction data on general meshes, + Journal of Computational Physics, 2019, + doi 10.1016/j.jcp.2019.01.009 + + \endverbatim + + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + cutCellPLIC.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cutCellPLIC_H +#define cutCellPLIC_H + +#include "cutCell.H" +#include "cutFacePLIC.H" +#include "fvMesh.H" +#include "surfaceFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cutCellPLIC Declaration +\*---------------------------------------------------------------------------*/ + +class cutCellPLIC +: + public cutCell +{ + // Private Data + + //- Mesh whose cells and faces to cut at their intersection with an + // isosurface. + const fvMesh& mesh_; + + //- Cell to cut + label cellI_; + + //- Normal of the cutting plane + vector normal_; + + //- Cutvalue used to cut cell + scalar cutValue_; + + //- An cutFacePLIC object to get access to its face cutting functionality + cutFacePLIC cutFace_; + + //- List of face centres for CutFaces + DynamicList<point> cutFaceCentres_; + + //- List of face area vectors for PLICCutFaces + DynamicList<vector> cutFaceAreas_; + + //- Storage for subFace edges belonging to PLICFace + DynamicList<DynamicList<point>> plicFaceEdges_; + + //- Points constituting the cell-PLICsurface intersection (isoface) + DynamicList<point> facePoints_; + + //- Face centre of the cutFace + point faceCentre_; + + //- Face normal of the PLICface by convention pointing from high to low + // values (i.e. opposite of the gradient vector). + vector faceArea_; + + //- Cell centre of the subcell of celli which is "fully submerged", i.e. + // where the function value is higher than the isoValue_ + point subCellCentre_; + + //- Volume of fully submerged subcell + scalar subCellVolume_; + + //- Volume of Fluid for cellI (subCellVolume_/mesh_.V()[cellI]) + scalar VOF_; + + //- A cell status label taking one of the values: + // + // -1: cell is fully below the PLICsurface + // 0: cell is cut + // +1: cell is fully above the PLICsurface + label cellStatus_; + + + public: + + // Constructors + + //- Construct from fvMesh + explicit cutCellPLIC(const fvMesh& mesh); + + + // Member Functions + + //- Sets internal values and returns face status + label calcSubCell + ( + const label celli, + const scalar cutValue, + const vector& normal + ); + + //- Returns subCellCentre + const point& subCellCentre() const; + + //- Returns subCellVolume + scalar subCellVolume() const; + + //- Returns the points of the cutting PLICface + const DynamicList<point>& facePoints(); + + //- Returns the centre of the cutting PLICface + const point& faceCentre() const; + + //- Returns the area normal vector of the cutting PLICface + const vector& faceArea() const; + + //- Returns cellStatus + label cellStatus() const; + + //- Returns volume of fluid value + scalar VolumeOfFluid() const; + + //- Returns cutValue + scalar cutValue() const; + + //- Resets internal values + void clearStorage(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFace.C b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFace.C new file mode 100644 index 0000000000000000000000000000000000000000..7b86efff173c81059325238e27e3e8c6a761e38b --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFace.C @@ -0,0 +1,337 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cutFace.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +int Foam::cutFace::debug = 0; + +// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * + +void Foam::cutFace::calcSubFace +( + const label faceI, + const scalarList& pointStatus, + label firstFullySubmergedPoint, + DynamicList<point>& subFacePoints, + DynamicList<point>& surfacePoints, + label& faceStatus, + vector& subFaceCentre, + vector& subFaceArea +) +{ + const pointField& points = mesh_.points(); + const face& f = mesh_.faces()[faceI]; + + if (firstFullySubmergedPoint == -1) // is in gasPhase + { + faceStatus = 1; + subFaceCentre = Zero; + subFaceArea = Zero; + return; + } + + // loop face and append the cuts + // loop starts at firstFullySubmergedPoint + for + ( + label i = firstFullySubmergedPoint; + i < firstFullySubmergedPoint + f.size(); + ++i + ) + { + // max two points are appended during one cycle + label idx = i % f.size(); + label nextIdx = (i + 1) % f.size(); + + if (pointStatus[idx] > 0) // append fluid point + { + subFacePoints.append(points[f[idx]]); + } + else if (pointStatus[idx] == 0) // append cut point + { + subFacePoints.append(points[f[idx]]); + surfacePoints.append(points[f[idx]]); + } + + if + ( + (pointStatus[idx] < 0 && pointStatus[nextIdx] > 0) || + (pointStatus[idx] > 0 && pointStatus[nextIdx] < 0) + ) // cut on edge cut Value is zero + { + label nextP = f.nextLabel(idx); + vector dir = points[nextP] - points[f[idx]]; + scalar weight = + (0.0 - pointStatus[idx]) / + (pointStatus[nextIdx] - pointStatus[idx]); // cutValue is zero + + point p = points[f[idx]] + weight * dir; + + subFacePoints.append(p); + surfacePoints.append(p); + } + } + + if (subFacePoints.size() >= 3) + { + faceStatus = 0; + calcSubFaceCentreAndArea(subFacePoints, subFaceCentre, subFaceArea); + } + else + { + faceStatus = -1; + } +} + + +void Foam::cutFace::calcSubFace +( + const label faceI, + const scalarList& pointStatus, + const scalarList& weights, + label firstFullySubmergedPoint, + DynamicList<point>& subFacePoints, + DynamicList<point>& surfacePoints, + label& faceStatus, + vector& subFaceCentre, + vector& subFaceArea +) +{ + const pointField& points = mesh_.points(); + const face& f = mesh_.faces()[faceI]; + + if (firstFullySubmergedPoint == -1) // is in gasPhase + { + faceStatus = 1; + subFaceCentre = Zero; + subFaceArea = Zero; + return; + } + + // loop face and append the cuts + // loop starts at firstFullySubmergedPoint + for + ( + label i = firstFullySubmergedPoint; + i < firstFullySubmergedPoint + f.size(); + ++i + ) + { + // max two points are appended during one cycle + label idx = i % f.size(); + label nextIdx = (i + 1) % f.size(); + + if (pointStatus[idx] > 0) // append fluid point + { + subFacePoints.append(points[f[idx]]); + } + else if (pointStatus[idx] == 0) // append cut point + { + subFacePoints.append(points[f[idx]]); + surfacePoints.append(points[f[idx]]); + } + + if + ( + (pointStatus[idx] < 0 && pointStatus[nextIdx] > 0) || + (pointStatus[idx] > 0 && pointStatus[nextIdx] < 0) + ) // cut on edge cut Value is zero + { + label nextP = f.nextLabel(idx); + vector dir = points[nextP] - points[f[idx]]; + + point p = points[f[idx]] + weights[idx] * dir; + + subFacePoints.append(p); + surfacePoints.append(p); + } + } + + if (subFacePoints.size() >= 3) + { + faceStatus = 0; + calcSubFaceCentreAndArea(subFacePoints, subFaceCentre, subFaceArea); + } + else + { + faceStatus = -1; + } +} + + +void Foam::cutFace::calcSubFace +( + const face& f, + const pointField& points, + const scalarList& pointStatus, + label firstFullySubmergedPoint, + DynamicList<point>& subFacePoints, + DynamicList<point>& surfacePoints, + label& faceStatus, + vector& subFaceCentre, + vector& subFaceArea +) +{ + if (firstFullySubmergedPoint == -1) // in Gas + { + faceStatus = 1; + subFaceCentre = Zero; + subFaceArea = Zero; + return; + } + + // loop face and append the cuts + for + ( + label i = firstFullySubmergedPoint; + i < firstFullySubmergedPoint + f.size(); + ++i + ) + { + // max two points are appended during one cycle + label idx = i % f.size(); + label nextIdx = (i + 1) % f.size(); + + if (pointStatus[idx] > 0) // append fluid point + { + subFacePoints.append(points[f[idx]]); + } + else if (pointStatus[idx] == 0) // append cut point + { + subFacePoints.append(points[f[idx]]); + surfacePoints.append(points[f[idx]]); + } + + if + ( + (pointStatus[idx] < 0 && pointStatus[nextIdx] > 0) || + (pointStatus[idx] > 0 && pointStatus[nextIdx] < 0) + ) + { + label nextP = f.nextLabel(idx); + vector dir = points[nextP] - points[f[idx]]; + scalar weight = + (0.0 - pointStatus[idx]) / + (pointStatus[nextIdx] - pointStatus[idx]); + + point p = points[f[idx]] + weight * dir; + + subFacePoints.append(p); + surfacePoints.append(p); + } + } + + if (subFacePoints.size() >= 3) + { + faceStatus = 0; + calcSubFaceCentreAndArea(subFacePoints, subFaceCentre, subFaceArea); + } + else + { + faceStatus = -1; + } +} + + +void Foam::cutFace::calcSubFaceCentreAndArea +( + DynamicList<point>& subFacePoints, + vector& subFaceCentre, + vector& subFaceArea +) +{ + const label nPoints = subFacePoints.size(); + + // If the face is a triangle, do a direct calculation for efficiency + // and to avoid round-off error-related problems + if (nPoints == 3) + { + subFaceCentre = + (1.0 / 3.0) * (subFacePoints[0] + subFacePoints[1] + subFacePoints[2]); + + subFaceArea = 0.5 * ((subFacePoints[1] - subFacePoints[0]) ^ + (subFacePoints[2] - subFacePoints[0])); + } + else if (nPoints > 0) + { + vector sumN{Zero}; + scalar sumA{0}; + vector sumAc{Zero}; + + point fCentre = subFacePoints[0]; + // initial guess of centre as average of subFacePoints + for (label pi = 1; pi < nPoints; pi++) + { + fCentre += subFacePoints[pi]; + } + + fCentre /= nPoints; + + // loop sub triangles + for (label pi = 0; pi < nPoints; pi++) + { + const point& nextPoint = subFacePoints[(pi + 1) % nPoints]; + + vector c = subFacePoints[pi] + nextPoint + fCentre; + vector n = + (nextPoint - subFacePoints[pi]) ^ (fCentre - subFacePoints[pi]); + scalar a = mag(n); + + sumN += n; + sumA += a; + sumAc += a * c; + } + + // This is to deal with zero-area faces. Mark very small faces + // to be detected in e.g., processorPolyPatch. + if (sumA < ROOTVSMALL) + { + subFaceCentre = fCentre; + subFaceArea = Zero; + } + else + { + subFaceCentre = (1.0 / 3.0) * sumAc / sumA; + subFaceArea = 0.5 * sumN; + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cutFace::cutFace(const fvMesh& mesh) +: + mesh_(mesh) +{} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFace.H b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFace.H new file mode 100644 index 0000000000000000000000000000000000000000..de8f6b72727e79e609ac15fcfa790c303c9acae4 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFace.H @@ -0,0 +1,152 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cutFace + +Description + Base class for cutting a face, faceI, of an fvMesh, mesh_, at its + intersections + + Original code supplied by + Johan Roenby, DHI (2016) + Henning Scheufler, DLR (2019) + +SourceFiles + cutFace.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cutFace_H +#define cutFace_H + +#include "fvMesh.H" +#include "surfaceFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cutFaces Declaration +\*---------------------------------------------------------------------------*/ + +class cutFace +{ + // Private Data + + //- Reference to mesh + const fvMesh& mesh_; + + +protected: + + //- Calculate cut points along edges of face with pointStatus, pointfield + //- and computes geometric information and the face status where: + // - -1: faceStatus is fully below the isosurface + // - 0: faceStatus is cut (has values larger and smaller than isoValue) + // - +1: faceStatus is fully above the isosurface + void calcSubFace + ( + const label faceI, + const scalarList& pointStatus, + label firstFullySubmergedPoint, + DynamicList<point>& subFacePoints, + DynamicList<point>& surfacePoints, + label& faceStatus, + vector& subFaceCentre, + vector& subFaceArea + ); + + //- Calculate cut points along edges of face with pointStatus, pointfield, + //- weights and computes geometric information and the face status where: + // - -1: faceStatus is fully below the isosurface + // - 0: faceStatus is cut (has values larger and smaller than isoValue) + // - +1: faceStatus is fully above the isosurface + void calcSubFace + ( + const label faceI, + const scalarList& pointStatus, + const scalarList& weights, + label firstFullySubmergedPoint, + DynamicList<point>& subFacePoints, + DynamicList<point>& surfacePoints, + label& faceStatus, + vector& subFaceCentre, + vector& subFaceArea + ); + + //- Calculates centre and normal of the face + void calcSubFaceCentreAndArea + ( + DynamicList<point>& subFacePoints, + vector& subFaceCentre, + vector& subFaceArea + ); + + //- Calculate cut points along edges of face with pointStatus, pointfield + //- and computes geometric information and the face status where: + // - -1: faceStatus is fully below the isosurface + // - 0: faceStatus is cut (has values larger and smaller than isoValue) + // - +1: faceStatus is fully above the isosurface + void calcSubFace + ( + const face& f, + const pointField& points, + const scalarList& pointStatus, + label firstFullySubmergedPoint, + DynamicList<point>& subFacePoints, + DynamicList<point>& surfacePoints, + label& faceStatus, + vector& subFaceCentre, + vector& subFaceArea + ); + + +public: + + // Static Data + static int debug; + + + // Constructors + + //- Construct from fvMesh + explicit cutFace(const fvMesh& mesh); +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceAdvect.C b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceAdvect.C new file mode 100644 index 0000000000000000000000000000000000000000..c5bd8b589a01c56e439d1eea753d93e4ea9a7017 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceAdvect.C @@ -0,0 +1,1024 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cutFaceAdvect.H" +#include "OFstream.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cutFaceAdvect::cutFaceAdvect +( + const fvMesh& mesh, + const volScalarField& alpha1 +) +: + cutFace(mesh), + mesh_(mesh), + alpha1_(alpha1), + subFaceCentre_(Zero), + subFaceArea_(Zero), + subFacePoints_(10), + surfacePoints_(4), + pointStatus_(10), + weight_(10), + pTimes_(10), + faceStatus_(-1) +{ + clearStorage(); +} + + +// * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::cutFaceAdvect::calcSubFace +( + const label faceI, + const vector& normal, + const vector& base +) +{ + clearStorage(); + + const face& f = mesh_.faces()[faceI]; + + label inLiquid = 0; + label firstFullySubmergedPoint = -1; + + // Loop face and calculate pointStatus + forAll(f, i) + { + scalar value = (mesh_.points()[f[i]] - base) & normal; + if (mag(value) < 10 * SMALL) + { + value = 0; + } + pointStatus_.append(value); + if (pointStatus_[i] > 10 * SMALL) + { + inLiquid++; + if (firstFullySubmergedPoint == -1) + { + firstFullySubmergedPoint = i; + } + } + } + + if (inLiquid == f.size()) // fluid face + { + faceStatus_ = -1; + subFaceCentre_ = mesh_.faceCentres()[faceI]; + subFaceArea_ = mesh_.faceAreas()[faceI]; + return faceStatus_; + } + else if (inLiquid == 0) // gas face + { + faceStatus_ = 1; + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + return faceStatus_; + } + + cutFace::calcSubFace + ( + faceI, + pointStatus_, + firstFullySubmergedPoint, + subFacePoints_, + surfacePoints_, + faceStatus_, + subFaceCentre_, + subFaceArea_ + ); + + return faceStatus_; +} + + +Foam::label Foam::cutFaceAdvect::calcSubFace +( + const face& f, + const pointField& points, + const scalarField& val, + const scalar cutValue +) +{ + clearStorage(); + + label inLiquid = 0; + label firstFullySubmergedPoint = -1; + scalarList pointStatus(f.size()); + + // Loop face and calculate pointStatus + forAll(f, i) + { + pointStatus[i] = val[f[i]] - cutValue; + if (mag(pointStatus[i]) < 10 * SMALL) + { + pointStatus[i] = 0; + } + if (pointStatus[i] > 10 * SMALL) + { + ++inLiquid; + if (firstFullySubmergedPoint == -1) + { + firstFullySubmergedPoint = i; + } + } + } + + if (inLiquid == f.size()) // fluid face + { + faceStatus_ = -1; + subFaceCentre_ = f.centre(points); + subFaceArea_ = f.areaNormal(points); + return faceStatus_; + } + else if (inLiquid == 0) // gas face + { + faceStatus_ = 1; + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + return faceStatus_; + } + + cutFace::calcSubFace + ( + f, + points, + pointStatus, + firstFullySubmergedPoint, + subFacePoints_, + surfacePoints_, + faceStatus_, + subFaceCentre_, + subFaceArea_ + ); + + return faceStatus_; +} + + +Foam::scalar Foam::cutFaceAdvect::timeIntegratedFaceFlux +( + const label faceI, + const vector& x0, + const vector& n0, // has to has the length of 1 + const scalar Un0, + const scalar dt, + const scalar phi, + const scalar magSf +) +{ + clearStorage(); + +/* Temporarily taken out + // Treating rare cases where isoface normal is not calculated properly + if (mag(n0) < 0.5) + { + scalar alphaf = 0.0; + scalar waterInUpwindCell = 0.0; + + if (phi > 0 || !mesh_.isInternalFace(faceI)) + { + const label upwindCell = mesh_.faceOwner()[faceI]; + alphaf = alpha1_[upwindCell]; + waterInUpwindCell = alphaf * mesh_.V()[upwindCell]; + } + else + { + const label upwindCell = mesh_.faceNeighbour()[faceI]; + alphaf = alpha1_[upwindCell]; + waterInUpwindCell = alphaf * mesh_.V()[upwindCell]; + } + + return min(alphaf * phi * dt, waterInUpwindCell); + }*/ + + // Find sorted list of times where the isoFace will arrive at face points + // given initial position x0 and velocity Un0*n0 + + // Get points for this face + const face& f = mesh_.faces()[faceI]; + const label nPoints = f.size(); + + if (mag(Un0) > 1e-12) // Note: tolerances + { + // Here we estimate time of arrival to the face points from their normal + // distance to the initial surface and the surface normal velocity + + for (const scalar fi : f) + { + scalar value = ((mesh_.points()[fi] - x0) & n0) / Un0; + if (mag(value) < 10 * SMALL) + { + value = 0; + } + pTimes_.append(value); + } + + scalar dVf = 0; + + // Check if pTimes changes direction more than twice when looping face + label nShifts = 0; + forAll(pTimes_, pi) // i have no clue what this is + { + const label oldEdgeSign = + sign(pTimes_[(pi + 1) % nPoints] - pTimes_[pi]); + const label newEdgeSign = + sign(pTimes_[(pi + 2) % nPoints] - pTimes_[(pi + 1) % nPoints]); + + if (newEdgeSign != oldEdgeSign) + { + nShifts++; + } + } + + if (nShifts == 2 || nShifts == 0) + { + dVf = phi / magSf * timeIntegratedArea(faceI, dt, magSf, Un0); + } + else if (nShifts > 2) // triangle decompose the non planar face + { + const pointField fPts(f.points(mesh_.points())); + pointField fPts_tri(3); + scalarField pTimes_tri(3); + fPts_tri[0] = mesh_.faceCentres()[faceI]; + pTimes_tri[0] = ((fPts_tri[0] - x0) & n0)/Un0; + scalar area = 0; + for (label pi = 0; pi < nPoints; ++pi) + { + fPts_tri[1] = fPts[pi]; + pTimes_tri[1] = pTimes_[pi]; + fPts_tri[2] = fPts[(pi + 1) % nPoints]; + pTimes_tri[2] = pTimes_[(pi + 1) % nPoints]; + const scalar magSf_tri = + mag + ( + 0.5 + *(fPts_tri[2] - fPts_tri[0]) + ^(fPts_tri[1] - fPts_tri[0]) + ); + area += magSf_tri; + const scalar phi_tri = phi*magSf_tri/magSf; + dVf += + phi_tri/magSf_tri + *timeIntegratedArea + ( + fPts_tri, + pTimes_tri, + dt, + magSf_tri, + Un0 + ); + } + } + else + { + if (debug) + { + WarningInFunction + << "Warning: nShifts = " << nShifts << " on face " + << faceI << " with pTimes = " << pTimes_ + << " owned by cell " << mesh_.faceOwner()[faceI] + << endl; + } + } + + return dVf; + } + else + { + // Un0 is almost zero and isoFace is treated as stationary + calcSubFace(faceI, -n0, x0); + const scalar alphaf = mag(subFaceArea() / magSf); + + if (debug) + { + WarningInFunction + << "Un0 is almost zero (" << Un0 + << ") - calculating dVf on face " << faceI + << " using subFaceFraction giving alphaf = " << alphaf + << endl; + } + + return phi * dt * alphaf; + } +} + + +Foam::scalar Foam::cutFaceAdvect::timeIntegratedFaceFlux +( + const label faceI, + const scalarField& times, + const scalar Un0, + const scalar dt, + const scalar phi, + const scalar magSf +) +{ + clearStorage(); + + label nPoints = times.size(); + + { + // Here we estimate time of arrival to the face points from their normal + // distance to the initial surface and the surface normal velocity + + pTimes_.append(times); + + scalar dVf = 0; + + // Check if pTimes changes direction more than twice when looping face + label nShifts = 0; + forAll(pTimes_, pi) // i have no clue what this is + { + const label oldEdgeSign = + sign(pTimes_[(pi + 1) % nPoints] - pTimes_[pi]); + const label newEdgeSign = + sign(pTimes_[(pi + 2) % nPoints] - pTimes_[(pi + 1) % nPoints]); + + if (newEdgeSign != oldEdgeSign) + { + ++nShifts; + } + } + + if (nShifts == 2) + { + dVf = phi/magSf*timeIntegratedArea(faceI, dt, magSf, Un0); + } + // not possible to decompose face + return dVf; + } +} + + +Foam::scalar Foam::cutFaceAdvect::timeIntegratedArea +( + const pointField& fPts, + const scalarField& pTimes, + const scalar dt, + const scalar magSf, + const scalar Un0 +) +{ + // Initialise time integrated area returned by this function + scalar tIntArea = 0.0; + + // Finding ordering of vertex points + const labelList order(Foam::sortedOrder(pTimes)); + const scalar firstTime = pTimes[order.first()]; + const scalar lastTime = pTimes[order.last()]; + + // Dealing with case where face is not cut by surface during time interval + // [0,dt] because face was already passed by surface + if (lastTime <= 0) + { + // If all face cuttings were in the past and cell is filling up (Un0>0) + // then face must be full during whole time interval + tIntArea = magSf * dt * pos0(Un0); + return tIntArea; + } + + // Dealing with case where face is not cut by surface during time interval + // [0, dt] because dt is too small for surface to reach closest face point + if (firstTime >= dt) + { + // If all cuttings are in the future but non of them within [0,dt] then + // if cell is filling up (Un0 > 0) face must be empty during whole time + // interval + tIntArea = magSf * dt * (1 - pos0(Un0)); + return tIntArea; + } + + // If we reach this point in the code some part of the face will be swept + // during [tSmall, dt-tSmall]. However, it may be the case that there are no + // vertex times within the interval. This will happen sometimes for small + // time steps where both the initial and the final face-interface + // intersection line (FIIL) will be along the same two edges. + + // Face-interface intersection line (FIIL) to be swept across face + DynamicList<point> FIIL(3); + // Submerged area at beginning of each sub time interval time + scalar initialArea = 0.0; + // Running time keeper variable for the integration process + scalar time = 0.0; + + // Special treatment of first sub time interval + if (firstTime > 0) + { + // If firstTime > 0 the face is uncut in the time interval + // [0, firstTime] and hence fully submerged in fluid A or B. + // If Un0 > 0 cell is filling up and it must initially be empty. + // If Un0 < 0 cell must initially be full(y immersed in fluid A). + time = firstTime; + initialArea = magSf * (1.0 - pos0(Un0)); + tIntArea = initialArea * time; + cutPoints(fPts, pTimes, time, FIIL); + } + else + { + // If firstTime <= 0 then face is initially cut and we must + // calculate the initial submerged area and FIIL: + time = 0.0; + // Note: calcSubFace assumes well-defined 2-point FIIL!!!! + // calcSubFace(fPts, -sign(Un0)*pTimes, time); + // calcSubFace(fPts, -sign(Un0)*pTimes, time) + calcSubFace(face(identity(pTimes.size())), fPts, pTimes, time); + initialArea = mag(subFaceArea()); + cutPoints(fPts, pTimes, time, FIIL); + } + + // Making sorted array of all vertex times that are between max(0,firstTime) + // and dt and further than tSmall from the previous time. + DynamicList<scalar> sortedTimes(pTimes.size()); + { + scalar prevTime = time; + const scalar tSmall = max(1e-6*dt, 10*SMALL); + + for (const scalar timeI : order) + { + if (timeI > prevTime + tSmall && timeI <= dt) + { + sortedTimes.append(timeI); + prevTime = timeI; + } + } + } + + // Sweeping all quadrilaterals corresponding to the intervals defined above + for (const scalar newTime : sortedTimes) + { + // New face-interface intersection line + DynamicList<point> newFIIL(3); + cutPoints(fPts, pTimes, newTime, newFIIL); + + // quadrilateral area coefficients + scalar alpha = 0, beta = 0; + quadAreaCoeffs(FIIL, newFIIL, alpha, beta); + // Integration of area(t) = A*t^2+B*t from t = 0 to 1 + tIntArea += (newTime - time) * + (initialArea + sign(Un0) * (alpha/3.0 + 0.5*beta)); + // Adding quad area to submerged area + initialArea += sign(Un0)*(alpha + beta); + + FIIL = newFIIL; + time = newTime; + } + + // Special treatment of last time interval + if (lastTime > dt) + { + // FIIL will end up cutting the face at dt + // New face-interface intersection line + DynamicList<point> newFIIL(3); + cutPoints(fPts, pTimes, dt, newFIIL); + + // quadrilateral area coefficients + scalar alpha = 0, beta = 0; + quadAreaCoeffs(FIIL, newFIIL, alpha, beta); + // Integration of area(t) = A*t^2+B*t from t = 0 to 1 + tIntArea += (dt - time) * + (initialArea + sign(Un0)*(alpha / 3.0 + 0.5 * beta)); + } + else + { + // FIIL will leave the face at lastTime and face will be fully in fluid + // A or fluid B in the time interval from lastTime to dt. + tIntArea += magSf*(dt - lastTime)*pos0(Un0); + } + + return tIntArea; +} + + +void Foam::cutFaceAdvect::isoFacesToFile +( + const DynamicList<List<point>>& faces, + const word& filNam, + const word& filDir +) const +{ + // Writing isofaces to vtk file for inspection in paraview + + fileName outputFile(filDir/(filNam + ".vtk")); + + mkDir(filDir); + Info<< "Writing file: " << outputFile << endl; + + OFstream os(outputFile); + os << "# vtk DataFile Version 2.0" << nl + << filNam << nl + << "ASCII" << nl + << "DATASET POLYDATA" << nl; + + label nPoints{0}; + for (const List<point>& f : faces) + { + nPoints += f.size(); + } + + os << "POINTS " << nPoints << " float" << nl; + for (const List<point>& f : faces) + { + for (const point& p : f) + { + os << p.x() << ' ' << p.y() << ' ' << p.z() << nl; + } + } + + os << "POLYGONS " + << faces.size() << ' ' << (nPoints + faces.size()) << nl; + + label pointi = 0; + for (const List<point>& f : faces) + { + label endp = f.size(); + os << endp; + + endp += pointi; + + while (pointi < endp) + { + os << ' ' << pointi; + ++pointi; + } + os << nl; + } +} + + +Foam::label Foam::cutFaceAdvect::calcSubFace +( + const label faceI, + const label sign, + const scalar cutValue +) +{ + // clearStorage(); + const face& f = mesh_.faces()[faceI]; + label inLiquid = 0; + label firstFullySubmergedPoint = -1; + + // Loop face and calculate pointStatus + forAll(f, i) + { + scalar value = (sign * pTimes_[i] - cutValue); + + if (mag(value) < 10 * SMALL) + { + value = 0; + } + pointStatus_.append(value); + if (pointStatus_[i] > 10 * SMALL) + { + inLiquid++; + if (firstFullySubmergedPoint == -1) + { + firstFullySubmergedPoint = i; + } + } + } + + if (inLiquid == f.size()) // fluid face + { + faceStatus_ = -1; + subFaceCentre_ = mesh_.faceCentres()[faceI]; + subFaceArea_ = mesh_.faceAreas()[faceI]; + return faceStatus_; + } + else if (inLiquid == 0) // gas face + { + faceStatus_ = 1; + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + return faceStatus_; + } + + cutFace::calcSubFace + ( + faceI, + pointStatus_, + firstFullySubmergedPoint, + subFacePoints_, + surfacePoints_, + faceStatus_, + subFaceCentre_, + subFaceArea_ + ); + + return faceStatus_; +} + + +Foam::scalar Foam::cutFaceAdvect::timeIntegratedArea +( + const label faceI, + const scalar dt, + const scalar magSf, + const scalar Un0 +) +{ + // Initialise time integrated area returned by this function + scalar tIntArea = 0.0; + + // Finding ordering of vertex points + const labelList order(Foam::sortedOrder(pTimes_)); + const scalar firstTime = pTimes_[order.first()]; + const scalar lastTime = pTimes_[order.last()]; + + // Dealing with case where face is not cut by surface during time interval + // [0,dt] because face was already passed by surface + if (lastTime <= 0) + { + // If all face cuttings were in the past and cell is filling up (Un0>0) + // then face must be full during whole time interval + tIntArea = magSf* dt * pos0(Un0); + return tIntArea; + } + + // Dealing with case where face is not cut by surface during time interval + // [0, dt] because dt is too small for surface to reach closest face point + if (firstTime >= dt) + { + // If all cuttings are in the future but non of them within [0,dt] then + // if cell is filling up (Un0 > 0) face must be empty during whole time + // interval + tIntArea = magSf * dt * (1 - pos0(Un0)); + return tIntArea; + } + + // If we reach this point in the code some part of the face will be swept + // during [tSmall, dt-tSmall]. However, it may be the case that there are no + // vertex times within the interval. This will happen sometimes for small + // time steps where both the initial and the final face-interface + // intersection line (FIIL) will be along the same two edges. + + // Face-interface intersection line (FIIL) to be swept across face + DynamicList<point> FIIL(3); + // Submerged area at beginning of each sub time interval time + scalar initialArea = 0.0; + // Running time keeper variable for the integration process + scalar time = 0.0; + + // Special treatment of first sub time interval + if (firstTime > 0) + { + // If firstTime > 0 the face is uncut in the time interval + // [0, firstTime] and hence fully submerged in fluid A or B. + // If Un0 > 0 cell is filling up and it must initially be empty. + // If Un0 < 0 cell must initially be full(y immersed in fluid A). + time = firstTime; + initialArea = magSf * (1.0 - pos0(Un0)); + tIntArea = initialArea * time; + cutPoints(faceI, time, FIIL); + } + else + { + // If firstTime <= 0 then face is initially cut and we must + // calculate the initial submerged area and FIIL: + time = 0.0; + // Note: calcSubFace assumes well-defined 2-point FIIL!!!! + calcSubFace(faceI, -sign(Un0), time); + initialArea = mag(subFaceArea()); + cutPoints(faceI, time, FIIL); + } + + // Making sorted array of all vertex times that are between max(0,firstTime) + // and dt and further than tSmall from the previous time. + DynamicList<scalar> sortedTimes(pTimes_.size()); + { + scalar prevTime = time; + const scalar tSmall = max(1e-6*dt, 10*SMALL); + for (const label oI : order) + { + const scalar timeI = pTimes_[oI]; + if (timeI > prevTime + tSmall && timeI <= dt) + { + sortedTimes.append(timeI); + prevTime = timeI; + } + } + } + + // Sweeping all quadrilaterals corresponding to the intervals defined above + for (const scalar newTime : sortedTimes) + { + // New face-interface intersection line + DynamicList<point> newFIIL(3); + cutPoints(faceI, newTime, newFIIL); + + // quadrilateral area coefficients + scalar alpha = 0, beta = 0; + + quadAreaCoeffs(FIIL, newFIIL, alpha, beta); + // Integration of area(t) = A*t^2+B*t from t = 0 to 1 + tIntArea += + (newTime - time) + * (initialArea + sign(Un0) + * (alpha / 3.0 + 0.5 * beta)); + // Adding quad area to submerged area + initialArea += sign(Un0) * (alpha + beta); + + FIIL = newFIIL; + time = newTime; + } + + // Special treatment of last time interval + if (lastTime > dt) + { + // FIIL will end up cutting the face at dt + // New face-interface intersection line + DynamicList<point> newFIIL(3); + cutPoints(faceI, dt, newFIIL); + + // quadrilateral area coefficients + scalar alpha = 0, beta = 0; + quadAreaCoeffs(FIIL, newFIIL, alpha, beta); + // Integration of area(t) = A*t^2+B*t from t = 0 to 1 + tIntArea += + (dt - time) + * (initialArea + sign(Un0) * (alpha / 3.0 + 0.5 * beta)); + } + else + { + // FIIL will leave the face at lastTime and face will be fully in fluid + // A or fluid B in the time interval from lastTime to dt. + tIntArea += magSf * (dt - lastTime) * pos0(Un0); + } + + return tIntArea; +} + + +void Foam::cutFaceAdvect::quadAreaCoeffs +( + const DynamicList<point>& pf0, + const DynamicList<point>& pf1, + scalar& alpha, + scalar& beta +) const +{ + // Number of points in provided face-interface intersection lines + const label np0 = pf0.size(); + const label np1 = pf1.size(); + + // quad area coeffs such that area(t) = alpha*t^2 + beta*t. + // With time interval normalised, we have full quadArea = alpha + beta + // and time integrated quad area = alpha/3 + beta/2; + alpha = 0.0; + beta = 0.0; + + if (np0 && np1) + { + // Initialising quadrilateral vertices A, B, C and D + vector A(pf0[0]); + vector C(pf1[0]); + vector B(pf0[0]); + vector D(pf1[0]); + + if (np0 == 2) + { + B = pf0[1]; + } + else if (np0 > 2) + { + WarningInFunction << "Vertex face was cut at pf0 = " << pf0 << endl; + } + + if (np1 == 2) + { + D = pf1[1]; + } + else if (np1 > 2) + { + WarningInFunction << "Vertex face was cut at pf1 = " << pf1 << endl; + } + + // Swapping pf1 points if pf0 and pf1 point in same general direction + // (because we want a quadrilateral ABCD where pf0 = AB and pf1 = CD) + if (((B - A) & (D - C)) > 0) + { + vector tmp = D; + D = C; + C = tmp; + } + + // Defining local coordinates (xhat, yhat) for area integration of swept + // quadrilateral ABCD such that A = (0,0), B = (Bx,0), C = (Cx,Cy) and + // D = (Dx,Dy) with Cy = 0 and Dy > 0. + + const scalar Bx = mag(B - A); + + vector xhat(Zero); + if (Bx > 10 * SMALL) + { + // If |AB| > 0 ABCD we use AB to define xhat + xhat = (B - A) / mag(B - A); + } + else if (mag(C - D) > 10 * SMALL) + { + // If |AB| ~ 0 ABCD is a triangle ACD and we use CD for xhat + xhat = (C - D) / mag(C - D); + } + else + { + return; + } + + // Defining vertical axis in local coordinates + vector yhat = D - A; + yhat -= ((yhat & xhat) * xhat); + + if (mag(yhat) > 10 * SMALL) + { + yhat /= mag(yhat); + + const scalar Cx = (C - A) & xhat; + const scalar Cy = mag((C - A) & yhat); + const scalar Dx = (D - A) & xhat; + const scalar Dy = mag((D - A) & yhat); + + // area = ((Cx - Bx)*Dy - Dx*Cy)/6.0 + 0.25*Bx*(Dy + Cy); + alpha = 0.5 * ((Cx - Bx) * Dy - Dx * Cy); + beta = 0.5 * Bx * (Dy + Cy); + } + } + else + { + WarningInFunction + << "Vertex face was cut at " << pf0 << " and at " + << pf1 << endl; + } +} + + +void Foam::cutFaceAdvect::cutPoints +( + const label faceI, + const scalar f0, + DynamicList<point>& cutPoints +) +{ + const face& f = mesh_.faces()[faceI]; + const label nPoints = f.size(); + scalar f1(pTimes_[0]); + + // Snapping vertex value to f0 if very close (needed for 2D cases) + if (mag(f1 - f0) < 10 * SMALL) + { + f1 = f0; + } + + forAll(f, pi) + { + label pi2 = (pi + 1) % nPoints; + scalar f2 = pTimes_[pi2]; + + // Snapping vertex value + if (mag(f2 - f0) < 10 * SMALL) + { + f2 = f0; + } + + if ((f1 < f0 && f2 > f0) || (f1 > f0 && f2 < f0)) + { + const scalar s = (f0 - f1) / (f2 - f1); + cutPoints.append + ( + mesh_.points()[f[pi]] + + s*(mesh_.points()[f[pi2]] - mesh_.points()[f[pi]]) + ); + } + else if (f1 == f0) + { + cutPoints.append(mesh_.points()[f[pi]]); + } + f1 = f2; + } + + if (cutPoints.size() > 2) + { + WarningInFunction + << "cutPoints = " << cutPoints + << " for pts = " << f.points(mesh_.points()) + << ", f - f0 = " << f - f0 << " and f0 = " << f0 + << endl; + } +} + + +void Foam::cutFaceAdvect::cutPoints +( + const pointField& pts, + const scalarField& f, + const scalar f0, + DynamicList<point>& cutPoints +) +{ + const label nPoints = pts.size(); + scalar f1(f[0]); + + // Snapping vertex value to f0 if very close (needed for 2D cases) + if (mag(f1 - f0) < 10 * SMALL) + { + f1 = f0; + } + + forAll(pts, pi) + { + label pi2 = (pi + 1) % nPoints; + scalar f2 = f[pi2]; + + // Snapping vertex value + if (mag(f2 - f0) < 10 * SMALL) + { + f2 = f0; + } + + if ((f1 < f0 && f2 > f0) || (f1 > f0 && f2 < f0)) + { + const scalar s = (f0 - f1) / (f2 - f1); + cutPoints.append(pts[pi] + s * (pts[pi2] - pts[pi])); + } + else if (f1 == f0) + { + cutPoints.append(pts[pi]); + } + f1 = f2; + } + + if (cutPoints.size() > 2) + { + WarningInFunction + << "cutPoints = " << cutPoints << " for pts = " << pts + << ", f - f0 = " << f - f0 << " and f0 = " << f0 + << endl; + } +} + + +const Foam::point& Foam::cutFaceAdvect::subFaceCentre() const +{ + return subFaceCentre_; +} + + +const Foam::vector& Foam::cutFaceAdvect::subFaceArea() const +{ + return subFaceArea_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutFaceAdvect::subFacePoints() const +{ + return subFacePoints_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutFaceAdvect::surfacePoints() const +{ + return surfacePoints_; +} + + +void Foam::cutFaceAdvect::clearStorage() +{ + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + subFacePoints_.clear(); + surfacePoints_.clear(); + pointStatus_.clear(); + pTimes_.clear(); + weight_.clear(); + faceStatus_ = -1; +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceAdvect.H b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceAdvect.H new file mode 100644 index 0000000000000000000000000000000000000000..51f3538193c69c2bda3194229029ddd4c7a66788 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceAdvect.H @@ -0,0 +1,258 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cutFaceAdvect + +Description + Calculates the face fluxes + + Reference: + \verbatim + Roenby, J., Bredmose, H. and Jasak, H. (2016). + A computational method for sharp interface advection + Royal Society Open Science, 3 + doi 10.1098/rsos.160405 + + \endverbatim + + Original code supplied by Johan Roenby, DHI (2016) + +SourceFiles + cutFaceAdvect.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cutFaceAdvect_H +#define cutFaceAdvect_H + +#include "cutFace.H" +#include "fvMesh.H" +#include "surfaceFields.H" +#include "volFields.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cutFaceAdvect Declaration +\*---------------------------------------------------------------------------*/ + +class cutFaceAdvect +: + public cutFace +{ + // Private Data + + typedef DynamicList<label> DynamicLabelList; + typedef DynamicList<scalar> DynamicScalarList; + typedef DynamicList<vector> DynamicVectorList; + typedef DynamicList<point> DynamicPointList; + + //- Mesh whose cells and faces to cut at their intersection + //- with an isoface + const fvMesh& mesh_; + + //- Reference to VoF field + const volScalarField& alpha1_; + + //- Storage for centre of subface + point subFaceCentre_; + + //- Storage for area vector of subface + vector subFaceArea_; + + //- Storage for subFacePoints + DynamicList<point> subFacePoints_; + + //- Storage for subFacePoints + DynamicList<point> surfacePoints_; + + //- Storage for pointStatus_ cuts the cell at 0 + DynamicList<scalar> pointStatus_; + + //- Storage of the edge weight + DynamicList<scalar> weight_; + + //- Storage for arrival Times + DynamicList<scalar> pTimes_; + + //- A face status label taking one of the values: + // + // -1: face is fully below the isosurface + // 0: face is cut, i.e. has values larger and smaller than isoValue_ + // +1: face is fully above the isosurface + label faceStatus_; + + + // Private Member Functions + + //- Write faces to vtk files + void isoFacesToFile + ( + const DynamicList<List<point>>& isoFacePts, + const word& fileName, + const word& fileDir + ) const; + + + public: + + // Constructors + + //- Construct from fvMesh and a scalarField + // Length of scalarField should equal number of mesh points + cutFaceAdvect(const fvMesh& mesh, const volScalarField& alpha1); + + + // Member Functions + + //- Calculates cut centre and cut area (plicReconstruction) + // \return face status + label calcSubFace + ( + const label faceI, + const vector& normal, + const vector& base + ); + + //- Calculates cut centre and cut area (iso reconstruction) + // \return face status + label calcSubFace + ( + const face& f, + const pointField& points, + const scalarField& val, + const scalar cutValue + ); + + //- Calculates cut centre and cut area (iso reconstruction) + // \return face status + label calcSubFace + ( + const label faceI, + const label sign, + const scalar cutValue + ); + + //- Calculate time integrated flux for a face + scalar timeIntegratedFaceFlux + ( + const label faceI, + const vector& x0, + const vector& n0, + const scalar Un0, + const scalar dt, + const scalar phi, + const scalar magSf + ); + + //- Calculate time integrated flux for a face + scalar timeIntegratedFaceFlux + ( + const label faceI, + const scalarField& times, + const scalar Un0, + const scalar dt, + const scalar phi, + const scalar magSf + ); + + //- Calculate time integrated area for a face + scalar timeIntegratedArea + ( + const label faceI, + const scalar dt, + const scalar magSf, + const scalar Un0 + ); + + //- Calculate time integrated area for a face + scalar timeIntegratedArea + ( + const pointField& fPts, + const scalarField& pTimes, + const scalar dt, + const scalar magSf, + const scalar Un0 + ); + + //- For face with vertices p calculate its area and integrated area + // between isocutting lines with isovalues f0 and f1 given vertex + // values f + void quadAreaCoeffs + ( + const DynamicPointList& pf0, + const DynamicPointList& pf1, + scalar& quadArea, + scalar& intQuadArea + ) const; + + //- Get cutPoints of face + void cutPoints + ( + const label faceI, + const scalar f0, + DynamicList<point>& cutPoints + ); + + //- Get cutPoints of face + void cutPoints + ( + const pointField& pts, + const scalarField& f, + const scalar f0, + DynamicList<point>& cutPoints + ); + + //- Returns centre of cutted face + const point& subFaceCentre() const; + + //- Returns area vector of cutted face + const vector& subFaceArea() const; + + //- Returns the cut edge of the cutted face + const DynamicList<point>& subFacePoints() const; + + //- Returns point of the cutted face in sorted order + const DynamicList<point>& surfacePoints() const; + + //- Resets internal variables + void clearStorage(); +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceIso.C b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceIso.C new file mode 100644 index 0000000000000000000000000000000000000000..778109da11e05b71e9e634cdde5c5b3e0d4a6634 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceIso.C @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cutFaceIso.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cutFaceIso::cutFaceIso(const fvMesh& mesh, scalarField& f) +: + cutFace(mesh), + mesh_(mesh), + f_(f), + subFaceCentre_(Zero), + subFaceArea_(Zero), + subFacePoints_(10), + surfacePoints_(4), + pointStatus_(10), + weight_(10), + faceStatus_(-1) +{ + clearStorage(); +} + + +// * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::cutFaceIso::calcSubFace +( + const label faceI, + const scalar cutValue +) +{ + clearStorage(); + const face& f = mesh_.faces()[faceI]; + label inLiquid = 0; + label firstFullySubmergedPoint = -1; + + // loop over face + forAll(f, i) + { + // pointStatus is f - cutValue + pointStatus_.append(f_[f[i]] - cutValue); + if (mag(pointStatus_[i]) < 10 * SMALL) + { + pointStatus_[i] = 0; + } + if (pointStatus_[i] > 10 * SMALL) + { + inLiquid++; + if (firstFullySubmergedPoint == -1) + { + firstFullySubmergedPoint = i; + } + } + } + + if (inLiquid == f.size()) // fluid face + { + faceStatus_ = -1; + subFaceCentre_ = mesh_.faceCentres()[faceI]; + subFaceArea_ = mesh_.faceAreas()[faceI]; + return faceStatus_; + } + else if (inLiquid == 0) // gas face + { + faceStatus_ = 1; + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + return faceStatus_; + } + + cutFace::calcSubFace + ( + faceI, + pointStatus_, + firstFullySubmergedPoint, + subFacePoints_, + surfacePoints_, + faceStatus_, + subFaceCentre_, + subFaceArea_ + ); + + return faceStatus_; +} + + +const Foam::point& Foam::cutFaceIso::subFaceCentre() const +{ + return subFaceCentre_; +} + + +const Foam::vector& Foam::cutFaceIso::subFaceArea() const +{ + return subFaceArea_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutFaceIso::subFacePoints() const +{ + return subFacePoints_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutFaceIso::surfacePoints() const +{ + return surfacePoints_; +} + + +void Foam::cutFaceIso::clearStorage() +{ + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + subFacePoints_.clear(); + surfacePoints_.clear(); + pointStatus_.clear(); + weight_.clear(); + faceStatus_ = -1; +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceIso.H b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceIso.H new file mode 100644 index 0000000000000000000000000000000000000000..8051dc80d8daaeef9789c4ad309af22599d2235b --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFaceIso.H @@ -0,0 +1,151 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cutFaceIso + +Description + Class for cutting a face, faceI, of an fvMesh, mesh_, at its intersection + with an isosurface defined by the mesh point values f_ and the isovalue, + cutValue. + + Reference: + \verbatim + Roenby, J., Bredmose, H. and Jasak, H. (2016). + A computational method for sharp interface advection + Royal Society Open Science, 3 + doi 10.1098/rsos.160405 + + \endverbatim + + Original code supplied by Johan Roenby, DHI (2016) + +SourceFiles + cutFaceIso.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cutFaceIso_H +#define cutFaceIso_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "cutFace.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cutFaceIso Declaration +\*---------------------------------------------------------------------------*/ + +class cutFaceIso +: + public cutFace +{ + // Private Data + + //- Mesh whose cells and faces to cut at their intersection with an + //- isoface + const fvMesh& mesh_; + + //- Isofunction values at mesh points. f_size() = mesh_.nPoints(). + scalarField& f_; + + //- Storage for centre of subface + point subFaceCentre_; + + //- Storage for area vector of subface + vector subFaceArea_; + + //- Storage for subFacePoints + DynamicList<point> subFacePoints_; + + //- Storage for subFacePoints + DynamicList<point> surfacePoints_; + + //- Storage for pointStatus_ cuts the cell at 0 + DynamicList<scalar> pointStatus_; + + //- Storage of the edge weight + DynamicList<scalar> weight_; + + //- A face status label taking one of the values: + // + // -1: face is fully below the isosurface + // 0: face is cut, i.e. has values larger and smaller than isoValue_ + // +1: face is fully above the isosurface + label faceStatus_; + + +public: + + // Constructors + + //- Construct from fvMesh and a scalarField + // length of scalarField should equal number of mesh points + cutFaceIso(const fvMesh& mesh, scalarField& f); + + + // Member Functions + + //- Calculate cut points along edges of faceI + label calcSubFace + ( + const label faceI, + const scalar cutValue + ); + + //- Returns centre of cutted face + const point& subFaceCentre() const; + + //- Returns area vector of cutted face + const vector& subFaceArea() const; + + //- Returns the cut edge of the cutted face + const DynamicList<point>& subFacePoints() const; + + //- Returns point of the face in sorted of cutted face + const DynamicList<point>& surfacePoints() const; + + //- Resets internal variables + void clearStorage(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFacePLIC.C b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFacePLIC.C new file mode 100644 index 0000000000000000000000000000000000000000..446b026e61280a40d1bed96ce31dde3797eb2e04 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFacePLIC.C @@ -0,0 +1,154 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "cutFacePLIC.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::cutFacePLIC::cutFacePLIC(const fvMesh& mesh) +: + cutFace(mesh), + mesh_(mesh), + subFaceCentre_(Zero), + subFaceArea_(Zero), + subFacePoints_(10), + surfacePoints_(4), + pointStatus_(10), + weight_(10), + faceStatus_(-1) +{ + clearStorage(); +} + + +// * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::cutFacePLIC::calcSubFace +( + const label faceI, + const vector& normal, + const vector& base + ) +{ + clearStorage(); + + const face& f = mesh_.faces()[faceI]; + label inLiquid = 0; + label firstFullySubmergedPoint = -1; + + // loop face + forAll(f, i) + { + // pointStatus is the distance to the plane + scalar value = (mesh_.points()[f[i]] - base) & normal; + if (mag(value) < SMALL) + { + value = 0; + } + + pointStatus_.append(value); + if (pointStatus_[i] > 0) + { + inLiquid++; + if (firstFullySubmergedPoint == -1) + { + firstFullySubmergedPoint = i; + } + } + } + + if (inLiquid == f.size()) // fluid face + { + faceStatus_ = -1; + subFaceCentre_ = mesh_.faceCentres()[faceI]; + subFaceArea_ = mesh_.faceAreas()[faceI]; + return faceStatus_; + } + else if (inLiquid == 0) // gas face + { + faceStatus_ = 1; + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + return faceStatus_; + } + + + cutFace::calcSubFace + ( + faceI, + pointStatus_, + firstFullySubmergedPoint, + subFacePoints_, + surfacePoints_, + faceStatus_, + subFaceCentre_, + subFaceArea_ + ); + + return faceStatus_; +} + + +const Foam::point& Foam::cutFacePLIC::subFaceCentre() const +{ + return subFaceCentre_; +} + + +const Foam::vector& Foam::cutFacePLIC::subFaceArea() const +{ + return subFaceArea_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutFacePLIC::subFacePoints() const +{ + return subFacePoints_; +} + + +const Foam::DynamicList<Foam::point>& Foam::cutFacePLIC::surfacePoints() const +{ + return surfacePoints_; +} + + +void Foam::cutFacePLIC::clearStorage() +{ + subFaceCentre_ = Zero; + subFaceArea_ = Zero; + subFacePoints_.clear(); + surfacePoints_.clear(); + pointStatus_.clear(); + weight_.clear(); + faceStatus_ = -1; +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/cellCuts/cutFace/cutFacePLIC.H b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFacePLIC.H new file mode 100644 index 0000000000000000000000000000000000000000..75b76a44d8ee0a8b761c1cc19d352fac5d4a45d7 --- /dev/null +++ b/src/transportModels/geometricVoF/cellCuts/cutFace/cutFacePLIC.H @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2016-2017 DHI + Copyright (C) 2018-2019 Johan Roenby + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::cutFacePLIC + +Description + Class for cutting a face, faceI, of an fvMesh, mesh_, at its intersection + with an plane defined by normal and a base point + + Reference: + \verbatim + + Henning Scheufler, Johan Roenby, + Accurate and efficient surface reconstruction from volume + fraction data on general meshes, + Journal of Computational Physics, 2019, + doi 10.1016/j.jcp.2019.01.009 + + \endverbatim + + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + cutFacePLIC.C + +\*---------------------------------------------------------------------------*/ + +#ifndef cutFacePLIC_H +#define cutFacePLIC_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "cutFace.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class cutFacePLIC Declaration +\*---------------------------------------------------------------------------*/ + +class cutFacePLIC +: + public cutFace +{ + // Private Data + + //- Mesh whose cells and faces to cut at their intersection + //- with an isoface + const fvMesh& mesh_; + + //- Storage for centre of subface + point subFaceCentre_; + + //- Storage for area vector of subface + vector subFaceArea_; + + //- Storage for subFacePoints + DynamicList<point> subFacePoints_; + + //- Storage for subFacePoints + DynamicList<point> surfacePoints_; + + //- Storage for pointStatus_ cuts the cell at 0 + DynamicList<scalar> pointStatus_; + + //- Storage of the edge weight + DynamicList<scalar> weight_; + + //- A face status label taking one of the values: + // + // -1: face is fully below the PLICsurface + // 0: face is cut (has values larger and smaller than cutValue_) + // +1: face is fully above the PLICsurface + label faceStatus_; + + +public: + + // Constructors + + //- Construct from fvMesh and a scalarField + explicit cutFacePLIC(const fvMesh& mesh); + + + // Member Functions + + //- Calculate cut points along edges of faceI + label calcSubFace + ( + const label faceI, + const vector& normal, + const vector& base + ); + + //- Returns centre of cutted face + const point& subFaceCentre() const; + + //- Returns area vector of cutted face + const vector& subFaceArea() const; + + //- Returns the cut edge of the cutted face + const DynamicList<point>& subFacePoints() const; + + //- Returns point of the face in sorted of cutted face + const DynamicList<point>& surfacePoints() const; + + //- Resets internal variables + void clearStorage(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructedDistanceFunction/reconstructedDistanceFunction.C b/src/transportModels/geometricVoF/reconstructedDistanceFunction/reconstructedDistanceFunction.C new file mode 100644 index 0000000000000000000000000000000000000000..7aba9c546de0ae1faf672ba56ea6a23f3270344c --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructedDistanceFunction/reconstructedDistanceFunction.C @@ -0,0 +1,427 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "emptyPolyPatch.H" +#include "reconstructedDistanceFunction.H" +#include "processorPolyPatch.H" +#include "syncTools.H" +#include "unitConversion.H" +#include "wedgePolyPatch.H" +#include "alphaContactAngleTwoPhaseFvPatchScalarField.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::indirectPrimitivePatch> +Foam::reconstructedDistanceFunction::coupledFacesPatch() const +{ + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + label nCoupled = 0; + + for (const polyPatch& pp : patches) + { + if (isA<coupledPolyPatch>(pp)) + { + nCoupled += pp.size(); + } + } + labelList nCoupledFaces(nCoupled); + nCoupled = 0; + + for (const polyPatch& pp : patches) + { + if (isA<coupledPolyPatch>(pp)) + { + label facei = pp.start(); + + forAll(pp, i) + { + nCoupledFaces[nCoupled++] = facei++; + } + } + } + + return autoPtr<indirectPrimitivePatch>::New + ( + IndirectList<face> + ( + mesh_.faces(), + nCoupledFaces + ), + mesh_.points() + ); +} + + +void Foam::reconstructedDistanceFunction::markCellsNearSurf +( + const boolList& interfaceCells, + const label neiRingLevel +) +{ + // performance might be improved by increasing the saving last iterations + // cells in a Map and loop over the map + if (mesh_.topoChanging()) + { + // Introduced resizing to cope with changing meshes + if (nextToInterface_.size() != mesh_.nCells()) + { + nextToInterface_.resize(mesh_.nCells()); + } + coupledBoundaryPoints_ = coupledFacesPatch()().meshPoints(); + } + + const labelListList& pCells = mesh_.cellPoints(); + const labelListList& cPoints = mesh_.pointCells(); + + boolList alreadyMarkedPoint(mesh_.nPoints(), false); + nextToInterface_ = false; + + // do coupled face first + Map<bool> syncMap; + + for (int level=0;level<=neiRingLevel;level++) + { + // parallel + if (level > 0) + { + forAll(coupledBoundaryPoints_, i) + { + const label pi = coupledBoundaryPoints_[i]; + forAll(mesh_.pointCells()[pi], j) + { + const label celli = cPoints[pi][j]; + if (cellDistLevel_[celli] == level-1) + { + syncMap.insert(pi, true); + break; + } + } + } + + syncTools::syncPointMap(mesh_, syncMap, orEqOp<bool>()); + + // mark parallel points first + forAllConstIters(syncMap, iter) + { + const label pi = iter.key(); + + if (!alreadyMarkedPoint[pi]) + { + // loop over all cells attached to the point + forAll(cPoints[pi], j) + { + const label pCelli = cPoints[pi][j]; + if (cellDistLevel_[pCelli] == -1) + { + cellDistLevel_[pCelli] = level; + nextToInterface_[pCelli] = true; + } + } + } + alreadyMarkedPoint[pi] = true; + } + } + + + forAll(cellDistLevel_, celli) + { + if (level == 0) + { + if (interfaceCells[celli]) + { + cellDistLevel_[celli] = 0; + nextToInterface_[celli] = true; + } + else + { + cellDistLevel_[celli] = -1; + } + } + else + { + if (cellDistLevel_[celli] == level-1) + { + forAll(pCells[celli], i) + { + const label pI = pCells[celli][i]; + + if (!alreadyMarkedPoint[pI]) + { + forAll(cPoints[pI], j) + { + const label pCelli = cPoints[pI][j]; + if (cellDistLevel_[pCelli] == -1) + { + cellDistLevel_[pCelli] = level; + nextToInterface_[pCelli] = true; + } + } + } + alreadyMarkedPoint[pI] = true; + } + } + } + } + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::reconstructedDistanceFunction::reconstructedDistanceFunction +( + const fvMesh& mesh +) +: + volScalarField + ( + IOobject + ( + "RDF", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + mesh, + dimensionedScalar(dimLength, Zero) + ), + mesh_(mesh), + coupledBoundaryPoints_(coupledFacesPatch()().meshPoints()), + cellDistLevel_ + ( + IOobject + ( + "cellDistLevel", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedScalar("cellDistLevel", dimless, -1) + ), + nextToInterface_(mesh.nCells(), false) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +const Foam::volScalarField& Foam::reconstructedDistanceFunction::constructRDF +( + const boolList& nextToInterface, + const volVectorField& centre, + const volVectorField& normal, + zoneDistribute& distribute, + bool updateStencil +) +{ + volScalarField& reconDistFunc = *this; + + if (nextToInterface.size() != centre.size()) + { + FatalErrorInFunction + << "size of nextToInterface: " << nextToInterface.size() + << "size of centre:" << centre.size() + << "do not match. Did the mesh change?" + << exit(FatalError); + return reconDistFunc; + } + + + distribute.setUpCommforZone(nextToInterface, updateStencil); + + Map<vector> mapCentres = + distribute.getDatafromOtherProc(nextToInterface, centre); + Map<vector> mapNormal = + distribute.getDatafromOtherProc(nextToInterface, normal); + + const labelListList& stencil = distribute.getStencil(); + + + forAll(nextToInterface,celli) + { + if (nextToInterface[celli]) + { + if (mag(normal[celli]) != 0) // interface cell + { + vector n = -normal[celli]/mag(normal[celli]); + scalar dist = (centre[celli] - mesh_.C()[celli]) & n; + reconDistFunc[celli] = dist; + } + else // nextToInterfaceCell or level == 1 cell + { + scalar averageDist = 0; + scalar avgWeight = 0; + const point p = mesh_.C()[celli]; + + forAll (stencil[celli],i) + { + const label gblIdx = stencil[celli][i]; + vector n = -distribute.getValue(normal, mapNormal, gblIdx); + if (mag(n) != 0) + { + n /= mag(n); + vector c = distribute.getValue(centre,mapCentres,gblIdx); + vector distanceToIntSeg = (c - p); + scalar distToSurf = distanceToIntSeg & (n); + scalar weight = 0; + + if (mag(distanceToIntSeg) != 0) + { + distanceToIntSeg /= mag(distanceToIntSeg); + weight = sqr(mag(distanceToIntSeg & n)); + } + else // exactly on the center + { + weight = 1; + } + averageDist += distToSurf * weight; + avgWeight += weight; + } + } + + if (avgWeight != 0) + { + reconDistFunc[celli] = averageDist / avgWeight; + } + } + } + else + { + reconDistFunc[celli] = 0; + } + } + + forAll(reconDistFunc.boundaryField(), patchI) + { + fvPatchScalarField& pRDF = reconDistFunc.boundaryFieldRef()[patchI]; + if (isA<calculatedFvPatchScalarField>(pRDF)) + { + const polyPatch& pp = pRDF.patch().patch(); + forAll(pRDF, i) + { + const label pCellI = pp.faceCells()[i]; + + if (nextToInterface_[pCellI]) + { + scalar averageDist = 0; + scalar avgWeight = 0; + const point p = mesh_.C().boundaryField()[patchI][i]; + + forAll (stencil[pCellI], j) + { + const label gblIdx = stencil[pCellI][j]; + vector n = -distribute.getValue(normal, mapNormal, gblIdx); + if (mag(n) != 0) + { + n /= mag(n); + vector c = + distribute.getValue(centre, mapCentres, gblIdx); + vector distanceToIntSeg = (c - p); + scalar distToSurf = distanceToIntSeg & (n); + scalar weight = 0; + + if (mag(distanceToIntSeg) != 0) + { + distanceToIntSeg /= mag(distanceToIntSeg); + weight = sqr(mag(distanceToIntSeg & n)); + } + else // exactly on the center + { + weight = 1; + } + averageDist += distToSurf * weight; + avgWeight += weight; + } + } + + if (avgWeight != 0) + { + pRDF[i] = averageDist / avgWeight; + } + else + { + pRDF[i] = 0; + } + } + else + { + pRDF[i] = 0; + } + } + } + } + + reconDistFunc.correctBoundaryConditions(); + + return reconDistFunc; +} + + +void Foam::reconstructedDistanceFunction::updateContactAngle +( + const volScalarField& alpha, + const volVectorField& U, + surfaceVectorField::Boundary& nHatb +) +{ + const fvMesh& mesh = alpha.mesh(); + const volScalarField::Boundary& abf = alpha.boundaryField(); + volScalarField::Boundary& RDFbf = this->boundaryFieldRef(); + + const fvBoundaryMesh& boundary = mesh.boundary(); + + forAll(boundary, patchi) + { + if (isA<alphaContactAngleTwoPhaseFvPatchScalarField>(abf[patchi])) + { + alphaContactAngleTwoPhaseFvPatchScalarField& acap = + const_cast<alphaContactAngleTwoPhaseFvPatchScalarField&> + ( + refCast<const alphaContactAngleTwoPhaseFvPatchScalarField> + ( + abf[patchi] + ) + ); + + fvsPatchVectorField& nHatp = nHatb[patchi]; + const scalarField theta + ( + degToRad()*acap.theta(U.boundaryField()[patchi], nHatp) + ); + + RDFbf[patchi] = + 1/acap.patch().deltaCoeffs()*cos(theta) + + RDFbf[patchi].patchInternalField(); + } + } +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructedDistanceFunction/reconstructedDistanceFunction.H b/src/transportModels/geometricVoF/reconstructedDistanceFunction/reconstructedDistanceFunction.H new file mode 100644 index 0000000000000000000000000000000000000000..278087e6d15f8444b177644ed56e7afa49c41117 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructedDistanceFunction/reconstructedDistanceFunction.H @@ -0,0 +1,131 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::reconstructedDistanceFunction + +Description + Calculates a reconstructed distance function + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + reconstructedDistanceFunction.C + +\*---------------------------------------------------------------------------*/ + +#ifndef reconstructedDistanceFunction_H +#define reconstructedDistanceFunction_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "globalIndex.H" +#include "Map.H" +#include "zoneDistribute.H" +#include "dimensionedScalar.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class reconstructedDistanceFunction Declaration +\*---------------------------------------------------------------------------*/ + +class reconstructedDistanceFunction +: + public volScalarField +{ + // Private Data + + //- Reference to mesh + const fvMesh& mesh_; + + //- Stores the coupled boundary points which have to be synced + labelList coupledBoundaryPoints_; + + //- Distance of the interface band to the interface + volScalarField cellDistLevel_; + + //- Is the cell in the interface band? + boolList nextToInterface_; + + //- Return patch of all coupled faces. + autoPtr<indirectPrimitivePatch> coupledFacesPatch() const; + + +public: + + //- Construct from fvMesh + explicit reconstructedDistanceFunction(const fvMesh& mesh); + + + // Member Functions + + void markCellsNearSurf + ( + const boolList& interfaceCells, + const label neiRingLevel + ); + + const volScalarField& constructRDF + ( + const boolList& nextToInterface, + const volVectorField& centre, + const volVectorField& normal, + zoneDistribute& distribute, + bool updateStencil=true + ); + + void updateContactAngle + ( + const volScalarField& alpha, + const volVectorField& U, + surfaceVectorField::Boundary& nHatb + ); + + const volScalarField& cellDistLevel() const + { + return cellDistLevel_; + } + + const boolList& nextToInterface() const + { + return nextToInterface_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/isoSchemes/isoAlpha/isoAlpha.C b/src/transportModels/geometricVoF/reconstructionSchemes/isoSchemes/isoAlpha/isoAlpha.C new file mode 100644 index 0000000000000000000000000000000000000000..8dcd46b87dbd52010d20ed03949df83b7367c0b6 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/isoSchemes/isoAlpha/isoAlpha.C @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "isoAlpha.H" +#include "addToRunTimeSelectionTable.H" +#include "cutCellPLIC.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace reconstruction +{ + defineTypeNameAndDebug(isoAlpha, 0); + addToRunTimeSelectionTable(reconstructionSchemes,isoAlpha, components); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::reconstruction::isoAlpha::isoAlpha +( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict +) +: + reconstructionSchemes + ( + typeName, + alpha1, + phi, + U, + dict + ), + mesh_(alpha1.mesh()), + // Interpolation data + ap_(mesh_.nPoints()), + + // Tolerances and solution controls + isoFaceTol_(modelDict().getOrDefault<scalar>("isoFaceTol", 1e-8)), + surfCellTol_(modelDict().getOrDefault<scalar>("surfCellTol", 1e-8)), + sIterIso_(mesh_, ap_, surfCellTol_) +{ + reconstruct(); +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::reconstruction::isoAlpha::reconstruct(bool forceUpdate) +{ + const bool uptodate = alreadyReconstructed(forceUpdate); + + if (uptodate && !forceUpdate) + { + return; + } + + // Interpolating alpha1 cell centre values to mesh points (vertices) + if (mesh_.topoChanging()) + { + // Introduced resizing to cope with changing meshes + if (ap_.size() != mesh_.nPoints()) + { + ap_.resize(mesh_.nPoints()); + + } + if (interfaceCell_.size() != mesh_.nCells()) + { + interfaceCell_.resize(mesh_.nCells()); + } + } + ap_ = volPointInterpolation::New(mesh_).interpolate(alpha1_); + + DynamicList<List<point>> facePts; + + interfaceLabels_.clear(); + + forAll(alpha1_,cellI) + { + if (sIterIso_.isASurfaceCell(alpha1_[cellI])) + { + interfaceLabels_.append(cellI); + + sIterIso_.vofCutCell + ( + cellI, + alpha1_[cellI], + isoFaceTol_, + 100 + ); + + if (sIterIso_.cellStatus() == 0) + { + normal_[cellI] = sIterIso_.surfaceArea(); + centre_[cellI] = sIterIso_.surfaceCentre(); + if (mag(normal_[cellI]) != 0) + { + interfaceCell_[cellI] = true; + } + else + { + interfaceCell_[cellI] = false; + } + } + else + { + normal_[cellI] = Zero; + centre_[cellI] = Zero; + interfaceCell_[cellI] = false; + } + } + else + { + normal_[cellI] = Zero; + centre_[cellI] = Zero; + interfaceCell_[cellI] = false; + } + } +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/isoSchemes/isoAlpha/isoAlpha.H b/src/transportModels/geometricVoF/reconstructionSchemes/isoSchemes/isoAlpha/isoAlpha.H new file mode 100644 index 0000000000000000000000000000000000000000..b5f436e200e48778d768fa90e612d2336be59d16 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/isoSchemes/isoAlpha/isoAlpha.H @@ -0,0 +1,150 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::reconstruction::isoAlpha + +Description + Reconstructs an interface (centre and normal vectors) consisting of isosurfaces + to match the internal fluid distribution in cells. The point values (ap_) + are estimated by inverse distance interpolation of the VoF (alpha) field. + + Reference: + \verbatim + Roenby, J., Bredmose, H. and Jasak, H. (2016). + A computational method for sharp interface advection + Royal Society Open Science, 3 + doi 10.1098/rsos.160405 + \endverbatim + + Original code supplied by Johan Roenby, DHI (2016) + +Author + Johan Roenby, DHI, all rights reserved. + Modified Henning Scheufler, DLR + +SourceFiles + isoAlpha.C + +\*---------------------------------------------------------------------------*/ + +#ifndef isoAlpha_H +#define isoAlpha_H + +#include "autoPtr.H" +#include "dimensionedScalar.H" +#include "reconstructionSchemes.H" +#include "typeInfo.H" +#include "volFields.H" + +#include "surfaceIteratorIso.H" +#include "volPointInterpolation.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace reconstruction +{ + +/*---------------------------------------------------------------------------*\ + Class isoAlpha Declaration +\*---------------------------------------------------------------------------*/ + +class isoAlpha +: + public reconstructionSchemes +{ + // Private Data + + //- Reference to mesh + const fvMesh& mesh_; + + //- VOF field interpolated to mesh points + scalarField ap_; + + // Switches and tolerances. Tolerances need to go into toleranceSwitches + + //- Tolerance for search of isoFace giving specified VOF value + scalar isoFaceTol_; + + //- Tolerance for marking of surface cells: + // Those with surfCellTol_ < alpha1 < 1 - surfCellTol_ + scalar surfCellTol_; + + //- surfaceIterator finds the isovalue for specified VOF value + surfaceIteratorIso sIterIso_; + + + // Private Member Functions + + //- No copy construct + isoAlpha(const isoAlpha&) = delete; + + //- No copy assignment + void operator=(const isoAlpha&) = delete; + + +public: + + //- Runtime type information + TypeName("isoAlpha"); + + //- Construct from components + isoAlpha + ( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict + ); + + + //- Destructor + virtual ~isoAlpha() = default; + + + // Member Functions + + //- Reconstructs the interface + virtual void reconstruct(bool forceUpdate = true); + + //- map VoF Field in case of refinement + virtual void mapAlphaField() const + { + // do nothing; + } +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace reconstruction +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/gradAlpha/gradAlpha.C b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/gradAlpha/gradAlpha.C new file mode 100644 index 0000000000000000000000000000000000000000..b65b323946b60e29c808934db412218e61960d53 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/gradAlpha/gradAlpha.C @@ -0,0 +1,223 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "gradAlpha.H" +#include "fvc.H" +#include "leastSquareGrad.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace reconstruction +{ + defineTypeNameAndDebug(gradAlpha, 0); + addToRunTimeSelectionTable(reconstructionSchemes, gradAlpha, components); +} +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::reconstruction::gradAlpha::gradSurf(const volScalarField& phi) +{ + leastSquareGrad<scalar> lsGrad("polyDegree1",mesh_.geometricD()); + + exchangeFields_.setUpCommforZone(interfaceCell_,true); + + Map<vector> mapCC + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, mesh_.C()) + ); + Map<scalar> mapPhi + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, phi) + ); + + DynamicField<vector> cellCentre(100); + DynamicField<scalar> phiValues(100); + + const labelListList& stencil = exchangeFields_.getStencil(); + + forAll(interfaceLabels_, i) + { + const label celli = interfaceLabels_[i]; + + cellCentre.clear(); + phiValues.clear(); + + for (const label gblIdx : stencil[celli]) + { + cellCentre.append + ( + exchangeFields_.getValue(mesh_.C(), mapCC, gblIdx) + ); + phiValues.append + ( + exchangeFields_.getValue(phi, mapPhi, gblIdx) + ); + } + + cellCentre -= mesh_.C()[celli]; + interfaceNormal_[i] = lsGrad.grad(cellCentre, phiValues); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::reconstruction::gradAlpha::gradAlpha +( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict +) +: + reconstructionSchemes + ( + typeName, + alpha1, + phi, + U, + dict + ), + mesh_(alpha1.mesh()), + interfaceNormal_(fvc::grad(alpha1)), + isoFaceTol_(modelDict().getOrDefault<scalar>("isoFaceTol", 1e-8)), + surfCellTol_(modelDict().getOrDefault<scalar>("surfCellTol", 1e-8)), + exchangeFields_(zoneDistribute::New(mesh_)), + sIterPLIC_(mesh_,surfCellTol_) +{ + reconstruct(); +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::reconstruction::gradAlpha::reconstruct(bool forceUpdate) +{ + const bool uptodate = alreadyReconstructed(forceUpdate); + + if (uptodate && !forceUpdate) + { + return; + } + + if (mesh_.topoChanging()) + { + // Introduced resizing to cope with changing meshes + if (interfaceCell_.size() != mesh_.nCells()) + { + interfaceCell_.resize(mesh_.nCells()); + } + } + interfaceCell_ = false; + + interfaceLabels_.clear(); + + forAll(alpha1_, celli) + { + if (sIterPLIC_.isASurfaceCell(alpha1_[celli])) + { + interfaceCell_[celli] = true; // is set to false earlier + interfaceLabels_.append(celli); + } + } + interfaceNormal_.resize(interfaceLabels_.size()); + centre_ = dimensionedVector("centre", dimLength, Zero); + normal_ = dimensionedVector("normal", dimArea, Zero); + + gradSurf(alpha1_); + + forAll(interfaceLabels_, i) + { + const label celli = interfaceLabels_[i]; + if (mag(interfaceNormal_[i]) == 0) + { + continue; + } + + sIterPLIC_.vofCutCell + ( + celli, + alpha1_[celli], + isoFaceTol_, + 100, + interfaceNormal_[i] + ); + + if (sIterPLIC_.cellStatus() == 0) + { + normal_[celli] = sIterPLIC_.surfaceArea(); + centre_[celli] = sIterPLIC_.surfaceCentre(); + if (mag(normal_[celli]) == 0) + { + normal_[celli] = Zero; + centre_[celli] = Zero; + } + } + else + { + normal_[celli] = Zero; + centre_[celli] = Zero; + } + } +} + + +void Foam::reconstruction::gradAlpha::mapAlphaField() const +{ + // Without this line, we seem to get a race condition + mesh_.C(); + + cutCellPLIC cutCell(mesh_); + + forAll(normal_, celli) + { + if (mag(normal_[celli]) != 0) + { + vector n = normal_[celli]/mag(normal_[celli]); + scalar cutValue = (centre_[celli] - mesh_.C()[celli]) & (n); + cutCell.calcSubCell + ( + celli, + cutValue, + n + ); + alpha1_[celli] = cutCell.VolumeOfFluid(); + } + } + + alpha1_.correctBoundaryConditions(); + alpha1_.oldTime () = alpha1_; + alpha1_.oldTime().correctBoundaryConditions(); +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/gradAlpha/gradAlpha.H b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/gradAlpha/gradAlpha.H new file mode 100644 index 0000000000000000000000000000000000000000..4933ddd005c929f801a7353e997baa601ecbbb43 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/gradAlpha/gradAlpha.H @@ -0,0 +1,142 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::reconstruction::gradAlpha + +Description + Reconstructs an interface (centre and normal vector) consisting of planes + to match the internal fluid distribution in cells. The interface normals + are estimated by least square gradient scheme on the VoF Field (alpha). + Also known as Young method + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + gradAlpha.C + +\*---------------------------------------------------------------------------*/ + +#ifndef gradAlpha_H +#define gradAlpha_H + +#include "typeInfo.H" +#include "reconstructionSchemes.H" +#include "volFields.H" +#include "dimensionedScalar.H" +#include "autoPtr.H" +#include "surfaceIteratorPLIC.H" +#include "zoneDistribute.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace reconstruction +{ + +/*---------------------------------------------------------------------------*\ + Class gradAlpha Declaration +\*---------------------------------------------------------------------------*/ + +class gradAlpha +: + public reconstructionSchemes +{ + // Private Data + + //- Reference to mesh + const fvMesh& mesh_; + + //- Interpolation object from cell centres to points + DynamicField<vector> interfaceNormal_; + + + // Switches and tolerances. Tolerances need to go into toleranceSwitches + + //- Tolerance for search of isoFace giving specified VOF value + scalar isoFaceTol_; + + //- Tolerance for marking of surface cells: + // Those with surfCellTol_ < alpha1 < 1 - surfCellTol_ + scalar surfCellTol_; + + //- Provides stencil and map + zoneDistribute& exchangeFields_; + + //- SurfaceIterator finds the plane centre for specified VOF value + surfaceIteratorPLIC sIterPLIC_; + + + // Private Member Functions + + //- Compute gradient at the surfaces + void gradSurf(const volScalarField& phi); + + //- No copy construct + gradAlpha(const gradAlpha&) = delete; + + //- No copy assignment + void operator=(const gradAlpha&) = delete; + + +public: + + //- Runtime type information + TypeName("gradAlpha"); + + //- Construct from components + gradAlpha + ( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict + ); + + //- Destructor + virtual ~gradAlpha() = default; + + + // Member Functions + + //- Reconstruct interface + virtual void reconstruct(bool forceUpdate = true); + + //- map VoF Field in case of refinement + virtual void mapAlphaField() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace reconstruction +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/plicRDF/plicRDF.C b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/plicRDF/plicRDF.C new file mode 100644 index 0000000000000000000000000000000000000000..7f30e66405e3add6ab2b802e4b1a251f49a3ca63 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/plicRDF/plicRDF.C @@ -0,0 +1,570 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "plicRDF.H" +#include "interpolationCellPoint.H" +#include "fvc.H" +#include "leastSquareGrad.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace reconstruction +{ + defineTypeNameAndDebug(plicRDF, 0); + addToRunTimeSelectionTable(reconstructionSchemes,plicRDF, components); +} +} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + +void Foam::reconstruction::plicRDF::interpolateNormal() +{ + scalar dt = mesh_.time().deltaTValue(); + + leastSquareGrad<scalar> lsGrad("polyDegree1",mesh_.geometricD()); + + exchangeFields_.setUpCommforZone(interfaceCell_,false); + + Map<vector> mapCentre + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, centre_) + ); + Map<vector> mapNormal + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, normal_) + ); + + Map<vector> mapCC + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, mesh_.C()) + ); + Map<scalar> mapAlpha + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, alpha1_) + ); + + DynamicField<vector > cellCentre(100); + DynamicField<scalar > alphaValues(100); + + DynamicList<vector> foundNormals(30); + + const labelListList& stencil = exchangeFields_.getStencil(); + + forAll(interfaceLabels_, i) + { + const label celli = interfaceLabels_[i]; + vector estimatedNormal{Zero}; + scalar weight{0}; + foundNormals.clear(); + forAll(stencil[celli], i) + { + const label gblIdx = stencil[celli][i]; + vector n = + exchangeFields_.getValue(normal_, mapNormal, gblIdx); + point p = mesh_.C()[celli]-U_[celli]*dt; + if (mag(n) != 0) + { + n /= mag(n); + vector centre = + exchangeFields_.getValue(centre_, mapCentre, gblIdx); + vector distanceToIntSeg = (tensor::I- n*n) & (p - centre); + estimatedNormal += n /max(mag(distanceToIntSeg), SMALL); + weight += 1/max(mag(distanceToIntSeg), SMALL); + foundNormals.append(n); + } + } + + if (weight != 0 && mag(estimatedNormal) != 0) + { + estimatedNormal /= weight; + estimatedNormal /= mag(estimatedNormal); + } + + bool tooCoarse = false; + + if (foundNormals.size() > 1 && mag(estimatedNormal) != 0) + { + forAll(foundNormals, i) + { + // all have the length of 1 + // to coarse if normal angle is bigger than 10 deg + if ((estimatedNormal & foundNormals[i]) <= 0.98) + { + tooCoarse = true; + } + } + } + else + { + tooCoarse = true; + } + + // if a normal was found and the interface is fine enough + // smallDist is always smallDist + if (mag(estimatedNormal) != 0 && !tooCoarse) + { + interfaceNormal_[i] = estimatedNormal; + } + else + { + cellCentre.clear(); + alphaValues.clear(); + + forAll(stencil[celli],i) + { + const label gblIdx = stencil[celli][i]; + cellCentre.append + ( + exchangeFields_.getValue(mesh_.C(), mapCC, gblIdx) + ); + alphaValues.append + ( + exchangeFields_.getValue(alpha1_, mapAlpha, gblIdx) + ); + } + cellCentre -= mesh_.C()[celli]; + interfaceNormal_[i] = lsGrad.grad(cellCentre, alphaValues); + } + + } +} + +void Foam::reconstruction::plicRDF::gradSurf(const volScalarField& phi) +{ + leastSquareGrad<scalar> lsGrad("polyDegree1", mesh_.geometricD()); + + exchangeFields_.setUpCommforZone(interfaceCell_, false); + + Map<vector> mapCC + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, mesh_.C()) + ); + Map<scalar> mapPhi + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, phi) + ); + + DynamicField<vector> cellCentre(100); + DynamicField<scalar> phiValues(100); + + const labelListList& stencil = exchangeFields_.getStencil(); + + forAll(interfaceLabels_, i) + { + const label celli = interfaceLabels_[i]; + + cellCentre.clear(); + phiValues.clear(); + + for (const label gblIdx : stencil[celli]) + { + cellCentre.append + ( + exchangeFields_.getValue(mesh_.C(), mapCC, gblIdx) + ); + phiValues.append + ( + exchangeFields_.getValue(phi, mapPhi, gblIdx) + ); + } + + cellCentre -= mesh_.C()[celli]; + interfaceNormal_[i] = lsGrad.grad(cellCentre, phiValues); + } +} + + +void Foam::reconstruction::plicRDF::setInitNormals(bool interpolate) +{ + interfaceLabels_.clear(); + + forAll(alpha1_, celli) + { + if (sIterPLIC_.isASurfaceCell(alpha1_[celli])) + { + interfaceCell_[celli] = true; // is set to false earlier + interfaceLabels_.append(celli); + } + } + interfaceNormal_.setSize(interfaceLabels_.size()); + + RDF_.markCellsNearSurf(interfaceCell_, 1); + const boolList& nextToInterface_ = RDF_.nextToInterface(); + exchangeFields_.updateStencil(nextToInterface_); + + if (interpolate) + { + interpolateNormal(); + } + else + { + gradSurf(alpha1_); + } +} + + +void Foam::reconstruction::plicRDF::calcResidual +( + Map<scalar>& normalResidual, + Map<scalar>& avgAngle +) +{ + exchangeFields_.setUpCommforZone(interfaceCell_,false); + + Map<vector> mapNormal + ( + exchangeFields_.getDatafromOtherProc(interfaceCell_, normal_) + ); + + const labelListList& stencil = exchangeFields_.getStencil(); + + normalResidual.clear(); + + forAll(interfaceLabels_, i) + { + const label celli = interfaceLabels_[i]; + if (mag(normal_[celli]) == 0 || mag(interfaceNormal_[i]) == 0) + { + continue; + } + + scalar avgDiffNormal = 0; + scalar maxDiffNormal = GREAT; + scalar weight= 0; + const vector cellNormal = normal_[celli]/mag(normal_[celli]); + + for (const label gblIdx : stencil[celli]) + { + vector normal = + exchangeFields_.getValue(normal_, mapNormal, gblIdx); + + if (mag(normal) != 0 && i != 0) + { + vector n = normal/mag(normal); + scalar cosAngle = max(min((cellNormal & n), 1), -1); + avgDiffNormal += acos(cosAngle) * mag(normal); + weight += mag(normal); + if (cosAngle < maxDiffNormal) + { + maxDiffNormal = cosAngle; + } + } + } + + if (weight != 0) + { + avgDiffNormal /= weight; + } + else + { + avgDiffNormal = 0; + } + + vector newCellNormal = normalised(interfaceNormal_[i]); + + scalar normalRes = (1 - (cellNormal & newCellNormal)); + avgAngle.insert(celli, avgDiffNormal); + normalResidual.insert(celli, normalRes); + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::reconstruction::plicRDF::plicRDF +( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict +) +: + reconstructionSchemes + ( + typeName, + alpha1, + phi, + U, + dict + ), + mesh_(alpha1.mesh()), + + interfaceNormal_(0.2*mesh_.nCells()), + + isoFaceTol_(modelDict().getOrDefault<scalar>("isoFaceTol", 1e-8)), + surfCellTol_(modelDict().getOrDefault<scalar>("surfCellTol", 1e-8)), + tol_(modelDict().getOrDefault<scalar>("tol", 1e-6)), + relTol_(modelDict().getOrDefault<scalar>("relTol", 0.1)), + iteration_(modelDict().getOrDefault<label>("iterations", 5)), + interpolateNormal_(modelDict().getOrDefault("interpolateNormal", true)), + RDF_(mesh_), + exchangeFields_(zoneDistribute::New(mesh_)), + sIterPLIC_(mesh_,surfCellTol_) +{ + setInitNormals(false); + + centre_ = dimensionedVector("centre", dimLength, Zero); + normal_ = dimensionedVector("normal", dimArea, Zero); + + forAll(interfaceLabels_, i) + { + const label celli = interfaceLabels_[i]; + if (mag(interfaceNormal_[i]) == 0) + { + continue; + } + sIterPLIC_.vofCutCell + ( + celli, + alpha1_[celli], + isoFaceTol_, + 100, + interfaceNormal_[i] + ); + + if (sIterPLIC_.cellStatus() == 0) + { + normal_[celli] = sIterPLIC_.surfaceArea(); + centre_[celli] = sIterPLIC_.surfaceCentre(); + if (mag(normal_[celli]) == 0) + { + normal_[celli] = Zero; + centre_[celli] = Zero; + } + } + else + { + normal_[celli] = Zero; + centre_[celli] = Zero; + } + } +} + + +// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // + +void Foam::reconstruction::plicRDF::reconstruct(bool forceUpdate) +{ + const bool uptodate = alreadyReconstructed(forceUpdate); + + if (uptodate && !forceUpdate) + { + return; + } + + if (mesh_.topoChanging()) + { + // Introduced resizing to cope with changing meshes + if (interfaceCell_.size() != mesh_.nCells()) + { + interfaceCell_.resize(mesh_.nCells()); + } + } + interfaceCell_ = false; + + // Sets interfaceCell_ and interfaceNormal + setInitNormals(interpolateNormal_); + + centre_ = dimensionedVector("centre", dimLength, Zero); + normal_ = dimensionedVector("normal", dimArea, Zero); + + // nextToInterface is update on setInitNormals + const boolList& nextToInterface_ = RDF_.nextToInterface(); + + labelHashSet tooCoarse; + + for (int iter=0; iter<iteration_; ++iter) + { + forAll(interfaceLabels_, i) + { + const label celli = interfaceLabels_[i]; + if (mag(interfaceNormal_[i]) == 0 || tooCoarse.found(celli)) + { + continue; + } + sIterPLIC_.vofCutCell + ( + celli, + alpha1_[celli], + isoFaceTol_, + 100, + interfaceNormal_[i] + ); + + if (sIterPLIC_.cellStatus() == 0) + { + + normal_[celli] = sIterPLIC_.surfaceArea(); + centre_[celli] = sIterPLIC_.surfaceCentre(); + if (mag(normal_[celli]) == 0) + { + normal_[celli] = Zero; + centre_[celli] = Zero; + } + } + else + { + normal_[celli] = Zero; + centre_[celli] = Zero; + } + } + + normal_.correctBoundaryConditions(); + centre_.correctBoundaryConditions(); + Map<scalar> residual; + Map<scalar> avgAngle; + + surfaceVectorField::Boundary nHatb(mesh_.Sf().boundaryField()); + nHatb *= 1/(mesh_.magSf().boundaryField()); + + { + RDF_.constructRDF + ( + nextToInterface_, + centre_, + normal_, + exchangeFields_, + false + ); + RDF_.updateContactAngle(alpha1_, U_, nHatb); + gradSurf(RDF_); + calcResidual(residual, avgAngle); + } + + + label resCounter = 0; + scalar avgRes = 0; + scalar avgNormRes = 0; + + Map<scalar>::iterator resIter = residual.begin(); + Map<scalar>::iterator avgAngleIter = avgAngle.begin(); + + while (resIter.found()) + { + if (avgAngleIter() > 0.26 && iter > 0) // 15 deg + { + tooCoarse.set(resIter.key()); + } + else + { + avgRes += resIter(); + scalar normRes = 0; + scalar discreteError = 0.01*sqr(avgAngleIter()); + if (discreteError != 0) + { + normRes= resIter()/max(discreteError, tol_); + } + else + { + normRes= resIter()/tol_; + } + avgNormRes += normRes; + resCounter++; + + } + + ++resIter; + ++avgAngleIter; + } + + reduce(avgRes,sumOp<scalar>()); + reduce(avgNormRes,sumOp<scalar>()); + reduce(resCounter,sumOp<label>()); + + if (resCounter == 0) // avoid division by zero and leave loop + { + resCounter = 1; + avgRes = 0; + avgNormRes = 0; + } + + + if (iter == 0) + { + DebugInfo + << "initial residual absolute = " + << avgRes/resCounter << nl + << "initial residual normalized = " + << avgNormRes/resCounter << nl; + } + + if + ( + ( + (avgNormRes/resCounter < relTol_ || avgRes/resCounter < tol_) + && (iter >= 1 ) + ) + || iter + 1 == iteration_ + ) + { + DebugInfo + << "iterations = " << iter << nl + << "final residual absolute = " + << avgRes/resCounter << nl + << "final residual normalized = " << avgNormRes/resCounter + << endl; + + break; + } + } +} + + +void Foam::reconstruction::plicRDF::mapAlphaField() const +{ + // without it we seem to get a race condition + mesh_.C(); + + cutCellPLIC cutCell(mesh_); + + forAll(normal_, celli) + { + if (mag(normal_[celli]) != 0) + { + vector n = normal_[celli]/mag(normal_[celli]); + scalar cutValue = (centre_[celli] - mesh_.C()[celli]) & (n); + cutCell.calcSubCell + ( + celli, + cutValue, + n + ); + alpha1_[celli] = cutCell.VolumeOfFluid(); + + } + } + alpha1_.correctBoundaryConditions(); + alpha1_.oldTime () = alpha1_; + alpha1_.oldTime().correctBoundaryConditions(); +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/plicRDF/plicRDF.H b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/plicRDF/plicRDF.H new file mode 100644 index 0000000000000000000000000000000000000000..6c394b2fc997d3970054c385637ffb094b021a52 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/plicRDF/plicRDF.H @@ -0,0 +1,185 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::reconstruction::plicRDF + +Description + Reconstructs an interface (centre and normal vector) consisting of planes + to match the internal fluid distribution in cells. The interface normals + are estimated by least square gradient scheme on the RDF function (height). + Uses the normal from the previous times step as intial guess. + + Reference: + \verbatim + Henning Scheufler, Johan Roenby, + Accurate and efficient surface reconstruction from volume + fraction data on general meshes, + Journal of Computational Physics, 2019, + doi 10.1016/j.jcp.2019.01.009 + + \endverbatim + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + plicRDF.C + +\*---------------------------------------------------------------------------*/ + +#ifndef plicRDF_H +#define plicRDF_H + +#include "typeInfo.H" +#include "reconstructionSchemes.H" +#include "volFields.H" +#include "dimensionedScalar.H" +#include "autoPtr.H" +#include "surfaceIteratorPLIC.H" +#include "reconstructedDistanceFunction.H" +#include "zoneDistribute.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace reconstruction +{ + +/*---------------------------------------------------------------------------*\ + Class plicRDF Declaration +\*---------------------------------------------------------------------------*/ + +class plicRDF +: + public reconstructionSchemes +{ + // Private Data + + //- Reference to mesh + const fvMesh& mesh_; + + //- Interpolation object from cell centres to points + DynamicField<vector> interfaceNormal_; + + + // Switches and tolerances. Tolerances need to go into toleranceSwitches + + //- Tolerance for search of isoFace giving specified VOF value + scalar isoFaceTol_; + + //- Tolerance for marking of surface cells: + // Those with surfCellTol_ < alpha1 < 1 - surfCellTol_ + scalar surfCellTol_; + + //- Tolerance + scalar tol_; + + //- Relative tolerance + scalar relTol_; + + //- Number of times that the interface is reconstructed + //- has to be bigger than 2 + label iteration_; + + //- Interpolated normal from previous time step + bool interpolateNormal_; + + //- Calculates the RDF function + reconstructedDistanceFunction RDF_; + + //- Provides stencil and map + zoneDistribute& exchangeFields_; + + //- surfaceIterator finds the plane centre for specified VOF value + surfaceIteratorPLIC sIterPLIC_; + + + // Private Member Functions + + //- Set initial normals by interpolation from the previous + //- timestep or with the Young method + void setInitNormals(bool interpolate); + + //- compute gradient at the surfaces + void gradSurf(const volScalarField& phi); + + //- compute the normal residuals + void calcResidual + ( + Map<scalar>& normalResidual, + Map<scalar>& avgAngle + ); + + //- interpolation of the normals from the previous time step + void interpolateNormal(); + + //- No copy construct + plicRDF(const plicRDF&) = delete; + + //- No copy assignment + void operator=(const plicRDF&) = delete; + + +public: + + //- Runtime type information + TypeName("plicRDF"); + + + //- Construct from components + plicRDF + ( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict + ); + + + //- Destructor + virtual ~plicRDF() = default; + + + // Member Functions + + //- Reconstruct interface + virtual void reconstruct(bool forceUpdate = true); + + //- Map VoF Field in case of refinement + virtual void mapAlphaField() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace reconstruction +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemes.C b/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemes.C new file mode 100644 index 0000000000000000000000000000000000000000..78f81981a0fe98bcca422caed8287fbe5c58a6a7 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemes.C @@ -0,0 +1,185 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "reconstructionSchemes.H" +#include "cutCellPLIC.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(reconstructionSchemes, 0); + defineRunTimeSelectionTable(reconstructionSchemes, components); +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +bool Foam::reconstructionSchemes::alreadyReconstructed(bool forceUpdate) const +{ + const Time& runTime = alpha1_.mesh().time(); + + label& curTimeIndex = timeIndexAndIter_.first(); + label& curIter = timeIndexAndIter_.second(); + + // Reset timeIndex and curIter + if (curTimeIndex < runTime.timeIndex()) + { + curTimeIndex = runTime.timeIndex(); + curIter = 0; + return false; + } + + if (forceUpdate) + { + curIter = 0; + return false; + } + + // Always reconstruct when subcycling + if (runTime.subCycling() != 0) + { + return false; + } + + ++curIter; + if (curIter > 1) + { + return true; + } + + return false; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::reconstructionSchemes::reconstructionSchemes +( + const word& type, + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict +) +: + IOdictionary + ( + IOobject + ( + "reconstructionScheme", + alpha1.time().constant(), + alpha1.db(), + IOobject::NO_READ, + IOobject::NO_WRITE + ) + ), + reconstructionSchemesCoeffs_(dict), + alpha1_(alpha1), + phi_(phi), + U_(U), + normal_ + ( + IOobject + ( + "recon::normal", + alpha1_.mesh().time().timeName(), + alpha1_.mesh(), + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + alpha1_.mesh(), + dimensionedVector(dimArea, Zero) + ), + centre_ + ( + IOobject + ( + "recon::centre", + alpha1_.mesh().time().timeName(), + alpha1_.mesh(), + IOobject::NO_READ, + IOobject::AUTO_WRITE + ), + alpha1_.mesh(), + dimensionedVector(dimLength, Zero) + ), + interfaceCell_(alpha1_.mesh().nCells(), false), + interfaceLabels_(0.2*alpha1_.mesh().nCells()), + timeIndexAndIter_(0, 0) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::reconstructionSchemes::interface Foam::reconstructionSchemes::surface() +{ + reconstruct(false); + const fvMesh& mesh = centre_.mesh(); + + cutCellPLIC cellCut(mesh); + + DynamicList<point> dynPts; + DynamicList<face> dynFaces(mesh.nCells()*0.1); + bitSet interfaceCellAddressing(mesh.nCells()); + + forAll(interfaceCell_, celli) + { + if (interfaceCell_[celli]) + { + if (mag(normal_[celli]) != 0) + { + interfaceCellAddressing.set(celli); + vector n = -normal_[celli]/mag(normal_[celli]); + + scalar cutVal = (centre_[celli] - mesh.C()[celli]) & n; + cellCut.calcSubCell(celli, cutVal, n); + + // cellCut.facePoints() are ordered and not connected + // to the other face + // append face with the starting label: dynPts.size() + dynFaces.append + ( + face(identity(cellCut.facePoints().size(), dynPts.size())) + ); + dynPts.append(cellCut.facePoints()); + } + } + } + + + labelList meshCells(interfaceCellAddressing.sortedToc()); + + // Transfer to mesh storage + pointField pts(std::move(dynPts)); + faceList faces(std::move(dynFaces)); + + return interface(std::move(pts), std::move(faces), std::move(meshCells)); +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemes.H b/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemes.H new file mode 100644 index 0000000000000000000000000000000000000000..4a3ce6caac4cf281c2d21816ba0ff4d2c1042345 --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemes.H @@ -0,0 +1,269 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::reconstructionSchemes + +Description + + Original code supplied by Henning Scheufler, DLR (2019) + +SourceFiles + reconstructionSchemes.C + +\*---------------------------------------------------------------------------*/ + +#ifndef reconstructionSchemes_H +#define reconstructionSchemes_H + +#include "typeInfo.H" +#include "runTimeSelectionTables.H" +#include "dimensionedScalar.H" +#include "volFields.H" +#include "IOdictionary.H" +#include "DynamicField.H" +#include "MeshedSurface.H" +#include "MeshedSurfacesFwd.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class reconstructionSchemes Declaration +\*---------------------------------------------------------------------------*/ + +class reconstructionSchemes +: + public IOdictionary +{ + // Private Data + + //- Coefficients dictionary + dictionary reconstructionSchemesCoeffs_; + + +protected: + + // Protected Data + + //- Reference to the VoF Field + volScalarField& alpha1_; + + //- Reference to the face fluxes + const surfaceScalarField& phi_; + + //- Reference to the velocity field + const volVectorField& U_; + + //- Interface area normals + volVectorField normal_; + + //- Interface centres + volVectorField centre_; + + //- Is interface cell? + boolList interfaceCell_; + + //- List of cell labels that have an interface + DynamicField<label> interfaceLabels_; + + //- Store timeindex/iteration to avoid multiple reconstruction + mutable Pair<label> timeIndexAndIter_; + + + // Protected Member Functions + + //- Is the interface already up-to-date? + bool alreadyReconstructed(bool forceUpdate = true) const; + + //- No copy construct + reconstructionSchemes(const reconstructionSchemes&) = delete; + + //- No copy assignment + void operator=(const reconstructionSchemes&) = delete; + + +public: + + // Public Classes + + class interface + : + public meshedSurface + { + //- For every face the original cell in mesh + labelList meshCells_; + + public: + + interface + ( + const pointField& pointLst, + const faceList& faceLst, + const labelList& meshCells + ) + : + meshedSurface(pointLst, faceLst, surfZoneList{}), + meshCells_(meshCells) + {} + + interface + ( + pointField&& pointLst, + faceList&& faceLst, + labelList&& meshCells + ) + : + meshedSurface + ( + std::move(pointLst), + std::move(faceLst), + surfZoneList{} + ), + meshCells_(std::move(meshCells)) + {} + + //- For every face, the original cell in mesh + const labelList& meshCells() const + { + return meshCells_; + } + }; + + +public: + + //- Runtime type information + TypeName("reconstructionSchemes"); + + + // Declare run-time constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + reconstructionSchemes, + components, + ( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict + ), + (alpha1, phi, U, dict) + ); + + + // Selectors + + //- Return a reference to the selected phaseChange model + static autoPtr<reconstructionSchemes> New + ( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict + ); + + + // Constructors + + //- Construct from components + reconstructionSchemes + ( + const word& type, + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict + ); + + + //- Destructor + virtual ~reconstructionSchemes() = default; + + + // Member Functions + + //- Access to the model dictionary + dictionary& modelDict() + { + return reconstructionSchemesCoeffs_; + } + + //- Const access to the model dictionary + const dictionary& modelDict() const + { + return reconstructionSchemesCoeffs_; + } + + //- Reconstruct the interface + virtual void reconstruct(bool forceUpdate = true) = 0; + + //- Reference to interface normals + const volVectorField& normal() const + { + return normal_; + } + + //- Reference to interface centres + const volVectorField& centre() const + { + return centre_; + } + + //- Does the cell contain interface + const boolList& interfaceCell() const + { + return interfaceCell_; + } + + //- List of cells with an interface + const DynamicField<label>& interfaceLabels() const + { + return interfaceLabels_; + } + + //- Map VoF Field in case of refinement + virtual void mapAlphaField() const + {} + + //- Generated interface surface points/faces. + // \note the points are disconnected! + interface surface(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemesNew.C b/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemesNew.C new file mode 100644 index 0000000000000000000000000000000000000000..7891acdc15dd50792d3d3f3fd334429000b0223e --- /dev/null +++ b/src/transportModels/geometricVoF/reconstructionSchemes/reconstructionSchemesNew.C @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "reconstructionSchemes.H" +#include "messageStream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::reconstructionSchemes> +Foam::reconstructionSchemes::New +( + volScalarField& alpha1, + const surfaceScalarField& phi, + const volVectorField& U, + const dictionary& dict +) +{ + word schemeType("isoAlpha"); + + if (!dict.readIfPresent("reconstructionScheme", schemeType)) + { + Warning + << "Entry '" + << "reconstructionScheme" << "' not found in dictionary " + << dict.name() << nl + << "using default" << nl; + } + + Info<< "Selecting reconstructionScheme: " << schemeType << endl; + + auto cstrIter = componentsConstructorTablePtr_->cfind(schemeType); + + if (!cstrIter.found()) + { + FatalIOErrorInLookup + ( + dict, + "reconstructionSchemes", + schemeType, + *componentsConstructorTablePtr_ + ) << exit(FatalIOError); + } + + return autoPtr<reconstructionSchemes>(cstrIter()(alpha1, phi, U, dict)); +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorIso.C b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorIso.C new file mode 100644 index 0000000000000000000000000000000000000000..305af0894b66139df17e4b09a482268b98331cfa --- /dev/null +++ b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorIso.C @@ -0,0 +1,203 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "surfaceIteratorIso.H" +#include "scalarMatrices.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceIteratorIso::surfaceIteratorIso +( + const fvMesh& mesh, + scalarField& pointVal, + const scalar tol +) +: + mesh_(mesh), + ap_(pointVal), + cutCell_(mesh_,ap_), + surfCellTol_(tol) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::surfaceIteratorIso::vofCutCell +( const label celli, + const scalar alpha1, + const scalar tol, + const label maxIter +) +{ + // Finding cell vertex extrema values + const labelList& pLabels = mesh_.cellPoints()[celli]; + scalarField fvert(pLabels.size()); + forAll(pLabels, pi) + { + fvert[pi] = ap_[pLabels[pi]]; + } + + const labelList order(Foam::sortedOrder(fvert)); + scalar f1 = fvert[order.first()]; + scalar f2 = fvert[order.last()]; + + // Special case where method is given an almost full or empty cell + if (alpha1 < tol) + { + return -1; // is area and centre is zero; + } + else if (1 - alpha1 < tol) + { + return 1; + } + + // Finding the two vertices inbetween which the isovalue giving alpha1 lies + label L1 = 0; + label L2 = fvert.size() - 1; + scalar a1 = 1; + scalar a2 = 0; + scalar L3, f3, a3; + + while (L2 - L1 > 1) + { + L3 = round(0.5*(L1 + L2)); + f3 = fvert[order[L3]]; + cutCell_.calcSubCell(celli, f3); + a3 = cutCell_.VolumeOfFluid(); + if (a3 > alpha1) + { + L1 = L3; f1 = f3; a1 = a3; + } + else if (a3 < alpha1) + { + L2 = L3; f2 = f3; a2 = a3; + } + else + { + return cutCell_.calcSubCell(celli, f3); + } + } + + if (mag(f1 - f2) < 10*SMALL) + { + return cutCell_.calcSubCell(celli, f1); + } + + if (mag(a1 - a2) < tol) + { + return cutCell_.calcSubCell(celli, 0.5*(f1 + f2)); + } + // Now we know that a(f) = alpha1 is to be found on the f interval + + + // Finding coefficients in 3 deg polynomial alpha(f) from 4 solutions + // Finding 2 additional points on 3 deg polynomial + f3 = f1 + (f2 - f1)/3; + cutCell_.calcSubCell(celli, f3); + a3 = cutCell_.VolumeOfFluid(); + + scalar f4 = f1 + 2*(f2 - f1)/3; + cutCell_.calcSubCell(celli, f4); + scalar a4 = cutCell_.VolumeOfFluid(); + + // Building and solving Vandermonde matrix equation + scalarField a(4), f(4), C(4), fOld(4); + { + a[0] = a1, a[1] = a3, a[2] = a4, a[3] = a2; + fOld[0] = f1, fOld[1] = f3, fOld[2] = f4, fOld[3] = f2; + f[0] = 0, f[1] = (f3-f1)/(f2-f1), f[2] = (f4-f1)/(f2-f1), f[3] = 1; + scalarSquareMatrix M(4); + forAll(f, i) + { + forAll(f, j) + { + M[i][j] = pow(f[i], 3 - j); + } + } + // C holds the 4 polynomial coefficients + C = a; + LUsolve(M, C); + } + + // Finding root with Newton method + + f3 = f[1]; a3 = a[1]; + label nIter = 0; + scalar res = mag(a3 - alpha1); + while (res > tol && nIter < 10*maxIter) + { + f3 -= (C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3] - alpha1) + /(3*C[0]*sqr(f3) + 2*C[1]*f3 + C[2]); + a3 = C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3]; + res = mag(a3 - alpha1); + nIter++; + } + // Scaling back to original range + f3 = f3*(f2 - f1) + f1; + + //Check result + label status = cutCell_.calcSubCell(celli, f3); + const scalar VOF = cutCell_.VolumeOfFluid(); + res = mag(VOF - alpha1); + + if (res > tol) + { + } + else + { + return status; + } + + // If tolerance not met use the secant method with f3 as a hopefully very + // good initial guess to crank res the last piece down below tol + + scalar x2 = f3; + scalar g2 = VOF - alpha1; + scalar x1 = max(1e-3*(f2 - f1), 100*SMALL); + x1 = max(x1, f1); + x1 = min(x1, f2); + cutCell_.calcSubCell(celli, x1); + scalar g1 = cutCell_.VolumeOfFluid() - alpha1; + + nIter = 0; + scalar g0(0), x0(0); + while (res > tol && nIter < maxIter && g1 != g2) + { + x0 = (x2*g1 - x1*g2)/(g1 - g2); + status = cutCell_.calcSubCell(celli, x0); + g0 = cutCell_.VolumeOfFluid() - alpha1; + res = mag(g0); + x2 = x1; g2 = g1; + x1 = x0; g1 = g0; + nIter++; + } + + return status; +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorIso.H b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorIso.H new file mode 100644 index 0000000000000000000000000000000000000000..50d9696db9e2ef2cbc1ec43ba47a1a05c58f1ea9 --- /dev/null +++ b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorIso.H @@ -0,0 +1,178 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceIteratorIso + +Description + Finds the isovalue that matches the volume fraction + + Reference: + \verbatim + Roenby, J., Bredmose, H. and Jasak, H. (2016). + A computational method for sharp interface advection + Royal Society Open Science, 3 + doi 10.1098/rsos.160405 + \endverbatim + +Author + Johan Roenby, DHI, all rights reserved. + +SourceFiles + surfaceIteratorIso.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfaceIteratorIso_H +#define surfaceIteratorIso_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "cutCellIso.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class surfaceIteratorIso Declaration +\*---------------------------------------------------------------------------*/ + +class surfaceIteratorIso +{ + // Private Data + + //- Mesh whose cells and faces to cut at their intersection with an + //- isosurface. + const fvMesh& mesh_; + + //- Reference to the point values + scalarField& ap_; + + //- Cuts the cell and returns volume centre and normal + cutCellIso cutCell_; + + //- Tolerance for marking of surface cells: + // Those with surfCellTol_ < alpha1 < 1 - surfCellTol_ + scalar surfCellTol_; + + +public: + + // Constructors + + //- Construct from fvMesh and a scalarField + // The scalarField size should equal the number of mesh points + surfaceIteratorIso + ( + const fvMesh& mesh, + scalarField& pointVal, + const scalar tol + ); + + + // Member Functions + + //- Determine if a cell is a surface cell + bool isASurfaceCell(const scalar alpha1) const + { + return + ( + surfCellTol_ < alpha1 + && alpha1 < 1 - surfCellTol_ + ); + } + + //- finds matching isoValue for the given value fraction + //- returns the cellStatus + label vofCutCell + ( + const label celli, + const scalar alpha1, + const scalar tol, + const label maxIter + ); + + //- The centre point of cutted volume + const point& subCellCentre() const + { + return cutCell_.subCellCentre(); + } + + //- The volume of cutted volume + scalar subCellVolume() const + { + return cutCell_.subCellVolume(); + } + + //- The centre of cutting isosurface + const point& surfaceCentre() const + { + return cutCell_.faceCentre(); + } + + //- The area vector of cutting isosurface + const vector& surfaceArea() const + { + return cutCell_.faceArea(); + } + + //- Volume of Fluid for cellI (subCellVolume_/mesh_.V()[cellI]) + scalar VolumeOfFluid() const + { + return cutCell_.VolumeOfFluid(); + } + + //- The cutValue + scalar cutValue() const + { + return cutCell_.cutValue(); + } + + //- The cellStatus + label cellStatus() + { + return cutCell_.cellStatus(); + } + + //- The points of the cutting isosurface in sorted order + const DynamicList<point>& facePoints() + { + return cutCell_.facePoints(); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorPLIC.C b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorPLIC.C new file mode 100644 index 0000000000000000000000000000000000000000..7882a449a5d8d425cb5373e306b2e0740a10d914 --- /dev/null +++ b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorPLIC.C @@ -0,0 +1,217 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +\*---------------------------------------------------------------------------*/ + +#include "surfaceIteratorPLIC.H" +#include "scalarMatrices.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::surfaceIteratorPLIC::surfaceIteratorPLIC +( + const fvMesh& mesh, + const scalar tol +) +: + mesh_(mesh), + cutCell_(mesh_), + surfCellTol_(tol) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +Foam::label Foam::surfaceIteratorPLIC::vofCutCell +( + const label celli, + const scalar alpha1, + const scalar tol, + const label maxIter, + vector normal +) +{ + if (mag(normal) == 0) + { + WarningInFunction + << "normal length is zero in cell: " << celli << nl + << "try increasing nCorrectors" << endl; + + return sign(alpha1-0.5); + } + + normal.normalise(); + + // Finding cell vertex extrema values + const labelList& pLabels = mesh_.cellPoints(celli); + scalarField fvert(pLabels.size()); + forAll(pLabels, pi) + { + fvert[pi] = (mesh_.points()[pLabels[pi]] - mesh_.C()[celli]) & (normal); + } + + const labelList order(Foam::sortedOrder(fvert)); + scalar f1 = fvert[order.first()]; + scalar f2 = fvert[order.last()]; + + + //Handling special case where method is handed an almost full or empty cell + if (alpha1 < tol) + { + return -1; + } + else if (1 - alpha1 < tol) + { + return 1; + } + + // Finding the two vertices inbetween which the isovalue giving alpha1 lies + label L1 = 0; + label L2 = fvert.size() - 1; + scalar a1 = 1; + scalar a2 = 0; + scalar L3, f3, a3; + + while (L2 - L1 > 1) + { + L3 = round(0.5*(L1 + L2)); + f3 = fvert[order[L3]]; + cutCell_.calcSubCell(celli, f3, normal); + a3 = cutCell_.VolumeOfFluid(); + if (a3 > alpha1) + { + L1 = L3; f1 = f3; a1 = a3; + } + else if (a3 < alpha1) + { + L2 = L3; f2 = f3; a2 = a3; + } + else + { + return cutCell_.calcSubCell(celli, f3, normal); + } + } + + if (mag(f1 - f2) < 10*SMALL) + { + return cutCell_.calcSubCell(celli, f1, normal); + } + + if (mag(a1 - a2) < tol) + { + return cutCell_.calcSubCell(celli, 0.5*(f1 + f2), normal); + } + // Now we know that a(f) = alpha1 is to be found on the f interval + // [f1, f2], i.e. alpha1 will be in the interval [a2,a1] + + + // Finding coefficients in 3 deg polynomial alpha(f) from 4 solutions + + // Finding 2 additional points on 3 deg polynomial + f3 = f1 + (f2 - f1)/3; + cutCell_.calcSubCell(celli, f3, normal); + a3 = cutCell_.VolumeOfFluid(); + + scalar f4 = f1 + 2*(f2 - f1)/3; + cutCell_.calcSubCell(celli, f4, normal); + scalar a4 = cutCell_.VolumeOfFluid(); + + // Building and solving Vandermonde matrix equation + scalarField a(4), f(4), C(4), fOld(4); + { + a[0] = a1, a[1] = a3, a[2] = a4, a[3] = a2; + fOld[0] = f1, fOld[1] = f3, fOld[2] = f4, fOld[3] = f2; + f[0] = 0, f[1] = (f3-f1)/(f2-f1), f[2] = (f4-f1)/(f2-f1), f[3] = 1; + scalarSquareMatrix M(4); + forAll(f, i) + { + forAll(f, j) + { + M[i][j] = pow(f[i], 3 - j); + } + } + // C holds the 4 polynomial coefficients + C = a; + LUsolve(M, C); + } + + // Finding root with Newton method + + f3 = f[1]; a3 = a[1]; + label nIter = 0; + scalar res = mag(a3 - alpha1); + while (res > tol && nIter < 10*maxIter) + { + f3 -= (C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3] - alpha1) + /(3*C[0]*sqr(f3) + 2*C[1]*f3 + C[2]); + a3 = C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3]; + res = mag(a3 - alpha1); + nIter++; + } + // Scaling back to original range + f3 = f3*(f2 - f1) + f1; + + //Check result + label status = cutCell_.calcSubCell(celli, f3, normal); + const scalar VOF = cutCell_.VolumeOfFluid(); + res = mag(VOF - alpha1); + + if (res > tol) + { + } + else + { + return status; + } + + // If tolerance not met use the secant method with f3 as a hopefully very + // good initial guess to crank res the last piece down below tol + + scalar x2 = f3; + scalar g2 = VOF - alpha1; + scalar x1 = max(1e-3*(f2 - f1), 100*SMALL); + x1 = max(x1, f1); + x1 = min(x1, f2); + cutCell_.calcSubCell(celli, x1,normal); + scalar g1 = cutCell_.VolumeOfFluid() - alpha1; + + nIter = 0; + scalar g0(0), x0(0); + while (res > tol && nIter < maxIter && g1 != g2) + { + x0 = (x2*g1 - x1*g2)/(g1 - g2); + status = cutCell_.calcSubCell(celli, x0, normal); + g0 = cutCell_.VolumeOfFluid() - alpha1; + res = mag(g0); + x2 = x1; g2 = g1; + x1 = x0; g1 = g0; + nIter++; + } + + return status; +} + + +// ************************************************************************* // diff --git a/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorPLIC.H b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorPLIC.H new file mode 100644 index 0000000000000000000000000000000000000000..c18ec3691e0c256e28f7845a5fe91069f9f8b759 --- /dev/null +++ b/src/transportModels/geometricVoF/surfaceIterators/surfaceIteratorPLIC.H @@ -0,0 +1,173 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019-2020 DLR +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::surfaceIteratorPLIC + +Description + Finds the cutValue that matches the volume fraction + + Reference: + \verbatim + Henning Scheufler, Johan Roenby, + Accurate and efficient surface reconstruction from volume + fraction data on general meshes, + Journal of Computational Physics, 2019, + doi 10.1016/j.jcp.2019.01.009 + \endverbatim + +Author + Johan Roenby, DHI, all rights reserved. + Modified Henning Scheufler, DLR + +SourceFiles + surfaceIteratorPLIC.C + +\*---------------------------------------------------------------------------*/ + +#ifndef surfaceIteratorPLIC_H +#define surfaceIteratorPLIC_H + +#include "fvMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "cutCellPLIC.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class surfaceIteratorPLIC Declaration +\*---------------------------------------------------------------------------*/ + +class surfaceIteratorPLIC +{ + // Private Data + + //- Mesh whose cells and faces to cut at their intersection with an + //- isosurface. + const fvMesh& mesh_; + + //- Cuts the cell and returns volume centre and normal + cutCellPLIC cutCell_; + + //- Tolerance for marking of surface cells: + // Those with surfCellTol_ < alpha1 < 1 - surfCellTol_ + scalar surfCellTol_; + + +public: + + // Constructors + + //- Construct from fvMesh and a scalarField + // Length of scalarField should equal number of mesh points + surfaceIteratorPLIC(const fvMesh& mesh, const scalar tol); + + + // Member Functions + + //- Determine if a cell is a surface cell + bool isASurfaceCell(const scalar alpha1) const + { + return + ( + surfCellTol_ < alpha1 + && alpha1 < 1 - surfCellTol_ + ); + } + + //- Finds matching cutValue for the given value fraction + // \return the cellStatus + label vofCutCell + ( + const label celli, + const scalar alpha1, + const scalar tol, + const label maxIter, + vector normal + ); + + //- The centre point of cutted volume + const point& subCellCentre() const + { + return cutCell_.subCellCentre(); + } + + //- The volume of cutted volume + scalar subCellVolume() const + { + return cutCell_.subCellVolume(); + } + + //- The centre of cutting isosurface + const point& surfaceCentre() const + { + return cutCell_.faceCentre(); + } + + //- The area vector of cutting isosurface + const vector& surfaceArea() const + { + return cutCell_.faceArea(); + } + + //- Volume of Fluid for cellI (subCellVolume_/mesh_.V()[cellI]) + scalar VolumeOfFluid() const + { + return cutCell_.VolumeOfFluid(); + } + + //- The cutValue + scalar cutValue() const + { + return cutCell_.cutValue(); + } + + //- The cellStatus + label cellStatus() + { + return cutCell_.cellStatus(); + } + + //- The points of the cutting isosurface in sorted order + const DynamicList<point>& facePoints() + { + return cutCell_.facePoints(); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/T b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/T new file mode 100644 index 0000000000000000000000000000000000000000..75a7ea9f69f56b51c745bf2a44094f78ded5f17e --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/T @@ -0,0 +1,37 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + wall + { + type zeroGradient; + } + + atmosphere + { + type inletOutlet; + inletValue $internalField; + } + + #includeEtc "caseDicts/setConstraintTypes" +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/U b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/U new file mode 100644 index 0000000000000000000000000000000000000000..93ad57faf604bddb3b802d375d2f76fbddf7ad84 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/U @@ -0,0 +1,47 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + rod + { + type rotatingWallVelocity; + axis (0 1 0); + origin (0 0 0); + omega constant #eval{ 2.1 * (2*pi()) }; // rev/s -> rads/s + value uniform (0 0 0); + } + vessel + { + type noSlip; + } + + atmosphere + { + type pressureInletOutletVelocity; + value $internalField; + } + + #includeEtc "caseDicts/setConstraintTypes" +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/alpha.liquid b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/alpha.liquid new file mode 100644 index 0000000000000000000000000000000000000000..54eaef30cdaa0cd17ef0a57e34610c12dce27d03 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/alpha.liquid @@ -0,0 +1,37 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object alpha.liquid; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + wall + { + type zeroGradient; + } + + atmosphere + { + type inletOutlet; + inletValue $internalField; + } + + #includeEtc "caseDicts/setConstraintTypes" +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/p b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/p new file mode 100644 index 0000000000000000000000000000000000000000..eeaa36ccf5f22c4040e1fd93fc5046972c7fb02e --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/p @@ -0,0 +1,38 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + wall + { + type calculated; + value $internalField; + } + + atmosphere + { + type calculated; + value $internalField; + } + + #includeEtc "caseDicts/setConstraintTypes" +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/p_rgh b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/p_rgh new file mode 100644 index 0000000000000000000000000000000000000000..f69d181a92b4712fedc910a17200593b5aa09d2d --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/p_rgh @@ -0,0 +1,38 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p_rgh; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + wall + { + type fixedFluxPressure; + value $internalField; + } + + atmosphere + { + type totalPressure; + p0 $internalField; + } + + #includeEtc "caseDicts/setConstraintTypes" +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/sigma.liquid b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/sigma.liquid new file mode 100644 index 0000000000000000000000000000000000000000..0b666ff4fae7bdf5289aa3c7aff1b299273069d4 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/0.orig/sigma.liquid @@ -0,0 +1,38 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volSymmTensorField; + object sigma.liquid; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform (0 0 0 0 0 0); + +boundaryField +{ + wall + { + type zeroGradient; + } + + atmosphere + { + type inletOutlet; + inletValue $internalField; + } + + #includeEtc "caseDicts/setConstraintTypes" +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/Allclean b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..fb1f3847301c377e02e12439ba58cbf303af3ef9 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/Allclean @@ -0,0 +1,8 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions +#------------------------------------------------------------------------------ + +cleanCase0 + +#------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/Allrun b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..316fb4d9fb2c421202cf3cc9aa27bb73099139c1 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/Allrun @@ -0,0 +1,14 @@ +#!/bin/sh +cd "${0%/*}" || exit # Run from this directory +. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions +#------------------------------------------------------------------------------ + +runApplication blockMesh +runApplication extrudeMesh + +restore0Dir + +runApplication setFields +runApplication $(getApplication) + +#------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/README b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/README new file mode 100644 index 0000000000000000000000000000000000000000..7d86d1f62fe4c5ac131e80e6fd62fb0442b632f1 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/README @@ -0,0 +1,41 @@ +Reference: + + Figueiredo, R. A., Oishi, C. M., Afonso, A. M., Tasso, I. V. M., & + Cuminato, J. A. (2016). + A two-phase solver for complex fluids: Studies of the Weissenberg effect. + International Journal of Multiphase Flow, 84, 98-115. + +In compressibleInterFoam with turbulenceProperties simulationType set to +twoPhaseTransport separate stress models (laminar, non-Newtonian, LES or RAS) +are instantiated for each of the two phases allowing for different modeling for +the phases. + +This example case uses: +- phases "air" and "liquid" +- air phase + - constant/turbulenceProperties.air: + - stress model set to laminar, Newtonian + - constant/thermophysicalProperties.air: + - transport set to const (Newtonian) + - mu (dynamic viscoity) = 1.84e-5 +- liquid phase + - constant/turbulenceProperties.liquid: + - stress model set to laminar, Maxwell non-Newtonian + - nuM (kinematic viscosity) = 0.01476 + - lambda = 0.018225 + - constant/thermophysicalProperties.liquid + - transport set to const (Newtonian) + - mu (dynamic viscoity) = 1.46 + +Liquid phase properties were calculated from the relations given in the paper: +- rho = 890 kg/m^3 +- mu = mu_{s} + mu_{p} = 146 poise = 14.6 Pa.s + s = solvent (Newtonian), p = polymer (Maxwell) +- mu_{s}/mu_{p} = 1/9 + +=> mu_{s} = 14.6/10 = 1.46 Pa.s +=> nu_{p} = nuM = (9/10)*14.6/890 = 0.01476 m^2/s + +compressibleInterFoam solves the energy equation, despite not being needed in +this example. The case is simply initialised at a uniform temperature of 300K +throughout the domain and at the atmosphere boundary. diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/fvOptions b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/fvOptions new file mode 100644 index 0000000000000000000000000000000000000000..9079bfed7a2b64fb8b4181155769ef191ac96add --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/fvOptions @@ -0,0 +1,28 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object fvOptions; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +stabilization +{ + type symmTensorPhaseLimitStabilization; + + field sigma.liquid; + rate rLambda.liquid; + residualAlpha 1e-3; +} + + +//************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/g b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/g new file mode 100644 index 0000000000000000000000000000000000000000..79b4fc3b5f23799fb44f6f3e83a2f8a5ca49da39 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/g @@ -0,0 +1,22 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; +value (0 -9.81 0); + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties new file mode 100644 index 0000000000000000000000000000000000000000..43d9ef28ace6559e73a5c74d1413c731558ab52f --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties @@ -0,0 +1,24 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +phases (liquid air); + +pMin 10000; + +sigma 0.0309; + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties.air b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties.air new file mode 100644 index 0000000000000000000000000000000000000000..2afc5fe91f5b6e4747857970ce861f7f7850b275 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties.air @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState rhoConst; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 28.9; + } + equationOfState + { + rho 1.2; + } + thermodynamics + { + Cp 1007; + Hf 0; + } + transport + { + mu 1.84e-05; + Pr 0.7; + } +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties.liquid b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties.liquid new file mode 100644 index 0000000000000000000000000000000000000000..3b5a74c3a7ddbe36a539316f9ede2ced40936e0d --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/thermophysicalProperties.liquid @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState rhoConst; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 18.0; + } + equationOfState + { + rho 890; + } + thermodynamics + { + Cp 4195; + Hf 0; + } + transport + { + mu 1.46; + Pr 2.289; + } +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..d9855126fa222f100a24e0f539a0f64b5ba9270c --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType twoPhaseTransport; + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties.air b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties.air new file mode 100644 index 0000000000000000000000000000000000000000..fbd1e3c277c13766d96341f6214f8c833ed4b691 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties.air @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties.liquid b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties.liquid new file mode 100644 index 0000000000000000000000000000000000000000..623d9231297ef6955b6bb506a07e866338416e76 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/constant/turbulenceProperties.liquid @@ -0,0 +1,29 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + +laminar +{ + laminarModel Maxwell; + + nuM 0.01476; + lambda 0.018225; +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/blockMeshDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..9170c10a1a09e7a75768275760880ea7e8d9daad --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/blockMeshDict @@ -0,0 +1,114 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 0.001; + +// H 77; +R 6.35; +Rc 152.25; +hTotal 110; + +rCells 80; +hCells 80; + +rGrading +( + (0.1 1 1) + (0.9 2.25 10) +); + +hGrading +( + (0.65 2 0.1) + (0.2 2.4 1) + (0.15 1.2 2) +); + +vertices +( + ($R 0 -1) + ($Rc 0 -1) + ($R $hTotal -1) + ($Rc $hTotal -1) + + ($R 0 0) + ($Rc 0 0) + ($R $hTotal 0) + ($Rc $hTotal 0) + +); + +blocks +( + hex (0 1 3 2 4 5 7 6) + ($rCells $hCells 1) + simpleGrading ($rGrading $hGrading 1) +); + +edges +( +); + +boundary +( + rod + { + type wall; + faces + ( + (0 2 6 4) + ); + } + vessel + { + type wall; + faces + ( + (1 3 7 5) + (0 1 5 4) + ); + } + atmosphere + { + type patch; + faces + ( + (2 3 7 6) + ); + } + back + { + type symmetry; + faces + ( + (0 2 3 1) + ); + } + front + { + type symmetry; + faces + ( + (4 5 7 6) + ); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/controlDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..13e28dcda7361be6a86ae556ca3084ebf214a83a --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/controlDict @@ -0,0 +1,56 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application compressibleInterIsoFoam; + +startFrom latestTime; + +startTime 0; + +stopAt endTime; + +endTime 25; + +deltaT 1e-3; + +writeControl adjustableRunTime; + +writeInterval 0.5; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 10; + +writeCompression off; + +timeFormat general; + +timePrecision 6; + +runTimeModifiable yes; + +adjustTimeStep yes; + +maxCo 1; +maxAlphaCo 1; + +maxDeltaT 1; + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/extrudeMeshDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/extrudeMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..ac346f35922b15803f4238e7f18eebeb58cdd477 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/extrudeMeshDict @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object extrudeMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +constructFrom patch; +sourceCase "$FOAM_CASE"; + +sourcePatches (front); +exposedPatchName back; + +extrudeModel wedge; + +sectorCoeffs //<- Also used for wedge +{ + point (0 0 0); + axis (0 -1 0); + angle 1; +} + +flipNormals false; + +mergeFaces false; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/fvSchemes b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..c19fc1c86bd1bcd926b55e95719b31ebb4c3f794 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/fvSchemes @@ -0,0 +1,67 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; +} + +divSchemes +{ + div(rhoPhi,U) Gauss linearUpwindV grad(U); + div(rhoPhi,T) Gauss linearUpwind grad(T); + div(phi,thermo:rho.liquid) Gauss linear; + div(phi,thermo:rho.air) Gauss linear; + + div(phi,alpha) Gauss vanLeer; + div(phirb,alpha) Gauss linear; + + div(phi,p) Gauss upwind; + div(rhoPhi,K) Gauss upwind; + + div(alphaRhoPhi.liquid,sigma.liquid) Gauss upwind; + + div(((alpha.liquid*thermo:rho.liquid)*sigma.liquid)) Gauss linear; + div((((alpha.liquid*thermo:rho.liquid)*nuM)*grad(U))) Gauss linear; + div((((alpha.liquid*thermo:rho.liquid)*(thermo:mu.liquid|thermo:rho.liquid))*dev2(T(grad(U))))) Gauss linear; + + div((((alpha.air*thermo:rho.air)*nuEff.air)*dev2(T(grad(U))))) Gauss linear; + div((((alpha.liquid*thermo:rho.liquid)*nuEff.liquid)*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/fvSolution b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..196ab714ebea769a31ad59988c2a86bd23ee3c87 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/fvSolution @@ -0,0 +1,90 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + "alpha.liquid.*" + { + nAlphaCorr 2; + nAlphaSubCycles 1; + cAlpha 1; + + reconstructionScheme isoAlpha; + isoFaceTol 1e-8; + surfCellTol 1e-8; + nAlphaBounds 3; + snapTol 1e-12; + clip true; + } + + "pcorr.*" + { + solver PCG; + preconditioner DIC; + tolerance 1e-5; + relTol 0; + } + + p_rgh + { + solver PCG; + preconditioner DIC; + tolerance 1e-9; + relTol 0.05; + } + + p_rghFinal + { + $p_rgh; + relTol 0; + } + + "U.*" + { + solver PBiCGStab; + preconditioner DILU; + tolerance 1e-6; + relTol 0; + } + + "(T|k|B|nuTilda|sigma).*" + { + solver PBiCGStab; + preconditioner DILU; + tolerance 1e-8; + relTol 0; + } +} + +PIMPLE +{ + momentumPredictor no; + nOuterCorrectors 1; + nCorrectors 2; + nNonOrthogonalCorrectors 0; +} + +relaxationFactors +{ + equations + { + ".*" 1; + } +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/setFieldsDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/setFieldsDict new file mode 100644 index 0000000000000000000000000000000000000000..1f992101fdd9e9ebe1a05bb3972e58f095ec41be --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/climbingRod/system/setFieldsDict @@ -0,0 +1,36 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object setFieldsDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +defaultFieldValues +( + volScalarFieldValue alpha.liquid 0 +); + +regions +( + boxToCell + { + box (0 0 -1) (1 0.0771 1); + fieldValues + ( + volScalarFieldValue alpha.liquid 1 + ); + } +); + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/T b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/T new file mode 100644 index 0000000000000000000000000000000000000000..21b16adb6a273c08f5358893fcf39591dd9a2f21 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/T @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + walls + { + type zeroGradient; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/U b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/U new file mode 100644 index 0000000000000000000000000000000000000000..00c303e2562e3c3237bfbd1ec92d462d00037d9f --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/U @@ -0,0 +1,33 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + walls + { + type noSlip; + } + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/alpha.water b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/alpha.water new file mode 100644 index 0000000000000000000000000000000000000000..fa7e6861d029e4d41f0ecac1ce9c17965d9084ca --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/alpha.water @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object alpha.water; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + walls + { + type zeroGradient; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/p b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/p new file mode 100644 index 0000000000000000000000000000000000000000..a7ee2ed31c529e5aed5aac42a37ce89dbf219f08 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/p @@ -0,0 +1,35 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + walls + { + type calculated; + value uniform 1e5; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/p_rgh b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/p_rgh new file mode 100644 index 0000000000000000000000000000000000000000..d332d26e556b288be6a159aaaa5323accb9e1fd8 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/0.orig/p_rgh @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p_rgh; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + walls + { + type fixedFluxPressure; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/Allclean b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..188f107b0e907b47bebd868d842a1853f587802a --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/Allclean @@ -0,0 +1,8 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory +. $WM_PROJECT_DIR/bin/tools/CleanFunctions # Tutorial clean functions + +cleanCase0 +rm -r sequencedVTK + +#------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/Allrun b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..98b1a954b1962b7c9b8b87946d83b23f1ccaf5cb --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/Allrun @@ -0,0 +1,12 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory +. $WM_PROJECT_DIR/bin/tools/RunFunctions # Tutorial run functions + +runApplication blockMesh +restore0Dir +runApplication setFields +runApplication setAlphaField +runApplication $(getApplication) +foamSequenceVTKFiles -vtp + +#------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/g b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/g new file mode 100644 index 0000000000000000000000000000000000000000..79b4fc3b5f23799fb44f6f3e83a2f8a5ca49da39 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/g @@ -0,0 +1,22 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; +value (0 -9.81 0); + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties new file mode 100644 index 0000000000000000000000000000000000000000..48fa89f53b49a4438dc67c8bc6018ebd92d741ab --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties @@ -0,0 +1,28 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +phases (water air); + +pMin 10000; + +sigma +{ + type constant; + sigma 0.07; +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties.air b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties.air new file mode 100644 index 0000000000000000000000000000000000000000..5c77a504431c915a7a4e441b5a9a1dcbcde4da2c --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties.air @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState perfectGas; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 28.9; + } + thermodynamics + { + Cp 1007; + Hf 0; + } + transport + { + mu 1.84e-05; + Pr 0.7; + } +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties.water b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties.water new file mode 100644 index 0000000000000000000000000000000000000000..50a924c51306411f5da14767e0db17c397f8cba8 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/thermophysicalProperties.water @@ -0,0 +1,69 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +/* +thermoType +{ + type heRhoThermo; + mixture pureMixture; + properties liquid; + energy sensibleInternalEnergy; +} + +mixture +{ + H2O; +} +*/ + + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState perfectFluid; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 18.0; + } + equationOfState + { + R 3000; + rho0 1027; + } + thermodynamics + { + Cp 4195; + Hf 0; + } + transport + { + mu 3.645e-4; + Pr 2.289; + } +} + + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/turbulenceProperties b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..fbd1e3c277c13766d96341f6214f8c833ed4b691 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/blockMeshDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..4c996b626091aa5adc8fc3c6aff6221e583aa77b --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/blockMeshDict @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 1; + +vertices +( + (0 0 -0.1) + (1 0 -0.1) + (1 2 -0.1) + (0 2 -0.1) + (0 0 0.1) + (1 0 0.1) + (1 2 0.1) + (0 2 0.1) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (80 160 1) simpleGrading (1 1 1) +); + +patches +( + wall walls + ( + (3 7 6 2) + (0 4 7 3) + (2 6 5 1) + (1 5 4 0) + ) + empty frontAndBack + ( + (0 3 2 1) + (4 5 6 7) + ) +); + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/controlDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..a346c2ef7637ef36aac9b89d7575e57ad905b41e --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/controlDict @@ -0,0 +1,78 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application compressibleInterIsoFoam; + +startFrom startTime; + +startTime 0; + +stopAt endTime; + +endTime 0.5; + +deltaT 0.0001; + +writeControl adjustableRunTime; + +writeInterval 0.01; + +purgeWrite 0; + +writeFormat binary; + +writePrecision 8; + +writeCompression off; + +timeFormat general; + +timePrecision 10; + +runTimeModifiable yes; + +adjustTimeStep yes; + +maxCo 0.5; +maxAlphaCo 0.5; +maxDeltaT 1; + +functions +{ + surfaces + { + type surfaces; + libs ("libsampling.so"); + writeControl writeTime; + + surfaceFormat vtp; + fields (p U); + + interpolationScheme cell; + + surfaces + { + freeSurf + { + type interface; + interpolate false; + } + } + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/fvSchemes b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..60587bab5bdbec6ff3d098ba45c93b7f1eabcfa0 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/fvSchemes @@ -0,0 +1,59 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; +} + +divSchemes +{ + div(phi,alpha) Gauss vanLeer; + div(phirb,alpha) Gauss linear; + div(phi,thermo:rho.water) Gauss upwind; + div(phi,thermo:rho.air) Gauss upwind; + + div(rhoPhi,U) Gauss upwind; + div(rhoPhi,T) Gauss upwind; + div(rhoPhi,K) Gauss upwind; + div(phi,p) Gauss upwind; + div(phi,k) Gauss upwind; + + div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear uncorrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default uncorrected; +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/fvSolution b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..377a54e4dbb29d75a943c56c162818f98d6ce872 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/fvSolution @@ -0,0 +1,107 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + "alpha.water.*" + { + nAlphaCorr 1; + nAlphaSubCycles 2; + cAlpha 1; + + reconstructionScheme gradAlpha; + isoFaceTol 1e-8; + surfCellTol 1e-6; + nAlphaBounds 3; + snapTol 1e-12; + clip true; + } + + ".*(rho|rhoFinal)" + { + solver diagonal; + } + + "pcorr.*" + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-05; + relTol 0; + smoother DICGaussSeidel; + } + tolerance 1e-05; + relTol 0; + maxIter 100; + } + + p_rgh + { + solver GAMG; + tolerance 1e-07; + relTol 0.01; + smoother DIC; + } + + p_rghFinal + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-07; + relTol 0; + nVcycles 2; + smoother DICGaussSeidel; + nPreSweeps 2; + } + tolerance 1e-07; + relTol 0; + maxIter 20; + } + + U + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-06; + relTol 0; + nSweeps 1; + } + + "(T|k|B|nuTilda).*" + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-08; + relTol 0; + } +} + +PIMPLE +{ + momentumPredictor no; + transonic no; + nOuterCorrectors 1; + nCorrectors 2; + nNonOrthogonalCorrectors 0; +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/setAlphaFieldDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/setAlphaFieldDict new file mode 100644 index 0000000000000000000000000000000000000000..f1fc08c099ac7c04c1f6547b5b1b30a5e67370c0 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/setAlphaFieldDict @@ -0,0 +1,40 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object setFieldsDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +field alpha.water; +type composedFunction; +mode subtract; +composedFunction +{ + plane + { + type plane; + origin (0 1. 0); + normal (0 -1 0); + } + + sphere + { + type cylinder; + radius 0.1; + origin (0.5 0.5 0); + direction (0 0 1); + scale -1; + } + +} +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/setFieldsDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/setFieldsDict new file mode 100644 index 0000000000000000000000000000000000000000..1e1e4de2615e5477e70a5641fbeaa51be1a9acfa --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge2D/system/setFieldsDict @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object setFieldsDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +defaultFieldValues +( +// volScalarFieldValue alpha.water 1 + volScalarFieldValue p_rgh 1e5 + volScalarFieldValue p 1e5 + volScalarFieldValue T 300 +); + +regions +( + sphereToCell + { + origin (0.5 0.5 0); + radius 0.1; + + fieldValues + ( + //volScalarFieldValue alpha.water 0 + volScalarFieldValue p_rgh 1e6 + volScalarFieldValue p 1e6 + volScalarFieldValue T 578 + ); + } + /* boxToCell + { + box (-10 1 -1) (10 10 1); + fieldValues + ( + volScalarFieldValue alpha.water 0 + ); + }*/ +); + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/T b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/T new file mode 100644 index 0000000000000000000000000000000000000000..21b16adb6a273c08f5358893fcf39591dd9a2f21 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/T @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + walls + { + type zeroGradient; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/U b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/U new file mode 100644 index 0000000000000000000000000000000000000000..00c303e2562e3c3237bfbd1ec92d462d00037d9f --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/U @@ -0,0 +1,33 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + walls + { + type noSlip; + } + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/alpha.water b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/alpha.water new file mode 100644 index 0000000000000000000000000000000000000000..fa7e6861d029e4d41f0ecac1ce9c17965d9084ca --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/alpha.water @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object alpha.water; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 0 0 0 0]; + +internalField uniform 0; + +boundaryField +{ + walls + { + type zeroGradient; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/p b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/p new file mode 100644 index 0000000000000000000000000000000000000000..a7ee2ed31c529e5aed5aac42a37ce89dbf219f08 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/p @@ -0,0 +1,35 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + walls + { + type calculated; + value uniform 1e5; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/p_rgh b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/p_rgh new file mode 100644 index 0000000000000000000000000000000000000000..c7db9671d503f9abd5bf8efddca9d8d1926f9a1d --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/0.orig/p_rgh @@ -0,0 +1,35 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p_rgh; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 1e5; + +boundaryField +{ + walls + { + type fixedFluxPressure; + value uniform 1e5; + } + + defaultFaces + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/Allclean b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/Allclean new file mode 100755 index 0000000000000000000000000000000000000000..3b8c6e8e2fb2b80437330845ebe5002ef787f4b3 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/Allclean @@ -0,0 +1,8 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory +. $WM_PROJECT_DIR/bin/tools/CleanFunctions # Tutorial clean functions + +cleanCase0 +rm -rf processor* + +#------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/Allrun b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/Allrun new file mode 100755 index 0000000000000000000000000000000000000000..bdb96428fab4a09fe5434006ac2651a46362525a --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/Allrun @@ -0,0 +1,12 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # Run from this directory +. $WM_PROJECT_DIR/bin/tools/RunFunctions # Tutorial run functions + +runApplication blockMesh +restore0Dir +runApplication setFields +runApplication decomposePar +runParallel $(getApplication) +runApplication reconstructPar + +#------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/g b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/g new file mode 100644 index 0000000000000000000000000000000000000000..79b4fc3b5f23799fb44f6f3e83a2f8a5ca49da39 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/g @@ -0,0 +1,22 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class uniformDimensionedVectorField; + location "constant"; + object g; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -2 0 0 0 0]; +value (0 -9.81 0); + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties new file mode 100644 index 0000000000000000000000000000000000000000..97199ca415d59d3326cd274950f23aead4eb3f8b --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties @@ -0,0 +1,24 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +phases (water air); + +pMin 10000; + +sigma 0.07; + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties.air b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties.air new file mode 100644 index 0000000000000000000000000000000000000000..5c77a504431c915a7a4e441b5a9a1dcbcde4da2c --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties.air @@ -0,0 +1,48 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState perfectGas; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 28.9; + } + thermodynamics + { + Cp 1007; + Hf 0; + } + transport + { + mu 1.84e-05; + Pr 0.7; + } +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties.water b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties.water new file mode 100644 index 0000000000000000000000000000000000000000..175e31bdf955911abef2b2ed520c1fe66b634412 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/thermophysicalProperties.water @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +thermoType +{ + type heRhoThermo; + mixture pureMixture; + transport const; + thermo hConst; + equationOfState perfectFluid; + specie specie; + energy sensibleInternalEnergy; +} + +mixture +{ + specie + { + molWeight 18.0; + } + equationOfState + { + R 3000; + rho0 1027; + } + thermodynamics + { + Cp 4195; + Hf 0; + } + transport + { + mu 3.645e-4; + Pr 2.289; + } +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/turbulenceProperties b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/turbulenceProperties new file mode 100644 index 0000000000000000000000000000000000000000..fbd1e3c277c13766d96341f6214f8c833ed4b691 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType laminar; + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/blockMeshDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/blockMeshDict new file mode 100644 index 0000000000000000000000000000000000000000..0a6ced00636e003bd82c8b8f215196ac3306aae1 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/blockMeshDict @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +scale 1; + +vertices +( + (0 0 0) + (1 0 0) + (1 2 0) + (0 2 0) + (0 0 1) + (1 0 1) + (1 2 1) + (0 2 1) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (80 160 80) simpleGrading (1 1 1) +); + +boundary +( + walls + { + type wall; + faces + ( + (3 7 6 2) + (0 4 7 3) + (2 6 5 1) + (1 5 4 0) + (0 3 2 1) + (4 5 6 7) + ); + } +); + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/controlDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/controlDict new file mode 100644 index 0000000000000000000000000000000000000000..7d517d7bf779edf2c39edfb68a28b9ae651b4f83 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/controlDict @@ -0,0 +1,57 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application compressibleInterIsoFoam; + +startFrom latestTime; + +startTime 0; + +stopAt endTime; + +endTime 0.5; + +deltaT 0.0001; + +writeControl adjustableRunTime; + +writeInterval 0.01; + +purgeWrite 0; + +writeFormat binary; + +writePrecision 8; + +writeCompression off; + +timeFormat general; + +timePrecision 10; + +runTimeModifiable yes; + +adjustTimeStep yes; + +maxCo 0.5; + +maxAlphaCo 0.5; + +maxDeltaT 1; + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/decomposeParDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/decomposeParDict new file mode 100644 index 0000000000000000000000000000000000000000..1a1deea863a53cf4d35811abec7dc81676da6774 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/decomposeParDict @@ -0,0 +1,26 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object decomposeParDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +numberOfSubdomains 4; + +method hierarchical; + +coeffs +{ + n (1 4 1); +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/fvSchemes b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/fvSchemes new file mode 100644 index 0000000000000000000000000000000000000000..281915333f391617b199d9398a8670ee4dab9bd9 --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/fvSchemes @@ -0,0 +1,59 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; +} + +divSchemes +{ + div(phi,alpha) Gauss vanLeer; + div(phirb,alpha) Gauss linear; + div(phi,thermo:rho.water) Gauss upwind; + div(phi,thermo:rho.air) Gauss upwind; + + div(rhoPhi,U) Gauss upwind; + div(rhoPhi,T) Gauss upwind; + div(rhoPhi,K) Gauss upwind; + div(phi,p) Gauss upwind; + div(phi,k) Gauss upwind; + + div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default Gauss linear uncorrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default uncorrected; +} + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/fvSolution b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/fvSolution new file mode 100644 index 0000000000000000000000000000000000000000..1890baebf39069786d3aac5c3fda980a9b96effe --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/fvSolution @@ -0,0 +1,107 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + "alpha.water.*" + { + nAlphaCorr 1; + nAlphaSubCycles 1; + cAlpha 1; + + reconstructionScheme isoAlpha; + vof2IsoTol 1e-8; + surfCellTol 1e-6; + nAlphaBounds 3; + snapTol 1e-12; + clip true; + } + + "pcorr.*" + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-05; + relTol 0; + smoother DICGaussSeidel; + } + tolerance 1e-05; + relTol 0; + maxIter 100; + } + + ".*(rho|rhoFinal)" + { + solver diagonal; + } + + p_rgh + { + solver GAMG; + tolerance 1e-10; + relTol 0.001; + smoother DIC; + } + + p_rghFinal + { + solver PCG; + preconditioner + { + preconditioner GAMG; + tolerance 1e-07; + relTol 0; + nVcycles 2; + smoother DICGaussSeidel; + nPreSweeps 2; + } + tolerance 1e-10; + relTol 0; + maxIter 50; + } + + UFinal + { + solver smoothSolver; + smoother GaussSeidel; + tolerance 1e-06; + relTol 0; + nSweeps 1; + } + + "(T|k|B|nuTilda).*" + { + solver smoothSolver; + smoother symGaussSeidel; + tolerance 1e-08; + relTol 0; + } +} + +PIMPLE +{ + momentumPredictor yes; + transonic no; + nOuterCorrectors 1; + nCorrectors 3; + nNonOrthogonalCorrectors 0; +} + + +// ************************************************************************* // diff --git a/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/setFieldsDict b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/setFieldsDict new file mode 100644 index 0000000000000000000000000000000000000000..3fa72d5343191bb524ecfb9be08e6dea28a989ed --- /dev/null +++ b/tutorials/multiphase/compressibleInterIsoFoam/laminar/depthCharge3D/system/setFieldsDict @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v2006 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object setFieldsDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +defaultFieldValues +( + volScalarFieldValue alpha.water 1 + volScalarFieldValue p_rgh 1e5 + volScalarFieldValue p 1e5 + volScalarFieldValue T 300 +); + +regions +( + sphereToCell + { + origin (0.5 0.5 0.5); + radius 0.1; + + fieldValues + ( + volScalarFieldValue alpha.water 0 + volScalarFieldValue p_rgh 1e6 + volScalarFieldValue p 1e6 + volScalarFieldValue T 578 + ); + } + boxToCell + { + box (-10 1 -1) (10 10 1); + fieldValues + ( + volScalarFieldValue alpha.water 0 + ); + } +); + + +// ************************************************************************* // diff --git a/tutorials/multiphase/interIsoFoam/damBreak/Allclean b/tutorials/multiphase/interIsoFoam/damBreak/Allclean index fb1f3847301c377e02e12439ba58cbf303af3ef9..02237030276d6ec77684aa5e1c1d323f7fd88991 100755 --- a/tutorials/multiphase/interIsoFoam/damBreak/Allclean +++ b/tutorials/multiphase/interIsoFoam/damBreak/Allclean @@ -5,4 +5,6 @@ cd "${0%/*}" || exit # Run from this directory cleanCase0 +rm -rf isoFaces sequencedVTK + #------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/interIsoFoam/damBreak/Allrun b/tutorials/multiphase/interIsoFoam/damBreak/Allrun index cc36822e88765b83d3e0074bffb6d56f150595d3..21b3ad0ed3e0c70c2c73a554dca7c94456baeace 100755 --- a/tutorials/multiphase/interIsoFoam/damBreak/Allrun +++ b/tutorials/multiphase/interIsoFoam/damBreak/Allrun @@ -10,5 +10,5 @@ runApplication blockMesh runApplication setFields runApplication $(getApplication) - +foamSequenceVTKFiles -vtp #------------------------------------------------------------------------------ diff --git a/tutorials/multiphase/interIsoFoam/damBreak/system/controlDict b/tutorials/multiphase/interIsoFoam/damBreak/system/controlDict index f777a69ecf022c0ff98de8f29332b479deda681a..58b788c0b82c685b1fbe6b20723134c1690c037f 100644 --- a/tutorials/multiphase/interIsoFoam/damBreak/system/controlDict +++ b/tutorials/multiphase/interIsoFoam/damBreak/system/controlDict @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -23,7 +23,7 @@ startTime 0; stopAt endTime; -endTime 2; +endTime 1; deltaT 0.001; @@ -54,4 +54,29 @@ maxAlphaCo 0.5; maxDeltaT 1; +functions +{ + surfaces + { + type surfaces; + libs ("libsampling.so"); + writeControl writeTime; + + surfaceFormat vtp; + fields (p U); + + interpolationScheme cell; + + surfaces + ( + freeSurf + { + type interface; + interpolate false; + } + + ); + } +} + // ************************************************************************* // diff --git a/tutorials/multiphase/interIsoFoam/damBreak/system/fvSolution b/tutorials/multiphase/interIsoFoam/damBreak/system/fvSolution index 6b2ebe597ef5e0a23677951ca118966cd9eb240d..9cab438115f041c4266b5ae5ec28a3cd394bbab2 100644 --- a/tutorials/multiphase/interIsoFoam/damBreak/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/damBreak/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -24,6 +24,7 @@ solvers nAlphaBounds 3; snapTol 1e-12; clip true; + reconstructionScheme isoAlpha; nAlphaSubCycles 1; cAlpha 1; // Note: cAlpha is not used by isoAdvector but must @@ -43,14 +44,14 @@ solvers { solver GAMG; smoother DICGaussSeidel; - tolerance 1e-07; + tolerance 1e-09; relTol 0.05; } p_rghFinal { $p_rgh; - tolerance 1e-07; + tolerance 1e-09; relTol 0; } diff --git a/tutorials/multiphase/interIsoFoam/damBreakWithObstacle/system/fvSolution b/tutorials/multiphase/interIsoFoam/damBreakWithObstacle/system/fvSolution index 2e43fdd84e966d36b6104472978ccc684025b931..1055760c6c2bab5d636d4645923b1dd185dd4ec9 100644 --- a/tutorials/multiphase/interIsoFoam/damBreakWithObstacle/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/damBreakWithObstacle/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -27,6 +27,7 @@ solvers writeSurfCells false; writeBoundedCells false; writeIsoFaces false; + reconstructionScheme plicRDF; // isoAlpha nAlphaCorr 1; nAlphaSubCycles 1; diff --git a/tutorials/multiphase/interIsoFoam/discInConstantFlow/system/fvSolution b/tutorials/multiphase/interIsoFoam/discInConstantFlow/system/fvSolution index 9eca06945a32d2469064ac5e17354232375fbe22..0064e91fec483b4cef90182f528aebe4032325fe 100644 --- a/tutorials/multiphase/interIsoFoam/discInConstantFlow/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/discInConstantFlow/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -26,6 +26,7 @@ solvers clip false; cAlpha 1; nAlphaSubCycles 1; + reconstructionScheme plicRDF; // isoAlpha } } diff --git a/tutorials/multiphase/interIsoFoam/discInConstantFlowCyclicBCs/system/fvSolution b/tutorials/multiphase/interIsoFoam/discInConstantFlowCyclicBCs/system/fvSolution index ca8558730b5b21bcd34f03993d490bd7dc4b300d..57e8c9f2abd06f59d79d8cfe5a86ee20bc19b429 100644 --- a/tutorials/multiphase/interIsoFoam/discInConstantFlowCyclicBCs/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/discInConstantFlowCyclicBCs/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -25,6 +25,7 @@ solvers snapTol 1e-10; nAlphaBounds 3; clip true; + reconstructionScheme isoAlpha; // isoAlpha nAlphaCorr 2; nAlphaSubCycles 1; diff --git a/tutorials/multiphase/interIsoFoam/discInReversedVortexFlow/system/fvSolution b/tutorials/multiphase/interIsoFoam/discInReversedVortexFlow/system/fvSolution index 8888d89ec34663b031b0da15f2c78cb2a4a27d57..cd741f6105c69a90137938489a35b96058979a07 100644 --- a/tutorials/multiphase/interIsoFoam/discInReversedVortexFlow/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/discInReversedVortexFlow/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -27,6 +27,7 @@ solvers nAlphaSubCycles 1; cAlpha 1; + reconstructionScheme plicRDF; // isoAlpha } } diff --git a/tutorials/multiphase/interIsoFoam/iobasin/system/fvSolution b/tutorials/multiphase/interIsoFoam/iobasin/system/fvSolution index c65a3141132432934896faf4d1ac5a7d9441f936..e6094374ecf28e9fb39fdca62a61ff075c1602fd 100644 --- a/tutorials/multiphase/interIsoFoam/iobasin/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/iobasin/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -21,6 +21,12 @@ solvers { nAlphaSubCycles 1; cAlpha 1; + reconstructionScheme isoAlpha; // plicRDF + isoFaceTol 1e-8; + surfCellTol 1e-6; + nAlphaBounds 3; + snapTol 0; + clip false; } "pcorr.*" diff --git a/tutorials/multiphase/interIsoFoam/notchedDiscInSolidBodyRotation/system/fvSolution b/tutorials/multiphase/interIsoFoam/notchedDiscInSolidBodyRotation/system/fvSolution index f8e6297298e5136f186f5d789afad8c9d9e793da..212bd37a6ea52c5b8c70deaeed2947ee1caf3230 100644 --- a/tutorials/multiphase/interIsoFoam/notchedDiscInSolidBodyRotation/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/notchedDiscInSolidBodyRotation/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -26,6 +26,7 @@ solvers clip false; nAlphaSubCycles 1; cAlpha 1; + reconstructionScheme isoAlpha; // plicRDF } } diff --git a/tutorials/multiphase/interIsoFoam/sloshingTank2D/system/fvSolution b/tutorials/multiphase/interIsoFoam/sloshingTank2D/system/fvSolution index 78da1382a17e8259363a46624b5994d6cb392026..8e67341327c2b51825c6d95306a99267b9b24f6b 100644 --- a/tutorials/multiphase/interIsoFoam/sloshingTank2D/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/sloshingTank2D/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -28,6 +28,7 @@ solvers nAlphaBounds 3; snapTol 1e-12; clip true; + reconstructionScheme isoAlpha; // plicRDF } "pcorr.*" diff --git a/tutorials/multiphase/interIsoFoam/sphereInReversedVortexFlow/system/fvSolution b/tutorials/multiphase/interIsoFoam/sphereInReversedVortexFlow/system/fvSolution index 296bb37513e4b30e3017eb3cd9daf77ef247be03..7cf62d33b93426f2043ff33d0bcd0e92cf6980d1 100644 --- a/tutorials/multiphase/interIsoFoam/sphereInReversedVortexFlow/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/sphereInReversedVortexFlow/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -22,10 +22,11 @@ solvers isoFaceTol 1e-8; surfCellTol 1e-8; snapTol 0; - nAlphaBounds 4; + nAlphaBounds 8; clip false; nAlphaSubCycles 1; cAlpha 1; + reconstructionScheme isoAlpha; } } diff --git a/tutorials/multiphase/interIsoFoam/standingWave/system/fvSolution b/tutorials/multiphase/interIsoFoam/standingWave/system/fvSolution index a008fb37fe247c338cf5273f2b4cc977a77eaa59..1f81d8863c4146ebb2dbbb2f311869393176499b 100644 --- a/tutorials/multiphase/interIsoFoam/standingWave/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/standingWave/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -27,6 +27,7 @@ solvers nAlphaSubCycles 1; cAlpha 1; + reconstructionScheme isoAlpha; // plicRDF } "pcorr.*" diff --git a/tutorials/multiphase/interIsoFoam/waveExampleStreamFunction/system/fvSolution b/tutorials/multiphase/interIsoFoam/waveExampleStreamFunction/system/fvSolution index 7e05141e54b58348533a677be66437cba61130d5..d4b766f007be66ea6f1de4e2dc927c5618301fad 100644 --- a/tutorials/multiphase/interIsoFoam/waveExampleStreamFunction/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/waveExampleStreamFunction/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -29,13 +29,7 @@ solvers nAlphaSubCycles 1; cAlpha 1; - MULESCorr yes; - nLimiterIter 5; - - solver smoothSolver; - smoother symGaussSeidel; - tolerance 1e-8; - relTol 0; + reconstructionScheme plicRDF; // plicRDF } "pcorr.*" diff --git a/tutorials/multiphase/interIsoFoam/weirOverflow/system/fvSolution b/tutorials/multiphase/interIsoFoam/weirOverflow/system/fvSolution index 644ee773d2c58f88e3585867d68faf96dc93bef3..03fac114d04d530f41f82eda5d2e5c9c343f6730 100644 --- a/tutorials/multiphase/interIsoFoam/weirOverflow/system/fvSolution +++ b/tutorials/multiphase/interIsoFoam/weirOverflow/system/fvSolution @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v1912 | +| \\ / O peration | Version: v2006 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -28,6 +28,7 @@ solvers cAlpha 1; // Note: cAlpha is not used by isoAdvector but must // be specified because interfacePropertes object // reads it during construction. + reconstructionScheme isoAlpha; // plicRDF } "pcorr.*"