Processing math: 0%
MAIA bb96820c
Multiphysics at AIA
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
FvMbCartesianSolverXD< nDim, SysEqn > Class Template Reference

#include <fvmbcartesiansolverxd.h>

Inheritance diagram for FvMbCartesianSolverXD< nDim, SysEqn >:
[legend]
Collaboration diagram for FvMbCartesianSolverXD< nDim, SysEqn >:
[legend]

Classes

struct  CellDataDlb
 
class  cellWithSplitFace
 
class  Csg
 
class  CsgNode
 
class  CsgPlane
 
class  CsgPolygon
 
class  CsgVector
 
class  CsgVertex
 
class  polyCutCell
 
class  polyCutCellBase
 
class  polyEdge2D
 
class  polyEdge3D
 
class  polyEdgeBase
 
class  polyFace
 
class  polyMultiFace
 
class  polyVertex
 
class  splitCartesianFace
 
class  surfBase
 

Public Types

using Base = FvCartesianSolverXD< nDim, SysEqn >
 
using SolverCell = FvCell
 
using Cell = typename maia::grid::tree::Tree< nDim >::Cell
 
using Timers = maia::fv::Timers_
 
- Public Types inherited from FvCartesianSolverXD< nDim, SysEqn >
using Cell = typename maia::grid::tree::Tree< nDim >::Cell
 
using FvSurfaceCollector = maia::fv::surface_collector::FvSurfaceCollector< nDim >
 
using SolverCell = FvCell
 
using CartesianSolver = typename maia::CartesianSolver< nDim, FvCartesianSolverXD >
 
using Grid = typename CartesianSolver::Grid
 
using GridProxy = typename CartesianSolver::GridProxy
 
using Geom = Geometry< nDim >
 
using PrimitiveVariables = typename SysEqn::PrimitiveVariables
 
- Public Types inherited from maia::CartesianSolver< nDim_, FvCartesianSolverXD< nDim_, SysEqn > >
using Grid = CartesianGrid< nDim >
 
using GridProxy = typename maia::grid::Proxy< nDim >
 
using Geom = Geometry< nDim >
 
using TreeProxy = maia::grid::tree::TreeProxy< nDim >
 
using Cell = maia::grid::tree::Cell
 

Public Member Functions

 FvMbCartesianSolverXD (MInt, MInt, const MBool *, maia::grid::Proxy< nDim > &gridProxy_, Geometry< nDim > &geometry_, const MPI_Comm comm)
 
 ~FvMbCartesianSolverXD () override
 
void initializeMb ()
 called by the constructor 1) read additional fvmb properties 2) allocate fvmb specific memory 3) initAnalyticalLevelSet More...
 
void initAnalyticalLevelSet ()
 This function creats the bodyTree for analytical LevelSets. More...
 
void allocateBodyMemory (MInt mode=0)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
MInt locatenear (const Point< nDim > &pt, MFloat r, MInt *list, MInt nmax, MBool returnCellId=true)
 
void setLevelSetMbCellProperties ()
 determines relevant cell properties More...
 
void writeListOfActiveFlowCells () override
 stores all cells and surfaces needed for the flux computation More...
 
void setTimeStep () override
 calls sets() and stores the time step for all cells More...
 
void initSolver () override
 Initializes the solution. More...
 
void finalizeInitSolver () override
 Initializes the solver afer the initialRefinement! More...
 
void initSolutionStep (MInt mode) override
 Initializes the solver. More...
 
void reInitSolutionStep (const MInt mode)
 Re-initializes the solver. More...
 
void updateInfinityVariables ()
 update infinity state for certain testcases with constructed level-set field! More...
 
void advanceSolution ()
 advances the time and stores the flow variables More...
 
void advanceBodies ()
 advances the time and stores the flow variables More...
 
void advanceTimeStep ()
 
void prepareNextTimeStep () override
 Updates the old Variables, the body positions and the increases the time. More...
 
void computeBoundarySurfaceForces ()
 
void applyInitialCondition () override
 
void applyExternalSource () override
 Add external sources to the RHS for new-RungeKutta-scheme for moving boundaries differs from the base fv-version, as the runge-Kutta ordering is differently and otherwise the externalSource is not conservative! More...
 
void applyExternalOldSource () override
 remove external sources from tho old RHS for new-RungeKutta-scheme for moving boundaries More...
 
void advanceExternalSource () override
 advance external sources More...
 
MBool maxResidual (MInt mode=0) override
 Computes the maxResiduum for all cells. More...
 
MLong getNumberOfCells (MInt mode)
 mode=0: total mode=1: min mode=2: max mode=3: average More...
 
void initGField ()
 initializes the level-set data at startup More...
 
void initBndryLayer ()
 initializes the bndryLayer data and is/was inactive at solver initialisation More...
 
void updateGeometry ()
 Updates the member-variables in the geometry-intersection class. More...
 
void constructGField (MBool updateBody=true)
 manually constructs the level-set field after each time step More...
 
MInt constructDistance (const MFloat deltaMax, MIntScratchSpace &nearestBodies, MFloatScratchSpace &nearestDist)
 
void transferLevelSetFieldValues (MBool)
 
void updateLevelSetOutsideBand ()
 computes an approximate level set value for cells outside the level-set computing band More...
 
MFloat CalculateLSV (MInt, MIntScratchSpace &)
 Calculate LevelSetValue with an Approximation of the Neighbours for a grid in the NarrowBand. More...
 
void setParticleFluidVelocities (MFloat *=nullptr)
 
void advancePointParticles ()
 
MBool constructGFieldCorrector ()
 determine the displacement of the embedded body – corrector step More...
 
void constructGFieldPredictor ()
 determine the displacement of the embedded body – predictor step More...
 
void initBodyProperties ()
 initialize properties of the embedded body at startup More...
 
void initPointParticleProperties ()
 
void initBodyVelocities ()
 
void updateBodyProperties ()
 update properties of the embedded body (mainly forced structural motion) More...
 
void transferBodyState (MInt k, MInt b)
 
void createPeriodicGhostBodies ()
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void createBodyTree ()
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void createBodyTree ()
 
void computeBodyMomentOfInertia ()
 
void integrateBodyRotation ()
 
void getBodyRotation (const MInt bodyId, MFloat *bodyRotation)
 
void getBodyRotationDt1 (const MInt bodyId, MFloat *bodyRotation)
 
void setBodyQuaternions (const MInt bodyId, MFloat *bodyRotation)
 
void setGapOpened ()
 sets the global-Trigger m_gapOpened, to determine if Gap-Cells are opened! old and incorrect version!!!! use m_gapInitMethod = 1 or 2 instead!! More...
 
void gapHandling ()
 determines Gap-state, and organises GapCells More...
 
void initGapCellExchange ()
 creates the gap-cell exchange communicators based on initializeMaxLevelExchange More...
 
void gapCellExchange (MInt)
 exchanges variables and wasInactive for gapCells More...
 
MInt checkNeighborActivity (MInt)
 ckecks that a new bndry-Cell has at least one neighbor which was active before if this is not the case, the largest neighbor of the cell is initialised and set to wasactive More...
 
void updateGapBoundaryCells ()
 set the velocity at gap-Boundary-Cells due to the irregular movement of the gap-surface during widening and shrinking the velocity and the volumes needs to be adapted More...
 
void checkGapCells ()
 determines Gap-state, and organises GapCells More...
 
void interpolateGapBodyVelocity ()
 sets the interpolated velocity for a bndryCell NOTE: all neighbors need to be available for levelset-interpolation! More...
 
MFloat interpolateLevelSet (MInt *, MFloat *, MInt)
 interpolates levelset function to a given coordinate More...
 
void setGapCellId ()
 set the gapCellId for gapInitMethod = 0, otherwise handeled in gapHandling! More...
 
void logBoundaryData (const MChar *fileName, MBool forceOutput)
 logs several boundary values to the given output file More...
 
void generateBndryCellsMb (const MInt mode)
 call all routines necessary for the generation of boundary cells mode = -1: default argument, regular call (each time step) mode = 0: reinit after mesh adaptation mode = 1: initial call before first time step mode = 2: reinit after load balancing (depricated) More...
 
void checkHaloBndryCells (MBool sweptVol)
 
void determineBndryCandidates ()
 determine all possible fluid boundary cells for a generic embedded body More...
 
void computeNodalLSValues ()
 compute the level-set values at the mesh vertices More...
 
void exchangeNodalLSValues ()
 
void initAzimuthalLinkedHaloExc ()
 Create exchange for all window/halo cells which are used for the azimuthal periodic interpolation. More...
 
void exchangeLinkedHaloCellsForAzimuthalReconstruction ()
 Create exchange for all window/halo cells which are used for the azimuthal periodic interpolation. More...
 
void storeAzimuthalPeriodicData (MInt mode=0)
 Stored azimuthal periodic data from halo rank on window rank. More...
 
void commAzimuthalPeriodicData (MInt mode=0)
 Send stored azimuthal periodic data from window to halo. More...
 
void computeAzimuthalReconstructionConstants (MInt mode=0) override
 Compute the reconstruction constants for azimuthal periodic exchange using a weighted least squares approached solved via singular value decomposition - Derieved form FvCartesianSolverXD::computeReconstructionConstantsSVD() More...
 
void buildAdditionalAzimuthalReconstructionStencil (MInt mode=0)
 Rebuild azimuthal reconstruction constants for moving boundary cells. More...
 
void updateAzimuthalMaxLevelRecCoords ()
 Update reconstruction coordinate for azimuthal halo cells on max level This is done because of moving boundary. More...
 
void updateAzimuthalNearBoundaryExchange ()
 Reset former azimuthal nearBoundaryCells. More...
 
void computeAzimuthalHaloNodalValues ()
 init exchange of nodal values of azimuthal periodic halo cells More...
 
void exchangeAzimuthalOuterNodalValues (std::vector< CutCandidate< nDim > > &candidates, std::vector< MInt > &candidateIds)
 Exchange of nodal values of azimuthal periodic halo cells. More...
 
void computeCutPointsMb_MGC ()
 Computes cutpoints of zero level-set with grid edges and creates boundary cells for cut-cells. More...
 
MBool createCutFaceMb ()
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void createCutFaceMb_MGC ()
 determines the geometric cut-cell data More...
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void createCutFaceMb_MGC ()
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void checkNormalVectors ()
 
void determineNearBndryCells ()
 determines cells at the boundary (i.e. boundary cells and their direct neighbors) More...
 
void computeGhostCellsMb ()
 creates a ghost cell for all cells near(!) the moving boundary More...
 
void setOuterBoundaryGhostCells ()
 
void setOuterBoundarySurfaces ()
 
void setupBoundaryCandidatesAnalytical ()
 determine all possible fluid boundary cells for a spherical embedded body More...
 
void checkBoundaryCells ()
 performs an integrety check of the boundary cells More...
 
void linkBndryCells ()
 Links bndryCells. More...
 
void redistributeMass ()
 
MInt createSplitCell (MInt cellId, MInt noSplitChilds)
 
MFloat updateCellVolumeGCL (MInt bndryId)
 
void correctRefinedBndryCell ()
 correct old-BndryCells which are no-longer leaf-Cells after the adaptation NOTE: mas-conservative update, as before the mass of the coarse Cell was distributed upon all childs. Now that we know which childs will be avtive, the mass must be distributed to just the active cells! More...
 
void correctRefinedBndryCellVolume ()
 correct BndryCells volume of bndryCells which were a bndryCell on a coarser level before More...
 
void correctCoarsenedBndryCellVolume ()
 correct BndryCells volume of bndryCells which were a bndryCell on a coarser level before More...
 
void rebuildKDTreeLocal ()
 
void rebuildKDTree ()
 
void resetSolverFull () override
 resets the solver More...
 
void resetSolverMb ()
 resets the solver to an empty domain without moving boundary More...
 
void resetSolver () override
 Reset the solver prior to load balancing. More...
 
void resetSurfaces () override
 
void balance (const MInt *const noCellsToReceiveByDomain, const MInt *const noCellsToSendByDomain, const MInt *const targetDomainsByCell, const MInt oldNoCells) override
 Balance the solver. More...
 
void balancePre () override
 Reinitialize solver for DLB prior to setting solution data. More...
 
void balancePost () override
 Reinitialize solver after setting solution data in DLB. More...
 
void finalizeBalance () override
 Reinitialize solver after all data structures have been recreated. More...
 
MBool hasSplitBalancing () const override
 Return if load balancing for solver is split into multiple methods or implemented in balance() More...
 
void localToGlobalIds () override
 Change local into global ids. More...
 
MInt noCellDataDlb () const override
 Methods to inquire solver data information. More...
 
MInt cellDataTypeDlb (const MInt dataId) const override
 
MInt cellDataSizeDlb (const MInt dataId, const MInt gridCellId) override
 Return data size to be communicated during DLB for a grid cell and given data id. More...
 
void getCellDataDlb (const MInt dataId, const MInt oldNoCells, const MInt *const bufferIdToCellId, MFloat *const data) override
 Return solver data for DLB. More...
 
void getCellDataDlb (const MInt dataId, const MInt oldNoCells, const MInt *const bufferIdToCellId, MLong *const data)
 Store the solver data for a given data id ordered in the given buffer for DLB. More...
 
void setCellDataDlb (const MInt dataId, const MFloat *const data) override
 Set solver data for DLB. More...
 
void setCellDataDlb (const MInt dataId, const MLong *const data)
 Set the solver cell data after DLB. More...
 
MBool adaptationTrigger () override
 
void resetMbBoundaryCells ()
 resets all moving boundary cells - STL boundary remains intact More...
 
void deleteNeighbourLinks ()
 deletes links to neighbours tagged inactive More...
 
void restoreNeighbourLinks ()
 restores previously deleted neighbour information and reactivates cells More...
 
void initializeEmergedCells ()
 initializes variables of cells which recently became active and therefore have no up-to-date history in the fluid phase (for MAIA_FV_MB_NEW_RK only for m_gapOpened ) More...
 
void initEmergingGapCells ()
 initializes variables of cells which occur in a freshly opened gap (valve gap etc.) More...
 
void updateCellSurfaceDistanceVectors ()
 correct the cell-surface distance vectors for cells near the moving boundary More...
 
void updateCellSurfaceDistanceVector (MInt srfcId)
 correct the cell-surface distance vectors for cells near the moving boundary More...
 
void updateViscousFluxComputation ()
 corrects the cell-surface distances at the boundary needed for the viscous flux computation More...
 
void leastSquaresReconstruction ()
 Least squares reconstruction. More...
 
void buildAdditionalReconstructionStencil ()
 correct reconstruction stencil for all cells near moving boundaries More...
 
void computeVolumeFraction ()
 computes the volume fraction V/h^d and the level-set value in the volumetric center of all boundary cells, More...
 
void computeReconstructionConstants () override
 computes the reconstruction constants using inverse distance weighted least squares More...
 
void prepareAdaptation () override
 
void setSensors (std::vector< std::vector< MFloat > > &sensors, std::vector< MFloat > &sensorWeight, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MInt > &sensorSolverId) override
 
void postAdaptation () override
 
void finalizeAdaptation () override
 
void sensorPatch (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt) override
 
void removeChilds (const MInt) override
 
void refineCell (const MInt) override
 
void setCellWeights (MFloat *) override
 set static cell weights for solver cells, which are used for the domain decomposition More...
 
void descendLevelSetValue (const MInt cellId, const MInt *const bodyIds, const MInt bodyCnt)
 
void descendDistance (const MInt cellId, const MInt *const bodyIds, const MInt bodyCnt, MIntScratchSpace &nearestBodies, MFloatScratchSpace &nearestDist)
 
void getBoundaryDistance (MFloatScratchSpace &) override
 
void swapCells (const MInt, const MInt) override
 
void moveSurface (const MInt toSrfcId, const MInt fromSrfcId)
 
void compactSurfaces ()
 
void correctMasterSlaveSurfaces ()
 Removes surfaces between master-slave pairs and reassigns slave cell surfaces required in order to make current MB branch version working with "normal" boundaries. More...
 
void restoreSurfaces (const MInt cellId)
 restores the surfaces of the given cell More...
 
void resetSurfaces (MInt cellId)
 resets the surfaces of the given cell to their original state More...
 
void removeSurfaces (MInt cellId)
 removes the surfaces of the given cell More...
 
void deleteSurface (MInt srfcId)
 removes the surfaces of the given cell More...
 
void createSurface (MInt srfcId, MInt nghbrId0, MInt nghbrId1, MInt orientation)
 restores the surfaces of the given cell More...
 
void createSurfaceSplit (MInt srfcId, MInt cellId, MInt splitChildId, MInt direction)
 restores the surfaces of the given cell More...
 
MInt getNewSurfaceId ()
 returns a new surface id More...
 
void rebuildReconstructionConstants (MInt cellId)
 computes the reconstruction constants using inverse distance weighted least squares More...
 
void setCellProperties () override
 set the properties of cells and determines the state of halo cells More...
 
void setAdditionalActiveFlag (MIntScratchSpace &) override
 
void computeLocalBoundingBox ()
 
void createInitialSrfcs ()
 computes initial set of internal grid surfaces More...
 
void correctSrfcsMb ()
 correct surfaces intersected by the moving boundary More...
 
void addBoundarySurfacesMb ()
 adds a surface for the ghost-boundary cell intersections More...
 
void Muscl (MInt timerId=-1) override
 Reconstructs the flux on the surfaces. More...
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void LSReconstructCellCenter() override
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void computeSurfaceValues(MInt timerId
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void computeSurfaceValuesLimited(MInt timerId
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void Ausm() override
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void viscousFlux() override
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void resetRHS() override
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void distributeFluxToCells() override
 
void initializeRungeKutta () override
 This function loads all terms used by Runge Kutta. More...
 
void setRungeKuttaFunctionPointer ()
 This function sets the function pointers for rungeKutta (also used in splitBalance) More...
 
MBool rungeKuttaStep () override
 calls a Runge Kutta substep More...
 
template<MInt timeStepMethod>
 ATTRIBUTES1 (ATTRIBUTE_HOT) MBool rungeKuttaStepStandard()
 
template<MInt timeStepMethod>
 ATTRIBUTES1 (ATTRIBUTE_HOT) MBool rungeKuttaStepNew()
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) MBool rungeKuttaStepNewLocalTimeStepping()
 
void computeTimeStep ()
 
void adaptTimeStep ()
 computes the time step More...
 
void updateSplitParentVariables () override
 
void updateSpongeLayer () override
 computes the additional rhs of all cells lying inside the sponge layer to dissipate outgoing waves. More...
 
virtual void generateBndryCells ()
 
 ATTRIBUTES1 (ATTRIBUTE_HOT) void exchange() override
 
void initializeMaxLevelExchange () override
 update window/halo cell collectors More...
 
void updateMultiSolverInformation (MBool fullReset=false) override
 
void exchangeLevelSetData ()
 
void applyALECorrection ()
 
void resetRHSCutOffCells () override
 
void applyBoundaryCondition () override
 dummy, since applyBoundaryCondition() it is placed wrong for moving boundary problems, see applyBoundaryConditionMb() More...
 
void applyBoundaryConditionMb ()
 applies the boundary condition at all boundaries More...
 
void applyBoundaryConditionSlope ()
 
void updateGhostCellSlopesInviscid ()
 
void updateGhostCellSlopesViscous ()
 
void applyDirichletCondition ()
 
void applyNeumannCondition ()
 
void setBoundaryVelocity ()
 Sets the boundry velocity at the moving cut-cells. sets: m_primVars[PV->VV[i]] to m_bodyVelocity[i] for all bodies. More...
 
void copyVarsToSmallCells () override
 calls m_fvBndryCnd->copyVarsToSmallCells() More...
 
void correctBoundarySurfaceVariablesMb ()
 sets boundary surface variables to their correct values More...
 
void computeBodySurfaceData (MFloat *pressureForce=nullptr)
 computes relevant variables at the moving boundary surface and determines the resulting body force More...
 
void resetRHSNonInternalCells () override
 
void updateLinkedCells ()
 update the temporarly-linked cells More...
 
void saveSolverSolution (const MBool forceOutput=false, const MBool finalTimeStep=false) override
 Manages solver-specific output. More...
 
void recordBodyData (const MBool &firstRun)
 
void crankAngleSolutionOutput ()
 save a full solutionOutput at timeSteps closesed to a specified crankAngle Interval save a solution slice at timeSteps closesed to a specified slice Interval More...
 
void writeStencil (const MInt bndryId)
 
void computeForceCoefficients (MFloat *&)
 dummy More...
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
MInt writeGeometryToVtkXmlFile (const MString &fileName)
 Writes VTK file for the embedded geometry. More...
 
void saveRestartFile (const MBool) override
 Saves the restart file. More...
 
void loadRestartFile () override
 Loads the restart files. More...
 
void loadBodyRestartFile (MInt)
 load restart body file readMode = 0 : do not read the cellVolume from file (read only bodyData) readMode = 1 : read cell volume from file for all bndryCells readMode = 2 : read cell volume and store in array (bndryCells not yet created) necessary for geometryChange at restart! More...
 
void setOldGeomBndryCellVolume ()
 set bndryCell volume from m_oldGeomBndryCells which is read from bodyRestartFile at initSolver and thus before the forcedAdaptation at the restart! More...
 
void saveBodyRestartFile (const MBool backup)
 save restart body file More...
 
void saveBodySamples ()
 
void saveParticleSamples ()
 
void writeVtkDebug (const MString suffix)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void writeVtkXmlOutput (const MString &fileName, MBool debugOutput=false)
 write flow variables as XML VTK More...
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void writeVtkXmlOutput (const MString &fileName, MBool debugOutput=false)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void writeVtkXmlOutput_MGC (const MString &fileName)
 write flow variables as XML VTK More...
 
void writeVtkXmlFiles (const MString fileName, const MString GFileName, MBool regularOutput, MBool diverged) override
 write flow variables as XML VTK files More...
 
void writeVtkErrorFile ()
 write flow variables as XML VTK files More...
 
void printDynamicCoefficients (MBool firstRun, MFloat *pressureForce)
 
void computeFlowStatistics (MBool force)
 
void saveParticleSlipData ()
 
void computeSlipStatistics (const MIntScratchSpace &nearestBodies, const MFloatScratchSpace &nearestDist, const MFloat maxDistConstructed)
 
void computeNearBodyFluidVelocity (const MIntScratchSpace &nearestBodies, const MFloatScratchSpace &nearestDist, MFloat *vel, MFloat *velGrad, MFloat *rotation, const std::vector< MFloat > &setup=std::vector< MFloat >(), MInt *skipBodies=nullptr, MFloat *meanBodyState=nullptr, MFloat *pressure=nullptr, MFloat *velDt=nullptr, MFloat *rotationDt=nullptr, MFloat *nearestFac=nullptr)
 Mean parameters: near body data estimated by weighted filtering procedure All parameters after "setup" can be replaced by nullptr, and will be excluded to safe comp.time setup expects a vector with up to 4 values: minimal Distance, maximal Distance, maximal Angle (dotProduct relative cell position with hydroForce) for velocity estimation, and maximal Angle for rotational velocity estimation. More...
 
void computeBodyVolume (MFloatScratchSpace &partVol)
 
void saveInitCorrData (const std::vector< MInt > &saveInitCorrDataTimeSteps, const MFloatScratchSpace &bodyVelocityInit, const MFloatScratchSpace &bodyAngularVelocityInit, const MFloatScratchSpace &bodyQuaternionInit, const MFloatScratchSpace &velMeanInit, const MFloatScratchSpace &velGradMeanInit, const MFloatScratchSpace &particleFluidRotationMeanInit, const MIntScratchSpace &corrBodies, const MFloatScratchSpace &bodyForceInit, const MFloatScratchSpace &bodyTorqueInit, const MIntScratchSpace &bodyOffsets)
 
MInt loadInitCorrData (const std::vector< MInt > &saveInitCorrDataTimeSteps, MFloatScratchSpace &bodyVelocityInit, MFloatScratchSpace &bodyAngularVelocityInit, MFloatScratchSpace &bodyQuaternionInit, MFloatScratchSpace &velMeanInit, MFloatScratchSpace &velGradMeanInit, MFloatScratchSpace &particleFluidRotationMeanInit, MIntScratchSpace &corrBodies, MFloatScratchSpace &bodyForceInit, MFloatScratchSpace &bodyTorqueInit, const MIntScratchSpace &bodyOffsets)
 
MFloat determineCoupling (MFloatScratchSpace &coupling)
 
void writeCenterLineVel (const MChar *fileName)
 writes the velocity at the center line of the domain More...
 
void readStlFile (const MChar *fileName, MBool readNormals)
 read specified STL file More...
 
MBool prepareRestart (MBool, MBool &) override
 Prepare the solvers for a grid-restart. More...
 
void reIntAfterRestart (MBool) override
 
void preTimeStep () override
 Performs the preTimeStep of the FVMB solver. More...
 
void preSolutionStep (const MInt=-1) override
 step before the solver solution Step More...
 
MBool solutionStep () override
 Performs the solutionStep of the FVMB solver the loop over the different RK-steps is done in the execution-recipe. More...
 
MBool postSolutionStep () override
 step after the solver solution Step More...
 
void postTimeStep () override
 Performs the postTimeStep of the FVMB solver. More...
 
void logOutput ()
 logs several collector sizes More...
 
void resetSlopes ()
 does what it says More...
 
void logData ()
 
MInt createBndryCellMb (MInt cellId)
 creates a moving boundary cell for the given cell More...
 
MInt getAdjacentCells (MInt cellId, MInt *adjacentCells)
 retrieves all direct and diagonal fluid cell neighbours of the given cell More...
 
MInt getAdjacentGridCells (MInt cellId, MInt *adjacentCells)
 retrieves all direct and diagonal fluid cell neighbours of the given cell More...
 
MInt getAdjacentCellsAllLevels (MInt cellId, MInt *adjacentCells)
 retrieves all direct and diagonal fluid cell neighbours of the given cell More...
 
MInt getAdjacentCellsExtended (MInt cellId, MInt *adjacentCells)
 retrieves the first two layers of direct and diagonal fluid cell neighbours of the given cell More...
 
MInt getEqualLevelNeighbors (MInt cellId, MInt(&nghbrs)[27])
 retrieves all direct and diagonal fluid cell neighbours of the given cell More...
 
MInt broadcastSignal (const MInt sender, const MInt signal)
 hijacked function to compute gradients in intial condition 122 for pressure poisson equation More...
 
MInt getFacingNghbrs (const MInt cellId, const MBool includeAllChilds)
 determines the neighbors sharing a face with the given cell More...
 
MFloat temperature (MInt cellId)
 temperature More...
 
MFloat filterFloat (MFloat number)
 filter nan's More...
 
MBool gridPointIsInside (MInt, MInt) override
 
MString getConservativeVarName (MInt i)
 returns the name of the conservative variable at the given index i More...
 
MString getPrimitiveVarName (MInt i)
 returns the name of the primitive variable at the given index i More...
 
MInt inverseGJ ()
 computes the Gauss Jordan matrix inversion of the first DxD-solver of m_A. The inverse A^-1 is stored in m_A[0:D-1][D:2D-1] More...
 
template<typename T >
MBool isNan (T val)
 
MFloat getDistance (const MFloat *const, const MInt)
 
MFloat getDistance (const MInt, const MInt)
 
MFloat getDistanceSphere (const MFloat *const, const MInt)
 
MFloat getDistanceSphere (const MInt, const MInt)
 
MFloat getDistancePiston (const MFloat *const, const MInt)
 
MFloat getDistancePiston (const MInt, const MInt)
 
MFloat getDistanceEllipsoid (const MFloat *const, const MInt)
 
MFloat getDistanceEllipsoid (const MInt, const MInt)
 
MFloat getDistanceNaca00XX (const MInt, const MInt)
 
MFloat getDistanceSplitSphere (const MInt, const MInt)
 determines the level-set value for the given cell provided that the embedded body is spherical More...
 
MFloat getDistanceTetrahedron (const MFloat *const, const MInt)
 
void getNormal (const MInt, const MInt, MFloat[])
 
void getNormalSphere (const MInt, const MInt, MFloat[])
 
void getNormalEllipsoid (const MInt, const MInt, MFloat[])
 
MFloat getLevelSetValueNaca00XX (const MFloat *const, const MFloat sign)
 
MFloat distancePointEllipsoidSpecial (const MFloat e[3], const MFloat y[3], MFloat x[3])
 
MFloat distancePointEllipsoidSpecial2 (const MFloat e[3], const MFloat y[3], MFloat x[3])
 
MFloat distancePointEllipsoid (const MFloat e[3], const MFloat y[3], MFloat x[3])
 
MFloat distEllipsoidEllipsoid (const MInt k0, const MInt k1, MFloat *xc0, MFloat *xc1)
 Compute the distance between two ellipsoids by iteratively searching the nearest point on the respectively other surface, xc0 and xc1 are the corresponding surface coordinates. More...
 
void checkCellState ()
 checks the cell state of the inactive cells based on the nodal ls values if a cell is inactive (levelSetValue < 0) but its nodal values are all positive, it is set active again (important for sharp features) More...
 
MBool inside (MFloat x, MFloat a, MFloat b)
 
MString printTime (const MFloat t)
 
MBool fileExists (const MChar *fileName)
 
MInt copyFile (const MChar *fromName, const MChar *toName)
 
void checkHaloCells (MInt mode=0)
 Checks a couple of important properties and variables of halo-cells. More...
 
MInt returnNoActiveCorners (MInt)
 returns the numer of active Corners for an arbitrary cell (the cell is not a bndryCandidate yet and the nodal-Ls-values have not been computed yet) just as in computeNodalLsValues, so that the same results are retrieved More...
 
- Public Member Functions inherited from FvCartesianSolverXD< nDim, SysEqn >
 FvCartesianSolverXD ()=delete
 
 FvCartesianSolverXD (MInt, MInt, const MBool *, maia::grid::Proxy< nDim_ > &gridProxy_, Geometry< nDim_ > &geometry_, const MPI_Comm comm)
 
 ~FvCartesianSolverXD ()
 
SysEqn sysEqn () const
 
SysEqn & sysEqn ()
 
MInt a_noCells () const
 Returns the number of cells. More...
 
MInt noInternalCells () const override
 Return the number of internal cells within this solver. More...
 
MBool a_isGapCell (const MInt cellId) const
 Returns isGapCell of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isGapCell (const MInt cellId)
 Returns isGapCell of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_wasGapCell (const MInt cellId)
 Returns wasGapCell of the cell cellId. More...
 
MBool a_isHalo (const MInt cellId) const
 Returns IsHalo of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isHalo (const MInt cellId)
 Returns IsHalo of the cell cellId. More...
 
MBool a_isWindow (const MInt cellId) const
 Returns IsWindow of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isWindow (const MInt cellId)
 Returns IsWindow of the cell cellId. More...
 
MBool a_isPeriodic (const MInt cellId) const
 Returns IsPeriodic of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isPeriodic (const MInt cellId)
 Returns IsPeriodic of the cell cellId. More...
 
MBool a_isBndryCell (const MInt cellId) const override
 Returns isBndryCell of the cell cellId. More...
 
MBool a_isInterface (const MInt cellId) const
 Returns isInterface of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isInterface (const MInt cellId)
 Returns isInterface of the cell cellId. More...
 
MBool a_isBndryGhostCell (const MInt cellId) const
 Returns isBndryGhostCell of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isBndryGhostCell (const MInt cellId)
 Returns isBndryGhostCell of the cell cellId. More...
 
MBool a_isWMImgCell (const MInt cellId) const
 Returns isWMImgCell of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isWMImgCell (const MInt cellId)
 Returns isWMImgCell of the cell cellId. More...
 
MBool a_isSandpaperTripCell (const MInt cellId) const
 Returns isWMImgCell of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_isSandpaperTripCell (const MInt cellId)
 Returns isWMImgCell of the cell cellId. More...
 
maia::fv::cell::BitsetTypea_properties (const MInt cellId)
 Returns properties of the cell cellId. More...
 
MFloata_spongeFactor (const MInt cellId)
 Returns the spongeFactor of the cell cellId. More...
 
MFloat a_spongeFactor (const MInt cellId) const
 Returns the spongeFactor of the cell cellId. More...
 
MFloata_coordinate (const MInt cellId, const MInt dir)
 Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir. More...
 
MFloat a_coordinate (const MInt cellId, const MInt dir) const
 Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir. More...
 
MInta_level (const MInt cellId)
 Returns the level of the cell from the fvcellcollector cellId. More...
 
MInt a_level (const MInt cellId) const
 Returns the level of the cell from the fvcellcollector cellId. More...
 
MFloata_cellVolume (const MInt cellId)
 Returns the cell volume of the cell from the fvcellcollector cellId. More...
 
MFloat a_cellVolume (const MInt cellId) const
 Returns the cell volume of the cell from the fvcellcollector cellId. More...
 
MFloata_FcellVolume (const MInt cellId) override
 Returns the inverse cell volume of the cell from the fvcellcollector cellId. More...
 
MFloat a_FcellVolume (const MInt cellId) const
 Returns the inverse cell volume of the cell from the fvcellcollector cellId. More...
 
MInt a_cutCellLevel (const MInt cellId) const
 Returns the level for cutCells, this can either be the maxRefinementLevel or the level of the current cellId. More...
 
MBool a_isInactive (const MInt cellId) const
 
MBool a_isActive (const MInt cellId) const
 
MBool a_isSplitCell (const MInt cellId) const
 
MInt a_noSplitCells () const
 
MInt a_noSplitChilds (const MInt sc) const
 
MInt a_splitChildId (const MInt sc, const MInt ssc)
 
MInt a_splitCellId (const MInt sc) const
 
void assertValidGridCellId (const MInt cellId) const
 Cecks wether the cell cellId is an actual grid-cell. More...
 
void assertValidGridCellId (const MInt NotUsed(cellId)) const
 
void assertDeleteNeighbor (const MInt cellId, const MInt dir) const
 Checks wether the cell cellId has a valid neighbor in direction dir. More...
 
MBool checkNeighborActive (const MInt cellId, const MInt dir) const
 Cecks wether the cell cellId has a valid neighbor in direction dir. More...
 
MFloat c_coordinate (const MInt cellId, const MInt dir) const
 Returns the coordinate of the cell from the grid().tree() cellId for dimension dir. More...
 
MBool c_isLeafCell (const MInt cellId) const
 
MInt c_level (const MInt cellId) const
 Returns the grid level of the cell cellId. More...
 
MInt c_noChildren (const MInt cellId) const
 Returns the number of children of the cell cellId. More...
 
MLong c_parentId (const MInt cellId) const
 Returns the grid parent id of the cell cellId. More...
 
MLong c_globalId (const MInt cellId) const
 Returns the global grid id of the grid cell cellId. More...
 
MFloat c_weight (const MInt cellId) const
 Returns the weight of the cell cellId. More...
 
MLong c_childId (const MInt cellId, const MInt pos) const
 Returns the grid child id of the grid cell cellId at position pos. More...
 
MLong c_neighborId (const MInt cellId, const MInt dir, const MBool assertNeighborState=true) const
 Returns the grid neighbor id of the grid cell cellId dir. More...
 
MFloat c_cellLengthAtCell (const MInt cellId) const
 Returns the length of the cell for level. More...
 
MFloat c_cellLengthAtLevel (const MInt level) const
 Returns the length of the cell for level. More...
 
MFloat c_cellVolumeAtLevel (const MInt level) const
 Returns the grid Volume of the cell for level. More...
 
MBool a_hasProperty (const MInt cellId, const Cell p) const
 Returns grid cell property p of the cell cellId. More...
 
maia::fv::cell::BitsetType::reference a_hasProperty (const MInt cellId, const SolverCell p)
 Returns solver cell property p of the cell cellId. More...
 
MBool a_hasProperty (const MInt cellId, const SolverCell p) const
 Returns solver cell property p of the cell cellId. More...
 
MBool c_isToDelete (const MInt cellId) const
 Returns the delete of the cell cellId. More...
 
MInt a_hasNeighbor (const MInt cellId, const MInt dir, const MBool assertNeighborState=true) const
 Returns noNeighborIds of the cell CellId for direction dir. More...
 
MFloata_variable (const MInt cellId, const MInt varId)
 Returns conservative variable v of the cell cellId for variables varId. More...
 
MFloat a_variable (const MInt cellId, const MInt varId) const
 Returns conservative variable v of the cell cellId for variables varId. More...
 
MFloata_pvariable (const MInt cellId, const MInt varId)
 Returns primitive variable v of the cell cellId for variables varId. More...
 
MFloat a_pvariable (const MInt cellId, const MInt varId) const
 Returns primitive variable v of the cell cellId for variables varId. More...
 
MFloata_avariable (const MInt cellId, const MInt varId)
 Returns additional variable v of the cell cellId for variables varId. More...
 
MFloat a_avariable (const MInt cellId, const MInt varId) const
 Returns additional variable v of the cell cellId for variables varId. More...
 
void a_resetPropertiesSolver (const MInt cellId)
 Returns property p of the cell cellId. More...
 
void a_copyPropertiesSolver (const MInt fromCellId, const MInt toCellId)
 Returns property p of the cell cellId. More...
 
MInta_reconstructionNeighborId (const MInt cellId, const MInt nghbrNo)
 Returns reconstruction neighbor n of the cell cellId. More...
 
MInt a_reconstructionNeighborId (const MInt cellId, const MInt nghbrNo) const
 Returns reconstruction neighbor n of the cell cellId. More...
 
MInt a_reconstructionNeighborId (const MInt cellId) const
 Returns reconstruction data offset i of the cell cellId. More...
 
MInta_reconstructionData (const MInt cellId)
 Returns reconstruction data offset i of the cell cellId. More...
 
MInta_spongeBndryId (const MInt cellId, const MInt dir)
 Returns the spongeBndryId of the cell cellId for direction dir. More...
 
MInt a_spongeBndryId (const MInt cellId, const MInt dir) const
 Returns the spongeBndryId of the cell cellId for direction dir. More...
 
MFloata_spongeFactorStart (const MInt cellId)
 Returns the spongeFactorStart of the cell cellId. More...
 
MFloat a_spongeFactorStart (const MInt cellId) const
 Returns the spongeFactorStart of the cell cellId. More...
 
MInta_bndryId (const MInt cellId)
 Returns the bndryId of the cell cellId. More...
 
MInt a_bndryId (const MInt cellId) const
 Returns the bndryId of the cell cellId. More...
 
MInta_noReconstructionNeighbors (const MInt cellId)
 Returns the noRcnstrctnNghbrIds of the cell cellId. More...
 
MInt a_noReconstructionNeighbors (const MInt cellId) const
 Returns the noRcnstrctnNghbrIds of the cell cellId. More...
 
MFloata_tau (const MInt cellId, const MInt varId)
 Returns the tau of the cell cellId for variable varId. More...
 
MFloat a_tau (const MInt cellId, const MInt varId) const
 Returns the tau of the cell cellId for variable varId. More...
 
MFloata_restrictedRHS (const MInt cellId, const MInt varId)
 Returns the restrictedRHS of the cell cellId for variable varId. More...
 
MFloat a_restrictedRHS (const MInt cellId, const MInt varId) const
 Returns the restrictedRHS of the cell cellId for variable varId. More...
 
MFloata_restrictedVar (const MInt cellId, const MInt varId)
 Returns restricted variables of cell cellId for variable varId on level level. More...
 
MFloat a_restrictedVar (const MInt cellId, const MInt varId) const
 Returns restricted variables of cell cellId for variable varId on level level. More...
 
MFloata_reactionRate (const MInt cellId, const MInt reactionId)
 Returns the reactionRate of the cell cellId for variables varId. More...
 
MFloat a_reactionRate (const MInt cellId, const MInt reactionId) const
 Returns the reactionRate of the cell cellId for variables varId. More...
 
MFloata_reactionRateBackup (const MInt cellId, const MInt reactionId)
 Returns the reactionRateBackup of the cell cellId for variables varId. More...
 
MFloat a_reactionRateBackup (const MInt cellId, const MInt reactionId) const
 Returns the reactionRateBackup of the cell cellId for variables varId. More...
 
MFloata_psi (const MInt cellId)
 Returns psi of the cell cellId for variables varId. More...
 
MFloat a_psi (const MInt cellId) const
 Returns psi of the cell cellId for variables varId. More...
 
MFloata_speciesReactionRate (const MInt cellId, const MInt speciesIndex)
 
MFloat a_speciesReactionRate (const MInt cellId, const MInt speciesIndex) const
 
MFloata_implicitCoefficient (const MInt cellId, const MInt coefId)
 Returns the implicitCoefficient of cell cellId for coefficient coefId. More...
 
MFloat a_implicitCoefficient (const MInt cellId, const MInt coefId) const
 Returns the implicitCoefficient of cell cellId for coefficient coefId. More...
 
MFloata_dt1Variable (const MInt cellId, const MInt varId)
 Returns dt1Variables of the cell CellId variables varId. More...
 
MFloat a_dt1Variable (const MInt cellId, const MInt varId) const
 Returns dt1Variables of the cell CellId variables varId. More...
 
MFloata_dt2Variable (const MInt cellId, const MInt varId)
 Returns dt2Variables of the cell CellId variables varId. More...
 
MFloat a_dt2Variable (const MInt cellId, const MInt varId) const
 Returns dt2Variables of the cell CellId variables varId. More...
 
MFloata_oldVariable (const MInt cellId, const MInt varId)
 Returns oldVariablesv of the cell cellId variables varId. More...
 
MFloat a_oldVariable (const MInt cellId, const MInt varId) const
 Returns oldVariables v of the cell cellId variables varId. More...
 
MFloata_slope (const MInt cellId, MInt const varId, const MInt dir) override
 Returns the slope of the cell cellId for the variable varId in direction dir. More...
 
MFloat a_slope (const MInt cellId, MInt const varId, const MInt dir) const
 Returns the slope of the cell cellId for the variable varId in direction dir. More...
 
MFloata_storedSlope (const MInt cellId, MInt const varId, const MInt dir)
 Returns the stored slope of the cell cellId for the variable varId in direction dir. More...
 
MFloat a_storedSlope (const MInt cellId, MInt const varId, const MInt dir) const
 Returns the stored slope of the cell cellId for the variable varId in direction dir. More...
 
MFloata_rightHandSide (const MInt cellId, MInt const varId)
 Returns the right hand side of the cell cellId for the variable varId. More...
 
MFloat a_rightHandSide (const MInt cellId, MInt const varId) const
 Returns the right hand side of the cell cellId for the variable varId. More...
 
MInt a_noSurfaces ()
 Returns the number of surfaces. More...
 
MInta_surfaceBndryCndId (const MInt srfcId)
 Returns the boundary condition of surface srfcId. More...
 
MInt a_surfaceBndryCndId (const MInt srfcId) const
 Returns the boundary condition of surface srfcId. More...
 
MInta_surfaceOrientation (const MInt srfcId)
 Returns the orientation of surface srfcId. More...
 
MInt a_surfaceOrientation (const MInt srfcId) const
 Returns the orientation of surface srfcId. More...
 
MFloata_surfaceArea (const MInt srfcId)
 Returns the area of surface srfcId. More...
 
MFloat a_surfaceArea (const MInt srfcId) const
 Returns the area of surface srfcId. More...
 
MFloata_surfaceFactor (const MInt srfcId, const MInt varId)
 Returns the factor of surface srfcId for variable varId. More...
 
MFloat a_surfaceFactor (const MInt srfcId, const MInt varId) const
 Returns the factor of surface srfcId for variable varId. More...
 
MFloata_surfaceCoordinate (const MInt srfcId, const MInt dir)
 Returns the coordinate of surface srfcId in direction dir. More...
 
MFloat a_surfaceCoordinate (const MInt srfcId, const MInt dir) const
 Returns the coordinate of surface srfcId in direction dir. More...
 
MFloata_surfaceDeltaX (const MInt srfcId, const MInt varId)
 Returns the delta X of surface srfcId for variable varId. More...
 
MFloat a_surfaceDeltaX (const MInt srfcId, const MInt varId) const
 Returns the delta X of surface srfcId for variable varId. More...
 
MInta_surfaceNghbrCellId (const MInt srfcId, const MInt dir)
 Returns the neighbor cell id of surface srfcId in direction dir. More...
 
MInt a_surfaceNghbrCellId (const MInt srfcId, const MInt dir) const
 Returns the neighbor cell id of surface srfcId in direction dir. More...
 
MFloata_surfaceVariable (const MInt srfcId, const MInt dir, const MInt varId)
 Returns the variable varId of surface srfcId in direction dir. More...
 
MFloat a_surfaceVariable (const MInt srfcId, const MInt dir, const MInt varId) const
 Returns the variable varId of surface srfcId in direction dir. More...
 
MFloata_surfaceUpwindCoefficient (const MInt srfcId)
 Returns the upwind coefficient of surface srfcId. More...
 
MFloat a_surfaceUpwindCoefficient (const MInt srfcId) const
 Returns the upwind coefficient of surface srfcId. More...
 
MFloata_surfaceCoefficient (const MInt srfcId, const MInt dimCoefficient)
 Returns the coefficient dimCoefficient of surface srfcId. More...
 
MFloat a_surfaceCoefficient (const MInt srfcId, const MInt dimCoefficient) const
 Returns the coefficient dimCoefficient of surface srfcId. More...
 
MFloata_surfaceFlux (const MInt srfcId, const MInt fVarId)
 Returns the flux fVarId for surface srfcId. More...
 
MFloat a_surfaceflux (const MInt srfcId, const MInt fVarId) const
 Returns the flux fVarId for surface srfcId. More...
 
MFloata_Ma ()
 Returns the Mach number of the solver. More...
 
const MFloata_Ma () const
 Returns the Mach number of the solver. More...
 
MFloata_cfl ()
 Returns the cfl number of the solver. More...
 
const MFloata_cfl () const
 
MInta_restartInterval ()
 Returns the restart interval of the solver. More...
 
const MInta_restartInterval () const
 Returns the restart interval of the solver. More...
 
MInta_bndryCndId (MInt bndryId)
 Return BndryCndId. More...
 
const MInta_bndryCndId (MInt bndryId) const
 Return BndryCndId. More...
 
MFloata_bndryNormal (MInt bndryId, MInt dir)
 Return normal direction of bndry srfc. More...
 
const MFloata_bndryNormal (MInt bndryId, MInt dir) const
 Return normal direction of bndry srfc. More...
 
MFloata_bndryCutCoord (MInt bndryId, MInt i, MInt j)
 Return cut coordinates of bndry srfc. More...
 
const MFloata_bndryCutCoord (MInt bndryId, MInt i, MInt j) const
 Return cut coordinates of bndry srfc. More...
 
const MInta_bndryGhostCellId (const MInt bndryId, const MInt srfc) const
 
MInta_identNghbrId (MInt nghbrId)
 Return ident nghbr Id. More...
 
const MInta_identNghbrId (MInt nghbrId) const
 Return ident nghbr Id. More...
 
MInta_storeNghbrId (MInt nghbrId)
 Return store nghbr Id. More...
 
const MInta_storeNghbrId (MInt nghbrId) const
 Return store nghbr Id. More...
 
MFloata_VVInfinity (MInt dir)
 Return mean flow velocity. More...
 
const MFloata_VVInfinity (MInt dir) const
 Return mean flow velocity. More...
 
MFloata_rhoInfinity ()
 Return rho infinity. More...
 
const MFloata_rhoInfinity () const
 Return rho infinity. More...
 
MFloata_PInfinity ()
 Return p infinity. More...
 
const MFloata_PInfinity () const
 Return p infinity. More...
 
MFloata_TInfinity ()
 Return T infinity. More...
 
const MFloata_TInfinity () const
 Return T infinity. More...
 
MFloata_timeRef ()
 Return time reference value. More...
 
const MFloata_timeRef () const
 Return time reference value. More...
 
MInta_noPart (MInt cellId)
 Return no particles. More...
 
const MInta_noPart (MInt cellId) const
 Return no particles. More...
 
MFloata_physicalTime ()
 Return physical time. More...
 
const MFloata_physicalTime () const
 Return physical time. More...
 
MFloata_time ()
 Return time. More...
 
const MFloata_time () const
 Return time. More...
 
MFloata_externalSource (MInt cellId, MInt var)
 Return external source. More...
 
const MFloata_externalSource (MInt cellId, MInt var) const
 Return external source. More...
 
MInta_maxLevelWindowCells (MInt domain, MInt id)
 Return max level window cells. More...
 
const MInta_maxLevelWindowCells (MInt domain, MInt id) const
 Return max level window cells. More...
 
MInta_maxLevelHaloCells (MInt domain, MInt id)
 Return max level halo cells. More...
 
const MInta_maxLevelHaloCells (MInt domain, MInt id) const
 Return max level halo cells. More...
 
MFloata_localTimeStep (const MInt cellId)
 Returns the local time-step of the cell cellId. More...
 
MFloat a_localTimeStep (const MInt cellId) const
 Returns the local time-step of the cell cellId. More...
 
MFloat a_dynViscosity (const MFloat T) const
 
MFloata_levelSetFunction (const MInt cellId, const MInt set)
 Returns the levelSet-value for fv-CellId cellId and set. More...
 
MFloat a_levelSetFunction (const MInt cellId, const MInt set) const
 Returns the levelSet-value for fv-CellId cellId and set. More...
 
MFloata_levelSetValuesMb (const MInt cellId, const MInt set)
 Returns the levelSetMb-value for fv-CellId cellId and set. More...
 
MFloat a_levelSetValuesMb (const MInt cellId, const MInt set) const
 Returns the levelSetMb-value for fv-CellId cellId and set. More...
 
MFloat a_alphaGas (const MInt cellId) const
 
MFloata_alphaGas (const MInt cellId)
 
MFloat a_uOtherPhase (const MInt cellId, const MInt dir) const
 
MFloata_uOtherPhase (const MInt cellId, const MInt dir)
 
MFloat a_uOtherPhaseOld (const MInt cellId, const MInt dir) const
 
MFloata_uOtherPhaseOld (const MInt cellId, const MInt dir)
 
MFloat a_gradUOtherPhase (const MInt cellId, const MInt uDir, const MInt gradDir) const
 
MFloata_gradUOtherPhase (const MInt cellId, const MInt uDir, const MInt gradDir)
 
MFloat a_vortOtherPhase (const MInt cellId, const MInt dir) const
 
MFloata_vortOtherPhase (const MInt cellId, const MInt dir)
 
MFloat a_nuTOtherPhase (const MInt cellId) const
 
MFloata_nuTOtherPhase (const MInt cellId)
 
MFloat a_nuEffOtherPhase (const MInt cellId) const
 
MFloata_nuEffOtherPhase (const MInt cellId)
 
MInta_associatedBodyIds (const MInt cellId, const MInt set)
 Returns the associatedBodyIds for fv-CellId cellId and set. More...
 
MInt a_associatedBodyIds (const MInt cellId, const MInt set) const
 Returns the associatedBodyIds for fv-CellId cellId and set. More...
 
MFloata_curvatureG (const MInt cellId, const MInt set)
 Returns the curvature-value for fv-CellId cellId and set. More...
 
MFloat a_curvatureG (const MInt cellId, const MInt set) const
 Returns the curvature-value for fv-CellId cellId and set. More...
 
MFloata_flameSpeed (const MInt cellId, const MInt set)
 Returns the flamespeed-value for fv-CellId cellId and set. More...
 
MFloat a_flameSpeed (const MInt cellId, const MInt set) const
 Returns the flamespeed-value for fv-CellId cellId and set. More...
 
MInta_noSets ()
 Returns the noSets for fv-CellId cellId and set. More...
 
MInt a_noSets () const
 Returns the noSets for fv-CellId cellId and set. More...
 
MInta_noLevelSetFieldData ()
 Returns the noSets for fv-CellId cellId and set. More...
 
MInt a_noLevelSetFieldData () const
 Returns the noSets for fv-CellId cellId and set. More...
 
const MIntgetAssociatedInternalCell (const MInt &cellId) const
 Returns the Id of the split cell, if cellId is a split child. More...
 
virtual void reIntAfterRestart (MBool)
 
virtual void resetRHS ()
 
virtual void resetRHSCutOffCells ()
 
virtual void initSolutionStep (MInt)
 Initializes the solver. More...
 
virtual void applyInitialCondition ()
 Initializes the entire flow field. More...
 
virtual void Ausm ()
 Dispatches the AUSM flux computation for different number of species. More...
 
virtual void Muscl (MInt=-1)
 Reconstructs the flux on the surfaces. More...
 
virtual void viscousFlux ()
 
virtual void copyVarsToSmallCells ()
 
virtual void computePV ()
 
virtual void computePrimitiveVariables ()
 Dispatches the computation of the primitive variables for different number of species. More...
 
virtual void filterConservativeVariablesAtFineToCoarseGridInterfaces ()
 
virtual void copyRHSIntoGhostCells ()
 
virtual void LSReconstructCellCenter_Boundary ()
 Computes the slopes at the cell centers of only the boundary cells. More...
 
virtual void LSReconstructCellCenter ()
 Dispatch the reconstruction computation to the appropiate loop. More...
 
virtual void applyBoundaryCondition ()
 handles the application of boundary conditions to the ghost cells More...
 
virtual void cutOffBoundaryCondition ()
 
virtual void computeConservativeVariables ()
 Dispatches the computation of the conservative variables for different number of species. More...
 
virtual void initNearBoundaryExchange (const MInt mode=0, const MInt offset=0)
 Setup the near-boundary communicator needed for the flux-redistribution method. More...
 
void initAzimuthalNearBoundaryExchange (MIntScratchSpace &activeFlag)
 
void azimuthalNearBoundaryExchange ()
 
void azimuthalNearBoundaryReverseExchange ()
 
void setActiveFlag (MIntScratchSpace &, const MInt mode, const MInt offset)
 Set the flag for the cells needed for near bndry exchange. More...
 
virtual void setAdditionalActiveFlag (MIntScratchSpace &)
 
void setInfinityState ()
 Computes/defines the infinity values/state once and for all Ideally the infinity variables should not be updated outside of this function! More...
 
void initAzimuthalCartesianHaloInterpolation ()
 
void computeSurfaceCoefficients ()
 Dispatches the transport coefficients computation at each surfaces by calling the relevant function from the detChemSysEqn class. Distinction between "Multi" and "Mix" transport models! Author: Borja Pedro. More...
 
void computeSpeciesReactionRates ()
 Dispatches the species reaction rate computation at each cell by calling the relevant method from the detChemSysEqn class. Author: Borja Pedro. More...
 
void computeMeanMolarWeights_PV ()
 Dispatches the mean molar weight computation at the cell center from the primitive variables by calling the relevant function from the detChemSysEqn class. The mean molar weight is stored inside the additional variables array. Author: Borja Pedro. More...
 
void computeMeanMolarWeights_CV ()
 Dispatches the mean molar weight computation at the cell center from the conservative variables by calling the relevant function from the detChemSysEqn class. The mean molar weight is stored inside the additional variables array. Author: Borja Pedro. More...
 
void setMeanMolarWeight_CV (MInt cellId)
 Computes the mean molar weight at the given cell ID from the primitive variables. The mean molar weight is stored inside the additional variables array. Author: Borja Pedro. More...
 
void setMeanMolarWeight_PV (MInt cellId)
 
void computeGamma ()
 Dispatches the gamma computation at each cell by calling the relevant function from the detChemSysEqn class. It is stored inside the additional variables array, and used to compute the time step. Author: Borja Pedro. More...
 
void computeDetailedChemistryVariables ()
 
void setAndAllocateDetailedChemistryProperties ()
 
void initCanteraObjects ()
 Allocates the Cantera objects that define a thermodynamic phase, reaction kinetics and transport properties for a given reaction mechanism. More...
 
void correctMajorSpeciesMassFraction ()
 Corrects the mass fraction of the predominant species to ensure conservation due to numerical or approximation erros For combustion with air: N2 is the major species Author: Borja Pedro. More...
 
void compute1DFlameSolution ()
 
void addSpeciesReactionRatesAndHeatRelease ()
 
void initHeatReleaseDamp ()
 
void computeAcousticSourceTermQe (MFloatScratchSpace &, MFloatScratchSpace &, MFloatScratchSpace &, MFloatScratchSpace &)
 
void computeVolumeForces ()
 
void computeRotForces ()
 
virtual MInt getAdjacentLeafCells_d0 (const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
 
virtual MInt getAdjacentLeafCells_d1 (const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
 
virtual MInt getAdjacentLeafCells_d2 (const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
 
virtual MInt getAdjacentLeafCells_d0_c (const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
 
virtual MInt getAdjacentLeafCells_d1_c (const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
 
virtual MInt getAdjacentLeafCells_d2_c (const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
 
MFloat computeRecConstSVD (const MInt cellId, const MInt offset, MFloatScratchSpace &tmpA, MFloatScratchSpace &tmpC, MFloatScratchSpace &weights, const MInt recDim, const MInt, const MInt, const std::array< MBool, nDim > dirs={}, const MBool relocateCenter=false)
 compute the reconstruction constants of the given cell by a weighted least-squares approach via singular value decomposition More...
 
void extendStencil (const MInt)
 extend the reconstruction sencil towards all diagonal cells on the first layer More...
 
MInt samplingInterval ()
 
void checkGhostCellIntegrity ()
 Checks whether cells' isGhost and the boundary Id coincede. Cells' isGhost is is used to tell the grid about ghost cells. In the solver sometimes boundaryId == -2 is used to check for ghost cells. More...
 
virtual void initializeRungeKutta ()
 Reads the Runge-Kutta properties and initializes the variables required for Runge Kutta time stepping. More...
 
virtual void initializeMaxLevelExchange ()
 parallel: Store all necessary data in send buffer More...
 
virtual void computePrimitiveVariablesCoarseGrid ()
 Computes the primitive variables: velocity, density, and pressure from the conservative variables and stores the primitive variables in a_pvariable( i , v ) More...
 
void initAzimuthalMaxLevelExchange ()
 
void finalizeMpiExchange ()
 Finalize non-blocking MPI communication (cancel open requests, free all requests) More...
 
void setUpwindCoefficient ()
 
void cellSurfaceMapping ()
 
void interpolateSurfaceDiffusionFluxOnCellCenter (MFloat *const, MFloat *const)
 
void interpolateSurfaceDiffusionFluxOnCellCenter (MFloat *const NotUsed(JA), MFloat *const dtdn)
 
void setNghbrInterface ()
 
void calcLESAverage ()
 
void saveLESAverage ()
 
void loadLESAverage ()
 
void finalizeLESAverage ()
 
MFloat getAveragingFactor ()
 
void saveSpongeData ()
 
void loadSpongeData ()
 
void initSTGSpongeExchange ()
 
void setAndAllocateZonalProperties ()
 
void readPreliminarySTGSpongeData ()
 
void calcPeriodicSpongeAverage ()
 
void exchangeZonalAverageCells ()
 
virtual void initSTGSponge ()
 Initializes zonal exchange arrays. More...
 
virtual void resetZonalLESAverage ()
 Initializes zonal exchange arrays. More...
 
virtual void determineLESAverageCells ()
 
virtual void resetZonalSolverData ()
 
virtual void getBoundaryDistance (MFloatScratchSpace &)
 Get distance to boundary, currently bc 3003. Should be replaced by more precise distance using STL information. More...
 
virtual void nonReflectingBCAfterTreatmentCutOff ()
 
virtual void nonReflectingBCCutOff ()
 
virtual void dqdtau ()
 
virtual bool rungeKuttaStep ()
 Dispatches the RungeKutta method for different number of species. More...
 
virtual void applyExternalSource ()
 Add external sources to the RHS. More...
 
virtual void applyExternalOldSource ()
 
virtual void advanceExternalSource ()
 
void exchangeExternalSources ()
 Exchange external sources. More...
 
void resetExternalSources ()
 Reset external sources. More...
 
MInt setUpBndryInterpolationStencil (const MInt, MInt *, const MFloat *)
 
void deleteSrfcs ()
 Deletes all surfaces existing. More...
 
virtual void resetRHSNonInternalCells ()
 
virtual void correctMasterCells ()
 adds the right hand side of small cells to their corresponding master cells and sets the small cell RHS to zero More...
 
void writeCellData (MInt)
 
virtual void convertPrimitiveRestartVariables ()
 converts the primitive restart variables to a new Mach Number More...
 
void initializeFvCartesianSolver (const MBool *propertiesGroups)
 FV Constructor: reads and allocate properties/variables: More...
 
void copyGridProperties ()
 
void allocateCommunicationMemory ()
 Allocates and initializes send/receive buffers for multiSolver computations. More...
 
void setTestcaseProperties ()
 Reads and initializes properties associated with the physics of the simulation and allocates small arrays of these properties. More...
 
void setSamplingProperties ()
 Reads properties associated with variable sampling. More...
 
void setInputOutputProperties ()
 Reads properties and initializes variables associated with input/output. More...
 
void setNumericalProperties ()
 Reads and initializes properties associated with the numerical method. More...
 
void setAndAllocateCombustionTFProperties ()
 Reads and initializes properties associated with combustion simulations. More...
 
void setAndAllocateSpongeLayerProperties ()
 Reads and initializes properties associated with sponge boundary conditions. More...
 
void allocateAndInitSolverMemory ()
 Allocates the resources of the FV solver. Mostly arrays of size maxNoCells used in the main part of the FV code plus - if required - moving grid arrays. IMPORTANT: This method should be called at the end of the FvCartesianSolver-Constructor, since other properties might be used in here, or datastructures previosly allocated might be referenced! More...
 
void setRungeKuttaProperties ()
 This function reads the properties required for Runge Kutta time stepping. More...
 
void setAndAllocateAdaptationProperties ()
 This function reads the properties required for adaptive mesh refinement. More...
 
virtual void exchange ()
 
void exchangeDataFV (T *data, const MInt blockSize=1, MBool cartesian=true, const std::vector< MInt > &rotIndex=std::vector< MInt >())
 
void exchangeFloatDataAzimuthal (MFloat *data, MInt noVars, const std::vector< MInt > &rotIndices)
 
void exchangeDataAzimuthal (T *data, const MInt dataBlockSize=1)
 
void exchangeAzimuthalRemappedHaloCells ()
 
virtual void exchangePeriodic ()
 
void exchangePipe ()
 
void startMpiExchange ()
 Begin non-blocking communication by posting new send requests. More...
 
void prepareMpiExchange ()
 
void finishMpiExchange ()
 Finish non-blocking communication by waiting for receive requests. More...
 
void cancelMpiRequests () override
 Cancel open MPI (receive) requests. More...
 
void gather ()
 Gather data of all window cells for all neighbors in the send buffers. More...
 
void receive (const MBool exchangeAll=false)
 Receive halo cell data from corresponding neighbors. More...
 
void send (const MBool exchangeAll=false)
 Send window cell data to corresponding neighbors. More...
 
void scatter ()
 Scatter received data of all neighbors to the corresponding halo cells. More...
 
void exchangeAll ()
 
virtual void computeReconstructionConstants ()
 
virtual void findNghbrIds ()
 
void getPrimitiveVariables (MInt, MFloat *, MFloat *, MInt)
 
void rhs ()
 
void rhsBnd ()
 
void initSolver () override
 Initializes the fv-solver. More...
 
void finalizeInitSolver () override
 Initializes the solver afer the initialRefinement! More...
 
void preSolutionStep (MInt) override
 
MBool solutionStep () override
 Performs one Runge-Kutta step of the FV solver, returns true if the time step is completed. More...
 
MBool postSolutionStep () override
 
MBool solverStep ()
 
void postTimeStep () override
 : Performs the post time step More...
 
void scalarLimiter ()
 
void cleanUp () override
 
void lhsBndFinish ()
 Finish the split MPI communication and perform the left out part from lhsBnd(). More...
 
void lhsBnd ()
 Apply lhsBnd. More...
 
virtual void smallCellCorrection (const MInt timerId=-1)
 Flux-redistribution method Apply a stable correction to small-cells and redistribute the defective flux to neighboring cells to re-establish conservation For details see Schneiders,Hartmann,Meinke,Schröder, J.Comput.Phys. 235 (2013) For more details see the dissertation of Lennart Schneiders, "Particle-Resolved Analysis of Turbulent Multiphase Flow by a Cut-Cell Method" Chapter 3.4. More...
 
virtual void smallCellRHSCorrection (const MInt timerId=-1)
 
virtual void updateSplitParentVariables ()
 
virtual void checkDiv ()
 
virtual void updateMaterialNo ()
 
void initSourceCells ()
 
void revertTimestep ()
 
void rhsEEGas ()
 
virtual void resetImplicitCoefficients ()
 
MFloat physicalTime ()
 
MFloat computeDomainLength (MInt direction)
 
const Geomgeometry () const
 the references to CartesianGrid data members end here More...
 
MPI_Comm globalMpiComm () const
 Return the global MPI communicator used by the grid. More...
 
void createGridSlice (const MString &direction, const MFloat intercept, const MString &fileName, MInt *const sliceCellIds)
 
MInt noVariables () const override
 Return the number of primitive variables. More...
 
void releaseMemory ()
 
constexpr MBool isMultilevel () const
 Return true if solver is part of a multilevel computation. More...
 
constexpr MBool isMultilevelPrimary () const
 Return true if solver is primary solver in multilevel computation. More...
 
constexpr MBool isMultilevelLowestSecondary () const
 
void setMultilevelPrimary (const MBool state=true)
 Designates solver as primary solver in multilevel computation. More...
 
void setMultilevelSecondary (const MBool state=true)
 
constexpr MBool isZonal () const
 
void loadSampleVariables (MInt timeStep)
 load variables for the specified timeStep More...
 
void getSampleVariables (MInt cellId, const MFloat *&vars)
 read only access to primitive variables of a single cell More...
 
void getSampleVariables (MInt const cellId, std::vector< MFloat > &vars)
 
void getSampleVariableNames (std::vector< MString > &varNames) override
 Return the sample variable names (primitive variables) More...
 
virtual void getSampleVarsDerivatives (const MInt cellId, const MFloat *&vars)
 Access derivatives of primitive variables of a given cell. More...
 
MBool getSampleVarsDerivatives (const MInt cellId, std::vector< MFloat > &vars)
 
void calculateHeatRelease ()
 calculates heatRelease, currently used for postprocessing (average_in) More...
 
void getHeatRelease (MFloat *&heatRelease)
 returns More...
 
virtual void getVorticity (MFloat *const vorticity)
 wrapper for vorticity computation More...
 
virtual void getVorticityT (MFloat *const vorticity)
 wrapper for vorticity computation (transposed version) More...
 
void oldPressure (MFloat *const p)
 This function computes the pressure from the oldVariables. More...
 
virtual MFloatvorticityAtCell (const MInt cellId, const MInt dir)
 
virtual MFloat getBoundaryHeatFlux (const MInt cellId) const
 calculates heat flux of boundary cells More...
 
MFloat time () const override
 returns the time More...
 
virtual void getDimensionalizationParams (std::vector< std::pair< MFloat, MString > > &dimParams) const
 get dimensionalization parameters More...
 
MInt getCellIdByIndex (const MInt index)
 Required for sampling, for FV the index is already the cell id. More...
 
MInt getIdAtPoint (const MFloat *point, MBool NotUsed(globalUnique=false))
 Return the leaf cell id containing the given point. More...
 
virtual void getSolverSamplingProperties (std::vector< MInt > &samplingVars, std::vector< MInt > &noSamplingVars, std::vector< std::vector< MString > > &samplingVarNames, const MString featureName="") override
 Read sampling related properties. More...
 
virtual void initSolverSamplingVariables (const std::vector< MInt > &varIds, const std::vector< MInt > &noSamplingVars) override
 Initialize sampling variables/allocate memory. More...
 
virtual void calcSamplingVariables (const std::vector< MInt > &varIds, const MBool exchange) override
 Calculate sampling variables. More...
 
virtual void initInterpolationForCell (const MInt cellId)
 Init the interpolation for points inside a given cell (based on interpolateVariables()) More...
 
virtual void calcSamplingVarAtPoint (const MFloat *point, const MInt id, const MInt sampleVarId, MFloat *state, const MBool interpolate=false) override
 Calculate the sampling variables at a given point in a cell. More...
 
MInt getCurrentTimeStep () const override
 Return the current time step. More...
 
MBool hasRestartTimeStep () const override
 
MInt determineRestartTimeStep () const override
 Determine the restart time step from the restart file (for useNonSpecifiedRestartFile = true) More...
 
virtual void finalizeInitEnthalpySolver ()
 
virtual void initMatDat ()
 
virtual void writeVtkXmlFiles (const MString, const MString, MBool, MBool)
 
MBool calcSlopesAfterStep ()
 Return if slopes should be calculated at after each step (not before) More...
 
void applyCoarseLevelCorrection ()
 Apply coarse-level correction to RHS. More...
 
void setAndAllocateCombustionGequPvProperties ()
 reads in the combustion properties More...
 
void setAndAllocateSpongeBoundaryProperties ()
 reads in the sponge properties for specific boundaries More...
 
MFloat setAndAllocateSpongeDomainProperties (MFloat)
 reads in the sponge properties for the domain boundaries More...
 
void setCombustionGequPvVariables ()
 reads in the combustion properties More...
 
MInt noSolverTimers (const MBool allTimings) override
 
void getSolverTimings (std::vector< std::pair< MString, MFloat > > &solverTimings, const MBool allTimings) override
 Get solver timings. More...
 
void limitWeights (MFloat *) override
 Limit Weight types to avoid large memory disbalance between ranks for DLB. More...
 
MInt noCellDataDlb () const override
 Methods to inquire solver data information. More...
 
MInt cellDataTypeDlb (const MInt dataId) const override
 
MInt cellDataSizeDlb (const MInt dataId, const MInt gridCellId) override
 Return data size to be communicated during DLB for a grid cell and given data id. More...
 
void getCellDataDlb (const MInt dataId, const MInt oldNoCells, const MInt *const bufferIdToCellId, MFloat *const data) override
 Return solver data for DLB. More...
 
void setCellDataDlb (const MInt dataId, const MFloat *const data) override
 Set solver data for DLB. More...
 
void getGlobalSolverVars (std::vector< MFloat > &globalFloatVars, std::vector< MInt > &globalIdVars) override
 Get/set global solver variables during DLB. More...
 
void setGlobalSolverVars (std::vector< MFloat > &globalFloatVars, std::vector< MInt > &globalIdVars) override
 Set global solver variables (see getGlobalSolverVars()) More...
 
MBool hasSplitBalancing () const override
 Return if load balancing for solver is split into multiple methods or implemented in balance() More...
 
virtual MBool adaptationTrigger ()
 
MBool forceAdaptation () override
 
void bubblePathDispersion ()
 
void computePrimitiveVariablesCoarseGrid (MInt)
 Computes the primitive variables: velocity, density, and pressure from the conservative variables and stores the primitive variables in a_pvariable( i , v ) More...
 
void forceTimeStep (const MFloat dt)
 Force time step externally. More...
 
MInt a_timeStepComputationInterval ()
 
void preTimeStep () override
 
void computeVolumeForcesRANS ()
 
void exchangeGapInfo ()
 exchanges the Gap-Information with the solver-own communicators! More...
 
void resetCutOffCells ()
 resets all Cut-Off Information should only be called before the adaptation and balance! More...
 
void resetSponge ()
 reset sponge properties More...
 
void exchangeProperties ()
 exchanges isInactive and isOnCurrentMGLevel More...
 
void computeUTau (MFloat *data, MInt cellId)
 
void computeDomainAndSpongeDimensions ()
 Extracts the minimum and maximum coordinates of all cells in the grid. More...
 
std::array< MFloat, 6 > computeTargetValues ()
 
std::array< MFloat, nDim_+2 > computeSpongeDeltas (MInt cellId, std::array< MFloat, 6 >)
 
void updateSpongeLayerRhs (MInt, std::array< MFloat, nDim_+2 >)
 
void checkCells ()
 
void checkForSrfcsMGC ()
 Check all existing cells if surfaces have to be created member function with the task to check all existing cells for the creation of surfaces. If a surface has to be created, another member function is called. More...
 
void checkForSrfcsMGC_2 ()
 
void checkForSrfcsMGC_2_ ()
 Check all existing cells if surfaces have to be created member function with the task to check all existing cells for the creation of surfaces. If a surface has to be created, another member function is called. More...
 
void computeSrfcs (MInt, MInt, MInt, MInt)
 
virtual void correctBoundarySurfaces ()
 
virtual void correctBoundarySurfaces_ ()
 
void checkCellSurfaces ()
 checks if the surfaces for a cell are correct and balanced The accumulated cell surfaces in +x direction must be balanced by the accumulated cell surfaces in -x direction and so on. If the surfaces are not balanced, the cell is loggd to the debug output method is not yet extended to moving boundary computations More...
 
void computeCellSurfaceDistanceVectors ()
 
void computeReconstructionConstantsSVD ()
 Compute the reconstruction constants using a weighted least squares approached solved via singular value decomposition. More...
 
void setConservativeVarsOnAzimuthalRecCells ()
 
void initAzimuthalReconstruction ()
 
void rebuildAzimuthalReconstructionConstants (MInt cellId, MInt offset, MFloat *recCoord, MInt mode=0)
 
void interpolateAzimuthalData (MFloat *data, MInt offset, MInt noVars, const MFloat *vars)
 
void fillExcBufferAzimuthal (MInt cellId, MInt offset, MFloat *dataDest, MFloat *dataSrc, MInt noData, const std::vector< MInt > &rotIndex=std::vector< MInt >())
 
void rotateVectorAzimuthal (MInt side, MFloat *data, MInt noData, const std::vector< MInt > &indices)
 
void interpolateAzimuthalDataReverse (MFloat *data, MInt offset, MInt noVars, const MFloat *vars)
 
void checkAzimuthalRecNghbrConsistency (MInt cellId)
 
void buildLeastSquaresStencilSimple ()
 Determine the least squares stencil. More...
 
void initViscousFluxComputation ()
 
void computeRecConstPeriodic ()
 
void computeRecConstPeriodic_ ()
 
void identPeriodicCells ()
 
void identPeriodicCells_ ()
 
 ATTRIBUTES2 (ATTRIBUTE_ALWAYS_INLINE, ATTRIBUTE_HOT) inline void LSReconstructCellCenter_(const MUint noSpecies)
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_FLATTEN) virtual void computeSurfaceValues(MInt timerId
 
 ATTRIBUTES2 (ATTRIBUTE_ALWAYS_INLINE, ATTRIBUTE_HOT) inline void computeSurfaceValues_(const MUint)
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_FLATTEN) virtual void computeSurfaceValuesLimited(MInt timerId
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_ALWAYS_INLINE) inline void computePrimitiveVariables_()
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_ALWAYS_INLINE) inline MBool uDLimiter(const MFloat *const
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_ALWAYS_INLINE) inline void computeConservativeVariables_()
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_ALWAYS_INLINE) inline MBool rungeKuttaStep_(const MUint)
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_ALWAYS_INLINE) inline MBool rungeKuttaStepEEGas()
 
void LSReconstructCellCenterCons (const MUint noSpecies)
 
virtual void computeSurfaceValuesLOCD (MInt timerId=-1)
 
virtual void computeLimitedSurfaceValues (MInt timerId=-1)
 
virtual void computeSurfaceValuesLimitedSlopes (MInt timerId=-1)
 
virtual void computeSurfaceValuesLimitedSlopesMan (MInt timerId=-1)
 aaplies the slope limiter to the slopes before calling computeSurfaceValues_ More...
 
virtual void initComputeSurfaceValuesLimitedSlopesMan1 ()
 initializes the limiter at cells, that are in the vicinity of a given stl-geometry More...
 
virtual void initComputeSurfaceValuesLimitedSlopesMan2 ()
 can be used to apply the slope limiter at certain positions such as refinement interfaces, cut off boundaries(sponge) etc. ... More...
 
void computeGridCellCoordinates (MFloat *)
 computes the coordinates of the grid cell centers and stores them into a one-dimensional array More...
 
void findNghbrIdsMGC ()
 
void findDirectNghbrs (MInt cellId, std::vector< MInt > &nghbrList)
 Obtain list of direct neighbors of given cell. More...
 
void findNeighborHood (MInt cellId, MInt layer, std::vector< MInt > &nghbrList)
 Obtain list of neighbors for the given extend. More...
 
void refineCell (const MInt) override
 
void removeChilds (const MInt) override
 
void removeCell (const MInt) override
 Remove the given cell. More...
 
void swapCells (const MInt, const MInt) override
 
void resizeGridMap () override
 Swap the given cells. More...
 
void swapProxy (const MInt, const MInt) override
 
MBool cellOutside (const MInt)
 
MInt cellOutside (const MFloat *, const MInt, const MInt) override
 
virtual void resetBoundaryCells (const MInt offset=0)
 
void reInitActiveCellIdsMemory ()
 Allocate memory to arrays according to the current number of cells. More...
 
void reInitSmallCellIdsMemory ()
 Reallocate memory to small and master cell id arrays according to the current number of cells. More...
 
void prepareAdaptation () override
 
void setSensors (std::vector< std::vector< MFloat > > &sensors, std::vector< MFloat > &sensorWeight, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MInt > &sensorSolverId) override
 set the sensors for the adaptation (i.e. which cell should be refined/removed?) More...
 
void postAdaptation () override
 
void finalizeAdaptation () override
 
void sensorInterface (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 
void sensorInterfaceDelta (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
void sensorInterfaceLsMb (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
void sensorInterfaceLs (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
void sensorCutOff (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
void sensorPatch (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 
void bandRefinementSensorDerivative (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, MInt sensorOffset, MInt sen, const std::vector< MFloat > &tau, const MFloat sensorThreshold)
 
void resetSolver () override
 Reset the solver prior to load balancing. More...
 
void setCellWeights (MFloat *) override
 
void balance (const MInt *const noCellsToReceiveByDomain, const MInt *const noCellsToSendByDomain, const MInt *const targetDomainsByCell, const MInt oldNoCells) override
 Balance the solver. More...
 
void balancePre () override
 Reinitialize solver for DLB prior to setting solution data. More...
 
void balancePost () override
 Reinitialize solver after setting solution data in DLB. More...
 
void finalizeBalance () override
 Reinitialize solver after all data structures have been recreated. More...
 
MInt noLoadTypes () const override
 
void getDefaultWeights (MFloat *weights, std::vector< MString > &names) const
 Return the default weights for all load quantities. More...
 
void getLoadQuantities (MInt *const loadQuantities) const override
 Return the cumulative load quantities on this domain. More...
 
MFloat getCellLoad (const MInt cellId, const MFloat *const weights) const override
 Return the load of a single cell (given computational weights). More...
 
void getDomainDecompositionInformation (std::vector< std::pair< MString, MInt > > &domainInfo) override
 Return decomposition information, i.e. number of local elements,... More...
 
void saveSolverSolution (const MBool forceOutput=false, const MBool finalTimeStep=false) override
 Manages solver-specific output. More...
 
void writeRestartFile (const MBool, const MBool, const MString, MInt *) override
 
void writeRestartFile (MBool) override
 
MBool prepareRestart (MBool, MBool &) override
 Prepare the solvers for a grid-restart. More...
 
void saveSampleFiles ()
 
void saveDebugRestartFile ()
 Saves the solver restart file and the grid restartFile NOTE: for debugging purposes only! for regular output use the saveRestartFile above! More...
 
void loadRestartFile () override
 
More...
 
void computeConservativeVariablesCoarseGrid ()
 Computes the primitive variables: velocity, density, and pressure from the conservative variables and stores the primitive variables in a_pvariable( i , v ) More...
 
void writeCenterLineVel ()
 
void computeForceCoefficients (MFloat *)
 
void checkInfinityVarsConsistency ()
 Check that all infinity (or other global) variables are equal on all ranks. More...
 
void computeInitialPressureLossForChannelFlow ()
 Computes pressure loss for the initial condition of channel flow testcases as \Delta_p = \frac{(\mathit{M} \mathit{Re}_{\tau} \sqrt{T_{\infty}})^{2}}{\mathit{Re}} \frac{\rho_{\infty}}{ L_{\infty} } . Requires property ReTau to be set in the property file. More...
 
void Ausm_ (F &fluxFct)
 
void viscousFlux_ (F &viscousFluxFct)
 Computes the viscous flux using a central difference scheme to approximate the slopes at the surface centroids (5-point stencil). More...
 
void viscousFluxCompact_ (F &viscousFluxFct)
 Computes the viscous fluxes using a compact stencil with increased stability for flows with dominating viscous effects. Uses a 3-point centered-differences stencil for the normal derivative and distance-weighted averaging of the cell slopes for the tangential derivatives (i.e., a variant of the method described by Berger et al. in AIAA 2012-1301) More...
 
void viscousFluxMultiSpecies_ ()
 
void computeConservativeVariablesMultiSpecies_ (const MUint)
 
void computePrimitiveVariablesMultiSpecies_ (const MUint)
 
virtual void distributeFluxToCells ()
 Distributes the surface fluxes to the cell RHS. More...
 
void implicitTimeStep () override
 
void computeCellVolumes ()
 
void computeSamplingTimeStep ()
 
void computeSamplingTimeStep_ ()
 computes the time step according to the sample variables More...
 
void computeCoarseGridCorrection (MInt)
 
void linearInterpolation (MInt, MInt, MInt *)
 
void bilinearInterpolation (MInt, MInt, MInt *)
 
void bilinearInterpolationAtBnd (MInt, MInt, MInt *)
 
void initCutOffBoundaryCondition ()
 
virtual void setConservativeVariables (MInt cellId)
 computes conservative from primitive variables for given cell id More...
 
void setPrimitiveVariables (MInt cellId)
 computes primitive from primitive variables for given cell id. This is the version for all SysEqn. More...
 
void initDepthCorrection ()
 
void divCheck (MInt)
 
MInt getAdjacentLeafCells (const MInt, const MInt, MIntScratchSpace &, MIntScratchSpace &)
 retrieves the first 'noLayers' layers of direct and(or diagonal neighbors to the given cell More...
 
MInt getNghbrLeafCells (const MInt cellId, MInt refCell, MInt layer, MInt *nghbrs, MInt dir, MInt dir1=-1, MInt dir2=-1) const
 returns the neighbor leaf cells in the specified direction 'dir' (dir1 and dir2 are used to identify only neighboring children beeing adjacent to the root cell) More...
 
void reduceVariables ()
 Check whether any of the extracted cells lie below the halo cell level and interpolate their variables in that case. More...
 
void computeSlopesByCentralDifferences ()
 
void generateBndryCells ()
 
void createBoundaryCells ()
 identifies bndry cells (Sets a_isInterface for the solver!) More...
 
void getInterpolatedVariables (const MInt cellId, const MFloat *position, MFloat *vars) override
 calculates interpolated variables for a given position in a given cell More...
 
void getInterpolatedVariables (const MInt cellId, const MFloat *position, MFloat *vars)
 
void getInterpolatedVariablesInCell (const MInt cellId, const MFloat *position, MFloat *vars)
 calculates interpolated variables for a given position in a given cell More...
 
void interpolateVariables (const MInt cellId, const MFloat *position, MFloat *result)
 calculates interpolated variables (in the range a, b) for a given position in a given cell More...
 
void interpolateVariablesInCell (const MInt cellId, const MFloat *position, std::function< MFloat(MInt, MInt)> variables, MFloat *result)
 Interpolate the given variable field inside a cell at a given position (based on interpolateVariables() but uses the stored interpolation information for a cell). More...
 
MFloat crankAngle (const MFloat, const MInt)
 help-function for engine calculations which returns the crank-angle for a given time mode = 0: return CAD in range of (0-720) mode = 1: return accumulated crankAnge in radian More...
 
MFloat cv_p (MInt cellId) const noexcept
 Returns the pressure computed from the conservative variables of the cell cellId. More...
 
MFloat cv_T (MInt cellId) const noexcept
 Returns the temperature computed from the conservative variables of the cell cellId. More...
 
MFloat cv_a (MInt cellId) const noexcept
 Returns the speed-of-sound computed from the conservative variables of the cell cellId. More...
 
void setTimeStep ()
 
void initSandpaperTrip ()
 
void applySandpaperTrip ()
 
void saveSandpaperTripVars ()
 
void tripForceCoefficients (MFloat *, MFloat *, MFloat *, MInt, MInt)
 
void tripFourierCoefficients (MFloat *, MInt, MFloat, MFloat)
 
void dumpCellData (const MString name)
 Dump cell data of each rank to a separate file for debugging purposes. More...
 
- Public Member Functions inherited from maia::CartesianSolver< nDim_, FvCartesianSolverXD< nDim_, SysEqn > >
 CartesianSolver (const MInt solverId, GridProxy &gridProxy_, const MPI_Comm comm, const MBool checkActive=false)
 
MInt minLevel () const
 Read-only accessors for grid data. More...
 
MInt maxLevel () const
 
MInt maxNoGridCells () const
 
MInt maxRefinementLevel () const
 
MInt maxUniformRefinementLevel () const
 
MInt noNeighborDomains () const
 
MInt neighborDomain (const MInt id) const
 
MLong domainOffset (const MInt id) const
 
MInt noHaloLayers () const
 
MInt noHaloCells (const MInt domainId) const
 
MInt haloCellId (const MInt domainId, const MInt cellId) const
 
MInt noWindowCells (const MInt domainId) const
 
MInt windowCellId (const MInt domainId, const MInt cellId) const
 
MString gridInputFileName () const
 
MFloat reductionFactor () const
 
MFloat centerOfGravity (const MInt dir) const
 
MInt neighborList (const MInt cellId, const MInt dir) const
 
const MLonglocalPartitionCellGlobalIds (const MInt cellId) const
 
MLong localPartitionCellOffsets (const MInt index) const
 
MInt noMinCells () const
 
MInt minCell (const MInt id) const
 
const MInthaloCell (const MInt domainId, const MInt cellId) const
 
const MIntwindowCell (const MInt domainId, const MInt cellId) const
 
MBool isActive () const override
 
constexpr GridProxygrid () const
 
GridProxygrid ()
 
virtual void sensorDerivative (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorDivergence (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorTotalPressure (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorEntropyGrad (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorEntropyQuot (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorVorticity (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorInterface (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
void sensorLimit (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt, std::function< MFloat(MInt)>, const MFloat, const MInt *, const MBool, const MBool allowCoarsening=true)
 simple sensor to apply a limit for a value More...
 
void sensorSmooth (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 sensor to smooth level jumps NOTE: only refines additional cells to ensure a smooth level transition this requires that all other sensors are frozen i.e. no refine/coarse sensors set! More...
 
void sensorBand (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 This sensor generates a max refinement band around the cells with max refinement level. In order for it to work, the property addedAdaptationSteps has to be equal to /maxRefinementLevel() - minLevel()/. This sensor also ensures a smooth transition between levels. Do not use together with sensorSmooth. More...
 
virtual void sensorMeanStress (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorParticle (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorSpecies (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
virtual void sensorPatch (std::vector< std::vector< MFloat > > &sensor, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
virtual void sensorCutOff (std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
void saveSensorData (const std::vector< std::vector< MFloat > > &sensors, const MInt &level, const MString &gridFileName, const MInt *const recalcIds) override
 Saves all sensor values for debug/tunig purposes. More...
 
void assertValidGridCellId (const MInt) const
 
MLong c_parentId (const MInt cellId) const
 Returns the grid parent id of the cell cellId. More...
 
MLong c_neighborId (const MInt cellId, const MInt dir) const
 Returns the grid neighbor id of the grid cell cellId dir. More...
 
MInt c_noCells () const
 
MInt c_level (const MInt cellId) const
 
MLong c_globalGridId (const MInt cellId)
 
void exchangeData (T *data, const MInt dataBlockSize=1)
 Exchange memory in 'data' assuming a solver size of 'dataBlockSize' per cell. More...
 
void exchangeLeafData (std::function< T &(MInt, MInt)> data, const MInt noDat=1)
 Blocking exchange memory in 'data' assuming a solver size of 'dataBlockSize' per cell NOTE: exchange is only performed on leaf-cells and leaf-NeighborDomains Assumes, that updateLeafCellExchange has been called in the proxy previously! More...
 
void exchangeSparseLeafValues (G getData, S setData, const MInt dataSize, M cellMapping)
 Exchange of sparse data structures on max Level. More...
 
void exchangeAzimuthalPer (T *data, MInt dataBlockSize=1, MInt firstBlock=0)
 Exchange of sparse data structures on max Level. More...
 
void collectVariables (T *variablesIn, ScratchSpace< T > &variablesOut, const std::vector< MString > &variablesNameIn, std::vector< MString > &variablesNameOut, const MInt noVars, const MInt noCells, const MBool reverseOrder=false)
 generalised helper function for writing restart files! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void collectVariables (T **variablesIn, ScratchSpace< T > &variablesOut, const std::vector< MString > &variablesNameIn, std::vector< MString > &variablesNameOut, const MInt noVars, const MInt noCells)
 generalised helper function for writing restart files! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void saveGridFlowVars (const MChar *fileName, const MChar *gridFileName, const MInt noTotalCells, const MInt noInternal, MFloatScratchSpace &dbVariables, std::vector< MString > &dbVariablesName, MInt noDbVars, MIntScratchSpace &idVariables, std::vector< MString > &idVariablesName, MInt noIdVars, MFloatScratchSpace &dbParameters, std::vector< MString > &dbParametersName, MIntScratchSpace &idParameters, std::vector< MString > &idParametersName, MInt *recalcIds, MFloat time)
 This function writes the parallel Netcdf cartesian grid cell based solution/restart file currently used in PostData, LPT and LS solvers! More...
 
void collectParameters (T, ScratchSpace< T > &, const MChar *, std::vector< MString > &)
 This function collects a single parameters for the massivley parallel IO functions. More...
 
void calcRecalcCellIdsSolver (const MInt *const recalcIdsTree, MInt &noCells, MInt &noInternalCellIds, std::vector< MInt > &recalcCellIdsSolver, std::vector< MInt > &reorderedCellIds)
 Derive recalc cell ids of the solver and reordered cell ids. More...
 
- Public Member Functions inherited from Solver
MString getIdentifier (const MBool useSolverId=false, const MString preString="", const MString postString="_")
 
virtual ~Solver ()=default
 
virtual MInt noInternalCells () const =0
 Return the number of internal cells within this solver. More...
 
virtual MFloat time () const =0
 Return the time. More...
 
virtual MInt noVariables () const
 Return the number of variables. More...
 
virtual void getDimensionalizationParams (std::vector< std::pair< MFloat, MString > > &) const
 Return the dimensionalization parameters of this solver. More...
 
void updateDomainInfo (const MInt domainId, const MInt noDomains, const MPI_Comm mpiComm, const MString &loc)
 Set new domain information. More...
 
virtual MFloata_slope (const MInt, MInt const, const MInt)
 
virtual MBool a_isBndryCell (const MInt) const
 
virtual MFloata_FcellVolume (MInt)
 
virtual MInt getCurrentTimeStep () const
 
virtual void accessSampleVariables (MInt, MFloat *&)
 
virtual void getSampleVariableNames (std::vector< MString > &NotUsed(varNames))
 
virtual MBool a_isBndryGhostCell (MInt) const
 
virtual void saveCoarseSolution ()
 
virtual void getSolverSamplingProperties (std::vector< MInt > &NotUsed(samplingVarIds), std::vector< MInt > &NotUsed(noSamplingVars), std::vector< std::vector< MString > > &NotUsed(samplingVarNames), const MString NotUsed(featureName)="")
 
virtual void initSolverSamplingVariables (const std::vector< MInt > &NotUsed(varIds), const std::vector< MInt > &NotUsed(noSamplingVars))
 
virtual void calcSamplingVariables (const std::vector< MInt > &NotUsed(varIds), const MBool NotUsed(exchange))
 
virtual void calcSamplingVarAtPoint (const MFloat *NotUsed(point), const MInt NotUsed(id), const MInt NotUsed(sampleVarId), MFloat *NotUsed(state), const MBool NotUsed(interpolate)=false)
 
virtual void balance (const MInt *const NotUsed(noCellsToReceiveByDomain), const MInt *const NotUsed(noCellsToSendByDomain), const MInt *const NotUsed(targetDomainsByCell), const MInt NotUsed(oldNoCells))
 Perform load balancing. More...
 
virtual MBool hasSplitBalancing () const
 Return if load balancing for solver is split into multiple methods or implemented in balance() More...
 
virtual void balancePre ()
 
virtual void balancePost ()
 
virtual void finalizeBalance ()
 
virtual void resetSolver ()
 Reset the solver/solver for load balancing. More...
 
virtual void cancelMpiRequests ()
 Cancel open mpi (receive) requests in the solver (e.g. due to interleaved execution) More...
 
virtual void setCellWeights (MFloat *)
 Set cell weights. More...
 
virtual MInt noLoadTypes () const
 
virtual void getDefaultWeights (MFloat *NotUsed(weights), std::vector< MString > &NotUsed(names)) const
 
virtual void getLoadQuantities (MInt *const NotUsed(loadQuantities)) const
 
virtual MFloat getCellLoad (const MInt NotUsed(cellId), const MFloat *const NotUsed(weights)) const
 
virtual void limitWeights (MFloat *NotUsed(weights))
 
virtual void localToGlobalIds ()
 
virtual void globalToLocalIds ()
 
virtual MInt noCellDataDlb () const
 Methods to inquire solver data information. More...
 
virtual MInt cellDataTypeDlb (const MInt NotUsed(dataId)) const
 
virtual MInt cellDataSizeDlb (const MInt NotUsed(dataId), const MInt NotUsed(cellId))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MInt *const NotUsed(data))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MLong *const NotUsed(data))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MFloat *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MInt *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MLong *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MFloat *const NotUsed(data))
 
virtual void getGlobalSolverVars (std::vector< MFloat > &NotUsed(globalFloatVars), std::vector< MInt > &NotUsed(globalIntVars))
 
virtual void setGlobalSolverVars (std::vector< MFloat > &NotUsed(globalFloatVars), std::vector< MInt > &NotUsed(globalIdVars))
 
void enableDlbTimers ()
 
void reEnableDlbTimers ()
 
void disableDlbTimers ()
 
MBool dlbTimersEnabled ()
 
void startLoadTimer (const MString name)
 
void stopLoadTimer (const MString &name)
 
void stopIdleTimer (const MString &name)
 
void startIdleTimer (const MString &name)
 
MBool isLoadTimerRunning ()
 
virtual MInt noSolverTimers (const MBool NotUsed(allTimings))
 
virtual void getSolverTimings (std::vector< std::pair< MString, MFloat > > &NotUsed(solverTimings), const MBool NotUsed(allTimings))
 
virtual void getDomainDecompositionInformation (std::vector< std::pair< MString, MInt > > &NotUsed(domainInfo))
 
void setDlbTimer (const MInt timerId)
 
virtual void prepareAdaptation (std::vector< std::vector< MFloat > > &, std::vector< MFloat > &, std::vector< std::bitset< 64 > > &, std::vector< MInt > &)
 
virtual void reinitAfterAdaptation ()
 
virtual void prepareAdaptation ()
 prepare adaptation for split adaptation before the adaptation loop More...
 
virtual void setSensors (std::vector< std::vector< MFloat > > &, std::vector< MFloat > &, std::vector< std::bitset< 64 > > &, std::vector< MInt > &)
 set solver sensors for split adaptation within the adaptation loop More...
 
virtual void saveSensorData (const std::vector< std::vector< MFloat > > &, const MInt &, const MString &, const MInt *const)
 
virtual void postAdaptation ()
 post adaptation for split adaptation within the adaptation loop More...
 
virtual void finalizeAdaptation ()
 finalize adaptation for split sadptation after the adaptation loop More...
 
virtual void refineCell (const MInt)
 Refine the given cell. More...
 
virtual void removeChilds (const MInt)
 Coarsen the given cell. More...
 
virtual void removeCell (const MInt)
 Remove the given cell. More...
 
virtual void swapCells (const MInt, const MInt)
 Swap the given cells. More...
 
virtual void swapProxy (const MInt, const MInt)
 Swap the given cells. More...
 
virtual MInt cellOutside (const MFloat *, const MInt, const MInt)
 Check whether cell is outside the fluid domain. More...
 
virtual void resizeGridMap ()
 Swap the given cells. More...
 
virtual MBool prepareRestart (MBool, MBool &)
 Prepare the solvers for a grid-restart. More...
 
virtual void reIntAfterRestart (MBool)
 
MPI_Comm mpiComm () const
 Return the MPI communicator used by this solver. More...
 
virtual MInt domainId () const
 Return the domainId (rank) More...
 
virtual MInt noDomains () const
 
virtual MBool isActive () const
 
void setSolverStatus (const MBool status)
 
MBool getSolverStatus ()
 Get the solver status indicating if the solver is currently active in the execution recipe. More...
 
MString testcaseDir () const
 Return the testcase directory. More...
 
MString outputDir () const
 Return the directory for output files. More...
 
MString restartDir () const
 Return the directory for restart files. More...
 
MString solverMethod () const
 Return the solverMethod of this solver. More...
 
MString solverType () const
 Return the solverType of this solver. More...
 
MInt restartInterval () const
 Return the restart interval of this solver. More...
 
MInt restartTimeStep () const
 Return the restart interval of this solver. More...
 
MInt solverId () const
 Return the solverId. More...
 
MBool restartFile ()
 
MInt readSolverSamplingVarNames (std::vector< MString > &varNames, const MString featureName="") const
 Read sampling variables names, store in vector and return the number of sampling variables. More...
 
virtual MBool hasRestartTimeStep () const
 
virtual MBool forceAdaptation ()
 
virtual void preTimeStep ()=0
 
virtual void postTimeStep ()=0
 
virtual void initSolver ()=0
 
virtual void finalizeInitSolver ()=0
 
virtual void saveSolverSolution (const MBool NotUsed(forceOutput)=false, const MBool NotUsed(finalTimeStep)=false)=0
 
virtual void cleanUp ()=0
 
virtual MBool solutionStep ()
 
virtual void preSolutionStep (MInt)
 
virtual MBool postSolutionStep ()
 
virtual MBool solverConverged ()
 
virtual void getInterpolatedVariables (MInt, const MFloat *, MFloat *)
 
virtual void loadRestartFile ()
 
virtual MInt determineRestartTimeStep () const
 
virtual void writeRestartFile (MBool)
 
virtual void writeRestartFile (const MBool, const MBool, const MString, MInt *)
 
virtual void setTimeStep ()
 
virtual void implicitTimeStep ()
 
virtual void prepareNextTimeStep ()
 

Static Public Member Functions

template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
static MInt locatenear (const Point< nDim > &, MFloat, MInt *, MInt, MBool returnCellId=true)
 
static void computeRotationMatrix (MFloatScratchSpace &, MFloat *q)
 rotation matrix co-rotating(~inertial) frame -> body-fixed frame More...
 
static void matrixProduct (MFloatScratchSpace &C, MFloatScratchSpace &A, MFloatScratchSpace &B)
 C=A*B. More...
 
static void matrixProductTranspose (MFloatScratchSpace &C, MFloatScratchSpace &A, MFloatScratchSpace &B)
 C=A*B^t. More...
 
static void matrixProductTranspose2 (MFloatScratchSpace &C, MFloatScratchSpace &A, MFloatScratchSpace &B)
 C=A^t*B. More...
 
static void matrixVectorProduct (MFloat *c, MFloatScratchSpace &A, MFloat *b)
 c=A*b More...
 
static void matrixVectorProductTranspose (MFloat *c, MFloatScratchSpace &A, MFloat *b)
 c=A^t*b More...
 
static void setAdditionalCellProperties ()
 set the properties of cells and determines the state of halo cells More...
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
static MInt writeGeometryToVtkXmlFile (const MString &fileName)
 
static void crossProduct (MFloat *c, MFloat *a, MFloat *b)
 computes the cross product c <- (a x b) for a, b, c in R^3 More...
 
static MFloat CdLaw (MFloat Re)
 
static MFloat distancePointEllipseSpecial (const MFloat e[2], const MFloat y[2], MFloat x[2])
 

Public Attributes

KDtree< nDim > * m_bodyTree = nullptr
 
KDtree< nDim > * m_bodyTreeLocal = nullptr
 
std::vector< Point< nDim > > m_bodyCenters
 
std::vector< Point< nDim > > m_bodyCentersLocal
 
friend FvBndryCndXD< nDim, SysEqn >
 
std::vector< MFloatm_oldBodyPosition
 
std::vector< MFloatm_movingPosDiff
 
MInt m_tCutGroup {}
 
MInt m_tCutGroupTotal {}
 
MBool m_trackMovingBndry {}
 
MBool m_logBoundaryData {}
 
MInt m_motionEquation {}
 
MInt m_movingBndryCndId {}
 
MInt m_loggingInterval {}
 
MInt m_bodySamplingInterval {}
 
MInt m_particleSamplingInterval {}
 
MInt m_onlineRestartInterval {}
 
MInt m_maxBndryLayerLevel {}
 
MInt m_maxBndryLayerWidth {}
 
MInt m_trackMbStart {}
 
MInt m_FSIStart {}
 
MInt m_trackMbEnd {}
 
MInt m_bodyTypeMb {}
 
MFloat m_FSIToleranceU {}
 
MFloat m_FSIToleranceX {}
 
MFloat m_FSIToleranceW {}
 
MFloat m_FSIToleranceR {}
 
MFloat m_outsideFactor {}
 
MInt m_killSwitchCheckInterval {}
 
MInt m_solutionDiverged {}
 
SolverType m_solverType
 
MBool m_maxLevelDecrease = false
 
MFloat m_Fr {}
 
MFloat m_g {}
 
MBool m_haloCellOutput {}
 
MBool m_complexBoundary {}
 
MBool m_conservationCheck {}
 
MBool m_writeCenterLineData {}
 
MBool m_gclIntermediate {}
 
MBool m_onlineRestart {}
 
MFloat m_physicalTimeDt1 {}
 
MInt m_timeStepAdaptationStart {}
 
MInt m_timeStepAdaptationEnd {}
 
MFloat m_cflInitial {}
 
MFloat m_cflTarget {}
 
MFloat m_previousTimeStep {}
 
MInt m_centralizeSurfaceVariables {}
 
MBool m_generateOuterBndryCells {}
 
MBool m_applyCollisionModel {}
 
MBool m_applyRotationalCollisionModel {}
 
MBool m_LsMovement {}
 
MBool m_alwaysResetCutOff {}
 
MBool m_standardRK = false
 
MInt m_reConstSVDWeightMode {}
 
MInt m_lsCutCellMinLevel
 
MIntm_lsCutCellLevel = nullptr
 
MBool m_maxLevelChange = false
 
MBool m_dynamicStencil {}
 
std::map< MInt, MFloatm_oldGeomBndryCells
 
MBoolm_geometryChange = nullptr
 
std::vector< MInt > * m_gapWindowCells = nullptr
 
std::vector< MInt > * m_gapHaloCells = nullptr
 
MBool m_gapCellExchangeInit = false
 
MBool m_noneGapRegions = true
 
MBool m_initGapCell = true
 
MIntm_gapState = nullptr
 
MInt m_noFlowCells {}
 
MInt m_noGCells {}
 
MInt m_noSurfaces {}
 
MInt m_noBndryCells {}
 
MInt m_maxNoEmbeddedBodiesPeriodic {}
 
MInt m_initialSurfacesOffset {}
 
MInt m_noOuterBoundarySurfaces {}
 
MInt m_noLsMbBndryCells {}
 
MInt m_noEmergedCells {}
 
MInt m_noEmergedWindowCells {}
 
MInt m_noBndryCandidates {}
 
MInt m_noAzimuthalBndryCandidates {}
 
MInt m_noNearBndryCells {}
 
MInt m_reconstructionOffset {}
 
MInt m_structureStep {}
 
MInt m_maxStructureSteps {}
 
MInt m_noSurfacePointSamples {}
 
MInt m_maxNoSurfacePointSamples {}
 
MInt m_noPointParticles {}
 
MInt m_noPointParticlesLocal {}
 
MIntm_sampleNghbrs = nullptr
 
MIntm_sampleNghbrOffsets = nullptr
 
MBool m_gapOpened {}
 
MBool m_trackBodySurfaceData = true
 
MBool m_buildCollectedLevelSetFunction = false
 
MInt m_startSet {}
 
MIntm_noBodiesInSet = nullptr
 
MIntm_bodyToSetTable = nullptr
 
const clock_t m_t0
 
const MInt m_noCVars
 
const MInt m_noFVars
 
const MInt m_noPVars
 
const MInt m_noSlopes
 
const MFloat m_gammaMinusOne
 
MInt m_maxNoSampleNghbrs {}
 
MFloat m_U2 {}
 
MFloat m_rhoU2 {}
 
MFloat m_bodyDistThreshold {}
 
MFloat m_periodicGhostBodyDist {}
 
MFloatm_gridCellArea = nullptr
 
MFloatm_gravity = nullptr
 
MFloatm_bodyRadius = nullptr
 
MFloat m_minBodyRadius {}
 
MFloat m_maxBodyRadius {}
 
MFloatm_bodyRadii = nullptr
 
MFloatm_bodyDiameter = nullptr
 
MFloatm_bodyVolume = nullptr
 
MFloatm_bodyMass = nullptr
 
MFloatm_projectedArea = nullptr
 
MFloat m_addedMassCoefficient {}
 
MFloat m_densityRatio {}
 
MFloat m_capacityConstantVolumeRatio {}
 
MFloat m_couplingRate {}
 
MFloat ** m_coupling = nullptr
 
MFloat m_couplingRateLinear {}
 
MFloat m_couplingRatePressure {}
 
MFloat m_couplingRateViscous {}
 
MFloatm_bodyQuaternion = nullptr
 
MFloatm_bodyQuaternionDt1 = nullptr
 
MFloatm_bodyDensity = nullptr
 
MFloatm_bodyMomentOfInertia = nullptr
 
MFloatm_bodyAccelerationDt1 = nullptr
 
MFloatm_bodyAccelerationDt2 = nullptr
 
MFloatm_bodyAccelerationDt3 = nullptr
 
MFloatm_bodyVelocityDt1 = nullptr
 
MFloatm_bodyVelocityDt2 = nullptr
 
MFloatm_bodyTorque = nullptr
 
MFloatm_bodyTorqueDt1 = nullptr
 
MFloatm_bodyForce = nullptr
 
MFloatm_bodyForceDt1 = nullptr
 
MFloatm_bodyAngularVelocityDt1 = nullptr
 
MFloatm_bodyAngularAccelerationDt1 = nullptr
 
MFloatm_hydroForce = nullptr
 
MFloatm_bodyCenterDt1 = nullptr
 
MFloatm_bodyCenterDt2 = nullptr
 
MFloatm_bodyCenterInitial = nullptr
 
MFloatm_bodyTerminalVelocity = nullptr
 
MIntm_fixedBodyComponents = nullptr
 
MIntm_fixedBodyComponentsRotation = nullptr
 
MFloatm_bodyNeutralCenter = nullptr
 
MIntm_bodyEquation = nullptr
 
MIntm_bodyInCollision = nullptr
 
MBoolm_bodyNearDomain = nullptr
 
MFloatm_bodyDataAverage = nullptr
 
MFloatm_bodyDataAverage2 = nullptr
 
MFloatm_bodyDataDevAverage = nullptr
 
MFloatm_bodySumAverage = nullptr
 
MBoolm_bodyDataCollision = nullptr
 
MBool m_forceAdaptation = false
 
MInt m_pointParticleTwoWayCoupling {}
 
MInt m_pointParticleType {}
 
MFloatm_particleTerminalVelocity = nullptr
 
std::vector< MFloatm_particleCoords
 
std::vector< MFloatm_particleCoordsDt1
 
std::vector< MFloatm_particleCoordsInitial
 
std::vector< MFloatm_particleVelocity
 
std::vector< MFloatm_particleTemperature
 
std::vector< MFloatm_particleTemperatureDt1
 
std::vector< MFloatm_particleHeatFlux
 
std::vector< MFloatm_particleVelocityDt1
 
std::vector< MFloatm_particleVelocityFluid
 
std::vector< MFloatm_particleFluidTemperature
 
std::vector< MFloatm_particleAcceleration
 
std::vector< MFloatm_particleAccelerationDt1
 
std::vector< MFloatm_particleQuaternions
 
std::vector< MFloatm_particleQuaternionsDt1
 
std::vector< MFloatm_particleAngularVelocity
 
std::vector< MFloatm_particleAngularVelocityDt1
 
std::vector< MFloatm_particleVelocityGradientFluid
 
std::vector< MFloatm_particleAngularAcceleration
 
std::vector< MFloatm_particleAngularAccelerationDt1
 
std::vector< MFloatm_particleShapeParams
 
std::vector< MFloatm_particleRadii
 
std::vector< MIntm_particleCellLink
 
std::vector< MIntm_particleGlobalId
 
std::vector< MInt > * m_periodicGhostBodies = nullptr
 
std::set< MIntm_bodyWasInCollision
 
std::set< MIntm_bodyWasActuallyInCollision
 
std::vector< MIntm_bndryCandidates
 
std::vector< CutCandidate< nDim > > m_cutCandidates
 
std::vector< MIntm_bndryCandidateIds
 
MBool m_wasBalanced = false
 
std::vector< MIntm_azimuthalBndryCandidates
 
std::vector< MIntm_azimuthalBndryCandidateIds
 
std::vector< MFloatm_candidateNodeValues
 
std::vector< MIntm_candidateNodeSet
 
std::vector< MIntm_bndryLayerCells
 
MFloatm_bodyReducedVelocity = nullptr
 
MFloatm_bodyReducedMass = nullptr
 
MFloatm_bodyReducedFrequency = nullptr
 
MFloatm_bodyDampingCoefficient = nullptr
 
MFloat ** m_maxBndryLayerDistances = nullptr
 
MFloatm_volumeFraction = nullptr
 
MFloat m_stableVolumeFraction {}
 
MFloatm_stableCellVolume = nullptr
 
MFloatm_sweptVolumeDt1 = nullptr
 
MFloat ** m_rhsViscous = nullptr
 
std::vector< MInt > * m_linkedWindowCells = nullptr
 
std::vector< MInt > * m_linkedHaloCells = nullptr
 
MFloatm_cellVolumesDt1 = nullptr
 
MFloatm_cellVolumesDt2 = nullptr
 
MFloatm_boundaryPressureDt1 = nullptr
 
MFloatm_boundaryDensityDt1 = nullptr
 
MBool ** m_pointIsInside = nullptr
 
MIntm_noCutCellFaces = nullptr
 
MInt ** m_noCutFacePoints = nullptr
 
MInt ** m_cutFacePointIds = nullptr
 
MFloat ** m_cutFaceArea = nullptr
 
MFloatm_sampleCoordinates = nullptr
 
MFloatm_sampleNormals = nullptr
 
MFloatm_bbox = nullptr
 
MFloatm_bboxLocal = nullptr
 
MIntm_nghbrList = nullptr
 
MPI_Request * g_mpiRequestMb = nullptr
 
MIntm_sendBufferSize = nullptr
 
MIntm_receiveBufferSize = nullptr
 
std::set< MIntm_freeSurfaceIndices
 
std::map< MInt, MFloatm_oldBndryCells
 
std::map< MInt, std::vector< MFloat > > m_nearBoundaryBackup
 
std::vector< std::tuple< MInt, MInt, MInt > > m_temporarilyLinkedCells
 
std::vector< MIntm_massRedistributionIds
 
std::vector< MFloatm_massRedistributionVariables
 
std::vector< MFloatm_massRedistributionRhs
 
std::vector< MFloatm_massRedistributionVolume
 
std::vector< MFloatm_massRedistributionSweptVol
 
std::vector< MIntm_refOldBndryCells
 
std::set< MIntm_coarseOldBndryCells
 
std::vector< std::vector< MInt > > m_azimuthalLinkedHaloCells
 
std::vector< std::vector< MInt > > m_azimuthalLinkedWindowCells
 
std::multimap< MLong, std::pair< std::vector< MFloat >, std::vector< MUlong > > > m_azimuthalNearBoundaryBackup
 
std::vector< MIntm_azimuthalWasNearBndryIds
 
MFloatm_azimuthalNearBoundaryBackupBalFloat
 
MLongm_azimuthalNearBoundaryBackupBalLong
 
MInt m_noFloatDataBalance = 0
 
MInt m_noFloatDataAdaptation = 0
 
MInt m_noLongData = 0
 
MInt m_noLongDataBalance = 0
 
const MFloat m_azimuthalCornerEps = 0.01
 
MFloatm_slope = nullptr
 
MFloatm_area = nullptr
 
MFloatm_surfaceVariables = nullptr
 
MFloatm_cellCoordinates = nullptr
 
MFloatm_surfaceCoordinates = nullptr
 
MFloatm_cellSlopes = nullptr
 
MFloatm_vars = nullptr
 
MFloatm_oldVars = nullptr
 
MBool m_firstStats = true
 
MFloat m_oldMeanState [m_noMeanStatistics][4] {}
 
MBool m_printHeaderCorr = true
 
MBool m_printHeaderSlip = true
 
MBool m_saveSlipData
 
MInt m_slipInterval
 
MInt m_saveSlipInterval
 
MInt m_noSlipDataOutputs
 
std::vector< MIntm_particleOffsets
 
MIntm_slipDataParticleCollision = nullptr
 
MFloatm_slipDataParticleQuaternion = nullptr
 
MFloatm_slipDataParticleVel = nullptr
 
MFloatm_slipDataParticleAngularVel = nullptr
 
MFloatm_slipDataParticleForce = nullptr
 
MFloatm_slipDataParticleTorque = nullptr
 
MFloatm_slipDataParticleFluidVel = nullptr
 
MFloatm_slipDataParticleFluidVelGrad = nullptr
 
MFloatm_slipDataParticleFluidVelRot = nullptr
 
MFloatm_slipDataParticleFluidVelRnd = nullptr
 
MFloatm_slipDataParticleFluidVelGradRnd = nullptr
 
MFloatm_slipDataParticleFluidVelRotRnd = nullptr
 
MFloatm_slipDataParticlePosition = nullptr
 
std::vector< MFloatm_slipDataTimeSteps
 
MFloatm_gapAngleClose = nullptr
 
MFloatm_gapAngleOpen = nullptr
 
MFloatm_gapSign = nullptr
 
MInt m_forceNoGaps
 
MBool(FvMbCartesianSolverXD::* execRungeKuttaStep )()
 
std::vector< MIntm_forceFVMBStatistics
 
GeometryIntersection< nDim > * m_geometryIntersection = nullptr
 
FvBndryCndXD< nDim, SysEqn > * m_fvBndryCnd = nullptr
 
- Public Attributes inherited from FvCartesianSolverXD< nDim, SysEqn >
Geometry< nDim > * m_geometry
 
MFloat m_eps
 
MInt m_noSpecies
 
SysEqn m_sysEqn
 
FvBndryCndXD< nDim_, SysEqn > * m_fvBndryCnd
 
std::shared_ptr< Cantera::Solution > m_canteraSolution
 
std::shared_ptr< Cantera::ThermoPhase > m_canteraThermo
 
std::shared_ptr< Cantera::Kinetics > m_canteraKinetics
 
std::shared_ptr< Cantera::Transport > m_canteraTransport
 
std::unique_ptr< OneDFlamem_oneDimFlame
 
std::vector< MStringm_speciesName
 
std::map< std::string, MIntspeciesMap
 
MFloatm_molarMass
 
MFloatm_fMolarMass
 
MFloatm_standardHeatFormation
 
MFloatm_YInfinity
 
MBool m_detChemExtendedOutput
 
MBool m_isInitSamplingVars
 Indicator if sampling variables are initialized. More...
 
std::array< MFloat **, s_maxNoSamplingVariablesm_samplingVariables
 Storage for solver specific sampling variables. More...
 
std::array< MInt, 2 *s_maxNoSamplingVariablesm_samplingVariablesStatus
 Status of sampling variables to check if variable is already computed and exchanged. More...
 
MBool m_localTS
 
List< MInt > * m_sortedPeriodicCells
 
MInt m_totalnosplitchilds
 
MInt m_totalnoghostcells
 
MBool m_constructGField
 
MBool m_deleteNeighbour
 
MBool m_bndryLevelJumps
 
MInt m_lsCutCellBaseLevel
 
MInt m_noOuterBndryCells
 
MBool m_refineDiagonals
 
MFloatm_sweptVolume
 
MFloatm_sweptVolumeBal
 
MBool m_engineSetup
 
Collector< PointBasedCell< nDim > > * m_extractedCells
 
Collector< CartesianGridPoint< nDim > > * m_gridPoints
 
MFloat RKSemiImplicitFactor
 
MFloat ** uOtherPhase
 
MFloat ** uOtherPhaseOld
 
MFloat ** gradUOtherPhase
 
MFloat ** vortOtherPhase
 
MFloatnuTOtherPhase
 
MFloatnuEffOtherPhase
 
MFloat Eo0
 
MFloat bubbleDiameter
 
MFloat CD
 
MFloat CL
 
MInt dragModel
 
MFloat liquidDensity
 
MFloat eps
 
MInt gasSource
 
MFloat gasSourceMassFlow
 
std::vector< MIntgasSourceCells
 
MInt noGasSourceBoxes
 
std::vector< MFloatgasSourceBox
 
MBool bubblePathDispersion
 
MFloat massSource
 
MFloat initialAlpha
 
MFloat alphaInf
 
MFloat alphaIn
 
MFloat schmidtNumber
 
MBool uDLimiter
 
MFloat uDLim
 
MBool depthCorrection
 
std::vector< MFloatgravity
 
std::vector< MFloatgravityRefCoords
 
std::vector< MFloatdepthCorrectionCoefficients
 
MFloat interpolationFactor
 
MFloat infTemperature
 
MFloat infPressure
 
MFloat infPhi
 
MStringinfSpeciesName
 
MFloatinfSpeciesMassFraction
 
MFloat infVelocity
 
MFloat laminarFlameSpeedFactor
 
MBool hasChemicalReaction
 
MString reactionMechanism
 
MString phaseName
 
MString transportModel
 
MBool soretEffect
 
SysEqn::PrimitiveVariables * PV
 
SysEqn::ConservativeVariables * CV
 
SysEqn::FluxVariables * FV
 
SysEqn::AdditionalVariables * AV
 
SysEqn::SurfaceCoefficients * SC
 
MInt ** m_setToBodiesTable
 
MFloatm_bodyCenter
 
MFloatm_bodyVelocity
 
MFloatm_bodyVelocityDt1
 
MFloatm_bodyVelocityDt2
 
MFloatm_bodyAcceleration
 
MFloatm_bodyAngularVelocity
 
MFloatm_bodyAngularAcceleration
 
MFloatm_bodyTemperature
 
MFloatm_bodyTemperatureDt1
 
MFloatm_bodyHeatFlux
 
MInt m_volumeForcingDir
 
MFloat m_pipeRadius
 
MInt m_noEmbeddedBodies
 
MInt m_noPeriodicGhostBodies
 
MIntm_internalBodyId
 
MInt m_levelSetAdaptationScheme
 
MBool m_closeGaps
 
MInt m_gapInitMethod
 
MInt m_noGapRegions
 
std::vector< MIntm_gapCellId
 
std::vector< FvGapCell > m_gapCells
 
MInt m_periodicCells
 
MFloat ** m_periodicDataToSend
 
MFloat ** m_periodicDataToReceive
 
MIntm_noPerCellsToSend
 
MIntm_noPerCellsToReceive
 
MIntm_noPeriodicCellsDom
 
MFloat ** m_periodicCellDataDom
 
MInt m_noPeriodicData
 
MInt m_noPeriodicCellData
 
MFloat m_oldPressure_Gradient
 
MFloat m_oldUbulk
 
MFloat m_target_Ubulk
 
MInt m_oldTimeStep
 
MFloat UbulkDiff
 
MFloat m_referenceTemperature
 
MFloat m_sutherlandConstant
 
MFloat m_sutherlandConstantThermal
 
MFloat m_sutherlandPlusOne
 
MFloat m_sutherlandPlusOneThermal
 
MBool m_sensorBandRefinement
 
MInt m_sensorBandRefinementAdditionalLayers
 
MFloatconst
 
void(FvCartesianSolverXD::* m_reconstructSurfaceData )(MInt)
 
void(FvCartesianSolverXD::* m_computeViscousFlux )()
 
void(FvCartesianSolverXD::* m_computeViscousFluxMultiSpecies )(MInt)
 
MFloat m_meanCoord [3]
 
MInt m_adaptationLevel
 
MBool m_wasAdapted
 
MBool m_wasBalancedZonal
 
MBool m_firstUseUpdateSpongeLayerCase51
 
MPI_Comm comm_sponge
 
MInt m_noSpongeZonesIn
 
MInt m_noSpongeZonesOut
 
MInt m_spongeDirectionsIn [s_maxNoSpongeZones]
 
MInt m_spongeDirectionsOut [s_maxNoSpongeZones]
 
MInt m_secondSpongeDirectionsIn [s_maxNoSpongeZones]
 
MInt m_secondSpongeDirectionsOut [s_maxNoSpongeZones]
 
MInt m_spongeAveragingIn [s_maxNoSpongeZones]
 
MInt m_spongeAveragingOut [s_maxNoSpongeZones]
 
MBool m_hasCellsInSpongeLayer
 
MFloat m_timeOfMaxPdiff
 
MFloatm_coordSpongeIn
 
MFloatm_secondCoordSpongeIn
 
MFloatm_coordSpongeOut
 
MFloatm_secondCoordSpongeOut
 
MFloatm_uNormal_r
 
std::map< MInt, std::vector< MInt > > m_cellToNghbrHood
 
MFloat m_maxLsValue
 
MBool m_linerLvlJump
 
MInt m_tripNoTrips
 
MInt m_tripNoModes
 
MInt m_tripTotalNoCells
 
MInt m_tripSeed
 
MBool m_tripUseRestart
 
MFloat m_tripDomainWidth
 
MBool m_tripAirfoil
 
MFloat m_tripAirfoilChordLength
 
MFloat m_tripAirfoilAOA
 
MFloatm_tripAirfoilNosePos
 
MFloatm_tripAirfoilChordPos
 
MFloatm_tripAirfoilForceDir
 
MIntm_tripAirfoilOrientation
 
MIntm_tripAirfoilBndryId
 
MIntm_tripAirfoilSide
 
std::vector< MIntm_tripCellIds
 
std::vector< MFloatm_tripCoords
 
MIntm_tripTimeStep
 
MIntm_tripNoCells
 
MIntm_tripCellOffset
 
MFloatm_tripDelta1
 
MFloatm_tripXOrigin
 
MFloatm_tripXLength
 
MFloatm_tripYOrigin
 
MFloatm_tripYHeight
 
MFloatm_tripCutoffZ
 
MFloatm_tripMaxAmpSteady
 
MFloatm_tripMaxAmpFluc
 
MFloatm_tripDeltaTime
 
MFloatm_tripG
 
MFloatm_tripH1
 
MFloatm_tripH2
 
MFloatm_tripModesG
 
MFloatm_tripModesH1
 
MFloatm_tripModesH2
 
MBool m_useMpiStartall
 
MBool m_onlyMaxLvlMpiRequests
 
MInt m_noMaxLvlMpiSendNeighbors
 
MInt m_noMaxLvlMpiRecvNeighbors
 
std::vector< MIntm_maxLvlMpiSendNeighbor
 
std::vector< MIntm_maxLvlMpiRecvNeighbor
 
- Public Attributes inherited from Solver
std::set< MIntm_freeIndices
 
MBool m_singleAdaptation = false
 
MBool m_splitAdaptation = true
 
MBool m_saveSensorData = false
 

Static Public Attributes

static constexpr MFloat FD = nDim
 
static constexpr MInt m_noCellNodes = IPOW2(nDim)
 
static constexpr MInt m_noMeanStatistics = 6
 
static constexpr MFloat m_distThresholdStat [m_noMeanStatistics] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0}
 
static constexpr MInt m_noAngleSetups = 3
 
static constexpr MInt m_noDistSetups = 3
 
- Static Public Attributes inherited from FvCartesianSolverXD< nDim, SysEqn >
static constexpr MInt nDim
 
static constexpr const MInt m_noDirs
 
static constexpr const MInt m_noEdges
 
static constexpr const MInt m_noCorners
 
static constexpr MFloat m_volumeThreshold
 
static constexpr MInt s_maxNoSamplingVariables
 
static constexpr MBool hasAV
 
static constexpr MBool hasSC
 
static constexpr MInt s_maxNoSpongeZones
 
static constexpr MInt s_maxNoEmbeddedBodies
 

Private Member Functions

void checkDiv () override
 Check for divergence in case we use MB_DEBUG or debug. More...
 
MBool test_face (MInt, MInt, MInt)
 Test a face (MarchingCubes helper routine) receives MAIA face if face>0 return true if the face contains a part of the surface. More...
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void writeVTKFileOfCell (MInt, const std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void writeVTKFileOfCutCell (MInt, std::vector< polyCutCell > *, const std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void outputPolyData (const MInt, const std::vector< polyCutCell > *, const std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void outputPolyData (const MInt, const std::vector< polyCutCell > *, const std::vector< polyFace > *, const std::vector< polyEdge3D > *, const std::vector< polyVertex > *, MInt)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void compVolumeIntegrals (std::vector< polyCutCell > *, std::vector< polyEdge2D > *, const std::vector< polyVertex > *)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void compFaceIntegrals (polyCutCell *, std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt, MInt)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void compProjectionIntegrals (polyCutCell *, std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt, MInt, MFloat *)
 compute various integrations over projection of face More...
 
MFloat checkCentroidDiff (MInt srfcId1, MInt srfcId2)
 
MFloat checkAreaDiff (MInt srfcId1, MInt srfcId2)
 

Static Private Member Functions

static MFloat sgn (MFloat val)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
static void computeNormal (const MFloat *p0, const MFloat *p1, MFloat *res, MFloat &w)
 returns the normal corresponding to the triangle abc and returns the result in res More...
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
static MFloat computeNormal (const MFloat *p0, const MFloat *p1, const MFloat *p2, MFloat *res, MFloat &w)
 returns the normal corresponding to the triangle abc and returns the result in res More...
 

Private Attributes

MBool m_static_initSolutionStep_firstRun = true
 
MBool m_static_initSolutionStep_frstrn = true
 
MInt m_static_createCutFaceMb_MGC_bodyFaceJoinMode = 1
 
MFloat m_static_createCutFaceMb_MGC_maxA = 0.1
 
MBool m_static_createCutFaceMb_MGC_first = true
 

Static Private Attributes

static const std::array< MInt, CellDataDlb::counts_cellDataTypeDlb
 

Additional Inherited Members

- Protected Types inherited from FvCartesianSolverXD< nDim, SysEqn >
using Timers = maia::fv::Timers_
 
- Protected Types inherited from maia::CartesianSolver< nDim_, FvCartesianSolverXD< nDim_, SysEqn > >
using fun = void(CartesianSolver< nDim, FvCartesianSolverXD< nDim_, SysEqn > >::*)(std::vector< std::vector< MFloat > > &, std::vector< std::bitset< 64 > > &, std::vector< MFloat > &, MInt, MInt)
 
- Protected Member Functions inherited from FvCartesianSolverXD< nDim, SysEqn >
Geomgeometry ()
 Access the solver's geometry (non-const version) More...
 
FvSurfaceCollectorm_surfaceCollector ()
 
void computeWallNormalPointCoords ()
 
void findWallNormalCellIds ()
 
MFloat interpolateWallNormalPointVars (MInt var, MFloat coords[], MInt localId, std::vector< MInt > neighborList)
 
std::vector< MIntfindWallNormalNeighbors (MInt pointId)
 
void getWallNormalPointVars ()
 
void initSpanAvgSrfcProbes ()
 
void writeSpanAvgSrfcProbes ()
 
MFloat computeWMViscositySpalding (MInt)
 
MFloat computeWMViscositySpalding3D (MInt)
 
void initWMSurfaceProbes ()
 
void writeWMSurfaceProbes ()
 
void writeWMTimersASCII ()
 
void initWMExchange ()
 
void exchangeWMVars ()
 
void gatherWMVars ()
 
void receiveWMVars ()
 
void sendWMVars ()
 
void scatterWMVars ()
 
void readWallModelProperties ()
 
void restartWMSurfaces ()
 
void initChannelForce ()
 
void applyChannelForce ()
 
virtual void viscousFlux_Gequ_Pv ()
 Computes the viscous flux using a central difference scheme. More...
 
virtual void viscousFlux_Gequ_Pv_Plenum ()
 Computes the viscous flux using a central difference scheme, modified version for flame plenum computations. More...
 
virtual void updateJet ()
 jet volume forcing jet volume forcing with vortex rings. Velocity profile and forcing ref: "Effects of Inflow Conditions and Forcing on Subsonic Jet Flows and Noise" Bogey and Bailly. More...
 
virtual void writeListOfActiveFlowCells ()
 
MFloat reduceData (const MInt cellId, MFloat *data, const MInt dataBlockSize=1, const MBool average=true)
 determines the value of 'data' in the given cell by recusively volumetric averaging among all its offsprings More...
 
void sensorEntropyGrad (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 
void sensorEntropyQuot (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 
void sensorVorticity (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 
void sensorDerivative (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 computes the sensor values for a derivative sensor More...
 
void sensorSpecies (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 
void sensorParticle (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
 
virtual void setCellProperties ()
 
void initSpongeLayer ()
 
void determineStructuredCells ()
 
void tagCellsNeededForSurfaceFlux ()
 
void writeCutCellsToGridFile ()
 Writes cut cell information to an existing grid file in order to visualize it in ParaView. More...
 
virtual MBool gridPointIsInside (MInt, MInt)
 
void saveGridFlowVarsPar (const MChar *fileName, MInt noTotalCells, MLong noInternalCells, MFloatScratchSpace &variables, std::vector< MString > &dbVariablesName, MInt, MIntScratchSpace &idVariables, std::vector< MString > &idVariablesName, MInt, MFloatScratchSpace &dbParameters, std::vector< MString > &dbParametersName, MIntScratchSpace &idParameters, std::vector< MString > &idParametersName, const MInt *recalcIds)
 This function stores the massivley parallel flow information of the cells. More...
 
void computeVorticity3D (MFloat *const vorticity)
 
void computeVorticity2D (MFloat *const vorticity)
 
void computeVorticity3DT (MFloat *const vorticity)
 Compute vorticity and store in vorticity pointer (transposed version) More...
 
void computeQCriterion (MFloatScratchSpace &qCriterion)
 
void loadRestartTime (const MChar *fileName, MInt &globalTimeStepInput, MFloat &timeInput, MFloat &physicalTimeInput)
 This function loads the flow information of the cells such as variables and attributes like u_velocity,density,etc.,. More...
 
virtual void loadOldVariables (const MString &fileName)
 This function loads oldVariable data from a restartFile-type file. More...
 
virtual void loadGridFlowVarsPar (const MChar *fileName)
 This function loads the flow information of the cells such as variables and attributes like u_velocity,density,etc.,. More...
 
virtual void loadRestartMaterial ()
 
virtual void initCellMaterialNo ()
 
virtual MFloat entropy (MInt cellId)
 
void setAndAllocateJetProperties ()
 reads in the jet properties More...
 
void initializeTimers ()
 Initializes the communication timers. More...
 
MFloat timeStep (MBool canSolver=false) noexcept
 
MBool useTimeStepFromRestartFile () const
 Returns true if the time-step from a restart file should be reused. More...
 
MBool requiresTimeStepUpdate () const
 Returns true if the time-step should be updated on this step. More...
 
void setRestartFileOutputTimeStep ()
 
void computeSourceTerms ()
 
MFloat computeTimeStep (MInt cellId) const noexcept
 
MFloat computeTimeStepMethod (MInt cellId) const noexcept
 Computes the time-step of the cell cellId. More...
 
MFloat computeTimeStepEulerDirectional (MInt cellId) const noexcept
 
MFloat computeTimeStepApeDirectional (MInt cellId) const noexcept
 
MBool cellParticipatesInTimeStep (MInt cellId) const noexcept
 Does the cell cellId participate in the time-step computation? More...
 
MFloat computeTimeStepDiffusionNS (MFloat density, MFloat temperature, MFloat Re, MFloat C, MFloat dx) const noexcept
 
void computeAndSetTimeStep ()
 
- Protected Member Functions inherited from maia::CartesianSolver< nDim_, FvCartesianSolverXD< nDim_, SysEqn > >
void identifyBoundaryCells (MBool *const isInterface, const std::vector< MInt > &bndCndIds=std::vector< MInt >())
 
void identifyBoundaryCells ()
 
MBool cellIsOnGeometry (MInt cellId, Geometry< nDim > *geom)
 checks whether a cell lies on a certain geometry copied the essential part from identifyBoundaryCells More...
 
void setBoundaryDistance (const MBool *const interfaceCell, const MFloat *const outerBandWidth, MFloatScratchSpace &distance)
 transverses over all neighboring cells for a specified length More...
 
void markSurrndCells (MIntScratchSpace &inList, const MInt bandWidth, const MInt level, const MBool refineDiagonals=true)
 
void receiveWindowTriangles ()
 Receives triangles from neighbors contained in their window cells and inserts them locally. More...
 
void compactCells ()
 Removes all holes in the cell collector and moves halo cells to the back of the collector. More...
 
MInt createCellId (const MInt gridCellId)
 
void removeCellId (const MInt cellId)
 
MInt inCell (const MInt cellId, MFloat *point, MFloat fac=F1)
 
MInt setUpInterpolationStencil (const MInt cellId, MInt *, const MFloat *, std::function< MBool(MInt, MInt)>, MBool allowIncompleteStencil)
 
MFloat interpolateFieldData (MInt *, MFloat *, MInt varId, std::function< MFloat(MInt, MInt)> scalarField, std::function< MFloat(MInt, MInt)> coordinate)
 
MFloat leastSquaresInterpolation (MInt *, MFloat *, MInt varId, std::function< MFloat(MInt, MInt)> scalarField, std::function< MFloat(MInt, MInt)> coordinate)
 
void checkNoHaloLayers ()
 check that each solver has the required number of haloLayers for leaf cells!!! TODO labels:toenhance under production, needs to be cleaned up! More...
 
void mapInterpolationCells (std::map< MInt, MInt > &cellMap)
 
void setHaloCellsOnInactiveRanks ()
 
void patchRefinement (std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)
 
void reOrderCellIds (std::vector< MInt > &reOrderedCells)
 reOrder cellIds before writing the restart file! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void recomputeGlobalIds (std::vector< MInt > &, std::vector< MLong > &)
 reOrder cellIds before writing the restart file! This is necessary for example if the minLevel shall be raised at the new restart! More...
 
void extractPointIdsFromGrid (Collector< PointBasedCell< nDim > > *&, Collector< CartesianGridPoint< nDim > > *&, const MBool, const std::map< MInt, MInt > &, MInt levelThreshold=999999, MFloat *bBox=nullptr, MBool levelSetMb=false) const
 Creates a list of unique corner points for all cells using a hash map levelThreshold optionally specifies the maximum cell level to be extracted bBox optionally specifies a bounding to box to which the extracted domain shall be truncated. More...
 
- Protected Member Functions inherited from Solver
 Solver (const MInt solverId, const MPI_Comm comm, const MBool isActive=true)
 
MFloat returnLoadRecord () const
 
MFloat returnIdleRecord () const
 
- Protected Attributes inherited from FvCartesianSolverXD< nDim, SysEqn >
FvSurfaceCollector m_surfaces
 
maia::fv::collector::FvCellCollector< nDimm_cells
 Collector for FV cells. More...
 
MFloat m_maRot
 
MFloat m_MaHg
 
MFloat m_THg
 
MFloat m_UHg
 
MFloat m_VHg
 
MFloat m_WHg
 
MFloat m_PHg
 
MFloat m_rhoHg
 
MFloat m_MaCg
 
MFloat m_TCg
 
MFloat m_UCg
 
MFloat m_VCg
 
MFloat m_WCg
 
MFloat m_PCg
 
MFloat m_rhoCg
 
MIntm_bndryRfnJumpInformation
 
MIntm_bndryRfnJumpInformation_
 
MInt m_sweepStartFirstCell
 
MIntm_activeCellIds
 
MInt m_noActiveCells
 
MInt m_noActiveHaloCellOffset
 
MIntm_cellsInsideSpongeLayer
 
MInt m_noCellsInsideSpongeLayer
 
MIntm_smallCellIds
 
MIntm_masterCellIds
 
MInt ** m_maxLevelWindowCells
 
MIntm_noMaxLevelWindowCells
 
MInt ** m_maxLevelHaloCells
 
MIntm_noMaxLevelHaloCells
 
MInt m_slopeMemory
 
MInt m_surfaceVarMemory
 
std::set< MIntm_splitSurfaces
 
std::vector< MIntm_splitCells
 
std::vector< std::vector< MInt > > m_splitChilds
 
std::set< MIntm_cutOffInterface
 
MFloat ** m_A
 
MFloat ** m_ATA
 
MFloat ** m_ATAi
 
MIntm_reconstructionDataPeriodic
 
MUint m_reconstructionDataSize
 
std::vector< MFloatm_reconstructionConstants
 
std::vector< MIntm_reconstructionCellIds
 
std::vector< MIntm_reconstructionNghbrIds
 
MFloatm_reconstructionConstantsPeriodic
 
std::vector< std::vector< MInt > > m_azimuthalMaxLevelHaloCells
 
std::vector< std::vector< MInt > > m_azimuthalMaxLevelWindowCells
 
std::vector< std::vector< MInt > > m_azimuthalRemappedHaloCells
 
std::vector< std::vector< MInt > > m_azimuthalRemappedWindowCells
 
std::vector< MIntm_azimuthalRemappedNeighborDomains
 
std::vector< MIntm_azimuthalRemappedNeighborsDomainIndex
 
MBool m_azimuthalRecConstSet
 
MBool m_azimuthalNearBndryInit
 
const MInt m_maxNoAzimuthalRecConst
 
MBool m_planeInterp
 
std::vector< MIntm_noAzimuthalReconstNghbrs
 
std::vector< MFloatm_azimuthalRecConsts
 
std::vector< MIntm_azimuthalReconstNghbrIds
 
std::vector< MIntm_azimuthalBndrySide
 
std::vector< MFloatm_azimuthalCutRecCoord
 
std::vector< std::vector< MInt > > m_azimuthalMaxLevelWindowMap
 
std::vector< MIntm_azimuthalHaloActive
 
const MInt m_azimuthalNearBoundaryBackupMaxCount
 
MFloat m_azimuthalAngle
 
std::vector< MIntm_rotIndVarsPV
 
std::vector< MIntm_rotIndVarsCV
 
MFloat m_angularBodyVelocity
 
MFloat m_surfaceTangentialVelocity
 
MIntm_secondBodyId
 
MFloat ** m_rhs0
 
MFloatm_volumeAcceleration
 
MFloatm_rotAxisCoord
 
MFloatm_heatRelease
 
MFloatm_limPhi
 
std::vector< MFloatm_dampFactor
 
MString m_reactionScheme
 
MFloat m_hInfinity
 
MFloat m_gasConstant
 
MFloat m_thickeningFactor
 
MFloat m_referenceDensityTF
 
MFloat m_heatReleaseReductionFactor
 
MInt m_temperatureChange
 
MFloat m_burntUnburntTemperatureRatio
 
MFloat m_burntUnburntTemperatureRatioEnd
 
MFloat m_burntUnburntTemperatureRatioStart
 
MFloatm_molecularWeight
 
MFloatm_FmolecularWeight
 
MFloatm_molarFormationEnthalpy
 
MFloatm_formationEnthalpy
 
MFloatm_referenceComposition
 
MFloatm_secondaryReferenceComposition
 
MBool m_jet
 
MBool m_jetForcing
 
MFloat m_jetForcingPosition
 
MFloat m_jetRandomSeed
 
MFloat m_jetHalfWidth
 
MFloat m_jetCoflowOffset
 
MFloat m_jetCoflowEndOffset
 
MFloat m_jetHalfLength
 
MInt m_noJetConst
 
MFloatm_jetConst
 
MFloat m_forceCoefficient
 
MFloat m_densityRatio
 
MFloat m_shearLayerThickness
 
MFloat m_MaCoflow
 
MFloat m_jetTemperature
 
MFloat m_jetDensity
 
MFloat m_jetPressure
 
MFloat m_jetHeight
 
MFloat m_primaryJetRadius
 
MFloat m_secondaryJetRadius
 
MInt m_modeNumbers
 
MFloat m_targetVelocityFactor
 
MFloat m_momentumThickness
 
MInt m_jetType
 
MBool m_chevron
 
MFloat m_inletRadius
 
MFloat m_outletRadius
 
MFloat m_normJetTemperature
 
MFloat m_maNozzleExit
 
MFloat m_nozzleExitMaJet
 
MFloat m_nozzleExitTemp
 
MFloat m_nozzleExitRho
 
MFloat m_nozzleExitU
 
MFloat m_maNozzleInlet
 
MFloat m_nozzleInletTemp
 
MFloat m_nozzleInletP
 
MFloat m_nozzleInletRho
 
MFloat m_nozzleInletU
 
MFloat m_c0
 
MFloat m_laminarFlameThickness
 
MFloat m_subfilterVariance
 
MFloat m_maxReactionRate
 
MFloat m_MaFlameTube
 
MFloat m_temperatureFlameTube
 
MFloat m_velocityFlameTube
 
MFloat m_rhoFlameTube
 
MFloat m_rhoUnburnt
 
MFloat m_rhoBurnt
 
MFloat m_pressureFlameTube
 
MFloat m_pressureUnburnt
 
MFloat m_inletTubeAreaRatio
 
MFloat m_flameOutletAreaRatio
 
MFloat m_inletOutletAreaRatio
 
MBool m_twoFlames
 
MFloat m_dampingDistanceFlameBase
 
MFloat m_dampingDistanceFlameBaseExtVel
 
MFloat m_realRadiusFlameTube
 
MFloat m_radiusVelFlameTube
 
MFloat m_radiusInjector
 
MFloat m_yOffsetInjector
 
MFloat m_radiusFlameTube
 
MFloat m_radiusFlameTube2
 
MFloat m_initialFlameHeight
 
MFloat m_xOffsetFlameTube
 
MFloat m_xOffsetFlameTube2
 
MFloat m_yOffsetFlameTube
 
MFloat m_yOffsetFlameTube2
 
MFloat m_deltaXtemperatureProfile
 
MFloat m_deltaYtemperatureProfile
 
MFloat m_thermalProfileStartFactor
 
MFloat m_flameRadiusOffset
 
MFloat m_shearLayerStrength
 
MFloat m_ScT
 
MFloat m_NuT
 
MFloat m_integralAmplitude
 
MFloat m_integralLengthScale
 
MInt m_spongeLayerLayout
 
MFloatm_domainBoundaries
 
MFloatm_spongeCoord
 
MBool m_levelSet
 
MBool m_levelSetMb
 
MBool m_LsRotate
 
MBool m_levelSetRans
 
MBool m_combustion
 
MBool m_LSSolver
 
MBool m_acousticAnalysis
 
MBool m_thickenedFlame
 
std::vector< MFloat > * m_levelSetValues
 
MFloatm_levelSetValuesMb
 
MIntm_associatedBodyIds
 
MInt m_noLevelSetsUsedForMb
 
MInt m_noLevelSetFieldData
 
std::vector< MFloat > * m_curvatureG
 
std::vector< MFloat > * m_flameSpeedG
 
MInt m_noSets
 
MBool m_reComputedBndry
 
MString m_currentGridFileName
 
MBool m_adaptationSinceLastRestart
 
MBool m_adaptationSinceLastRestartBackup
 
MBool m_forceRestartGrid
 
MBool m_force1DFiltering
 
MBool m_gridConvergence
 
MBool m_gridInterfaceFilter
 
MBool m_totalDamp
 
MBool m_heatReleaseDamp
 
MBool m_useCorrectedBurningVelocity
 
MBool m_modelCheck
 
MBool m_recordBodyData
 
MBool m_recordLandA
 
MBool m_recordPressure
 
MBool m_vtkTest
 
MBool m_recordFlameFrontPosition
 
MBool m_recordWallVorticity
 
MBool m_structuredFlameOutput
 
MBool m_surfDistParallel
 
MBool m_surfDistCartesian
 
MInt m_writeOutData
 
MBool m_writeCutCellsToGridFile
 
MBool m_restartOldVariables
 
MBool m_restartOldVariablesReset
 
MBool m_bodyIdOutput
 
MBool m_levelSetOutput
 
MBool m_isActiveOutput
 
MBool m_domainIdOutput
 
MBool m_multipleFvSolver
 
const MChar ** m_variablesName
 
const MChar ** m_vorticityName
 
MBool m_saveVorticityToRestart
 
MBool m_vorticityOutput
 
MInt m_vorticitySize
 
MBool m_qCriterionOutput
 
MBool m_vtuWritePointData
 
MBool m_vtuWriteGeometryFile
 
MBool m_vtuWriteParticleFile
 
MBool m_vtuCutCellOutput
 
std::set< MIntm_vtuGeometryOutput
 
MBool m_vtuGlobalIdOutput
 
MBool m_vtuDomainIdOutput
 
MBool m_vtuDensityOutput
 
MBool m_vtuLevelSetOutput
 
MBool m_vtuQCriterionOutput
 
MBool m_vtuLambda2Output
 
MBool m_vtuVorticityOutput
 
MBool m_vtuVelocityGradientOutput
 
MBool m_vtuGeometryOutputExtended
 
MBool m_vtuSaveHeaderTesting
 
MInt m_vtuLevelThreshold
 
MFloatm_vtuCoordinatesThreshold
 
MBool m_checkCellSurfaces
 
MBool m_considerVolumeForces
 
MBool m_considerRotForces
 
MString m_outputFormat
 
MBool m_allowInterfaceRefinement
 
MInt m_bndryCellSurfacesOffset
 
MInt m_bndrySurfacesOffset
 
MInt m_cellToRecordData
 
MInt m_counterCx
 
MInt m_dragOutputInterval
 
MBool m_integratedHeatReleaseOutput
 
MInt m_integratedHeatReleaseOutputInterval
 
MBool m_dualTimeStepping
 
MBool m_euler
 
MInt m_bndryGhostCellsOffset
 
MInt m_initialCondition
 
MInt m_limiter
 
MInt m_maxNoTimeSteps
 
MInt m_maxNoSurfaces
 
MInt m_noGNodes
 
MInt m_noRKSteps
 
MInt m_noSamples
 
MInt m_maxIterations
 
MInt m_orderOfReconstruction
 
MInt m_restartBackupInterval
 
MBool m_restartBc2800
 
MFloat m_restartTimeBc2800
 
MInt m_RKStep
 
MInt m_rungeKuttaOrder
 
MInt m_noTimeStepsBetweenSamples
 
MInt m_forceNoTimeSteps
 
MInt m_structuredFlameOutputLevel
 
MFloat m_adaptationDampingDistance
 
MFloatm_angle
 
MFloatm_RKalpha
 
MBool m_isEEGas
 
struct {
   MFloat   RKSemiImplicitFactor
 
   MFloat **   uOtherPhase = nullptr
 
   MFloat **   uOtherPhaseOld = nullptr
 
   MFloat **   gradUOtherPhase = nullptr
 
   MFloat **   vortOtherPhase = nullptr
 
   MFloat *   nuTOtherPhase = nullptr
 
   MFloat *   nuEffOtherPhase = nullptr
 
   MFloat   Eo0
 
   MFloat   bubbleDiameter
 
   MFloat   CD
 
   MFloat   CL
 
   MInt   dragModel
 
   MFloat   liquidDensity
 
   MFloat   eps
 
   MInt   gasSource
 
   MFloat   gasSourceMassFlow
 
   std::vector< MInt >   gasSourceCells
 
   MInt   noGasSourceBoxes
 
   std::vector< MFloat >   gasSourceBox
 
   MBool   bubblePathDispersion
 
   MFloat   massSource
 
   MFloat   initialAlpha
 
   MFloat   alphaInf
 
   MFloat   alphaIn
 
   MFloat   schmidtNumber
 
   MBool   uDLimiter
 
   MFloat   uDLim
 
   MBool   depthCorrection
 
   std::vector< MFloat >   gravity
 
   std::vector< MFloat >   gravityRefCoords
 
   std::vector< MFloat >   depthCorrectionCoefficients
 
   MFloat   interpolationFactor
 
m_EEGas
 
struct {
   MFloat   infTemperature
 
   MFloat   infPressure
 
   MFloat   infPhi
 
   MString *   infSpeciesName
 
   MFloat *   infSpeciesMassFraction
 
   MFloat   infVelocity
 
   MFloat   laminarFlameSpeedFactor
 
   MBool   hasChemicalReaction
 
   MString   reactionMechanism
 
   MString   phaseName
 
   MString   transportModel
 
   MBool   soretEffect
 
m_detChem
 
MIntm_storeNghbrIds
 
MIntm_identNghbrIds
 
MBool m_zonal
 
MInt m_zonalRestartInterpolationSolverId
 
MBool m_resetInitialCondition
 
MBool m_rans
 
MInt m_noRansEquations
 
MFloat m_turbulenceDegree
 
MFloat m_ransTransPos
 
MInt m_zonalAveragingTimeStep
 
MInt m_zonalTransferInterval
 
MInt m_noRANSVariables
 
MInt m_noLESVariables
 
std::vector< MFloat > * m_RANSValues
 
std::vector< MFloat > * m_LESValues
 
std::vector< MFloat > * m_LESVarAverage
 
std::vector< MFloat > * m_LESVarAverageBal
 
std::vector< MIntm_LESAverageCells
 
MInt m_LESNoVarAverage
 
std::vector< MFloatm_averagePos
 
std::vector< MIntm_averageDir
 
std::vector< MBoolm_averageReconstructNut
 
MBool m_calcLESAverage
 
MBool m_restartLESAverage
 
MInt m_averageStartTimeStep
 
MInt m_rntStartTimeStep
 
MString m_bc7909RANSSolverType
 
MInt m_stgStartTimeStep
 
MBool m_stgIsActive
 
MFloat m_pressureRatioChannel
 
MInt m_pressureRatioStartTimeStep
 
MInt m_pressureRatioEndTimeStep
 
MInt m_spongeTimeVelocity
 
MFloat ** m_stgEddieCoverage
 
MInt m_stgSpongeTimeStep
 
MFloatm_stgSpongePositions
 
MInt m_noStgSpongePositions
 
MBool m_STGSponge
 
MBool m_preliminarySponge
 
MInt m_spongeRoot
 
MFloat m_7901Position
 
MInt m_7901faceNormalDir
 
MInt m_7901wallDir
 
MInt m_7901periodicDir
 
std::vector< MFloat > * m_STGSpongeFactor
 
MFloat ** m_LESPeriodicAverage
 
MFloatm_uvErr
 
MFloatm_uvRans
 
MFloatm_uvInt
 
MFloat m_spongeLimitFactor
 
MPI_Comm m_spongeComm
 
MInt m_spongeCommSize
 
MInt m_spongeRank
 
MInt m_noSpongeCells
 
MInt m_globalNoSpongeLocations
 
MIntm_globalNoPeriodicExchangeCells
 
std::vector< MInt > * m_spongeAverageCellId
 
std::vector< MIntm_spongeCells
 
std::vector< MFloatm_spongeLocations
 
MFloatm_globalBcStgLocationsG
 
std::vector< std::pair< MFloat, MFloat > > m_globalSpongeLocations
 
MFloat m_tkeFactor
 
MFloat m_kInfinityFactor
 
MFloat m_omegaInfinityFactor
 
std::vector< FvWMSurface< nDim > > m_wmSurfaces
 
MInt m_wmSurfaceProbeInterval
 
MInt m_wmGlobalNoSrfcProbeIds
 
MInt m_wmDomainId
 
MInt m_wmNoDomains
 
MBool m_wmLES
 
MBool m_wmOutput
 
MBool m_wmTimeFilter
 
MBool m_wmUseInterpolation
 
MFloat m_wmDistance
 
MInt m_wmIterator
 
MPI_Comm m_comm_wm
 
MIntm_wmLocalNoSrfcProbeIds
 
MIntm_noWMImgPointsSend
 
MIntm_noWMImgPointsRecv
 
MIntm_wmImgRecvIdMap
 
MFloatm_wmImgSendBuffer
 
MFloatm_wmImgRecvBuffer
 
MFloatm_wmSrfcProbeSendBuffer
 
MFloatm_wmSrfcProbeRecvBuffer
 
MPI_Request * m_mpi_wmRequest
 
MPI_Request * m_mpi_wmSendReq
 
MPI_Request * m_mpi_wmRecvReq
 
std::vector< std::vector< MInt > > m_wmImgCellIds
 
std::vector< std::vector< MInt > > m_wmImgWMSrfcIds
 
std::vector< std::vector< MFloat > > m_wmImgCoords
 
std::vector< MIntm_wmSurfaceProbeIds
 
std::vector< MIntm_wmSurfaceProbeSrfcs
 
MFloat m_normalLength
 
MInt m_normalNoPoints
 
MInt m_normalOutputInterval
 
MInt m_normalOutputInitCounter
 
MInt m_normalBcId
 
MBool m_wallNormalOutput
 
MBool m_useWallNormalInterpolation
 
std::vector< MFloatm_normalSamplingCoords
 
std::vector< MIntm_normalSamplingSide
 
MInt m_noWallNormals
 
std::vector< MFloatm_wallNormalPointCoords
 
std::vector< MFloatm_wallNormalVectors
 
std::vector< MFloatm_wallSetupOrigin
 
std::vector< MIntm_wallSetupOriginSide
 
std::vector< MIntm_wallNormalPointDomains
 
std::vector< MIntm_wallNormalPointCellIDs
 
std::vector< std::vector< MInt > > m_neighborPointIds
 
std::vector< MFloatTensorm_interpolationMatrices
 
std::vector< MIntm_interpolationPosition
 
MInt m_saNoSrfcProbes
 
MInt m_saSrfcProbeInterval
 
MInt m_saSrfcProbeStart
 
MBool m_saSrfcProbes
 
MString m_saSrfcProbeDir
 
std::vector< std::vector< MInt > > m_saSrfcProbeIds
 
std::vector< std::vector< MInt > > m_saSrfcProbeSrfcs
 
MFloatm_saSrfcProbeBuffer
 
MIntm_saSrfcProbeNoSamples
 
MBool m_useSandpaperTrip
 
MBool m_useChannelForce
 
MFloat m_channelVolumeForce
 
MFloat m_chi
 
MInt m_upwindMethod
 
MInt m_reConstSVDWeightMode
 
MBool m_relocateCenter
 
MBool m_reExcludeBndryDiagonals
 
MBool m_2ndOrderWeights
 
MFloat m_cfl
 
MFloat m_cflViscous
 
MFloat m_convergenceCriterion
 
MFloat m_deltaP
 
MFloat m_deltaPL
 
MFloat m_gamma
 
MFloat m_globalUpwindCoefficient
 
MFloat m_inflowTemperatureRatio
 
MFloat ** m_kronecker
 
MFloat m_massConsumption
 
MFloat m_maxTemp
 
MFloat m_meanPressure
 
MFloat m_meanY
 
MFloat m_physicalTime
 
MFloat m_physicalTimeStep
 
MFloat m_Pr
 
MFloat m_rPr
 
MFloat m_rRe0
 
MFloat m_referenceLength
 
MFloat m_previousMa
 
MBool m_changeMa
 
MBool m_useCreateCutFaceMGC
 
MFloat m_sampleRate
 
MFloat m_samplingTimeBegin
 
MFloat m_samplingTimeEnd
 
MInt m_spongeLayerType
 
MFloat m_sigmaSponge
 
MFloat m_sigmaSpongeInflow
 
MFloat m_spongeReductionFactor
 
MFloatm_spongeFactor
 
MFloat m_spongeLayerThickness
 
MBool m_createSpongeBoundary
 
MInt m_noSpongeFactors
 
MInt m_noSpongeBndryCndIds
 number of sponge boundary IDs More...
 
MInt m_noMaxSpongeBndryCells
 
MFloatm_sigmaSpongeBndryId
 
MFloatm_sigmaEndSpongeBndryId
 
MIntm_spongeDirections
 
MIntm_spongeBndryCndIds
 
MFloatm_spongeStartIteration
 
MFloatm_spongeEndIteration
 
MIntm_spongeTimeDependent
 
MBool m_spongeTimeDep
 
MBool m_velocitySponge
 
MFloat m_spongeWeight
 
MFloat m_spongeBeta
 
MFloat m_targetDensityFactor
 
MBool m_outputPhysicalTime
 
MFloat m_time
 
MFloat m_timeRef
 
MFloat m_totalHeatReleaseRate
 
MInt ** m_cellSurfaceMapping
 
MUlong m_randomDeviceSeed
 
MBool m_useCentralDifferencingSlopes
 
MFloat m_oldMomentOfVorticity
 
MFloat m_oldNegativeMomentOfVorticity
 
MFloat m_oldPositiveMomentOfVorticity
 
MFloat ** m_vorticity
 
MBool m_loadSampleVariables
 
MString m_testCaseName
 
MFloat m_timeStepConvergenceCriterion
 
MFloat ** m_externalSource
 
MFloat ** m_externalSourceDt1
 
MIntm_noParts
 
MBool m_hasExternalSource
 
std::map< MInt, std::vector< MFloat > > m_vapourData
 
MBool m_calcSlopesAfterStep
 
MBool m_multilevel
 Stores whether this solver is part of a multilevel computation. More...
 
MBool m_isMultilevelPrimary
 Stores whether this solver is the primary solver (i.e., it has the finshest mesh) of a multilevel computation. More...
 
MBool m_isLowestSecondary
 
MInt m_maxLevelBeforeAdaptation
 
MBool m_statisticCombustionAnalysis
 
MBool m_averageVorticity
 
MInt m_movingAvgInterval
 
MBool m_averageSpeedOfSound
 
MInt m_skewness
 
MInt m_kurtosis
 
std::set< MIntm_activeMeanVars
 
MFloat ** m_sendBuffers
 
MFloat ** m_receiveBuffers
 
MInt m_dataBlockSize
 
MBool m_nonBlockingComm
 
MFloat ** m_sendBuffersNoBlocking
 
MFloat ** m_receiveBuffersNoBlocking
 
MPI_Request * m_mpi_request
 
MPI_Request * m_mpi_sendRequest
 
MPI_Request * m_mpi_receiveRequest
 
MBool m_mpiRecvRequestsOpen
 
MBool m_mpiSendRequestsOpen
 
MBool m_splitMpiCommRecv
 
Collector< FvBndryCell< nDim, SysEqn > > * m_bndryCells
 
std::vector< MIntm_associatedInternalCells
 
std::map< MInt, MIntm_splitChildToSplitCell
 
MString m_surfaceValueReconstruction
 
MString m_viscousFluxScheme
 
MString m_advectiveFluxScheme
 
MFloat m_enhanceThreePointViscFluxFactor
 
MInt m_noLimitedSlopesVar
 
MIntm_limitedSlopesVar
 
MInt m_computeExtVel
 
MBool m_massFlux
 
MBool m_plenumWall
 
MBool m_plenum
 
MBool m_confinedFlame
 
MBool m_filterFlameTubeEdges
 
MFloat m_filterFlameTubeEdgesDistance
 
MBool m_divergenceTreatment
 
MBool m_specialSpongeTreatment
 
MInt m_constantFlameSpeed
 
MFloat m_flameSpeed
 
MFloat m_turbFlameSpeed
 
MFloat m_Da
 
MFloat m_noReactionCells
 
MFloat m_velocityOutlet
 
MFloat m_analyticIntegralVelocity
 
MInt m_pressureLossFlameSpeed
 
MFloat m_pressureLossCorrection
 
MFloat m_meanVelocity
 
MFloat m_meanVelocityOutlet
 
MFloat m_tubeLength
 
MFloat m_outletLength
 
MFloat m_radiusOutlet
 
MFloat m_strouhal
 
MFloat m_strouhalInit
 
MFloat m_flameStrouhal
 
MFloat m_neutralFlameStrouhal
 
MInt m_samplingEndCycle
 
MInt m_samplingStartCycle
 
MInt m_samplingStartIteration
 
MInt m_noSamplingCycles
 
MFloat m_samplesPerCycle
 
MInt m_noForcingCycles
 
MBool m_forcing
 
MFloat m_forcingAmplitude
 
MFloat m_perturbationAmplitude
 
MFloat m_perturbationAmplitudeCorr
 
MFloat m_lambdaPerturbation
 
MInt m_outputOffset
 
MFloat m_marksteinLength
 
MFloat m_marksteinLengthPercentage
 
MBool m_zeroLineCorrection
 
MFloat m_marksteinLengthTh
 
MInt m_loadBalancingReinitStage
 
MBool m_weightBndryCells
 
MBool m_weightCutOffCells
 
MBool m_weightBc1601
 
MBool m_weightInactiveCell
 
MBool m_weightNearBndryCells
 
MBool m_limitWeights
 
MBool m_weightLvlJumps
 
MBool m_weightSmallCells
 
MFloat m_weightBaseCell
 
MFloat m_weightLeafCell
 
MFloat m_weightActiveCell
 
MFloat m_weightBndryCell
 
MFloat m_weightNearBndryCell
 
MFloat m_weightMulitSolverFactor
 
MInt m_timerGroup
 
std::array< MInt, Timers::_countm_timers
 
MInt m_tgfv
 
MInt m_tcomm
 
MInt m_texchange
 
MInt m_tgatherAndSend
 
MInt m_tgatherAndSendWait
 
MInt m_tscatterWaitSome
 
MInt m_tgather
 
MInt m_tsend
 
MInt m_treceive
 
MInt m_tscatter
 
MInt m_treceiving
 
MInt m_treceiveWait
 
MInt m_texchangeDt
 
MFloat m_UInfinity
 
MFloat m_VInfinity
 
MFloat m_WInfinity
 
MFloat m_PInfinity
 
MFloat m_TInfinity
 
MFloat m_DthInfinity
 
MFloat m_nuTildeInfinity
 
MFloat m_kInfinity
 
MFloat m_omegaInfinity
 
MFloat m_DInfinity
 
MFloat m_SInfinity
 
MFloat m_VVInfinity [3]
 
MFloat m_rhoUInfinity
 
MFloat m_rhoVInfinity
 
MFloat m_rhoWInfinity
 
MFloat m_rhoEInfinity
 
MFloat m_rhoInfinity
 
MFloat m_rhoVVInfinity [3]
 
MFloatm_postShockPV
 
MFloatm_postShockCV
 
MInt m_timeStepMethod
 
MBool m_timeStepVolumeWeighted
 Should the time-step in the boundary cells be weighted by their volume? More...
 
MFloat m_timeStep
 
MBool m_timeStepNonBlocking
 Reduce the timeStep using non-blocking communication;. More...
 
MPI_Request m_timeStepReq
 Request for reducing the time-step using non-blocking comm. More...
 
MBool m_timeStepAvailable
 Has the non-blocking reduction of the time-step finished? More...
 
MBool m_timeStepUpdated
 time-step has been updated More...
 
MFloat m_timeStepFixedValue
 Forces the time-step to be set to a fixed value: More...
 
MInt m_timeStepComputationInterval
 How often should the time-step be recomputed? More...
 
MFloat m_restartFileOutputTimeStep
 
MBool m_static_logCell_firstRun
 
MBool m_static_smallCellCorrection_first
 
MInt m_static_smallCellCorrection_slipDirection
 
MFloat m_static_smallCellCorrection_slipCoordinate
 
MBool m_static_computeSurfaceValuesLimitedSlopesMan_checkedBndryCndIds
 
MBool m_static_computeSurfaceValuesLimitedSlopesMan_correctWallBndryFluxes
 
MFloat m_static_getDistanceSplitSphere_h
 
MBool m_static_getDistanceSplitSphere_first
 
MBool m_static_constructGFieldPredictor_firstRun
 
MBool m_static_constructGFieldPredictor_adaptiveGravity
 
MFloat m_static_advanceSolution_meanDragCoeff
 
MFloat m_static_advanceSolution_meanDrag
 
MFloat m_static_advanceSolution_dragCnt
 
MBool m_static_advanceSolution_firstRun
 
MBool m_static_updateBodyProperties_c453_firstRun
 
MBool m_static_updateBodyProperties_c455_firstRun
 
MBool m_static_updateBodyProperties_firstTime
 
MBool m_static_redistributeMass_firstRun
 
MBool m_static_applyBoundaryCondition_firstRun
 
MFloat m_static_applyBoundaryCondition_ERhoL1
 
MFloat m_static_applyBoundaryCondition_ERhoL2
 
MFloat m_static_applyBoundaryCondition_ERhoLoo
 
MFloat m_static_applyBoundaryCondition_EVelL1
 
MFloat m_static_applyBoundaryCondition_EVelL2
 
MFloat m_static_applyBoundaryCondition_EVelLoo
 
MFloat m_static_applyBoundaryCondition_refMass
 
MFloat m_static_applyBoundaryCondition_oldMass
 
MFloat m_static_applyBoundaryCondition_oldVol2
 
MBool m_static_updateSpongeLayer_mbSpongeLayer
 
MBool m_static_updateSpongeLayer_first
 
MBool m_static_logData_firstRun4
 
MBool m_static_logData_ic45299_first
 
MFloat m_static_logData_ic45299_amplitude [s_logData_ic45299_maxNoEmbeddedBodies]
 
MFloat m_static_logData_ic45299_freqFactor [s_logData_ic45299_maxNoEmbeddedBodies]
 
MFloat m_static_logData_ic45299_maxF
 
MFloat m_static_logData_ic45299_maxA
 
MFloat m_static_logData_ic45299_cutOffAngle
 
MFloat m_static_logData_ic45299_xCutOff
 
MBool m_static_logData_ic45301_first
 
MFloat m_static_logData_ic45301_Strouhal
 
MFloat m_static_logData_ic45301_freqFactor [s_logData_ic45301_maxNoEmbeddedBodies]
 
MFloat m_static_logData_ic45301_maxF
 
MFloat m_static_logData_ic45301_pressurePoints [s_logData_ic45301_maxNoPressurePoints *nDim]
 
MInt m_static_logData_ic45301_noPressurePoints
 
MInt m_static_logData_ic45301_containingCellIds [s_logData_ic45301_maxNoPressurePoints]
 
MBool m_static_saveSolverSolutionxd_firstRun
 
MFloat m_static_computeFlowStatistics_thetaDensityAverage [s_computeFlowStatistics_noSamples *s_computeFlowStatistics_thetaSize *s_computeFlowStatistics_noDat]
 
MFloat m_static_computeFlowStatistics_thetaDensityAverage2 [s_computeFlowStatistics_noSamples *s_computeFlowStatistics_thetaSize *s_computeFlowStatistics_noDat]
 
MInt m_static_computeFlowStatistics_currentIndex
 
MFloat m_static_computeFlowStatistics_pdfAverage [s_computeFlowStatistics_noSamples2 *s_computeFlowStatistics_noPdfs *s_computeFlowStatistics_noPdfPoints]
 
MFloat m_static_computeFlowStatistics_pdfAverage2 [s_computeFlowStatistics_noSamples2 *s_computeFlowStatistics_noPdfs *s_computeFlowStatistics_noPdfPoints]
 
MFloat m_static_computeFlowStatistics_jointPdfAverage [s_computeFlowStatistics_noSamples2 *s_computeFlowStatistics_noJointPdfs *s_computeFlowStatistics_noPdfPoints *s_computeFlowStatistics_noPdfPoints]
 
MInt m_static_computeFlowStatistics_currentIndex2
 
MFloat m_static_computeFlowStatistics_sdatAverage [s_computeFlowStatistics_noSamples *s_computeFlowStatistics_noAngles *s_computeFlowStatistics_noAngleDat]
 
MFloat m_static_computeFlowStatistics_sdatAverage2 [s_computeFlowStatistics_noSamples *s_computeFlowStatistics_noAngles *s_computeFlowStatistics_noAngleDat]
 
MFloat m_static_computeFlowStatistics_sdatSum [s_computeFlowStatistics_noSamples *s_computeFlowStatistics_noAngles]
 
MInt m_static_computeFlowStatistics_currentIndex3
 
MInt m_maxNearestBodies
 
MInt m_static_computeFlowStatistics_currentIndex4
 
MInt m_static_computeFlowStatistics_currentCnt
 
MFloat m_static_computeFlowStatistics_bodyCntAvg [s_computeFlowStatistics_noSamples *s_computeFlowStatistics_noReClasses]
 
MBool m_static_computeFlowStatistics_firstBD
 
MBool m_static_writeVtkXmlFiles_firstCall
 
MBool m_static_writeVtkXmlFiles_firstCall2
 
MBool m_static_logCellxd_firstRun
 
std::vector< MIntm_cellInterpolationIndex
 
std::vector< std::vector< MFloat > > m_cellInterpolationMatrix
 
std::vector< std::vector< MInt > > m_cellInterpolationIds
 
- Protected Attributes inherited from maia::CartesianSolver< nDim_, FvCartesianSolverXD< nDim_, SysEqn > >
MIntm_rfnBandWidth
 
MInt m_noSensors
 
MInt m_adaptationInterval
 
MInt m_adaptationStep
 
std::vector< MIntm_maxSensorRefinementLevel
 
std::vector< MFloatm_sensorWeight
 
std::vector< MFloatm_sensorDerivativeVariables
 
MBool m_adaptation
 
MBool m_adapts
 
MInt m_noInitialSensors
 
MBool m_resTriggeredAdapt
 
MInt m_noSmoothingLayers
 
MInt m_sensorBandAdditionalLayers
 
MBool m_sensorInterface
 
MBool m_sensorParticle
 
std::vector< MStringm_sensorType
 
MIntm_recalcIds
 
std::vector< funm_sensorFnPtr
 
MInt m_maxNoSets
 
std::vector< MFloatm_azimuthalCartRecCoord
 
const MInt m_revDir [6]
 
const MInt m_noDirs
 
- Protected Attributes inherited from Solver
MFloat m_Re {}
 the Reynolds number More...
 
MFloat m_Ma {}
 the Mach number More...
 
MInt m_solutionInterval
 The number of timesteps before writing the next solution file. More...
 
MInt m_solutionOffset {}
 
std::set< MIntm_solutionTimeSteps
 
MInt m_restartInterval
 The number of timesteps before writing the next restart file. More...
 
MInt m_restartTimeStep
 
MInt m_restartOffset
 
MString m_solutionOutput
 
MBool m_useNonSpecifiedRestartFile = false
 
MBool m_initFromRestartFile
 
MInt m_residualInterval
 The number of timesteps before writing the next residual. More...
 
const MInt m_solverId
 a unique solver identifier More...
 
MFloatm_outerBandWidth = nullptr
 
MFloatm_innerBandWidth = nullptr
 
MIntm_bandWidth = nullptr
 
MBool m_restart = false
 
MBool m_restartFile = false
 
- Static Protected Attributes inherited from FvCartesianSolverXD< nDim, SysEqn >
static constexpr MInt s_logData_ic45299_maxNoEmbeddedBodies
 
static constexpr MInt s_logData_ic45301_maxNoEmbeddedBodies
 
static constexpr MInt s_logData_ic45301_maxNoPressurePoints
 
static constexpr MInt s_computeFlowStatistics_noSamples
 
static constexpr MInt s_computeFlowStatistics_thetaSize
 
static constexpr MInt s_computeFlowStatistics_noDat
 
static constexpr MInt s_computeFlowStatistics_noPdfPoints
 
static constexpr MInt s_computeFlowStatistics_noPdfs
 
static constexpr MInt s_computeFlowStatistics_noJointPdfs
 
static constexpr MInt s_computeFlowStatistics_noSamples2
 
static constexpr MInt s_computeFlowStatistics_noSamples3
 
static constexpr MInt s_computeFlowStatistics_noAngles
 
static constexpr MInt s_computeFlowStatistics_noAngleDat
 
static constexpr MInt s_computeFlowStatistics_noReClasses
 
static constexpr MInt s_computeFlowStatistics_noSamples4
 

Detailed Description

template<MInt nDim, class SysEqn>
class FvMbCartesianSolverXD< nDim, SysEqn >

Definition at line 53 of file fvmbcartesiansolverxd.h.

Member Typedef Documentation

◆ Base

template<MInt nDim, class SysEqn >
using FvMbCartesianSolverXD< nDim, SysEqn >::Base = FvCartesianSolverXD<nDim, SysEqn>

Definition at line 55 of file fvmbcartesiansolverxd.h.

◆ Cell

template<MInt nDim, class SysEqn >
using FvMbCartesianSolverXD< nDim, SysEqn >::Cell = typename maia::grid::tree::Tree<nDim>::Cell

Definition at line 57 of file fvmbcartesiansolverxd.h.

◆ SolverCell

template<MInt nDim, class SysEqn >
using FvMbCartesianSolverXD< nDim, SysEqn >::SolverCell = FvCell

Definition at line 56 of file fvmbcartesiansolverxd.h.

◆ Timers

template<MInt nDim, class SysEqn >
using FvMbCartesianSolverXD< nDim, SysEqn >::Timers = maia::fv::Timers_

Definition at line 480 of file fvmbcartesiansolverxd.h.

Constructor & Destructor Documentation

◆ FvMbCartesianSolverXD()

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::FvMbCartesianSolverXD ( MInt  solverId_,
MInt  noSpecies,
const MBool propertiesGroups,
maia::grid::Proxy< nDim > &  gridProxy_,
Geometry< nDim > &  geometry_,
const MPI_Comm  comm 
)

Constructor

Definition at line 40 of file fvmbcartesiansolverxd.cpp.

44 : FvCartesianSolverXD<nDim, SysEqn>(solverId_, noSpecies, propertiesGroups, gridProxy_, geometry_, comm),
45 m_t0(clock()),
46 m_noCVars(CV->noVariables),
47 m_noFVars(FV->noVariables),
48 m_noPVars(PV->noVariables),
51 TRACE();
52
54 if(this->m_fvBndryCnd == nullptr) mTerm(1, AT_, "something went wrong with the boundary condition in MB...");
55
56 m_levelSetMb = propertiesGroups[LEVELSETMB];
57 ASSERT(m_levelSetMb, "Calling fvMb without levelSetMb");
58
61}
SysEqn::ConservativeVariables * CV
void initializeMb()
called by the constructor 1) read additional fvmb properties 2) allocate fvmb specific memory 3) init...
FvBndryCndXD< nDim, SysEqn > * m_fvBndryCnd
@ LEVELSETMB
Definition: enums.h:275
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29

◆ ~FvMbCartesianSolverXD()

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::~FvMbCartesianSolverXD
override

Destructor

Definition at line 68 of file fvmbcartesiansolverxd.cpp.

68 {
69 TRACE();
70
71 const clock_t t1 = clock();
72 const MFloat t = static_cast<MFloat>(t1 - m_t0) / CLOCKS_PER_SEC;
73 m_log << "========================================" << endl;
74 m_log << "Total execution time FvMbSolver3D: " << printTime(t) << " (" << setprecision(8) << t << ")" << endl;
75 m_log << "========================================" << endl;
76}
MString printTime(const MFloat t)
InfoOutFile m_log
double MFloat
Definition: maiatypes.h:52

Member Function Documentation

◆ adaptationTrigger()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::adaptationTrigger
overridevirtual
Author
Tim Wegmann

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 15387 of file fvmbcartesiansolverxd.cpp.

15387 {
15388 TRACE();
15389
15390 MBool forceAdaptation = false;
15391
15392 if(m_engineSetup) {
15393 static const MInt cadInterval = 5;
15394
15395 const MInt cad = this->crankAngle(m_physicalTime, 0);
15396 const MInt cad_dt1 = this->crankAngle(m_physicalTime - timeStep(), 0);
15397
15398 if(cad % cadInterval == 0 && cad_dt1 % cadInterval != 0) {
15399 forceAdaptation = true;
15400 if(domainId() == 0) {
15401 cerr << " FvMb-Solver is forcing a mesh-adaptation at time step " << globalTimeStep << endl;
15402 }
15403 }
15404 }
15405
15406 if(m_forceAdaptation) {
15407 forceAdaptation = true;
15408 m_forceAdaptation = false;
15409 }
15410
15411 return forceAdaptation;
15412}
MFloat crankAngle(const MFloat, const MInt)
help-function for engine calculations which returns the crank-angle for a given time mode = 0: return...
MFloat timeStep(MBool canSolver=false) noexcept
virtual MInt domainId() const
Return the domainId (rank)
Definition: solver.h:383
MInt globalTimeStep
int32_t MInt
Definition: maiatypes.h:62
bool MBool
Definition: maiatypes.h:58

◆ adaptTimeStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::adaptTimeStep
Author
Lennart Schneiders

Definition at line 8818 of file fvmbcartesiansolverxd.cpp.

8818 {
8819 TRACE();
8820
8822
8827 } else {
8828 const MFloat t = (MFloat)globalTimeStep;
8831 m_cfl = m_cflInitial + (t - t0) * (m_cflTarget - m_cflInitial) / (t1 - t0);
8832 m_log << "Adapted CFL number: " << m_cfl << " at time step " << globalTimeStep << ";" << endl;
8833 }
8834}

◆ addBoundarySurfacesMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::addBoundarySurfacesMb
Author
Daniel Hartmann, January 10, 2007

Definition at line 21198 of file fvmbcartesiansolverxd.cpp.

21198 {
21199 TRACE();
21200
21201 MInt noCells = m_fvBndryCnd->m_bndryCells->size();
21202 MFloat epsilon = pow(10.0, -13.0);
21203 m_fvBndryCnd->m_noBoundarySurfaces = m_noOuterBoundarySurfaces;
21204
21205 for(MInt bndryId = m_noOuterBndryCells; bndryId < noCells; bndryId++) {
21206 for(MInt srfc = 0; srfc < FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces; srfc++) {
21207 for(MInt i = 0; i < nDim; i++) {
21208 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
21209 }
21210 }
21211 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
21212
21213 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21214 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
21215 if(a_isHalo(cellId)) continue;
21216 if(a_isPeriodic(cellId)) continue;
21217
21218 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
21219 cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId;
21220 }
21221
21222 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
21223 const MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
21224 if(a_hasProperty(cellId, SolverCell::IsSplitChild)
21225 || (c_noChildren(cellId) == 0 && a_level(cellId) <= maxRefinementLevel())
21226 || (c_noChildren(cellId) > 0 && a_level(cellId) == maxRefinementLevel())) {
21227 // create one surface per space direction
21228 for(MInt i = 0; i < nDim; i++) {
21229 // if the surface is inclined, replace it by its projections
21230 // into the Cartesian frame of reference
21231 if(fabs(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]) > epsilon) {
21233 const MInt srfcId = a_noSurfaces() - 1;
21234
21235 // add the boundary surface
21236 m_fvBndryCnd->m_boundarySurfaces[m_fvBndryCnd->m_noBoundarySurfaces] = srfcId;
21237 m_fvBndryCnd->m_noBoundarySurfaces++;
21238
21239 // set the boundary condition
21240 a_surfaceBndryCndId(srfcId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId;
21241
21242 // the coordinates of the new surface are shifted...
21243 for(MInt j = 0; j < nDim; j++) {
21244 a_surfaceCoordinate(srfcId, j) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[j];
21245 }
21246
21247 // projection to compute the area of the surface
21248 a_surfaceArea(srfcId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
21249 * fabs(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]);
21250
21251 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = srfcId;
21252
21253 if(a_surfaceArea(srfcId) < F0) {
21254 cerr << "Warning: negative surface area of surface " << srfcId << " at time step " << globalTimeStep
21255 << " !!!!!!" << endl;
21256 }
21257
21258 // set the surface orientation
21259 a_surfaceOrientation(srfcId) = i;
21261
21262 MFloat dn = F0;
21263 for(MInt k = 0; k < nDim; k++) {
21264 dn +=
21265 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[k]
21266 * (a_coordinate(cellId, k) - m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[k]);
21267 }
21268
21269 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] > F0) {
21270 a_surfaceNghbrCellId(srfcId, 0) = ghostCellId;
21271 a_surfaceNghbrCellId(srfcId, 1) = cellId;
21272 a_surfaceFactor(srfcId, 0) = F1B2; // don't modify, crucial for accurate fluid-structure coupling!
21273 a_surfaceFactor(srfcId, 1) = F1B2;
21274 } else {
21275 a_surfaceNghbrCellId(srfcId, 1) = ghostCellId;
21276 a_surfaceNghbrCellId(srfcId, 0) = cellId;
21277 a_surfaceFactor(srfcId, 1) = F1B2;
21278 a_surfaceFactor(srfcId, 0) = F1B2;
21279 }
21280
21281 for(MInt k = 0; k < nDim; k++) {
21282 a_surfaceDeltaX(srfcId, k) =
21283 a_surfaceCoordinate(srfcId, k) - a_coordinate(a_surfaceNghbrCellId(srfcId, 0), k);
21284 a_surfaceDeltaX(srfcId, nDim + k) =
21285 a_surfaceCoordinate(srfcId, k) - a_coordinate(a_surfaceNghbrCellId(srfcId, 1), k);
21286 }
21287 }
21288 }
21289 }
21290 }
21291 }
21292}
MInt a_noSurfaces()
Returns the number of surfaces.
MBool a_isPeriodic(const MInt cellId) const
Returns IsPeriodic of the cell cellId.
Collector< FvBndryCell< nDim, SysEqn > > * m_bndryCells
MInt & a_surfaceOrientation(const MInt srfcId)
Returns the orientation of surface srfcId.
MBool a_isHalo(const MInt cellId) const
Returns IsHalo of the cell cellId.
MFloat & a_surfaceArea(const MInt srfcId)
Returns the area of surface srfcId.
MFloat & a_surfaceCoordinate(const MInt srfcId, const MInt dir)
Returns the coordinate of surface srfcId in direction dir.
MFloat & a_surfaceUpwindCoefficient(const MInt srfcId)
Returns the upwind coefficient of surface srfcId.
MFloat & a_surfaceDeltaX(const MInt srfcId, const MInt varId)
Returns the delta X of surface srfcId for variable varId.
MBool a_hasProperty(const MInt cellId, const Cell p) const
Returns grid cell property p of the cell cellId.
MFloat & a_surfaceFactor(const MInt srfcId, const MInt varId)
Returns the factor of surface srfcId for variable varId.
MInt c_noChildren(const MInt cellId) const
Returns the number of children of the cell cellId.
MFloat & a_coordinate(const MInt cellId, const MInt dir)
Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir.
MInt & a_surfaceNghbrCellId(const MInt srfcId, const MInt dir)
Returns the neighbor cell id of surface srfcId in direction dir.
MInt & a_surfaceBndryCndId(const MInt srfcId)
Returns the boundary condition of surface srfcId.
MInt & a_level(const MInt cellId)
Returns the level of the cell from the fvcellcollector cellId.
void append(const MInt count)
Append nodes to end of tree.
Definition: container.h:223
void const MInt cellId
Definition: collector.h:239

◆ advanceBodies()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::advanceBodies
Author
Lennart Schneiders

Definition at line 5229 of file fvmbcartesiansolverxd.cpp.

5229 {
5230 TRACE();
5231
5232 const size_t dim3 = 3 * m_noEmbeddedBodies * sizeof(MFloat);
5233 const size_t dim4 = 4 * m_noEmbeddedBodies * sizeof(MFloat);
5234 const size_t dimD = nDim * m_noEmbeddedBodies * sizeof(MFloat);
5235
5236 if(m_motionEquation > 1) {
5237 memcpy(m_bodyVelocityDt2, m_bodyVelocityDt1, dimD);
5238 memcpy(m_bodyCenterDt2, m_bodyCenterDt1, dimD);
5241 }
5242
5243 memcpy(m_bodyVelocityDt1, m_bodyVelocity, dimD);
5244 memcpy(m_bodyCenterDt1, m_bodyCenter, dimD);
5246 memcpy(m_bodyTorqueDt1, m_bodyTorque, dim3);
5251
5252 if(!m_constructGField) return;
5253
5254 if(m_noPointParticles > 0) {
5255 m_fvBndryCnd->recorrectCellCoordinates();
5256
5257 const MInt heatRelated = 2;
5258 const MInt dataSize = 7 * 3 + 2 * 4 + heatRelated;
5259
5260 MIntScratchSpace sendCount(noDomains(), AT_, "sendCount");
5261 MIntScratchSpace recvCount(noDomains(), AT_, "recvCount");
5262 ScratchSpace<MPI_Request> sendReq(noNeighborDomains(), AT_, "sendReq");
5263 ScratchSpace<vector<MFloat>> sendVars(noNeighborDomains(), AT_, "sendVars");
5264 ScratchSpace<vector<MFloat>> recvVars(noNeighborDomains(), AT_, "recvVars");
5265 ScratchSpace<vector<MLong>> sendIds(noNeighborDomains(), AT_, "sendIds");
5266 ScratchSpace<vector<MLong>> recvIds(noNeighborDomains(), AT_, "recvIds");
5267 ScratchSpace<vector<MInt>> sendParticleGlobalIds(noNeighborDomains(), AT_, "sendParticleGlobalIds");
5268 ScratchSpace<vector<MInt>> recvParticleGlobalIds(noNeighborDomains(), AT_, "recvParticleGlobalIds");
5269 map<MLong, MInt> globalToLocal;
5270 ScratchSpace<MLong> globalIds(a_noCells(), AT_, "globalId");
5271 sendCount.fill(0);
5272 recvCount.fill(0);
5273
5274 for(MInt i = 0; i < noNeighborDomains(); ++i) {
5275 sendVars[i].clear();
5276 recvVars[i].clear();
5277 sendIds[i].clear();
5278 recvIds[i].clear();
5279 }
5280
5281 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
5282 if(!a_isHalo(cellId) && c_globalId(cellId) > -1) {
5283 globalToLocal[(MLong)c_globalId(cellId)] = cellId;
5284 }
5285 globalIds(cellId) = (MLong)c_globalId(cellId);
5286 }
5287
5288 exchangeDataFV(&globalIds[0]);
5289
5290 for(MUint p = 0; p < m_particleCellLink.size(); p++) {
5292 const MFloat cellHalfLength = F1B2 * c_cellLengthAtCell(cellId);
5293 MInt dirCode[3] = {0, 0, 0};
5294 for(MInt i = 0; i < nDim; i++) {
5295 if(m_particleCoords[nDim * p + i] < a_coordinate(cellId, i) - cellHalfLength)
5296 dirCode[i] = -1;
5297 else if(m_particleCoords[nDim * p + i] > a_coordinate(cellId, i) + cellHalfLength)
5298 dirCode[i] = 1;
5299 }
5300 if(dirCode[0] != 0 || dirCode[1] != 0 || dirCode[2] != 0) {
5301 MInt nghbrId = cellId;
5302 for(MInt i = 0; i < nDim; i++) {
5303 if(dirCode[i] == 0) continue;
5304 MInt dir = (dirCode[i] > 0) ? 2 * i + 1 : 2 * i;
5305 if(dirCode[i] > 0 && a_hasNeighbor(nghbrId, dir) == 0) mTerm(1, AT_, "particle moved into void");
5306 nghbrId = c_neighborId(nghbrId, dir);
5307 }
5308 while(c_noChildren(nghbrId) > 0) {
5309 MInt child = 0;
5310 for(MUint i = 0; i < nDim; i++) {
5311 if(m_particleCoords[nDim * p + i] > a_coordinate(nghbrId, i)) child += IPOW2(i);
5312 }
5313 nghbrId = c_childId(nghbrId, child);
5314 if(nghbrId < 0 || nghbrId >= a_noCells()) mTerm(1, AT_, "Point particle linking failed.");
5315 }
5316 if(!a_isHalo(nghbrId)) {
5317 m_particleCellLink[p] = nghbrId;
5318 } else {
5319 MLong globalId = globalIds(nghbrId); // c_globalId(nghbrId); //since m_globalId not set in periodic cells...
5320 MInt nghbrDomain = -1;
5321 for(MInt i = 0; i < noNeighborDomains(); ++i) {
5322 if(globalId >= domainOffset(neighborDomain(i)) && globalId < domainOffset(neighborDomain(i) + 1)) {
5323 nghbrDomain = i;
5324 break;
5325 }
5326 }
5327 if(nghbrDomain < 0) mTerm(1, AT_, "Neighbor domain not found " + to_string(globalId));
5328 for(MInt i = 0; i < 3; i++) {
5329 sendVars[nghbrDomain].push_back(m_particleCoords[nDim * p + i] - a_coordinate(nghbrId, i));
5330 }
5331 for(MInt i = 0; i < 3; i++) {
5332 sendVars[nghbrDomain].push_back(m_particleVelocity[nDim * p + i]);
5333 }
5334 for(MInt i = 0; i < 3; i++) {
5335 sendVars[nghbrDomain].push_back(m_particleAcceleration[nDim * p + i]);
5336 }
5337 for(MInt i = 0; i < 4; i++) {
5338 sendVars[nghbrDomain].push_back(m_particleQuaternions[4 * p + i]);
5339 }
5340 for(MInt i = 0; i < 3; i++) {
5341 sendVars[nghbrDomain].push_back(m_particleAngularVelocity[3 * p + i]);
5342 }
5343 for(MInt i = 0; i < 3; i++) {
5344 sendVars[nghbrDomain].push_back(m_particleAngularAcceleration[3 * p + i]);
5345 }
5346 for(MInt i = 0; i < 4; i++) {
5347 sendVars[nghbrDomain].push_back(m_particleShapeParams[4 * p + i]);
5348 }
5349 for(MInt i = 0; i < 3; i++) {
5350 sendVars[nghbrDomain].push_back(m_particleRadii[3 * p + i]);
5351 }
5352
5353 sendVars[nghbrDomain].push_back(m_particleTemperature[p]);
5354 sendVars[nghbrDomain].push_back(m_particleHeatFlux[p]);
5355
5356 sendIds[nghbrDomain].push_back(globalId);
5357 m_particleCellLink[p] = -1;
5358 sendCount(neighborDomain(nghbrDomain))++;
5359 sendParticleGlobalIds[nghbrDomain].push_back(m_particleGlobalId[p]);
5360 }
5361 }
5362 }
5363 MPI_Alltoall(&sendCount[0], 1, MPI_INT, &recvCount[0], 1, MPI_INT, mpiComm(), AT_, "sendCount[0]", "recvCount[0]");
5364 for(MInt i = 0; i < noNeighborDomains(); ++i) {
5365 if(recvCount[neighborDomain(i)] > 0) {
5366 recvVars[i].resize(dataSize * recvCount[neighborDomain(i)]);
5367 recvIds[i].resize(recvCount[neighborDomain(i)]);
5368 recvParticleGlobalIds[i].resize(recvCount[neighborDomain(i)]);
5369 }
5370 }
5371 sendReq.fill(MPI_REQUEST_NULL);
5372 MInt cnt = 0;
5373 for(MInt i = 0; i < noNeighborDomains(); i++) {
5374 if(sendCount[neighborDomain(i)] == 0) continue;
5375 MPI_Issend(&sendIds[i].front(), sendCount[neighborDomain(i)], MPI_LONG, neighborDomain(i), 78, mpiComm(),
5376 &sendReq[cnt], AT_, "sendIds[i].front()");
5377 cnt++;
5378 }
5379 for(MInt i = 0; i < noNeighborDomains(); i++) {
5380 if(recvCount[neighborDomain(i)] == 0) continue;
5381 MPI_Recv(&recvIds[i].front(), recvCount[neighborDomain(i)], MPI_LONG, neighborDomain(i), 78, mpiComm(),
5382 MPI_STATUS_IGNORE, AT_, "recvIds[i].front()");
5383 }
5384 if(cnt > 0) MPI_Waitall(cnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
5385 sendReq.fill(MPI_REQUEST_NULL);
5386 cnt = 0;
5387 for(MInt i = 0; i < noNeighborDomains(); i++) {
5388 if(sendCount[neighborDomain(i)] == 0) continue;
5389 MPI_Issend(&sendVars[i].front(), dataSize * sendCount[neighborDomain(i)], MPI_DOUBLE, neighborDomain(i), 79,
5390 mpiComm(), &sendReq[cnt], AT_, "sendVars[i].front()");
5391 cnt++;
5392 }
5393 for(MInt i = 0; i < noNeighborDomains(); i++) {
5394 if(recvCount[neighborDomain(i)] == 0) continue;
5395 MPI_Recv(&recvVars[i].front(), dataSize * recvCount[neighborDomain(i)], MPI_DOUBLE, neighborDomain(i), 79,
5396 mpiComm(), MPI_STATUS_IGNORE, AT_, "recvVars[i].front()");
5397 }
5398 if(cnt > 0) MPI_Waitall(cnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
5399 sendReq.fill(MPI_REQUEST_NULL);
5400 cnt = 0;
5401 for(MInt i = 0; i < noNeighborDomains(); i++) {
5402 if(sendCount[neighborDomain(i)] == 0) continue;
5403 MPI_Issend(&sendParticleGlobalIds[i].front(), sendCount[neighborDomain(i)], MPI_INT, neighborDomain(i), 80,
5404 mpiComm(), &sendReq[cnt], AT_, "sendParticleGlobalIds[i].front()");
5405 cnt++;
5406 }
5407 for(MInt i = 0; i < noNeighborDomains(); i++) {
5408 if(recvCount[neighborDomain(i)] == 0) continue;
5409 MPI_Recv(&recvParticleGlobalIds[i].front(), recvCount[neighborDomain(i)], MPI_INT, neighborDomain(i), 80,
5410 mpiComm(), MPI_STATUS_IGNORE, AT_, "recvParticleGlobalIds[i].front()");
5411 }
5412
5413 if(cnt > 0) MPI_Waitall(cnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
5414
5415 vector<MFloat> tmpCoord;
5416 vector<MFloat> tmpVel;
5417 vector<MFloat> tmpTemp;
5418 vector<MFloat> tmpHeat;
5419 vector<MFloat> tmpAcc;
5420 vector<MFloat> tmpCoordsInitial;
5421 vector<MFloat> tmpQuat;
5422 vector<MFloat> tmpAngVel;
5423 vector<MFloat> tmpAngAcc;
5424 vector<MFloat> tmpShape;
5425 vector<MFloat> tmpRad;
5426 vector<MInt> tmpLink;
5427 vector<MInt> tmpParticleGlobalId;
5428
5429 tmpCoord.clear();
5430 tmpVel.clear();
5431 tmpTemp.clear();
5432 tmpHeat.clear();
5433 tmpAcc.clear();
5434 tmpLink.clear();
5435 tmpQuat.clear();
5436 tmpAngVel.clear();
5437 tmpAngAcc.clear();
5438 tmpShape.clear();
5439 tmpRad.clear();
5440 tmpParticleGlobalId.clear();
5441
5442 for(MInt p = 0; p < m_noPointParticlesLocal; p++) {
5443 if(m_particleCellLink[p] > -1) {
5444 tmpLink.push_back(m_particleCellLink[p]);
5445 for(MInt i = 0; i < 3; i++)
5446 tmpCoord.push_back(m_particleCoords[nDim * p + i]);
5447 for(MInt i = 0; i < 3; i++)
5448 tmpVel.push_back(m_particleVelocity[nDim * p + i]);
5449 for(MInt i = 0; i < 3; i++)
5450 tmpAcc.push_back(m_particleAcceleration[nDim * p + i]);
5451 for(MInt i = 0; i < 4; i++)
5452 tmpQuat.push_back(m_particleQuaternions[4 * p + i]);
5453 for(MInt i = 0; i < 3; i++)
5454 tmpAngVel.push_back(m_particleAngularVelocity[3 * p + i]);
5455 for(MInt i = 0; i < 3; i++)
5456 tmpAngAcc.push_back(m_particleAngularAcceleration[3 * p + i]);
5457 for(MInt i = 0; i < 4; i++)
5458 tmpShape.push_back(m_particleShapeParams[4 * p + i]);
5459 for(MInt i = 0; i < 3; i++)
5460 tmpRad.push_back(m_particleRadii[3 * p + i]);
5461 tmpTemp.push_back(m_particleTemperature[p]);
5462 tmpHeat.push_back(m_particleHeatFlux[p]);
5463 tmpParticleGlobalId.push_back(m_particleGlobalId[p]);
5464 }
5465 }
5466
5467 m_particleCellLink = tmpLink;
5468 m_particleCoords = tmpCoord;
5469 m_particleVelocity = tmpVel;
5470 m_particleTemperature = tmpTemp;
5471 m_particleHeatFlux = tmpHeat;
5472 m_particleAcceleration = tmpAcc;
5473 m_particleQuaternions = tmpQuat;
5474 m_particleAngularVelocity = tmpAngVel;
5476 m_particleShapeParams = tmpShape;
5477 m_particleRadii = tmpRad;
5478 m_particleGlobalId = tmpParticleGlobalId;
5479
5480 for(MInt i = 0; i < noNeighborDomains(); i++) {
5481 for(MInt k = 0; k < recvCount[neighborDomain(i)]; k++) {
5482 if(globalToLocal.count(recvIds[i][k]) == 0) mTerm(1, AT_, "Global id invalid " + to_string(recvIds[i][k]));
5483 MInt cellId = globalToLocal[recvIds[i][k]];
5484 if(cellId < 0 || cellId >= a_noCells() || c_globalId(cellId) != recvIds[i][k]) {
5485 cerr << cellId << " " << c_globalId(cellId) << " " << recvIds[i][k] << endl;
5486 mTerm(1, AT_,
5487 "Global id mismatch " + to_string(cellId) + " " + to_string(c_globalId(cellId)) + " "
5488 + to_string(recvIds[i][k]));
5489 }
5490 m_particleCellLink.push_back(cellId);
5491 MInt id = 0;
5492
5493 for(MInt j = 0; j < 3; j++) {
5494 m_particleCoords.push_back(a_coordinate(cellId, j) + recvVars[i][dataSize * k + id]);
5495 id++;
5496 }
5497 for(MInt j = 0; j < 3; j++) {
5498 m_particleVelocity.push_back(recvVars[i][dataSize * k + id]);
5499 id++;
5500 }
5501 for(MInt j = 0; j < 3; j++) {
5502 m_particleAcceleration.push_back(recvVars[i][dataSize * k + id]);
5503 id++;
5504 }
5505 for(MInt j = 0; j < 4; j++) {
5506 m_particleQuaternions.push_back(recvVars[i][dataSize * k + id]);
5507 id++;
5508 }
5509 for(MInt j = 0; j < 3; j++) {
5510 m_particleAngularVelocity.push_back(recvVars[i][dataSize * k + id]);
5511 id++;
5512 }
5513 for(MInt j = 0; j < 3; j++) {
5514 m_particleAngularAcceleration.push_back(recvVars[i][dataSize * k + id]);
5515 id++;
5516 }
5517 for(MInt j = 0; j < 4; j++) {
5518 m_particleShapeParams.push_back(recvVars[i][dataSize * k + id]);
5519 id++;
5520 }
5521 for(MInt j = 0; j < 3; j++) {
5522 m_particleRadii.push_back(recvVars[i][dataSize * k + id]);
5523 id++;
5524 }
5525 m_particleTemperature.push_back(recvVars[i][dataSize * k + id]);
5526 id++;
5527 m_particleHeatFlux.push_back(recvVars[i][dataSize * k + id]);
5528 id++;
5529 m_particleGlobalId.push_back(recvParticleGlobalIds[i][k]);
5530 }
5531 }
5532
5533 m_fvBndryCnd->rerecorrectCellCoordinates();
5534
5546
5547 if(m_noPointParticles == 1) {
5548 for(MInt p = 0; p < m_noPointParticlesLocal; p++) {
5549 cerr << domainId() << ": particle " << globalTimeStep << " / " << m_particleCoords[nDim * p] << " "
5550 << m_particleCoords[nDim * p + 1] << " " << m_particleCoords[nDim * p + 2] << " / "
5551 << m_particleVelocity[nDim * p] << " " << m_particleVelocity[nDim * p + 1] << " "
5552 << m_particleVelocity[nDim * p + 2] << "/ " << m_particleTemperature[p] << "/ " << m_particleHeatFlux[p]
5553 << endl;
5554 }
5555 }
5556 }
5557}
MLong c_neighborId(const MInt cellId, const MInt dir, const MBool assertNeighborState=true) const
Returns the grid neighbor id of the grid cell cellId dir.
MLong c_childId(const MInt cellId, const MInt pos) const
Returns the grid child id of the grid cell cellId at position pos.
MFloat c_cellLengthAtCell(const MInt cellId) const
Returns the length of the cell for level.
MInt a_noCells() const
Returns the number of cells.
MLong c_globalId(const MInt cellId) const
Returns the global grid id of the grid cell cellId.
void exchangeDataFV(T *data, const MInt blockSize=1, MBool cartesian=true, const std::vector< MInt > &rotIndex=std::vector< MInt >())
MInt a_hasNeighbor(const MInt cellId, const MInt dir, const MBool assertNeighborState=true) const
Returns noNeighborIds of the cell CellId for direction dir.
std::vector< MFloat > m_particleQuaternions
std::vector< MFloat > m_particleVelocityDt1
std::vector< MFloat > m_particleAngularAcceleration
std::vector< MFloat > m_particleCoords
std::vector< MFloat > m_particleCoordsDt1
std::vector< MFloat > m_particleAccelerationDt1
std::vector< MFloat > m_particleAngularVelocityDt1
std::vector< MFloat > m_particleHeatFlux
std::vector< MFloat > m_particleTemperature
std::vector< MInt > m_particleGlobalId
std::vector< MFloat > m_particleRadii
std::vector< MFloat > m_particleTemperatureDt1
std::vector< MInt > m_particleCellLink
std::vector< MFloat > m_particleAngularAccelerationDt1
std::vector< MFloat > m_particleVelocityFluid
std::vector< MFloat > m_particleQuaternionsDt1
std::vector< MFloat > m_particleVelocity
std::vector< MFloat > m_particleAngularVelocity
std::vector< MFloat > m_particleVelocityGradientFluid
std::vector< MFloat > m_particleFluidTemperature
std::vector< MFloat > m_particleShapeParams
std::vector< MFloat > m_particleAcceleration
This class is a ScratchSpace.
Definition: scratch.h:758
MPI_Comm mpiComm() const
Return the MPI communicator used by this solver.
Definition: solver.h:380
virtual MInt noDomains() const
Definition: solver.h:387
constexpr MLong IPOW2(MInt x)
uint32_t MUint
Definition: maiatypes.h:63
int64_t MLong
Definition: maiatypes.h:64
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status, const MString &name, const MString &varname)
same as MPI_Recv
int MPI_Issend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Issend
int MPI_Waitall(int count, MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Waitall
int MPI_Alltoall(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Alltoall
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.

◆ advanceExternalSource()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::advanceExternalSource
overridevirtual
Author
Tim Wegmann

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 14224 of file fvmbcartesiansolverxd.cpp.

14224 {
14225 if(!m_hasExternalSource) return;
14226
14227 const MInt noCBytes = a_noCells() * m_noCVars * sizeof(MFloat);
14228 memcpy(&m_externalSourceDt1[0][0], &(a_externalSource(0, 0)), noCBytes);
14229}
MFloat & a_externalSource(MInt cellId, MInt var)
Return external source.

◆ advancePointParticles()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::advancePointParticles
Author

Definition at line 7416 of file fvmbcartesiansolverxd.cpp.

7416 {
7417 const MBool saffmanLift = false;
7418
7419 if(m_pointParticleType == 1) {
7420 MFloat vrel[3];
7421 MFloat vort[3];
7422 MFloat lift[3];
7423
7424 const MFloat dt = timeStep();
7426
7427 // 1. prediction step
7428 for(MInt p = 0; p < m_noPointParticlesLocal; p++) {
7429 for(MInt i = 0; i < nDim; i++) {
7430 m_particleCoords[nDim * p + i] =
7432 + F1B2 * dt * (m_particleVelocity[nDim * p + i] + m_particleVelocityDt1[nDim * p + i])
7433 + F1B4 * POW2(dt) * (m_particleAcceleration[nDim * p + i] + m_particleAccelerationDt1[nDim * p + i]);
7434 m_particleVelocity[nDim * p + i] =
7436 }
7438 }
7439
7440 // 2. compute fluid velocity
7442
7443 // 3. correction step
7444 for(MInt p = 0; p < m_noPointParticlesLocal; p++) {
7446 const MFloat diameter =
7447 F2 * pow(m_particleRadii[3 * p] * m_particleRadii[3 * p + 1] * m_particleRadii[3 * p + 2], F1B3);
7448 const MFloat T = sysEqn().temperature_ES(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
7449 const MFloat mue = SUTHERLANDLAW(T);
7450 const MFloat FAC = 18.0 * mue / (sysEqn().m_Re0 * m_densityRatio * m_rhoInfinity * POW2(diameter));
7451 MFloat Rep = F0;
7452 for(MInt i = 0; i < nDim; i++) {
7453 vrel[i] = m_particleVelocityFluid[nDim * p + i] - m_particleVelocity[nDim * p + i];
7454 Rep += POW2(vrel[i]);
7455 }
7456 Rep = sqrt(Rep) * diameter * a_pvariable(cellId, PV->RHO) * sysEqn().m_Re0 / mue;
7457 vort[0] = a_slope(cellId, PV->VV[2], 1) - a_slope(cellId, PV->VV[1], 2);
7458 vort[1] = a_slope(cellId, PV->VV[0], 2) - a_slope(cellId, PV->VV[2], 0);
7459 vort[2] = a_slope(cellId, PV->VV[1], 0) - a_slope(cellId, PV->VV[0], 1);
7460 lift[0] = vort[2] * vrel[1] - vort[1] * vrel[2];
7461 lift[1] = vort[0] * vrel[2] - vort[2] * vrel[0];
7462 lift[2] = vort[1] * vrel[0] - vort[0] * vrel[1];
7463 MFloat Res = a_pvariable(cellId, PV->RHO) * POW2(diameter) * sqrt(POW2(vort[0]) + POW2(vort[1]) + POW2(vort[2]))
7464 * sysEqn().m_Re0 / mue;
7465 MFloat beta = F1B2 * Res / Rep;
7466 MFloat CLS = 4.1126 * ((F1 - 0.3314 * sqrt(beta)) * exp(-0.1 * Rep) + 0.3314 * sqrt(beta)) / sqrt(Res);
7467 if(Rep > 40.0) CLS = 0.0524 * sqrt(beta * Rep);
7468 for(MInt i = 0; i < nDim; i++) {
7470 FAC * (F1 + 0.15 * pow(Rep, 0.687)) * vrel[i] + FAC * m_particleTerminalVelocity[i];
7471 if(saffmanLift) m_particleAcceleration[nDim * p + i] += F3B4 * CLS * lift[i] / (m_densityRatio * diameter);
7472 m_particleVelocity[nDim * p + i] =
7474 + dt * F1B2 * (m_particleAcceleration[nDim * p + i] + m_particleAccelerationDt1[nDim * p + i]);
7475 m_particleCoords[nDim * p + i] =
7477 + dt * F1B2 * (m_particleVelocity[nDim * p + i] + m_particleVelocityDt1[nDim * p + i]);
7478 }
7479
7480 // Temperature update
7481 const MFloat particleSurface = PI * POW2(diameter);
7482 const MFloat mass = F1B6 * PI * POW3(diameter) * m_densityRatio * m_rhoInfinity;
7483 // See Whitaker 1972, AIChE Journal, Attention: not validated for Re < 4,
7484 // Nu = 2 for Re -> 0 is a solution of Stokes flow
7485 const MFloat mueParticle = SUTHERLANDLAW(m_particleTemperature[p]);
7486 const MFloat nusselt =
7487 F2
7488 + pow(m_Pr, 2.0 / 5.0) * (2.0 / 5.0 * pow(Rep, F1B2) + 0.06 * pow(Rep, F2B3)) * pow(mue / mueParticle, 0.25);
7489 const MFloat lambdaFluid = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
7490 const MFloat alpha = nusselt * lambdaFluid / diameter;
7492 m_particleHeatFlux[p] = (particleSurface * alpha * m_gamma) / (mass * Cvp * m_Pr * sysEqn().m_Re0) * deltaT;
7495 }
7496 //}
7497 } else if(m_pointParticleType == 3) {
7498 const MFloat dt = timeStep();
7499 const MFloat dt2 = F1B2 * timeStep();
7500 MFloatScratchSpace K(3, 3, AT_, "K");
7501 MFloatScratchSpace R(3, 3, AT_, "R");
7502 MFloatScratchSpace W(4, 4, AT_, "W");
7503 MFloatScratchSpace rhs(4, AT_, "rhs");
7504
7505 MFloat q[3];
7506 MFloat q0[3];
7507 MFloat tq[3];
7508 MFloat tq0[3];
7509 MFloat vrel[3];
7510 MFloat vrelhat[3];
7511 MFloat tmp[3];
7512 MFloat vort[3];
7513 MFloat strain[3];
7514
7515 // 1. predictor step
7516 for(MInt p = 0; p < m_noPointParticlesLocal; p++) {
7517 const MFloat w = m_particleQuaternionsDt1[4 * p + 0];
7518 const MFloat x = m_particleQuaternionsDt1[4 * p + 1];
7519 const MFloat y = m_particleQuaternionsDt1[4 * p + 2];
7520 const MFloat z = m_particleQuaternionsDt1[4 * p + 3];
7521 for(MInt i = 0; i < 3; i++) {
7522 q0[i] = m_particleAngularVelocityDt1[3 * p + i];
7523 }
7524 m_particleQuaternions[4 * p + 0] = w + F1B2 * dt * (-x * q0[0] - y * q0[1] - z * q0[2]);
7525 m_particleQuaternions[4 * p + 1] = x + F1B2 * dt * (w * q0[0] - z * q0[1] + y * q0[2]);
7526 m_particleQuaternions[4 * p + 2] = y + F1B2 * dt * (z * q0[0] + w * q0[1] - x * q0[2]);
7527 m_particleQuaternions[4 * p + 3] = z + F1B2 * dt * (-y * q0[0] + x * q0[1] + w * q0[2]);
7528 for(MInt i = 0; i < 3; i++) {
7529 m_particleAngularVelocity[3 * p + i] =
7531 }
7532 for(MInt i = 0; i < nDim; i++) {
7533 m_particleCoords[nDim * p + i] =
7535 + F1B2 * dt * (m_particleVelocity[nDim * p + i] + m_particleVelocityDt1[nDim * p + i])
7536 + F1B4 * POW2(dt) * (m_particleAcceleration[nDim * p + i] + m_particleAccelerationDt1[nDim * p + i]);
7537 m_particleVelocity[nDim * p + i] =
7539 }
7540
7542 }
7543
7544 // 2. compute fluid velocity
7546
7547 // 3. correction step
7548 for(MInt p = 0; p < m_noPointParticlesLocal; p++) {
7550 const MFloat beta = m_particleRadii[3 * p + 2] / m_particleRadii[3 * p];
7551 const MFloat beta2 = POW2(beta);
7552 const MFloat radius = pow(m_particleRadii[3 * p] * m_particleRadii[3 * p + 1] * m_particleRadii[3 * p + 2], F1B3);
7553 const MFloat diameter = F2 * radius;
7554 const MFloat T = sysEqn().temperature_ES(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
7555 const MFloat mue = SUTHERLANDLAW(T);
7556 const MFloat taup = F2 * m_densityRatio * POW2(radius) / (9.0 * mue / sysEqn().m_Re0);
7557 const MFloat FAC = (8.0 / 3.0) * pow(beta, F2B3) / taup;
7558 const MFloat FAC2 = (40.0 / 9.0) * pow(beta, F2B3) / taup;
7559 const MFloat FAC0 = (9.0 / 2.0) * mue / (sysEqn().m_Re0 * m_densityRatio * m_rhoInfinity * POW2(radius));
7560
7561 // integrate angular velocity
7562 const MInt maxit = 100;
7563 MFloat delta = F1;
7564 MInt it = 0;
7565
7566 W(0, 0) = F1 + dt2 * FAC2 / (m_particleShapeParams[4 * p + 1] + beta2 * m_particleShapeParams[4 * p + 3]);
7567 W(1, 1) = F1 + dt2 * FAC2 / (m_particleShapeParams[4 * p + 1] + beta2 * m_particleShapeParams[4 * p + 3]);
7568 W(2, 2) = F1 + dt2 * FAC2 / (F2 * m_particleShapeParams[4 * p + 1]);
7569 W(2, 0) = F0;
7570 W(2, 1) = F0;
7571 for(MInt i = 0; i < 3; i++) {
7572 tq0[i] = m_particleAngularAccelerationDt1[3 * p + i];
7573 q0[i] = m_particleAngularVelocityDt1[3 * p + i];
7574 tq[i] = tq0[i];
7575 q[i] = q0[i];
7576 }
7577
7578 for(MInt i = 0; i < 3; i++) {
7579 MInt id0 = (i + 1) % 3;
7580 MInt id1 = (id0 + 1) % 3;
7581 strain[i] = F1B2
7582 * (m_particleVelocityGradientFluid[9 * p + 3 * id1 + id0]
7583 + m_particleVelocityGradientFluid[9 * p + 3 * id0 + id1]);
7584 vort[i] = F1B2
7585 * (m_particleVelocityGradientFluid[9 * p + 3 * id1 + id0]
7586 - m_particleVelocityGradientFluid[9 * p + 3 * id0 + id1]);
7587 }
7588
7589 // Newton iterations
7590 while(delta > 1e-10 && it < maxit) {
7591 W(0, 1) = -dt2 * q[2] * (beta2 - F1) / (beta2 + F1);
7592 W(0, 2) = -dt2 * q[1] * (beta2 - F1) / (beta2 + F1);
7593 W(1, 0) = -dt2 * q[2] * (F1 - beta2) / (beta2 + F1);
7594 W(1, 2) = -dt2 * q[0] * (F1 - beta2) / (beta2 + F1);
7595
7596 maia::math::invert(&W(0, 0), 3, 3);
7597
7598 tq[0] = q[1] * q[2] * (beta2 - F1) / (beta2 + F1)
7599 + FAC2 * (((F1 - beta2) / (F1 + beta2)) * strain[0] + vort[0] - q[0])
7600 / (m_particleShapeParams[4 * p + 1] + beta2 * m_particleShapeParams[4 * p + 3]);
7601 tq[1] = q[0] * q[2] * (F1 - beta2) / (beta2 + F1)
7602 + FAC2 * (((beta2 - F1) / (F1 + beta2)) * strain[1] + vort[1] - q[1])
7603 / (m_particleShapeParams[4 * p + 1] + beta2 * m_particleShapeParams[4 * p + 3]);
7604 tq[2] = FAC2 * (vort[2] - q[2]) / (F2 * m_particleShapeParams[4 * p + 1]);
7605
7606 for(MInt i = 0; i < 3; i++)
7607 rhs[i] = q[i] - q0[i] - dt2 * (tq0[i] + tq[i]);
7608
7609 delta = F0;
7610 for(MInt i = 0; i < 3; i++) {
7611 const MFloat qq = q[i];
7612 for(MInt j = 0; j < 3; j++) {
7613 q[i] -= W(i, j) * rhs(j);
7614 }
7615 delta = mMax(delta, fabs(q[i] - qq));
7616 }
7617 it++;
7618 }
7619 if(it >= maxit || it <= 0) {
7620 cerr << "Newton iterations did not converge " << p << endl;
7621 }
7622
7623 m_particleAngularVelocity[3 * p + 0] = q[0];
7624 m_particleAngularVelocity[3 * p + 1] = q[1];
7625 m_particleAngularVelocity[3 * p + 2] = q[2];
7626 m_particleAngularAcceleration[3 * p + 0] = tq[0];
7627 m_particleAngularAcceleration[3 * p + 1] = tq[1];
7628 m_particleAngularAcceleration[3 * p + 2] = tq[2];
7629
7630 // integrate quaternions
7631 const MFloat w = m_particleQuaternionsDt1[4 * p + 0];
7632 const MFloat x = m_particleQuaternionsDt1[4 * p + 1];
7633 const MFloat y = m_particleQuaternionsDt1[4 * p + 2];
7634 const MFloat z = m_particleQuaternionsDt1[4 * p + 3];
7635
7636 W(0, 0) = F0;
7637 W(0, 1) = -q[0];
7638 W(0, 2) = -q[1];
7639 W(0, 3) = -q[2];
7640 W(1, 0) = q[0];
7641 W(1, 1) = F0;
7642 W(1, 2) = q[2];
7643 W(1, 3) = -q[1];
7644 W(2, 0) = q[1];
7645 W(2, 1) = -q[2];
7646 W(2, 2) = F0;
7647 W(2, 3) = q[0];
7648 W(3, 0) = q[2];
7649 W(3, 1) = q[1];
7650 W(3, 2) = -q[0];
7651 W(3, 3) = F0;
7652
7653 for(MInt i = 0; i < 4; i++)
7654 for(MInt j = 0; j < 4; j++)
7655 W(i, j) = -F1B2 * dt2 * W(i, j);
7656 for(MInt i = 0; i < 4; i++)
7657 W(i, i) = F1;
7658
7659 rhs(0) = w + F1B2 * dt2 * (-x * q0[0] - y * q0[1] - z * q0[2]);
7660 rhs(1) = x + F1B2 * dt2 * (w * q0[0] - z * q0[1] + y * q0[2]);
7661 rhs(2) = y + F1B2 * dt2 * (z * q0[0] + w * q0[1] - x * q0[2]);
7662 rhs(3) = z + F1B2 * dt2 * (-y * q0[0] + x * q0[1] + w * q0[2]);
7663
7664 maia::math::invert(&W(0, 0), 4, 4);
7665
7666 for(MInt i = 0; i < 4; i++) {
7667 m_particleQuaternions[4 * p + i] = F0;
7668 for(MInt j = 0; j < 4; j++) {
7669 m_particleQuaternions[4 * p + i] += W(i, j) * rhs(j);
7670 }
7671 }
7672
7673 MFloat abs = F0;
7674 for(MInt i = 0; i < 4; i++)
7675 abs += POW2(m_particleQuaternions[4 * p + i]);
7676 for(MInt i = 0; i < 4; i++)
7677 m_particleQuaternions[4 * p + i] /= sqrt(abs);
7678
7679 // integrate linear motion
7680 K.fill(F0);
7681 K(0, 0) = F1 / (m_particleShapeParams[4 * p] / POW2(m_particleRadii[3 * p]) + m_particleShapeParams[4 * p + 1]);
7682 K(1, 1) = K(0, 0);
7683 K(2, 2) =
7684 F1 / (m_particleShapeParams[4 * p] / POW2(m_particleRadii[3 * p]) + beta2 * m_particleShapeParams[4 * p + 3]);
7686 for(MInt i = 0; i < nDim; i++) {
7687 vrel[i] = m_particleVelocityFluid[nDim * p + i] - m_particleVelocity[nDim * p + i];
7688 }
7689 matrixVectorProduct(vrelhat, R, vrel); // principal axes frame relative velocity
7690 matrixVectorProduct(tmp, K, vrelhat);
7691 matrixVectorProductTranspose(vrel, R, tmp);
7692
7693 for(MInt i = 0; i < nDim; i++) {
7694 m_particleAcceleration[nDim * p + i] = FAC * vrel[i] + FAC0 * m_particleTerminalVelocity[i];
7695 m_particleVelocity[nDim * p + i] =
7697 + dt * F1B2 * (m_particleAcceleration[nDim * p + i] + m_particleAccelerationDt1[nDim * p + i]);
7698 m_particleCoords[nDim * p + i] =
7700 + dt * F1B2 * (m_particleVelocity[nDim * p + i] + m_particleVelocityDt1[nDim * p + i])
7701 + F1B4 * POW2(dt) * (m_particleAcceleration[nDim * p + i] + m_particleAccelerationDt1[nDim * p + i]);
7702 }
7703
7704 // temperature update
7705 const MFloat mass = F4B3 * PI * m_particleRadii[3 * p] * m_particleRadii[3 * p + 1] * m_particleRadii[3 * p + 2]
7708
7709 MFloat particleSurface = 0;
7710 if(fabs(beta - F1) < 1e-14)
7711 particleSurface = 4 * PI * POW2(m_particleRadii[3 * p]);
7712 else {
7713 if(beta < 1) {
7714 const MFloat factor = sqrt(1 - beta2);
7715 particleSurface =
7716 2 * PI * m_particleRadii[3 * p] * m_particleRadii[3 * p + 1] * (1 + (beta2 / factor * atanh(factor)));
7717 } else {
7718 const MFloat factor = sqrt(1 - 1 / beta2);
7719 particleSurface = 2 * PI * m_particleRadii[3 * p] * m_particleRadii[3 * p + 1]
7720 * (1 + m_particleRadii[3 * p + 2] / (m_particleRadii[3 * p] * factor) * asin(factor));
7721 }
7722 }
7723
7724 // nusselt correlation for sphere in Stokesian flow
7725 const MFloat nusselt = 2;
7726 const MFloat lambdaFluid = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
7727 const MFloat alpha = nusselt * lambdaFluid / diameter;
7729 m_particleHeatFlux[p] = (particleSurface * alpha * m_gamma) / (mass * Cvp * m_Pr * sysEqn().m_Re0) * deltaT;
7732 }
7733 } else {
7734 mTerm(1, AT_, "part type.");
7735 }
7736}
MFloat & a_slope(const MInt cellId, MInt const varId, const MInt dir) override
Returns the slope of the cell cellId for the variable varId in direction dir.
MFloat & a_pvariable(const MInt cellId, const MInt varId)
Returns primitive variable v of the cell cellId for variables varId.
static void computeRotationMatrix(MFloatScratchSpace &, MFloat *q)
rotation matrix co-rotating(~inertial) frame -> body-fixed frame
void setParticleFluidVelocities(MFloat *=nullptr)
static void matrixVectorProduct(MFloat *c, MFloatScratchSpace &A, MFloat *b)
c=A*b
static void matrixVectorProductTranspose(MFloat *c, MFloatScratchSpace &A, MFloat *b)
c=A^t*b
constexpr Real POW3(const Real x)
Definition: functions.h:123
constexpr Real POW2(const Real x)
Definition: functions.h:119
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
void invert(MFloat *A, const MInt m, const MInt n)
Definition: maiamath.cpp:171
define array structures

◆ advanceSolution()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::advanceSolution
Author
Lennart Schneiders

Definition at line 5151 of file fvmbcartesiansolverxd.cpp.

5151 {
5152 TRACE();
5153
5154 const MInt noCBytes = a_noCells() * m_noCVars * sizeof(MFloat);
5155 const MInt noFBytes = a_noCells() * m_noFVars * sizeof(MFloat);
5156 MFloat* RESTRICT cVars = (MFloat*)(&(a_variable(0, 0)));
5157 MFloat* RESTRICT oCVars = (MFloat*)(&(a_oldVariable(0, 0)));
5158
5159 memcpy(oCVars, cVars, noCBytes);
5160 memcpy(&(m_rhs0[0][0]), &(a_rightHandSide(0, 0)), noFBytes);
5161
5162 if(m_dualTimeStepping) memcpy(&(m_cellVolumesDt2[0]), &(m_cellVolumesDt1[0]), a_noCells() * sizeof(MFloat));
5163 memcpy(&(m_cellVolumesDt1[0]), &(a_cellVolume(0)), a_noCells() * sizeof(MFloat));
5164
5165 for(MInt cellId = 0; cellId < m_bndryGhostCellsOffset; cellId++) {
5166 a_hasProperty(cellId, SolverCell::WasInactive) = a_hasProperty(cellId, SolverCell::IsInactive);
5167 }
5168
5170
5171 m_nearBoundaryBackup.clear();
5172
5173 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
5175 if(!m_constructGField) {
5176 ASSERT(a_hasProperty(cellId, SolverCell::NearWall),
5177 to_string(m_solverId) + " " + to_string(globalDomainId()) + " " + to_string(domainId()));
5178 }
5179
5180 vector<MFloat> tmp(max(m_noCVars + m_noFVars, 0) + 1);
5181 tmp[0] = m_cellVolumesDt1[cellId];
5182
5183 for(MInt v = 0; v < m_noCVars; v++) {
5184 tmp[1 + v] = a_oldVariable(cellId, v);
5185 }
5186
5187 for(MInt v = 0; v < m_noFVars; v++) {
5188 tmp[1 + m_noCVars + v] = m_rhs0[cellId][v];
5189 }
5190
5191 m_nearBoundaryBackup.insert(make_pair(cellId, tmp));
5192 }
5193
5194 m_oldBndryCells.clear();
5195 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
5196 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
5197
5198 ASSERT(!a_isBndryGhostCell(cellId), "");
5199 if(!m_constructGField) {
5200 ASSERT(a_hasProperty(cellId, SolverCell::IsMovingBnd), "");
5201 }
5202
5203 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
5204 a_hasProperty(cellId, SolverCell::IsMovingBnd) = false;
5205 a_hasProperty(cellId, SolverCell::NearWall) = false;
5206 continue;
5207 }
5208 m_oldBndryCells.insert(make_pair(cellId, m_sweptVolume[bndryId]));
5209 }
5210 m_reComputedBndry = false;
5211
5212 for(MUint it = 0; it < m_temporarilyLinkedCells.size(); it++) {
5213 const MInt cellId = get<1>(m_temporarilyLinkedCells[it]);
5214 a_hasProperty(cellId, SolverCell::IsTempLinked) = false;
5215 }
5217 for(MInt i = 0; i < noNeighborDomains(); i++) {
5218 m_linkedWindowCells[i].clear();
5219 m_linkedHaloCells[i].clear();
5220 }
5221}
MFloat & a_rightHandSide(const MInt cellId, MInt const varId)
Returns the right hand side of the cell cellId for the variable varId.
MFloat & a_oldVariable(const MInt cellId, const MInt varId)
Returns oldVariablesv of the cell cellId variables varId.
MFloat & a_variable(const MInt cellId, const MInt varId)
Returns conservative variable v of the cell cellId for variables varId.
MBool a_isBndryGhostCell(const MInt cellId) const
Returns isBndryGhostCell of the cell cellId.
MFloat & a_cellVolume(const MInt cellId)
Returns the cell volume of the cell from the fvcellcollector cellId.
std::vector< std::tuple< MInt, MInt, MInt > > m_temporarilyLinkedCells
std::map< MInt, std::vector< MFloat > > m_nearBoundaryBackup
std::vector< MInt > * m_linkedWindowCells
void advanceExternalSource() override
advance external sources
std::vector< MInt > * m_linkedHaloCells
std::map< MInt, MFloat > m_oldBndryCells
std::vector< MInt > m_bndryLayerCells
const MInt m_solverId
a unique solver identifier
Definition: solver.h:90
MInt globalDomainId()
Return global domain id.

◆ advanceTimeStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::advanceTimeStep

◆ allocateBodyMemory()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::allocateBodyMemory ( MInt  mode = 0)
Author

Definition at line 1186 of file fvmbcartesiansolverxd.cpp.

1186 {
1187 if(mode == 1) {
1209
1210 if(m_motionEquation > 1) {
1215
1220
1222 }
1223
1228
1236
1239 }
1240
1241 mAlloc(m_bodyTerminalVelocity, nDim, "m_bodyTerminalVelocity", F0, AT_);
1242
1243 mAlloc(m_bodyCenter, nDim * m_maxNoEmbeddedBodiesPeriodic, "m_bodyCenter", F0, AT_);
1244 mAlloc(m_bodyVolume, m_noEmbeddedBodies, "m_bodyVolume", F0, AT_);
1245 mAlloc(m_bodyMass, m_noEmbeddedBodies, "m_bodyMass", F0, AT_);
1246 mAlloc(m_projectedArea, m_noEmbeddedBodies, "m_projectedArea", F0, AT_);
1247 mAlloc(m_bodyRadii, 3 * m_maxNoEmbeddedBodiesPeriodic, "m_bodyRadii", F0, AT_);
1248 mAlloc(m_bodyRadius, m_maxNoEmbeddedBodiesPeriodic, "m_bodyRadius", F0, AT_);
1249 mAlloc(m_bodyDiameter, m_maxNoEmbeddedBodiesPeriodic, "m_bodyDiameter", F0, AT_);
1250 mAlloc(m_bodyVelocity, nDim * m_maxNoEmbeddedBodiesPeriodic, "m_bodyVelocity", F0, AT_);
1251 mAlloc(m_bodyAcceleration, nDim * m_maxNoEmbeddedBodiesPeriodic, "m_bodyAcceleration", F0, AT_);
1252 mAlloc(m_bodyAngularVelocity, 3 * m_maxNoEmbeddedBodiesPeriodic, "m_bodyAngularVelocity", F0, AT_);
1253 mAlloc(m_bodyAngularVelocityDt1, 3 * m_noEmbeddedBodies, "m_bodyAngularVelocityDt1", F0, AT_);
1254 mAlloc(m_bodyTorque, 3 * m_noEmbeddedBodies, " m_bodyTorque", F0, AT_);
1255 mAlloc(m_bodyTorqueDt1, 3 * m_noEmbeddedBodies, "m_bodyTorqueDt1", F0, AT_);
1256 mAlloc(m_bodyQuaternion, 4 * m_maxNoEmbeddedBodiesPeriodic, "m_bodyQuaternion", F0, AT_);
1257 mAlloc(m_bodyQuaternionDt1, 4 * m_noEmbeddedBodies, "m_bodyQuaternionDt1", F0, AT_);
1258 mAlloc(m_bodyAngularAcceleration, 3 * m_maxNoEmbeddedBodiesPeriodic, "m_bodyAngularAcceleration", F0, AT_);
1259 mAlloc(m_bodyAngularAccelerationDt1, 3 * m_noEmbeddedBodies, "m_bodyAngularAccelerationDt1", F0, AT_);
1260 mAlloc(m_bodyDensity, m_noEmbeddedBodies, "m_bodyDensity", F0, AT_);
1261 mAlloc(m_bodyMomentOfInertia, 3 * m_noEmbeddedBodies, "m_bodyMomentOfInertia", F0, AT_);
1262 mAlloc(m_bodyAccelerationDt1, nDim * m_noEmbeddedBodies, "m_bodyAccelerationDt1", F0, AT_);
1263 mAlloc(m_bodyVelocityDt1, nDim * m_noEmbeddedBodies, "m_bodyVelocityDt1", F0, AT_);
1264 mAlloc(m_bodyCenterDt1, nDim * m_noEmbeddedBodies, "m_bodyCenterDt1", F0, AT_);
1265
1266 if(m_motionEquation > 1) {
1267 mAlloc(m_bodyAccelerationDt2, nDim * m_noEmbeddedBodies, "m_bodyAccelerationDt2", F0, AT_);
1268 mAlloc(m_bodyAccelerationDt3, nDim * m_noEmbeddedBodies, "m_bodyAccelerationDt3", F0, AT_);
1269 mAlloc(m_bodyVelocityDt2, nDim * m_noEmbeddedBodies, "m_bodyVelocityDt2", F0, AT_);
1270 mAlloc(m_bodyCenterDt2, nDim * m_noEmbeddedBodies, "m_bodyCenterDt2", F0, AT_);
1271 mAlloc(m_bodyReducedVelocity, m_noEmbeddedBodies, "m_bodyReducedVelocity", F0, AT_);
1272 mAlloc(m_bodyReducedFrequency, m_noEmbeddedBodies, "m_bodyReducedFrequency", F0, AT_);
1273 mAlloc(m_bodyReducedMass, m_noEmbeddedBodies, "m_bodyReducedMass", F0, AT_);
1274 mAlloc(m_bodyDampingCoefficient, m_noEmbeddedBodies, "m_bodyDampingCoefficient", F0, AT_);
1275 mAlloc(m_bodyNeutralCenter, nDim * m_noEmbeddedBodies, "m_bodyNeutralCenter", F0, AT_);
1276 }
1277
1278 mAlloc(m_bodyTemperature, m_noEmbeddedBodies, "m_bodyTemperature", F1, AT_);
1279 mAlloc(m_bodyTemperatureDt1, m_noEmbeddedBodies, "m_bodyTemperatureDt1", F1, AT_);
1280 mAlloc(m_bodyEquation, m_noEmbeddedBodies, "m_bodyEquation", -1, AT_);
1281 mAlloc(m_bodyInCollision, m_noEmbeddedBodies, "m_bodyInCollision", 0, AT_);
1282 mAlloc(m_periodicGhostBodies, m_noEmbeddedBodies, "m_periodicGhostBodies", AT_);
1283 mAlloc(m_internalBodyId, m_maxNoEmbeddedBodiesPeriodic, "m_internalBodyId", -1, AT_);
1284 mAlloc(m_bodyNearDomain, m_maxNoEmbeddedBodiesPeriodic, "m_bodyNearDomain", true, AT_);
1285 mAlloc(m_fixedBodyComponents, nDim, "m_fixedBodyComponents", 0, AT_);
1286 mAlloc(m_fixedBodyComponentsRotation, 3, "m_fixedBodyComponentsRotation", 0, AT_);
1287
1288 mAlloc(m_bodyForce, nDim * m_noEmbeddedBodies, "m_bodyForce", F0, AT_);
1289 mAlloc(m_bodyForceDt1, nDim * m_noEmbeddedBodies, "m_bodyForceDt1", F0, AT_);
1290 mAlloc(m_bodyHeatFlux, m_noEmbeddedBodies, "m_bodyHeatFlux", F0, AT_);
1291 mAlloc(m_hydroForce, nDim * m_noEmbeddedBodies, "m_hydroForce", F0, AT_);
1292}
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
Definition: alloc.h:173
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
Definition: alloc.h:544
std::vector< MInt > * m_periodicGhostBodies

◆ applyALECorrection()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyALECorrection
Author

Definition at line 13974 of file fvmbcartesiansolverxd.cpp.

13974 {
13975 TRACE();
13976
13977 if(m_dualTimeStepping) return;
13978
13979 const MUint noFluxVars = FV->noVariables;
13980 const MUint noPVars = PV->noVariables;
13981 const MInt noBCells = m_fvBndryCnd->m_bndryCells->size();
13982 const MUint surfaceVarMemory = 2 * noPVars;
13983 MFloat* RESTRICT area = &a_surfaceArea(0);
13984 MFloat* const RESTRICT fluxes = ALIGNED_MF(&a_surfaceFlux(0, 0));
13985 MFloat* const RESTRICT surfaceVars = ALIGNED_F(&a_surfaceVariable(0, 0, 0));
13986
13987 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBCells; bndryId++) {
13988 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
13989
13990 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
13991 if(a_isHalo(cellId)) continue;
13992
13993#if defined _ALE_FORM_
13994 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
13995#else
13996 if(a_hasProperty(cellId, SolverCell::IsSplitCell) || a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
13997#endif
13998
13999#ifdef _MB_DEBUG_
14000 MFloat totalArea = F0;
14001 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
14002 totalArea += m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
14003 }
14004#endif
14005
14006 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
14007 for(MInt i = 0; i < nDim; i++) {
14008 MInt srfcId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i];
14009 if(srfcId < 0) continue;
14010
14011#if defined _MB_DEBUG_ || !defined NDEBUG
14012 MFloat area0 = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
14013 MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
14014 ASSERT(fabs(area[srfcId] - area0 * fabs(nml)) < 1e-12,
14015 to_string(area[srfcId]) + " " + to_string(area0 * fabs(nml)));
14016#endif
14017
14018
14019#if defined _ALE_FORM_
14020 const MUint fluxOffset = srfcId * noFluxVars;
14021 const MUint offset = srfcId * surfaceVarMemory;
14022 MFloat* const RESTRICT flux = ALIGNED_MF(fluxes + fluxOffset);
14023 MFloat* const RESTRICT leftSurface = ALIGNED_F(surfaceVars + offset);
14024 const MFloat* const bndrySurf = &m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_primVars[0];
14025
14026 sysEqn().AusmALECorrection(i, area[srfcId], flux, leftSurface, bndrySurf);
14027#else
14028
14029 const MFloat PLR = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P];
14030 const MFloat VLR = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]];
14031
14032
14033 MFloatScratchSpace work(m_noCVars, FUN_, "work");
14034 for(MInt v = 0; v < m_noCVars; v++) {
14035 work[v] = F0;
14036 }
14037 work[CV->RHO_VV[i]] = PLR * area[srfcId];
14038 work[CV->RHO_E] = PLR * VLR * area[srfcId];
14039
14040 a_surfaceVariable(srfcId, 0, PV->VV[i]) = VLR;
14041 a_surfaceVariable(srfcId, 1, PV->VV[i]) = VLR;
14042
14043 const MFloat sign = (nml > F0) ? -F1 : F1;
14044 const MFloat dVdt = (a_cellVolume(cellId) - m_cellVolumesDt1[cellId]) / timeStep();
14045 const MFloat fac = area0 * POW2(nml) / mMax(m_eps, totalArea);
14046#ifdef _MB_DEBUG_
14047 for(MInt v = 0; v < m_noCVars; v++) {
14048 if(std::isnan(work[v]) || std::isnan(sign * fac * a_oldVariable(cellId, v) * dVdt)) {
14049 cerr << domainId() << ": cell " << cellId << " diverged after ALE formulation at " << globalTimeStep << " "
14050 << srfc << " " << i << " " << v << " " << a_hasProperty(cellId, SolverCell::WasInactive) << " /flx "
14051 << work[v] << " " << sign << " " << fac << " " << a_oldVariable(cellId, v) << " /vol " << dVdt << " "
14052 << a_cellVolume(cellId) << " " << m_cellVolumesDt1[cellId] << " /var " << PLR << " "
14053 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_primVars[v] << endl;
14054 }
14055 }
14056#endif
14057 for(MInt v = 0; v < m_noCVars; v++) {
14058 a_surfaceFlux(srfcId, v) = (sign * fac * a_oldVariable(cellId, v) * dVdt) + work[v];
14059 }
14060#endif
14061 }
14062 }
14063 }
14064}
MFloat & a_surfaceVariable(const MInt srfcId, const MInt dir, const MInt varId)
Returns the variable varId of surface srfcId in direction dir.
MFloat & a_surfaceFlux(const MInt srfcId, const MInt fVarId)
Returns the flux fVarId for surface srfcId.

◆ applyBoundaryCondition()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyBoundaryCondition
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 13791 of file fvmbcartesiansolverxd.cpp.

13791 {
13792 // dummy, see applyBoundaryConditionMb()
13793
13794 for(MInt i = 0; i < noNeighborDomains(); i++) {
13795 for(MInt j = 0; j < m_noMaxLevelHaloCells[i]; j++) {
13798 }
13799 }
13800
13801 if(grid().azimuthalPeriodicity()) {
13802 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
13803 for(MUint j = 0; j < m_azimuthalMaxLevelHaloCells[i].size(); j++) {
13806 }
13807 }
13808 }
13809
13810 // update split childs after exchange()
13811 for(MUint sc = 0; sc < m_splitCells.size(); sc++) {
13812 const MInt cellId = m_splitCells[sc];
13813 if(!a_isHalo(cellId)) continue;
13814 MFloat volCnt = F0;
13815 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
13816 const MInt splitChildId = m_splitChilds[sc][ssc];
13817 for(MInt v = 0; v < m_noCVars; v++) {
13818 a_variable(splitChildId, v) = a_variable(cellId, v);
13819 }
13820 for(MInt v = 0; v < m_noFVars; v++) {
13821 a_rightHandSide(splitChildId, v) = a_rightHandSide(cellId, v);
13822 m_rhs0[splitChildId][v] = m_rhs0[cellId][v];
13823 }
13824 volCnt += a_cellVolume(splitChildId);
13825 }
13826 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
13827 const MInt splitChildId = m_splitChilds[sc][ssc];
13828 volCnt = mMax(volCnt, 1e-15);
13829 for(MInt v = 0; v < m_noFVars; v++) {
13830 a_rightHandSide(splitChildId, v) *= a_cellVolume(splitChildId) / volCnt;
13831 m_rhs0[splitChildId][v] *= a_cellVolume(splitChildId) / volCnt;
13832 }
13833 setPrimitiveVariables(splitChildId);
13834 }
13835 }
13836
13837
13838 // if ( m_noPointParticles > 0 ) advancePointParticles();
13840
13841 if(m_RKStep != 0 || globalTimeStep == 0) return;
13844 MFloat eRhoL1 = F0;
13845 MFloat eRhoL2 = F0;
13846 MFloat eRhoLoo = F0;
13847 MFloat eVelL1 = F0;
13848 MFloat eVelL2 = F0;
13849 MFloat eVelLoo = F0;
13850 MFloat counter = F0;
13851 MFloat mass = F0;
13852 MFloat vol = F0;
13853 MFloat oldVol = F0;
13854 MFloat rhs = F0;
13855 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
13856 if(a_isBndryGhostCell(cellId)) continue;
13857 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
13858 if(a_isPeriodic(cellId)) continue;
13859 if(a_isHalo(cellId)) continue;
13860 if(c_noChildren(cellId) > 0) continue;
13861 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
13862 // if ( a_coordinate( cellId , 0) < m_bodyCenter[0]) continue;
13863 if(a_coordinate(cellId, 0) > m_bodyCenter[0]) continue;
13864 rhs += a_rightHandSide(cellId, CV->RHO);
13865 MFloat vel = F0;
13866 for(MInt i = 0; i < nDim; i++)
13867 vel += POW2(a_pvariable(cellId, PV->VV[i]) - m_VVInfinity[i]);
13868 vel = sqrt(vel);
13869 eRhoL1 += fabs(a_pvariable(cellId, PV->RHO) - m_rhoInfinity);
13870 eRhoL2 += POW2(a_pvariable(cellId, PV->RHO) - m_rhoInfinity);
13871 eRhoLoo = mMax(eRhoLoo, fabs(a_pvariable(cellId, PV->RHO) - m_rhoInfinity));
13872 eVelL1 += fabs(vel);
13873 eVelL2 += POW2(vel);
13874 eVelLoo = mMax(eVelLoo, fabs(vel));
13875 counter += F1;
13876 mass += a_cellVolume(cellId) * a_variable(cellId, CV->RHO);
13877 vol += a_cellVolume(cellId);
13878 oldVol += m_cellVolumesDt1[cellId];
13879 }
13880 MFloat delta = F0;
13881 MFloat area = F0;
13882 for(MInt bs = 0; bs < m_fvBndryCnd->m_noBoundarySurfaces; bs++) {
13883 MInt srfcId = m_fvBndryCnd->m_boundarySurfaces[bs];
13884 if(a_surfaceBndryCndId(srfcId) / 1000 == 3) {
13885 continue;
13886 }
13888 delta -= a_surfaceFlux(srfcId, CV->RHO);
13889 else
13890 delta += a_surfaceFlux(srfcId, CV->RHO);
13891 area += a_surfaceArea(srfcId);
13892 }
13893 MPI_Allreduce(MPI_IN_PLACE, &mass, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "mass");
13894 MPI_Allreduce(MPI_IN_PLACE, &delta, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "delta");
13895 MPI_Allreduce(MPI_IN_PLACE, &vol, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "vol");
13896 MPI_Allreduce(MPI_IN_PLACE, &oldVol, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "oldVol");
13906 if(firstRun) {
13907 ERhoL1 = F0;
13908 ERhoL2 = F0;
13909 ERhoLoo = F0;
13910 EVelL1 = F0;
13911 EVelL2 = F0;
13912 EVelLoo = F0;
13913 refMass = mass;
13914 oldMass = mass;
13915 oldVol2 = vol;
13916 }
13917 ERhoL1 += eRhoL1;
13918 ERhoL2 += eRhoL2;
13919 ERhoLoo = mMax(ERhoLoo, eRhoLoo);
13920 EVelL1 += eVelL1;
13921 EVelL2 += eVelL2;
13922 EVelLoo = mMax(EVelLoo, eVelLoo);
13923 refMass -= timeStep() * delta;
13924 oldMass -= timeStep() * delta;
13926 if(domainId() == 0) {
13927 ofstream ofl;
13928 if(firstRun)
13929 ofl.open("mass_loss", ios_base::out | ios_base::trunc);
13930 else
13931 ofl.open("mass_loss", ios_base::out | ios_base::app);
13932 cerr << "mass defect" << globalTimeStep << " (" << delta * timeStep() << ") " << refMass - mass << " "
13933 << oldMass - mass //<< " " << area
13934 << " //vol " << vol - oldVol << " (" << oldVol - oldVol2 << ") " << setprecision(16)
13935 << timeStep() * (rhs - delta);
13936 if(m_noCellsInsideSpongeLayer > 0) cerr << " | Warning: sponge is on!";
13937 cerr << setprecision(6) << endl;
13938 if(ofl.is_open() && ofl.good()) {
13939 ofl << "mass defect" << setprecision(10) << globalTimeStep << " (" << delta * timeStep() << ") "
13940 << refMass - mass << " " << oldMass - mass //<< " " << area
13941 << " //vol " << vol - oldVol << " (" << oldVol - oldVol2 << ") " << timeStep() * (rhs - delta) << endl;
13942 ofl.close();
13943 }
13944 }
13945 if(m_initialCondition == 474) {
13946 cerr << domainId() << ": ERROR rho " << globalTimeStep << " " << m_bodyCenter[0] / m_bodyDiameter[0] << " // "
13947 << eRhoLoo << " " << eRhoL1 / counter << " " << sqrt(eRhoL2 / counter) << " // " << ERhoLoo << " "
13948 << ERhoL1 / (counter * FTS) << " " << sqrt(ERhoL2 / (counter * FTS));
13949 cerr << " ||| ERROR vel " << eVelLoo << " " << eVelL1 / counter << " " << sqrt(eVelL2 / counter) << " // "
13950 << EVelLoo << " " << EVelL1 / (counter * FTS) << " " << sqrt(EVelL2 / (counter * FTS)) << endl;
13951 if(domainId() == 0) {
13952 ofstream ofl;
13953 ofl.open("mass_error", ios_base::out | ios_base::app);
13954 if(ofl.is_open() && ofl.good()) {
13955 ofl << setprecision(16) << m_time << " " << fabs(refMass - mass) << " " << fabs(oldMass - mass) << " "
13956 << eRhoLoo << " " << eRhoL1 / counter << " " << eVelLoo << " " << eVelL1 / counter << endl;
13957 ofl.close();
13958 }
13959 }
13960 if(m_bodyCenter[0] > m_bodyDiameter[0]) mTerm(0, AT_, "one diameter traveled.");
13961 }
13962 oldMass = mass;
13963 oldVol2 = vol;
13964 firstRun = false;
13965 }
13966}
std::vector< std::vector< MInt > > m_splitChilds
virtual void setConservativeVariables(MInt cellId)
computes conservative from primitive variables for given cell id
std::vector< std::vector< MInt > > m_azimuthalMaxLevelHaloCells
void setPrimitiveVariables(MInt cellId)
computes primitive from primitive variables for given cell id. This is the version for all SysEqn.
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce

◆ applyBoundaryConditionMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyBoundaryConditionMb
Author
Lennart Schneiders

Definition at line 18100 of file fvmbcartesiansolverxd.cpp.

18100 {
18101 TRACE();
18102
18103 applyDirichletCondition(); // apply Dirichlet boundary conditions
18104 applyNeumannCondition(); // apply Neumann boundary conditions
18105
18106#if defined _MB_DEBUG_ || !defined NDEBUG
18107 m_solutionDiverged = false;
18108 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
18109 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
18110 const MInt cellId = m_fvBndryCnd->m_bndryCell[bndryId].m_cellId;
18111 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
18112 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
18113 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
18114 for(MInt v = 0; v < m_noPVars; v++) {
18115 const MFloat val = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v];
18116 const MFloat val2 = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_normalDeriv[v];
18117 if(std::isnan(val) || std::isinf(val)) {
18118 cerr << setprecision(16) << domainId() << ": bnd surf var div after BC: " << globalTimeStep << "/" << m_RKStep
18119 << " " << cellId << " " << c_globalId(cellId) << " "
18120 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume / grid().gridCellVolume(a_level(cellId)) << " "
18121 << c_noChildren(cellId) << " " << a_isHalo(cellId) << " "
18122 << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " "
18123 << m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size() << " "
18124 << a_hasProperty(cellId, SolverCell::IsInactive) << ", " << srfc << " " << getPrimitiveVarName(v) << " "
18125 << val << " " << a_pvariable(cellId, v) << endl;
18126 m_solutionDiverged = true;
18127 }
18128 if(std::isnan(val2) || std::isinf(val2)) {
18129 cerr << domainId() << ": bnd surf grad div after BC: " << globalTimeStep << "/" << m_RKStep << " " << cellId
18130 << " " << c_globalId(cellId) << " " << m_volumeFraction[bndryId] << " " << c_noChildren(cellId) << " "
18131 << a_isHalo(cellId) << " " << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " "
18132 << m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size() << " "
18133 << a_hasProperty(cellId, SolverCell::IsInactive) << " / " << srfc << " " << getPrimitiveVarName(v) << " "
18134 << val2 << endl;
18135 m_solutionDiverged = true;
18136 }
18137 }
18138 if(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] < F0
18139 || m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] < F0) {
18140 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
18141 cerr << domainId() << ": bnd surf var negative after BC: " << globalTimeStep << "/" << m_RKStep << " " << cellId
18142 << " " << c_globalId(cellId) << " " << m_volumeFraction[bndryId] << " " << a_level(cellId) << " "
18143 << c_noChildren(cellId) << " " << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " "
18144 << a_isHalo(cellId) << " " << a_hasProperty(cellId, SolverCell::IsNotGradient) << " "
18145 << m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size() << " "
18146 << a_hasProperty(cellId, SolverCell::IsInactive) << " / " << srfc << " " << a_pvariable(cellId, PV->P)
18147 << " " << a_pvariable(cellId, PV->RHO) << " / "
18148 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] << " "
18149 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] << " / "
18150 << a_pvariable(ghostCellId, PV->P) << " " << a_pvariable(ghostCellId, PV->RHO) << " v "
18151 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[0]] << " "
18152 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[1]] << " "
18153 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[2]] << " "
18154 << c_coordinate(cellId, 0) << " " << c_coordinate(cellId, 1) << " " << c_coordinate(cellId, nDim - 1)
18155 << endl;
18156 m_solutionDiverged = true;
18157 }
18158 }
18159 }
18160 if(m_solutionDiverged) {
18161 cerr << "Solution diverged (BC) at solver " << domainId() << " " << globalTimeStep << " " << m_RKStep << endl;
18162 }
18163 MPI_Allreduce(MPI_IN_PLACE, &m_solutionDiverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
18164 "m_solutionDiverged");
18165
18166 if(m_solutionDiverged) {
18167 writeVtkXmlFiles("QOUT", "GEOM", false, true);
18168 MPI_Barrier(mpiComm(), AT_);
18169 mTerm(1, AT_, "Solution diverged after BC handling.");
18170 }
18171#endif
18172}
MFloat c_coordinate(const MInt cellId, const MInt dir) const
Returns the coordinate of the cell from the grid().tree() cellId for dimension dir.
void writeVtkXmlFiles(const MString fileName, const MString GFileName, MBool regularOutput, MBool diverged) override
write flow variables as XML VTK files
MString getPrimitiveVarName(MInt i)
returns the name of the primitive variable at the given index i
int MPI_Barrier(MPI_Comm comm, const MString &name)
same as MPI_Barrier

◆ applyBoundaryConditionSlope()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyBoundaryConditionSlope
Author
Lennart Schneiders

Definition at line 11468 of file fvmbcartesiansolverxd.cpp.

11468 {
11469 TRACE();
11470
11471 mTerm(1, AT_, "deprecated, ghost cells are not anticipated for memory efficiency.");
11472
11473 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
11474 const MInt cellId = m_bndryLayerCells[c];
11475
11476 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
11477 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
11478 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
11479 if(a_isBndryGhostCell(cellId)) continue;
11480 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
11481 if(a_bndryId(cellId) < -1) continue;
11482 if(c_noChildren(cellId) > 0) continue;
11483
11484 const MInt bndryId = a_bndryId(cellId);
11485 MFloatScratchSpace dummyPvariables(m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs, PV->noVariables, AT_,
11486 "dummyPvariables");
11487 for(MInt set = m_startSet; set < m_noSets; set++) {
11488 if(a_associatedBodyIds(cellId, set) < 0) continue;
11489
11490 const MInt ghostCellId = -1; // m_nearBndryGhostCells[c][set];
11491
11492 if(ghostCellId < 0) continue;
11493 const MInt bodyId = a_associatedBodyIds(cellId, set);
11494 if(bodyId < 0) {
11495 cerr << "Warning: no associated body" << endl;
11496 continue;
11497 }
11498 const MFloat phi = a_levelSetValuesMb(cellId, set);
11499 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
11500 MFloat vel[3] = {F0, F0, F0};
11501 MFloat xsurf[3] = {F0, F0, F0};
11502 MFloat normal[3] = {F0, F0, F0};
11503 MInt srfc = -1;
11504 if(bndryId >= m_noOuterBndryCells) {
11505 for(MInt s = 0; s < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; s++) {
11506 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[s]->m_bodyId[0] == bodyId) {
11507 srfc = s;
11508 break;
11509 }
11510 }
11511 if(srfc < 0 && m_noLevelSetsUsedForMb == 1) mTerm(1, AT_, "srfc not found.");
11512 }
11513
11514 for(MInt i = 0; i < nDim; i++) {
11515 normal[i] = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVectorCentroid[i];
11516 }
11517
11518 for(MInt i = 0; i < nDim; i++) {
11519 vel[i] = m_bodyVelocity[bodyId * nDim + i];
11520 xsurf[i] = a_coordinate(cellId, i) - phi * normal[i];
11521 }
11522
11523 MFloat dx[3] = {F0, F0, F0};
11524 MFloat omega[3] = {F0, F0, F0};
11525
11526 for(MInt i = 0; i < nDim; i++) {
11527 dx[i] = xsurf[i] - m_bodyCenter[bodyId * nDim + i];
11528 }
11529
11530 for(MInt i = 0; i < 3; i++) {
11531 omega[i] = m_bodyAngularVelocity[bodyId * 3 + i];
11532 }
11533
11534 vel[0] += omega[1] * dx[2] - omega[2] * dx[1];
11535 vel[1] += omega[2] * dx[0] - omega[0] * dx[2];
11536 IF_CONSTEXPR(nDim == 3) { vel[2] += omega[0] * dx[1] - omega[1] * dx[0]; }
11537
11538 if(m_euler) {
11539 MFloat vel2[3];
11540 for(MInt i = 0; i < nDim; i++) {
11541 vel2[i] = a_pvariable(cellId, PV->VV[i]);
11542 for(MInt j = 0; j < nDim; j++) {
11543 vel2[i] += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
11544 * (vel[i] - a_pvariable(cellId, PV->VV[j]))
11545 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[j];
11546 }
11547 }
11548 for(MInt i = 0; i < nDim; i++) {
11549 vel[i] = vel2[i];
11550 }
11551 }
11552
11553 MFloat imageVel[3];
11554 for(MInt i = 0; i < nDim; i++) {
11555 imageVel[i] = a_pvariable(cellId, PV->VV[i]);
11556 }
11557 if(bndryId >= m_noOuterBndryCells && srfc > -1) {
11558 for(MInt s = 0; s < mMin((signed)m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size(),
11559 m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs);
11560 s++) {
11561 for(MInt i = 0; i < nDim; i++) {
11562 dummyPvariables(s, PV->VV[i]) = vel[i];
11563 }
11564 }
11565 for(MInt i = 0; i < nDim; i++) {
11566 imageVel[i] = F0;
11567 }
11568 for(MInt n = 0; n < (signed)m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size(); n++) {
11569 const MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
11570 for(MInt i = 0; i < nDim; i++) {
11571 const MFloat nghbrPvariable = (n < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs)
11572 ? dummyPvariables(n, PV->VV[i])
11573 : a_pvariable(nghbrId, PV->VV[i]);
11574 imageVel[i] +=
11575 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariable;
11576 }
11577 }
11578 MFloat vf = a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId));
11579 MFloat fac = maia::math::deltaFun(vf, 0.95, F1);
11580 for(MInt i = 0; i < nDim; i++) {
11581 imageVel[i] = (fac * a_pvariable(cellId, PV->VV[i]) + (F1 - fac) * imageVel[i]);
11582 }
11583 }
11584
11585
11586 for(MInt i = 0; i < nDim; i++) {
11587 a_pvariable(ghostCellId, PV->VV[i]) = F2 * vel[i] - imageVel[i];
11588 }
11589
11590
11591 MFloat dn = F0;
11592 for(MInt i = 0; i < nDim; i++) {
11593 dn += (a_coordinate(cellId, i) - a_coordinate(ghostCellId, i)) * normal[i];
11594 }
11595 dn -= phi;
11596 if(dn + phi < 1e-8) {
11597 cerr << domainId() << ": warning very small distance " << c_globalId(cellId) << " " << phi << " " << dn << endl;
11598 }
11599
11600 MFloat delta[3] = {F0, F0, F0};
11601 MFloat dr[3] = {F0, F0, F0};
11602 MFloat dw[3] = {F0, F0, F0};
11603 MFloat dg[3] = {F0, F0, F0};
11604 MFloat du[3] = {F0, F0, F0};
11605 MFloat dv[3] = {F0, F0, F0};
11606 for(MInt i = 0; i < nDim; i++) {
11607 dr[i] = a_coordinate(cellId, i) - phi * normal[i] - m_bodyCenter[bodyId * nDim + i];
11608 du[i] = m_bodyAcceleration[bodyId * nDim + i];
11609 dv[i] = vel[i] - m_bodyVelocity[bodyId * nDim + i];
11610 }
11611 for(MInt i = 0; i < 3; i++) {
11612 dw[i] = m_bodyAngularAcceleration[bodyId * 3 + i];
11613 dg[i] = m_bodyAngularVelocity[bodyId * 3 + i];
11614 }
11615 // assemble material acceleration
11616 delta[0] = du[0] + dw[1] * dr[2] - dw[2] * dr[1] + dg[1] * dv[2] - dg[2] * dv[1];
11617 delta[1] = du[1] + dw[2] * dr[0] - dw[0] * dr[2] + dg[2] * dv[0] - dg[0] * dv[2];
11618 delta[2] = du[2] + dw[0] * dr[1] - dw[1] * dr[0] + dg[0] * dv[1] - dg[1] * dv[0];
11619
11620 MFloat an = F0;
11621 for(MInt i = 0; i < nDim; i++) {
11622 an += normal[i] * delta[i];
11623 }
11624
11625 MFloat surfTemp = sysEqn().temperature_ES(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
11626 const MFloat beta = sysEqn().density_ES(an, surfTemp);
11627 const MFloat fac = (F1 + F1B2 * beta * (dn + phi)) / (F1 - F1B2 * beta * (dn + phi));
11628
11629 a_pvariable(ghostCellId, PV->P) = fac * a_pvariable(cellId, PV->P);
11630 a_pvariable(ghostCellId, PV->RHO) = fac * a_pvariable(cellId, PV->RHO);
11631 }
11632 }
11633}
MFloat & a_levelSetValuesMb(const MInt cellId, const MInt set)
Returns the levelSetMb-value for fv-CellId cellId and set.
MInt & a_associatedBodyIds(const MInt cellId, const MInt set)
Returns the associatedBodyIds for fv-CellId cellId and set.
MInt & a_bndryId(const MInt cellId)
Returns the bndryId of the cell cellId.
constexpr T mMin(const T &x, const T &y)
Definition: functions.h:90
MFloat deltaFun(const MFloat r, const MFloat r0, const MFloat r1)
Definition: maiamath.h:885

◆ applyDirichletCondition()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyDirichletCondition
Author
Lennart Schneiders

Definition at line 17842 of file fvmbcartesiansolverxd.cpp.

17842 {
17843#ifndef NDEBUG
17844 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
17845 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
17846 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
17847 ASSERT(a_associatedBodyIds(cellId, 0) > -1
17849 "associated body is invalid: " + to_string(0) + "/" + to_string(a_associatedBodyIds(cellId, 0)) + " "
17850 + to_string(c_globalId(cellId)));
17851 }
17852#endif
17853
17854 m_fvBndryCnd->updateGhostCellVariables();
17855}

◆ applyExternalOldSource()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyExternalOldSource
overridevirtual
Author
Tim Wegmann

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 14208 of file fvmbcartesiansolverxd.cpp.

14208 {
14209 TRACE();
14210
14211 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
14212 if(!a_hasProperty(cellId, SolverCell::IsActive)) continue;
14213 for(MInt var = 0; var < CV->noVariables; var++) {
14214 m_rhs0[cellId][var] -= m_externalSourceDt1[cellId][var];
14215 }
14216 }
14217}

◆ applyExternalSource()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyExternalSource
overridevirtual
Author
Tim Wegmann

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 14162 of file fvmbcartesiansolverxd.cpp.

14162 {
14163 TRACE();
14164
14165 if(m_RKStep == m_noRKSteps - 1) {
14166 // applying the complete source term at the last RK-step for conservation!
14167 // i.e. devide by RK-factor
14168 // this requires that the rhs0 is free of the old/current source term
14169 MFloat beta = 1 / m_RKalpha[m_RKStep - 1];
14170 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
14171 if(!a_hasProperty(cellId, SolverCell::IsActive)) continue;
14172 for(MInt var = 0; var < CV->noVariables; var++) {
14173 a_rightHandSide(cellId, var) += beta * a_externalSource(cellId, var);
14174 if(std::isnan(a_externalSource(cellId, var))) {
14175 cerr << domainId() << " " << cellId << " " << var << " " << a_coordinate(cellId, 0) << " "
14176 << a_coordinate(cellId, 1) << " " << a_coordinate(cellId, nDim - 1) << " " << var << endl;
14177 mTerm(1, AT_, "External source is nan!");
14178 }
14179 }
14180 }
14181 } else {
14182 if(m_RKStep != 3) {
14183 // apply partial old/current source term to the rightHandSide
14184 // here a devision by the rk-Factor is not necessary as the same source term is
14185 // also applied to the rhs0
14186 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
14187 if(!a_hasProperty(cellId, SolverCell::IsActive)) continue;
14188 for(MInt var = 0; var < CV->noVariables; var++) {
14189 a_rightHandSide(cellId, var) += a_externalSource(cellId, var);
14190 }
14191 }
14192 } else {
14193 // apply old external source
14194 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
14195 if(!a_hasProperty(cellId, SolverCell::IsActive)) continue;
14196 for(MInt var = 0; var < CV->noVariables; var++) {
14197 a_rightHandSide(cellId, var) += m_externalSourceDt1[cellId][var];
14198 }
14199 }
14200 }
14201 }
14202}

◆ applyInitialCondition()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyInitialCondition
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 1522 of file fvmbcartesiansolverxd.cpp.

1522 {
1523 TRACE();
1524
1528}
virtual void applyInitialCondition()
Initializes the entire flow field.
void setInfinityState()
Computes/defines the infinity values/state once and for all Ideally the infinity variables should not...
void updateInfinityVariables()
update infinity state for certain testcases with constructed level-set field!

◆ applyNeumannCondition()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::applyNeumannCondition
Author
Lennart Schneiders

Definition at line 17863 of file fvmbcartesiansolverxd.cpp.

17863 {
17864#ifndef NDEBUG
17865 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
17866 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
17867 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
17868 ASSERT(a_associatedBodyIds(cellId, 0) > -1
17870 "associated body is invalid: " + to_string(0) + "/" + to_string(a_associatedBodyIds(cellId, 0)));
17871 }
17872#endif
17873
17874 m_fvBndryCnd->applyNeumannBoundaryCondition();
17875}

◆ ATTRIBUTES1() [1/11]

template<MInt nDim, class SysEqn >
template<MInt timeStepMethod>
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )

◆ ATTRIBUTES1() [2/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )

◆ ATTRIBUTES1() [3/11]

template<MInt nDim, class SysEqn >
template<MInt timeStepMethod>
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )

◆ ATTRIBUTES1() [4/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )
override

◆ ATTRIBUTES1() [5/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )

◆ ATTRIBUTES1() [6/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )

◆ ATTRIBUTES1() [7/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )
override

◆ ATTRIBUTES1() [8/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )
override

◆ ATTRIBUTES1() [9/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  ) const
override

◆ ATTRIBUTES1() [10/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )
override

◆ ATTRIBUTES1() [11/11]

template<MInt nDim, class SysEqn >
FvMbCartesianSolverXD< nDim, SysEqn >::ATTRIBUTES1 ( ATTRIBUTE_HOT  )
override

◆ balance()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::balance ( const MInt *const  noCellsToReceiveByDomain,
const MInt *const  noCellsToSendByDomain,
const MInt *const  sortedCellId,
const MInt  oldNoCells 
)
override
Author
Jerry Grimmen, Lennart Schneiders, Ansgar Niemoeller

Definition at line 14693 of file fvmbcartesiansolverxd.cpp.

14695 {
14696 TRACE();
14697
14698 // set only restart to true for the next initSolutionStep call!
14699 m_onlineRestart = true;
14700
14701 // additional data to the fv-solver to-be saved during the balancing:
14702 // if globalTimeStep < -1: nothing additionally
14703 // if globalTimeStep > -1:
14704 // - a_rightHandSide
14705 // - m_sweptVolume (in sweptVolBalance)
14706 // - a_properties (in propsBalance and later in propsBak)
14707 // if dualTimeStepping:
14708 // - m_cellVolumesDt1
14709
14710 if(!isActive()) {
14711 grid().update();
14712 FvCartesianSolverXD<nDim, SysEqn>::updateDomainInfo(-1, -1, MPI_COMM_NULL, AT_);
14713 return;
14714 }
14715
14716 MFloatScratchSpace RHS(noCellsToReceiveByDomain[noDomains()], CV->noVariables, FUN_, "RHS");
14717 MFloatScratchSpace cellVolumesDt1((m_dualTimeStepping ? noCellsToReceiveByDomain[noDomains()] : 1), FUN_,
14718 "cellVolumesDt1");
14719 ScratchSpace<maia::fv::cell::BitsetType> props(noCellsToReceiveByDomain[noDomains()], FUN_, "props");
14720 MFloatScratchSpace sweptVol(noCellsToReceiveByDomain[noDomains()], FUN_, "sweptVol");
14721
14722 MBool azimuthal = grid().azimuthalPeriodicity();
14723
14724 if(globalTimeStep > -1) {
14725 MFloatScratchSpace sweptVolBalance(oldNoCells, FUN_, "sweptVolBalance");
14726 ScratchSpace<maia::fv::cell::BitsetType> propsBalance(oldNoCells, FUN_, "propsBalance");
14727 MFloatScratchSpace rightHandSideBalance(oldNoCells, CV->noVariables, FUN_, "rightHandSideBalance");
14728 MFloatScratchSpace volumeDt1Balance(oldNoCells, FUN_, "volumeDt1Balance");
14729
14730 sweptVolBalance.fill(std::numeric_limits<MFloat>::lowest());
14731 propsBalance.fill(maia::fv::cell::BitsetType());
14732
14733 rightHandSideBalance.fill(-1);
14734 volumeDt1Balance.fill(-1);
14735
14736 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14737 assertValidGridCellId(cellId);
14738 MInt gridCellId = grid().tree().solver2grid(cellId);
14739
14740 propsBalance(gridCellId) = a_properties(cellId);
14741
14742 for(MInt variable = 0; variable < CV->noVariables; variable++) {
14743 rightHandSideBalance(gridCellId, variable) = a_rightHandSide(cellId, variable);
14744 }
14745 }
14746 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
14747 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
14748 ASSERT(!a_isBndryGhostCell(cellId), "");
14749 if(a_isHalo(cellId)) continue;
14750 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
14751 assertValidGridCellId(cellId);
14752 MInt gridCellId = grid().tree().solver2grid(cellId);
14753 // ASSERT( gridCellId < noCellsToSendByDomain[noDomains()], "" );
14754 ASSERT(a_hasProperty(cellId, SolverCell::IsMovingBnd), "");
14755 sweptVolBalance(gridCellId) = m_sweptVolume[bndryId];
14756 }
14757
14758 if(m_dualTimeStepping) {
14759 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14760 MInt gridCellId = grid().tree().solver2grid(cellId);
14761 volumeDt1Balance(gridCellId) = m_cellVolumesDt1[cellId];
14762 }
14763 }
14764
14765
14766 // Azimuthal periodicity
14767 {
14768 MInt noAziDataToSend = 1;
14769 MInt noAziDataToReceive = 1;
14770 MIntScratchSpace sndSizeAzi(noDomains(), FUN_, "sndSizeAzi");
14771 sndSizeAzi.fill(0);
14772 MIntScratchSpace rcvSizeAzi(noDomains(), FUN_, "rcvSizeAzi");
14773 rcvSizeAzi.fill(0);
14774 MIntScratchSpace sortedIdMap(oldNoCells, FUN_, "sortedIdMap");
14775 sortedIdMap.fill(0);
14776 if(azimuthal) {
14777 m_wasBalanced = true;
14778
14779 MIntScratchSpace sortedCntsAzi(oldNoCells, FUN_, "sortedCntsAzi");
14780 sortedCntsAzi.fill(0);
14781 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14782 MInt gridCellId = grid().tree().solver2grid(cellId);
14783 if(sortedCellId[gridCellId] < 0) continue;
14784 MLong gCellId = c_globalId(cellId);
14785 sortedCntsAzi[sortedCellId[gridCellId]] = m_azimuthalNearBoundaryBackup.count(gCellId);
14786 }
14787 MInt cnt = 0;
14788 for(MInt i = 0; i < oldNoCells; i++) {
14789 sortedIdMap[i] = cnt;
14790 cnt += sortedCntsAzi[i];
14791 }
14792 MInt offset = 0;
14793 for(MInt i = 0; i < noDomains(); i++) {
14794 for(MInt j = 0; j < noCellsToSendByDomain[i]; j++) {
14795 sndSizeAzi[i] += sortedCntsAzi[offset + j];
14796 }
14797 offset += noCellsToSendByDomain[i];
14798 }
14799 MIntScratchSpace dummyScratch(noDomains(), FUN_, "dummyScratch");
14800 dummyScratch.fill(1);
14801 maia::mpi::exchangeData(&sndSizeAzi[0], domainId(), noDomains(), mpiComm(), 1, &dummyScratch[0],
14802 &dummyScratch[0], &rcvSizeAzi[0]);
14803
14804 noAziDataToSend = mMax(1, std::accumulate(&sndSizeAzi[0], &sndSizeAzi[0] + noDomains(), 0));
14805 noAziDataToReceive = mMax(1, std::accumulate(&rcvSizeAzi[0], &rcvSizeAzi[0] + noDomains(), 0));
14806 }
14807
14808 ScratchSpace<MLong> globalIdAzi(noAziDataToReceive, FUN_, "globalIdAzi");
14809 MFloatScratchSpace cellVolumesAzi(noAziDataToReceive, FUN_, "cellVolumesAzi");
14810 MFloatScratchSpace cellVolumesDt1Azi(noAziDataToReceive, FUN_, "cellVolumesDt1Azi");
14811 MFloatScratchSpace sweptVolAzi(noAziDataToReceive, FUN_, "sweptVolAzi");
14812 ScratchSpace<MUlong> bndryCntAzi(noAziDataToReceive, FUN_, "bndryCntAzi");
14813 ScratchSpace<MUlong> propsAzi(noAziDataToReceive, FUN_, "propsAzi");
14814 MFloatScratchSpace variablesAzi(noAziDataToReceive, CV->noVariables, FUN_, "variablesAzi");
14815 MFloatScratchSpace imageCoordsAzi(noAziDataToReceive, nDim, FUN_, "imageCoordsAzi");
14816 globalIdAzi.fill(-1);
14817 cellVolumesAzi.fill(-1.0);
14818 cellVolumesDt1Azi.fill(-1.0);
14819 sweptVolAzi.fill(std::numeric_limits<MFloat>::lowest());
14820 bndryCntAzi.fill(0);
14821 propsAzi.fill(0);
14822 variablesAzi.fill(-1.0);
14823 imageCoordsAzi.fill(-1.0);
14824 MLongScratchSpace globalIdAziBalance(noAziDataToSend, FUN_, "globalIdAziBalance");
14825 MFloatScratchSpace cellVolumesAziBalance(noAziDataToSend, FUN_, "cellVolumesAziBalance");
14826 MFloatScratchSpace cellVolumesDt1AziBalance(noAziDataToSend, FUN_, "cellVolumesDt1AziBalance");
14827 MFloatScratchSpace sweptVolAziBalance(noAziDataToSend, FUN_, "sweptVolAziBalance");
14828 ScratchSpace<MUlong> bndryCntAziBalance(noAziDataToSend, FUN_, "bndryCntAziBalance");
14829 ScratchSpace<MUlong> propsAziBalance(noAziDataToSend, FUN_, "propsAziBalance");
14830 MFloatScratchSpace variablesAziBalance(noAziDataToSend, CV->noVariables, FUN_, "variablesAziBalance");
14831 MFloatScratchSpace imageCoordsAziBalance(noAziDataToSend, nDim, FUN_, "imageCoordsAziAziBalance");
14832 globalIdAziBalance.fill(-1);
14833 cellVolumesAziBalance.fill(-1);
14834 cellVolumesDt1AziBalance.fill(-1);
14835 sweptVolAziBalance.fill(std::numeric_limits<MFloat>::lowest());
14836 bndryCntAziBalance.fill(0);
14837 propsAziBalance.fill(0);
14838 variablesAziBalance.fill(-1.0);
14839 imageCoordsAziBalance.fill(-1.0);
14840
14841 if(azimuthal) {
14842 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14843 MInt gridCellId = grid().tree().solver2grid(cellId);
14844 if(sortedCellId[gridCellId] < 0) continue;
14845 MLong gCellId = c_globalId(cellId);
14846 if(m_azimuthalNearBoundaryBackup.count(gCellId) != 0) {
14847 MInt cnt = 0;
14848 auto range = m_azimuthalNearBoundaryBackup.equal_range(gCellId);
14849 for(auto it = range.first; it != range.second; ++it) {
14850 globalIdAziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt) = gCellId;
14851 cellVolumesAziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt) = (it->second).first[nDim];
14852 cellVolumesDt1AziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt) = (it->second).first[nDim + 1];
14853 sweptVolAziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt) = (it->second).first[nDim + 2];
14854 bndryCntAziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt) = (it->second).second[0];
14855 propsAziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt) = (it->second).second[1];
14856 for(MInt v = 0; v < CV->noVariables; v++) {
14857 variablesAziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt, v) = (it->second).first[nDim + 3 + v];
14858 }
14859 for(MInt d = 0; d < nDim; d++) {
14860 imageCoordsAziBalance(sortedIdMap[sortedCellId[gridCellId]] + cnt, d) = (it->second).first[d];
14861 }
14862 cnt++;
14863 }
14864 }
14865 }
14866
14867 maia::mpi::exchangeData(&globalIdAziBalance[0], domainId(), noDomains(), mpiComm(), 1, &sndSizeAzi[0],
14868 &rcvSizeAzi[0], &globalIdAzi[0]);
14869 maia::mpi::exchangeData(&cellVolumesAziBalance[0], domainId(), noDomains(), mpiComm(), 1, &sndSizeAzi[0],
14870 &rcvSizeAzi[0], &cellVolumesAzi[0]);
14871 maia::mpi::exchangeData(&cellVolumesDt1AziBalance[0], domainId(), noDomains(), mpiComm(), 1, &sndSizeAzi[0],
14872 &rcvSizeAzi[0], &cellVolumesDt1Azi[0]);
14873 maia::mpi::exchangeData(&sweptVolAziBalance[0], domainId(), noDomains(), mpiComm(), 1, &sndSizeAzi[0],
14874 &rcvSizeAzi[0], &sweptVolAzi[0]);
14875 maia::mpi::exchangeData(&bndryCntAziBalance[0], domainId(), noDomains(), mpiComm(), 1, &sndSizeAzi[0],
14876 &rcvSizeAzi[0], &bndryCntAzi[0]);
14877 maia::mpi::exchangeData(&propsAziBalance[0], domainId(), noDomains(), mpiComm(), 1, &sndSizeAzi[0],
14878 &rcvSizeAzi[0], &propsAzi[0]);
14879 maia::mpi::exchangeData(&variablesAziBalance[0], domainId(), noDomains(), mpiComm(), CV->noVariables,
14880 &sndSizeAzi[0], &rcvSizeAzi[0], &variablesAzi[0]);
14881 maia::mpi::exchangeData(&imageCoordsAziBalance[0], domainId(), noDomains(), mpiComm(), nDim, &sndSizeAzi[0],
14882 &rcvSizeAzi[0], &imageCoordsAzi[0]);
14883
14884
14885 MInt offset = 0;
14887 MInt noFloatData = nDim + sysEqn().CV->noVariables + 3;
14888 MInt noIntData = 2;
14889 for(MInt i = 0; i < noDomains(); i++) {
14890 for(MInt j = 0; j < rcvSizeAzi[i]; j++) {
14891 MInt ind = offset + j;
14892 MLong gCellId = globalIdAzi[ind];
14893 vector<MFloat> tmpF(mMax(noFloatData + nDim, nDim + 3));
14894 vector<MUlong> tmpI(noIntData);
14895 for(MInt d = 0; d < nDim; d++) {
14896 tmpF[d] = imageCoordsAzi(ind, d); // Image coordinate
14897 }
14898 tmpF[nDim] = cellVolumesAzi[ind]; // cellVol
14899 tmpF[nDim + 1] = cellVolumesDt1Azi[ind]; // cellVolDt1
14900 tmpF[nDim + 2] = sweptVolAzi[ind]; // sweptVol
14901 for(MInt v = 0; v < CV->noVariables; v++) {
14902 tmpF[nDim + 3 + v] = variablesAzi(ind, v);
14903 }
14904
14905 tmpI[0] = bndryCntAzi[ind]; // oldBndryCnt
14906 tmpI[1] = propsAzi[ind]; // cell properties
14907 m_azimuthalNearBoundaryBackup.insert(make_pair(gCellId, make_pair(tmpF, tmpI)));
14908 }
14909 offset += rcvSizeAzi[i];
14910 }
14911 }
14912 }
14913
14914 RHS.fill(-1.0);
14915 cellVolumesDt1.fill(-1.0);
14916 props.fill(maia::fv::cell::BitsetType());
14917 sweptVol.fill(std::numeric_limits<MFloat>::lowest());
14918
14919 maia::mpi::communicateData(&rightHandSideBalance(0, 0), oldNoCells, sortedCellId, noDomains(), domainId(),
14920 mpiComm(), noCellsToSendByDomain, noCellsToReceiveByDomain, CV->noVariables, &RHS[0]);
14921 if(m_dualTimeStepping) {
14922 maia::mpi::communicateData(&volumeDt1Balance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
14923 noCellsToSendByDomain, noCellsToReceiveByDomain, 1, &cellVolumesDt1[0]);
14924 }
14925
14926 maia::mpi::communicateBitsetData(&propsBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
14927 noCellsToSendByDomain, noCellsToReceiveByDomain, 1, &props[0]);
14928 maia::mpi::communicateData(&sweptVolBalance[0], oldNoCells, sortedCellId, noDomains(), domainId(), mpiComm(),
14929 noCellsToSendByDomain, noCellsToReceiveByDomain, 1, &sweptVol[0]);
14930
14931#ifndef NDEBUG
14932 // Timw: avoided as bndryCells exist which are inactive and notMovingBand
14933 // if during cutCell-computation no valid surfaces can be found!
14934 /*
14935 {
14936 MIntScratchSpace nbTest(m_cells.size(), 2, FUN_, "nbTest");
14937 nbTest.fill(0);
14938 for( MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++ ) {
14939 MInt cellId = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_cellId;
14940 //if ( a_isHalo(cellId) ) continue;
14941 if ( !a_hasProperty(cellId, SolverCell::IsSplitChild) ) {
14942 ASSERT( cellId > -1 && cellId < oldNoCells, "" );
14943 }
14944 ASSERT( a_hasProperty( cellId, SolverCell::IsMovingBnd ), "" );
14945 nbTest( cellId, 0 ) = 1;
14946 }
14947 for ( MUint c = 0; c < m_bndryLayerCells.size(); c++ ) {
14948 const MInt cellId = m_bndryLayerCells[ c ];
14949 //if ( a_isHalo(cellId) ) continue;
14950 //if ( a_hasProperty(cellId, SolverCell::IsSplitChild) ) continue;
14951 nbTest( cellId, 1 ) = 1;
14952 }
14953 for ( MInt cellId = 0; cellId < a_noCells(); cellId++ ) {
14954 //if ( a_isHalo(cellId) ) continue;
14955 //if ( a_hasProperty(cellId, SolverCell::IsSplitChild) ) continue;
14956 if ( nbTest(cellId, 0) != (MInt)a_hasProperty( cellId, SolverCell::IsMovingBnd ) )
14957 cerr << cellId << " " << oldNoCells << " " << a_hasProperty(cellId, SolverCell::IsSplitChild) << " " <<
14958 nbTest(cellId, 0) << " " << nbTest(cellId, 1)
14959 << " " << (MInt)a_hasProperty( cellId, SolverCell::IsMovingBnd ) << " " << a_isHalo( cellId) << endl;
14960 ASSERT( nbTest(cellId, 0) == (MInt)a_hasProperty( cellId, SolverCell::IsMovingBnd ), to_string(nbTest(cellId,
14961 0))+" "+to_string(nbTest(cellId, 1))
14962 +" "+to_string((MInt)a_hasProperty( cellId, SolverCell::IsMovingBnd )) );
14963 ASSERT( nbTest(cellId, 1) == (MInt)a_hasProperty( cellId, SolverCell::NearWall ), to_string(nbTest(cellId, 1))
14964 +" "+to_string((MInt)a_hasProperty( cellId, SolverCell::NearWall )) );
14965 if ( a_hasProperty( cellId, SolverCell::IsMovingBnd ) ) ASSERT( m_oldBndryCells.count(cellId) == 1, "" );
14966 }
14967 }
14968 */
14969#endif
14970 }
14971
14972 FvCartesianSolverXD<nDim, SysEqn>::balance(noCellsToReceiveByDomain, noCellsToSendByDomain, sortedCellId, oldNoCells);
14973
14974 ASSERT(m_cells.size() == c_noCells(), "");
14975
14976 if(globalTimeStep > -1) {
14977 MFloatScratchSpace sweptVolBak(a_noCells(), FUN_, "sweptVolBak");
14978 ScratchSpace<maia::fv::cell::BitsetType> propsBak(a_noCells(), FUN_, "propsBak");
14979
14980 sweptVolBak.fill(std::numeric_limits<MFloat>::lowest());
14981 propsBak.fill(maia::fv::cell::BitsetType());
14982
14983 // Step 1: set properties for all Internal-Cells
14984
14985 // Iterate over all received cells (already sorted by global id)
14986 MInt cnt = 0;
14987 for(MInt gridCellId = 0; gridCellId < noCellsToReceiveByDomain[noDomains()]; gridCellId++) {
14988 if(!grid().raw().treeb().solver(gridCellId, m_solverId)) continue;
14989
14990 MInt cellId = cnt;
14991
14992 if(!grid().raw().bitOffset()) {
14993 ASSERT(grid().tree().solver2grid(cellId) == gridCellId, "");
14994 }
14995
14996 // Set solver data
14997 for(MInt j = 0; j < CV->noVariables; j++) {
14998 a_rightHandSide(cellId, j) = RHS(gridCellId, j);
14999 }
15000 if(m_dualTimeStepping) {
15001 m_cellVolumesDt1[cellId] = cellVolumesDt1(gridCellId);
15002 }
15003 assertValidGridCellId(cellId);
15004
15005 sweptVolBak(cellId) = sweptVol(gridCellId);
15006 propsBak(cellId) = props(gridCellId);
15007
15008 cnt++;
15009 }
15010
15011 // Step 2: exchange additiondal properties
15012
15013 maia::mpi::exchangeBitset(grid().neighborDomains(), grid().haloCells(), grid().windowCells(), mpiComm(),
15014 &propsBak[0], m_cells.size());
15015 exchangeData(&a_rightHandSide(0, 0), CV->noVariables);
15016 exchangeData(&sweptVolBak[0], 1);
15017 if(m_dualTimeStepping) {
15019 }
15020
15021 // Step 3: set additional properties for all cells (also for ghost-cells)
15022
15023 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
15024 assertValidGridCellId(cellId);
15025 if(m_dualTimeStepping) {
15027 }
15029 for(MInt j = 0; j < CV->noVariables; j++) {
15030 m_rhs0[cellId][j] = a_rightHandSide(cellId, j);
15031 }
15032 a_hasProperty(cellId, SolverCell::IsMovingBnd) = propsBak[cellId][maia::fv::cell::p(SolverCell::IsMovingBnd)];
15033 a_hasProperty(cellId, SolverCell::NearWall) = propsBak[cellId][maia::fv::cell::p(SolverCell::NearWall)];
15034 a_hasProperty(cellId, SolverCell::IsInactive) = propsBak[cellId][maia::fv::cell::p(SolverCell::IsInactive)];
15035 a_hasProperty(cellId, SolverCell::WasInactive) = a_hasProperty(cellId, SolverCell::IsInactive);
15036 }
15037
15038#ifndef NDEBUG
15040#endif
15041
15042 m_nearBoundaryBackup.clear();
15043 m_bndryLayerCells.clear();
15044 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
15045 if(a_hasProperty(cellId, SolverCell::NearWall)) {
15046 vector<MFloat> tmp(max(m_noCVars + m_noFVars, 0) + 1);
15047 tmp[0] = m_cellVolumesDt1[cellId];
15048 for(MInt v = 0; v < m_noCVars; v++) {
15049 tmp[1 + v] = a_oldVariable(cellId, v);
15050 }
15051 for(MInt v = 0; v < m_noFVars; v++) {
15052 tmp[1 + m_noCVars + v] = m_rhs0[cellId][v];
15053 }
15054 m_nearBoundaryBackup.insert(make_pair(cellId, tmp));
15055 m_bndryLayerCells.push_back(cellId);
15056 }
15057 }
15058
15059 m_oldBndryCells.clear();
15060 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
15061 if(a_hasProperty(cellId, SolverCell::IsMovingBnd)) {
15062 // ASSERT( !a_hasProperty( cellId, SolverCell::IsInactive ), "" );
15063 m_oldBndryCells.insert(make_pair(cellId, sweptVolBak[cellId]));
15064 }
15065 }
15066
15067 if(azimuthal) {
15070 }
15071 }
15072
15078 mAlloc(m_sendBufferSize, noNeighborDomains(), "m_sendBufferSize", 0, AT_);
15079 mAlloc(m_receiveBufferSize, noNeighborDomains(), "m_receiveBufferSize", 0, AT_);
15080 mAlloc(g_mpiRequestMb, noNeighborDomains(), "g_mpiRequestMb", MPI_REQ_NULL, AT_);
15081 mAlloc(m_linkedWindowCells, noNeighborDomains(), "m_linkedWindowCells", AT_);
15082 mAlloc(m_linkedHaloCells, noNeighborDomains(), "m_linkedHaloCells", AT_);
15083
15084
15085 for(MInt i = 0; i < noNeighborDomains(); i++) {
15086 m_linkedWindowCells[i].clear();
15087 m_linkedHaloCells[i].clear();
15088 // m_fvBndryCnd->m_nearBoundaryWindowCells[i].clear();
15089 // m_fvBndryCnd->m_nearBoundaryHaloCells[i].clear();
15090 }
15091
15092 if(m_closeGaps) {
15095 mAlloc(m_gapWindowCells, noNeighborDomains(), "m_gapWindowCells", AT_);
15096 mAlloc(m_gapHaloCells, noNeighborDomains(), "m_gapHaloCells", AT_);
15097 for(MInt i = 0; i < noNeighborDomains(); i++) {
15098 m_gapWindowCells[i].clear();
15099 m_gapHaloCells[i].clear();
15100 }
15101 }
15102
15109
15110 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
15112 }
15113
15115
15116 if(azimuthal) {
15118 }
15119
15120 ASSERT(m_cells.size() == c_noCells(), "");
15121
15122 // check-Cells:
15123
15124#if defined _MB_DEBUG_ || !defined NDEBUG
15125 if(domainId() == 0) {
15126 cerr << "Checking cells after balance... ";
15127 }
15128 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
15129 for(MInt v = 0; v < CV->noVariables; v++) {
15130 if(std::isnan(a_variable(cellId, v)) && !a_hasProperty(cellId, SolverCell::IsInactive)
15131 && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15132 cerr << "Nan in variable after balance " << cellId << " "
15133 << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << endl;
15134 }
15135 }
15136 if((a_variable(cellId, CV->RHO) < 0 || a_pvariable(cellId, PV->RHO) < 0)
15137 && !a_hasProperty(cellId, SolverCell::IsInactive)) {
15138 cerr << "Neg. density after balance" << cellId << endl;
15139 }
15140 }
15141 cerr0 << "finished. " << endl;
15142#endif
15143}
void balance(const MInt *const noCellsToReceiveByDomain, const MInt *const noCellsToSendByDomain, const MInt *const targetDomainsByCell, const MInt oldNoCells) override
Balance the solver.
maia::fv::collector::FvCellCollector< nDim > m_cells
Collector for FV cells.
maia::fv::cell::BitsetType & a_properties(const MInt cellId)
Returns properties of the cell cellId.
void assertValidGridCellId(const MInt cellId) const
Cecks wether the cell cellId is an actual grid-cell.
std::vector< MInt > m_massRedistributionIds
std::multimap< MLong, std::pair< std::vector< MFloat >, std::vector< MUlong > > > m_azimuthalNearBoundaryBackup
std::vector< MInt > * m_gapHaloCells
void commAzimuthalPeriodicData(MInt mode=0)
Send stored azimuthal periodic data from window to halo.
std::vector< MFloat > m_massRedistributionRhs
std::vector< MFloat > m_massRedistributionSweptVol
std::vector< MFloat > m_massRedistributionVolume
std::vector< MFloat > m_massRedistributionVariables
std::vector< MInt > * m_gapWindowCells
void checkHaloCells(MInt mode=0)
Checks a couple of important properties and variables of halo-cells.
void updateDomainInfo(const MInt domainId, const MInt noDomains, const MPI_Comm mpiComm, const MString &loc)
Set new domain information.
Definition: solver.h:135
void exchangeData(T *data, const MInt dataBlockSize=1)
Exchange memory in 'data' assuming a solver size of 'dataBlockSize' per cell.
std::ostream cerr0
constexpr std::underlying_type< FvCell >::type p(const FvCell property)
Converts property name to underlying integer value.
std::bitset< p(FvCell::NumProperties)> BitsetType
void communicateData(const DataType *const data, const MInt noCells, const MInt *const sortedCellId, const MInt noDomains, const MInt domainId, const MPI_Comm mpiComm, const MInt *const noCellsToSendByDomain, const MInt *const noCellsToReceiveByDomain, const MInt dataBlockSize, DataType *const buffer)
Assemble given data in send buffer and communicate.
Definition: mpiexchange.h:858
void exchangeData(const MInt noNghbrDomains, const MInt *const nghbrDomains, const MInt *const noHaloCells, const MInt **const, const MInt *const noWindowCells, const MInt **const windowCells, const MPI_Comm comm, const U *const data, U *const haloBuffer, const MInt noDat=1)
Generic exchange of data.
Definition: mpiexchange.h:295
void communicateBitsetData(const std::bitset< N > *const data, const MInt noCells, const MInt *const sortedCellId, const MInt noDomains, const MInt domainId, const MPI_Comm mpiComm, const MInt *const noCellsToSendByDomain, const MInt *const noCellsToReceiveByDomain, const MInt dataBlockSize, std::bitset< N > *const buffer)
Definition: mpiexchange.h:873
void exchangeBitset(const std::vector< MInt > &nghbrDomains, const std::vector< std::vector< MInt > > &haloCellVec, const std::vector< std::vector< MInt > > &windowCellVec, const MPI_Comm comm, std::bitset< N > *const data, const MInt noCells, const MInt noDat=1)
Generic exchange of data.
Definition: mpiexchange.h:516

◆ balancePost()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::balancePost
overridevirtual
Author
Jannik Borgelt

Reimplemented from Solver.

Definition at line 14394 of file fvmbcartesiansolverxd.cpp.

14394 {
14395 TRACE();
14396
14398
14399 // append the halo-cells
14400 m_cells.append(c_noCells() - m_cells.size());
14401
14403
14406 ASSERT(m_cells.size() == c_noCells() && c_noCells() == a_noCells(), "");
14407
14408
14409 m_oldBndryCells.clear();
14410 std::map<MInt, std::vector<MFloat>>().swap(m_nearBoundaryBackup);
14411 std::vector<MInt>().swap(m_bndryLayerCells);
14412 std::vector<MInt>().swap(m_massRedistributionIds);
14413 std::vector<MFloat>().swap(m_massRedistributionVariables);
14414 std::vector<MFloat>().swap(m_massRedistributionRhs);
14415 std::vector<MFloat>().swap(m_massRedistributionVolume);
14416 std::vector<MFloat>().swap(m_massRedistributionSweptVol);
14417 std::vector<std::tuple<MInt, MInt, MInt>>().swap(m_temporarilyLinkedCells);
14423 if(m_closeGaps) {
14426 }
14427
14428 // Nothing to do if solver is not active
14429 if(!grid().isActive()) {
14430 return;
14431 }
14432
14434 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
14435 a_bndryId(cellId) = -1;
14436 a_isBndryGhostCell(cellId) = false;
14437 a_hasProperty(cellId, SolverCell::IsSplitChild) = false;
14438 }
14439
14440 // this can only be done, after the halo property has been set above
14441 this->checkNoHaloLayers();
14442
14443 // ### from c'tor ###
14444 // compute min and max coordinates in the grid
14446 // ###
14447
14449
14450 if(!m_fvBndryCnd->m_cellMerging) {
14451 mDeallocate(m_fvBndryCnd->m_nearBoundaryWindowCells);
14452 mDeallocate(m_fvBndryCnd->m_nearBoundaryHaloCells);
14453 mAlloc(m_fvBndryCnd->m_nearBoundaryWindowCells, noNeighborDomains(), "m_nearBoundaryWindowCells", AT_);
14454 mAlloc(m_fvBndryCnd->m_nearBoundaryHaloCells, noNeighborDomains(), "m_nearBoundaryHaloCells", AT_);
14455 }
14456
14457 std::vector<MInt>().swap(m_splitCells);
14458 std::vector<std::vector<MInt>>().swap(m_splitChilds);
14459 std::map<MInt, MInt>().swap(m_splitChildToSplitCell);
14461
14462 // during the balance cells are sorted again
14463 if(this->m_adaptation) {
14464 for(MInt i = 0; i < maxNoGridCells(); i++)
14465 m_recalcIds[i] = i;
14466 }
14467
14468 // Azimuthal Balance
14469 if(grid().azimuthalPeriodicity()) {
14472
14473 MInt noFloatData_ = nDim + m_noFloatDataBalance;
14475 MInt noFloatData = m_azimuthalNearBoundaryBackupMaxCount * noFloatData_;
14476
14477 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
14478 for(MInt cnt = 0; cnt < m_azimuthalNearBoundaryBackupMaxCount; cnt++) {
14479 MInt longIndex = cnt * m_noLongDataBalance;
14480
14481 MLong gCellId = m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData + longIndex];
14482
14483 if(gCellId == -1) {
14484 continue;
14485 }
14486
14487 ASSERT(gCellId == c_globalId(cellId), "Azimuthal balance, this is not correct. " + to_string(cellId) + " "
14488 + to_string(c_globalId(cellId)) + " " + to_string(gCellId) + " "
14489 + to_string(domainId()));
14490
14491 MInt offset = cnt * noFloatData_;
14492 vector<MFloat> tmpF(noFloatData_);
14493 vector<MUlong> tmpI(m_noLongData);
14494
14495 for(MInt d = offset; d < offset + noFloatData_; d++) {
14496 tmpF[d - offset] = m_azimuthalNearBoundaryBackupBalFloat[cellId * noFloatData + d];
14497 }
14498
14499 tmpI[0] = (MUlong)m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData + longIndex + 1];
14500 tmpI[1] = (MUlong)m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData + longIndex + 2];
14501
14502 m_azimuthalNearBoundaryBackup.insert(make_pair(gCellId, make_pair(tmpF, tmpI)));
14503 }
14504 }
14505
14508
14509 m_wasBalanced = true;
14510 }
14511
14512 exchangeData(&a_variable(0, 0), CV->noVariables);
14513 exchangeData(&a_cellVolume(0), 1);
14515 if(m_dualTimeStepping) {
14517 }
14518 // change this for proper splitBalance where only boundary data is exchanged
14520
14521 // exchange properties that are of type MBool
14522 maia::mpi::exchangeBitset(grid().neighborDomains(), grid().haloCells(), grid().windowCells(), mpiComm(),
14523 &a_properties(0), a_noCells());
14524
14525 ScratchSpace<maia::fv::cell::BitsetType> propsBalance(a_noCells(), FUN_, "propsBalance");
14526 propsBalance.fill(maia::fv::cell::BitsetType());
14527
14528 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
14529 setPrimitiveVariables(cellId);
14530 for(MInt v = 0; v < CV->noVariables; v++) {
14531 a_oldVariable(cellId, v) = a_variable(cellId, v);
14532 }
14533 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
14534 propsBalance[cellId][maia::fv::cell::p(SolverCell::IsMovingBnd)] =
14535 a_properties(cellId)[maia::fv::cell::p(SolverCell::IsMovingBnd)];
14536 propsBalance[cellId][maia::fv::cell::p(SolverCell::NearWall)] =
14537 a_properties(cellId)[maia::fv::cell::p(SolverCell::NearWall)];
14538 propsBalance[cellId][maia::fv::cell::p(SolverCell::IsInactive)] =
14539 a_properties(cellId)[maia::fv::cell::p(SolverCell::IsInactive)];
14540 propsBalance[cellId][maia::fv::cell::p(SolverCell::WasInactive)] =
14541 a_properties(cellId)[maia::fv::cell::p(SolverCell::WasInactive)];
14542 }
14543
14544 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14546 }
14547
14548 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14549 assertValidGridCellId(cellId);
14550 if(m_dualTimeStepping) {
14552 }
14554 for(MInt j = 0; j < m_noFVars; j++) {
14555 m_rhs0[cellId][j] = a_rightHandSide(cellId, j);
14556 }
14557 a_hasProperty(cellId, SolverCell::IsMovingBnd) = propsBalance[cellId][maia::fv::cell::p(SolverCell::IsMovingBnd)];
14558 a_hasProperty(cellId, SolverCell::NearWall) = propsBalance[cellId][maia::fv::cell::p(SolverCell::NearWall)];
14559 a_hasProperty(cellId, SolverCell::IsInactive) = propsBalance[cellId][maia::fv::cell::p(SolverCell::IsInactive)];
14560 a_hasProperty(cellId, SolverCell::WasInactive) = propsBalance[cellId][maia::fv::cell::p(SolverCell::IsInactive)];
14561 }
14562
14563 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14564 if(a_hasProperty(cellId, SolverCell::NearWall)) {
14565 vector<MFloat> tmp(max(m_noCVars + m_noFVars, 0) + 1);
14566 tmp[0] = m_cellVolumesDt1[cellId];
14567 for(MInt v = 0; v < m_noCVars; v++) {
14568 tmp[1 + v] = a_oldVariable(cellId, v);
14569 }
14570 for(MInt v = 0; v < m_noFVars; v++) {
14571 tmp[1 + m_noCVars + v] = m_rhs0[cellId][v];
14572 }
14573 m_nearBoundaryBackup.insert(make_pair(cellId, tmp));
14574 m_bndryLayerCells.push_back(cellId);
14575 }
14576 // a_hasProperty(cellId, SolverCell::WasInactive) = a_hasProperty(cellId, SolverCell::IsInactive);
14577 }
14578
14579 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
14580 if(a_hasProperty(cellId, SolverCell::IsMovingBnd)) {
14581 // ASSERT( !a_hasProperty( cellId, SolverCell::IsInactive ), "" );
14582 ASSERT(m_sweptVolumeBal[cellId] > -1, "something is wrong with m_sweptVolumeBal");
14583 m_oldBndryCells.insert(make_pair(cellId, m_sweptVolumeBal[cellId]));
14584 }
14585 }
14586
14587 if(grid().azimuthalPeriodicity()) {
14589 }
14590
14591
14592 // ToDo: currently untested
14593 if(m_zonal) {
14597
14598 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
14600 for(MInt var = 0; var < m_LESNoVarAverage; var++) {
14601 // m_LESVarAverageBal[var].resize(c_noCells());
14602 MFloatScratchSpace exchangeLESVarAverageBal(c_noCells(), FUN_, "exchangeIsMovingBnd");
14603 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
14604 exchangeLESVarAverageBal[cellId] = m_LESVarAverageBal[var][cellId];
14605 }
14606 exchangeData(&exchangeLESVarAverageBal[0], 1);
14607 for(MInt i = 0; i < (MInt)m_LESAverageCells.size(); i++) {
14609 m_LESVarAverage[var][i] = exchangeLESVarAverageBal[cellId];
14610 }
14611 }
14612 }
14613
14614 MInt cnt = (MInt)m_LESAverageCells.size();
14615 MPI_Allreduce(MPI_IN_PLACE, &cnt, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "cnt");
14616 if(domainId() == 0) cerr << "m_noLESAverageCells: " << cnt << endl;
14617 }
14618 // Deallocate memory again
14619 for(MInt var = 0; var < m_LESNoVarAverage; var++) {
14620 m_LESVarAverageBal[var].clear();
14621 }
14623 }
14624
14626
14627#ifndef NDEBUG
14629#endif
14630
14631 // reset additional data
14632 mAlloc(m_sendBufferSize, noNeighborDomains(), "m_sendBufferSize", 0, AT_);
14633 mAlloc(m_receiveBufferSize, noNeighborDomains(), "m_receiveBufferSize", 0, AT_);
14634 mAlloc(g_mpiRequestMb, noNeighborDomains(), "g_mpiRequestMb", MPI_REQ_NULL, AT_);
14635 mAlloc(m_linkedWindowCells, noNeighborDomains(), "m_linkedWindowCells", AT_);
14636 mAlloc(m_linkedHaloCells, noNeighborDomains(), "m_linkedHaloCells", AT_);
14637
14638 for(MInt i = 0; i < noNeighborDomains(); i++) {
14639 m_linkedWindowCells[i].clear();
14640 m_linkedHaloCells[i].clear();
14641 }
14642
14643 if(m_closeGaps) {
14644 mAlloc(m_gapWindowCells, noNeighborDomains(), "m_gapWindowCells", AT_);
14645 mAlloc(m_gapHaloCells, noNeighborDomains(), "m_gapHaloCells", AT_);
14646 for(MInt i = 0; i < noNeighborDomains(); i++) {
14647 m_gapWindowCells[i].clear();
14648 m_gapHaloCells[i].clear();
14649 }
14650 }
14651
14652 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
14654 }
14655
14657
14658 ASSERT(m_cells.size() == c_noCells(), "");
14659
14660 if(this->m_adaptation) {
14663 }
14664
14666
14667#if defined _MB_DEBUG_ || !defined NDEBUG
14668 if(domainId() == 0) {
14669 cerr << "Checking cells after balance... ";
14670 }
14671 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
14672 for(MInt v = 0; v < CV->noVariables; v++) {
14673 if(std::isnan(a_variable(cellId, v)) && !a_hasProperty(cellId, SolverCell::IsInactive)) {
14674 cerr << "Nan in variable after balance " << cellId << " "
14675 << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << endl;
14676 }
14677 }
14678 if((a_variable(cellId, CV->RHO) < 0 || a_pvariable(cellId, PV->RHO) < 0)
14679 && !a_hasProperty(cellId, SolverCell::IsInactive)) {
14680 cerr << "Neg. density after balance" << cellId << endl;
14681 }
14682 }
14683 if(domainId() == 0) cerr << "finished. " << endl;
14684#endif
14685}
std::vector< MFloat > * m_LESVarAverageBal
std::map< MInt, MInt > m_splitChildToSplitCell
void a_resetPropertiesSolver(const MInt cellId)
Returns property p of the cell cellId.
void computeDomainAndSpongeDimensions()
Extracts the minimum and maximum coordinates of all cells in the grid.
static constexpr MFloat m_volumeThreshold
virtual void resetZonalLESAverage()
Initializes zonal exchange arrays.
void allocateCommunicationMemory()
Allocates and initializes send/receive buffers for multiSolver computations.
MFloat & a_FcellVolume(const MInt cellId) override
Returns the inverse cell volume of the cell from the fvcellcollector cellId.
MFloat * m_azimuthalNearBoundaryBackupBalFloat
void checkNoHaloLayers()
check that each solver has the required number of haloLayers for leaf cells!!! TODO labels:toenhance ...
uint64_t MUlong
Definition: maiatypes.h:65
void swap(Tensor< TT > &a, Tensor< TT > &b)
Non-member swap exchanges the contents of two Tensors.
Definition: tensor.h:752

◆ balancePre()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::balancePre
overridevirtual
Author
Jannik Borgelt

Reimplemented from Solver.

Definition at line 14353 of file fvmbcartesiansolverxd.cpp.

14353 {
14354 TRACE();
14355
14357 // for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
14358 // a_resetPropertiesSolver(cellId);
14359 // }
14360
14361
14362 // ToDo: currently untested
14363 if(isActive()) {
14364 IF_CONSTEXPR(SysEqn::m_noRansEquations == 0) {
14365 if(m_zonal) {
14368 mAlloc(m_LESVarAverageBal, m_LESNoVarAverage, "m_LESVarAverage", AT_);
14369 for(MInt var = 0; var < m_LESNoVarAverage; var++) {
14370 m_LESVarAverageBal[var].resize(noInternalCells());
14371 }
14372 }
14373 }
14374 }
14375 }
14376
14377 // set only restart to true for the next initSolutionStep call!
14378 m_onlineRestart = true;
14379
14380 if(!isActive()) {
14382 } else {
14384 }
14385
14386 mAlloc(m_sweptVolumeBal, c_noCells(), "m_sweptVolumeBal", -F1, AT_);
14387}
void balancePre() override
Reinitialize solver for DLB prior to setting solution data.

◆ broadcastSignal()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::broadcastSignal ( const MInt  sender,
const MInt  signal 
)
Author
Lennart Schneiders

Definition at line 21324 of file fvmbcartesiansolverxd.cpp.

21324 {
21325 TRACE();
21326
21327 ScratchSpace<MInt> globalSignal(1, AT_, "globalSignal");
21328 globalSignal.p[0] = signal;
21329 MPI_Bcast(globalSignal.getPointer(), 1, MPI_INT, sender, mpiComm(), AT_, "globalSignal.getPointer()");
21330
21331 return globalSignal.p[0];
21332}
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast

◆ buildAdditionalAzimuthalReconstructionStencil()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::buildAdditionalAzimuthalReconstructionStencil ( MInt  mode = 0)
Author
Thomas Hoesgen

Definition at line 36248 of file fvmbcartesiansolverxd.cpp.

36248 {
36249 TRACE();
36250
36251 MFloat recCoord[3];
36252 if(mode == 0) {
36253 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36254 for(MUint j = 0; j < m_azimuthalMaxLevelWindowCells[i].size(); j++) {
36255 MInt offset = m_azimuthalMaxLevelWindowMap[i][j];
36257 if(m_azimuthalWasNearBndryIds[offset] <= -1) {
36258 continue;
36259 }
36260 for(MInt d = 0; d < nDim; d++) {
36261 recCoord[d] = m_azimuthalCutRecCoord[offset * nDim + d];
36262 }
36263 rebuildAzimuthalReconstructionConstants(cellId, offset, recCoord, mode);
36264 }
36265 }
36266 } else if(mode == 1) {
36267 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36268 for(MUint j = 0; j < m_azimuthalMaxLevelWindowCells[i].size(); j++) {
36269 MInt offset = m_azimuthalMaxLevelWindowMap[i][j];
36271 if(m_azimuthalWasNearBndryIds[offset] > -1) {
36272 for(MInt d = 0; d < nDim; d++) {
36273 recCoord[d] = m_azimuthalCutRecCoord[offset * nDim + d];
36274 }
36275 rebuildAzimuthalReconstructionConstants(cellId, offset, recCoord, mode);
36276 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36277 MBool rebuild = false;
36278 for(MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36280 if(a_bndryId(recId) > -1) {
36281 rebuild = true;
36282 break;
36283 }
36284 }
36285 if(!rebuild) {
36286 // If stencil does not contain bndry cells, reconstruction constants do not have to be recomputed
36287 m_azimuthalWasNearBndryIds[offset] = -1;
36288 }
36289 }
36290 }
36291 }
36292 }
36293}
std::vector< std::vector< MInt > > m_azimuthalMaxLevelWindowCells
std::vector< std::vector< MInt > > m_azimuthalMaxLevelWindowMap
void rebuildAzimuthalReconstructionConstants(MInt cellId, MInt offset, MFloat *recCoord, MInt mode=0)
std::vector< MInt > m_azimuthalWasNearBndryIds

◆ buildAdditionalReconstructionStencil()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::buildAdditionalReconstructionStencil
Author
Lennart Schneiders

Definition at line 11641 of file fvmbcartesiansolverxd.cpp.

11641 {
11642 TRACE();
11643
11644 const MInt recDim = (m_orderOfReconstruction == 2) ? (IPOW2(nDim) + 1) : nDim;
11645
11646 MIntScratchSpace nghbrList(100, AT_, "nghbrList");
11647 MIntScratchSpace nghbrListTmp(100, AT_, "nghbrListTmp");
11648 MIntScratchSpace layerId(100, AT_, "layerList");
11649 MFloatScratchSpace tmpA(100, recDim, AT_, "tmpA");
11650 MFloatScratchSpace tmpC(recDim, 100, AT_, "tmpC");
11651 MFloatScratchSpace weights(100, AT_, "weights");
11652#if defined _MB_DEBUG_ || !defined NDEBUG
11653 MFloat cntCnd = F0;
11654 MFloat avgCnd = F0;
11655 MFloat maxCnd = F0;
11656#endif
11657
11658 // reset noReconstruction neighbors for all bndryLayer Cells
11659 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
11660 const MInt cellId = m_bndryLayerCells[c];
11661 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
11662 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
11663 a_hasProperty(cellId, SolverCell::IsFlux) = true;
11664 a_noReconstructionNeighbors(cellId) = 0;
11665 }
11666
11667 // recompute noReconstruction neighbors for all bndryLayeCells
11668 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
11669 const MInt cellId = m_bndryLayerCells[c];
11670 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
11671 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
11672 if(a_isBndryGhostCell(cellId)) continue;
11673 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
11674 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
11675 if(a_bndryId(cellId) < -1) continue;
11676 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && c_noChildren(cellId) > 0) continue;
11677 ASSERT(a_noReconstructionNeighbors(cellId) == 0,
11678 to_string(cellId) + " " + to_string(c) + " " + to_string(a_noReconstructionNeighbors(cellId)));
11679
11680 const MInt bndryId = a_bndryId(cellId);
11681
11682 // add ghostCells as reconstruction neighbor for bndryCells, each bndrySurface has one ghostCell
11683 if(bndryId >= m_noOuterBndryCells) {
11684 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
11685 const MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
11686 ASSERT(ghostCellId > -1, "");
11687 a_reconstructionNeighborId(cellId, a_noReconstructionNeighbors(cellId)) = ghostCellId;
11689 }
11690 }
11691
11692 const MInt rootCell =
11693 (a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId;
11694 ASSERT(rootCell > -1 && rootCell < a_noCells(), "");
11695
11696 // get all neighbors (also diagonal) with 1 layer
11697 // this causes problems at level jumps, as then
11698 // more than the allowed number of reconstruction neighbors may be found!!!!
11699 // the last entries are then randomly disregareded!
11700 MInt counter = -1;
11701 MInt noactiveNeighbors = 1;
11703 counter = this->template getAdjacentLeafCells<2, true>(rootCell, 1, nghbrList, layerId);
11704 } else {
11705 // new faster version which only uses direct neighbors and not diagonal ones
11706 // counter = this->template getAdjacentLeafCells<0,true>( rootCell, 1, nghbrList, layerId );
11707
11708 // new!
11709 // check the number of active neighbors,
11710 // reduce the stencil if the number is above the threshold!
11711 // TODO labels:FVMB,totest check if this is done consistently on window&halo cells!
11712 counter = this->template getAdjacentLeafCells<2, true>(rootCell, 1, nghbrList, layerId);
11713 // TODO labels:FVMB update testcases to correct value below!
11714 if(m_engineSetup) {
11715 noactiveNeighbors = a_noReconstructionNeighbors(cellId);
11716 }
11717 for(MInt n = 0; n < counter; n++) {
11718 const MInt nghbrId = nghbrList[n];
11719 if(nghbrId < 0) continue;
11720 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
11721 noactiveNeighbors++;
11722 }
11723 if(noactiveNeighbors > m_cells.noRecNghbrs() - 1) {
11724 counter = this->template getAdjacentLeafCells<0, true>(rootCell, 1, nghbrList, layerId);
11725 }
11726 }
11727
11728 // add reconstruction neighbors
11729 for(MInt n = 0; n < counter; n++) {
11730 const MInt nghbrId = nghbrList[n];
11731 if(nghbrId < 0) continue;
11732 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
11733 if(a_noReconstructionNeighbors(cellId) < m_cells.noRecNghbrs()) {
11736 } else {
11737 cerr << "Warning: too many reconstruction neighbors for cell " << cellId;
11738 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
11739 cerr << "/-";
11740 } else {
11741 cerr << "/" << c_globalId(cellId);
11742 }
11743 cerr << " " << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << " " << a_coordinate(cellId, 2)
11744 << " " << a_noReconstructionNeighbors(cellId) << "/" << counter << endl;
11745 }
11746 }
11747
11748
11749 const MInt offset = m_cells.noRecNghbrs() * cellId;
11750
11751 // NOTE: cbc cutOff cells should only use direct neighbors for slope-interpolation!
11752 const MInt mode = (m_fvBndryCnd->m_cbcSmallCellCorrection && a_hasProperty(cellId, SolverCell::IsCutOff))
11753 ? 1
11755 MFloat condNum = computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, mode, 1);
11756
11757
11758 // if the condNum is invalid, the stencil is recomputed:
11759 if((condNum < F0 || condNum > 1e6 || std::isnan(condNum))) {
11760#if defined _MB_DEBUG_ || !defined NDEBUG
11761
11762 const MFloat vf = (a_bndryId(cellId) > -1) ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume
11763 / grid().gridCellVolume(a_level(cellId))
11764 : F1;
11765
11766 cerr << domainId() << " " << globalTimeStep << " recompute stencil for cell " << cellId << "/"
11767 << c_globalId(cellId) << " level " << a_level(cellId) << " vol "
11768 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << " " << vf << " cond " << condNum << " "
11769 << endl;
11770#endif
11771 }
11772
11773
11774 if(a_noReconstructionNeighbors(cellId) > m_cells.noRecNghbrs()) {
11775 mTerm(1, AT_, "Error in buildAdditionalReconstructionStencil too many rec neighbors.");
11776 }
11777
11778#if defined _MB_DEBUG_ || !defined NDEBUG
11779 avgCnd += condNum;
11780 maxCnd = mMax(maxCnd, condNum);
11781 cntCnd += F1;
11782#endif
11783 }
11784
11787
11788#if defined _MB_DEBUG_ || !defined NDEBUG
11789 if(globalTimeStep % 100 == 0) {
11790 MPI_Allreduce(MPI_IN_PLACE, &maxCnd, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "maxCnd");
11791 MPI_Allreduce(MPI_IN_PLACE, &avgCnd, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "avgCnd");
11792 MPI_Allreduce(MPI_IN_PLACE, &cntCnd, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "cntCnd");
11793
11794 m_log << "Singular value decomposition: near-boundary maximum/average condition number: " << maxCnd << "/"
11795 << avgCnd / cntCnd << endl;
11796 }
11797#endif
11798}
MInt & a_reconstructionData(const MInt cellId)
Returns reconstruction data offset i of the cell cellId.
MInt & a_reconstructionNeighborId(const MInt cellId, const MInt nghbrNo)
Returns reconstruction neighbor n of the cell cellId.
MInt & a_noReconstructionNeighbors(const MInt cellId)
Returns the noRcnstrctnNghbrIds of the cell cellId.
MFloat computeRecConstSVD(const MInt cellId, const MInt offset, MFloatScratchSpace &tmpA, MFloatScratchSpace &tmpC, MFloatScratchSpace &weights, const MInt recDim, const MInt, const MInt, const std::array< MBool, nDim > dirs={}, const MBool relocateCenter=false)
compute the reconstruction constants of the given cell by a weighted least-squares approach via singu...
const MInt & getAssociatedInternalCell(const MInt &cellId) const
Returns the Id of the split cell, if cellId is a split child.

◆ CalculateLSV()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::CalculateLSV ( MInt  cellId,
MIntScratchSpace flag 
)
Author
Claudia Guenther

Definition at line 3333 of file fvmbcartesiansolverxd.cpp.

3333 {
3334 TRACE();
3335
3336 // LevelSetValues of the direct and second Neighbours
3337 MFloat a[3] = {F0, F0, F0};
3338 MFloat delta_cell[3] = {F0, F0, F0};
3339 // 1.Index: approximation level 2.Index: direction
3340 MFloat delta_taylor[2][3] = {{F0, F0, F0}, {F0, F0, F0}};
3341 MFloat levelSetValues = c_cellLengthAtLevel(0);
3343 const MInt accepted = 0;
3344
3345 // find smallest values and associated delta_cell by every axes direction
3346 for(MInt direction = 0; direction < (2 * nDim); direction++) {
3347 MInt index = (MInt)direction / 2;
3348 for(MInt j = m_identNghbrIds[2 * cellId * nDim + direction]; j < m_identNghbrIds[2 * cellId * nDim + direction + 1];
3349 j++) {
3350 MInt nghbrId = m_storeNghbrIds[j];
3351 if(flag[nghbrId] == accepted && a_levelSetValuesMb(nghbrId, 0) < a_levelSetValuesMb(cellId, 0)) {
3352 if(a[index] > F0) {
3353 if(a_levelSetValuesMb(nghbrId, 0) < a[index]) {
3354 a[index] = a_levelSetValuesMb(nghbrId, 0);
3355 delta_cell[index] = c_cellLengthAtLevel(a_level(nghbrId));
3356 }
3357 } else {
3358 a[index] = a_levelSetValuesMb(nghbrId, 0);
3359 delta_cell[index] = c_cellLengthAtLevel(a_level(nghbrId));
3360 }
3361 }
3362 }
3363 }
3364 // 2D CalculateLSV by approximation with taylor
3365 IF_CONSTEXPR(nDim == 2) {
3366 if(!(a[0] > F0) && !(a[1] > F0)) {
3367 } else if(!(a[0] > F0)) {
3368 // only in y-Direction
3369 delta_taylor[0][1] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[1]) * FFPOW2(1);
3370 levelSetValues = a[1] + delta_taylor[0][1];
3371 } else if(!(a[1] > F0)) {
3372 // only in x-Direction
3373 delta_taylor[0][0] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[0]) * FFPOW2(1);
3374 levelSetValues = a[0] + delta_taylor[0][0];
3375 } else {
3376 // in both directions
3377 // 1.Order
3378 MFloat p, q;
3379 if(abs(delta_cell[0] - delta_cell[1]) < eps) { // same distance to both cells
3380 // pq-equation
3381 delta_taylor[0][0] = (delta_cell[0] + c_cellLengthAtLevel(a_level(cellId))) * FFPOW2(1);
3382 p = -(a[0] + a[1]);
3383 q = (a[0] * a[0] + a[1] * a[1] - delta_taylor[0][0] * delta_taylor[0][0]) * FFPOW2(1);
3384 } else {
3385 delta_taylor[0][0] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[0]) * FFPOW2(1);
3386 delta_taylor[0][1] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[1]) * FFPOW2(1);
3387 p = -2 * (delta_taylor[0][1] * delta_taylor[0][1] * a[0] + delta_taylor[0][0] * delta_taylor[0][0] * a[1])
3388 / (delta_taylor[0][0] * delta_taylor[0][0] + delta_taylor[0][1] * delta_taylor[0][1]);
3389 q = (delta_taylor[0][1] * delta_taylor[0][1] * a[0] * a[0]
3390 + delta_taylor[0][0] * delta_taylor[0][0] * a[1] * a[1]
3391 - delta_taylor[0][1] * delta_taylor[0][1] * delta_taylor[0][0] * delta_taylor[0][0])
3392 / (delta_taylor[0][1] * delta_taylor[0][1] + delta_taylor[0][0] * delta_taylor[0][0]);
3393 }
3394 MFloat psqf4mq = p * p * FFPOW2(2) - q;
3395 if(psqf4mq < F0) psqf4mq = F0;
3396 levelSetValues = -p * FFPOW2(1) + sqrt(psqf4mq);
3397 }
3398 }
3399 else IF_CONSTEXPR(nDim == 3) {
3400 // 3D CalculateLSV by approximation with taylor
3401 if(!(a[0] > F0) && !(a[1] > F0) && !(a[2] > F0)) { // no valid neighbor
3402 } else if(!(a[1] > F0) && !(a[2] > F0)) {
3403 // only in x-Direction
3404 delta_taylor[0][0] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[0]) * FFPOW2(1);
3405 levelSetValues = a[0] + delta_taylor[0][0];
3406 } else if(!(a[0] > F0) && !(a[2] > F0)) {
3407 // only in y-Direction
3408 delta_taylor[0][1] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[1]) * FFPOW2(1);
3409 levelSetValues = a[1] + delta_taylor[0][1];
3410 } else if(!(a[0] > F0) && !(a[1] > F0)) {
3411 // only in z-Direction
3412 delta_taylor[0][2] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[2]) * FFPOW2(1);
3413 levelSetValues = a[2] + delta_taylor[0][2];
3414 } else if(!(a[2] > F0)) {
3415 // in x- and y-Direction
3416 MFloat p, q;
3417 if(abs(delta_cell[0] - delta_cell[1]) < eps) { // same distance to both cells
3418 // pq-equation
3419 delta_taylor[0][0] = (delta_cell[0] + c_cellLengthAtLevel(a_level(cellId))) * FFPOW2(1);
3420 p = -(a[0] + a[1]);
3421 q = (a[0] * a[0] + a[1] * a[1] - delta_taylor[0][0] * delta_taylor[0][0]) * FFPOW2(1);
3422 } else {
3423 delta_taylor[0][0] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[0]) * FFPOW2(1);
3424 delta_taylor[0][1] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[1]) * FFPOW2(1);
3425 MFloat x2 = delta_taylor[0][0] * delta_taylor[0][0];
3426 MFloat y2 = delta_taylor[0][1] * delta_taylor[0][1];
3427 MFloat denominator = x2 + y2;
3428 MFloat x2y2 = x2 * y2;
3429 p = -2 * (a[0] * y2 + a[1] * x2) / denominator;
3430 q = (a[0] * a[0] * y2 + a[1] * a[1] * x2 - x2y2) / denominator;
3431 }
3432 MFloat psqf4mq = p * p * FFPOW2(2) - q;
3433 if(psqf4mq < F0) psqf4mq = F0;
3434 levelSetValues = -p * FFPOW2(1) + sqrt(psqf4mq);
3435 } else if(!(a[1] > F0)) {
3436 // in x- and z-Direction
3437 MFloat p, q;
3438 if(abs(delta_cell[0] - delta_cell[2]) < eps) { // same distance to both cells
3439 // pq-equation
3440 delta_taylor[0][0] = (delta_cell[0] + c_cellLengthAtLevel(a_level(cellId))) * FFPOW2(1);
3441 p = -(a[0] + a[2]);
3442 q = (a[0] * a[0] + a[2] * a[2] - delta_taylor[0][0] * delta_taylor[0][0]) * FFPOW2(1);
3443 } else {
3444 delta_taylor[0][0] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[0]) * FFPOW2(1);
3445 delta_taylor[0][2] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[2]) * FFPOW2(1);
3446 MFloat x2 = delta_taylor[0][0] * delta_taylor[0][0];
3447 MFloat z2 = delta_taylor[0][2] * delta_taylor[0][2];
3448 MFloat denominator = x2 + z2;
3449 MFloat x2z2 = x2 * z2;
3450 p = -2 * (a[0] * z2 + a[2] * x2) / denominator;
3451 q = (a[0] * a[0] * z2 + a[2] * a[2] * x2 - x2z2) / denominator;
3452 }
3453 MFloat psqf4mq = p * p * FFPOW2(2) - q;
3454 if(psqf4mq < F0) psqf4mq = F0;
3455 levelSetValues = -p * FFPOW2(1) + sqrt(psqf4mq);
3456 } else if(!(a[0] > F0)) {
3457 // in y- and z-Direction
3458 MFloat p, q;
3459 if(abs(delta_cell[1] - delta_cell[2]) < eps) { // same distance to both cells
3460 // pq-equation
3461 delta_taylor[0][0] = (delta_cell[1] + c_cellLengthAtLevel(a_level(cellId))) * FFPOW2(1);
3462 p = -(a[1] + a[2]);
3463 q = (a[1] * a[1] + a[2] * a[2] - delta_taylor[0][0] * delta_taylor[0][0]) * FFPOW2(1);
3464 } else {
3465 delta_taylor[0][1] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[1]) * FFPOW2(1);
3466 delta_taylor[0][2] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[2]) * FFPOW2(1);
3467 MFloat y2 = delta_taylor[0][1] * delta_taylor[0][1];
3468 MFloat z2 = delta_taylor[0][2] * delta_taylor[0][2];
3469 MFloat denominator = z2 + y2;
3470 MFloat z2y2 = z2 * y2;
3471 p = -2 * (a[1] * z2 + a[2] * y2) / denominator;
3472 q = (a[1] * a[1] * z2 + a[2] * a[2] * y2 - z2y2) / denominator;
3473 }
3474 MFloat psqf4mq = p * p * FFPOW2(2) - q;
3475 if(psqf4mq < F0) psqf4mq = F0;
3476 levelSetValues = -p * FFPOW2(1) + sqrt(psqf4mq);
3477 } else {
3478 // in all three directions
3479 MFloat p, q;
3480 if(abs(delta_cell[0] - delta_cell[2]) < eps
3481 && abs(delta_cell[1] - delta_cell[2]) < eps) { // same distance to all three cells
3482 // pq-equation
3483 delta_taylor[0][0] = (delta_cell[0] + c_cellLengthAtLevel(a_level(cellId))) * FFPOW2(1);
3484 p = -F2B3 * (a[0] + a[1] + a[2]);
3485 q = F1B3 * (a[0] * a[0] + a[1] * a[1] + a[2] * a[2] - delta_taylor[0][0] * delta_taylor[0][0]);
3486 } else { // different distances in at least one direction
3487 delta_taylor[0][0] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[0]) * FFPOW2(1);
3488 delta_taylor[0][1] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[1]) * FFPOW2(1);
3489 delta_taylor[0][2] = (c_cellLengthAtLevel(a_level(cellId)) + delta_cell[2]) * FFPOW2(1);
3490 MFloat x2y2 = delta_taylor[0][0] * delta_taylor[0][0] * delta_taylor[0][1] * delta_taylor[0][1];
3491 MFloat x2z2 = delta_taylor[0][0] * delta_taylor[0][0] * delta_taylor[0][2] * delta_taylor[0][2];
3492 MFloat y2z2 = delta_taylor[0][1] * delta_taylor[0][1] * delta_taylor[0][2] * delta_taylor[0][2];
3493 MFloat x2y2z2 = delta_taylor[0][0] * delta_taylor[0][0] * delta_taylor[0][1] * delta_taylor[0][1]
3494 * delta_taylor[0][2] * delta_taylor[0][2];
3495 MFloat denominator = (x2y2 + x2z2 + y2z2);
3496 p = -2 * (y2z2 * a[0] + x2z2 * a[1] + x2y2 * a[2]) / denominator;
3497 q = (y2z2 * a[0] * a[0] + x2z2 * a[1] * a[1] + x2y2 * a[2] * a[2] - x2y2z2) / denominator;
3498 }
3499 MFloat psqf4mq = p * p * FFPOW2(2) - q;
3500 if(psqf4mq < F0) psqf4mq = F0;
3501 levelSetValues = -p * FFPOW2(1) + sqrt(psqf4mq);
3502 }
3503 }
3504
3505 return levelSetValues;
3506}
MFloat c_cellLengthAtLevel(const MInt level) const
Returns the length of the cell for level.
constexpr MFloat FFPOW2(MInt x)
IdType index(const FloatType *const x, const IdType level)
Return Hilbert index for given location and level in 2D or 3D.
Definition: hilbert.h:165
Definition: contexttypes.h:19

◆ CdLaw()

template<MInt nDim, class SysEqn >
static MFloat FvMbCartesianSolverXD< nDim, SysEqn >::CdLaw ( MFloat  Re)
inlinestatic

Definition at line 1220 of file fvmbcartesiansolverxd.h.

1220{ return 24.0 * (F1 + (0.15 * pow(Re, 0.687))) / Re; }

◆ cellDataSizeDlb()

template<MInt nDim_, class SysEqn >
MInt FvMbCartesianSolverXD< nDim_, SysEqn >::cellDataSizeDlb ( const MInt  dataId,
const MInt  gridCellId 
)
override

Definition at line 1815 of file fvmbcartesiansolverxd.h.

1815 {
1816 // Inactive ranks do not have any data to communicate
1817 if(!isActive()) {
1818 return 0;
1819 }
1820
1821 // Convert to solver cell id and check
1822 const MInt cellId = grid().tree().grid2solver(gridCellId);
1823 if(cellId < 0 || cellId >= noInternalCells()) {
1824 return 0;
1825 }
1826
1827 MInt dataSize = 1;
1828
1829 switch(dataId) {
1831 dataSize = m_noCVars;
1832 break;
1833 }
1835 dataSize = 1;
1836 break;
1837 }
1839 dataSize = m_noFVars;
1840 break;
1841 }
1843 dataSize = 1;
1844 break;
1845 }
1847 dataSize = 1;
1848 break;
1849 }
1851 dataSize = 1;
1852 break;
1853 }
1855 if(grid().azimuthalPeriodicity()) {
1857 } else {
1858 dataSize = 0;
1859 }
1860 break;
1861 }
1863 if(grid().azimuthalPeriodicity()) {
1865 } else {
1866 dataSize = 0;
1867 }
1868 break;
1869 }
1870 default: {
1871 TERMM(1, "Unknown data id.");
1872 break;
1873 }
1874 }
1875
1876 return dataSize;
1877}
static constexpr const MInt ELEM_RIGHTHANDSIDE
static constexpr const MInt ELEM_CELLVOLUMES
static constexpr const MInt ELEM_AZIMUTHAL_LONG
static constexpr const MInt ELEM_PROPERTIES
static constexpr const MInt ELEM_SWEPTVOLUMES
static constexpr const MInt ELEM_AZIMUTHAL_FLOAT
static constexpr const MInt ELEM_CELLVOLUMESDT1
static constexpr const MInt ELEM_AVARIABLE

◆ cellDataTypeDlb()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::cellDataTypeDlb ( const MInt  dataId) const
inlineoverride

Definition at line 1019 of file fvmbcartesiansolverxd.h.

1019 {
1020 MInt dataType = -1;
1021 if(dataId < CellDataDlb::count) {
1022 dataType = s_cellDataTypeDlb[dataId];
1023 } else {
1024 TERMM(1, "solverCelldataType: invalid data id " + std::to_string(dataId));
1025 }
1026 return dataType;
1027 };
static const std::array< MInt, CellDataDlb::count > s_cellDataTypeDlb

◆ checkAreaDiff()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::checkAreaDiff ( MInt  srfcId1,
MInt  srfcId2 
)
inlineprivate
Author

Definition at line 31343 of file fvmbcartesiansolverxd.cpp.

31343 {
31344 return fabs(a_surfaceArea(srfcId1) - a_surfaceArea(srfcId2));
31345}

◆ checkBoundaryCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::checkBoundaryCells
Author
Lennart Schneiders

Definition at line 10689 of file fvmbcartesiansolverxd.cpp.

10689 {
10690 TRACE();
10691
10692 MInt errorId = 0;
10693 MInt globalErrorId = 0;
10694
10695
10696 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
10697 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
10698
10699 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
10700 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
10701 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
10702 errorId = 0;
10703
10704 const MFloat faceArea = (nDim == 3) ? POW2(sqrt(F3) * c_cellLengthAtLevel(a_cutCellLevel(cellId)))
10705 : sqrt(F2) * c_cellLengthAtLevel(a_cutCellLevel(cellId));
10706 const MFloat faceArea0 =
10708
10709 ASSERT(m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs > 0, "");
10710
10711 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume < F0)
10712 errorId = 1;
10713 else if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume > (grid().gridCellVolume(a_level(cellId)) + m_eps))
10714 errorId = 1;
10715 else if(std::isnan(m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume))
10716 errorId = 1;
10717 if(errorId == 1) m_log << "BC: " << bndryId << " " << cellId << " " << errorId << endl;
10718
10719 if(m_volumeFraction[bndryId] < F0)
10720 errorId = 2;
10721 else if(m_volumeFraction[bndryId] > (F1 + m_eps))
10722 errorId = 2;
10723 else if(std::isnan(m_volumeFraction[bndryId]))
10724 errorId = 2;
10725 if(errorId == 2) {
10726 m_log << "BC: " << bndryId << " " << cellId << " " << errorId << " " << m_volumeFraction[bndryId] << endl;
10727 // if ( !a_isHalo(cellId) ) cerr << domainId() << ": BC " << bndryId << " " << cellId << " " << errorId << " " <<
10728 // m_volumeFraction[ bndryId ]
10729 // << " " << a_cellVolume(cellId) << " " << m_cellVolumesDt1[cellId]
10730 // << " " << c_globalId(cellId) << endl;
10731 }
10732
10733 for(MInt i = 0; i < nDim; i++)
10734 if(std::isnan(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i])) errorId = 3;
10735 if(errorId == 3) {
10736 m_log << "BC: " << bndryId << " " << cellId << " " << errorId << endl;
10737 }
10738
10739 for(MInt i = 0; i < nDim; i++)
10740 if(fabs(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i]) > (F1 + m_eps)) errorId = 4;
10741 if(errorId == 4) {
10742 IF_CONSTEXPR(nDim == 2) {
10743 m_log << "BC: " << bndryId << " " << cellId << " " << errorId << " "
10744 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[0] << " "
10745 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[1] << " " << scientific
10746 << setprecision(16) << m_volumeFraction[bndryId] << endl;
10747 }
10748 else IF_CONSTEXPR(nDim == 3) {
10749 m_log << "BC: " << bndryId << " " << cellId << " " << errorId << " "
10750 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[0] << " "
10751 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[1] << " "
10752 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[2] << " " << scientific
10753 << setprecision(16) << m_volumeFraction[bndryId] << endl;
10754 }
10755 }
10756
10757 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_area < F0)
10758 errorId = 5;
10759 else if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_area > (faceArea + m_eps))
10760 errorId = 5;
10761 else if(std::isnan(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_area))
10762 errorId = 5;
10763 if(errorId == 5) m_log << "BC: " << bndryId << " " << cellId << " " << errorId << endl;
10764
10765 if(a_hasProperty(cellId, SolverCell::IsInactive))
10766 errorId = 6;
10767 else if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
10768 errorId = 6;
10769 if(errorId == 6) m_log << "BC: " << bndryId << " " << cellId << " " << errorId << endl;
10770
10771 for(MInt i = 0; i < nDim; i++)
10772 if(fabs(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[i] - a_coordinate(cellId, i))
10773 > (F1B2 * c_cellLengthAtLevel(a_cutCellLevel(cellId)) + m_eps))
10774 errorId = 7;
10775 for(MInt i = 0; i < nDim; i++)
10776 if(std::isnan(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[i])) errorId = 7;
10777 if(errorId == 7) {
10778 // cerr << "error7 " << domainId() << " " << globalTimeStep << " " << cellId << " "
10779 // << m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_noSrfcs << " "
10780 // << fabs( m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_srfcs[0]->m_coordinates[ 0 ] - a_coordinate(cellId, 0)
10781 // ) - ( F1B2 * c_cellLengthAtLevel( a_cutCellLevel(cellId) ) ) << " "
10782 // << fabs( m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_srfcs[0]->m_coordinates[ 1 ] - a_coordinate(cellId, 1)
10783 // ) - ( F1B2 * c_cellLengthAtLevel( a_cutCellLevel(cellId) ) )
10784 // << endl;
10785 // errorId = -1;
10786 m_log << "BC: " << bndryId << " " << cellId << " " << errorId << endl;
10787 }
10788
10789 MFloat ar = -F1;
10790 for(MInt dir = 0; dir < m_noDirs; dir++) {
10791 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
10792 if(srfcId > -1) {
10793 if(a_surfaceArea(srfcId) < F0)
10794 errorId = 8;
10795 else if(a_surfaceArea(srfcId) > (faceArea0 + 100 * m_eps))
10796 errorId = 8;
10797 else if(std::isnan(a_surfaceArea(srfcId)))
10798 errorId = 8;
10799 for(MInt i = 0; i < nDim; i++) {
10800 if(fabs(a_surfaceCoordinate(srfcId, i) - a_coordinate(cellId, i))
10801 > (F1B2 * c_cellLengthAtLevel(a_level(cellId)) + 100 * m_eps))
10802 errorId = 8;
10803 if(std::isnan(a_surfaceCoordinate(srfcId, i))) errorId = 8;
10804 }
10805 if(errorId == 8) m_log << a_surfaceCoordinate(srfcId, 0) << " " << a_surfaceCoordinate(srfcId, 1) << endl;
10806 if(errorId == 8) m_log << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << endl;
10807 ar = a_surfaceArea(srfcId);
10808 }
10809 }
10810 if(errorId == 8) {
10811 m_log << "BC: " << bndryId << " " << cellId << " " << errorId << " " << ar << " " << ar - faceArea0 << endl;
10812 for(MInt i = 0; i < nDim; i++)
10813 m_log << a_coordinate(cellId, i) << " ";
10814 m_log << endl;
10816 if(cndId > -1) {
10817 for(MInt node = 0; node < m_noCellNodes; node++) {
10818 m_log << node << " ";
10819 if(m_candidateNodeSet[cndId * m_noCellNodes + node])
10820 m_log << m_candidateNodeValues[IDX_LSSETNODES(cndId, node, 0)] << ", ";
10821 else
10822 m_log << " -1, ";
10823 }
10824 m_log << endl;
10825 }
10826 for(MInt dir = 0; dir < m_noDirs; dir++) {
10827 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
10828 if(srfcId > -1) {
10829 m_log << setprecision(12) << dir << " " << srfcId << ": " << a_surfaceArea(srfcId) / faceArea0 << " ";
10830 for(MInt i = 0; i < nDim; i++)
10831 m_log << F1B2 * c_cellLengthAtLevel(a_level(cellId))
10832 - fabs(a_surfaceCoordinate(srfcId, i) - a_coordinate(cellId, i))
10833 << " ";
10834 m_log << endl;
10835 }
10836 }
10837 }
10838
10839 for(MInt i = 0; i < nDim; i++) {
10840 if(fabs(m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[i])
10841 > (F1B2 * c_cellLengthAtLevel(a_cutCellLevel(cellId)) + m_eps)) {
10842 m_log << "check BC: " << bndryId << " " << errorId << " " << setprecision(16) << m_volumeFraction[bndryId]
10843 << setprecision(8) << " "
10844 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[i] / c_cellLengthAtLevel(a_cutCellLevel(cellId))
10845 << " " << F1B2 * c_cellLengthAtLevel(a_cutCellLevel(cellId)) << endl;
10846 errorId = 9 + i;
10847 }
10848 if(std::isnan(m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[i])) {
10849 m_log << "check BC: " << bndryId << " " << errorId << " " << setprecision(16) << m_volumeFraction[bndryId]
10850 << setprecision(8) << " "
10851 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[i] / c_cellLengthAtLevel(a_cutCellLevel(cellId))
10852 << " " << F1B2 * c_cellLengthAtLevel(a_cutCellLevel(cellId)) << endl;
10853 errorId = 9 + i;
10854 }
10855 }
10856 globalErrorId = mMax(globalErrorId, errorId);
10857 }
10858
10859 if(globalErrorId > 0) {
10860 m_log << "Warning " << globalErrorId << " in FvMbCartesianSolverXD::checkBoundaryCells at timestep "
10861 << globalTimeStep << endl;
10862 cerr << "Warning " << globalErrorId << " in FvMbCartesianSolverXD::checkBoundaryCells at timestep "
10863 << globalTimeStep << endl;
10864 stringstream GName;
10865 GName.str("");
10866 GName << m_solutionOutput;
10867 GName << "solver_data/GEOM";
10868 GName << "_B" << domainId();
10869 GName << "_00" << globalTimeStep;
10870 GName << "_warning";
10871 GName << ".vtp";
10872 // writeGeometryToVtkXmlFile( GName.str() );
10873 }
10874}
MInt a_cutCellLevel(const MInt cellId) const
Returns the level for cutCells, this can either be the maxRefinementLevel or the level of the current...
static constexpr const MInt m_noDirs
std::vector< MInt > m_bndryCandidateIds
static constexpr MInt m_noCellNodes
std::vector< MFloat > m_candidateNodeValues
std::vector< MInt > m_candidateNodeSet
MString m_solutionOutput
Definition: solver.h:82

◆ checkCellState()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::checkCellState

void FvMbCartesianSolverXD<nDim, SysEqn>::checkCellState()

Author
Claudia Guenther
Date
March 2011

Definition at line 26061 of file fvmbcartesiansolverxd.cpp.

26061 {
26062 TRACE();
26063
26064 for(MInt cnd = 0; cnd < m_noBndryCandidates; cnd++) {
26066
26067 MBool isGapCell = false;
26068 if(m_levelSet && m_closeGaps) {
26069 isGapCell = (a_hasProperty(cellId, SolverCell::IsGapCell));
26070 }
26071 MInt startSet = 0;
26072 MInt endSet = 1;
26073 if(m_complexBoundary && m_noLevelSetsUsedForMb > 1 && (!isGapCell)) {
26074 startSet = 1;
26075 endSet = m_noLevelSetsUsedForMb;
26076 }
26077 if(a_hasProperty(cellId, SolverCell::IsInactive) == false) {
26078 MInt minus = true;
26079 for(MInt node = 0; node < m_noCellNodes; node++) {
26080 if(m_candidateNodeValues[IDX_LSSETNODES(cnd, node, 0)] > 0) minus = false;
26081 }
26082 if(minus) {
26083 a_hasProperty(cellId, SolverCell::IsInactive) = true;
26084 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = false;
26085 removeSurfaces(cellId);
26086 }
26087 } else {
26088 MInt plus = true;
26089 for(MInt node = 0; node < m_noCellNodes; node++) {
26090 for(MInt set = startSet; set < endSet; set++)
26091 if(m_candidateNodeValues[IDX_LSSETNODES(cnd, node, set)] <= 0) plus = false;
26092 }
26093 if(plus && c_isLeafCell(cellId)) {
26094 a_hasProperty(cellId, SolverCell::IsInactive) = false;
26095 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = true;
26096 restoreSurfaces(cellId);
26097 }
26098 }
26099 }
26100}
MBool c_isLeafCell(const MInt cellId) const
void removeSurfaces(MInt cellId)
removes the surfaces of the given cell
void restoreSurfaces(const MInt cellId)
restores the surfaces of the given cell
std::vector< MInt > m_bndryCandidates

◆ checkCentroidDiff()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::checkCentroidDiff ( MInt  srfcId1,
MInt  srfcId2 
)
inlineprivate
Author

Definition at line 31326 of file fvmbcartesiansolverxd.cpp.

31326 {
31327 MFloat xDiff = F0;
31328
31329 for(MInt i = 0; i < nDim; i++) {
31330 MFloat diff = a_surfaceCoordinate(srfcId1, i) - a_surfaceCoordinate(srfcId2, i);
31331 xDiff += (diff * diff);
31332 }
31333
31334 return sqrt(xDiff);
31335}

◆ checkDiv()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::checkDiv
inlineoverrideprivatevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 26309 of file fvmbcartesiansolverxd.cpp.

26309 {
26310#if defined _MB_DEBUG_ || !defined NDEBUG
26311 // needs to be int for mpi
26312 MInt solutionDiverged = 0;
26313 MInt cnt = 0;
26314
26315 for(MInt i = a_noCells(); i--;) {
26316 if(cnt >= 100) break;
26317 if(!a_hasProperty(i, SolverCell::IsActive)) continue;
26318 if(!a_hasProperty(i, SolverCell::IsOnCurrentMGLevel)) continue;
26319 if(a_isHalo(i)) continue;
26320 if(a_isBndryGhostCell(i)) continue;
26321
26322 for(MInt v = 0; v < noVariables(); v++) {
26323 if(!(a_variable(i, v) >= F0 || a_variable(i, v) < F0) || std::isnan(a_variable(i, v))) {
26324 cerr << domainId() << ": LHSB " << c_globalId(i) << " " << a_bndryId(i) << " " << a_level(i) << " " << v << " "
26325 << a_variable(i, v) << " "
26326 << "cells[i].b_properties.to_string()"
26327 << " /v " << a_cellVolume(i) / grid().gridCellVolume(c_level(i)) << " "
26328 << m_cellVolumesDt1[i] / grid().gridCellVolume(c_level(i)) << " "
26329 << a_hasProperty(i, SolverCell::IsSplitCell) << " " << a_hasProperty(i, SolverCell::IsSplitChild) << " "
26330 << a_isPeriodic(i) << " " << a_coordinate(i, 0) << " " << a_coordinate(i, 1) << " "
26331 << a_coordinate(i, mMin(nDim - 1, 2)) << " " << a_levelSetValuesMb(i, 0) << " /v "
26332 << a_cellVolume(i) * a_FcellVolume(i) << " " << m_cellVolumesDt1[i] * a_FcellVolume(i) << endl;
26333 solutionDiverged = 1;
26334 cnt++;
26335 }
26336 }
26337
26338 // setPrimitiveVariables(i);
26339 if(a_cellVolume(i) / grid().gridCellVolume(a_level(i)) > m_fvBndryCnd->m_volumeLimitWall) {
26342 cerr << domainId() << ": LHSB(2) " << i << " " << c_globalId(i) << " " << a_bndryId(i) << " " << a_level(i)
26343 << " /r " << a_pvariable(i, maia::fv::PrimitiveVariables<nDim>::RHO) << " /p "
26345 << a_cellVolume(i) / grid().gridCellVolume(c_level(i)) << " "
26346 << m_cellVolumesDt1[i] / grid().gridCellVolume(c_level(i)) << " "
26347 << "cells[i].b_properties.to_string()"
26348 << " " << a_hasProperty(i, SolverCell::IsSplitCell) << " " << a_hasProperty(i, SolverCell::IsSplitChild)
26349 << " " << a_isPeriodic(i) << " " << a_coordinate(i, 0) << " " << a_coordinate(i, 1) << " "
26350 << a_coordinate(i, mMin(nDim - 1, 2)) << " /v " << a_cellVolume(i) * a_FcellVolume(i) << " "
26351 << m_cellVolumesDt1[i] * a_FcellVolume(i) << endl;
26352 solutionDiverged = 1;
26353 cnt++;
26354 }
26355 }
26356 }
26357
26358 if(cnt >= 10) cerr << "More than 10 errors. Not reporting any more." << endl;
26359 if(solutionDiverged == 1) {
26360 cerr << "Solution diverged (LHSB) at solver " << domainId() << " " << globalTimeStep << " " << m_RKStep << endl;
26361 // writeVtkErrorFile();
26362 }
26363
26364 MPI_Allreduce(MPI_IN_PLACE, &solutionDiverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
26365 "solutionDiverged");
26366 if(solutionDiverged == 1) {
26367 writeVtkXmlFiles("QOUT", "GEOM", false, true);
26368 MPI_Barrier(mpiComm(), AT_);
26369 mTerm(1, "Solution diverged after LHSB handling.");
26370 }
26371
26372#endif
26373}
MInt c_level(const MInt cellId) const
Returns the grid level of the cell cellId.
MInt noVariables() const override
Return the number of primitive variables.
Static indices for accessing primitive variables in nd spatial dimensions.
Definition: variables.h:224

◆ checkGapCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::checkGapCells
Author
Tim Wegmann

Definition at line 28349 of file fvmbcartesiansolverxd.cpp.

28349 {
28350 TRACE();
28351
28352 ASSERT(m_levelSet && m_closeGaps, "");
28353 ASSERT(m_gapInitMethod > 0, "");
28354
28355 // const MFloat eps = sqrt( nDim ) * c_cellLengthAtLevel(m_lsCutCellBaseLevel);
28356
28357 // general Checks in all cases:
28358 for(MInt region = 0; region < m_noGapRegions; region++) {
28359 for(MUint it = 0; it < m_gapCells.size(); it++) {
28360 const MInt regionId = m_gapCells[it].region;
28361 if(regionId != region) continue;
28362 const MInt cellId = m_gapCells[it].cellId;
28363 const MInt status = m_gapCells[it].status;
28364
28365 ASSERT(a_cellVolume(cellId) > 0, "");
28366
28367 if(a_cellVolume(cellId) > grid().gridCellVolume(a_level(cellId))) {
28368 const MInt globalId = cellId < c_noCells() ? c_globalId(cellId) : -1;
28369 cerr << "Large Volume " << globalId << " " << status << endl;
28370 }
28371
28372 // ASSERT(m_cellVolumesDt1[ cellId ] > 0 , "");
28373 if(m_cellVolumesDt1[cellId] < 0) {
28374 const MInt globalId = cellId < c_noCells() ? c_globalId(cellId) : -1;
28375 cerr << "Negative Dt-Volume " << globalId << " " << status << " "
28376 << m_cellVolumesDt1[cellId] / grid().gridCellVolume(a_level(cellId)) << endl;
28377 }
28378
28379 if(m_cellVolumesDt1[cellId] > grid().gridCellVolume(a_level(cellId))) {
28380 const MInt globalId = cellId < c_noCells() ? c_globalId(cellId) : -1;
28381 cerr << "Large Dt-Volume " << globalId << " " << status << " "
28382 << m_cellVolumesDt1[cellId] / grid().gridCellVolume(a_level(cellId)) << endl;
28383 }
28384 }
28385 }
28386
28387 // current bndry-cells are checked in updateGapBoundaryCells!
28388
28389 // during gapClosure
28390 for(MInt region = 0; region < m_noGapRegions; region++) {
28391 if(m_gapState[region] != -2) continue;
28392 for(MUint it = 0; it < m_gapCells.size(); it++) {
28393 const MInt regionId = m_gapCells[it].region;
28394 if(regionId != region) continue;
28395 const MInt cellId = m_gapCells[it].cellId;
28396 const MInt status = m_gapCells[it].status;
28397 if(status == 3 || status == 4) {
28398 ASSERT(a_hasProperty(cellId, SolverCell::IsInactive), "");
28399 for(MInt dir = 0; dir < m_noDirs; dir++) {
28400 ASSERT(m_cellSurfaceMapping[cellId][dir] == -1, "");
28401 }
28402 auto it1 = m_oldBndryCells.find(cellId);
28403 ASSERT(it1 == m_oldBndryCells.end(), "");
28404 } else if(status == 5 || status == 6 || status == 7) {
28405 ASSERT(a_isBndryCell(cellId), "");
28406
28407 } else if(status == 8 || status == 9) {
28408 ASSERT(!a_hasProperty(cellId, SolverCell::IsInactive), "");
28409 ASSERT(!a_isBndryCell(cellId), "");
28410 ASSERT(abs(a_cellVolume(cellId) - grid().gridCellVolume(a_level(cellId))) < 0.000001, "");
28411 } else if(status == 2) {
28412 ASSERT(a_hasProperty(cellId, SolverCell::IsInactive), "");
28413 }
28414 }
28415 }
28416
28417 // during gap widening
28418 for(MInt region = 0; region < m_noGapRegions; region++) {
28419 if(m_gapState[region] != 3) continue;
28420 for(MUint it = 0; it < m_gapCells.size(); it++) {
28421 const MInt regionId = m_gapCells[it].region;
28422 if(regionId != region) continue;
28423 const MInt cellId = m_gapCells[it].cellId;
28424 const MInt status = m_gapCells[it].status;
28425
28426 ASSERT((status >= 10 && status < 18) || (status == 0 /*&& a_levelSetValuesMb(cellId, 0) < -eps*/)
28427 || (status == 21 || status == 22 || status == 28 || status == 29),
28428 to_string(status));
28429
28430 // check that all active cells either are a bndry-Cell or were active before
28431 if(!a_hasProperty(cellId, SolverCell::IsInactive) && !a_isBndryCell(cellId)) {
28432 ASSERT(!a_hasProperty(cellId, SolverCell::WasInactive), "");
28433 }
28434
28435 if(status == 10)
28436 ASSERT(a_cellVolume(cellId) - grid().gridCellVolume(a_level(cellId)) < 0.00001, to_string(c_globalId(cellId)));
28437
28438 if(status != 11) {
28439 if(a_cellVolume(cellId) < 0 || m_cellVolumesDt1[cellId] < 0) {
28440 cerr << "Volume-Error in gap-Cell " << c_globalId(cellId) << " " << status << " "
28441 << a_hasProperty(cellId, SolverCell::IsInactive) << " " << a_isHalo(cellId) << endl;
28442 }
28443 }
28444
28445 if(status == 12 || status == 13) {
28446 if(a_isHalo(cellId)) {
28447 /*
28448 auto it1 = m_linkedHaloCells.find( cellId );
28449 if(it1 == m_linkedHaloCells.end()) {
28450 cerr << "CAUTION: unable to link Halo-gap BndryCell during Gap-Widening " << c_globalId(cellId)
28451 << " " << status << " " << a_hasProperty(cellId, SolverCell::IsInactive)
28452 << " " << a_isBndryCell(cellId) << " " << a_hasProperty(cellId, SolverCell::WasInactive)
28453 << " " << a_isHalo(cellId)
28454 << endl;
28455 }
28456 */
28457 } else if(!a_hasProperty(cellId, SolverCell::IsSplitChild)) {
28458 if(!a_hasProperty(cellId, SolverCell::IsTempLinked)) {
28459 cerr << "CAUTION: unable to link gap BndryCell during Gap-Widening " << c_globalId(cellId) << " " << status
28460 << " " << a_hasProperty(cellId, SolverCell::IsInactive) << " " << a_isBndryCell(cellId) << " "
28461 << a_hasProperty(cellId, SolverCell::WasInactive) << " " << a_isHalo(cellId) << endl;
28462 }
28463 }
28464
28465 } else if(status == 14 || status == 15) {
28466 if(a_cellVolume(cellId) < 0 || a_cellVolume(cellId) > grid().gridCellVolume(a_level(cellId))) {
28467 // cerr << "Invalid Volume " << c_globalId(cellId) << " " << status
28468 // << " " << a_isHalo(cellId) << " " << a_cellVolume(cellId) << " "
28469 // << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " "
28470 // << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << endl;
28471 }
28472 }
28473 }
28474 }
28475
28476 // during gap opening
28477 for(MInt region = 0; region < m_noGapRegions; region++) {
28478 if(m_gapState[region] != 2) continue;
28479 for(MUint it = 0; it < m_gapCells.size(); it++) {
28480 const MInt regionId = m_gapCells[it].region;
28481 if(regionId != region) continue;
28482 const MInt cellId = m_gapCells[it].cellId;
28483 const MInt status = m_gapCells[it].status;
28484
28485 ASSERT(((status > 20 && status <= 29) || status == 99 || status == 98), to_string(status));
28486
28487 if(status == 21) {
28488 if(a_cellVolume(cellId) > grid().gridCellVolume(a_level(cellId))
28489 || a_cellVolume(cellId) < grid().gridCellVolume(a_level(cellId))) {
28490 cerr << "Incorrect Cell-Volume of arising Gap-Cell" << c_globalId(cellId) << " " << a_cellVolume(cellId)
28491 << " " << grid().gridCellVolume(a_level(cellId)) << endl;
28492 }
28493
28494 // surface-check
28495 ASSERT(!a_hasProperty(cellId, SolverCell::IsInactive), "");
28496
28497 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
28498 for(MInt dir = 0; dir < m_noDirs; dir++) {
28499 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
28500 MInt nghbrId = c_neighborId(cellId, dir);
28501 if(nghbrId < 0) continue;
28502 if(a_isHalo(cellId) && a_isHalo(nghbrId)) continue;
28503 if(srfcId < 0) {
28504 cerr << "CAUTION: Arising-Gap-Cell is missing surfaces " << c_globalId(cellId) << " " << dir << " "
28505 << a_levelSetValuesMb(cellId, 0) << " " << a_isHalo(cellId) << " "
28506 << a_hasProperty(cellId, SolverCell::IsNotGradient) << endl;
28507 }
28508 }
28509 } else if(status == 22 && false) {
28510 if(!a_isHalo(cellId)) {
28511 if(!a_hasProperty(cellId, SolverCell::IsTempLinked)) {
28512 cerr << "CAUTION: unable to link gap BndryCell during initGapOpening " << c_globalId(cellId) << " "
28513 << status << " " << a_hasProperty(cellId, SolverCell::IsInactive) << " " << a_isBndryCell(cellId)
28514 << " " << a_hasProperty(cellId, SolverCell::WasInactive) << " " << a_isHalo(cellId) << endl;
28515 }
28516 }
28517 }
28518 }
28519 }
28520
28521 // during gap shrinking
28522 for(MInt region = 0; region < m_noGapRegions; region++) {
28523 if(m_gapState[region] != -1) continue;
28524 for(MUint it = 0; it < m_gapCells.size(); it++) {
28525 MInt regionId = m_gapCells[it].region;
28526 if(regionId != region) continue;
28527 MInt cellId = m_gapCells[it].cellId;
28528
28529 if(!a_isBndryCell(cellId)) continue;
28530 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
28531 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
28532
28533 if(a_wasGapCell(cellId) && !a_isGapCell(cellId)) continue;
28534
28535 MInt bndryId = a_bndryId(cellId);
28536 if(bndryId < -1) continue;
28537 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28538 for(MInt i = 0; i < nDim; i++) {
28539 ASSERT(abs(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]]) < 0.00000001, "");
28540 }
28541 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
28542 if(ghostCellId < 0) continue;
28543 }
28544 }
28545 }
28546
28547 // checkGapHaloCells:
28548 const MInt noChecks = 4;
28549 MFloatScratchSpace cellCheck(a_noCells(), noChecks, AT_, "cellCheck");
28550 cellCheck.fill(std::numeric_limits<MFloat>::max());
28551
28552 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
28553 cellCheck(cellId, 0) = (MFloat)a_isGapCell(cellId);
28554 cellCheck(cellId, 1) = (MFloat)a_wasGapCell(cellId);
28555 cellCheck(cellId, 2) = -F1;
28556 cellCheck(cellId, 3) = -F1;
28557 if(a_isGapCell(cellId) || a_wasGapCell(cellId)) {
28558 const MInt region = m_gapCells[m_gapCellId[cellId]].region;
28559 const MInt status = m_gapCells[m_gapCellId[cellId]].status;
28560 cellCheck(cellId, 2) = (MFloat)region;
28561 cellCheck(cellId, 3) = (MFloat)status;
28562 }
28563 }
28564
28565 exchangeDataFV(&cellCheck(0), noChecks);
28566
28567 for(MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
28568 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
28569 if((MInt)cellCheck(cellId, 0) != a_isGapCell(cellId)) {
28570 cerr << domainId() << ": ERR0 checkGapHaloCells " << globalTimeStep << " " << c_globalId(cellId) << endl;
28571 }
28572 if((MInt)cellCheck(cellId, 1) != a_wasGapCell(cellId)) {
28573 cerr << domainId() << ": ERR1 checkGapHaloCells " << globalTimeStep << " " << c_globalId(cellId) << endl;
28574 }
28575 MInt region = -1;
28576 MInt status = -1;
28577 if(a_isGapCell(cellId) || a_wasGapCell(cellId)) {
28578 region = m_gapCells[m_gapCellId[cellId]].region;
28579 status = m_gapCells[m_gapCellId[cellId]].status;
28580 }
28581
28582 if((MInt)cellCheck(cellId, 2) != region) {
28583 cerr << domainId() << ": ERR2 checkGapHaloCells " << globalTimeStep << " " << c_globalId(cellId) << endl;
28584 }
28585 if((MInt)cellCheck(cellId, 3) != status) {
28586 cerr << domainId() << ": ERR3 checkGapHaloCells " << globalTimeStep << " " << c_globalId(cellId) << endl;
28587 }
28588 }
28589}
MBool a_isBndryCell(const MInt cellId) const override
Returns isBndryCell of the cell cellId.
MBool a_isGapCell(const MInt cellId) const
Returns isGapCell of the cell cellId.
maia::fv::cell::BitsetType::reference a_wasGapCell(const MInt cellId)
Returns wasGapCell of the cell cellId.

◆ checkHaloBndryCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::checkHaloBndryCells ( MBool  sweptVol)
Author
Lennart Schneiders

Definition at line 9950 of file fvmbcartesiansolverxd.cpp.

9950 {
9951 TRACE();
9952
9953 constexpr MFloat eps0 = 1e-12;
9954 constexpr MFloat eps1 = 1e-11;
9955
9956 MFloatScratchSpace cellCheck(a_noCells(), 14, AT_, "cellCheck");
9957 cellCheck.fill(std::numeric_limits<MFloat>::max());
9958
9959 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
9960 cellCheck(cellId, 0) = (MFloat)a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel);
9961 cellCheck(cellId, 1) = a_bndryId(cellId) > -1 ? (MFloat)m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs
9962 : std::numeric_limits<MFloat>::max();
9963 cellCheck(cellId, 2) = a_levelSetValuesMb(cellId, 0);
9964 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
9965 cellCheck(cellId, 3) = (MFloat)a_hasProperty(cellId, SolverCell::IsInactive);
9966 cellCheck(cellId, 4) = (MFloat)a_hasProperty(cellId, SolverCell::WasInactive);
9967 cellCheck(cellId, 5) = (MFloat)a_hasProperty(cellId, SolverCell::IsSplitCell);
9968 cellCheck(cellId, 6) = (MFloat)a_hasProperty(cellId, SolverCell::IsSplitChild);
9969 cellCheck(cellId, 7) = (MFloat)a_hasProperty(cellId, SolverCell::IsGapCell);
9970 cellCheck(cellId, 8) = (MFloat)a_hasProperty(cellId, SolverCell::WasGapCell);
9971 cellCheck(cellId, 9) = a_cellVolume(cellId);
9972 cellCheck(cellId, 10) = m_cellVolumesDt1[cellId];
9973 cellCheck(cellId, 11) =
9974 a_bndryId(cellId) > -1 ? m_sweptVolume[a_bndryId(cellId)] : std::numeric_limits<MFloat>::max();
9975 cellCheck(cellId, 12) =
9976 a_bndryId(cellId) > -1 ? m_sweptVolumeDt1[a_bndryId(cellId)] : std::numeric_limits<MFloat>::max();
9977 cellCheck(cellId, 13) = F1;
9978 }
9979 for(MUint sc = 0; sc < m_splitCells.size(); sc++) {
9980 const MInt cellId = m_splitCells[sc];
9981 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
9982 cellCheck(cellId, 9) += a_cellVolume(m_splitChilds[sc][ssc]);
9983 cellCheck(cellId, 10) += m_cellVolumesDt1[m_splitChilds[sc][ssc]];
9984 cellCheck(cellId, 11) += m_sweptVolume[a_bndryId(m_splitChilds[sc][ssc])];
9985 cellCheck(cellId, 12) += m_sweptVolumeDt1[a_bndryId(m_splitChilds[sc][ssc])];
9986 cellCheck(cellId, 13) += F1;
9987 }
9988 }
9989
9990 // exchangeData( &cellCheck(0), (MInt)cellCheck.size1() );
9991 exchangeData(&cellCheck(0), 14);
9992
9993 for(MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
9994 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
9995 // Azimuthal periodic window/halo cells are not identical in the sense of the cartesian grid!
9996 if(grid().azimuthalPeriodicity() && a_isPeriodic(cellId)) continue;
9997
9998 if((MInt)cellCheck(cellId, 0) != a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))
9999 cerr << domainId() << ": ERR0 generateBndryCellsMb " << globalTimeStep << " " << cellId << " "
10000 << c_globalId(cellId) << " " << cellCheck(cellId, 0) << " "
10001 << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " "
10002 << (((a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId)) << " "
10003 << a_hasProperty(cellId, SolverCell::IsSplitCell) << " " << a_hasProperty(cellId, SolverCell::IsSplitChild)
10004 << " " << a_isHalo(cellId) << " " << a_isWindow(cellId) << " "
10005 << a_levelSetValuesMb(cellId, 0) / c_cellLengthAtCell(cellId) << " " << a_bndryId(cellId) << " "
10006 << a_level(((a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId))
10007 << endl;
10008 if((MInt)cellCheck(cellId, 1)
10009 != (MInt)(a_bndryId(cellId) > -1 ? (MFloat)m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs
10010 : std::numeric_limits<MFloat>::max())) {
10011 MFloat noSurfaces = std::numeric_limits<MFloat>::max();
10012 if(a_bndryId(cellId) > -1) {
10013 noSurfaces = (MFloat)m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs;
10014 }
10015 cerr << domainId() << ": ERR1 generateBndryCellsMb " << globalTimeStep << " " << cellId << " "
10016 << m_noOuterBndryCells << " " << a_bndryId(cellId) << " " << noSurfaces << " " << c_globalId(cellId) << endl;
10017 }
10018 if(fabs(cellCheck(cellId, 2) - a_levelSetValuesMb(cellId, 0)) > eps1)
10019 if(!m_adaptation
10020 || mMin(cellCheck(cellId, 2), a_levelSetValuesMb(cellId, 0)) < m_outerBandWidth[maxUniformRefinementLevel()])
10021 cerr << domainId() << ": ERR2 generateBndryCellsMb " << globalTimeStep << " " << cellId << " "
10022 << cellCheck(cellId, 2) << " " << a_levelSetValuesMb(cellId, 0) << " "
10023 << cellCheck(cellId, 2) - a_levelSetValuesMb(cellId, 0) << " " << c_globalId(cellId) << " "
10024 << m_bodyDistThreshold << endl;
10025 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
10026 if(!a_isHalo(cellId)) continue;
10027 if((MInt)cellCheck(cellId, 3) != a_hasProperty(cellId, SolverCell::IsInactive))
10028 cerr << domainId() << ": ERR3 generateBndryCellsMb " << globalTimeStep << " " << cellId << " "
10029 << a_hasProperty(cellId, SolverCell::IsSplitCell) << " " << a_hasProperty(cellId, SolverCell::IsSplitChild)
10030 << " " << a_isHalo(cellId) << " " << a_isWindow(cellId) << " " << a_levelSetValuesMb(cellId, 0) << endl;
10031 if((MInt)cellCheck(cellId, 4) != a_hasProperty(cellId, SolverCell::WasInactive))
10032 cerr << domainId() << ": ERR4 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10033 if((MInt)cellCheck(cellId, 5) != a_hasProperty(cellId, SolverCell::IsSplitCell))
10034 cerr << domainId() << ": ERR5 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10035 if((MInt)cellCheck(cellId, 6) != a_hasProperty(cellId, SolverCell::IsSplitChild))
10036 cerr << domainId() << ": ERR6 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10037 if((MInt)cellCheck(cellId, 7) != a_hasProperty(cellId, SolverCell::IsGapCell))
10038 cerr << domainId() << ": ERR7 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10039 if((MInt)cellCheck(cellId, 8) != a_hasProperty(cellId, SolverCell::WasGapCell))
10040 cerr << domainId() << ": ERR8 generateBndryCellsMb " << globalTimeStep << " " << c_globalId(cellId) << endl;
10041 if(!a_hasProperty(cellId, SolverCell::IsSplitCell) && !a_hasProperty(cellId, SolverCell::IsSplitCell)) {
10042 if(fabs(cellCheck(cellId, 9) - a_cellVolume(cellId)) > eps0)
10043 cerr << domainId() << ": ERR9 generateBndryCellsMb " << cellId << " " << c_globalId(cellId) << " "
10044 << a_hasProperty(cellId, SolverCell::IsSplitCell) << " " << a_hasProperty(cellId, SolverCell::IsSplitChild)
10045 << " " << a_isHalo(cellId) << " " << a_isWindow(cellId) << " ls " << a_levelSetValuesMb(cellId, 0) << " "
10046 << a_isGapCell(cellId) << " " << a_wasGapCell(cellId) << " " << a_bndryId(cellId) << " " << a_level(cellId)
10047 << " " << a_cellVolume(cellId) << " "
10048 << (cellCheck(cellId, 9) - grid().gridCellVolume(a_level(cellId))) / grid().gridCellVolume(a_level(cellId))
10049 << " "
10050 << (a_cellVolume(cellId) - grid().gridCellVolume(a_level(cellId))) / grid().gridCellVolume(a_level(cellId))
10051 << " " << fabs(cellCheck(cellId, 9) - a_cellVolume(cellId)) / grid().gridCellVolume(a_level(cellId))
10052 << endl;
10053
10054 if(fabs(cellCheck(cellId, 10) - m_cellVolumesDt1[cellId]) > eps0)
10055 cerr << domainId() << ": ERR10 generateBndryCellsMb " << globalTimeStep << " " << cellId << " "
10056 << c_globalId(cellId) << " " << a_isGapCell(cellId) << a_wasGapCell(cellId) << endl;
10057 if(sweptVol) {
10058 if(a_bndryId(cellId) > -1 && fabs(cellCheck(cellId, 11) - m_sweptVolume[a_bndryId(cellId)]) > eps0)
10059 cerr << domainId() << ": ERR11 generateBndryCellsMb " << globalTimeStep << " " << cellId << " "
10060 << c_globalId(cellId) << " " << cellCheck(cellId, 11) << " " << m_sweptVolume[a_bndryId(cellId)] << " "
10061 << a_bndryId(cellId) << " " << m_noOuterBndryCells << " "
10062 << a_hasProperty(cellId, SolverCell::IsSplitCell) << " "
10063 << a_hasProperty(cellId, SolverCell::IsSplitChild) << " " << a_isGapCell(cellId) << " "
10064 << a_wasGapCell(cellId) << endl;
10065 if(a_bndryId(cellId) > -1 && fabs(cellCheck(cellId, 12) - m_sweptVolumeDt1[a_bndryId(cellId)]) > eps0)
10066 cerr << domainId() << ": ERR12 generateBndryCellsMb " << globalTimeStep << " " << cellId << " "
10067 << a_isGapCell(cellId) << " " << a_wasGapCell(cellId) << endl;
10068 }
10069 }
10070 }
10071 for(MUint sc = 0; sc < m_splitCells.size(); sc++) {
10072 const MInt cellId = m_splitCells[sc];
10073 if(a_isHalo(cellId)) {
10074 // Azimuthal periodic window/halo cells are not identical in the sense of the cartesian grid!
10075 if(grid().azimuthalPeriodicity() && a_isPeriodic(cellId)) continue;
10076 MFloat test0 = F1;
10077 MFloat test1 = a_cellVolume(cellId);
10079 MFloat test33 = m_sweptVolume[a_bndryId(cellId)];
10080 MFloat test4 = m_sweptVolumeDt1[a_bndryId(cellId)];
10081 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
10082 test0 += F1;
10083 test1 += a_cellVolume(m_splitChilds[sc][ssc]);
10084 test2 += m_cellVolumesDt1[m_splitChilds[sc][ssc]];
10085 test33 += m_sweptVolume[a_bndryId(m_splitChilds[sc][ssc])];
10086 test4 += m_sweptVolumeDt1[a_bndryId(m_splitChilds[sc][ssc])];
10087 }
10088 if((MInt)test0 != (MInt)cellCheck(cellId, 13))
10089 cerr << domainId() << ": ERR13 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10090 if(fabs(test1 - cellCheck(cellId, 9)) > eps0)
10091 cerr << domainId() << ": ERR14 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10092 if(fabs(test2 - cellCheck(cellId, 10)) > eps0)
10093 cerr << domainId() << ": ERR15 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10094 if(sweptVol) {
10095 if(fabs(test33 - cellCheck(cellId, 11)) > eps0)
10096 cerr << domainId() << ": ERR16 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10097 if(fabs(test4 - cellCheck(cellId, 12)) > eps0)
10098 cerr << domainId() << ": ERR17 generateBndryCellsMb " << globalTimeStep << " " << cellId << endl;
10099 }
10100 }
10101 }
10102}
MBool a_isWindow(const MInt cellId) const
Returns IsWindow of the cell cellId.
MFloat * m_outerBandWidth
Definition: solver.h:92

◆ checkHaloCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::checkHaloCells ( MInt  mode = 0)

mode = 0 : default mode mode = 1 : in reinitAfterAdaptation, here IsInactive is not set correctly yet. mode = 2 : only check gap-properties mode = 3 : skip cellVolumesDt1 check

Author
Tim Wegmann

Definition at line 27054 of file fvmbcartesiansolverxd.cpp.

27054 {
27055 TRACE();
27056
27057 const MFloat eps0 = 1e-12;
27058 const MInt noChecks = 11;
27059 MFloatScratchSpace cellCheck(a_noCells(), noChecks, AT_, "cellCheck");
27060 cellCheck.fill(std::numeric_limits<MFloat>::max());
27061
27062 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
27063 cellCheck(cellId, 0) = F1;
27064 cellCheck(cellId, 1) = a_cellVolume(cellId);
27065 cellCheck(cellId, 2) = m_cellVolumesDt1[cellId];
27066 cellCheck(cellId, 3) = (MFloat)a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel);
27067 cellCheck(cellId, 4) = (MFloat)a_hasProperty(cellId, SolverCell::IsInactive);
27068 cellCheck(cellId, 5) = a_levelSetValuesMb(cellId, 0);
27069 cellCheck(cellId, 6) = (MFloat)a_isGapCell(cellId);
27070 cellCheck(cellId, 7) = (MFloat)a_wasGapCell(cellId);
27071 cellCheck(cellId, 8) = (MFloat)a_hasProperty(cellId, SolverCell::NearWall);
27072 cellCheck(cellId, 9) = (MFloat)a_bndryId(cellId) > -1 ? 1 : -1;
27073 cellCheck(cellId, 10) = (MFloat)a_hasProperty(cellId, SolverCell::WasInactive);
27074 }
27075
27076 exchangeData(&cellCheck(0), noChecks);
27077
27078 for(MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
27079 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
27080 if(a_isBndryGhostCell(cellId)) continue;
27081 // Azimuthal periodic window/halo cells are not identical in the sense of the cartesian grid!
27082 if(grid().azimuthalPeriodicity() && a_isPeriodic(cellId)) continue;
27083
27084 ASSERT((MInt)cellCheck(cellId, 0) == 1, to_string(a_isHalo(cellId)));
27085
27086 if(mode == 2) {
27087 if((MInt)cellCheck(cellId, 6) != a_isGapCell(cellId)) {
27088 cerr << domainId() << ": ERR7 checkHaloCells " << globalTimeStep << " " << c_globalId(cellId) << endl;
27089 }
27090
27091 if((MInt)cellCheck(cellId, 7) != a_wasGapCell(cellId)) {
27092 cerr << domainId() << ": ERR7 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27093 }
27094 continue;
27095 }
27096
27097
27098 if(fabs(cellCheck(cellId, 1) - a_cellVolume(cellId)) > eps0) {
27099 cerr << domainId() << ": ERR1 checkHaloCells " << cellId << " " << c_globalId(cellId) << " "
27100 << a_hasProperty(cellId, SolverCell::IsSplitCell) << " " << a_hasProperty(cellId, SolverCell::IsSplitChild)
27101 << " " << a_isHalo(cellId) << " " << a_isWindow(cellId) << " " << a_level(cellId) << " "
27102 << a_cellVolume(cellId) << " " << cellCheck(cellId, 1) << " "
27103 << (cellCheck(cellId, 1) - grid().gridCellVolume(a_level(cellId))) / grid().gridCellVolume(a_level(cellId))
27104 << " "
27105 << (a_cellVolume(cellId) - grid().gridCellVolume(a_level(cellId))) / grid().gridCellVolume(a_level(cellId))
27106 << " " << fabs(cellCheck(cellId, 1) - a_cellVolume(cellId)) / grid().gridCellVolume(a_level(cellId)) << endl;
27107 }
27108 if(fabs(cellCheck(cellId, 2) - m_cellVolumesDt1[cellId]) > eps0 && mode != 3) {
27109 cerr << domainId() << ": ERR2 checkHaloCells " << globalTimeStep << " " << c_globalId(cellId) << " "
27110 << m_cellVolumesDt1[cellId] << " " << cellCheck(cellId, 2) << " " << c_isLeafCell(cellId) << endl;
27111 }
27112 if((MInt)cellCheck(cellId, 3) != a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
27113 cerr << domainId() << ": ERR3 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27114 }
27115
27116 if(fabs(cellCheck(cellId, 5) - a_levelSetValuesMb(cellId, 0)) > eps0) {
27117 cerr << domainId() << ": ERR5 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27118 }
27119
27120 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
27121
27122 if(mode != 1) {
27123 if((MInt)cellCheck(cellId, 4) != a_hasProperty(cellId, SolverCell::IsInactive)) {
27124 cerr << domainId() << ": ERR4 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27125 }
27126 }
27127
27128 if((MInt)cellCheck(cellId, 6) != a_isGapCell(cellId)) {
27129 cerr << domainId() << ": ERR6 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27130 }
27131
27132 if((MInt)cellCheck(cellId, 7) != a_wasGapCell(cellId)) {
27133 cerr << domainId() << ": ERR7 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27134 }
27135 if((MInt)cellCheck(cellId, 8) != a_hasProperty(cellId, SolverCell::NearWall)) {
27136 cerr << domainId() << ": ERR8 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27137 }
27138 const MInt isbndry = a_bndryId(cellId) > -1 ? 1 : -1;
27139 if((MInt)cellCheck(cellId, 9) != isbndry) {
27140 cerr << domainId() << ": ERR9 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27141 }
27142
27143 if(mode != 3) {
27144 if((MInt)cellCheck(cellId, 10) != a_hasProperty(cellId, SolverCell::WasInactive)) {
27145 cerr << domainId() << ": ERR10 checkHaloCells " << globalTimeStep << " " << cellId << endl;
27146 }
27147 }
27148 }
27149}

◆ checkNeighborActivity()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::checkNeighborActivity ( MInt  cellId)
Author
Tim Wegmann

Definition at line 29512 of file fvmbcartesiansolverxd.cpp.

29512 {
29513 TRACE();
29514
29515 ASSERT(cellId >= 0, "");
29516
29517 if(!a_hasProperty(cellId, SolverCell::WasInactive)) return -1;
29518 if(a_hasProperty(cellId, SolverCell::IsInactive)) return -2;
29519
29520 MInt masterId = -1;
29521 MInt largestNeighbor = -1;
29522 MFloat maxVol = F0;
29523 MFloat maxVolActive = F0;
29524 MInt noInternalNghbrs = 0;
29525 for(MInt dir = 0; dir < m_noDirs; dir++) {
29526 if(!checkNeighborActive(cellId, dir) || a_hasNeighbor(cellId, dir) == 0) continue;
29527 const MInt nghbrId = c_neighborId(cellId, dir);
29528 if(nghbrId < 0) continue;
29529 if(a_hasProperty(nghbrId, SolverCell::IsSplitCell)) continue;
29530 if(a_hasProperty(nghbrId, SolverCell::IsSplitChild)) continue;
29531 if(a_cellVolume(nghbrId) > maxVolActive && !a_hasProperty(nghbrId, SolverCell::WasInactive)) {
29532 masterId = nghbrId;
29533 maxVolActive = a_cellVolume(nghbrId);
29534 }
29535 if(a_cellVolume(nghbrId) > maxVol) {
29536 largestNeighbor = nghbrId;
29537 maxVol = a_cellVolume(nghbrId);
29538 }
29539 }
29540
29541 if(masterId > -1) return -1;
29542 if(a_isHalo(cellId) && noInternalNghbrs == 0) return -1;
29543
29544 ASSERT(a_hasProperty(largestNeighbor, SolverCell::WasInactive), "");
29545 ASSERT(largestNeighbor > 0, "");
29546
29547 // reverse the further search!
29548 if(a_cellVolume(largestNeighbor) < a_cellVolume(cellId)) {
29549 MInt backup = cellId;
29550 cellId = largestNeighbor;
29551 largestNeighbor = backup;
29552 }
29553
29554 /*
29555 cerr << "New small gap-bndry cell is " << c_globalId(cellId)
29556 << " with volume "
29557 << m_fvBndryCnd->m_bndryCells->a[ a_bndryId( cellId ) ].m_volume /grid().gridCellVolume(a_level(cellId)) << "
29558 "
29559 << a_isHalo(cellId) << " "
29560 << a_hasProperty( cellId, Cell::IsWindow )
29561 << " largestNeighbor is " << c_globalId(largestNeighbor)
29562 << " with volume " << m_fvBndryCnd->m_bndryCells->a[ a_bndryId( largestNeighbor )
29563 ].m_volume/grid().gridCellVolume(a_level(largestNeighbor)) << " "
29564 << a_isHalo(largestNeighbor) << " "
29565 << a_hasProperty( largestNeighbor, Cell::IsWindow ) << " "
29566 << domainId()
29567 << endl;
29568 */
29569
29570 ASSERT(a_wasGapCell(largestNeighbor) || a_isGapCell(largestNeighbor), "");
29571
29572
29573 // initialise the largest-Neighbor for partial-gap-opening!
29574 const MInt region = m_gapCells[m_gapCellId[cellId]].region;
29575 ASSERT(region > -1 && region < m_noGapRegions, "");
29576 if(m_gapState[region] != 2) {
29577 // find a neighbor of the largestneighbor which was active before and initialise
29578 // the largetsNeighbor before the linking
29579
29580 // find a sourringding cell of the largestNeighbor
29581 // which was active before and initialise the largestNeighbor with its values
29582
29583
29584 // if ( a_isHalo( cellId ) && a_isHalo(largestNeighbor) ) return -1;
29585
29586 // return if the largestNeighbor is on the secondHalo-layer
29587 // and thus might not find a masterId as it might be on a different rank!
29588 if(a_isHalo(largestNeighbor) && a_hasProperty(largestNeighbor, SolverCell::IsNotGradient)) {
29589 return -1;
29590 }
29591
29592 maxVol = F0;
29593 for(MInt dir = 0; dir < m_noDirs; dir++) {
29594 if(!checkNeighborActive(largestNeighbor, dir) || a_hasNeighbor(largestNeighbor, dir) == 0) continue;
29595 MInt nghbrId = c_neighborId(largestNeighbor, dir);
29596 if(nghbrId < 0) continue;
29597 if(a_hasProperty(nghbrId, SolverCell::WasInactive)) continue;
29598 if(a_cellVolume(nghbrId) > maxVol) {
29599 masterId = nghbrId;
29600 maxVol = a_cellVolume(nghbrId);
29601 }
29602 }
29603
29604 if(masterId > -1) {
29605 for(MInt v = 0; v < m_noCVars; v++) {
29606 a_variable(largestNeighbor, v) = a_variable(masterId, v);
29607 a_oldVariable(largestNeighbor, v) = a_oldVariable(masterId, v);
29608 }
29609 for(MInt v = 0; v < m_noPVars; v++) {
29610 a_pvariable(largestNeighbor, v) = a_pvariable(masterId, v);
29611 }
29612 for(MInt v = 0; v < m_noFVars; v++) {
29613 a_rightHandSide(largestNeighbor, v) = F0;
29614 m_rhs0[largestNeighbor][v] = F0;
29615 }
29616 } else {
29617 // the largest neighbor does not have an neighbor who was active before and
29618 // can thus not be initialised!
29619 //=> new search for a different neighbor!
29620 // a) initialise neighbor with infinity variables
29621 // b) retry neighbor search from cellId to find any neighboring cell which
29622 // has an active neighbor!
29623 cerr << a_isHalo(largestNeighbor) << " " << a_isHalo(cellId) << endl;
29624 mTerm(1, AT_, "Even the largest neighbor is inactive!");
29625 }
29626 }
29627
29628
29629 if(a_isHalo(largestNeighbor)) {
29630 cerr << "Caution changing cell-property of a Halo-Cell! " << endl;
29631 // mark this cell and change the window-Cell accordingly!
29632 }
29633
29634 a_hasProperty(largestNeighbor, SolverCell::WasInactive) = false;
29635 m_oldBndryCells.insert(make_pair(largestNeighbor, F0));
29636
29637
29638 return largestNeighbor;
29639}
MBool checkNeighborActive(const MInt cellId, const MInt dir) const
Cecks wether the cell cellId has a valid neighbor in direction dir.

◆ checkNormalVectors()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==3, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::checkNormalVectors
Author

Definition at line 31638 of file fvmbcartesiansolverxd.cpp.

31638 {
31639 const MInt noCells = m_fvBndryCnd->m_bndryCells->size();
31640
31641 for(MInt bndryId = m_noOuterBndryCells; bndryId < noCells; bndryId++) {
31642 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
31643 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId < 0) {
31644 mTerm(1, AT_, "error in createCutFaceMb(): m_bndryCndId not set: " + to_string(bndryId));
31645 }
31646 MFloat test = F0;
31647 for(MInt i = 0; i < nDim; i++) {
31648 test += POW2(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]);
31649 }
31650 if(fabs(test - F1) > 0.1) {
31651 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
31652#ifdef _MB_DEBUG_
31653 cerr << domainId() << ": bad normal vector corrected, n^2=" << test << ", timestep= " << globalTimeStep
31654 << ", cell " << cellId << " " << bndryId << " " << srfc << " " << c_globalId(cellId)
31655 << " /p15=" << a_isHalo(cellId) << " /n "
31656 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0] << " "
31657 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1] << " "
31658 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2] << " /a "
31659 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcs[srfc]->m_area << " /v "
31660 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume / grid().gridCellVolume(a_level(cellId)) << " /c "
31661 << m_bndryCells->a[bndryId].m_coordinates[0] << " " << m_bndryCells->a[bndryId].m_coordinates[1] << " "
31662 << m_bndryCells->a[bndryId].m_coordinates[2] << " /s "
31663 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[0] << " "
31664 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[1] << " "
31665 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[2] << endl;
31666#endif
31667 MFloat nablaPhi[3] = {F1, F1, F1};
31668 MFloat nablaAbs = F0;
31669 for(MInt i = 0; i < nDim; i++) {
31670 MInt n0 = (a_hasNeighbor(cellId, 2 * i) > 0) ? c_neighborId(cellId, 2 * i) : cellId;
31671 MInt n1 = (a_hasNeighbor(cellId, 2 * i + 1) > 0) ? c_neighborId(cellId, 2 * i + 1) : cellId;
31672 if(n0 != n1) {
31673 nablaPhi[i] = (a_levelSetValuesMb(n1, 0) - a_levelSetValuesMb(n0, 0))
31674 / mMax(1e-14, a_coordinate(n1, i) - a_coordinate(n0, i));
31675 }
31676 nablaAbs += POW2(nablaPhi[i]);
31677 }
31678 nablaAbs = sqrt(nablaAbs);
31679 for(MInt i = 0; i < nDim; i++) {
31680 nablaPhi[i] /= nablaAbs;
31681 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] = nablaPhi[i];
31682 }
31683#ifdef _MB_DEBUG_
31684 cerr << domainId() << ": corrected " << POW2(nablaAbs) << " /n "
31685 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0] << " "
31686 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1] << " "
31687 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2] << endl;
31688 // m_fvBndryCnd->writeStlFileOfCell(cellId,("out/cell_"+to_string(c_globalId(cellId))+"_"+to_string(globalTimeStep)+".stl").c_str());
31689#endif
31690 } else {
31691 test = sqrt(test);
31692 for(MInt i = 0; i < nDim; i++) {
31693 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] /= test;
31694 }
31695 }
31696 }
31697 }
31698}

◆ commAzimuthalPeriodicData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::commAzimuthalPeriodicData ( MInt  mode = 0)
Author
Thomas Hoesgen

Definition at line 36604 of file fvmbcartesiansolverxd.cpp.

36604 {
36605 TRACE();
36606
36607 if(grid().noAzimuthalNeighborDomains() == 0) return;
36608
36609 MInt noFloatData = (mode == 0 ? m_noFloatDataAdaptation : m_noFloatDataBalance);
36610 MInt noIntData = m_noLongData;
36611
36612 MUint sndSize = maia::mpi::getBufferSize(grid().azimuthalWindowCells());
36613 MFloatScratchSpace windowFData(sndSize * noFloatData, AT_, "windowFData");
36614 windowFData.fill(-1.0);
36615 ScratchSpace<MUlong> windowIData(sndSize * noIntData, AT_, "windowIData");
36616 windowFData.fill(0);
36617 MUint rcvSize = maia::mpi::getBufferSize(grid().azimuthalHaloCells());
36618 MFloatScratchSpace haloFData(rcvSize * noFloatData, AT_, "haloFData");
36619 haloFData.fill(-1.0);
36620 ScratchSpace<MUlong> haloIData(rcvSize * noIntData, AT_, "haloIData");
36621 haloIData.fill(0);
36622
36623 MInt sndCnt = 0;
36624 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36625 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
36626 MInt cellId = grid().azimuthalWindowCell(i, j);
36627 MLong gCellId = cellId;
36628 if(mode == 1) gCellId = c_globalId(cellId);
36629 if(m_azimuthalNearBoundaryBackup.count(gCellId) != 0) {
36630 MFloat recCoord[nDim];
36631 for(MInt d = 0; d < nDim; d++) {
36632 recCoord[d] = this->m_azimuthalCartRecCoord[sndCnt * nDim + d];
36633 }
36634 MFloat cellLength = c_cellLengthAtCell(cellId);
36635 MFloat tmp[nDim];
36636 auto range = m_azimuthalNearBoundaryBackup.equal_range(gCellId);
36637 for(auto it = range.first; it != range.second; ++it) {
36638 for(MInt d = 0; d < nDim; d++) {
36639 tmp[d] = (it->second).first[d];
36640 }
36641 MBool isEqual = true;
36642 for(MInt d = 0; d < nDim; d++) {
36643 if(!approx(tmp[d], recCoord[d], 0.01 * cellLength)) isEqual = false;
36644 }
36645 if(isEqual) {
36646 ASSERT((it->second).second[0] > 0 || mode == 1, "WRONG!");
36647 windowFData[sndCnt * noFloatData] = (it->second).first[nDim]; // cellVolume
36648 windowFData[sndCnt * noFloatData + 1] = (it->second).first[nDim + 1]; // cellVolumeDt1
36649 windowFData[sndCnt * noFloatData + 2] = (it->second).first[nDim + 2]; // sweptVolume
36650 if(mode == 1) {
36651 for(MInt v = 0; v < CV->noVariables; v++) {
36652 windowFData[sndCnt * noFloatData + 3 + v] = (it->second).first[nDim + 3 + v];
36653 }
36654 }
36655
36656 windowIData[sndCnt * noIntData] = (it->second).second[0]; // oldBndryCnt
36657 windowIData[sndCnt * noIntData + 1] = (it->second).second[1]; // cell properties
36658
36659 break;
36660 }
36661 }
36662 }
36663
36664 sndCnt++;
36665 }
36666 }
36667
36669
36670 // Exchange
36671 maia::mpi::exchangeBuffer(grid().azimuthalNeighborDomains(), grid().azimuthalHaloCells(),
36672 grid().azimuthalWindowCells(), mpiComm(), windowFData.getPointer(), haloFData.getPointer(),
36673 noFloatData);
36674 maia::mpi::exchangeBuffer(grid().azimuthalNeighborDomains(), grid().azimuthalHaloCells(),
36675 grid().azimuthalWindowCells(), mpiComm(), windowIData.getPointer(), haloIData.getPointer(),
36676 noIntData);
36677
36678 MInt rcvCnt = 0;
36679 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36680 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
36681 MInt cellId = grid().azimuthalHaloCell(i, j);
36682
36683 if(mode == 1) {
36684 maia::fv::cell::BitsetType props = (haloIData[rcvCnt * noIntData + 1]);
36685 a_hasProperty(cellId, SolverCell::WasInactive) = props[maia::fv::cell::p(SolverCell::WasInactive)];
36686 } else {
36687 if(a_levelSetValuesMb(cellId, 0) < F0) {
36688 a_hasProperty(cellId, SolverCell::WasInactive) = true;
36689 } else {
36690 a_hasProperty(cellId, SolverCell::WasInactive) = false;
36691 }
36692 }
36693 a_hasProperty(cellId, SolverCell::WasGapCell) = false;
36694 if(m_closeGaps) mTerm(1, AT_, "AzimuthalPer adaptation not working with gap closing!");
36695
36696 if(mode == 1) {
36697 for(MInt v = 0; v < CV->noVariables; v++) {
36698 a_variable(cellId, v) = haloFData[rcvCnt * noFloatData + 3 + v];
36699 a_oldVariable(cellId, v) = a_variable(cellId, v);
36700 }
36701 setPrimitiveVariables(cellId);
36702 }
36703 if(haloIData[rcvCnt * noIntData] > 0) {
36704 a_cellVolume(cellId) = haloFData[rcvCnt * noFloatData];
36705 m_cellVolumesDt1[cellId] = haloFData[rcvCnt * noFloatData + 1];
36706
36707 m_oldBndryCells.insert(make_pair(cellId, haloFData[rcvCnt * noFloatData + 2]));
36708
36709 maia::fv::cell::BitsetType props = (haloIData[rcvCnt * noIntData + 1]);
36710 a_hasProperty(cellId, SolverCell::IsMovingBnd) = props[maia::fv::cell::p(SolverCell::IsMovingBnd)];
36711 a_hasProperty(cellId, SolverCell::NearWall) = props[maia::fv::cell::p(SolverCell::NearWall)];
36712 a_hasProperty(cellId, SolverCell::IsInactive) = props[maia::fv::cell::p(SolverCell::IsInactive)];
36713 a_hasProperty(cellId, SolverCell::WasInactive) = a_hasProperty(cellId, SolverCell::WasInactive);
36714 a_hasProperty(cellId, SolverCell::WasGapCell) = props[maia::fv::cell::p(SolverCell::WasGapCell)];
36715 } else {
36716 a_cellVolume(cellId) = grid().gridCellVolume(a_level(cellId));
36717 m_cellVolumesDt1[cellId] = grid().gridCellVolume(a_level(cellId));
36718 }
36719
36720 if((a_level(cellId) >= m_lsCutCellMinLevel)
36723 vector<MFloat> tmp(max(m_noCVars + m_noFVars, 0) + 1);
36724 tmp[0] = m_cellVolumesDt1[cellId];
36725 for(MInt v = 0; v < m_noCVars; v++) {
36726 tmp[1 + v] = std::numeric_limits<MFloat>::lowest();
36727 }
36728 for(MInt v = 0; v < m_noFVars; v++) {
36729 tmp[1 + m_noCVars + v] = std::numeric_limits<MFloat>::lowest();
36730 }
36731 m_nearBoundaryBackup.insert(make_pair(cellId, tmp));
36732 }
36733
36734 rcvCnt++;
36735 }
36736 }
36737}
MBool approx(const T &, const U &, const T)
Definition: functions.h:272
MUint getBufferSize(const std::vector< std::vector< MInt > > &exchangeCells)
Generic exchange of data.
Definition: mpiexchange.h:681
void exchangeBuffer(const MInt noExDomains, const MInt *const exDomainId, const MInt *const recvSize, const MInt *const sendSize, const MPI_Comm comm, U *const receiveBuffer, const U *const sendBuffer, const MInt noDat=1)
Generic exchange of data.
Definition: mpiexchange.h:44

◆ compactSurfaces()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::compactSurfaces
Author
Lennart Schneiders

Definition at line 16472 of file fvmbcartesiansolverxd.cpp.

16472 {
16473 MInt delCnt = 0;
16474 MInt delCnt2 = 0;
16475 MInt lastSrfcId = a_noSurfaces() - 1;
16476
16477 if(a_noSurfaces() > 0) {
16478 for(set<MInt>::iterator it = m_freeSurfaceIndices.begin(); it != m_freeSurfaceIndices.end(); ++it) {
16479 MInt srfcId = *it;
16480 if((a_surfaceNghbrCellId(srfcId, 0) > -1) || (a_surfaceNghbrCellId(srfcId, 1) > -1)) {
16481 cerr << "Warning: not expected in compactSurfaces()" << endl;
16482 continue;
16483 }
16484 while((a_surfaceNghbrCellId(lastSrfcId, 0) < 0) || (a_surfaceNghbrCellId(lastSrfcId, 1) < 0)) {
16485 if(lastSrfcId < a_noSurfaces()) {
16486 m_surfaces.erase(lastSrfcId);
16487 m_surfaces.size(lastSrfcId);
16488 }
16489 lastSrfcId = a_noSurfaces() - 1;
16490 if(lastSrfcId == -1) break;
16491 }
16492 if(lastSrfcId == -1 || srfcId >= a_noSurfaces()) {
16493 break;
16494 } else {
16495 lastSrfcId = a_noSurfaces() - 1;
16496 moveSurface(srfcId, lastSrfcId);
16497 m_surfaces.erase(lastSrfcId);
16498 m_surfaces.size(lastSrfcId);
16499 delCnt2++;
16500 }
16501 delCnt++;
16502 }
16503 }
16504 m_freeSurfaceIndices.clear();
16506}
std::set< MInt > m_freeSurfaceIndices
void moveSurface(const MInt toSrfcId, const MInt fromSrfcId)
void erase(const MInt begin, const MInt end)
Erase nodes in range [begin, end) and update parent/child/neighbor information.
Definition: container.h:335
constexpr MInt size() const
Return size (i.e., currently used number of nodes)
Definition: container.h:89

◆ compFaceIntegrals()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::compFaceIntegrals ( polyCutCell cutCell,
std::vector< polyEdge2D > *  edges,
const std::vector< polyVertex > *  vertices,
MInt  A,
MInt  B 
)
private
Author

Definition at line 31570 of file fvmbcartesiansolverxd.cpp.

31571 {
31572 MFloat P[3];
31573
31574 compProjectionIntegrals(cutCell, edges, vertices, A, B, P);
31575
31576 MFloat area = P[0];
31577 if(area > 1e3 * m_eps) {
31578 cutCell->volume = area;
31579 cutCell->center[A] = P[1] / area;
31580 cutCell->center[B] = P[2] / area;
31581 } else if(area > F0) {
31582 cutCell->volume = area;
31583 P[1] = F0;
31584 P[2] = F0;
31585 for(MInt i = 0; (unsigned)i < (*cutCell).faces_edges.size(); i++) {
31586 MInt edge = (*cutCell).faces_edges[i];
31587 MInt vertex0 = (*edges)[edge].vertices[0];
31588 P[1] += (*vertices)[vertex0].coordinates[0];
31589 P[2] += (*vertices)[vertex0].coordinates[1];
31590 }
31591 P[1] /= (*cutCell).faces_edges.size();
31592 P[2] /= (*cutCell).faces_edges.size();
31593 cutCell->center[A] = P[1];
31594 cutCell->center[B] = P[2];
31595 } else {
31596 cutCell->volume = F0;
31597 P[1] = F0;
31598 P[2] = F0;
31599 for(MInt i = 0; (unsigned)i < (*cutCell).faces_edges.size(); i++) {
31600 MInt edge = (*cutCell).faces_edges[i];
31601 MInt vertex0 = (*edges)[edge].vertices[0];
31602 P[1] += (*vertices)[vertex0].coordinates[0];
31603 P[2] += (*vertices)[vertex0].coordinates[1];
31604 }
31605 P[1] /= (*cutCell).faces_edges.size();
31606 P[2] /= (*cutCell).faces_edges.size();
31607 cutCell->center[A] = P[1];
31608 cutCell->center[B] = P[2];
31609 }
31610}
void compProjectionIntegrals(polyCutCell *, std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt, MInt, MFloat *)
compute various integrations over projection of face

◆ compProjectionIntegrals()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::compProjectionIntegrals ( polyCutCell cutCell,
std::vector< polyEdge2D > *  edges,
const std::vector< polyVertex > *  vertices,
MInt  A,
MInt  B,
MFloat P 
)
private
Author

Definition at line 31526 of file fvmbcartesiansolverxd.cpp.

31528 {
31529 MFloat P1 = F0, Pa = F0, Pb = F0;
31530
31531 for(MInt i = 0; (unsigned)i < (*cutCell).faces_edges.size(); i++) {
31532 MInt edge = (*cutCell).faces_edges[i];
31533 MInt vertex0, vertex1;
31534 vertex0 = (*edges)[edge].vertices[0];
31535 vertex1 = (*edges)[edge].vertices[1];
31536 MFloat a0 = (*vertices)[vertex0].coordinates[A];
31537 MFloat b0 = (*vertices)[vertex0].coordinates[B];
31538 MFloat a1 = (*vertices)[vertex1].coordinates[A];
31539 MFloat b1 = (*vertices)[vertex1].coordinates[B];
31540 MFloat da = a1 - a0;
31541 MFloat db = b1 - b0;
31542 MFloat a0_2 = a0 * a0;
31543 MFloat b0_2 = b0 * b0;
31544
31545 MFloat C1 = a1 + a0;
31546 MFloat Ca = a1 * C1 + a0_2;
31547 MFloat Cb = b1 * (b1 + b0) + b0_2;
31548
31549 P1 += db * C1;
31550 Pa += db * Ca;
31551 Pb += da * Cb;
31552
31553 (*edges)[edge].center[A] = a0 + F1B2 * da;
31554 (*edges)[edge].center[B] = b0 + F1B2 * db;
31555 (*edges)[edge].area = sqrt(da * da + db * db);
31556 }
31557
31558 P[0] = P1 / 2.0;
31559 P[1] = Pa / 6.0;
31560 P[2] = Pb / -6.0;
31561}

◆ computeAzimuthalHaloNodalValues()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeAzimuthalHaloNodalValues
Author
Thomas Hoesgen

Definition at line 5838 of file fvmbcartesiansolverxd.cpp.

5838 {
5839 TRACE();
5840
5841 MBool gapClosure = false;
5842 if(m_levelSet && m_closeGaps && (m_gapInitMethod > 0 || nDim == 3)) {
5843 gapClosure = true;
5844 }
5845 if(gapClosure) ASSERT(false, "Are you sure? AzimuthalPer with gapClosing is untested!");
5846
5847 const MFloat limitDistance = F2 * c_cellLengthAtLevel(m_lsCutCellBaseLevel);
5848
5849 std::vector<MInt> azimuthalCandidateIds;
5850 std::vector<CutCandidate<nDim>> azimuthalCandidates;
5851 MInt noAzimuthalCandidates = 0;
5852
5853 azimuthalCandidateIds.assign(a_noCells(), -1);
5854 azimuthalCandidates.clear();
5855
5856 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5857 for(MUint j = 0; j < m_azimuthalMaxLevelHaloCells[i].size(); j++) {
5859 if(a_bndryId(cellId) < -1) continue;
5860 if(cellId >= a_noCells()) continue;
5861 if(fabs(a_levelSetValuesMb(cellId, 0)) < limitDistance && a_level(cellId) >= m_lsCutCellMinLevel) {
5862 azimuthalCandidates.emplace_back();
5863 azimuthalCandidates[noAzimuthalCandidates].cellId = cellId;
5864 azimuthalCandidateIds[cellId] = noAzimuthalCandidates;
5865 noAzimuthalCandidates++;
5866 } else {
5867 azimuthalCandidateIds[cellId] = -1;
5868 }
5869 }
5870 }
5871
5872 MBoolScratchSpace isGapCell(a_noCells(), AT_, "isGapCell");
5873 isGapCell.fill(false);
5874 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
5875 if(a_isGapCell(cellId)) isGapCell[cellId] = true;
5876 }
5877
5878 m_geometryIntersection->computeNodalValues(azimuthalCandidates, &azimuthalCandidateIds[0], &a_levelSetValuesMb(0, 0),
5879 &a_associatedBodyIds(0, 0), &isGapCell(0), gapClosure);
5880
5881 exchangeAzimuthalOuterNodalValues(azimuthalCandidates, azimuthalCandidateIds);
5882
5883 for(MUint i = 0; i < azimuthalCandidates.size(); i++) {
5884 // add halo-cutCandidate
5885 MInt cellId = azimuthalCandidates[i].cellId;
5886 const MInt candId = m_cutCandidates.size();
5887 m_cutCandidates.emplace_back();
5888 m_cutCandidates[candId].cellId = cellId;
5889
5890 // add infomation from computeNodalvalues:
5891 for(MInt node = 0; node < m_noCorners; node++) {
5892 m_cutCandidates[candId].nodeValueSet[node] = true;
5893 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
5894 m_cutCandidates[candId].nodalValues[set][node] = azimuthalCandidates[i].nodalValues[set][node];
5895 }
5896 }
5897 m_cutCandidates[candId].isGapCell = azimuthalCandidates[i].isGapCell;
5898
5899 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
5900 m_cutCandidates[candId].associatedBodyIds[set] = azimuthalCandidates[i].associatedBodyIds[set];
5901 }
5902
5903 m_bndryCandidateIds[cellId] = candId;
5904 }
5905}
static constexpr const MInt m_noCorners
std::vector< CutCandidate< nDim > > m_cutCandidates
void exchangeAzimuthalOuterNodalValues(std::vector< CutCandidate< nDim > > &candidates, std::vector< MInt > &candidateIds)
Exchange of nodal values of azimuthal periodic halo cells.
GeometryIntersection< nDim > * m_geometryIntersection
void computeNodalValues(std::vector< CutCandidate< nDim > > &candidates, MInt *candidateIds, const MFloat *scalarField, const MInt *bodyIdField, const MBool *const gapPropertyField, const MBool gapClosure)
1) add cutCandidates based on the solver m_bndryCandidates 2) set cutCandidate information 3) set the...

◆ computeAzimuthalReconstructionConstants()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeAzimuthalReconstructionConstants ( MInt  mode = 0)
overridevirtual
Author
Thomas Hoesgen

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 36411 of file fvmbcartesiansolverxd.cpp.

36411 {
36412 TRACE();
36413
36414 MFloat recCoord[nDim];
36415
36416 MInt offset = 0;
36417 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36418 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
36419 MInt cellId = grid().azimuthalWindowCell(i, j);
36420
36421 if(a_levelSetValuesMb(cellId, 0) < F0) {
36423 m_noAzimuthalReconstNghbrs[offset] = 1;
36425 offset++;
36426 continue;
36427 }
36428
36429 std::copy_n(&m_azimuthalCutRecCoord[offset * nDim], nDim, &recCoord[0]);
36430
36431 rebuildAzimuthalReconstructionConstants(cellId, offset, recCoord, mode);
36432
36433 offset++;
36434 }
36435 }
36436
36437 for(MUint i = 0; i < m_azimuthalRemappedNeighborDomains.size(); i++) {
36438 for(MUint j = 0; j < m_azimuthalRemappedWindowCells[i].size(); j++) {
36440
36441 if(a_levelSetValuesMb(cellId, 0) < F0) {
36443 m_noAzimuthalReconstNghbrs[offset] = 1;
36445 continue;
36446 }
36447
36448 std::copy_n(&m_azimuthalCutRecCoord[offset * nDim], nDim, &recCoord[0]);
36449
36450 rebuildAzimuthalReconstructionConstants(cellId, offset, recCoord, mode);
36451
36452 offset++;
36453 }
36454 }
36455}
std::vector< std::vector< MInt > > m_azimuthalRemappedWindowCells
std::vector< MInt > m_azimuthalRemappedNeighborDomains

◆ computeBodyMomentOfInertia()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeBodyMomentOfInertia
Author
Lennart Schneiders

Definition at line 8761 of file fvmbcartesiansolverxd.cpp.

8761 {
8762 TRACE();
8763
8764 ScratchSpace<MFloat> globalMI(3 * m_noEmbeddedBodies, AT_, "globalMI");
8765
8766 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
8767 for(MInt i = 0; i < 3; i++) {
8768 globalMI[3 * k + i] = F0;
8769 m_bodyMomentOfInertia[3 * k + i] = F0;
8770 }
8771
8772 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
8773 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
8774 if(a_associatedBodyIds(cellId, 0) != k) continue;
8775 if(a_isHalo(cellId)) continue;
8776 if(a_isBndryGhostCell(cellId)) continue;
8777 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
8778 MFloat dx[3] = {F0, F0, F0};
8779 MFloat normal[3] = {F0, F0, F0};
8780 MFloat fac[3] = {F0, F0, F0};
8781 for(MInt i = 0; i < nDim; i++) {
8782 dx[i] = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i] - m_bodyCenter[nDim * k + i];
8783 normal[i] = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
8784 }
8785 IF_CONSTEXPR(nDim == 3) {
8786 fac[0] = normal[1] * POW3(dx[1]) + normal[2] * POW3(dx[2]);
8787 fac[1] = normal[0] * POW3(dx[0]) + normal[2] * POW3(dx[2]);
8788 }
8789 fac[2] = normal[0] * POW3(dx[0]) + normal[1] * POW3(dx[1]);
8790 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
8791
8792 for(MInt i = 0; i < 3; i++) {
8793 m_bodyMomentOfInertia[3 * k + i] += area * fac[i];
8794 }
8795 }
8796
8797 for(MInt i = 0; i < 3; i++) {
8798 m_bodyMomentOfInertia[3 * k + i] *= F1B3 * m_bodyDensity[k];
8799 }
8800 }
8801 }
8802 MPI_Allreduce(m_bodyMomentOfInertia, globalMI.begin(), 3 * m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
8803 "m_bodyMomentOfInertia", "globalMI.begin()");
8804
8805 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
8806 for(MInt i = 0; i < 3; i++) {
8807 m_bodyMomentOfInertia[3 * k + i] = globalMI[3 * k + i];
8808 }
8809 }
8810}

◆ computeBodySurfaceData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeBodySurfaceData ( MFloat pressureForce = nullptr)
Author
Lennart Schneiders If the pointers are set, the routine gathers the dynamic Coefficients

Definition at line 12983 of file fvmbcartesiansolverxd.cpp.

12983 {
12984 TRACE();
12985
12986 NEW_TIMER_GROUP_STATIC(t_bodyTimer, "computeBodySurfaceData");
12987 NEW_TIMER_STATIC(t_timertotal, "computeBodySurfaceData", t_bodyTimer);
12988 NEW_SUB_TIMER_STATIC(t_local, "localForce", t_timertotal);
12989 NEW_SUB_TIMER_STATIC(t_reduce, "reduce", t_timertotal);
12990 NEW_SUB_TIMER_STATIC(t_collision, "collision", t_timertotal);
12991 RECORD_TIMER_START(t_timertotal);
12992 RECORD_TIMER_START(t_local);
12993
12994 // bodyForce:nDim, bodyTorque:3, bodyHeatFlux:1
12995 MBool returnCoeffs = false;
12996 MInt noValues = nDim + 3 + 1;
12997 MInt noReturnCoeffs = nDim;
12998
12999 if(pressureForce != nullptr) {
13000 returnCoeffs = true;
13001 noValues += noReturnCoeffs;
13002 }
13003
13004 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
13005 const MFloat F1BRe = F1 / (m_referenceLength * sysEqn().m_Re0);
13006 const MFloat F1BPr = F1 / (m_Pr);
13007
13008 MFloatScratchSpace bodyForce(mMax(1, m_noEmbeddedBodies), noValues, AT_, "bodyForce");
13009 bodyForce.fill(F0);
13010 MFloat coupling = F0;
13011
13012 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
13013 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
13014
13015 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
13016 if(a_isHalo(cellId)) continue;
13017 if(a_isPeriodic(cellId)) continue;
13018 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
13019 if(a_isBndryGhostCell(cellId)) continue;
13020 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
13021
13022 MFloatScratchSpace dummyPvariables(m_bndryCells->a[bndryId].m_noSrfcs, PV->noVariables, AT_, "dummyPvariables");
13023 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
13024 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area < 1e-14) continue;
13025 MInt k = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0];
13027 MInt body = m_internalBodyId[k];
13028 ASSERT(body > -1 && body < m_noEmbeddedBodies, "");
13029
13030 MFloat rhoSurface = F0;
13031 MFloat pSurface = F0;
13032 MInt surfVars = mMin((signed)m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size(),
13033 m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs);
13034
13035 for(MInt s = 0; s < surfVars; s++) {
13036 dummyPvariables(s, PV->P) = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[s]->m_primVars[PV->P];
13037 dummyPvariables(s, PV->RHO) = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[s]->m_primVars[PV->RHO];
13038 }
13039 for(MInt n = 0; n < (signed)m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size(); n++) {
13040 const MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
13041 const MFloat nghbrPvariableP = (n < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs)
13042 ? dummyPvariables(n, PV->P)
13043 : a_pvariable(nghbrId, PV->P);
13044 const MFloat nghbrPvariableRho = (n < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs)
13045 ? dummyPvariables(n, PV->RHO)
13046 : a_pvariable(nghbrId, PV->RHO);
13047 rhoSurface +=
13048 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariableRho;
13049 pSurface += m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariableP;
13050 }
13051
13052 MFloat normal0[3] = {F0, F0, F0};
13053 MFloat normal[3] = {F0, F0, F0};
13054 for(MInt i = 0; i < nDim; i++) {
13055 normal0[i] = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
13056 normal[i] = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVectorCentroid[i];
13057 }
13058
13059 MFloat dn = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
13060 MFloat T = sysEqn().temperature_ES(rhoSurface, pSurface);
13061 MFloat mue = SUTHERLANDLAW(T);
13062 MFloat dx[3] = {F0, F0, F0};
13063 MFloat df[3] = {F0, F0, F0};
13064 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
13065
13066 for(MInt i = 0; i < nDim; i++) {
13067 const MFloat dp0 = -pSurface * normal0[i] * area;
13068 const MFloat dp = -pSurface * normal[i] * area;
13069 MFloat grad = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[i]];
13070 for(MInt j = 0; j < nDim; j++)
13071 grad += F1B3 * normal[i] * normal[j]
13072 * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[j]];
13073 MFloat ds0 = F1BRe * mue * grad * area;
13074 // The following version was used for JFM2020 "Correlations based on highly resolved simulations".
13075 // TODO labels:FVMB Check the difference for 3D_ellipsoids_Couette for Re -> 0.
13076 // MFloat grad = m_fvBndryCnd->m_bndryCell[ bndryId].m_srfcVariables[srfc]->m_normalDeriv[ PV->VV[i] ];
13077 // for( MInt j = 0; j < nDim; j++ ) grad +=
13078 // F1B3*normal0[i]*normal0[j]*m_fvBndryCnd->m_bndryCell[ bndryId
13079 // ].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[j]
13080 // ]; df[i] = dp0 + ds0; dx[i] = a_coordinate( cellId , i ) - dn * normal0[ i ] - m_bodyCenter[nDim*k+i ];
13081 df[i] = dp + ds0;
13082 dx[i] = a_coordinate(cellId, i) - dn * normal[i] - m_bodyCenter[nDim * k + i];
13083 bodyForce(body, i) += dp0 + ds0;
13084 if(returnCoeffs == true) {
13085 bodyForce(body, nDim + 3 + 1 + i) += dp0;
13086 }
13087 coupling -= (dp0 + ds0) * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]];
13088
13089#if defined _MB_DEBUG_ || !defined NDEBUG
13090 if(std::isnan(dp0) || std::isnan(ds0)) {
13091 const MInt rootId =
13092 (a_hasProperty(cellId, SolverCell::IsSplitChild)) ? getAssociatedInternalCell(cellId) : cellId;
13093 cerr << domainId() << " local body force diverged " << globalTimeStep << " " << body << " " << i << " " << k
13094 << " / " << ds0 << " " << dp0 << " " << pSurface << " " << rhoSurface << " " << mue << " " << grad
13095 << " / " << area / m_gridCellArea[a_level(rootId)] << " " << normal0[i] << " " << normal[i] << " "
13096 << dn / c_cellLengthAtCell(rootId) << " / " << cellId << " " << c_globalId(rootId) << " "
13097 << a_level(rootId) << " " << a_hasProperty(cellId, SolverCell::IsSplitChild) << " "
13098 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs << endl;
13099 }
13100#endif
13101 }
13102#ifdef _MB_DEBUG_
13103 if(std::isnan(dx[1] * df[2] - dx[2] * df[1]) || std::isnan(dx[2] * df[0] - dx[0] * df[2])
13104 || std::isnan(dx[0] * df[1] - dx[1] * df[0]))
13105 cerr << domainId() << ": torque0 " << globalTimeStep << " " << c_globalId(cellId) << " " << bndryId << " "
13106 << srfc << " = " << pSurface << " " << rhoSurface << " / " << dx[0] << " " << dx[1] << " " << dx[2]
13107 << " / " << df[0] << " " << df[1] << " " << df[2] << " // " << area / m_gridCellArea[a_level(cellId)]
13108 << " " << pSurface << " " << mue << " "
13109 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[0]] << " "
13110 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[1]] << " "
13111 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[2]] << endl;
13112#endif
13113 IF_CONSTEXPR(nDim == 3) {
13114 bodyForce(body, nDim + 0) += dx[1] * df[2] - dx[2] * df[1];
13115 bodyForce(body, nDim + 1) += dx[2] * df[0] - dx[0] * df[2];
13116 }
13117 bodyForce(body, nDim + 2) += dx[0] * df[1] - dx[1] * df[0];
13118
13119 MFloat gradP = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->P];
13120 MFloat gradRho = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->RHO];
13121 MFloat gradT = m_gamma * (rhoSurface * gradP - pSurface * gradRho) / POW2(rhoSurface);
13122 const MFloat lambdaFluid = (T * sqrt(T) * m_sutherlandPlusOneThermal) / (T + m_sutherlandConstantThermal);
13123 MFloat heatFlux = gradT * area * F1BRe * F1BPr * lambdaFluid * m_gamma;
13124 bodyForce(body, nDim + 3) += heatFlux;
13125 }
13126 }
13127 RECORD_TIMER_STOP(t_local);
13128 RECORD_TIMER_START(t_reduce);
13129
13130 if(m_nonBlockingComm) {
13131#ifndef MAIA_MS_COMPILER
13132 MPI_Request redReq1 = MPI_REQUEST_NULL;
13133 MPI_Request redReq2 = MPI_REQUEST_NULL;
13134 MPI_Iallreduce(MPI_IN_PLACE, &bodyForce[0], bodyForce.size(), MPI_DOUBLE, MPI_SUM, mpiComm(), &redReq1, AT_,
13135 "MPI_IN_PLACE", "bodyForce[0]");
13136 MPI_Iallreduce(MPI_IN_PLACE, &coupling, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), &redReq2, AT_, "MPI_IN_PLACE",
13137 "coupling");
13138 MPI_Wait(&redReq1, MPI_STATUSES_IGNORE, AT_);
13139 MPI_Wait(&redReq2, MPI_STATUSES_IGNORE, AT_);
13140#else
13141 MPI_Allreduce(MPI_IN_PLACE, &bodyForce[0], bodyForce.size(), MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
13142 "bodyForce[0]");
13143 MPI_Allreduce(MPI_IN_PLACE, &coupling, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "coupling");
13144#endif
13145 } else {
13146 MPI_Allreduce(MPI_IN_PLACE, &bodyForce[0], bodyForce.size(), MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
13147 "bodyForce[0]");
13148 MPI_Allreduce(MPI_IN_PLACE, &coupling, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "coupling");
13149 }
13150 RECORD_TIMER_STOP(t_reduce);
13151
13152 // If a pressureForce is requested, it is assumed that the bodyForces are gathered for statistics. To avoid
13153 // additional updates of the bodyForces and torques between the time steps, the function is returned here.
13154 // Updates of the bodyForces and torques after the time step will change the solution.
13155 m_couplingRate = coupling;
13156 if(pressureForce != nullptr) {
13157 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
13158 for(MInt i = 0; i < nDim; i++) {
13159 pressureForce[k * nDim + i] = bodyForce(k, nDim + 3 + 1 + i);
13160 }
13161 }
13162 RECORD_TIMER_STOP(t_timertotal);
13163 return;
13164 }
13165 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
13166 for(MInt i = 0; i < nDim; i++) {
13167 m_bodyForce[k * nDim + i] = bodyForce(k, i);
13168 m_hydroForce[k * nDim + i] = bodyForce(k, i);
13169 }
13170 }
13171 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
13172 m_bodyHeatFlux[k] = bodyForce(k, nDim + 3);
13173 for(MInt i = 0; i < 3; i++) {
13174 m_bodyTorque[k * 3 + i] = bodyForce(k, nDim + i);
13175 }
13176 }
13177
13178 // collision model, Glowinski et al
13179 RECORD_TIMER_START(t_collision);
13180 IF_CONSTEXPR(nDim == 3) {
13183 const MFloat deltaMax = 1.5 * S + F2 * m_maxBodyRadius;
13184
13186 MIntScratchSpace nearBodies(m_noEmbeddedBodies, AT_, "nearBodies");
13187
13188 for(MInt p = 0; p < m_noEmbeddedBodies; p++) {
13189 m_bodyInCollision[p] = 0;
13190 }
13191
13192 for(MInt p = 0; p < m_noEmbeddedBodies; p++) {
13193 ASSERT(m_bodyTree != nullptr, "");
13194
13195 Point<nDim> pt(m_bodyCenter[p * nDim], m_bodyCenter[p * nDim + 1], m_bodyCenter[p * nDim + 2]);
13196 MInt noNearBodies = m_bodyTree->locatenear(pt, deltaMax, &nearBodies[0], m_noEmbeddedBodies);
13197
13198 for(MInt b = 0; b < noNearBodies; b++) {
13199 const MInt q = nearBodies[b];
13200 if(p == q) continue;
13201
13202 m_bodyInCollision[p] = 1;
13203
13204 const MFloat dp = F2 * mMax(m_bodyRadii[p * 3 + 0], mMax(m_bodyRadii[p * 3 + 1], m_bodyRadii[p * 3 + 2]));
13205 const MFloat dq = F2 * mMax(m_bodyRadii[q * 3 + 0], mMax(m_bodyRadii[q * 3 + 1], m_bodyRadii[q * 3 + 2]));
13206 const MFloat D = F1B2 * (dp + dq);
13207 const MFloat termv =
13209 const MFloat delta = sqrt(POW2(m_bodyCenter[p * nDim] - m_bodyCenter[q * nDim])
13210 + POW2(m_bodyCenter[p * nDim + 1] - m_bodyCenter[q * nDim + 1])
13211 + POW2(m_bodyCenter[p * nDim + 2] - m_bodyCenter[q * nDim + 2]));
13212 MFloat dist = delta - D;
13213
13214 if(dist > S) continue;
13215
13216 if(m_bodyTypeMb == 1) {
13217 if(dist < F0 && domainId() == 0) cerr << "Warning: potential overlap for bodies " << p << " " << q << endl;
13218 const MFloat eps = POW2(S / D);
13219 const MFloat C = CdLaw(m_Re * D) * F1B2 * m_rhoU2 * F1B4 * PI * POW2(D);
13221 const MFloat C0 = 8.0 * M * POW2(m_UInfinity + termv) / c_cellLengthAtLevel(maxRefinementLevel());
13222 if(dist < S) {
13223 m_bodyInCollision[p] = 2;
13224 }
13225 for(MInt i = 0; i < nDim; i++) {
13226 MFloat df = C0 * POW2(mMax(F0, -(dist - S) / S))
13227 * (m_bodyCenter[p * nDim + i] - m_bodyCenter[q * nDim + i]) / dist;
13228 m_bodyForce[p * nDim + i] += df;
13229 }
13230 if(domainId() == 0 && dist / c_cellLengthAtLevel(maxRefinementLevel()) < 1.5)
13231 cerr << globalTimeStep << " ---- repulsive force " << m_internalBodyId[q] << " -> " << p << ": "
13232 << C0 * POW2(mMax(F0, -(dist - S) / S)) << " / " << C * POW2(mMax(F0, -(dist - S) / S)) / eps << " ("
13233 << C0 / (C / eps) << ") dist=" << dist / c_cellLengthAtLevel(maxRefinementLevel()) << endl;
13234
13235 } else if(m_bodyTypeMb == 3) {
13237 const MFloat C0 = 16.0 * M * POW2(m_UInfinity + termv) / c_cellLengthAtLevel(maxRefinementLevel());
13238
13239 MFloat xcp[3];
13240 MFloat xcq[3];
13241 MFloat df[3];
13242 dist = distEllipsoidEllipsoid(p, q, xcp, xcq);
13243
13244 if(dist < S) {
13245 m_bodyInCollision[p] = 2;
13246 }
13247
13248 for(MInt i = 0; i < nDim; i++) {
13249 df[i] = C0 * POW2(mMax(F0, -(dist - S) / S)) * (xcp[i] - xcq[i]) / dist;
13250 m_bodyForce[p * nDim + i] += df[i];
13251 }
13252
13253 if(domainId() == 0 && dist / c_cellLengthAtLevel(maxRefinementLevel()) < 1.5)
13254 cerr << globalTimeStep << " ---- repulsive force " << m_internalBodyId[q] << " -> " << p << ": "
13255 << C0 * POW2(mMax(F0, -(dist - S) / S))
13256 << " dist=" << dist / c_cellLengthAtLevel(maxRefinementLevel()) << endl;
13257 }
13258 }
13259 }
13260
13261 if(m_saveSlipInterval > 0) {
13262 MInt noParticlesLocal = m_particleOffsets[domainId() + 1] - m_particleOffsets[domainId()];
13263 MInt noTimeStepsSaved = m_slipDataTimeSteps.size();
13264
13265 for(MInt p = 0; p < noParticlesLocal; p++) {
13266 m_slipDataParticleCollision[noParticlesLocal * noTimeStepsSaved + p] =
13268 }
13269 }
13270 }
13271 }
13272
13273#if defined _MB_DEBUG_ || !defined NDEBUG
13274 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
13275 for(MInt i = 0; i < nDim; i++) {
13276 if(std::isnan(m_bodyForce[k * nDim + i]) && domainId() == 0) {
13277 cerr << "force " << setprecision(15) << k << " " << i << " " << m_bodyForce[k * nDim + i] << endl;
13278 m_log << "force " << setprecision(15) << k << " " << i << " " << m_bodyForce[k * nDim + i];
13279 for(MInt j = 0; j < nDim; j++)
13280 m_log << " " << m_bodyCenter[nDim * k + j];
13281 for(MInt j = 0; j < 4; j++)
13282 m_log << " " << m_bodyQuaternion[4 * k + j];
13283 m_log << endl;
13284 }
13285 }
13286
13287 for(MInt i = 0; i < 3; i++) {
13288 if(std::isnan(m_bodyTorque[k * 3 + i]) && domainId() == 0) {
13289 cerr << "torque " << setprecision(15) << k << " " << i << " " << m_bodyTorque[k * 3 + i] << endl;
13290 m_log << "torque " << setprecision(15) << k << " " << i << " " << m_bodyTorque[k * 3 + i];
13291 for(MInt j = 0; j < nDim; j++)
13292 m_log << " " << m_bodyCenter[nDim * k + j];
13293 for(MInt j = 0; j < 4; j++)
13294 m_log << " " << m_bodyQuaternion[4 * k + j];
13295 m_log << endl;
13296 }
13297 }
13298 }
13299#endif
13300 RECORD_TIMER_STOP(t_collision);
13301 RECORD_TIMER_STOP(t_timertotal);
13302 DISPLAY_TIMER_OFFSET(t_timertotal, m_restartInterval);
13303}
std::vector< MFloat > m_slipDataTimeSteps
static MFloat CdLaw(MFloat Re)
std::vector< MInt > m_particleOffsets
MFloat distEllipsoidEllipsoid(const MInt k0, const MInt k1, MFloat *xc0, MFloat *xc1)
Compute the distance between two ellipsoids by iteratively searching the nearest point on the respect...
MInt m_restartInterval
The number of timesteps before writing the next restart file.
Definition: solver.h:79
MFloat m_Re
the Reynolds number
Definition: solver.h:68
int MPI_Wait(MPI_Request *request, MPI_Status *status, const MString &name)
same as MPI_Wait
int MPI_Iallreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Iallreduce
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
Definition: pointbox.h:54
MInt locatenear(Point< DIM > pt, MFloat r, MInt *list, MInt nmax, MBool returnCellId=true)
Definition: kdtree.h:320
Definition: pointbox.h:20

◆ computeBodyVolume()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeBodyVolume ( MFloatScratchSpace partVol)

Definition at line 23285 of file fvmbcartesiansolverxd.cpp.

23285 {
23286 TRACE();
23287 if(m_noEmbeddedBodies > 0) {
23288 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
23289 if(a_bndryId(cellId) < -1) continue;
23290 if(a_isHalo(cellId)) continue;
23291 if(a_isPeriodic(cellId)) continue;
23292 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && c_noChildren(cellId) > 0) continue;
23293
23294 if(a_levelSetValuesMb(cellId, 0) < F0 || a_bndryId(cellId) >= m_noOuterBndryCells) {
23295 if(m_associatedBodyIds[IDX_LSSETMB(cellId, 0)] < 0
23296 || m_associatedBodyIds[IDX_LSSETMB(cellId, 0)] > m_noEmbeddedBodies + m_noPeriodicGhostBodies) {
23297 cerr << domainId() << ": negative body id B " << m_associatedBodyIds[IDX_LSSETMB(cellId, 0)] << " "
23298 << a_hasProperty(cellId, SolverCell::IsSplitCell) << " "
23299 << a_hasProperty(cellId, SolverCell::IsSplitChild) << endl;
23300 continue;
23301 }
23302 MInt bodyId = m_internalBodyId[m_associatedBodyIds[IDX_LSSETMB(cellId, 0)]];
23303 MFloat svol = grid().gridCellVolume(a_level(cellId));
23304 if(a_bndryId(cellId) > -1) svol -= a_cellVolume(cellId);
23305 partVol(bodyId) += svol;
23306 if(a_bndryId(cellId) < 0 && a_hasProperty(cellId, SolverCell::IsInactive)) a_cellVolume(cellId) = F0;
23307 }
23308 }
23309 MPI_Allreduce(MPI_IN_PLACE, &partVol[0], m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23310 "partVol[0]");
23311 return;
23312 } else {
23313 cerr0 << "computeBodyVolume skipped since there are no Bodies." << endl;
23314 return;
23315 }
23316}

◆ computeBoundarySurfaceForces()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeBoundarySurfaceForces
Author

Definition at line 13778 of file fvmbcartesiansolverxd.cpp.

13778 {
13779 TRACE();
13780
13783}
void computeBodySurfaceData(MFloat *pressureForce=nullptr)
computes relevant variables at the moving boundary surface and determines the resulting body force
void applyBoundaryConditionMb()
applies the boundary condition at all boundaries

◆ computeCutPointsMb_MGC()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeCutPointsMb_MGC
Note
can handle complex geometries with sub-cell resolution, needs multi LVS method
Author
Claudia Guenther, Update Tim Wegmann
Date
30.07.2013

Definition at line 18273 of file fvmbcartesiansolverxd.cpp.

18273 {
18274 TRACE();
18275
18276 const MInt DOFStencil[12] = {1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 2, 2};
18277
18278 const MInt signStencil[3][12] = {{-1, 1, 0, 0, -1, 1, 0, 0, -1, 1, -1, 1},
18279 {0, 0, -1, 1, 0, 0, -1, 1, -1, -1, 1, 1},
18280 {-1, -1, -1, -1, 1, 1, 1, 1, 0, 0, 0, 0}};
18281
18282 const MBool redirect = true;
18283 if(redirect && !m_constructGField) {
18284 vector<MInt> candidatesOrder;
18285
18287
18288 // rescale cutPoints to cell-size:
18290 for(MInt cnd = 0; cnd < (signed)m_cutCandidates.size(); cnd++) {
18291 const MInt cellId = m_cutCandidates[cnd].cellId;
18292 const MFloat cellLength = c_cellLengthAtLevel(a_cutCellLevel(cellId));
18293 const MFloat cellHalfLength = F1B2 * cellLength;
18294
18295
18296 for(MInt cpId = 0; cpId < m_cutCandidates[cnd].noCutPoints; cpId++) {
18297 const MInt cutEdge = m_cutCandidates[cnd].cutEdges[cpId];
18298
18299 for(MInt i = 0; i < nDim; i++) {
18300 MFloat cutCoordinate = m_cutCandidates[cnd].cutPoints[cpId][i];
18301 const MInt sign = signStencil[i][cutEdge];
18302
18303 if(sign == 0) {
18304 cutCoordinate = a_coordinate(cellId, i) + cellHalfLength * m_cutCandidates[cnd].cutPoints[cpId][i];
18305 } else {
18306 cutCoordinate = a_coordinate(cellId, i) + signStencil[i][cutEdge] * cellHalfLength;
18307 }
18308 m_cutCandidates[cnd].cutPoints[cpId][i] = cutCoordinate;
18309 }
18310 }
18311 }
18312 }
18313
18314 // generate BndryCells based on the cutCandidates!
18315 // TODO labels:FVMB this should then be moved to the end of createCutFaceMb_MGC()
18316 // and instead the cutCells should be set!
18317
18318 // NOTE: bndryCell ordering appears to change the result for gapClosure!
18319 for(MInt i = 0; i < (signed)candidatesOrder.size(); i++) {
18320 const MInt cndt = candidatesOrder[i];
18321 const MInt cellId = m_cutCandidates[cndt].cellId;
18322 ASSERT(m_cutCandidates[cndt].noCutPoints > 0, "");
18323 MInt bndryId = -1;
18324 if(!a_isBndryCell(cellId)) {
18325 ASSERT(a_bndryId(cellId) == -1, to_string(a_bndryId(cellId)));
18326 bndryId = createBndryCellMb(cellId);
18327 } else {
18328 bndryId = a_bndryId(cellId);
18329 ASSERT(bndryId > -1, "");
18330 }
18331 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints = m_cutCandidates[cndt].noCutPoints;
18332
18333 for(MInt noCPs = 0; noCPs < m_cutCandidates[cndt].noCutPoints; noCPs++) {
18334 for(MInt dim = 0; dim < nDim; dim++) {
18335 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[noCPs][dim] =
18336 m_cutCandidates[cndt].cutPoints[noCPs][dim];
18337 }
18338 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[noCPs] = m_cutCandidates[cndt].cutBodyIds[noCPs];
18339 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[noCPs] = m_cutCandidates[cndt].cutEdges[noCPs];
18340 }
18341 }
18342
18343 return;
18344 }
18345
18346 const MInt edgesPerDim = IPOW2(nDim - 1);
18347
18348 const MInt faceStencil[2][12] = {{0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 0, 1}, {4, 4, 4, 4, 5, 5, 5, 5, 2, 2, 3, 3}};
18349
18350 // edege -> opposing edge
18351 // 1: oppsing edge on the same higher face count
18352 // 2: opposing edge on the same lower face count
18353 // 3: oppsong edge accros the cube
18354 // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
18355 const MInt reverseEdgeStencil[3][12] = {{1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10},
18356 {4, 5, 6, 7, 0, 1, 2, 3, 10, 11, 8, 9},
18357 {5, 4, 7, 6, 1, 0, 3, 2, 11, 10, 9, 8}};
18358
18359
18360 // edeg -> corner: returns the two corners for any edge
18361 // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11
18362 const MInt nodeStencil[2][12] = {{0, 1, 0, 2, 4, 5, 4, 6, 0, 1, 2, 3}, {2, 3, 1, 3, 6, 7, 5, 7, 4, 5, 6, 7}};
18363
18364
18365 const MBool multiCutCell = false;
18366 const MFloat eps = multiCutCell ? 10 * m_eps : m_eps;
18367 MInt errorFlag = 0;
18368
18369
18370 ASSERT(m_noBndryCandidates == (signed)m_bndryCandidates.size(), "");
18371 ScratchSpace<MBool> edgeChecked(m_noBndryCandidates * m_noEdges, AT_, "edgeChecked");
18372 edgeChecked.fill(false);
18373
18374 for(MInt i = 0; i < m_noBndryCandidates; i++) {
18375 for(MInt e = 0; e < m_noEdges; e++) {
18376 edgeChecked.p[i * m_noEdges + e] = false;
18377 }
18378 }
18379 MIntScratchSpace noCutPointsOnEdge(m_fvBndryCnd->m_maxNoBndryCells, m_noEdges, AT_, "noCutPointsOnEdge");
18380 noCutPointsOnEdge.fill(0);
18381
18382 for(MInt i = 0; i < m_fvBndryCnd->m_maxNoBndryCells; i++)
18383 for(MInt e = 0; e < m_noEdges; e++)
18384 noCutPointsOnEdge(i, e) = 0;
18385
18386
18387 // loop over candidates, determine cutpoints, store bndryCell properties
18388 for(MInt cndt = 0; cndt < m_noBndryCandidates; cndt++) {
18390
18391 const MFloat cellLength = c_cellLengthAtLevel(a_cutCellLevel(cellId));
18392 const MFloat cellHalfLength = F1B2 * cellLength;
18393
18394 MInt face[2];
18395 for(MInt edge = 0; edge < m_noEdges; edge++) {
18396 if(edgeChecked.p[cndt * m_noEdges + edge]) continue;
18397
18398 // first do some data structure related stuff
18399 face[0] = faceStencil[0][edge]; // in 2D: face == edge
18400 IF_CONSTEXPR(nDim == 3) {
18401 face[1] = faceStencil[1][edge]; // in 3D: each edge is connected to two faces
18402 }
18403 MInt edgeDOF = DOFStencil[edge]; // edge's degree of freedom
18404
18405 MInt directNeighbourIds[4]{-1, -1, -1, -1}; // direct neighbours of each edge -> requires that neighboring cells
18406 // are on same level!
18407 directNeighbourIds[0] = cellId;
18408 directNeighbourIds[1] = -1;
18409 if(a_hasNeighbor(cellId, face[0]) > 0) directNeighbourIds[1] = c_neighborId(cellId, face[0]);
18410
18411 MInt reverseEdge[4] = {0, 0, 0, 0};
18412 reverseEdge[0] = edge;
18413 reverseEdge[1] = reverseEdgeStencil[0][edge];
18414 IF_CONSTEXPR(nDim == 3) {
18415 directNeighbourIds[2] = -1;
18416 if(a_hasNeighbor(cellId, face[1]) > 0) {
18417 directNeighbourIds[2] = c_neighborId(cellId, face[1]);
18418 }
18419 directNeighbourIds[3] = -1;
18420 if(a_hasNeighbor(cellId, face[0]) > 0) {
18421 if(a_hasNeighbor(c_neighborId(cellId, face[0]), face[1]) > 0) {
18422 directNeighbourIds[3] = c_neighborId(c_neighborId(cellId, face[0]), face[1]);
18423 }
18424 }
18425 if(directNeighbourIds[3] < 0) {
18426 if(a_hasNeighbor(cellId, face[1]) > 0) {
18427 if(a_hasNeighbor(c_neighborId(cellId, face[1]), face[0]) > 0) {
18428 directNeighbourIds[3] = c_neighborId(c_neighborId(cellId, face[1]), face[0]);
18429 }
18430 }
18431 }
18432 reverseEdge[2] = reverseEdgeStencil[1][edge];
18433 reverseEdge[3] = reverseEdgeStencil[2][edge];
18434 }
18435
18436 // here, the real cut point computation begins
18437 MInt startSet = 0;
18438 MInt endSet = 1;
18439 MBool isGapCell = false;
18440 if(m_levelSet && m_closeGaps) {
18441 isGapCell = (a_hasProperty(cellId, SolverCell::IsGapCell));
18442 }
18443 if(m_complexBoundary && m_noLevelSetsUsedForMb > 1 && (!isGapCell)) {
18444 startSet = 1;
18445 endSet = m_noLevelSetsUsedForMb;
18446 } else if(m_complexBoundary && m_noLevelSetsUsedForMb > 1 && (isGapCell)) {
18447 startSet = 0;
18448 endSet = 1;
18449 }
18450
18451
18452 for(MInt set = startSet; set < endSet; set++) {
18453 MFloat phi[2]; // signed-distance value on both vertices defining an edge
18454 phi[0] = m_candidateNodeValues[IDX_LSSETNODES(cndt, nodeStencil[0][edge], set)];
18455 phi[1] = m_candidateNodeValues[IDX_LSSETNODES(cndt, nodeStencil[1][edge], set)];
18456 if(!m_candidateNodeSet[cndt * m_noCellNodes + nodeStencil[0][edge]])
18457 cerr << domainId() << ": warning node value 0 not set at " << globalTimeStep << ", " << cellId << " " << cndt
18458 << " " << edge << " " << nodeStencil[0][edge] << " " << set << " " << a_isHalo(cellId) << endl;
18459 if(!m_candidateNodeSet[cndt * m_noCellNodes + nodeStencil[1][edge]])
18460 cerr << domainId() << ": warning node value 1 not set at " << globalTimeStep << ", " << cellId << " " << cndt
18461 << " " << edge << " " << nodeStencil[1][edge] << " " << set << " " << a_isHalo(cellId) << endl;
18462
18463 // added by Claudia to prevent zero-volume cells
18464 if(fabs(phi[0]) < eps) {
18465 if(phi[0] < F0)
18466 phi[0] = -eps;
18467 else
18468 phi[0] = eps;
18469 }
18470 if(fabs(phi[1]) < eps) {
18471 if(phi[1] < F0)
18472 phi[1] = -eps;
18473 else
18474 phi[1] = eps;
18475 }
18476
18477 // limit the distance of a cutPoint to any corner:
18478 // together with the above, this ensure that the CP
18479 // is always 2 eps appart from the corner!
18480 // necessary for multiCutCell but not included in the trunk!
18481 if(multiCutCell) {
18482 if(approx(fabs(phi[0]), cellHalfLength, eps)) {
18483 if(phi[0] > F0)
18484 phi[0] = cellHalfLength - eps;
18485 else
18486 phi[0] = -cellHalfLength + eps;
18487 }
18488 if(approx(fabs(phi[1]), cellHalfLength, eps)) {
18489 if(phi[1] > F0)
18490 phi[1] = cellHalfLength - eps;
18491 else
18492 phi[1] = -cellHalfLength + eps;
18493 }
18494 }
18495
18496 // found a cutpoint if sign differs
18497 if(phi[0] * phi[1] < 0) {
18498 MFloat cutpoint[nDim];
18499 // determine cutpoint coordinates
18500 MFloat deltaCutpoint = cellHalfLength * (phi[0] + phi[1]) / (phi[0] - phi[1]);
18501 ASSERT((phi[0] + phi[1]) / (phi[0] - phi[1]) < 1 && (phi[0] + phi[1]) / (phi[0] - phi[1]) > -1, "");
18502 for(MInt dim = 0; dim < nDim; dim++) {
18503 if(dim == edgeDOF) continue;
18504 cutpoint[dim] = a_coordinate(cellId, dim) + signStencil[dim][edge] * cellHalfLength;
18505 }
18506 cutpoint[edgeDOF] = a_coordinate(cellId, edgeDOF) + deltaCutpoint;
18507
18508 // store this cutpoint at all direct neighbours
18509 for(MInt nb = 0; nb < edgesPerDim; nb++) {
18510 MInt nbCell = directNeighbourIds[nb];
18511 if(nbCell < 0) continue;
18512 if(m_bndryCandidateIds[nbCell] < 0) {
18513 continue;
18514 }
18515 // may occur in multi-domain computations
18516 if(edgeChecked.p[m_bndryCandidateIds[nbCell] * m_noEdges + reverseEdge[nb]]) {
18517 cerr << "Strange behaviour! " << endl;
18518 continue;
18519 }
18520 // if neighbour isn't already moving boundary cell create a new one
18521 MInt nbBndryCell = -1;
18522 if(!a_isBndryCell(nbCell)) {
18523 if(a_bndryId(nbCell) != -1) {
18524 cerr << domainId() << "Missing boundary cell: " << cellId << " " << nbCell << " " << a_level(cellId)
18525 << " " << a_level(nbCell) << " " << c_neighborId(cellId, face[0]) << " " << face[0] << " "
18526 << a_isHalo(cellId) << " " << a_isHalo(nbCell) << endl;
18527 }
18528 ASSERT(a_bndryId(nbCell) == -1, to_string(a_bndryId(nbCell)));
18529 nbBndryCell = createBndryCellMb(nbCell);
18530 } else {
18531 nbBndryCell = a_bndryId(nbCell);
18532 if(nbBndryCell < 0) {
18533 errorFlag = 1;
18534 cerr << "Critical error in at " << globalTimeStep << ". Quit.";
18535 }
18536 }
18537
18538 // store relevant information
18539 MInt noCPs = m_fvBndryCnd->m_bndryCells->a[nbBndryCell].m_srfcs[0]->m_noCutPoints;
18540 if(noCPs == 2 * m_noEdges) {
18541 mTerm(1, AT_, "Error: Too many cut points, can't store more... Please check!");
18542 }
18543 if(noCutPointsOnEdge(nbBndryCell, reverseEdge[nb]) == 2) {
18544 mTerm(1, AT_, "Error: Already two cut points on edge, can't store more... Please check!");
18545 }
18546
18547 ASSERT(a_associatedBodyIds(cellId, set) > -1
18549 "");
18550
18551 if(set >= m_startSet && a_associatedBodyIds(cellId, set) != a_associatedBodyIds(nbCell, set)) {
18552 cerr << domainId() << ": warning associated body mismatch! " << globalTimeStep << " " << set << " "
18553 << isGapCell << ", " << c_globalId(cellId) << " " << c_globalId(nbCell) << ", "
18554 << a_isPeriodic(cellId) << " " << a_isPeriodic(nbCell) << "/ " << a_associatedBodyIds(cellId, set)
18555 << " " << a_associatedBodyIds(nbCell, set) << ", " << a_associatedBodyIds(cellId, 0) << " "
18556 << a_associatedBodyIds(nbCell, 0) << "/ " << a_levelSetValuesMb(cellId, set) << " "
18557 << a_levelSetValuesMb(nbCell, set) << ", " << a_levelSetValuesMb(cellId, 0) << " "
18558 << a_levelSetValuesMb(nbCell, 0) << "/ " << a_hasProperty(cellId, Cell::IsHalo) << " "
18559 << a_hasProperty(nbCell, Cell::IsHalo) << ", " << a_hasProperty(cellId, SolverCell::IsGapCell) << " "
18560 << a_hasProperty(nbCell, SolverCell::IsGapCell) << endl;
18561 directNeighbourIds[nb] = -1;
18562 continue;
18563 }
18564
18565 for(MInt dim = 0; dim < nDim; dim++)
18566 m_fvBndryCnd->m_bndryCells->a[nbBndryCell].m_srfcs[0]->m_cutCoordinates[noCPs][dim] = cutpoint[dim];
18567
18568 m_fvBndryCnd->m_bndryCells->a[nbBndryCell].m_srfcs[0]->m_bodyId[noCPs] = a_associatedBodyIds(nbCell, set);
18569 m_fvBndryCnd->m_bndryCells->a[nbBndryCell].m_srfcs[0]->m_cutEdge[noCPs] = reverseEdge[nb];
18570 m_fvBndryCnd->m_bndryCells->a[nbBndryCell].m_srfcs[0]->m_noCutPoints++;
18571 noCutPointsOnEdge(nbBndryCell, reverseEdge[nb])++;
18572 } // for nb
18573 } // phi1*phi2<0
18574 } // for sets
18575
18576 // flag direct neighbours so that this edge is only checked once
18577 for(MInt nb = 0; nb < edgesPerDim; nb++) {
18578 if(directNeighbourIds[nb] < 0) continue;
18579 MInt nbCndt = m_bndryCandidateIds[directNeighbourIds[nb]];
18580 if(nbCndt < 0) continue;
18581 edgeChecked.p[nbCndt * m_noEdges + reverseEdge[nb]] = true;
18582 }
18583 } // for edge
18584 } // for cndt
18585
18586 /*
18587 // // debug: plot cut points:
18588 // const char* fileName = "AllCutPoints_";
18589 // stringstream fileName2;
18590 // fileName2 << fileName << domainId() << ".vtk";
18591 // ofstream ofl;
18592 // ofl.open((fileName2.str()).c_str(), ofstream::trunc );
18593 //
18594 // MInt noCutPoints = 0;
18595 // MInt noCells = m_bndryCells->size();
18596 //
18597 //
18598 //
18599 // // count the total number of cut points
18600 // for(MInt bndryId = 0; bndryId < noCells; bndryId++){
18601 // noCutPoints += m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints;
18602 // }
18603 //
18604 // if(ofl){
18605 //
18606 // ofl.setf(ios::fixed);
18607 // ofl.precision(7);
18608 //
18609 // ofl << "# vtk DataFile Version 3.0" << endl
18610 // << "MAIAD intersectionPoints file" << endl
18611 // << "ASCII" << endl
18612 // << "DATASET POLYDATA" << endl
18613 // << "POINTS " << noCutPoints << " float" << endl;
18614 //
18615 // // write each cut point in the data file
18616 // for(MInt bndryId = 0; bndryId < noCells; bndryId++){
18617 // if(m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints > 0){
18618 // for(MInt n = 0; n < m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints; n++){
18619 // for(MInt i = 0; i < nDim; i++){
18620 // ofl << m_bndryCells->a[ bndryId ].m_srfcs[0]->m_cutCoordinates[ n ][ i ] << " ";
18621 // }
18622 // IF_CONSTEXPR(nDim == 2)
18623 // ofl << F0 << " ";
18624 // ofl << endl;
18625 // }
18626 // }
18627 // }
18628 //
18629 // ofl << "VERTICES " << noCutPoints << " " << noCutPoints * 2 << endl;
18630 // for(MInt i = 0; i < noCutPoints; i++){
18631 // ofl << "1 " << i << endl;
18632 // }
18633 //
18634 // ofl << "POINT_DATA " << noCutPoints << endl;
18635 // ofl << "SCALARS bodyId int" << endl;
18636 // ofl << "LOOKUP_TABLE default" << endl;
18637 // for(MInt bndryId = 0; bndryId < noCells; bndryId++){
18638 // if(m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints > 0){
18639 // for(MInt n = 0; n < m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints; n++){
18640 // ofl << m_bndryCells->a[ bndryId ].m_srfcs[0]->m_bodyId[ n ] << " ";
18641 // }
18642 // }
18643 // }
18644 // ofl << endl;
18645 // }
18646 //
18647 // ofl.close();
18648 */
18649
18650#ifdef _MB_DEBUG_
18651 MPI_Allreduce(MPI_IN_PLACE, &errorFlag, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "errorFlag");
18652#endif
18653 if(errorFlag) {
18654 writeVtkDebug("error" + getIdentifier(false, "_", "_"));
18655 mTerm(1, AT_, "Critical error in computeCutPointsMb_MGC! Quit.");
18656 }
18657}
static constexpr const MInt m_noEdges
void writeVtkDebug(const MString suffix)
MInt createBndryCellMb(MInt cellId)
creates a moving boundary cell for the given cell
void computeCutPoints(std::vector< CutCandidate< nDim > > &candidates, const MInt *candidateIds, std::vector< MInt > &candidatesOrder)
Computes cutpoints for the scalar-Field with grid edges and updates cutPoint-Info in the cutCandidate...
MString getIdentifier(const MBool useSolverId=false, const MString preString="", const MString postString="_")
Definition: solver.cpp:188

◆ computeFlowStatistics()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeFlowStatistics ( MBool  force)
Author
Lennart Schneiders

Definition at line 21526 of file fvmbcartesiansolverxd.cpp.

21526 {
21527 TRACE();
21528 NEW_TIMER_GROUP(t_statistics, "statistics");
21529 NEW_TIMER(t_timertotal, "statistics", t_statistics);
21530 NEW_SUB_TIMER(t_slip, "slip", t_timertotal);
21531 NEW_SUB_TIMER(t_states, "states", t_timertotal);
21532 NEW_SUB_TIMER(t_odf, "odf", t_timertotal);
21533 NEW_SUB_TIMER(t_pdf, "pdf", t_timertotal);
21534 NEW_SUB_TIMER(t_near, "near", t_timertotal);
21535 NEW_SUB_TIMER(t_near_bodydat, "near_bodydat", t_near);
21536 NEW_SUB_TIMER(t_near_bodydat2, "near_bodydat2", t_near);
21537 NEW_SUB_TIMER(t_near_output, "near_output", t_near);
21538 NEW_SUB_TIMER(t_fft, "fft", t_timertotal);
21539
21540 TERMM_IF_COND(m_reConstSVDWeightMode == 3 || m_reConstSVDWeightMode == 4, "Not yet implemented!");
21541
21542 // short-cut for property input with defaultValue
21543 auto getIntProp = [&](const char* name, const MInt defaultValue) {
21544 return (Context::propertyExists(name, 0)) ? Context::getSolverProperty<MInt>(name, m_solverId, AT_) : defaultValue;
21545 };
21546
21547 // regular output intervals with default values
21548 const MInt statsInterval = getIntProp("statsInterval", m_dragOutputInterval);
21549 const MInt pdfInterval = getIntProp("pdfInterval", 0);
21550 const MInt angleInterval = getIntProp("angleInterval", 0);
21551 const MInt nearBodyInterval = getIntProp("nearBodyInterval", 0);
21552 const MInt scatterInterval = getIntProp("scatterInterval", 0);
21553 const MInt fftInterval = getIntProp("fftInterval", 0);
21554
21555 // check which statistics have to be computed at the current time step
21556 MBool computeStats = (statsInterval > 0 && globalTimeStep % statsInterval == 0);
21557 MBool computeSlipStats = (m_slipInterval > 0 && globalTimeStep % m_slipInterval == 0);
21558 MBool outputSlipStats = (m_saveSlipInterval > 0 && globalTimeStep % m_saveSlipInterval == 0);
21559 MBool computePdf = (pdfInterval > 0 && globalTimeStep % pdfInterval == 0);
21560 MBool computeAngles = (angleInterval > 0 && globalTimeStep % angleInterval == 0);
21561 MBool computeNearBody = (nearBodyInterval > 0 && globalTimeStep % nearBodyInterval == 0);
21562 MBool computeScatter = (scatterInterval > 0 && globalTimeStep % scatterInterval == 0);
21563 MBool computeFFT = (fftInterval > 0 && globalTimeStep % fftInterval == 0);
21564
21565 // manual output time steps, overrides regular output intervals
21566 MBool forceOutput = false;
21567 if(m_forceFVMBStatistics.size() == 0 && Context::propertyExists("forceFVMBStatistics", 0)) {
21568 const MInt cnt = Context::propertyLength("forceFVMBStatistics", m_solverId);
21569 for(MInt k = 0; k < cnt; k++) {
21570 MInt ts = Context::getSolverProperty<MInt>("forceFVMBStatistics", m_solverId, AT_, k);
21571 m_forceFVMBStatistics.push_back(ts);
21572 }
21573 }
21574 for(MUint i = 0; i < m_forceFVMBStatistics.size(); i++) {
21575 if(globalTimeStep == m_forceFVMBStatistics[i]) forceOutput = true;
21576 }
21577
21578 if(forceOutput == true) {
21579 computeStats = (statsInterval > 0);
21580 computeSlipStats = (m_slipInterval > 0);
21581 outputSlipStats = (m_saveSlipInterval > 0);
21582 computePdf = (pdfInterval > 0);
21583 computeAngles = (angleInterval > 0);
21584 computeNearBody = (nearBodyInterval > 0);
21585 computeScatter = (scatterInterval > 0);
21586 computeFFT = (fftInterval > 0);
21587 }
21588
21589 // computeStats is required for further statistics
21590 if(computePdf || computeSlipStats || computeAngles || computeNearBody || computeScatter || computeFFT || force)
21591 computeStats = true;
21592
21593 if(!computeStats) return;
21594
21595 if(domainId() == 0) {
21596 cerr << globalTimeStep << " " << m_restartTimeStep << " "
21597 << "computeStats " << computeStats << " "
21598 << "computeSlipStats " << computeSlipStats << " "
21599 << "outputSlipStats " << outputSlipStats << " "
21600 << "computePdf " << computePdf << " "
21601 << "computeAngles " << computeAngles << " "
21602 << "computeNearBody " << computeNearBody << " "
21603 << "computeScatter " << computeScatter << " "
21604 << "computeFFT " << computeFFT << endl;
21605 }
21606
21607 RECORD_TIMER_START(t_timertotal);
21608 leastSquaresReconstruction(); // update the slopes
21609 RECORD_TIMER_START(t_slip); // t_slip contains all calls of computeNearBodyFluidVelocity()
21610 MInt noParticles = 0;
21611 if(m_noPointParticles > 0)
21612 noParticles = m_noPointParticlesLocal;
21613 else if(m_noEmbeddedBodies > 0)
21614 noParticles = m_noEmbeddedBodies;
21615 const MBool computeBodyVol = true;
21616 MFloatScratchSpace partVol(mMax(1, noParticles), AT_, "partVol");
21617 // Unified data access for Lagrangian point-particles / and embedded Bodies
21618 MFloat* vel = nullptr;
21619 MFloat* velGradient = nullptr;
21620 MFloat* quats = nullptr;
21621 MFloat* pvel = nullptr;
21622 MFloat* pvelDt1 = nullptr;
21623 MFloat* protVelHat = nullptr;
21624 MFloat* protVelHatDt1 = nullptr;
21625 MFloat* nearBodyState = nullptr;
21626 MFloat* pRadii = nullptr;
21627 MFloat* pTemperature = nullptr;
21628 const MInt noNearBodyState = 5;
21629 // memory nearBodyData
21630 MFloatScratchSpace velMem(mMax(1, m_noEmbeddedBodies) * nDim, AT_, "velMem");
21631 MFloatScratchSpace velGradMem(mMax(1, m_noEmbeddedBodies) * nDim * nDim, AT_, "velGradMem");
21632 MFloatScratchSpace pOmegaHat(mMax(1, noParticles) * nDim, AT_, "pOmegaHat");
21633 MFloatScratchSpace protVelHatMem(mMax(1, noParticles) * nDim, AT_, "protVelHatMem");
21634 MFloatScratchSpace protVelHatMemDt1(mMax(1, noParticles) * nDim, AT_, "protVelHatMemDt1");
21635 MFloatScratchSpace velShearHat(mMax(1, noParticles) * nDim, AT_, "velShearHat");
21636 MFloatScratchSpace particleFluidRotation(mMax(1, m_noEmbeddedBodies), nDim, AT_, "particleFluidRotation");
21637 MFloatScratchSpace nbStateMem(mMax(1, m_noEmbeddedBodies) * noNearBodyState, AT_, "nbStateMem");
21638 MFloatScratchSpace particleFluidPressure(mMax(1, noParticles), AT_, "particleFluidPressure");
21639 MIntScratchSpace nearestBodies((m_noPointParticles > 0 ? 1 : m_maxNearestBodies * a_noCells()), AT_, "nearestBodies");
21640 MFloatScratchSpace nearestDist((m_noPointParticles > 0 ? 1 : m_maxNearestBodies * a_noCells()), AT_, "nearestDist");
21641 MFloatScratchSpace nearestFac((m_noPointParticles > 0 ? 1 : m_maxNearestBodies * a_noCells()), AT_, "nearestFac");
21642 const MFloat maxDistConstruct = (m_noEmbeddedBodies <= 0 ? -1 : 5.0 * m_bodyDiameter[0]);
21643 MIntScratchSpace skipParticle(mMax(1, noParticles), AT_, "skipParticle");
21644 skipParticle.fill(0);
21645 if(m_noPointParticles > 0) {
21646 setParticleFluidVelocities(&(particleFluidPressure[0]));
21647 vel = &(m_particleVelocityFluid[0]);
21648 velGradient = &(m_particleVelocityGradientFluid[0]);
21649 quats = &(m_particleQuaternions[0]);
21650 pvel = &(m_particleVelocity[0]);
21651 pvelDt1 = &(m_particleVelocityDt1[0]);
21652 protVelHat = &(m_particleAngularVelocity[0]);
21653 protVelHatDt1 = &(m_particleAngularVelocityDt1[0]);
21654 pRadii = &(m_particleRadii[0]);
21655 pTemperature = &(m_particleTemperature[0]);
21656 } else if(m_noEmbeddedBodies > 0) {
21657 MInt maxBodyCnt = 0;
21658 nearestBodies.fill(-1);
21659 nearestDist.fill(numeric_limits<MFloat>::max());
21660 maxBodyCnt = constructDistance(maxDistConstruct, nearestBodies, nearestDist);
21661 if(maxBodyCnt > m_maxNearestBodies) {
21662 cerr << "constructDistance: maxBodyCnt " << maxBodyCnt << " exceeds m_maxNearestBodies " << m_maxNearestBodies
21663 << " computeNearBodyFluidVelocity will be affected in the statistics on domainId " << domainId() << endl;
21664 }
21665 const MFloat minDist = 2.0;
21666 const MFloat maxDist = minDist + 1.0;
21667 constexpr MFloat maxAngleVel = 0.0;
21668 constexpr MFloat maxAngleRot = 0.0;
21669 vector<MFloat> setup = {minDist, maxDist, maxAngleVel, maxAngleRot};
21670 if(computePdf || computeNearBody) {
21671 computeNearBodyFluidVelocity(nearestBodies, nearestDist, &velMem[0], &velGradMem[0], &particleFluidRotation[0],
21672 setup, &skipParticle[0], &nbStateMem[0], &particleFluidPressure[0], &nearestFac[0]);
21673 } else {
21674 computeNearBodyFluidVelocity(nearestBodies, nearestDist, &velMem[0], &velGradMem[0], &particleFluidRotation[0],
21675 setup, &skipParticle[0]);
21676 }
21677 quats = &(m_bodyQuaternion[0]);
21678 pvel = &(m_bodyVelocity[0]);
21679 pvelDt1 = &(m_bodyVelocityDt1[0]);
21680 protVelHat = &(protVelHatMem[0]);
21681 protVelHatDt1 = &(protVelHatMemDt1[0]);
21682 vel = &velMem[0];
21683 velGradient = &velGradMem[0];
21684 // fluid rotation is evaluated using velGradient, particleFluidRotation would be an alternative
21685 nearBodyState = &nbStateMem[0];
21686 pRadii = &(m_bodyRadii[0]);
21687 pTemperature = &(m_bodyTemperature[0]);
21688 }
21689 // Transform values for rotational dynamics from inertial frame into body frame of reference for fully-resolved
21690 // particles
21691 if(m_noEmbeddedBodies > 0) {
21692 for(MInt p = 0; p < noParticles; p++) {
21693 MFloat qiRotvel[3];
21694 MFloat qiRotvelDt1[3];
21695 MFloat qiRotFluid[3];
21696 MFloat qiShear[3];
21697 MFloat qbRotvel[3];
21698 MFloat qbRotvelDt1[3];
21699 MFloat qbRot[3];
21700 MFloat qbShear[3];
21701 for(MInt i = 0; i < nDim; i++) {
21702 MInt id0 = (i + 1) % 3;
21703 MInt id1 = (id0 + 1) % 3;
21704 qiRotFluid[i] = F1B2 * (velGradient[9 * p + 3 * id1 + id0] - velGradient[9 * p + 3 * id0 + id1]);
21705 qiShear[i] = F1B2 * (velGradient[9 * p + 3 * id1 + id0] + velGradient[9 * p + 3 * id0 + id1]);
21706 qiRotvel[i] = m_bodyAngularVelocity[3 * p + i];
21707 qiRotvelDt1[i] = m_bodyAngularVelocityDt1[3 * p + i];
21708 }
21709 MFloatScratchSpace R(3, 3, AT_, "R");
21710 computeRotationMatrix(R, &(quats[4 * p]));
21711 matrixVectorProduct(qbRot, R, qiRotFluid);
21712 matrixVectorProduct(qbShear, R, qiShear);
21713 matrixVectorProduct(qbRotvel, R, qiRotvel);
21714 matrixVectorProduct(qbRotvelDt1, R, qiRotvelDt1);
21715 for(MInt i = 0; i < nDim; i++) {
21716 pOmegaHat[p * nDim + i] = qbRot[i];
21717 velShearHat[p * nDim + i] = qbShear[i];
21718 protVelHat[p * nDim + i] = qbRotvel[i];
21719 protVelHatDt1[p * nDim + i] = qbRotvelDt1[i];
21720 }
21721 }
21722 } else {
21723 for(MInt p = 0; p < noParticles; p++) {
21724 for(MInt i = 0; i < nDim; i++) {
21725 MInt id0 = (i + 1) % 3;
21726 MInt id1 = (id0 + 1) % 3;
21727 pOmegaHat[p * nDim + i] = F1B2 * (velGradient[9 * p + 3 * id1 + id0] - velGradient[9 * p + 3 * id0 + id1]);
21728 velShearHat[p * nDim + i] = F1B2 * (velGradient[9 * p + 3 * id1 + id0] + velGradient[9 * p + 3 * id0 + id1]);
21729 }
21730 }
21731 }
21732 // Compute time-resolved particle-induced dissipation
21733 if(computeSlipStats) computeSlipStatistics(nearestBodies, nearestDist, maxDistConstruct);
21734 if(outputSlipStats) saveParticleSlipData();
21735 RECORD_TIMER_STOP(t_slip);
21736
21737 const MFloat DX = (m_bbox[3] - m_bbox[0]);
21738 partVol.fill(F0);
21739 if(m_noEmbeddedBodies > 0) {
21740 if(computeBodyVol) {
21741 computeBodyVolume(partVol);
21742 } else {
21743 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
21744 partVol[b] = m_bodyVolume[b];
21745 }
21746 }
21747 } else {
21748 for(MInt p = 0; p < m_noPointParticlesLocal; p++) {
21749 partVol[p] = F4B3 * PI * m_particleRadii[3 * p] * m_particleRadii[3 * p + 1] * m_particleRadii[3 * p + 2];
21750 }
21751 }
21752 MIntScratchSpace leafCells(a_noCells(), AT_, "leafCells");
21753 MInt noLeafCells = 0;
21754 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
21755 if(a_isBndryGhostCell(cellId)) continue;
21756 if(a_isHalo(cellId)) continue;
21757 if(a_isPeriodic(cellId)) continue;
21758 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21759 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
21760 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && c_noChildren(cellId) > 0) continue;
21761 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21762 if(a_bndryId(cellId) < 0 && a_levelSetValuesMb(cellId, 0) < F0) cerr << "warn: neg LS " << endl;
21763 leafCells(noLeafCells++) = cellId;
21764 }
21765 RECORD_TIMER_START(t_states);
21766 vector<MFloat> eKinFlowDataMean(17, F0);
21767 MFloatScratchSpace meanState(4, AT_, "meanState");
21768 for(MInt stat = 0; stat < m_noMeanStatistics; stat++) {
21769 const MFloat refRadius = (noParticles > 0 ? pow(pRadii[0] * pRadii[1] * pRadii[2], F1B3) : 0);
21770 // gather fluid statistics
21771 for(MInt c = 0; c < noLeafCells; c++) {
21772 MInt cellId = leafCells(c);
21773 MFloat volume = a_cellVolume(cellId);
21774 if(volume < 1e-14) continue;
21775 if(stat > 0 && a_levelSetValuesMb(cellId, 0) < m_distThresholdStat[stat] * refRadius) continue;
21776 MFloat U2 = F0;
21777 MFloat U20 = F0;
21778 MFloat w2 = F0;
21779 MFloat s2 = F0;
21780 for(MInt i = 0; i < nDim; i++) {
21781 U2 += POW2(a_variable(cellId, CV->RHO_VV[i]) / a_variable(cellId, CV->RHO));
21782 U20 += POW2(a_oldVariable(cellId, CV->RHO_VV[i]) / a_oldVariable(cellId, CV->RHO));
21783 w2 += POW2(a_slope(cellId, PV->VV[(i + 1) % nDim], (i + 2) % nDim)
21784 - a_slope(cellId, PV->VV[(i + 2) % nDim], (i + 1) % nDim));
21785 s2 += POW2(a_slope(cellId, PV->VV[(i + 1) % nDim], (i + 2) % nDim)
21786 + a_slope(cellId, PV->VV[(i + 2) % nDim], (i + 1) % nDim));
21787 }
21788 MFloat T = sysEqn().temperature_ES(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
21789 MFloat mue = SUTHERLANDLAW(T) / sysEqn().m_Re0;
21790
21791 MFloat div = F0;
21792 for(MInt i = 0; i < nDim; i++) {
21793 div += a_slope(cellId, PV->VV[i], i);
21794 }
21795 eKinFlowDataMean[0] += F1B2 * volume * U2;
21796 eKinFlowDataMean[1] += F1B2 * volume * a_variable(cellId, CV->RHO) * U2;
21797 eKinFlowDataMean[2] += F1B2 * m_cellVolumesDt1[cellId] * U20;
21798 eKinFlowDataMean[3] += F1B2 * m_cellVolumesDt1[cellId] * a_oldVariable(cellId, CV->RHO) * U20;
21799 eKinFlowDataMean[4] += volume * fabs(div);
21800 eKinFlowDataMean[5] += volume * w2;
21801 for(MInt i = 0; i < nDim; i++) {
21802 for(MInt j = 0; j < nDim; j++) {
21803 eKinFlowDataMean[6] += volume * mue * (a_slope(cellId, PV->VV[i], j) + a_slope(cellId, PV->VV[j], i))
21804 * a_slope(cellId, PV->VV[i], j);
21805 eKinFlowDataMean[7] +=
21806 volume * F1B2 * mue * POW2(a_slope(cellId, PV->VV[i], j) + a_slope(cellId, PV->VV[j], i));
21807 eKinFlowDataMean[8] += volume * mue * a_slope(cellId, PV->VV[i], j) * a_slope(cellId, PV->VV[i], j);
21808 }
21809 eKinFlowDataMean[9] += volume * POW2(a_slope(cellId, PV->VV[i], i));
21810 eKinFlowDataMean[10] += volume * POW3(a_slope(cellId, PV->VV[i], i));
21811 }
21812 eKinFlowDataMean[11] += volume * mue;
21813 eKinFlowDataMean[12] += volume * a_variable(cellId, CV->RHO);
21814 eKinFlowDataMean[13] += T * volume;
21815 eKinFlowDataMean[14] += volume;
21816 eKinFlowDataMean[15] += volume * POW2(div);
21817 eKinFlowDataMean[16] += volume * POW2(a_variable(cellId, CV->RHO));
21818 }
21819 MPI_Allreduce(MPI_IN_PLACE, eKinFlowDataMean.data(), eKinFlowDataMean.size(), MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
21820 "MPI_IN_PLACE", "eKinFlowDataMean[0]");
21821
21822 // gather solid statistics
21823 vector<MFloat> eKinPartDataMean(25, F0);
21824 for(MInt p = 0; p < noParticles; p++) {
21825 eKinPartDataMean[0] += F1;
21826 eKinPartDataMean[1] += partVol[p];
21827 eKinPartDataMean[2] += pvel[p * nDim];
21828 eKinPartDataMean[3] += pvel[p * nDim + 1];
21829 eKinPartDataMean[4] += pvel[p * nDim + 2];
21830 eKinPartDataMean[5] += POW2(pvel[p * nDim]);
21831 eKinPartDataMean[6] += POW2(pvel[p * nDim + 1]);
21832 eKinPartDataMean[7] += POW2(pvel[p * nDim + 2]);
21833 eKinPartDataMean[8] += protVelHat[p * nDim + 0];
21834 eKinPartDataMean[9] += protVelHat[p * nDim + 1];
21835 eKinPartDataMean[10] += protVelHat[p * nDim + 2];
21836 eKinPartDataMean[11] += POW2(protVelHat[p * nDim + 0]);
21837 eKinPartDataMean[12] += POW2(protVelHat[p * nDim + 1]);
21838 eKinPartDataMean[13] += POW2(protVelHat[p * nDim + 2]);
21839 MFloatScratchSpace R(3, 3, AT_, "R");
21840 computeRotationMatrix(R, &(quats[4 * p]));
21841 // assuming zHat as major axis of ellipsoid which is fixed for point-particles and variable for fully resolved
21842 // fv_mb_cleanup
21843 MFloat tmp[3] = {F1, F0, F0};
21844 MFloat zHat[3];
21845 matrixVectorProductTranspose(zHat, R, tmp); // orientation of z-principal axis
21846 for(MInt i = 0; i < nDim; i++) {
21847 zHat[i] /= mMax(1e-12, sqrt(zHat[0] * zHat[0] + zHat[1] * zHat[1] + zHat[2] * zHat[2]));
21848 }
21849 eKinPartDataMean[14] += fabs(zHat[2]); // assuming z-axis is direction of anisotropy, e.g. direction of gravity
21850 MFloat diameter = F2 * pow(pRadii[3 * p] * pRadii[3 * p + 1] * pRadii[3 * p + 2], F1B3);
21851 MFloat Rep = F0;
21852 for(MInt i = 0; i < nDim; i++) {
21853 Rep += POW2(vel[3 * p + i] - pvel[3 * p + i]);
21854 }
21855 Rep = sqrt(Rep) * diameter * m_rhoInfinity * sysEqn().m_Re0 / sysEqn().m_muInfinity; // isothermal
21856 eKinPartDataMean[15] += Rep;
21857 eKinPartDataMean[16] += POW2(Rep);
21858 MFloat pmass = partVol[p] * m_densityRatio * m_rhoInfinity;
21859 eKinPartDataMean[17] += pmass;
21860 MFloat momI[3] = {F0, F0, F0};
21861 momI[0] = F1B5 * (POW2(pRadii[3 * p + 1]) + POW2(pRadii[3 * p + 2]));
21862 momI[1] = F1B5 * (POW2(pRadii[3 * p + 0]) + POW2(pRadii[3 * p + 2]));
21863 momI[2] = F1B5 * (POW2(pRadii[3 * p + 0]) + POW2(pRadii[3 * p + 1]));
21864 for(MInt i = 0; i < nDim; i++) {
21865 eKinPartDataMean[18] += partVol[p] * F1B2 * POW2(pvel[p * nDim + i]);
21866 eKinPartDataMean[19] += partVol[p] * F1B2 * momI[i] * POW2(protVelHat[p * nDim + i]);
21867 eKinPartDataMean[20] += partVol[p] * F1B2 * POW2(pvelDt1[p * nDim + i]);
21868 eKinPartDataMean[21] += partVol[p] * F1B2 * momI[i] * POW2(protVelHatDt1[p * nDim + i]);
21869 }
21870 MFloat vrel[3] = {F0, F0, F0};
21871 MFloat omegaRel[3] = {F0, F0, F0};
21872 for(MInt i = 0; i < nDim; i++) {
21873 vrel[i] = vel[nDim * p + i] - pvel[nDim * p + i];
21874 omegaRel[i] = pOmegaHat[i] - protVelHat[p * 3 + i];
21875 }
21876 if(m_noEmbeddedBodies > 0) {
21877 eKinPartDataMean[22] += (m_hydroForce[nDim * p + 0] * vrel[0] + m_hydroForce[nDim * p + 1] * vrel[1]
21878 + m_hydroForce[nDim * p + 2] * vrel[2]);
21879 eKinPartDataMean[23] += (m_bodyTorque[nDim * p + 0] * omegaRel[0] + m_bodyTorque[nDim * p + 1] * omegaRel[1]
21880 + m_bodyTorque[nDim * p + 2] * omegaRel[2]);
21881 } else {
21882 eKinPartDataMean[22] +=
21883 pmass
21884 * (m_particleAcceleration[nDim * p + 0] * vrel[0] + m_particleAcceleration[nDim * p + 1] * vrel[1]
21885 + m_particleAcceleration[nDim * p + 2] * vrel[2]);
21886 eKinPartDataMean[23] += F0; // no source terms because of particle rotation
21887 }
21888 eKinPartDataMean[24] += pTemperature[p];
21889 }
21890 if(m_noPointParticles > 0) {
21891 if(domainId() == 0) {
21892 MPI_Reduce(MPI_IN_PLACE, eKinPartDataMean.data(), eKinPartDataMean.size(), MPI_DOUBLE, MPI_SUM, 0, mpiComm(),
21893 AT_, "MPI_IN_PLACE", "eKinPartDataMean");
21894 } else {
21895 MPI_Reduce(eKinPartDataMean.data(), eKinPartDataMean.data(), eKinPartDataMean.size(), MPI_DOUBLE, MPI_SUM, 0,
21896 mpiComm(), AT_, "MPI_IN_PLACE", "eKinPartDataMean");
21897 }
21898 }
21899
21900 const MFloat volF = eKinFlowDataMean[14];
21901 const MFloat fluidMass = eKinFlowDataMean[12];
21902 const MFloat volP = eKinPartDataMean[1];
21903 const MFloat totalMass = fluidMass + eKinPartDataMean[17];
21904 const MInt cnt = eKinPartDataMean[0];
21905 const MFloat partLinDiss = eKinPartDataMean[22] / POW3(DX);
21906 const MFloat partRotDiss = eKinPartDataMean[23] / POW3(DX);
21907 if(cnt != noParticles) {
21908 cerr << "Number of particles in statistics is wrong " << cnt << " " << m_noEmbeddedBodies << " "
21909 << m_noPointParticles << " " << noParticles << endl;
21910 }
21911
21912 MFloat EkT = eKinFlowDataMean[1] + (eKinPartDataMean[18] + eKinPartDataMean[19]) * m_densityRatio * m_rhoInfinity;
21913 MFloat EkB = (eKinPartDataMean[18] + eKinPartDataMean[19]) / volP;
21914
21915 for(MUint i = 0; i < eKinFlowDataMean.size(); i++) {
21916 eKinFlowDataMean[i] /= volF;
21917 }
21918 for(MUint i = 0; i < eKinPartDataMean.size(); i++) {
21919 eKinPartDataMean[i] /= cnt;
21920 }
21921
21922 // store mean values for later statistics (e.g., nearBodyData)
21923 if(stat == 0) {
21924 meanState(0) = eKinFlowDataMean[0]; // Ek
21925 meanState(1) = EkT / totalMass; // EkT
21926 meanState(2) = EkB; // Ekb
21927 meanState(3) = (5.0 * (sysEqn().m_muInfinity / sysEqn().m_Re0) * (eKinFlowDataMean[9] / F3)); // eps1
21928 }
21929 if(m_firstStats) {
21930 m_oldMeanState[stat][0] = meanState(0); // Ek
21931 m_oldMeanState[stat][1] = meanState(1); // EkT
21932 m_oldMeanState[stat][2] = meanState(2); // EkB
21933 m_oldMeanState[stat][3] = meanState(3); // eps1
21934 }
21935 if(domainId() == 0) {
21936 MFloat mue = eKinFlowDataMean[11];
21937 MFloat dudx = eKinFlowDataMean[9];
21938 MFloat eps4 = F5 * mue * dudx;
21939 MFloat skewness = (eKinFlowDataMean[10] / F3) / pow(dudx / F3, F3B2);
21940 MFloat eta = pow(mue, 0.75) / pow(eps4, 0.25);
21941 MFloat lambda = sqrt(F2B3 * eKinFlowDataMean[0]) / sqrt(dudx / F3);
21942 MFloat reLambda = lambda * sqrt(F2B3 * eKinFlowDataMean[0]) * eKinFlowDataMean[12] / mue;
21943 MFloat coupling = m_couplingRate / (volF + volP);
21944 MFloat* termVel = nullptr;
21945 MFloat defaultTermVel[3] = {F0, F0, F0};
21946 if(m_noPointParticles > 0 && m_particleRadii.size() > 0) {
21948 } else if(m_noEmbeddedBodies > 0) {
21949 termVel = m_bodyTerminalVelocity;
21950 } else {
21951 termVel = defaultTermVel;
21952 }
21953 const MFloat taup = F2 * m_densityRatio * POW2(refRadius) / (9.0 * sysEqn().m_muInfinity / sysEqn().m_Re0);
21954 const MFloat epsRef = DX / (POW3(m_UInfinity));
21955 // gather value-header pairs
21956 vector<pair<string, double>> eKinOutput;
21957 eKinOutput.push_back(make_pair("ts", globalTimeStep));
21958 eKinOutput.push_back(make_pair("t", m_time));
21959 eKinOutput.push_back(make_pair("tf", m_physicalTime));
21960 eKinOutput.push_back(make_pair("Ek", eKinFlowDataMean[0] / POW2(m_UInfinity)));
21961 eKinOutput.push_back(make_pair("EkB", EkB / POW2(m_UInfinity)));
21962 eKinOutput.push_back(make_pair("EkT", EkT / (POW2(m_UInfinity) * totalMass)));
21963 eKinOutput.push_back(make_pair("-d(Ek)dt", -(meanState(0) - m_oldMeanState[stat][0]) * epsRef
21965 eKinOutput.push_back(make_pair("-d(EkB)dt", -(meanState(2) - m_oldMeanState[stat][2]) * epsRef
21967 eKinOutput.push_back(make_pair("-d(EkT)dt", -(meanState(1) - m_oldMeanState[stat][1]) * epsRef
21969 eKinOutput.push_back(make_pair("divergence", eKinFlowDataMean[4] / m_UInfinity));
21970 eKinOutput.push_back(make_pair("divergenceRMS", sqrt(eKinFlowDataMean[15]) / m_UInfinity));
21971 eKinOutput.push_back(make_pair("enstrophy", eKinFlowDataMean[5]));
21972 eKinOutput.push_back(make_pair("eps", eKinFlowDataMean[6] * epsRef));
21973 eKinOutput.push_back(make_pair("eps2", eKinFlowDataMean[7] * epsRef));
21974 eKinOutput.push_back(make_pair("eps3", eKinFlowDataMean[8] * epsRef));
21975 eKinOutput.push_back(make_pair("eps4", eps4 * epsRef));
21976 eKinOutput.push_back(make_pair("skewness", -skewness));
21977 eKinOutput.push_back(make_pair("volF", volF / POW3(DX)));
21978 eKinOutput.push_back(make_pair("volP", volP / POW3(DX)));
21979 eKinOutput.push_back(make_pair("volDiff", (POW3(DX) - volF - volP) / POW3(DX)));
21980 eKinOutput.push_back(make_pair("Kolmogorov-scale", eta / DX));
21981 eKinOutput.push_back(make_pair("Taylor-scale", lambda / DX));
21982 eKinOutput.push_back(make_pair("ReLambda", reLambda));
21983 eKinOutput.push_back(make_pair("Interphase-Momentum-Exchange", coupling * epsRef));
21984 eKinOutput.push_back(make_pair("uPMean", eKinPartDataMean[2] / m_Ma));
21985 eKinOutput.push_back(make_pair("vPMean", eKinPartDataMean[3] / m_Ma));
21986 eKinOutput.push_back(make_pair("wPMean", eKinPartDataMean[4] / m_Ma));
21987 eKinOutput.push_back(make_pair("uPRMS", sqrt(eKinPartDataMean[5]) / m_Ma));
21988 eKinOutput.push_back(make_pair("vPRMS", sqrt(eKinPartDataMean[6]) / m_Ma));
21989 eKinOutput.push_back(make_pair("wPRMS", sqrt(eKinPartDataMean[7]) / m_Ma));
21990 eKinOutput.push_back(make_pair("OmegaxPMean", eKinPartDataMean[8]));
21991 eKinOutput.push_back(make_pair("OmegayPMean", eKinPartDataMean[9]));
21992 eKinOutput.push_back(make_pair("OmegazPMean", eKinPartDataMean[10]));
21993 eKinOutput.push_back(make_pair("OmegaxPRMS", sqrt(eKinPartDataMean[11])));
21994 eKinOutput.push_back(make_pair("OmegayPRMS", sqrt(eKinPartDataMean[12])));
21995 eKinOutput.push_back(make_pair("OmegazPRMS", sqrt(eKinPartDataMean[13])));
21996 eKinOutput.push_back(make_pair("thetaMean", eKinPartDataMean[14]));
21997 eKinOutput.push_back(make_pair("RepMean", eKinPartDataMean[15]));
21998 eKinOutput.push_back(make_pair("RepRMS", sqrt(eKinPartDataMean[16])));
21999 eKinOutput.push_back(make_pair("Stokes", taup * sqrt(F5 * dudx)));
22000 eKinOutput.push_back(make_pair("Froude", taup * POW2(termVel[2]) / mue));
22001 eKinOutput.push_back(make_pair("mueMean", mue / (sysEqn().m_muInfinity / sysEqn().m_Re0)));
22002 eKinOutput.push_back(make_pair("rhoMean", eKinFlowDataMean[12] / m_rhoInfinity));
22003 eKinOutput.push_back(make_pair("rhoRMS", sqrt(eKinFlowDataMean[16]) / m_rhoInfinity));
22004 eKinOutput.push_back(make_pair("TFluid", eKinFlowDataMean[13] / m_TInfinity));
22005 eKinOutput.push_back(make_pair("TPart", eKinPartDataMean[24] / m_TInfinity));
22006 eKinOutput.push_back(make_pair("part_lin_diss", partLinDiss * epsRef));
22007 eKinOutput.push_back(make_pair("part_rot_diss", partRotDiss * epsRef));
22008 // output as ASCII-file
22009 ofstream ofl;
22010 MString suffix = (stat > 0) ? "_D" + to_string(m_distThresholdStat[stat]) : "";
22011 suffix.erase(suffix.find_last_not_of('0') + 1, std::string::npos);
22012 suffix.erase(suffix.find_last_not_of('.') + 1, std::string::npos);
22013 // if first file access, make a backup of existing files and print the header
22014 if(globalTimeStep == 0 && m_firstStats) {
22015 rename(("kineticEnergy" + suffix + "_BAK1").c_str(), ("kineticEnergy" + suffix + "_BAK2").c_str());
22016 rename(("kineticEnergy" + suffix + "_BAK0").c_str(), ("kineticEnergy" + suffix + "_BAK1").c_str());
22017 rename(("kineticEnergy" + suffix + "_BAK").c_str(), ("kineticEnergy" + suffix + "_BAK0").c_str());
22018 rename(("kineticEnergy" + suffix).c_str(), ("kineticEnergy" + suffix + "_BAK").c_str());
22019 ofl.open(("kineticEnergy" + suffix).c_str(), ios_base::out | ios_base::trunc);
22020 ofl << "# "; // outcommented for gnuplot
22021 for(MUint i = 0; i < eKinOutput.size(); i++) {
22022 ofl << i + 1 << ":" << get<0>(eKinOutput[i]) << " ";
22023 }
22024 ofl << endl;
22025 } else {
22026 ofl.open(("kineticEnergy" + suffix).c_str(), ios_base::out | ios_base::app);
22027 }
22028 if(ofl.is_open() && ofl.good()) {
22029 for(MUint i = 0; i < eKinOutput.size(); i++) {
22030 ofl << get<1>(eKinOutput[i]) << " ";
22031 }
22032 ofl << endl;
22033 ofl.close();
22034 }
22035 }
22036 m_oldMeanState[stat][0] = meanState(0);
22037 m_oldMeanState[stat][1] = meanState(1);
22038 m_oldMeanState[stat][2] = meanState(2);
22039 m_oldMeanState[stat][3] = meanState(3);
22040 }
22041 RECORD_TIMER_STOP(t_states);
22042
22043 // probability density function and orientation distribution function
22044 if(computePdf) {
22045 IF_CONSTEXPR(nDim == 2) mTerm(1, AT_, "computePdf not implemented for 2D!");
22046 RECORD_TIMER_START(t_odf);
22047 const MInt noSamples = 1; // no temporal averaging
22048 const MInt thetaSize = 100; // noBins for odf and pdf
22049 const MFloat deltaRadius = F2 / ((MFloat)thetaSize);
22050 const MInt noDat = 64; // mutiples of 4!
22051 // two containers for angles in radians and in degrees
22052 MFloatScratchSpace angles(noDat, AT_, "angles");
22053 MFloatScratchSpace angles2(noDat, AT_, "angles2");
22054 MFloatScratchSpace thetaDensity(thetaSize, noDat, AT_, "thetaDensity");
22055 MFloatScratchSpace thetaDensity2(thetaSize, noDat, AT_, "thetaDensity2");
22056 MFloatScratchSpace thetaPoints(thetaSize, AT_, "thetaPoints");
22057 MFloatScratchSpace thetaPoints2(thetaSize, AT_, "thetaPoints2");
22058 MFloatScratchSpace thetaBounds(thetaSize + 1, AT_, "thetaBounds");
22059 MFloatScratchSpace thetaBounds2(thetaSize + 1, AT_, "thetaBounds2");
22060 angles.fill(F0);
22061 angles2.fill(F0);
22062 thetaDensity.fill(F0);
22063 thetaDensity2.fill(F0);
22064 thetaBounds(0) = F0;
22065 thetaBounds2(0) = -F1;
22066 for(MInt i = 0; i < thetaSize; i++) {
22067 MFloat theta0 = thetaBounds(i);
22068 MFloat theta1 = acos(F1 - ((MFloat)(i + 1)) * deltaRadius); // equal-area bins for angle output
22069 MFloat theta02 = thetaBounds2(i);
22070 MFloat theta12 = thetaBounds2(0) + ((MFloat)(i + 1)) * deltaRadius; // uniform for directional cosines
22071 thetaPoints(i) = F1B2 * (theta0 + theta1);
22072 thetaPoints2(i) = F1B2 * (theta02 + theta12);
22073 thetaBounds(i + 1) = theta1;
22074 thetaBounds2(i + 1) = theta12;
22075 }
22076 thetaBounds(thetaSize) = PI;
22077 thetaBounds2(thetaSize) = F1;
22078 for(MInt p = 0; p < noParticles; p++) {
22079 if(skipParticle(p)) continue;
22080 vector<MFloat> values;
22081 MFloat fdir[3] = {F0, F0, F0};
22082 MFloat wdir[3] = {F0, F0, F0};
22083 MFloat pdir[3] = {F0, F0, F0};
22084 MFloat rdir[3] = {F0, F0, F0};
22085 MFloat reldir[3] = {F0, F0, F0};
22086 for(MInt i = 0; i < nDim; i++) {
22087 fdir[i] = vel[nDim * p + i];
22088 wdir[i] = pOmegaHat[nDim * p + i];
22089 pdir[i] = pvel[nDim * p + i];
22090 rdir[i] = protVelHat[nDim * p + i];
22091 reldir[i] = vel[nDim * p + i] - pvel[nDim * p + i];
22092 }
22093 const MFloat ffabs = sqrt(POW2(fdir[0]) + POW2(fdir[1]) + POW2(fdir[2]));
22094 const MFloat wabs = sqrt(POW2(wdir[0]) + POW2(wdir[1]) + POW2(wdir[2]));
22095 const MFloat pabs = sqrt(POW2(pdir[0]) + POW2(pdir[1]) + POW2(pdir[2]));
22096 const MFloat rabs = sqrt(POW2(rdir[0]) + POW2(rdir[1]) + POW2(rdir[2]));
22097 const MFloat relabs = sqrt(POW2(reldir[0]) + POW2(reldir[1]) + POW2(reldir[2]));
22098 MFloatScratchSpace R(3, 3, AT_, "R");
22099 computeRotationMatrix(R, &(quats[4 * p]));
22100 MFloat q[3];
22101 // fv_mb_cleanup
22102 MFloat tmp[3] = {F1, F0, F0};
22103 matrixVectorProductTranspose(q, R, tmp); // orientation of z-principal axis in world space
22104 const MFloat qabs = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2]);
22105 for(MInt i = 0; i < nDim; i++) {
22106 fdir[i] /= mMax(1e-12, ffabs);
22107 wdir[i] /= mMax(1e-12, wabs);
22108 pdir[i] /= mMax(1e-12, pabs);
22109 rdir[i] /= mMax(1e-12, rabs);
22110 reldir[i] /= mMax(1e-12, relabs);
22111 q[i] /= mMax(1e-12, qabs);
22112 }
22113 matrixVectorProduct(tmp, R, fdir);
22114 values.push_back(q[0]); // angle between major axis and x-axis
22115 values.push_back(q[1]); // angle between major axis and y-axis
22116 values.push_back(q[2]); // angle between major axis and z-axis
22117 values.push_back(tmp[2]); // angle between major axis and flow direction
22118 values.push_back(wdir[2]); // angle between major axis and vorticity direction
22119 MFloat omegaVel = F0; // angle between particle and fluid velocity
22120 MFloat omegaVort = F0; // angle between particle and fluid velocity
22121 for(MInt i = 0; i < nDim; i++) {
22122 omegaVel += pdir[i] * fdir[i];
22123 omegaVort += rdir[i] * wdir[i];
22124 }
22125 values.push_back(omegaVel);
22126 values.push_back(omegaVort);
22127 values.push_back(pdir[0] * q[0] + pdir[1] * q[1] + pdir[2] * q[2]);
22128 values.push_back(reldir[0] * q[0] + reldir[1] * q[1] + reldir[2] * q[2]);
22129 if(m_noEmbeddedBodies > 0)
22130 values.push_back(q[0] * rdir[0] + q[1] * rdir[1] + q[2] * rdir[2]);
22131 else
22132 values.push_back(rdir[2]);
22133
22134 MInt cnt = 0;
22135 for(MUint i = 0; i < values.size(); i++) {
22136 for(MInt j = 0; j < 4; j++) {
22137 angles[cnt] = acos(values[i]);
22138 angles2[cnt++] = values[i];
22139 }
22140 }
22141
22142 const MFloat kernelWidth = 0.05;
22143 const MFloat kernelWidth2 = 0.02;
22144 const MFloat fac = F1 / (kernelWidth);
22145 const MFloat fac2 = F1 / (kernelWidth2);
22146 for(MInt j = 0; j < noDat; j++) {
22147 for(MInt i = 0; i < thetaSize; i++) {
22148 MInt ii = i;
22149 MInt ii2 = i;
22150 if(j % 4 > 1 && i >= thetaSize / 2) ii = thetaSize - i - 1; // symmetry in theta
22151 if(j % 4 > 1 && i < thetaSize / 2) ii2 = thetaSize - i - 1; // symmetry in theta
22152 if(j % 2 == 0) {
22153 if(angles[j] > thetaBounds(i) && angles[j] < thetaBounds(i + 1)) thetaDensity(ii, j) += F1; // bin counting
22154 if(angles2[j] > thetaBounds2(i) && angles2[j] < thetaBounds2(i + 1))
22155 thetaDensity2(ii2, j) += F1; // bin counting
22156 } else {
22157 MFloat DA = thetaBounds(thetaSize) - thetaBounds(0);
22158 MFloat DA2 = thetaBounds2(thetaSize) - thetaBounds2(0);
22159 MFloat t = fabs(angles[j] - thetaPoints(i)) / kernelWidth;
22160 t = mMin(t, fabs(angles[j] + DA - thetaPoints(i)) / kernelWidth); // symmetry in theta
22161 t = mMin(t, fabs(angles[j] - DA - thetaPoints(i)) / kernelWidth); // symmetry in theta
22162 MFloat t2 = fabs(angles2[j] - thetaPoints2(i)) / kernelWidth2;
22163 t2 = mMin(t2, fabs(angles2[j] + DA2 - thetaPoints2(i)) / kernelWidth2); // symmetry in theta
22164 t2 = mMin(t2, fabs(angles2[j] - DA2 - thetaPoints2(i)) / kernelWidth2); // symmetry in theta
22165 // Smoothing using Gaussian kernel
22166 thetaDensity(ii, j) += fac * (thetaBounds(i + 1) - thetaBounds(i)) * exp(-F1B2 * POW2(t)) / sqrt(F2 * PI);
22167 thetaDensity2(ii2, j) +=
22168 fac2 * (thetaBounds2(i + 1) - thetaBounds2(i)) * exp(-F1B2 * POW2(t2)) / sqrt(F2 * PI);
22169 }
22170 }
22171 }
22172 }
22173 if(m_noPointParticles > 0) {
22174 MPI_Allreduce(MPI_IN_PLACE, &thetaDensity[0], noDat * thetaSize, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
22175 "MPI_IN_PLACE", "thetaDensity[0]");
22176 MPI_Allreduce(MPI_IN_PLACE, &thetaDensity2[0], noDat * thetaSize, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
22177 "MPI_IN_PLACE", "thetaDensity2[0]");
22178 }
22179 MFloatScratchSpace sum(noDat, AT_, "sum");
22180 MFloatScratchSpace sum2(noDat, AT_, "sum2");
22181 sum.fill(F0);
22182 sum2.fill(F0);
22183 for(MInt i = 0; i < thetaSize; i++) {
22184 MFloat ang = thetaPoints(i);
22185 MFloat fac = sin(ang);
22186 MFloat fac2 = F1;
22187 for(MInt j = 0; j < noDat; j++) {
22188 sum[j] += fac * (thetaBounds(i + 1) - thetaBounds(i)) * thetaDensity(i, j);
22189 sum2[j] += fac2 * (thetaBounds2(i + 1) - thetaBounds2(i)) * thetaDensity2(i, j);
22190 }
22191 }
22192 for(MInt i = 0; i < thetaSize; i++) {
22193 for(MInt j = 0; j < noDat; j++) {
22194 thetaDensity(i, j) /= sum[j];
22195 thetaDensity2(i, j) /= sum2[j];
22196 }
22197 }
22198
22199 if(domainId() == 0) {
22200 ofstream ofl;
22201 ofstream ofl2;
22202 ofl.open("angleDensity_00" + to_string(globalTimeStep), ios_base::out | ios_base::trunc);
22203 ofl2.open("angleDensityCos_00" + to_string(globalTimeStep), ios_base::out | ios_base::trunc);
22204 if(ofl.is_open() && ofl.good()) {
22205 ofl << "# average orientation distribution functions, sampled from time steps " << globalTimeStep - noSamples
22206 << " to " << globalTimeStep << " (time level " << m_time - (((MFloat)noSamples) * timeStep()) << " to "
22207 << m_time << ")" << endl;
22208 ofl2 << "# average orientation distribution functions (cosines), sampled from time steps "
22209 << globalTimeStep - noSamples << " to " << globalTimeStep << " (time level "
22210 << m_time - (((MFloat)noSamples) * timeStep()) << " to " << m_time << ")" << endl;
22211 ofl << "# 1: angle" << endl;
22212 ofl << "# 2: bin size" << endl;
22213 ofl << "# 3: no samples in bin" << endl;
22214 ofl << "# 4-7: alignment of particle symmetry axis with x-axis" << endl;
22215 ofl << "# 8-11: alignment of particle symmetry axis with y-axis" << endl;
22216 ofl << "# 12-15: alignment of particle symmetry axis with z-axis" << endl;
22217 ofl << "# 16-19: alignment of particle symmetry axis with flow direction" << endl;
22218 ofl << "# 20-23: alignment of particle symmetry axis with vorticity direction" << endl;
22219 ofl << "# 24-27: alignment of particle velocity with flow velocity" << endl;
22220 ofl << "# 28-31: alignment of particle angular velocity with fluid vorticity" << endl;
22221 ofl << "# 32-35: alignment of particle velocity vector with symmetry axis" << endl;
22222 ofl << "# 36-39: alignment of particle rotation vector with symmetry axis" << endl;
22223 ofl << "# 40-43: alignment of relative velocity vector with symmetry axis" << endl;
22224 for(MInt i = 0; i < thetaSize; i++) {
22225 ofl << thetaPoints(i) << " " << thetaBounds(i + 1) - thetaBounds(i) << " " << F0;
22226 ofl2 << thetaPoints2(i) << " " << thetaBounds2(i + 1) - thetaBounds2(i) << " " << F0;
22227 for(MInt j = 0; j < noDat; j++) {
22228 if(j % 4 > 1 && i >= thetaSize / 2)
22229 ofl << " nan"; // symmetry in theta
22230 else
22231 ofl << " " << thetaDensity(i, j);
22232 if(j % 4 > 1 && i < thetaSize / 2)
22233 ofl2 << " nan"; // symmetry in theta
22234 else
22235 ofl2 << " " << thetaDensity2(i, j);
22236 }
22237 ofl << endl;
22238 ofl2 << endl;
22239 }
22240 ofl.close();
22241 ofl2.close();
22242 }
22243 }
22244
22245 RECORD_TIMER_STOP(t_odf);
22246 RECORD_TIMER_START(t_pdf);
22247
22248 const MInt noPdfPoints = 100;
22249 // const MInt kernelSteps = 0; //no kernel smoothing
22250 const MInt kernelSteps = 5; // kernel smoothing
22251 // PF: Particle & Fluid
22252 // P: Particle
22253 const MInt noPdfsPF = 7;
22254 const MInt noPdfsP = 17;
22255 MFloatScratchSpace dataPointsPF(noPdfsPF, AT_, "dataPointsPF");
22256 MFloatScratchSpace pdfPointsPF(noPdfsPF, noPdfPoints, AT_, "pdfPointsPF");
22257 MFloatScratchSpace pdfBoundsPF(noPdfsPF, noPdfPoints + 1, AT_, "pdfBoundsPF");
22258 MFloatScratchSpace pdfValuesPFfluid(noPdfsPF, noPdfPoints, AT_, "pdfValuesPFfluid");
22259 MFloatScratchSpace pdfValuesPFparticle(noPdfsPF, noPdfPoints, AT_, "pdfValuesPFparticle");
22260 MFloatScratchSpace dataPointsP(noPdfsP, AT_, "dataPointsP");
22261 MFloatScratchSpace pdfPointsP(noPdfsP, noPdfPoints, AT_, "pdfPointsP");
22262 MFloatScratchSpace pdfBoundsP(noPdfsP, noPdfPoints + 1, AT_, "pdfBoundsP");
22263 MFloatScratchSpace pdfValuesP(noPdfsP, noPdfPoints, AT_, "pdfValuesP");
22264 MFloatScratchSpace meanValsPF(2, noPdfsPF, AT_, "meanValsPF");
22265 MFloatScratchSpace rmsValsPF(2, noPdfsPF, AT_, "rmsValsPF");
22266 MFloatScratchSpace sumValsPF(2, AT_, "sumValsPF");
22267 MFloatScratchSpace meanValsP(noPdfsP, AT_, "meanValsP");
22268 MFloatScratchSpace rmsValsP(noPdfsP, AT_, "rmsValsP");
22269 vector<MString> pdfTitle;
22270 dataPointsPF.fill(F0);
22271 pdfPointsPF.fill(F0);
22272 pdfBoundsPF.fill(F0);
22273 pdfValuesPFfluid.fill(F0);
22274 pdfValuesPFparticle.fill(F0);
22275 dataPointsP.fill(F0);
22276 pdfPointsP.fill(F0);
22277 pdfBoundsP.fill(F0);
22278 pdfValuesP.fill(F0);
22279 meanValsPF.fill(F0);
22280 rmsValsPF.fill(F0);
22281 meanValsP.fill(F0);
22282 rmsValsP.fill(F0);
22283 sumValsPF.fill(F0);
22284 MFloat sumValsP = F0;
22285
22286 //------- Fluid values in the flow field and near the particle
22287 pdfBoundsPF(0, 0) = 0.0;
22288 pdfBoundsPF(0, noPdfPoints) = 200.0;
22289 pdfTitle.push_back("angular-velocity(particle-fluid)");
22290 pdfBoundsPF(1, 0) = 0.0;
22291 pdfBoundsPF(1, noPdfPoints) = 200.0;
22292 pdfTitle.push_back("strain-rate(particle-fluid)");
22293 pdfBoundsPF(2, 0) = 0.98;
22294 pdfBoundsPF(2, noPdfPoints) = 1.03;
22295 pdfTitle.push_back("pressure(particle-fluid)");
22296 pdfBoundsPF(3, 0) = 0.0;
22297 pdfBoundsPF(3, noPdfPoints) = 3.0;
22298 pdfTitle.push_back("velocity(particle-fluid)");
22299
22300 pdfBoundsPF(4, 0) = -1.5;
22301 pdfBoundsPF(4, noPdfPoints) = 1.5;
22302 pdfTitle.push_back("velX(particle-fluid)");
22303 pdfBoundsPF(5, 0) = -1.5;
22304 pdfBoundsPF(5, noPdfPoints) = 1.5;
22305 pdfTitle.push_back("velY(particle-fluid)");
22306 pdfBoundsPF(6, 0) = -1.5;
22307 pdfBoundsPF(6, noPdfPoints) = 1.5;
22308 pdfTitle.push_back("velZ(particle-fluid)");
22309 //------- Particle-related values
22310 pdfBoundsP(0, 0) = 0.0;
22311 pdfBoundsP(0, noPdfPoints) = 3.0;
22312 pdfTitle.push_back("velocity(particle)");
22313 pdfBoundsP(1, 0) = 0.0;
22314 pdfBoundsP(1, noPdfPoints) = 150.0;
22315 pdfTitle.push_back("angular-velocity(particle)");
22316 pdfBoundsP(2, 0) = 0.0;
22317 pdfBoundsP(2, noPdfPoints) = 50.0;
22318 pdfTitle.push_back("particle-Reynolds-number");
22319 pdfBoundsP(3, 0) = -10.0;
22320 pdfBoundsP(3, noPdfPoints) = 100.0;
22321 pdfTitle.push_back("F_p");
22322 pdfBoundsP(4, 0) = -2.0;
22323 pdfBoundsP(4, noPdfPoints) = 30.0;
22324 pdfTitle.push_back("F*(U_p-v_p)");
22325 pdfBoundsP(5, 0) = -8.0;
22326 pdfBoundsP(5, noPdfPoints) = 20.0;
22327 pdfTitle.push_back("F*U_p");
22328 pdfBoundsP(6, 0) = -25.0;
22329 pdfBoundsP(6, noPdfPoints) = 2.0;
22330 pdfTitle.push_back("F*v_p");
22331 pdfBoundsP(7, 0) = -2.0;
22332 pdfBoundsP(7, noPdfPoints) = 10.0;
22333 pdfTitle.push_back("T_p");
22334 pdfBoundsP(8, 0) = -0.3;
22335 pdfBoundsP(8, noPdfPoints) = 0.3;
22336 pdfTitle.push_back("T_p*(O_p-w_p)");
22337 pdfBoundsP(9, 0) = -0.2;
22338 pdfBoundsP(9, noPdfPoints) = 0.2;
22339 pdfTitle.push_back("T_p*O_p");
22340 pdfBoundsP(10, 0) = -0.3;
22341 pdfBoundsP(10, noPdfPoints) = 0.3;
22342 pdfTitle.push_back("T_p*w_p");
22343 pdfBoundsP(11, 0) = -100.0;
22344 pdfBoundsP(11, noPdfPoints) = 100.0;
22345 pdfTitle.push_back("wHat_px");
22346 pdfBoundsP(12, 0) = -100.0;
22347 pdfBoundsP(12, noPdfPoints) = 100.0;
22348 pdfTitle.push_back("wHat_py");
22349 pdfBoundsP(13, 0) = -100.0;
22350 pdfBoundsP(13, noPdfPoints) = 100.0;
22351 pdfTitle.push_back("wHat_pz");
22352 pdfBoundsP(14, 0) = -100.0;
22353 pdfBoundsP(14, noPdfPoints) = 100.0;
22354 pdfTitle.push_back("OHat_px");
22355 pdfBoundsP(15, 0) = -100.0;
22356 pdfBoundsP(15, noPdfPoints) = 100.0;
22357 pdfTitle.push_back("OHat_py");
22358 pdfBoundsP(16, 0) = -100.0;
22359 pdfBoundsP(16, noPdfPoints) = 100.0;
22360 pdfTitle.push_back("OHat_pz");
22361
22362 for(MInt i = 0; i < noPdfsPF; i++) {
22363 const MFloat DV = (pdfBoundsPF(i, noPdfPoints) - pdfBoundsPF(i, 0)) / ((MFloat)noPdfPoints);
22364 for(MInt j = 0; j < noPdfPoints; j++) {
22365 pdfBoundsPF(i, j + 1) = pdfBoundsPF(i, j) + DV;
22366 pdfPointsPF(i, j) = F1B2 * (pdfBoundsPF(i, j + 1) + pdfBoundsPF(i, j));
22367 }
22368 }
22369 for(MInt i = 0; i < noPdfsP; i++) {
22370 const MFloat DV = (pdfBoundsP(i, noPdfPoints) - pdfBoundsP(i, 0)) / ((MFloat)noPdfPoints);
22371 for(MInt j = 0; j < noPdfPoints; j++) {
22372 pdfBoundsP(i, j + 1) = pdfBoundsP(i, j) + DV;
22373 pdfPointsP(i, j) = F1B2 * (pdfBoundsP(i, j + 1) + pdfBoundsP(i, j));
22374 }
22375 }
22376
22377 for(MInt c = 0; c < noLeafCells; c++) {
22378 MInt cellId = leafCells(c);
22379 MFloat volume = a_cellVolume(cellId) / grid().gridCellVolume(maxUniformRefinementLevel());
22380 MFloat vort = F0;
22381 MFloat strain = F0;
22382 MFloat velm = F0;
22383 for(MInt i = 0; i < nDim; i++) {
22384 MInt id0 = (i + 1) % 3;
22385 MInt id1 = (id0 + 1) % 3;
22386 vort += POW2(F1B2 * (a_slope(cellId, PV->VV[id1], id0) - a_slope(cellId, PV->VV[id0], id1)));
22387 for(MInt j = 0; j < nDim; j++) {
22388 strain += POW2(F1B2 * (a_slope(cellId, PV->VV[i], j) + a_slope(cellId, PV->VV[j], i)));
22389 }
22390 velm += POW2(a_pvariable(cellId, PV->VV[i]));
22391 }
22392 vort = sqrt(vort);
22393 strain = sqrt(strain);
22394 velm = sqrt(velm);
22395 MFloat pressure = a_pvariable(cellId, PV->P) / m_PInfinity;
22396 dataPointsPF(0) = vort * DX / m_UInfinity;
22397 dataPointsPF(1) = strain * DX / m_UInfinity;
22398 dataPointsPF(2) = pressure;
22399 dataPointsPF(3) = velm / m_UInfinity;
22400 dataPointsPF(4) = a_pvariable(cellId, PV->VV[0]) / m_UInfinity;
22401 dataPointsPF(5) = a_pvariable(cellId, PV->VV[1]) / m_UInfinity;
22402 dataPointsPF(6) = a_pvariable(cellId, PV->VV[2]) / m_UInfinity;
22403 const MFloat weight = volume;
22404 for(MInt i = 0; i < noPdfsPF; i++) {
22405 meanValsPF(0, i) += weight * dataPointsPF(i);
22406 rmsValsPF(0, i) += weight * POW2(dataPointsPF(i));
22407 }
22408 sumValsPF(0) += weight;
22409
22410 for(MInt i = 0; i < noPdfsPF; i++) {
22411 const MFloat DV = (pdfBoundsPF(i, noPdfPoints) - pdfBoundsPF(i, 0)) / ((MFloat)noPdfPoints);
22412 MInt bin = (MInt)floor((dataPointsPF(i) - pdfBoundsPF(i, 0)) / DV);
22413 const MFloat kernelWidth = DV * ((MFloat)kernelSteps);
22414 const MFloat fac = F1 / (kernelWidth);
22415 if(kernelSteps == 0) {
22416 if(bin > -1 && bin < noPdfPoints) pdfValuesPFfluid(i, bin) += weight;
22417 } else {
22418 for(MInt j = bin - 5 * kernelSteps; j < bin + 5 * kernelSteps; j++) {
22419 if(j < 0 || j >= noPdfPoints) continue;
22420 MFloat t = fabs(dataPointsPF(i) - pdfPointsPF(i, j)) / DV;
22421 pdfValuesPFfluid(i, j) += fac * weight * exp(-F1B2 * POW2(t)) / sqrt(F2 * PI); // Gaussian kernel
22422 }
22423 }
22424 }
22425 }
22426
22427 for(MInt p = 0; p < noParticles; p++) {
22428 if(skipParticle(p)) continue;
22429 // --- particle-fluid
22430 MFloat velRot = F0;
22431 MFloat shear = F0;
22432 MFloat velm = F0;
22433 for(MInt i = 0; i < nDim; i++) {
22434 velRot += POW2(pOmegaHat[p * nDim + i]);
22435 for(MInt j = 0; j < nDim; j++) {
22436 shear += POW2(velShearHat[p * nDim + i]);
22437 }
22438 velm += POW2(vel[3 * p + i]);
22439 }
22440 dataPointsPF(0) = sqrt(velRot) * DX / m_UInfinity;
22441 dataPointsPF(1) = sqrt(shear) * DX / m_UInfinity;
22442 dataPointsPF(2) = particleFluidPressure[p] / m_PInfinity;
22443 dataPointsPF(3) = sqrt(velm) / m_UInfinity;
22444 dataPointsPF(4) = vel[3 * p + 0] / m_UInfinity;
22445 dataPointsPF(5) = vel[3 * p + 1] / m_UInfinity;
22446 dataPointsPF(6) = vel[3 * p + 2] / m_UInfinity;
22447 for(MInt i = 0; i < noPdfsPF; i++) {
22448 const MFloat DV = (pdfBoundsPF(i, noPdfPoints) - pdfBoundsPF(i, 0)) / ((MFloat)noPdfPoints);
22449 MInt bin = (MInt)floor((dataPointsPF(i) - pdfBoundsPF(i, 0)) / DV);
22450 const MFloat kernelWidth = DV * ((MFloat)kernelSteps);
22451 const MFloat fac = F1 / (kernelWidth);
22452 if(kernelSteps == 0) {
22453 if(bin > -1 && bin < noPdfPoints) pdfValuesPFparticle(i, bin) += F1;
22454 } else {
22455 for(MInt j = bin - 5 * kernelSteps; j < bin + 5 * kernelSteps; j++) {
22456 if(j < 0 || j >= noPdfPoints) continue;
22457 MFloat t = fabs(dataPointsPF(i) - pdfPointsPF(i, j)) / DV;
22458 pdfValuesPFparticle(i, j) += fac * exp(-F1B2 * POW2(t)) / sqrt(F2 * PI); // Gaussian kernel
22459 }
22460 }
22461 }
22462 for(MInt i = 0; i < noPdfsPF; i++) {
22463 meanValsPF(1, i) += dataPointsPF(i);
22464 rmsValsPF(1, i) += POW2(dataPointsPF(i));
22465 }
22466 sumValsPF(1) += F1;
22467 // --- particle
22468 MFloat prot = F0;
22469 MFloat partvel = F0;
22470 for(MInt i = 0; i < nDim; i++) {
22471 partvel += POW2(pvel[3 * p + i]);
22472 prot += POW2(protVelHat[3 * p + i]);
22473 }
22474 dataPointsP(0) = sqrt(partvel) / m_UInfinity;
22475 dataPointsP(1) = sqrt(prot) * DX / m_UInfinity;
22476 MFloat Rep = F0;
22477 MFloat diameter = F2 * pow(pRadii[3 * p] * pRadii[3 * p + 1] * pRadii[3 * p + 2], F1B3);
22478 for(MInt i = 0; i < nDim; i++) {
22479 Rep += POW2(vel[nDim * p + i] - pvel[nDim * p + i]);
22480 }
22481 dataPointsP(2) = sqrt(Rep) * diameter * m_rhoInfinity * sysEqn().m_Re0 / sysEqn().m_muInfinity;
22482 MFloat pF = F0;
22483 MFloat pFUv = F0;
22484 MFloat pFU = F0;
22485 MFloat pFv = F0;
22486 MFloat pT = F0;
22487 MFloat pTOw = F0;
22488 MFloat pTO = F0;
22489 MFloat pTw = F0;
22490 vector<MFloat> pForce(3, F0);
22491 vector<MFloat> pTorqueHat(3, F0);
22492 MFloat q[3];
22493 MFloatScratchSpace R(3, 3, AT_, "R");
22494 computeRotationMatrix(R, &(quats[4 * p]));
22495 if(m_noEmbeddedBodies > 0) {
22497 for(MInt i = 0; i < nDim; i++) {
22498 pForce[i] = m_hydroForce[nDim * p + i];
22499 pTorqueHat[i] = q[i];
22500 }
22501 } else { // point-particles
22502 const MFloat pmass = F4B3 * PI * m_particleRadii[3 * p] * m_particleRadii[3 * p + 1]
22504 const MFloat Ix = F1B5 * (POW2(m_particleRadii[3 * p + 1]) + POW2(m_particleRadii[3 * p + 2])) * pmass;
22505 const MFloat Iy = F1B5 * (POW2(m_particleRadii[3 * p + 0]) + POW2(m_particleRadii[3 * p + 2])) * pmass;
22506 const MFloat Iz = F1B5 * (POW2(m_particleRadii[3 * p + 0]) + POW2(m_particleRadii[3 * p + 1])) * pmass;
22507 const MFloat momI[3] = {Ix, Iy, Iz};
22508 for(MInt i = 0; i < nDim; i++) {
22509 pForce[i] = pmass * m_particleAcceleration[nDim * p + i];
22510 pTorqueHat[i] = momI[i] * m_particleAngularAcceleration[3 * p + i];
22511 protVelHat[i] = protVelHat[p * 3 + i];
22512 }
22513 }
22514 for(MInt i = 0; i < nDim; i++) {
22515 pF += POW2(pForce[i]);
22516 pFUv += pForce[i] * (vel[nDim * p + i] - pvel[nDim * p + i]);
22517 pFU += pForce[i] * vel[nDim * p + i];
22518 pFv += pForce[i] * pvel[nDim * p + i];
22519 pT += POW2(pTorqueHat[i]);
22520 pTOw += pTorqueHat[i] * (pOmegaHat[p * 3 + i] - protVelHat[p * 3 + i]);
22521 pTO += pTorqueHat[i] * pOmegaHat[p * 3 + i];
22522 pTw += pTorqueHat[i] * protVelHat[p * 3 + i];
22523 }
22524 dataPointsP(3) = sqrt(pF) / (POW3(m_UInfinity) * POW2(diameter));
22525 dataPointsP(4) = pFUv / (POW3(m_UInfinity) * POW2(diameter));
22526 dataPointsP(5) = pFU / (POW3(m_UInfinity) * POW2(diameter));
22527 dataPointsP(6) = pFv / (POW3(m_UInfinity) * POW2(diameter));
22528 dataPointsP(7) = sqrt(pT) / (POW3(m_UInfinity) * POW2(diameter));
22529 dataPointsP(8) = pTOw / (POW3(m_UInfinity) * POW2(diameter));
22530 dataPointsP(9) = pTO / (POW3(m_UInfinity) * POW2(diameter));
22531 dataPointsP(10) = pTw / (POW3(m_UInfinity) * POW2(diameter));
22532
22533 for(MInt i = 0; i < nDim; i++) {
22534 dataPointsP(11 + i) = protVelHat[p * nDim + i] * DX / m_UInfinity;
22535 dataPointsP(14 + i) = pOmegaHat[p * nDim + i] * DX / m_UInfinity;
22536 }
22537 for(MInt i = 0; i < noPdfsP; i++) {
22538 meanValsP(i) += dataPointsP(i);
22539 rmsValsP(i) += POW2(dataPointsP(i));
22540 }
22541 sumValsP += F1;
22542
22543 for(MInt i = 0; i < noPdfsP; i++) {
22544 const MFloat DV = (pdfBoundsP(i, noPdfPoints) - pdfBoundsP(i, 0)) / ((MFloat)noPdfPoints);
22545 MInt bin = (MInt)floor((dataPointsP(i) - pdfBoundsP(i, 0)) / DV);
22546 const MFloat kernelWidth = DV * ((MFloat)kernelSteps);
22547 const MFloat fac = F1 / (kernelWidth);
22548 if(kernelSteps == 0) {
22549 if(bin > -1 && bin < noPdfPoints) pdfValuesP(i, bin) += F1;
22550 } else {
22551 for(MInt j = bin - 5 * kernelSteps; j < bin + 5 * kernelSteps; j++) {
22552 if(j < 0 || j >= noPdfPoints) continue;
22553 MFloat t = fabs(dataPointsP(i) - pdfPointsP(i, j)) / DV;
22554 pdfValuesP(i, j) += fac * exp(-F1B2 * POW2(t)) / sqrt(F2 * PI); // Gaussian kernel
22555 }
22556 }
22557 }
22558 }
22559
22560 if(domainId() == 0) {
22561 MPI_Reduce(MPI_IN_PLACE, &meanValsPF[0], 2 * noPdfsPF, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22562 "meanValsPF[0]");
22563 MPI_Reduce(MPI_IN_PLACE, &rmsValsPF[0], 2 * noPdfsPF, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22564 "rmsValsPF[0]");
22565 MPI_Reduce(MPI_IN_PLACE, &sumValsPF[0], 2, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22566 "sumValsPF[0]");
22567 } else {
22568 MPI_Reduce(&meanValsPF[0], &meanValsPF[0], 2 * noPdfsPF, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22569 "meanValsPF[0]");
22570 MPI_Reduce(&meanValsPF[0], &rmsValsPF[0], 2 * noPdfsPF, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22571 "rmsValsPF[0]");
22572 MPI_Reduce(&meanValsPF[0], &sumValsPF[0], 2, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22573 "sumValsPF[0]");
22574 }
22575
22576 if(m_noPointParticles > 0) {
22577 MPI_Reduce(MPI_IN_PLACE, &pdfValuesPFfluid[0], noPdfsPF * noPdfPoints, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_,
22578 "MPI_IN_PLACE", "pdfValuesPFfluid[0]");
22579 MPI_Reduce(MPI_IN_PLACE, &pdfValuesPFparticle[0], noPdfsPF * noPdfPoints, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_,
22580 "MPI_IN_PLACE", "pdfValuesPFparticle[0]");
22581 MPI_Reduce(MPI_IN_PLACE, &meanValsP[0], noPdfsP, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22582 "meanValsP[0]");
22583 MPI_Reduce(MPI_IN_PLACE, &rmsValsP[0], noPdfsP, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE",
22584 "rmsValsP[0]");
22585 MPI_Reduce(MPI_IN_PLACE, &sumValsP, 1, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_, "MPI_IN_PLACE", "sumValsP[0]");
22586 MPI_Reduce(MPI_IN_PLACE, &pdfValuesP[0], noPdfsP * noPdfPoints, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_,
22587 "MPI_IN_PLACE", "pdfValuesP[0]");
22588 }
22589
22590 if(domainId() == 0) {
22591 for(MInt i = 0; i < noPdfsPF; i++) {
22592 meanValsPF(0, i) /= sumValsPF(0);
22593 meanValsPF(1, i) /= sumValsPF(1);
22594 rmsValsPF(0, i) = sqrt(rmsValsPF(0, i) / sumValsPF(0));
22595 rmsValsPF(1, i) = sqrt(rmsValsPF(1, i) / sumValsPF(1));
22596 }
22597 for(MInt i = 0; i < noPdfsP; i++) {
22598 meanValsP(i) /= sumValsP;
22599 rmsValsP(i) = sqrt(rmsValsP(i) / sumValsP);
22600 }
22601
22602 MFloatScratchSpace nfacsPF(noPdfsPF, 2, AT_, "nfacsPF");
22603 MFloatScratchSpace nfacsP(noPdfsP, AT_, "nfacsP");
22604 for(MInt i = 0; i < noPdfsPF; i++) {
22605 MFloat sumv = F0;
22606 MFloat sumv2 = F0;
22607 for(MInt j = 0; j < noPdfPoints; j++) {
22608 sumv += (pdfBoundsPF(i, j + 1) - pdfBoundsPF(i, j)) * pdfValuesPFfluid(i, j);
22609 sumv2 += (pdfBoundsPF(i, j + 1) - pdfBoundsPF(i, j)) * pdfValuesPFparticle(i, j);
22610 }
22611 nfacsPF(i, 0) = sumv;
22612 nfacsPF(i, 1) = sumv2;
22613 for(MInt j = 0; j < noPdfPoints; j++) {
22614 pdfValuesPFfluid(i, j) /= sumv;
22615 pdfValuesPFparticle(i, j) /= sumv2;
22616 }
22617 }
22618 for(MInt i = 0; i < noPdfsP; i++) {
22619 MFloat sumv = F0;
22620 for(MInt j = 0; j < noPdfPoints; j++) {
22621 sumv += (pdfBoundsP(i, j + 1) - pdfBoundsP(i, j)) * pdfValuesP(i, j);
22622 }
22623 nfacsP(i) = sumv;
22624 for(MInt j = 0; j < noPdfPoints; j++) {
22625 pdfValuesP(i, j) /= sumv;
22626 }
22627 }
22628 ofstream ofl;
22629 ofl.open("pdf_00" + to_string(globalTimeStep), ios_base::out | ios_base::trunc);
22630 if(ofl.is_open() && ofl.good()) {
22631 // print header --------
22632 ofl << "# average pdfs, sampled at time step " << globalTimeStep << " (time level " << m_time << ")" << endl;
22633 ofl << "#particle-fluid meanVals: #fluid #particle-fluid: ";
22634 for(MInt i = 0; i < noPdfsPF; i++) {
22635 ofl << meanValsPF(0, i) << " " << meanValsPF(1, i) << " ";
22636 }
22637 ofl << endl;
22638 ofl << "#particle-fluid rmsVals: #fluid #particle-fluid: ";
22639 for(MInt i = 0; i < noPdfsPF; i++) {
22640 ofl << rmsValsPF(0, i) << " " << rmsValsPF(1, i) << " ";
22641 }
22642 ofl << endl;
22643 ofl << "#particle meanVals: ";
22644 for(MInt i = 0; i < noPdfsP; i++) {
22645 ofl << meanValsP(i) << " ";
22646 }
22647 ofl << endl;
22648 ofl << "#particle rmsVals: ";
22649 for(MInt i = 0; i < noPdfsP; i++) {
22650 ofl << rmsValsP(i) << " ";
22651 }
22652 ofl << endl;
22653 MInt cnt = 1;
22654 for(MUint i = 0; i < noPdfsPF; i++) {
22655 ofl << "#" << cnt++ << ":" << pdfTitle[i];
22656 ofl << ", " << cnt++ << ": pdf_fluid, ";
22657 ofl << cnt++ << ": pdf_particleFluid" << endl;
22658 }
22659 for(MUint i = noPdfsPF; i < pdfTitle.size(); i++) {
22660 ofl << "#" << cnt++ << ":" << pdfTitle[i];
22661 ofl << ", " << cnt++ << ": pdf_particle" << endl;
22662 }
22663 // print header -------- finished
22664 for(MInt j = 0; j < noPdfPoints; j++) {
22665 for(MInt i = 0; i < noPdfsPF; i++) {
22666 ofl << pdfPointsPF(i, j) << " " << pdfValuesPFfluid(i, j) << " " << pdfValuesPFparticle(i, j) << " ";
22667 }
22668 for(MInt i = 0; i < noPdfsP; i++) {
22669 ofl << pdfPointsP(i, j) << " " << pdfValuesP(i, j) << " ";
22670 }
22671 for(MInt i = 0; i < noPdfsPF; i++) {
22672 ofl << nfacsPF(i, 0) << " " << nfacsPF(i, 1) << " ";
22673 }
22674 for(MInt i = 0; i < noPdfsP; i++) {
22675 ofl << nfacsP(i) << " " << nfacsP(i) << " ";
22676 }
22677 ofl << endl;
22678 }
22679 ofl.close();
22680 }
22681 }
22682 RECORD_TIMER_STOP(t_pdf);
22683 }
22684
22685 // near-particle statistics
22686 if(computeNearBody && m_noEmbeddedBodies > 0) {
22687 IF_CONSTEXPR(nDim == 2) mTerm(1, AT_, "computeNearBody not implemented for 2D!");
22688 RECORD_TIMER_START(t_near);
22689
22690 // bodyDataScatter -> scatter plot
22691 constexpr MInt noDat2 = 26;
22692 const MInt noReClasses = (m_bodyTypeMb == 3 ? 6 : 1);
22693 MFloatScratchSpace ReClass(m_noEmbeddedBodies, AT_, "ReClass");
22694 MFloatScratchSpace ReClassBounds(noReClasses, AT_, "ReClassBounds");
22695 MFloatScratchSpace bodyDataScatter(m_noEmbeddedBodies, noDat2, AT_, "bodyDataScatter");
22696 MFloatScratchSpace bodyCnt(noReClasses, AT_, "bodyCnt");
22697 bodyDataScatter.fill(F0);
22698 bodyCnt.fill(F0);
22699
22700 if(m_bodyTypeMb == 3) {
22701 ReClassBounds(0) = 0;
22702 ReClassBounds(1) = 10;
22703 ReClassBounds(2) = 40;
22704 ReClassBounds(3) = 50;
22705 ReClassBounds(4) = 80;
22706 ReClassBounds(5) = 90;
22707 }
22708
22709 RECORD_TIMER_START(t_near_bodydat2);
22710 for(MInt p = 0; p < m_noEmbeddedBodies; p++) {
22711 MFloat diameter = F2 * pow(m_bodyRadii[3 * p] * m_bodyRadii[3 * p + 1] * m_bodyRadii[3 * p + 2], F1B3);
22712 MFloat vrel[3] = {F0, F0, F0};
22713 MFloat vdir[3] = {F0, F0, F0};
22714 MFloat vpdir[3] = {F0, F0, F0};
22715 MFloat vfdir[3] = {F0, F0, F0};
22716 MFloat omegaRel[3] = {F0, F0, F0};
22717 MFloat vrel_mag = F0;
22718 MFloat vp_mag = F0;
22719 MFloat vf_mag = F0;
22720 for(MInt i = 0; i < nDim; i++) {
22721 vrel[i] = vel[nDim * p + i] - pvel[nDim * p + i];
22722 vpdir[i] = pvel[nDim * p + i];
22723 vfdir[i] = vel[nDim * p + i];
22724 vrel_mag += POW2(vrel[i]);
22725 vp_mag += POW2(vpdir[i]);
22726 vf_mag += POW2(vfdir[i]);
22727 }
22728 vrel_mag = sqrt(vrel_mag);
22729 vp_mag = sqrt(vp_mag);
22730 vf_mag = sqrt(vf_mag);
22731 for(MInt i = 0; i < nDim; i++) {
22732 vdir[i] = vrel[i] / mMax(1e-12, vrel_mag);
22733 vpdir[i] /= mMax(1e-12, vp_mag);
22734 vfdir[i] /= mMax(1e-12, vf_mag);
22735 }
22736 MFloat q[3];
22737 // fv_mb_cleanup
22738 MFloat tmp[3] = {F1, F0, F0};
22739 MFloatScratchSpace R(3, 3, AT_, "R");
22740 computeRotationMatrix(R, &(quats[4 * p]));
22741 matrixVectorProductTranspose(q, R, tmp); // orientation of z-principal axis
22742 const MFloat qabs = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2]);
22743 for(MInt i = 0; i < nDim; i++)
22744 q[i] /= mMax(1e-12, qabs);
22745 MFloat Rep = vrel_mag * diameter * m_rhoInfinity * sysEqn().m_Re0 / sysEqn().m_muInfinity;
22746 MInt classId = -1;
22747 if(m_bodyTypeMb == 3) {
22748 MFloat aof = F0;
22749 for(MInt i = 0; i < nDim; i++) {
22750 aof += vdir[i] * q[i];
22751 }
22752 aof = acos(fabs(aof)) * 360.0 / (2.0 * PI);
22753 for(MInt i = 1; i < noReClasses; i++) {
22754 if(aof >= ReClassBounds(i - 1) && aof < ReClassBounds(i)) {
22755 classId = i;
22756 break;
22757 }
22758 }
22759 ReClass(p) = classId;
22760 bodyCnt[0] += F1;
22761 bodyCnt[classId] += F1;
22762 } else {
22763 classId = 0;
22764 ReClass(p) = classId;
22765 bodyCnt[0] += F1;
22766 bodyCnt[classId] += F1;
22767 }
22768
22769 MFloat eps0 = F0;
22770 MFloat eps1 = F0;
22771 for(MInt i = 0; i < nDim; i++) {
22772 eps0 += 5.0 * (sysEqn().m_muInfinity / sysEqn().m_Re0) * POW2(velGradient[9 * p + 3 * i + i]);
22773 for(MInt j = 0; j < nDim; j++) {
22774 eps1 += (sysEqn().m_muInfinity / sysEqn().m_Re0)
22775 * (velGradient[9 * p + 3 * i + j] + velGradient[9 * p + 3 * j + i]) * velGradient[9 * p + 3 * i + j];
22776 }
22777 }
22778 const MFloat epsRef = diameter / (POW3(m_UInfinity));
22779 MFloat wdir[3]{};
22780 MFloat pOmega[3]{};
22781 for(MInt i = 0; i < nDim; i++) {
22782 MInt id0 = (i + 1) % 3;
22783 MInt id1 = (id0 + 1) % 3;
22784 wdir[i] = F1B2 * (velGradient[9 * p + 3 * id1 + id0] - velGradient[9 * p + 3 * id0 + id1]);
22785 pOmega[i] = wdir[i];
22786 }
22787 for(MInt i = 0; i < 3; i++) {
22788 omegaRel[i] = wdir[i] - m_bodyAngularVelocity[p * 3 + i];
22789 }
22790 const MFloat wabs = sqrt(POW2(wdir[0]) + POW2(wdir[1]) + POW2(wdir[2]));
22791 for(MInt i = 0; i < nDim; i++) {
22792 wdir[i] /= mMax(1e-12, wabs);
22793 }
22794
22795 MFloat tmp2[3]{};
22796 MFloat force_frs[3]{};
22797 for(MInt i = 0; i < nDim; i++) {
22798 tmp2[i] = m_hydroForce[nDim * p + i];
22799 }
22800 matrixVectorProduct(force_frs, R, tmp2);
22801 MFloat torque_frs[3];
22802 for(MInt i = 0; i < 3; i++) {
22803 tmp2[i] = m_bodyTorque[3 * p + i];
22804 }
22805 matrixVectorProduct(torque_frs, R, tmp2);
22806
22807 MInt cnt = 0;
22808 bodyDataScatter(p, cnt++) = Rep;
22809 bodyDataScatter(p, cnt++) = sqrt(POW2(vrel[0]) + POW2(vrel[1]) + POW2(vrel[2])) / m_UInfinity;
22810 bodyDataScatter(p, cnt++) =
22811 sqrt(POW2(pvel[nDim * p + 0]) + POW2(pvel[nDim * p + 1]) + POW2(pvel[nDim * p + 2])) / m_UInfinity;
22812 bodyDataScatter(p, cnt++) =
22813 (pvel[nDim * p + 0] * vdir[0] + pvel[nDim * p + 1] * vdir[1] + pvel[nDim * p + 2] * vdir[2]) / m_UInfinity;
22814 bodyDataScatter(p, cnt++) =
22815 sqrt(POW2(vel[nDim * p + 0]) + POW2(vel[nDim * p + 1]) + POW2(vel[nDim * p + 2])) / m_UInfinity;
22816 bodyDataScatter(p, cnt++) =
22817 (vel[nDim * p + 0] * vdir[0] + vel[nDim * p + 1] * vdir[1] + vel[nDim * p + 2] * vdir[2]) / m_UInfinity;
22818 bodyDataScatter(p, cnt++) = sqrt(POW2(pOmega[0]) + POW2(pOmega[1]) + POW2(pOmega[2])) * diameter / m_UInfinity;
22819 bodyDataScatter(p, cnt++) =
22820 (pOmega[0] * vdir[0] + pOmega[1] * vdir[1] + pOmega[2] * vdir[2]) * diameter / m_UInfinity;
22821 bodyDataScatter(p, cnt++) = (vfdir[0] * vpdir[0] + vfdir[1] * vpdir[1] + vfdir[2] * vpdir[2]);
22822 bodyDataScatter(p, cnt++) = (vdir[0] * vpdir[0] + vdir[1] * vpdir[1] + vdir[2] * vpdir[2]);
22823 bodyDataScatter(p, cnt++) = (particleFluidPressure[p] - m_PInfinity) / (F1B2 * m_rhoInfinity * POW2(m_UInfinity));
22824 bodyDataScatter(p, cnt++) = eps0 * epsRef;
22825 bodyDataScatter(p, cnt++) = eps1 * epsRef;
22826 bodyDataScatter(p, cnt++) = nearBodyState[noNearBodyState * p + 0] * epsRef;
22827 bodyDataScatter(p, cnt++) = nearBodyState[noNearBodyState * p + 1] * epsRef;
22828 bodyDataScatter(p, cnt++) = nearBodyState[noNearBodyState * p + 2] * epsRef;
22829 bodyDataScatter(p, cnt++) = nearBodyState[noNearBodyState * p + 3] * epsRef;
22830 bodyDataScatter(p, cnt++) = nearBodyState[noNearBodyState * p + 4] * epsRef;
22831 bodyDataScatter(p, cnt++) = (m_hydroForce[nDim * p + 0] * vrel[0] + m_hydroForce[nDim * p + 1] * vrel[1]
22832 + m_hydroForce[nDim * p + 2] * vrel[2])
22833 / (POW3(m_UInfinity) * POW2(diameter));
22834 bodyDataScatter(p, cnt++) = (m_bodyTorque[3 * p + 0] * omegaRel[0] + m_bodyTorque[nDim * p + 1] * omegaRel[1]
22835 + m_bodyTorque[nDim * p + 2] * omegaRel[2])
22836 / (POW3(m_UInfinity) * POW2(diameter));
22837 bodyDataScatter(p, cnt++) = force_frs[0];
22838 bodyDataScatter(p, cnt++) = force_frs[1];
22839 bodyDataScatter(p, cnt++) = force_frs[2];
22840 bodyDataScatter(p, cnt++) = torque_frs[0];
22841 bodyDataScatter(p, cnt++) = torque_frs[1];
22842 bodyDataScatter(p, cnt++) = torque_frs[2];
22843
22844 if(cnt != noDat2) mTerm(1, AT_, "data size mismatch.");
22845 }
22846 RECORD_TIMER_STOP(t_near_bodydat2);
22847
22848 RECORD_TIMER_START(t_near_bodydat);
22849 // nearBodydata -> near-body flow pattern
22850 // define a local uniform grid around the particle for visualization
22851 const MFloat refRadius = m_maxBodyRadius;
22852 constexpr MInt noDat = 13;
22853 const MFloat dxm = 4.0;
22854 // const MFloat deltaR = mMin(drm, mMax(m_outerBandWidth[maxUniformRefinementLevel() + 1] / refRadius, 4.0));
22855 const MFloat deltaX =
22857 const MFloat dx =
22859 const MInt noPointsX = (MInt)((deltaX + 0.001 * dx) / dx);
22860 const MFloat deltaY = deltaX;
22861 const MInt noPointsY = noPointsX;
22862 const MFloat dy = dx;
22863 MFloatScratchSpace nearBodyData(noPointsX, noPointsY, noDat * noReClasses, AT_, "nearBodyData");
22864 MFloatScratchSpace bodySum(noPointsX, noPointsY, noReClasses, AT_, "bodySum");
22865 MFloatScratchSpace xPoints(noPointsX, AT_, "xPoints");
22866 MFloatScratchSpace xBounds(noPointsX + 1, AT_, "xBounds");
22867 MFloatScratchSpace yPoints(noPointsY, AT_, "yPoints");
22868 MFloatScratchSpace yBounds(noPointsY + 1, AT_, "yBounds");
22869 MFloatScratchSpace dat(noDat, AT_, "dat");
22870 MFloatScratchSpace K(3, 3, AT_, "K");
22871 const MInt dataSize0 = noPointsX * noPointsY * noReClasses;
22872 const MInt dataSize = noDat * dataSize0;
22873 nearBodyData.fill(F0);
22874 bodySum.fill(F0);
22875
22876 xBounds(0) = (m_bodyTypeMb == 3) ? -F1B2 * deltaX : 0.0;
22877 for(MInt i = 0; i < noPointsX; i++) {
22878 xBounds(i + 1) = xBounds(i) + dx;
22879 xPoints(i) = F1B2 * (xBounds(i) + xBounds(i + 1));
22880 }
22881 yBounds(0) = (m_bodyTypeMb == 3) ? -F1B2 * deltaY : 0.0;
22882 for(MInt i = 0; i < noPointsY; i++) {
22883 yBounds(i + 1) = yBounds(i) + dy;
22884 yPoints(i) = F1B2 * (yBounds(i) + yBounds(i + 1));
22885 }
22886
22887 for(MInt c = 0; c < noLeafCells; c++) {
22888 MInt cellId = leafCells(c);
22889 MFloat volume = F1; // no volume - weighting for nearBodyData
22890 if(volume < 1e-14) continue;
22891 if(a_level(cellId) <= maxUniformRefinementLevel()) continue;
22892
22893 for(MInt set = m_startSet; set < m_noSets; set++) {
22894 if(a_associatedBodyIds(cellId, set) < 0) continue;
22895 // const MFloat dist0 = a_levelSetValuesMb(cellId, set);
22896 const MInt p = a_associatedBodyIds(cellId, set);
22897 const MInt q = m_internalBodyId[p];
22898 if(q < 0 || q >= m_noEmbeddedBodies) {
22899 cerr << "Warning: body id " << endl;
22900 continue;
22901 }
22902 if(skipParticle(q)) continue;
22903 const MInt classId = ReClass(q);
22904 if(classId < 0) continue;
22905 MFloat diameter = F2 * pow(m_bodyRadii[3 * q] * m_bodyRadii[3 * q + 1] * m_bodyRadii[3 * q + 2], F1B3);
22906 MFloat vrel[3] = {F0, F0, F0};
22907 MFloat vdir[3] = {F0, F0, F0};
22908 MFloat vrel_mag = F0;
22909 MFloat vmag = F0;
22910 MFloat r = F0;
22911 MFloat crossp[3] = {F0, F0, F0};
22912 MFloat crossp2[3] = {F0, F0, F0};
22913 MFloat symm[3];
22914 // fv_mb_cleanup
22915 MFloat tmp[3] = {F1, F0, F0};
22916 MFloat scnt = F0;
22917 MFloatScratchSpace R(3, 3, AT_, "R");
22918 computeRotationMatrix(R, &(quats[4 * q]));
22919 matrixVectorProductTranspose(symm, R, tmp); // orientation of z-principal axis
22920 for(MInt i = 0; i < nDim; i++) {
22921 vrel[i] = vel[nDim * q + i] - pvel[nDim * q + i];
22922 vrel_mag += POW2(vrel[i]);
22923 vmag += POW2(pvel[nDim * q + i]);
22924 scnt += POW2(symm[i]);
22925 }
22926 vmag = sqrt(vmag);
22927 vrel_mag = sqrt(vrel_mag);
22928 r = sqrt(r);
22929 scnt = sqrt(scnt);
22930 for(MInt i = 0; i < nDim; i++) {
22931 vdir[i] = vrel[i] / mMax(1e-14, vrel_mag);
22932 symm[i] = symm[i] / mMax(1e-14, scnt);
22933 }
22934 if(m_bodyTypeMb == 3) {
22935 MFloat minRad = mMin(mMin(m_bodyRadii[3 * p], m_bodyRadii[3 * p + 1]), m_bodyRadii[3 * p + 2]);
22936 r = (r - minRad) / minRad;
22937 } else {
22938 r = (r - m_bodyRadius[p]) / m_bodyRadius[p];
22939 }
22940
22941 MFloat csm = F0;
22942 MFloat trans = F0;
22943 crossProduct(crossp, vdir, symm);
22944 for(MInt i = 0; i < nDim; i++) {
22945 csm += POW2(crossp[i]);
22946 }
22947 csm = sqrt(csm);
22948 for(MInt i = 0; i < nDim; i++) {
22949 crossp[i] = crossp[i] / mMax(1e-14, csm);
22950 trans += crossp[i] * (a_coordinate(cellId, i) - m_bodyCenter[nDim * p + i]);
22951 }
22952 crossProduct(crossp2, vdir, crossp);
22953 MFloat csm2 = F0;
22954 for(MInt i = 0; i < nDim; i++) {
22955 csm2 += POW2(crossp2[i]);
22956 }
22957 csm2 = sqrt(csm2);
22958 for(MInt i = 0; i < nDim; i++) {
22959 crossp2[i] = crossp2[i] / mMax(1e-14, csm2);
22960 }
22961
22962 if(fabs(trans) > mMax(F2 * c_cellLengthAtLevel(maxRefinementLevel()), c_cellLengthAtCell(cellId))) {
22963 continue;
22964 }
22965
22966 MInt idx = -1;
22967 MInt idy = -1;
22968 // Cartesian interpolation
22969 MFloat aof0 = F0;
22970 for(MInt i = 0; i < nDim; i++) {
22971 aof0 += vdir[i] * symm[i];
22972 }
22973 MFloat distx = F0;
22974 MFloat disty = F0;
22975 for(MInt i = 0; i < nDim; i++) {
22976 distx += (a_coordinate(cellId, i) - m_bodyCenter[nDim * p + i]) * vdir[i] / refRadius;
22977 disty += (a_coordinate(cellId, i) - m_bodyCenter[nDim * p + i]) * crossp2[i] / refRadius;
22978 }
22979 if(aof0 < F0) disty *= -F1;
22980 idx = (MInt)(distx / dx) + noPointsX / 2;
22981 idy = (MInt)(disty / dy) + noPointsY / 2;
22982
22983 dat.fill(F0);
22984 if(idy < 0 || idx < 0 || idy >= noPointsY || idx >= noPointsX) {
22985 continue;
22986 }
22987
22988 MInt idCnt = 0;
22989 MFloat vabs = F0;
22990 MFloat vabs2 = F0;
22991 for(MInt i = 0; i < nDim; i++) {
22992 vabs += POW2(a_pvariable(cellId, PV->VV[i]) - pvel[nDim * q + i]);
22993 vabs2 += POW2(a_pvariable(cellId, PV->VV[i]) - vel[nDim * q + i]);
22994 }
22995 vabs = sqrt(vabs);
22996 vabs2 = sqrt(vabs2);
22997 dat(idCnt++) = vabs / m_UInfinity;
22998 dat(idCnt++) = vabs / vmag;
22999 dat(idCnt++) = vabs2 / m_UInfinity;
23000 dat(idCnt++) = vabs2 / vrel_mag;
23001 MFloat cp = (a_pvariable(cellId, PV->P) - particleFluidPressure[q]);
23002 dat(idCnt++) = cp / (F1B2 * m_rhoInfinity * POW2(m_UInfinity));
23003 dat(idCnt++) = cp / (F1B2 * m_rhoInfinity * POW2(vrel_mag));
23004
23005 MFloat vort[3]{};
23006 for(MInt i = 0; i < nDim; i++) {
23007 MInt id0 = (i + 1) % 3;
23008 MInt id1 = (id0 + 1) % 3;
23009 vort[i] = F1B2 * (a_slope(cellId, PV->VV[id1], id0) - a_slope(cellId, PV->VV[id0], id1));
23010 }
23011
23012 MFloat U2 = F0;
23013 MFloat eps = F0;
23014 MFloat eps0 = F0;
23015 for(MInt i = 0; i < nDim; i++) {
23016 U2 += POW2(a_variable(cellId, CV->RHO_VV[i]) / a_variable(cellId, CV->RHO));
23017 }
23018 MFloat mue = sysEqn().m_muInfinity / sysEqn().m_Re0;
23019 MFloat Ek = F1B2 * U2;
23020 for(MInt i = 0; i < nDim; i++) {
23021 eps0 += 5.0 * mue * POW2(a_slope(cellId, PV->VV[i], i));
23022 for(MInt j = 0; j < nDim; j++) {
23023 eps +=
23024 mue * (a_slope(cellId, PV->VV[i], j) + a_slope(cellId, PV->VV[j], i)) * a_slope(cellId, PV->VV[i], j);
23025 }
23026 }
23027 const MFloat epsRef = diameter / (POW3(m_UInfinity));
23028 dat(idCnt++) = Ek / POW2(m_UInfinity);
23029 dat(idCnt++) = (Ek - meanState(0)) / POW2(m_UInfinity);
23030 dat(idCnt++) = eps * epsRef;
23031 dat(idCnt++) = eps0 * epsRef;
23032 dat(idCnt++) = (eps - meanState(3)) * epsRef;
23033 dat(idCnt++) = (eps0 - meanState(2)) * epsRef;
23034 dat(idCnt++) = (POW2(vort[0]) + POW2(vort[1]) + POW2(vort[2])) * diameter / m_UInfinity;
23035 if(idCnt != noDat) mTerm(1, AT_, "id mismatch.");
23036
23037 for(MInt i = mMax(0, idx - 3); i < mMin(noPointsX, idx + 4); i++) {
23038 for(MInt j = mMax(0, idy - 3); j < mMin(noPointsY, idy + 4); j++) {
23039 const MFloat dist = sqrt(POW2((i - idx) * dx) + POW2((j - idy) * dy));
23040 const MFloat fac =
23041 exp(-F1B4 * POW2(dist)) * a_cellVolume(cellId) / grid().gridCellVolume(maxUniformRefinementLevel());
23042 for(MInt k = 0; k < noDat; k++) {
23043 nearBodyData(i, j, k) += fac * volume * dat(k);
23044 }
23045 bodySum(i, j, 0) += fac * volume;
23046 if(classId > 0) {
23047 for(MInt k = 0; k < noDat; k++) {
23048 nearBodyData(i, j, classId * noDat + k) += fac * volume * dat(k);
23049 }
23050 bodySum(i, j, classId) += fac * volume;
23051 }
23052 }
23053 }
23054 }
23055 }
23056 MPI_Allreduce(MPI_IN_PLACE, &nearBodyData[0], dataSize, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23057 "nearBodyData[0]");
23058 MPI_Allreduce(MPI_IN_PLACE, &bodySum[0], dataSize0, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23059 "bodySum[0]");
23060
23061 for(MInt i = 0; i < noPointsX; i++) {
23062 for(MInt j = 0; j < noPointsY; j++) {
23063 for(MInt k = 0; k < noDat; k++) {
23064 for(MInt l = 0; l < noReClasses; l++) {
23065 if(bodySum(i, j, l) > F0) {
23066 nearBodyData(i, j, l * noDat + k) /= bodySum(i, j, l);
23067 }
23068 }
23069 }
23070 }
23071 }
23072 RECORD_TIMER_STOP(t_near_bodydat);
23073 RECORD_TIMER_START(t_near_output);
23074 // This output should be evantually generated via Netcdf
23075 if(domainId() == 0) {
23076 for(MInt l = 0; l < noReClasses; l++) {
23077 ofstream ofl;
23078 string suffix = (l > 0) ? "_class" + to_string(l) : "";
23079 ofl.open(("nearBodyData" + suffix + "_00" + to_string(globalTimeStep)).c_str(),
23080 ios_base::out | ios_base::trunc);
23081 if(ofl.is_open() && ofl.good()) {
23082 ofl << "# mean near-body statistics at time step " << globalTimeStep << ", \n";
23083 ofl << "# average number of bodies in class: " << bodyCnt[l] << "\n";
23084 ofl << "# 1: lower bound x" << endl;
23085 ofl << "# 2: upper bound x" << endl;
23086 ofl << "# 3: x-Coordinate" << endl;
23087 ofl << "# 4: lower bound y" << endl;
23088 ofl << "# 5: upper bound y" << endl;
23089 ofl << "# 6: y-Coordinate" << endl;
23090 ofl << "# 7: sample weight" << endl;
23091 ofl << "# 8-9: relative velocity abs(u-v_p)" << endl;
23092 ofl << "# 12-13: relative velocity abs(u-U_p)" << endl;
23093 ofl << "# 14-15: cp" << endl;
23094 ofl << "# 16: Ek" << endl;
23095 ofl << "# 17: Ek - Ek_mean" << endl;
23096 ofl << "# 18: eps (isotropic)" << endl;
23097 ofl << "# 19: eps0" << endl;
23098 ofl << "# 20: eps - eps_mean (isotropic)" << endl;
23099 ofl << "# 21: eps0 - eps0_mean" << endl;
23100 ofl << "# 22: vorticity magnitude" << endl;
23101 ofl << endl;
23102 for(MInt i = 0; i < noPointsX; i++) {
23103 for(MInt j = 0; j < noPointsY; j++) {
23104 ofl << xBounds(i) << " " << xBounds(i + 1) << " " << xPoints(i) << " ";
23105 ofl << yBounds(j) << " " << yBounds(j + 1) << " " << yPoints(j) << " ";
23106 ofl << bodySum(i, j, l) << " ";
23107 if(bodySum(i, j, l) > F0) {
23108 for(MInt k = 0; k < noDat; k++) {
23109 ofl << nearBodyData(i, j, l * noDat + k) << " ";
23110 }
23111 } else {
23112 for(MInt k = 0; k < noDat; k++) {
23113 ofl << F0 << " " << F0 << " ";
23114 }
23115 }
23116 ofl << endl;
23117 }
23118 ofl << endl;
23119 }
23120 }
23121 ofl.close();
23122 }
23123 }
23124 // This output should be evantually generated via Netcdf
23125 if(domainId() == 0) {
23126 ofstream ofl;
23127 ofl.open("bodyData_00" + to_string(globalTimeStep), ios_base::out | ios_base::trunc);
23128 if(ofl.is_open() && ofl.good()) {
23129 ofl << "# body statistics at time step " << globalTimeStep << endl;
23130 ofl << "# 1: Re_p" << endl;
23131 ofl << "# 2: vel_rel abs" << endl;
23132 ofl << "# 3: vel_part abs" << endl;
23133 ofl << "# 4: vel_part inline" << endl;
23134 ofl << "# 5: vel_fluid abs" << endl;
23135 ofl << "# 6: vel_fluid inline" << endl;
23136 ofl << "# 7: vorticity abs" << endl;
23137 ofl << "# 8: cosine vorticity times vrel" << endl;
23138 ofl << "# 9: cosine vel fluid times vel part " << endl;
23139 ofl << "# 10: cosine rel vel times vel part " << endl;
23140 ofl << "# 11: c_p" << endl;
23141 ofl << "# 12: eps0" << endl;
23142 ofl << "# 13: eps1" << endl;
23143 ofl << "# 14: near-body eps 0.5 d_p" << endl;
23144 ofl << "# 15: near-body eps 1.0 d_p" << endl;
23145 ofl << "# 16: near-body eps 1.5 d_p" << endl;
23146 ofl << "# 17: near-body eps 2.0 d_p" << endl;
23147 ofl << "# 18: near-body eps 2.5 d_p" << endl;
23148 ofl << "# 19: F_p * (U_p - v_p)" << endl;
23149 ofl << "# 20: T_p * (O_p - o_p)" << endl;
23150 ofl << "# 21: FxHat" << endl;
23151 ofl << "# 22: FyHat" << endl;
23152 ofl << "# 23: FzHat" << endl;
23153 ofl << "# 24: TxHat" << endl;
23154 ofl << "# 25: TyHat" << endl;
23155 ofl << "# 26: TzHat" << endl;
23156
23157 for(MInt p = 0; p < m_noEmbeddedBodies; p++) {
23158 for(MInt i = 0; i < noDat2; i++) {
23159 ofl << bodyDataScatter[noDat2 * p + i] << " ";
23160 }
23161 ofl << endl;
23162 }
23163 ofl.clear();
23164 }
23165 ofl.close();
23166 }
23167 RECORD_TIMER_STOP(t_near_output);
23168 RECORD_TIMER_STOP(t_near);
23169 }
23170
23171 if(computeFFT) {
23172 RECORD_TIMER_START(t_fft);
23173 // fft-domain dimensions
23174 // this holds the size of the domain in number of cells on lowest level
23175 const MInt fftLevel = maxUniformRefinementLevel();
23176 if(fftLevel > maxUniformRefinementLevel()) mTerm(1, AT_, "Non-isotropic mesh is not implemented, yet");
23177 if(fftLevel < minLevel()) mTerm(1, AT_, "Parents missing for fftLevel < minLevel()");
23178
23179 const MFloat dx = c_cellLengthAtLevel(fftLevel);
23180 const MFloat dxeps = 0.1 * dx;
23181 MInt nx = (m_bbox[3] - m_bbox[0] + dxeps) / dx;
23182 MInt ny = (m_bbox[4] - m_bbox[1] + dxeps) / dx;
23183 MInt nz = (m_bbox[5] - m_bbox[2] + dxeps) / dx;
23184
23185 MFloatScratchSpace coupling(a_noCells(), nDim, AT_, "coupling");
23186 MFloatScratchSpace pVariables(a_noCells(), m_noPVars, AT_, "pVariables");
23187 MFloatScratchSpace cVariables(a_noCells(), m_noCVars, AT_, "cVariables");
23188 MFloatScratchSpace oldVariables(a_noCells(), m_noCVars, AT_, "oldVariables");
23189 MInt filterLvlLaplace = fftLevel;
23190 filterLvlLaplace = Context::getSolverProperty<MInt>("filterLvlLaplace", m_solverId, AT_, &filterLvlLaplace);
23191
23192 MFloat couplingCheck = determineCoupling(coupling);
23193 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
23194 for(MInt i = 0; i < m_noPVars; i++) {
23195 pVariables(cellId, i) = a_pvariable(cellId, i);
23196 }
23197 for(MInt i = 0; i < m_noCVars; i++) {
23198 cVariables(cellId, i) = a_variable(cellId, i);
23199 oldVariables(cellId, i) = a_oldVariable(cellId, i);
23200 }
23201 }
23202 if(domainId() == 0)
23203 cerr << "coupling check " << couplingCheck << " " << m_couplingRate << " " << couplingCheck / (DX * DX * DX)
23204 << " " << m_couplingRate / (DX * DX * DX) << " " << DX * m_couplingRate / POW3(DX * m_UInfinity) << endl;
23205
23206 // Apply volumetric filter
23207 if(maxRefinementLevel() != fftLevel) {
23208 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
23209 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
23210 if(a_isPeriodic(cellId)) continue;
23211 if(a_bndryId(cellId) < -1) continue;
23212 if(a_isHalo(cellId)) continue;
23213 if(a_level(cellId) != fftLevel) continue;
23214 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && c_noChildren(cellId) > 0) {
23215 reduceData(cellId, &coupling(0), nDim, false);
23216 reduceData(cellId, &(pVariables(0, 0)), m_noPVars);
23217 reduceData(cellId, &(cVariables(0, 0)), m_noCVars);
23218 reduceData(cellId, &(oldVariables(0, 0)), m_noCVars);
23219 }
23220 }
23221 }
23222
23223 MInt noLocDat = 0;
23224 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
23225 if(a_isHalo(cellId)) continue;
23226 if(a_isBndryGhostCell(cellId)) continue;
23227 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
23228 if(a_level(cellId) != fftLevel) continue;
23229 noLocDat++;
23230 }
23231 MFloatScratchSpace velDat(noLocDat, 3 * nDim, AT_, "velDat");
23232 MIntScratchSpace velPos(noLocDat, AT_, "velPos");
23233 noLocDat = 0;
23234 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
23235 if(a_isHalo(cellId)) continue;
23236 if(a_isBndryGhostCell(cellId)) continue;
23237 if(a_level(cellId) != fftLevel) continue;
23238 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
23239 MFloat actualCellLength = c_cellLengthAtCell(cellId);
23240 MInt xPos = floor((F1B2 * nx + (a_coordinate(cellId, 0) - F1B2 * (actualCellLength)) / dx) + 0.1);
23241 MInt yPos = floor((F1B2 * ny + (a_coordinate(cellId, 1) - F1B2 * (actualCellLength)) / dx) + 0.1);
23242 MInt zPos = floor((F1B2 * nz + (a_coordinate(cellId, 2) - F1B2 * (actualCellLength)) / dx) + 0.1);
23243 if(xPos > nx - 1 || xPos < 0 || yPos > ny - 1 || yPos < 0 || zPos > nz - 1 || zPos < 0) {
23244 cerr << "ERROR: wrong array position!" << endl;
23245 cerr << "pos=" << xPos << ", " << yPos << ", " << zPos << endl;
23246 cerr << "coorda = (" << a_coordinate(cellId, 0) << ", " << a_coordinate(cellId, 1) << ", "
23247 << a_coordinate(cellId, 2) << ")" << endl;
23248 cerr << "actuallength=" << actualCellLength << endl;
23249 cerr << "minlevel=" << minLevel() << ", maxLevel=" << maxLevel() << endl;
23250 cerr << "lenght on level0=" << c_cellLengthAtLevel(0) << endl;
23251 mTerm(1, AT_, "Wrong array position");
23252 }
23253 MInt pos = zPos + nz * (yPos + ny * xPos);
23254 for(MInt i = 0; i < nDim; i++) {
23255 velDat(noLocDat, i) = pVariables(cellId, PV->VV[i]) / m_UInfinity;
23256 velDat(noLocDat, nDim + i) = coupling(cellId, i) * DX / (grid().gridCellVolume(fftLevel) * POW2(m_UInfinity));
23257 MFloat u1 = cVariables(cellId, CV->RHO_VV[i]) / cVariables(cellId, CV->RHO);
23258 MFloat u0 = oldVariables(cellId, CV->RHO_VV[i]) / oldVariables(cellId, CV->RHO);
23259 velDat(noLocDat, 2 * nDim + i) = ((u1 - u0) / timeStep()) * DX / POW2(m_UInfinity);
23260 }
23262 for(MInt i = 0; i < nDim; i++) {
23263 velDat(noLocDat, nDim + i) =
23264 m_coupling[cellId][i] * (DX / (grid().gridCellVolume(fftLevel) * POW2(m_UInfinity)));
23265 }
23266 }
23267 velPos(noLocDat) = pos;
23268 noLocDat++;
23269 }
23270
23271 maia::math::computeEnergySpectrum(velDat, velPos, 3 * nDim, noLocDat, nx, ny, nz,
23272 F1 / (sysEqn().m_Re0 * DX * m_UInfinity), mpiComm());
23273
23274 RECORD_TIMER_STOP(t_fft);
23275 }
23276
23277 m_firstStats = false;
23278
23279 RECORD_TIMER_STOP(t_timertotal);
23280 DISPLAY_TIMER(t_timertotal);
23281}
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
Definition: context.cpp:538
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Definition: context.cpp:494
MFloat reduceData(const MInt cellId, MFloat *data, const MInt dataBlockSize=1, const MBool average=true)
determines the value of 'data' in the given cell by recusively volumetric averaging among all its off...
void leastSquaresReconstruction()
Least squares reconstruction.
static constexpr MFloat m_distThresholdStat[m_noMeanStatistics]
void computeSlipStatistics(const MIntScratchSpace &nearestBodies, const MFloatScratchSpace &nearestDist, const MFloat maxDistConstructed)
static constexpr MInt m_noMeanStatistics
void computeNearBodyFluidVelocity(const MIntScratchSpace &nearestBodies, const MFloatScratchSpace &nearestDist, MFloat *vel, MFloat *velGrad, MFloat *rotation, const std::vector< MFloat > &setup=std::vector< MFloat >(), MInt *skipBodies=nullptr, MFloat *meanBodyState=nullptr, MFloat *pressure=nullptr, MFloat *velDt=nullptr, MFloat *rotationDt=nullptr, MFloat *nearestFac=nullptr)
Mean parameters: near body data estimated by weighted filtering procedure All parameters after "setup...
void computeBodyVolume(MFloatScratchSpace &partVol)
static void crossProduct(MFloat *c, MFloat *a, MFloat *b)
computes the cross product c <- (a x b) for a, b, c in R^3
MInt constructDistance(const MFloat deltaMax, MIntScratchSpace &nearestBodies, MFloatScratchSpace &nearestDist)
MFloat m_oldMeanState[m_noMeanStatistics][4]
MFloat determineCoupling(MFloatScratchSpace &coupling)
std::vector< MInt > m_forceFVMBStatistics
MInt m_restartTimeStep
Definition: solver.h:80
MFloat m_Ma
the Mach number
Definition: solver.h:71
MInt minLevel() const
Read-only accessors for grid data.
std::basic_string< char > MString
Definition: maiatypes.h:55
int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Reduce
void computeEnergySpectrum(MFloatScratchSpace &velocity, MIntScratchSpace &indices, const ptrdiff_t howmany, MInt locSize, MInt nx, MInt ny, MInt nz, MFloat viscosity, const MPI_Comm comm)
Compute energy spectrum on unity cube.
Definition: maiafftw.h:1051

◆ computeForceCoefficients()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeForceCoefficients ( MFloat *&  forceCoefficients)
Author
Lennart Schneiders

Definition at line 21188 of file fvmbcartesiansolverxd.cpp.

21188 {
21189 cerr << "FvMbCartesianSolverXD::computeForceCoefficients(..) is empty. " << forceCoefficients[0] << endl;
21190}

◆ computeGhostCellsMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeGhostCellsMb
Author
Lennart Schneiders
  1. determine ghost cells for normal boundary cells and predicted boundary cells
  2. sets m_predictedGhostCellsOffset

Definition at line 19602 of file fvmbcartesiansolverxd.cpp.

19602 {
19603 TRACE();
19604
19605 MInt noOuterBndryGhostCells = 0;
19606 for(MInt bndryId = 0; bndryId < m_noOuterBndryCells; bndryId++) {
19607 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
19608 noOuterBndryGhostCells++;
19609 }
19610 }
19611 m_associatedInternalCells.resize(noOuterBndryGhostCells);
19612
19613 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
19614 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
19615 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = -1;
19616 }
19617 }
19618
19619 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
19620 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
19621
19622 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
19623 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19624 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19625
19626 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
19627 // append a cell to the fv-cell collectors
19628 m_cells.append();
19630
19631 MInt ghostCellId = a_noCells() - 1;
19632 m_associatedInternalCells.push_back(cellId);
19633
19634 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = ghostCellId;
19635
19636 a_cellVolume(ghostCellId) = grid().gridCellVolume(a_level(cellId));
19637 m_cellVolumesDt1[ghostCellId] = grid().gridCellVolume(a_level(cellId));
19638 a_FcellVolume(ghostCellId) = F1 / a_cellVolume(ghostCellId);
19639
19640 const MFloat cellLength = c_cellLengthAtLevel(a_level(cellId));
19641 const MFloat cellHalfLength = F1B2 * cellLength;
19642
19643 MFloat dn = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
19644
19645 for(MInt i = 0; i < nDim; i++) {
19646 a_coordinate(ghostCellId, i) =
19647 a_coordinate(cellId, i)
19648 - mMax(F2 * dn, dn + cellHalfLength) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVectorCentroid[i];
19649 }
19650
19651 for(MInt set0 = 0; set0 < m_noLevelSetsUsedForMb; set0++) {
19652 a_associatedBodyIds(ghostCellId, set0) = -1;
19653 }
19654 a_resetPropertiesSolver(ghostCellId);
19655 a_noReconstructionNeighbors(ghostCellId) = 0;
19656 a_level(ghostCellId) = a_level(cellId);
19657
19658 for(MInt var = 0; var < CV->noVariables; var++) {
19659 a_variable(ghostCellId, var) = a_variable(cellId, var);
19660 a_oldVariable(ghostCellId, var) = a_variable(cellId, var);
19661 a_pvariable(ghostCellId, var) = a_pvariable(cellId, var);
19662 for(MInt i = 0; i < nDim; i++)
19663 a_slope(ghostCellId, var, i) = F0;
19664 }
19665
19666 a_bndryId(ghostCellId) = -2;
19667 a_isBndryGhostCell(ghostCellId) = 1;
19668 ASSERT(a_level(ghostCellId) == a_level(getAssociatedInternalCell(ghostCellId)), "");
19669 }
19670 }
19671
19672 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
19673 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
19674 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
19675 // if ( a_hasProperty(cellId, SolverCell::IsNotGradient) ) continue;
19676 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19677 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19678 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
19679 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId < 0)
19680 mTerm(1, AT_, "Ghost cell missing.");
19681 }
19682 for(MInt srfc = 1; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
19683 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId
19684 == m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc - 1]->m_ghostCellId)
19685 mTerm(1, AT_, "Ghost cell duplicate.");
19686 }
19687 }
19688}

◆ computeLocalBoundingBox()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeLocalBoundingBox
Author

Definition at line 2296 of file fvmbcartesiansolverxd.cpp.

2296 {
2297 for(MInt i = 0; i < nDim; i++) {
2298 m_bboxLocal[i] = std::numeric_limits<MFloat>::max();
2299 m_bboxLocal[nDim + i] = std::numeric_limits<MFloat>::lowest();
2300 }
2301
2302 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
2303 if(a_isPeriodic(cellId)) continue;
2304
2305 for(MInt i = 0; i < nDim; i++) {
2306 m_bboxLocal[i] = mMin(m_bboxLocal[i], a_coordinate(cellId, i) - F1B2 * c_cellLengthAtCell(cellId));
2307 m_bboxLocal[nDim + i] = mMax(m_bboxLocal[nDim + i], a_coordinate(cellId, i) + F1B2 * c_cellLengthAtCell(cellId));
2308 }
2309 }
2310}

◆ computeNearBodyFluidVelocity()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeNearBodyFluidVelocity ( const MIntScratchSpace nearestBodies,
const MFloatScratchSpace nearestDist,
MFloat vel,
MFloat velGrad,
MFloat rotation,
const std::vector< MFloat > &  setup = std::vector<MFloat>(),
MInt skipBodies = nullptr,
MFloat meanBodyState = nullptr,
MFloat pressure = nullptr,
MFloat velDt = nullptr,
MFloat rotationDt = nullptr,
MFloat nearestFac = nullptr 
)
Author

Definition at line 23327 of file fvmbcartesiansolverxd.cpp.

23330 {
23331 TRACE();
23332
23333 if(m_noEmbeddedBodies == 0) return;
23334
23335 const MFloat minDist = (setup.size() >= 1 ? setup[0] : 0.5) * m_bodyDiameter[0];
23336 const MFloat maxDist = (setup.size() >= 2 ? setup[1] : 4.0) * m_bodyDiameter[0];
23337 const MFloat maxAngleVel = (setup.size() >= 3 ? setup[2] : F0);
23338 const MFloat maxAngleRot = (setup.size() >= 4 ? setup[3] : F0);
23339 const MFloat sigma = (setup.size() >= 5 ? setup[2] : (maxDist - minDist) / 6.0);
23340 const MFloat D0 = (setup.size() >= 6 ? setup[3] : (maxDist + minDist) / F2); // distance for peak weight
23341
23342 if(minDist > maxDist || maxAngleVel < -F1 || maxAngleRot < -F1) {
23343 cerr << "computeNearBodyFluidVelocity: wrong setup " << endl;
23344 return;
23345 }
23346
23347 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23348 for(MInt i = 0; i < nDim; i++) {
23349 vel[b * nDim + i] = F0;
23350 rotation[b * nDim + i] = F0;
23351 for(MInt j = 0; j < nDim; j++) {
23352 velGrad[b * nDim * nDim + i * nDim + j] = F0;
23353 }
23354 }
23355 }
23356
23357 if(nearestFac != NULL) {
23358 std::fill_n(nearestFac, m_maxNearestBodies * a_noCells(), F0);
23359 }
23360
23361 MFloatScratchSpace weights(m_noEmbeddedBodies, AT_, "weights");
23362 MFloatScratchSpace vel0((velDt || rotationDt || meanBodyState) ? m_noEmbeddedBodies : 1, nDim, AT_, "vel0");
23363 weights.fill(F0);
23364 vel0.fill(F0);
23365
23366 vector<vector<MInt>> velCells(m_noEmbeddedBodies);
23367 vector<vector<MInt>> rotCells(m_noEmbeddedBodies);
23368 MInt noLeafCells = 0;
23369 MIntScratchSpace leafCells(a_noCells(), AT_, "leafCells");
23370 MIntScratchSpace skipBody(m_noEmbeddedBodies, AT_, "skipBody");
23371
23372 {
23373 MInt cnt1 = 0;
23374 MInt cnt2 = 0;
23375 for(MInt bodyId = 0; bodyId < m_noEmbeddedBodies; bodyId++) {
23376 skipBody(bodyId) = 0;
23377 MFloat hydroForceAbs = F0;
23378 for(MInt i = 0; i < nDim; i++) {
23379 hydroForceAbs += POW2(m_hydroForce[bodyId * nDim + i]);
23380 }
23381 if(hydroForceAbs < 1e-12) {
23382 skipBody(bodyId) = 1;
23383 cnt1++;
23384 }
23385 if(m_bodyInCollision[bodyId] > 0) {
23386 skipBody(bodyId) = 1;
23387 cnt2++;
23388 }
23389 }
23390 m_log << "computeNearBodyFluidVelocities: noBodies skipped (small Body force): " << cnt1 << " collision: " << cnt2
23391 << " " << minDist / m_bodyDiameter[0] << " " << maxDist / m_bodyDiameter[0] << " " << maxAngleVel << endl;
23392 }
23393
23394 MLong smallGradPhi = 0;
23395 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
23396 if(a_isBndryGhostCell(cellId)) continue;
23397 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && c_noChildren(cellId) > 0) continue;
23398 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
23399 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
23400 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
23401 if(a_hasProperty(cellId, SolverCell::IsSplitChild) ? a_hasProperty(getAssociatedInternalCell(cellId), Cell::IsHalo)
23403 continue;
23404 if(a_hasProperty(cellId, SolverCell::IsSplitChild) ? a_isPeriodic(getAssociatedInternalCell(cellId))
23405 : a_isPeriodic(cellId))
23406 continue;
23407 leafCells(noLeafCells++) = cellId;
23408 for(MInt nb = 0; nb < m_maxNearestBodies; nb++) {
23409 const MInt bodyId0 = nearestBodies[m_maxNearestBodies * cellId + nb];
23410 if(bodyId0 < 0) continue;
23411 const MInt bodyId = m_internalBodyId[bodyId0];
23412 if(skipBody(bodyId)) continue;
23413 const MFloat phi = nearestDist[m_maxNearestBodies * cellId + nb];
23414 if(phi > minDist && phi < maxDist) {
23415 MFloat gradPhi[3] = {F0, F0, F0};
23416 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
23417 cerr << "debug state splitChild in CNBFV 1"
23418 << " remove this message, if it was reached and everything went fine" << endl;
23419 MInt splitChildBndryId = a_bndryId(cellId);
23420 if(m_bndryCells->a[splitChildBndryId].m_noSrfcs > 1)
23421 cerr << "SplitChilds due to collision should not appear here." << endl;
23422 for(MInt i = 0; i < nDim; i++) {
23423 gradPhi[i] = m_fvBndryCnd->m_bndryCells->a[splitChildBndryId].m_srfcs[0]->m_normalVector[i];
23424 }
23425 } else {
23426 for(MInt i = 0; i < nDim; i++) {
23427 MInt n0 = (a_hasNeighbor(cellId, 2 * i, false) > 0) ? c_neighborId(cellId, 2 * i, false) : cellId;
23428 MInt n1 = (a_hasNeighbor(cellId, 2 * i + 1, false) > 0) ? c_neighborId(cellId, 2 * i + 1, false) : cellId;
23429 if(n0 > -1 && n1 > -1) {
23430 MInt nb0, nb1;
23431 for(nb0 = 0; nb0 < m_maxNearestBodies; nb0++) {
23432 if(nearestBodies[m_maxNearestBodies * n0 + nb0] == bodyId0) break;
23433 }
23434 for(nb1 = 0; nb1 < m_maxNearestBodies; nb1++) {
23435 if(nearestBodies[m_maxNearestBodies * n1 + nb1] == bodyId0) break;
23436 }
23437 if(nb0 < m_maxNearestBodies && nb1 < m_maxNearestBodies) {
23438 gradPhi[i] = (nearestDist[m_maxNearestBodies * n1 + nb1] - nearestDist[m_maxNearestBodies * n0 + nb0])
23439 / (a_coordinate(n1, i) - a_coordinate(n0, i));
23440 }
23441 }
23442 }
23443 }
23444 MFloat distDotVelGuess = F0;
23445 MFloat gradPhiAbs = F0;
23446 MFloat hydroForceAbs = F0;
23447 for(MInt i = 0; i < nDim; i++) {
23448 distDotVelGuess += gradPhi[i] * m_hydroForce[bodyId * nDim + i];
23449 gradPhiAbs += POW2(gradPhi[i]);
23450 hydroForceAbs += POW2(m_hydroForce[bodyId * nDim + i]);
23451 }
23452 if(gradPhiAbs < 1e-12) {
23453 smallGradPhi++;
23454 continue;
23455 }
23456 MFloat angle = distDotVelGuess / sqrt(gradPhiAbs * hydroForceAbs);
23457 if(angle < maxAngleVel) {
23458 MFloat velWeight = a_cellVolume(cellId);
23459 MFloat distanceBasedWeight = F1 / sqrt(F2 * PI * POW2(sigma)) * exp(-POW2(phi - D0) / (F2 * POW2(sigma)));
23460 velWeight *= distanceBasedWeight;
23461 weights(bodyId) += velWeight;
23462 for(MInt i = 0; i < nDim; i++) {
23463 vel[bodyId * nDim + i] += velWeight * a_pvariable(cellId, PV->VV[i]);
23464 }
23465 if(nearestFac != NULL) {
23466 nearestFac[m_maxNearestBodies * cellId + nb] += velWeight;
23467 }
23468 velCells[bodyId].push_back(cellId);
23469 if(velDt || rotationDt || meanBodyState) {
23470 for(MInt i = 0; i < nDim; i++) {
23471 vel0(bodyId, i) += velWeight * a_oldVariable(cellId, CV->RHO_VV[i]) / a_oldVariable(cellId, CV->RHO);
23472 }
23473 }
23474 }
23475 if(distDotVelGuess / sqrt(gradPhiAbs * hydroForceAbs) < maxAngleRot) {
23476 rotCells[bodyId].push_back(cellId);
23477 }
23478 }
23479 }
23480 }
23481
23482 MLong globalSmallGradPhi = 0;
23483 MPI_Reduce(&smallGradPhi, &globalSmallGradPhi, 1, MPI_LONG, MPI_SUM, 0, mpiComm(), AT_, "smallGradPhi",
23484 "globalSmallGradPhi");
23485 if(globalSmallGradPhi > 0) {
23486 m_log << "Skipping cells for nearBodyFluidVelocities (small gradPhi) " << globalSmallGradPhi << " "
23487 << minDist / m_bodyDiameter[0] << " " << maxDist / m_bodyDiameter[0] << " " << maxAngleVel << endl;
23488 }
23489
23490 MPI_Allreduce(MPI_IN_PLACE, &vel[0], nDim * m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23491 "vel[0]");
23492 MPI_Allreduce(MPI_IN_PLACE, &weights[0], m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23493 "weights[0]");
23494
23495 if(velDt || rotationDt || meanBodyState) {
23496 MPI_Allreduce(MPI_IN_PLACE, &vel0[0], nDim * m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
23497 "MPI_IN_PLACE", "vel0[0]");
23498 }
23499
23500 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23501 if((weights(b) < 1e-10) && !skipBody(b)) {
23502 if(domainId() == 0)
23503 cerr << setprecision(12) << "Warning: near body velocity interpolation " << b << " " << weights(b) << " "
23504 << minDist / m_bodyDiameter[0] << " " << maxDist / m_bodyDiameter[0] << " " << maxAngleVel << endl;
23505 skipBody(b) = 1;
23506 }
23507 for(MInt i = 0; i < nDim; i++) {
23508 vel[b * nDim + i] /= mMax(1e-10, weights(b));
23509 if(velDt || rotationDt || meanBodyState) vel0(b, i) /= mMax(1e-10, weights(b));
23510 }
23511 }
23512 if(velDt) {
23513 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23514 for(MInt i = 0; i < nDim; i++) {
23515 velDt[b * nDim + i] = vel0(b, i);
23516 }
23517 }
23518 }
23519
23520 if(nearestFac != NULL) {
23521 for(MInt c = 0; c < noLeafCells; c++) {
23522 MInt cellId = leafCells(c);
23523 for(MInt nb = 0; nb < m_maxNearestBodies; nb++) {
23524 const MInt bodyId0 = nearestBodies[m_maxNearestBodies * cellId + nb];
23525 if(bodyId0 < 0) continue;
23526 const MInt bodyId = m_internalBodyId[bodyId0];
23527 nearestFac[m_maxNearestBodies * cellId + nb] /= weights(bodyId);
23528 }
23529 }
23530 }
23531
23532 weights.fill(F0);
23533 for(MInt bodyId = 0; bodyId < m_noEmbeddedBodies; bodyId++) {
23534 for(auto const& cellId : rotCells[bodyId]) {
23535 MInt bodyId0 = -1;
23536 MFloat phi = F0;
23537 for(MInt nb = 0; nb < m_maxNearestBodies; nb++) {
23538 if(nearestBodies[m_maxNearestBodies * cellId + nb] > -1
23539 && m_internalBodyId[nearestBodies[m_maxNearestBodies * cellId + nb]] == bodyId) {
23540 bodyId0 = nearestBodies[m_maxNearestBodies * cellId + nb];
23541 phi = nearestDist[m_maxNearestBodies * cellId + nb];
23542 if(bodyId0 < 0)
23543 cerr << "bodyId not found " << bodyId0 << " bodyId " << bodyId << " domainId() " << domainId() << endl;
23544 MFloat gradPhi[3] = {F0, F0, F0};
23545 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
23546 cerr << "debug state splitChild in CNBFV 2"
23547 << " remove this message, if it was reached and everything went fine" << endl;
23548 MInt splitChildBndryId = a_bndryId(cellId);
23549 if(m_bndryCells->a[splitChildBndryId].m_noSrfcs > 1)
23550 cerr << "SplitChilds due to collision should not appear here." << endl;
23551 for(MInt i = 0; i < nDim; i++) {
23552 gradPhi[i] = m_fvBndryCnd->m_bndryCells->a[splitChildBndryId].m_srfcs[0]->m_normalVector[i];
23553 }
23554 } else {
23555 for(MInt i = 0; i < nDim; i++) {
23556 MInt n0 = (a_hasNeighbor(cellId, 2 * i, false) > 0) ? c_neighborId(cellId, 2 * i, false) : cellId;
23557 MInt n1 = (a_hasNeighbor(cellId, 2 * i + 1, false) > 0) ? c_neighborId(cellId, 2 * i + 1, false) : cellId;
23558 if(n0 == n1) cerr << "wrong neighbors" << endl;
23559 if(n0 > -1 && n1 > -1) {
23560 MInt nb0, nb1;
23561 for(nb0 = 0; nb0 < m_maxNearestBodies; nb0++) {
23562 if(nearestBodies[m_maxNearestBodies * n0 + nb0] == bodyId0) break;
23563 }
23564 for(nb1 = 0; nb1 < m_maxNearestBodies; nb1++) {
23565 if(nearestBodies[m_maxNearestBodies * n1 + nb1] == bodyId0) break;
23566 }
23567 if(nb0 < m_maxNearestBodies && nb1 < m_maxNearestBodies) {
23568 gradPhi[i] = (nearestDist[m_maxNearestBodies * n1 + nb1] - nearestDist[m_maxNearestBodies * n0 + nb0])
23569 / (a_coordinate(n1, i) - a_coordinate(n0, i));
23570 }
23571 }
23572 }
23573 }
23574
23575 MFloat gradPhiAbs = F0;
23576 for(MInt i = 0; i < nDim; i++) {
23577 gradPhiAbs += POW2(gradPhi[i]);
23578 }
23579 if(gradPhiAbs < 1e-12) {
23580 continue;
23581 }
23582 MFloat rot[3]{};
23583 MFloat rot0[3]{};
23584 MFloat rad[3]{};
23585 MFloat rad0[3]{};
23586 MFloat vpr[3]{};
23587 MFloat vpr0[3]{};
23588 MFloat r2 = F0;
23589 MFloat r20 = F0;
23590 MFloat rotWeight = a_cellVolume(cellId);
23591 MFloat distanceBasedWeight = F1 / sqrt(F2 * PI * POW2(sigma)) * exp(-POW2(phi - D0) / (F2 * POW2(sigma)));
23592 rotWeight *= distanceBasedWeight;
23593 for(MInt i = 0; i < nDim; i++) {
23594 rad[i] = a_coordinate(cellId, i) - m_bodyCenter[bodyId0 * nDim + i];
23595 vpr[i] = a_pvariable(cellId, PV->VV[i]) - vel[bodyId * nDim + i];
23596 r2 += POW2(rad[i]);
23597 for(MInt j = 0; j < nDim; j++) {
23598 velGrad[bodyId * nDim * nDim + i * nDim + j] += rotWeight * a_slope(cellId, PV->VV[i], j);
23599 }
23600 }
23601 crossProduct(rot, rad, vpr);
23602 for(MInt i = 0; i < nDim; i++) {
23603 rotation[bodyId * nDim + i] += rotWeight * rot[i] / r2;
23604 }
23605 if(velDt || rotationDt || meanBodyState) {
23606 for(MInt i = 0; i < nDim; i++) {
23607 rad0[i] = a_coordinate(cellId, i)
23608 - (m_bodyCenter[bodyId0 * nDim + i] + m_bodyCenterDt1[bodyId * nDim + i]
23609 - m_bodyCenter[bodyId * nDim + i]);
23610 vpr0[i] = a_oldVariable(cellId, CV->RHO_VV[i]) / a_oldVariable(cellId, CV->RHO) - vel0(bodyId, i);
23611 r20 += POW2(rad0[i]);
23612 }
23613 crossProduct(rot0, rad0, vpr0);
23614 }
23615 if(rotationDt) {
23616 for(MInt i = 0; i < nDim; i++) {
23617 rotationDt[bodyId * nDim + i] += rotWeight * (rot0[i] / r20);
23618 }
23619 }
23620 weights(bodyId) += rotWeight;
23621 }
23622 }
23623 }
23624 }
23625
23626 MPI_Allreduce(MPI_IN_PLACE, &weights[0], m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23627 "weights[0]");
23628 MPI_Allreduce(MPI_IN_PLACE, &velGrad[0], nDim * nDim * m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
23629 "MPI_IN_PLACE", "velGrad[0]");
23630 MPI_Allreduce(MPI_IN_PLACE, &rotation[0], nDim * m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
23631 "MPI_IN_PLACE", "rotation[0]");
23632 if(rotationDt)
23633 MPI_Allreduce(MPI_IN_PLACE, &rotationDt[0], nDim * m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
23634 "MPI_IN_PLACE", "rotationDt[0]");
23635
23636 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23637 if(domainId() == 0 && weights(b) < 1e-10 && !skipBody(b)) {
23638 cerr << setprecision(12) << "Warning: near body velocity gradient interpolation " << b << " " << weights(b) << " "
23639 << minDist / m_bodyDiameter[0] << " " << maxDist / m_bodyDiameter[0] << " " << maxAngleRot << endl;
23640 }
23641 for(MInt i = 0; i < nDim; i++) {
23642 rotation[b * nDim + i] /= mMax(1e-10, weights(b));
23643 for(MInt j = 0; j < nDim; j++) {
23644 velGrad[b * nDim * nDim + i * nDim + j] /= mMax(1e-10, weights(b));
23645 }
23646 }
23647 }
23648
23649 if(rotationDt) {
23650 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23651 for(MInt i = 0; i < nDim; i++) {
23652 rotationDt[b * nDim + i] /= mMax(1e-10, weights(b));
23653 }
23654 }
23655 }
23656
23657 if(meanBodyState && pressure) {
23658 const MInt noNearBodyState = 5;
23659 weights.fill(F0);
23660 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23661 pressure[b] = F0;
23662 for(MInt i = 0; i < noNearBodyState; i++) {
23663 meanBodyState[noNearBodyState * b + i] = F0;
23664 }
23665 }
23666
23667 for(MInt c = 0; c < noLeafCells; c++) {
23668 MInt cellId = leafCells(c);
23669 for(MInt nb = 0; nb < m_maxNearestBodies; nb++) {
23670 const MInt bodyId0 = nearestBodies[m_maxNearestBodies * cellId + nb];
23671 if(bodyId0 < 0) continue;
23672 const MInt bodyId = m_internalBodyId[bodyId0];
23673 // if(skipBody(bodyId)) continue;
23674 const MFloat phi = nearestDist[m_maxNearestBodies * cellId + nb];
23675 MFloat weight = a_cellVolume(cellId);
23676 MFloat distanceBasedWeight = F1 / sqrt(F2 * PI * POW2(sigma)) * exp(-POW2(phi - D0) / (F2 * POW2(sigma)));
23677 weight *= distanceBasedWeight;
23678 pressure[bodyId] += weight * a_pvariable(cellId, PV->P);
23679 weights(bodyId) += weight;
23680 MFloat eps1 = F0;
23681 for(MInt i = 0; i < nDim; i++) {
23682 for(MInt j = 0; j < nDim; j++) {
23683 eps1 += F1B2 * (sysEqn().m_muInfinity / sysEqn().m_Re0)
23684 * POW2(a_slope(cellId, PV->VV[i], j) + a_slope(cellId, PV->VV[j], i));
23685 }
23686 }
23687
23688 if(phi < 0.5 * m_bodyDiameter[bodyId]) meanBodyState[noNearBodyState * bodyId] += a_cellVolume(cellId) * eps1;
23689 if(phi < 1.0 * m_bodyDiameter[bodyId])
23690 meanBodyState[noNearBodyState * bodyId + 1] += a_cellVolume(cellId) * eps1;
23691 if(phi < 1.5 * m_bodyDiameter[bodyId])
23692 meanBodyState[noNearBodyState * bodyId + 2] += a_cellVolume(cellId) * eps1;
23693 if(phi < 2.0 * m_bodyDiameter[bodyId])
23694 meanBodyState[noNearBodyState * bodyId + 3] += a_cellVolume(cellId) * eps1;
23695 if(phi < 2.5 * m_bodyDiameter[bodyId])
23696 meanBodyState[noNearBodyState * bodyId + 4] += a_cellVolume(cellId) * eps1;
23697 }
23698 }
23699
23700 MPI_Allreduce(MPI_IN_PLACE, &weights[0], m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23701 "weights[0]");
23702 MPI_Allreduce(MPI_IN_PLACE, &pressure[0], m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
23703 "pressure[0]");
23704 MPI_Allreduce(MPI_IN_PLACE, &meanBodyState[0], noNearBodyState * m_noEmbeddedBodies, MPI_DOUBLE, MPI_SUM, mpiComm(),
23705 AT_, "MPI_IN_PLACE", "meanBodyState[0]");
23706
23707 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23708 if(domainId() == 0 && weights(b) < 1e-10 && !skipBody(b)) {
23709 cerr << "Warning: near body pressure interpolation " << b << " " << weights(b) / m_bodyVolume[b] << " "
23710 << minDist / m_bodyDiameter[0] << " " << maxDist / m_bodyDiameter[0] << " " << maxAngleVel << endl;
23711 }
23712 pressure[b] /= mMax(1e-10, weights(b));
23713 }
23714 }
23715
23716 if(skipBodies) {
23717 MInt cnt = 0;
23718 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
23719 skipBodies[b] = skipBody(b);
23720 if(skipBody(b)) cnt++;
23721 }
23722 if(domainId() == 0 && cnt > 0 && globalTimeStep % m_dragOutputInterval == 0)
23723 m_log << "computeNearBodyFluidVelocities: noBodies skipped " << cnt << " (" << globalTimeStep << ")" << endl;
23724 }
23725}
typename maia::grid::tree::Tree< nDim >::Cell Cell

◆ computeNodalLSValues()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeNodalLSValues
Author
Lennart Schneiders, Update Tim Wegmann

Definition at line 5762 of file fvmbcartesiansolverxd.cpp.

5762 {
5763 TRACE();
5764
5765 MBool gapClosure = false;
5766 if(m_levelSet && m_closeGaps && (m_gapInitMethod > 0 || nDim == 3)) {
5767 gapClosure = true;
5768 }
5769
5770 // fill cutCandidates-Information!
5771 m_cutCandidates.clear();
5772
5773 for(MInt cnd = 0; cnd < m_noBndryCandidates; cnd++) {
5774 const MInt cellId = m_bndryCandidates[cnd];
5775 ASSERT(!a_isHalo(cellId), "");
5776 m_cutCandidates.emplace_back();
5777 m_cutCandidates[cnd].cellId = cellId;
5778 }
5779
5780
5781 MBoolScratchSpace isGapCell(a_noCells(), AT_, "isGapCell");
5782 isGapCell.fill(false);
5783 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
5784 if(a_isGapCell(cellId)) isGapCell[cellId] = true;
5785 }
5786
5788 &a_associatedBodyIds(0, 0), &isGapCell(0), gapClosure);
5789
5790 ASSERT((signed)m_cutCandidates.size() == m_noBndryCandidates, "");
5791
5792 ScratchSpace<const MInt*> p_maxLevelWindowCells(noNeighborDomains(), AT_, "p_maxLevelWindowCells");
5793 ScratchSpace<const MInt*> p_maxLevelHaloCells(noNeighborDomains(), AT_, "p_maxLevelHaloCells");
5794
5795 for(MInt d = 0; d < noNeighborDomains(); d++) {
5796 p_maxLevelWindowCells[d] = m_maxLevelWindowCells[d];
5797 p_maxLevelHaloCells[d] = m_maxLevelHaloCells[d];
5798 }
5799
5800 m_geometryIntersection->exchangeNodalValues(p_maxLevelWindowCells.data(), &m_noMaxLevelWindowCells[0],
5801 p_maxLevelHaloCells.data(), m_cutCandidates, &m_bndryCandidateIds[0]);
5802
5803 // Azimuthal periodicity
5804 if(grid().azimuthalPeriodicity()) {
5806 }
5807
5808 ASSERT((signed)m_cutCandidates.size() >= m_noBndryCandidates, "");
5809
5810 // fill fv-solver-structre
5811 m_noBndryCandidates = (signed)m_cutCandidates.size();
5812 m_bndryCandidates.clear();
5813
5816
5817 for(MInt cnd = 0; cnd < m_noBndryCandidates; cnd++) {
5818 const MInt cellId = m_cutCandidates[cnd].cellId;
5819 ASSERT(!m_cutCandidates[cnd].isbndryLvlJumpParent, "");
5820
5821 m_bndryCandidates.push_back(cellId);
5822
5823 for(MInt node = 0; node < m_noCellNodes; node++) {
5824 m_candidateNodeSet[cnd * m_noCellNodes + node] = m_cutCandidates[cnd].nodeValueSet[node];
5825 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
5826 m_candidateNodeValues[IDX_LSSETNODES(cnd, node, set)] = m_cutCandidates[cnd].nodalValues[set][node];
5827 }
5828 }
5830 }
5831}
void computeAzimuthalHaloNodalValues()
init exchange of nodal values of azimuthal periodic halo cells
void exchangeNodalValues(const MInt **maxLevelWindowCells, const MInt *noMaxLevelWindowCells, const MInt **maxLevelHaloCells, std::vector< CutCandidate< nDim > > &candidates, MInt *candidateIds)
halo cell - window cell exchange of nodal scalar field data

◆ computeNormal() [1/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
static MFloat FvMbCartesianSolverXD< nDim, SysEqn >::computeNormal ( const MFloat p0,
const MFloat p1,
const MFloat p2,
MFloat res,
MFloat w 
)
inlinestaticprivate
Author
Claudia Guenther, September 2013

Definition at line 1414 of file fvmbcartesiansolverxd.h.

1414 {
1415 const MFloat a0 = p1[0] - p0[0], a1 = p1[1] - p0[1], a2 = p1[2] - p0[2], b0 = p2[0] - p0[0], b1 = p2[1] - p0[1],
1416 b2 = p2[2] - p0[2];
1417 res[0] = a1 * b2 - a2 * b1;
1418 res[1] = a2 * b0 - a0 * b2;
1419 res[2] = a0 * b1 - a1 * b0;
1420 const MFloat abs = sqrt(res[0] * res[0] + res[1] * res[1] + res[2] * res[2]);
1421 res[0] /= abs;
1422 res[1] /= abs;
1423 res[2] /= abs;
1424 w = -res[0] * p0[0] - res[1] * p0[1] - res[2] * p0[2];
1425 return abs;
1426 }

◆ computeNormal() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
static void FvMbCartesianSolverXD< nDim, SysEqn >::computeNormal ( const MFloat p0,
const MFloat p1,
MFloat res,
MFloat w 
)
inlinestaticprivate
Author
Claudia Guenther, November 2013

Definition at line 1397 of file fvmbcartesiansolverxd.h.

1397 {
1398 const MFloat dx = p1[0] - p0[0];
1399 const MFloat dy = p1[1] - p0[1];
1400 res[0] = -dy;
1401 res[1] = dx;
1402 const MFloat abs = sqrt(res[0] * res[0] + res[1] * res[1]);
1403 res[0] /= abs;
1404 res[1] /= abs;
1405 w = -res[0] * p0[0] - res[1] * p0[1];
1406 }

◆ computeReconstructionConstants()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeReconstructionConstants
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 17256 of file fvmbcartesiansolverxd.cpp.

17256 {
17257 TRACE();
17258
17262
17263 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
17264
17265 // reset number of reconstruction Neighbors for all cells!
17266 a_noReconstructionNeighbors(cellId) = 0;
17267
17268 if(a_isBndryGhostCell(cellId)) continue;
17269 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17270 if(!a_hasProperty(cellId, SolverCell::IsFlux)) continue;
17271 if(a_bndryId(cellId) == -2) continue;
17272 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
17273 if(c_noChildren(cellId) > 0) continue;
17274 if(a_bndryId(cellId) > -1) {
17275 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_linkedCellId > -1) continue;
17276 }
17277 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17278
17279 // recompute number of reconstruction constants for relevant cells
17281 }
17282}
std::vector< MFloat > m_reconstructionConstants
void rebuildReconstructionConstants(MInt cellId)
computes the reconstruction constants using inverse distance weighted least squares

◆ computeRotationMatrix()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeRotationMatrix ( MFloatScratchSpace R,
MFloat q 
)
inlinestatic
Author
Lennart Schneiders

Definition at line 4133 of file fvmbcartesiansolverxd.cpp.

4133 {
4134 R(0, 0) = q[0] * q[0] + q[1] * q[1] - q[2] * q[2] - q[3] * q[3];
4135 R(1, 1) = q[0] * q[0] - q[1] * q[1] + q[2] * q[2] - q[3] * q[3];
4136 R(2, 2) = q[0] * q[0] - q[1] * q[1] - q[2] * q[2] + q[3] * q[3];
4137
4138 R(0, 1) = F2 * (q[1] * q[2] + q[0] * q[3]);
4139 R(0, 2) = F2 * (q[1] * q[3] - q[0] * q[2]);
4140 R(1, 0) = F2 * (q[1] * q[2] - q[0] * q[3]);
4141 R(1, 2) = F2 * (q[2] * q[3] + q[0] * q[1]);
4142 R(2, 0) = F2 * (q[1] * q[3] + q[0] * q[2]);
4143 R(2, 1) = F2 * (q[2] * q[3] - q[0] * q[1]);
4144}

◆ computeSlipStatistics()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeSlipStatistics ( const MIntScratchSpace nearestBodies,
const MFloatScratchSpace nearestDist,
const MFloat  maxDistConstructed 
)
Author

Definition at line 26450 of file fvmbcartesiansolverxd.cpp.

26452 {
26453 TRACE();
26454
26455 MInt noParticlesGlobal = mMax(m_noPointParticles, m_noEmbeddedBodies);
26456 if(noParticlesGlobal == 0) return;
26457 const MFloat DX = (m_bbox[nDim] - m_bbox[0]);
26458 const MFloat epsRef = DX / (POW3(m_UInfinity));
26460 MIntScratchSpace particleOffsets(noDomains() + 1, AT_, "particleOffsets");
26461 particleOffsets(0) = 0;
26462
26463 for(MLong dom = 0; dom < noDomains(); dom++) {
26464 MLong tmpv = (((MLong)noParticlesGlobal) * (dom + 1)) / ((MLong)noDomains());
26465 if(tmpv > numeric_limits<MInt>::max()) mTerm(1, "MInt overflow");
26466 particleOffsets(dom + 1) = (MInt)tmpv;
26467 }
26468 if(m_noEmbeddedBodies > 0) noParticles = particleOffsets(domainId() + 1) - particleOffsets(domainId());
26469
26470 // Memory for computeNearBodyFluidVelocity
26471 MFloatScratchSpace velMem(mMax(1, m_noEmbeddedBodies) * nDim, AT_, "velMem");
26472 MFloatScratchSpace velGradMem(mMax(1, m_noEmbeddedBodies) * nDim * nDim, AT_, "velGradMem");
26473 MFloatScratchSpace particleFluidRotationMem(mMax(1, m_noEmbeddedBodies), nDim, AT_, "particleFluidRotationMem");
26474 MIntScratchSpace skipBodies((m_noPointParticles > 0 ? 1 : m_noEmbeddedBodies), AT_, "skipBodies");
26475 // Memory for Lagrangian point-particles
26476 MFloatScratchSpace pointParticleForceMem(mMax(1, (m_noPointParticles > 0 ? noParticles : -1)), nDim, AT_,
26477 "pointParticleForceMem");
26478 MFloatScratchSpace pointParticleTorqueMem(mMax(1, (m_noPointParticles > 0 ? noParticles : -1)), nDim, AT_,
26479 "pointParticleTorqueMem");
26480 const MFloat distWidth = F1; // scaled with m_bodyDiameter[0]
26481 const MFloat minDistBound = 0.5;
26482 const MFloat maxDistBound = 2.5;
26483 const MFloat correctionBuffer = 1.0;
26484 const MFloat maxAngleBound = 0.5 + correctionBuffer;
26485 const MFloat minAngleBound = -0.5 + correctionBuffer;
26486 const MInt noAngleSetups = (m_noPointParticles > 0 ? 1 : 3);
26487 const MInt noDistSetups = (m_noPointParticles > 0 ? 1 : 3);
26488 struct gradRot {
26489 MFloat grad = F0;
26490 MFloat rotation = F0;
26491 };
26492 for(MInt i = 0; i < noAngleSetups; i++) {
26493 MFloat maxAngle = (maxAngleBound - minAngleBound) / mMax((MFloat)noAngleSetups - 1, F1) * i + minAngleBound;
26494 maxAngle -= correctionBuffer;
26495 if(m_noPointParticles > 0) maxAngle = 1.0;
26496 for(MInt j = 0; j < noDistSetups; j++) {
26497 MFloat* fluidVel = nullptr;
26498 MFloat* fluidVelGrad = nullptr;
26499 MFloat* fluidRotation = nullptr;
26500 MFloat* particleVelocity = nullptr;
26501 MFloat* particleAngularVelocity = nullptr;
26502 MFloat* particleQuaternion = nullptr;
26503 MFloat* particleForce = nullptr;
26504 MFloat* particleTorque = nullptr;
26505 MFloat minDist = F1;
26506 MFloat maxDist = F1;
26507 if(m_noEmbeddedBodies > 0) {
26508 minDist = (maxDistBound - minDistBound) / mMax((MFloat)noDistSetups - 1, F1) * j
26509 + minDistBound; // distances are scaled with body diameter afterwards
26510 maxDist = minDist + distWidth;
26511 if(maxDist * m_bodyDiameter[0] > maxDistConstructed && domainId() == 0)
26512 cerr << "Warning slip statistics: maxDist " << maxDist << " exceeds maxDistConstructed " << maxDistConstructed
26513 << endl;
26514 vector<MFloat> setup = {minDist, maxDist, maxAngle, maxAngle}; // use the same angles for velocity and rotation
26515 fluidVel = &velMem[0];
26516 fluidVelGrad = &velGradMem[0];
26517 fluidRotation = &particleFluidRotationMem[0];
26518 particleVelocity = &m_bodyVelocity[0];
26519 particleAngularVelocity = &m_bodyAngularVelocity[0];
26520 particleQuaternion = &m_bodyQuaternion[0];
26521 particleForce = &m_hydroForce[0];
26522 particleTorque = &m_bodyTorque[0];
26523 computeNearBodyFluidVelocity(nearestBodies, nearestDist, &fluidVel[0], &fluidVelGrad[0], &fluidRotation[0],
26524 setup, &skipBodies[0]);
26525 } else if(m_noPointParticles > 0) {
26527 fluidVel = &(m_particleVelocityFluid[0]);
26528 fluidVelGrad = &(m_particleVelocityGradientFluid[0]);
26529 particleVelocity = &m_particleVelocity[0];
26530 particleAngularVelocity = &m_particleAngularVelocity[0];
26531 particleQuaternion = &m_particleQuaternions[0];
26532 for(MInt p = 0; p < noParticles; p++) {
26533 const MFloat pmass = F4B3 * PI * m_particleRadii[3 * p] * m_particleRadii[3 * p + 1]
26535 const MFloat Ix = F1B5 * (POW2(m_particleRadii[3 * p + 1]) + POW2(m_particleRadii[3 * p + 2])) * pmass;
26536 const MFloat Iy = F1B5 * (POW2(m_particleRadii[3 * p + 0]) + POW2(m_particleRadii[3 * p + 2])) * pmass;
26537 const MFloat Iz = F1B5 * (POW2(m_particleRadii[3 * p + 0]) + POW2(m_particleRadii[3 * p + 1])) * pmass;
26538 const MFloat momI[3] = {Ix, Iy, Iz};
26539 for(MInt dim = 0; dim < nDim; dim++) {
26540 MInt id0 = (dim + 1) % 3;
26541 MInt id1 = (id0 + 1) % 3;
26542 pointParticleForceMem[nDim * p + dim] = pmass * m_particleAcceleration[nDim * p + dim];
26543 pointParticleTorqueMem[nDim * p + dim] = momI[dim] * m_particleAngularAcceleration[3 * p + dim];
26544 particleFluidRotationMem[nDim * p + dim] =
26545 F1B2 * (fluidVelGrad[9 * p + 3 * id1 + id0] - fluidVelGrad[9 * p + 3 * id0 + id1]);
26546 }
26547 }
26548 particleForce = &pointParticleForceMem[0];
26549 particleTorque = &pointParticleTorqueMem[0];
26550 fluidRotation = &particleFluidRotationMem[0];
26551 }
26552
26553 // Generate time resolved statistics using particle slip data here
26554 MInt cnt = 0;
26555 MFloat meanPartVel = F0;
26556 MFloat meanPartAngularVel = F0;
26557 MFloat Rep = F0;
26558 MFloat lin_diss = F0;
26559 MFloat FUf = F0;
26560 MFloat FVp = F0;
26561 gradRot nearParticleRot;
26562 gradRot rot_diss;
26563 gradRot meanOmega;
26564 gradRot meanOmegaRel;
26565 gradRot TOmegaF;
26566 MFloat TOmegaP = F0;
26567 for(MInt p = 0; p < noParticles; p++) {
26568 if(m_noEmbeddedBodies > 0) {
26569 p += particleOffsets(domainId());
26570 if(skipBodies[p]) continue;
26571 }
26572 const MFloat refRad =
26574 ? pow(m_particleRadii[3 * p + 0] * m_particleRadii[3 * p + 1] * m_particleRadii[3 * p + 2], F1B3)
26575 : pow(m_bodyRadii[nDim * p + 0] * m_bodyRadii[nDim * p + 1] * m_bodyRadii[nDim * p + 2], F1B3));
26576 const MFloat diameter = F2 * refRad;
26577 MFloat partVel = F0;
26578 MFloat partAngularVel = F0;
26579 MFloat omegaGrad = F0;
26580 MFloat omegaRotation = F0;
26581 MFloat omegaRelGrad = F0;
26582 MFloat meanOmegaRelRotation = F0;
26583 MFloat vrelAbs = F0;
26584 vector<MFloat> vrel(nDim);
26585 vector<gradRot> omegaRel(nDim);
26586 for(MInt dim = 0; dim < nDim; dim++) {
26587 vrel[dim] = fluidVel[nDim * p + dim] - particleVelocity[nDim * p + dim];
26588 vrelAbs += POW2(vrel[dim]);
26589 lin_diss += particleForce[nDim * p + dim] * vrel[dim];
26590 partVel += POW2(particleVelocity[nDim * p + dim]);
26591 FUf += particleForce[p * nDim + dim] * fluidVel[nDim * p + dim];
26592 FVp += particleForce[p * nDim + dim] * particleVelocity[nDim * p + dim];
26593
26594 // rotationional dynamics
26595 MInt id0 = (dim + 1) % nDim;
26596 MInt id1 = (id0 + 1) % nDim;
26597 nearParticleRot.grad =
26598 F1B2
26599 * (fluidVelGrad[POW2(nDim) * p + nDim * id1 + id0] - fluidVelGrad[POW2(nDim) * p + nDim * id0 + id1]);
26600 nearParticleRot.rotation = fluidRotation[p * nDim + dim];
26601 omegaRel[dim].grad = nearParticleRot.grad - particleAngularVelocity[p * nDim + dim];
26602 omegaRel[dim].rotation = nearParticleRot.rotation - particleAngularVelocity[p * nDim + dim];
26603 rot_diss.grad += particleTorque[nDim * p + dim] * omegaRel[dim].grad;
26604 rot_diss.rotation += particleTorque[nDim * p + dim] * omegaRel[dim].rotation;
26605 omegaGrad += POW2(nearParticleRot.grad);
26606 omegaRotation += POW2(nearParticleRot.rotation);
26607 omegaRelGrad += POW2(omegaRel[dim].grad);
26608 meanOmegaRelRotation += POW2(omegaRel[dim].rotation);
26609 partAngularVel += POW2(particleAngularVelocity[p * nDim + dim]);
26610 TOmegaF.grad += particleTorque[nDim * p + dim] * nearParticleRot.grad;
26611 TOmegaF.rotation += particleTorque[nDim * p + dim] * nearParticleRot.rotation;
26612 TOmegaP += particleTorque[nDim * p + dim] * particleAngularVelocity[p * nDim + dim];
26613 }
26614 meanPartVel += sqrt(partVel);
26615 meanPartAngularVel += sqrt(partAngularVel);
26616 meanOmega.grad += sqrt(omegaGrad);
26617 meanOmega.rotation += sqrt(omegaRotation);
26618 meanOmegaRel.grad += sqrt(omegaRelGrad);
26619 meanOmegaRel.rotation += sqrt(meanOmegaRelRotation);
26620 Rep += sqrt(vrelAbs) * diameter * m_rhoInfinity * sysEqn().m_Re0 / sysEqn().m_muInfinity;
26621 cnt++;
26622 }
26623
26624 vector<MFloat> communicateData = {lin_diss,
26625 FUf,
26626 FVp,
26627 rot_diss.grad,
26628 rot_diss.rotation,
26629 meanPartVel,
26630 Rep,
26631 meanOmega.grad,
26632 meanOmega.rotation,
26633 meanOmegaRel.grad,
26634 meanOmegaRel.rotation,
26635 meanPartAngularVel,
26636 TOmegaF.grad,
26637 TOmegaF.rotation,
26638 TOmegaP};
26639 MPI_Allreduce(MPI_IN_PLACE, &cnt, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "cnt");
26640 MPI_Allreduce(MPI_IN_PLACE, communicateData.data(), communicateData.size(), MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
26641 "MPI_IN_PLACE", "communicateData.data()");
26642 MUint id = 0;
26643 lin_diss = (epsRef / POW3(DX)) * communicateData[id++];
26644 FUf = (epsRef / POW3(DX)) * communicateData[id++];
26645 FVp = (epsRef / POW3(DX)) * communicateData[id++];
26646 rot_diss.grad = (epsRef / POW3(DX)) * communicateData[id++];
26647 rot_diss.rotation = (epsRef / POW3(DX)) * communicateData[id++];
26648 meanPartVel = communicateData[id++] / (m_UInfinity * cnt);
26649 Rep = communicateData[id++];
26650 meanOmega.grad = (DX / (m_UInfinity * cnt)) * communicateData[id++];
26651 meanOmega.rotation = (DX / (m_UInfinity * cnt)) * communicateData[id++];
26652 meanOmegaRel.grad = (DX / (m_UInfinity * cnt)) * communicateData[id++];
26653 meanOmegaRel.rotation = (DX / (m_UInfinity * cnt)) * communicateData[id++];
26654 meanPartAngularVel = (DX / (m_UInfinity * cnt)) * communicateData[id++];
26655 TOmegaF.grad = (epsRef / POW3(DX)) * communicateData[id++];
26656 TOmegaF.rotation = (epsRef / POW3(DX)) * communicateData[id++];
26657 TOmegaP = (epsRef / POW3(DX)) * communicateData[id++];
26658
26659 if(id != communicateData.size()) mTerm(1, AT_, "Communication messed up in slipStatistics;");
26660 if(domainId() == 0) {
26661 ofstream ofl;
26662 ofl.open("slipStatistics_angle_" + to_string(maxAngle) + "_minDist_" + to_string(minDist),
26663 ios_base::out | ios_base::app);
26664 MString seperator = " ";
26665 if(ofl.is_open() && ofl.good()) {
26667 ofl << "# 1:ts 2:time 3:physicalTime "
26668 << " 4:maxAngle 5:minDist 6:maxDist 7:noBodies "
26669 << " 8:Rep(m)"
26670 << " 9:linDiss(m)"
26671 << " 10:rotDiss(G) 11:rotDiss(R)"
26672 << " 12:meanOmega(G) 13:meanOmega(R)"
26673 << " 14:meanOmegaRel(G) 15:meanOmega(R)"
26674 << " 16:meanPartVel 17:meanPartAngularVal "
26675 << " 18:F*U_f(m) 19:F*v_P "
26676 << " 20:T*O_f(G) 21:T*O_f(R) 22:T*O_p "
26677 << " " << endl;
26678 m_printHeaderSlip = false;
26679 }
26680 ofl << globalTimeStep << " " << m_time << " " << m_physicalTime << seperator << " " << maxAngle << " "
26681 << minDist << " " << maxDist << " " << cnt << seperator << " " << Rep / MFloat(cnt) << " " << lin_diss
26682 << " " << rot_diss.grad << " " << rot_diss.rotation << " " << meanOmega.grad << " " << meanOmega.rotation
26683 << " " << meanOmegaRel.grad << " " << meanOmegaRel.rotation << " " << meanPartVel << " "
26684 << meanPartAngularVel << " " << FUf << " " << FVp << " " << TOmegaF.grad << " " << TOmegaF.rotation << " "
26685 << TOmegaP << endl;
26686 ofl.close();
26687 }
26688 }
26689
26690 if(m_saveSlipInterval > 0) {
26691 MInt noTimeStepsSaved = m_slipDataTimeSteps.size();
26692 for(MInt p = 0; p < noParticles; p++) {
26693 MInt globalPId = p + particleOffsets(domainId());
26694 if(i == 0 && j == 0) {
26695 for(MInt dim = 0; dim < nDim; dim++) {
26696 m_slipDataParticleVel[nDim * noParticles * noTimeStepsSaved + p * nDim + dim] =
26697 (!(skipBodies[globalPId] == 1) ? particleVelocity[globalPId * nDim + dim] : -1234);
26698 m_slipDataParticleForce[nDim * noParticles * noTimeStepsSaved + p * nDim + dim] =
26699 (!(skipBodies[globalPId] == 1) ? particleForce[globalPId * nDim + dim] : -1234);
26700 m_slipDataParticlePosition[nDim * noParticles * noTimeStepsSaved + p * nDim + dim] =
26701 m_bodyCenter[globalPId * nDim + dim];
26702 }
26703 for(MInt dim = 0; dim < 4; dim++) {
26704 m_slipDataParticleQuaternion[4 * noParticles * noTimeStepsSaved + p * 4 + dim] =
26705 (!(skipBodies[globalPId] == 1) ? particleQuaternion[globalPId * 4 + dim] : -1234);
26706 }
26707 for(MInt dim = 0; dim < nDim; dim++) {
26708 m_slipDataParticleAngularVel[nDim * noParticles * noTimeStepsSaved + p * nDim + dim] =
26709 (!(skipBodies[globalPId] == 1) ? particleAngularVelocity[globalPId * nDim + dim] : -1234);
26710 m_slipDataParticleTorque[nDim * noParticles * noTimeStepsSaved + p * nDim + dim] =
26711 (!(skipBodies[globalPId] == 1) ? particleTorque[globalPId * nDim + dim] : -1234);
26712 }
26713 }
26714 for(MInt dim = 0; dim < nDim; dim++) {
26715 m_slipDataParticleFluidVel[noTimeStepsSaved * noParticles * nDim * m_noDistSetups * m_noAngleSetups
26717 + j * nDim + dim] =
26718 (!(skipBodies[globalPId] == 1) ? fluidVel[globalPId * nDim + dim] : -1234);
26719 m_slipDataParticleFluidVelRot[noTimeStepsSaved * noParticles * nDim * m_noDistSetups * m_noAngleSetups
26721 + j * nDim + dim] =
26722 (!(skipBodies[globalPId] == 1) ? fluidRotation[globalPId * nDim + dim] : -1234);
26723 }
26724 for(MInt dim = 0; dim < POW2(nDim); dim++) {
26725 m_slipDataParticleFluidVelGrad[noTimeStepsSaved * noParticles * POW2(nDim) * m_noDistSetups
26728 + i * POW2(nDim) * m_noDistSetups + j * POW2(nDim) + dim] =
26729 (!(skipBodies[globalPId] == 1) ? fluidVelGrad[globalPId * POW2(nDim) + dim] : -1234);
26730 }
26731 }
26732 }
26733 }
26734 }
26735 if(m_saveSlipInterval > 0) {
26737 }
26738}
static constexpr MInt m_noAngleSetups
static constexpr MInt m_noDistSetups
MBool m_restart
Definition: solver.h:97

◆ computeTimeStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeTimeStep ( )

◆ computeVolumeFraction()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::computeVolumeFraction
Note
{includes extra treatment for extremely small 3D cut-cells}
Author
Lennart Schneiders

Definition at line 11051 of file fvmbcartesiansolverxd.cpp.

11051 {
11052 TRACE();
11053
11054 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
11055 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
11056 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
11057
11058 a_cellVolume(cellId) = mMax(m_volumeThreshold, m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume);
11059 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
11060 m_volumeFraction[bndryId] = mMax(m_volumeThreshold, m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume)
11061 / grid().gridCellVolume(a_level(cellId));
11062 }
11063}

◆ compVolumeIntegrals()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::compVolumeIntegrals ( std::vector< polyCutCell > *  cutCells,
std::vector< polyEdge2D > *  edges,
const std::vector< polyVertex > *  vertices 
)
private
Author

Definition at line 31619 of file fvmbcartesiansolverxd.cpp.

31621 {
31622 MInt A = 0, B = 1;
31623
31624 for(MInt cC = 0; (unsigned)cC < cutCells->size(); cC++) {
31625 polyCutCell* cutCell = &(*cutCells)[cC];
31626
31627 compFaceIntegrals(cutCell, edges, vertices, A, B);
31628 }
31629}
void compFaceIntegrals(polyCutCell *, std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt, MInt)

◆ constructDistance()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::constructDistance ( const MFloat  deltaMax,
MIntScratchSpace nearestBodies,
MFloatScratchSpace nearestDist 
)
Author
Lennart Schneiders

Definition at line 2504 of file fvmbcartesiansolverxd.cpp.

2505 {
2506 TRACE();
2507
2508 if(!m_constructGField) mTerm(1, AT_, "m_constructGField not set.");
2509 if(m_noEmbeddedBodies == 0) {
2510 return 0;
2511 }
2512
2513 if(m_bodyTypeMb) {
2515
2516 MFloatScratchSpace bodyDist(noBodies, AT_, "bodyDist");
2517 MIntScratchSpace bodyIds(noBodies, AT_, "bodyIds");
2518
2519 constexpr MFloat safetyFac = 1.1;
2520 const MFloat deltaMax1 = safetyFac * (deltaMax + c_cellLengthAtLevel(minLevel()) + m_maxBodyRadius);
2521 bodyDist.fill(deltaMax1);
2522 bodyIds.fill(-1);
2523
2524 MInt maxBodyCnt = 0;
2525 for(MInt i = 0; i < noMinCells(); i++) {
2526 MInt cellId = minCell(i);
2527 MInt bodyCnt = noBodies;
2528 IF_CONSTEXPR(nDim == 3) {
2529 if(m_bodyTypeMb == 1 || m_bodyTypeMb == 3) {
2530 MBool overflow = false;
2531 Point<nDim> pt(a_coordinate(cellId, 0), a_coordinate(cellId, 1), a_coordinate(cellId, 2));
2532 if(deltaMax1 < m_bodyDistThreshold) {
2533 bodyCnt = m_bodyTreeLocal->locatenearest(pt, deltaMax1, &bodyIds[0], &bodyDist[0], noBodies, overflow);
2534 } else {
2535 bodyCnt = m_bodyTree->locatenearest(pt, deltaMax1, &bodyIds[0], &bodyDist[0], noBodies, overflow);
2536 }
2537 } else {
2538 for(MInt k = 0; k < noBodies; k++) {
2539 bodyIds[k] = k;
2540 }
2541 }
2542 }
2543 else {
2544 for(MInt k = 0; k < noBodies; k++) {
2545 bodyIds[k] = k;
2546 }
2547 }
2548 if(bodyCnt > 0) descendDistance(cellId, &bodyIds[0], bodyCnt, nearestBodies, nearestDist);
2549 maxBodyCnt = mMax(maxBodyCnt, bodyCnt);
2550 }
2551 MPI_Allreduce(MPI_IN_PLACE, &maxBodyCnt, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "maxBodyCnt");
2552 return maxBodyCnt;
2553 }
2554 return 0;
2555}
void descendDistance(const MInt cellId, const MInt *const bodyIds, const MInt bodyCnt, MIntScratchSpace &nearestBodies, MFloatScratchSpace &nearestDist)
KDtree< nDim > * m_bodyTreeLocal
MInt locatenearest(Point< DIM > pt, MFloat r, MInt *list, MFloat *dn, MInt nmax, MBool &overflow)
Definition: kdtree.h:372

◆ constructGField()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::constructGField ( MBool  updateBody = true)
Author
Lennart Schneiders

Definition at line 2376 of file fvmbcartesiansolverxd.cpp.

2376 {
2377 TRACE();
2378
2379 if(m_noEmbeddedBodies == 0) {
2380 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
2382 a_hasProperty(cellId, SolverCell::IsInactive) = false;
2383 }
2384 return;
2385 }
2386
2387 if(m_motionEquation == 0) {
2388 if(updateBody) {
2390 }
2393 }
2394
2396 if(m_noLevelSetsUsedForMb == 1) {
2397 for(MInt k = 0; k < noBodies; k++) {
2398 m_bodyNearDomain[k] = true;
2399 for(MInt i = 0; i < nDim; i++) {
2400 if(m_bodyCenter[k * nDim + i] < m_bboxLocal[i] - (m_bodyDistThreshold + m_bodyRadius[k])) {
2401 m_bodyNearDomain[k] = false;
2402 }
2403 if(m_bodyCenter[k * nDim + i] > m_bboxLocal[nDim + i] + (m_bodyDistThreshold + m_bodyRadius[k])) {
2404 m_bodyNearDomain[k] = false;
2405 }
2406 }
2407 }
2408 }
2409
2410 if(!m_constructGField) {
2411 return;
2412 }
2413
2415
2416 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
2418 }
2419
2420 constexpr MFloat safetyFac = 1.1;
2421 const MFloat uncertaintyAngle = sqrt(FD) * c_cellLengthAtLevel(minLevel());
2422 const MFloat uncertaintyRotation = m_maxBodyRadius;
2423 const MFloat minWallDist = F3 * c_cellLengthAtLevel(maxLevel());
2424 const MFloat delta1 = safetyFac * (uncertaintyAngle + uncertaintyRotation);
2425 const MFloat delta0 = delta1 + safetyFac * minWallDist;
2426
2427 MFloatScratchSpace bodyDist(noBodies, AT_, "bodyDist");
2428 MIntScratchSpace bodyIds(noBodies, AT_, "bodyIds");
2430 bodyDist.fill(deltaMax);
2431 bodyIds.fill(-1);
2432
2433 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
2434 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
2435 a_associatedBodyIds(cellId, set) = -1;
2436 a_levelSetValuesMb(cellId, set) = m_bodyDistThreshold + 1e-14;
2437 }
2438 }
2439
2440 for(MInt i = 0; i < noMinCells(); i++) {
2441 MInt cellId = minCell(i);
2442 MFloat minDist = c_cellLengthAtLevel(0);
2443 MInt bodyCnt = noBodies;
2444
2445 IF_CONSTEXPR(nDim == 3) {
2446 if(m_bodyTypeMb == 1 || m_bodyTypeMb == 3) {
2447 MBool overflow = false;
2448 Point<nDim> pt(a_coordinate(cellId, 0), a_coordinate(cellId, 1), a_coordinate(cellId, 2));
2449 bodyCnt = m_bodyTreeLocal->locatenearest(pt, deltaMax, &bodyIds[0], &bodyDist[0], noBodies, overflow);
2450 } else {
2451 for(MInt k = 0; k < noBodies; k++) {
2452 bodyIds[k] = k;
2453 }
2454 }
2455 }
2456 else {
2457 for(MInt k = 0; k < noBodies; k++) {
2458 bodyIds[k] = k;
2459 }
2460 }
2461
2462 // first check to improve performance: remove bodies which are too far away to be relevant
2463 for(MInt k = 0; k < bodyCnt; k++) {
2464 MFloat dist = F0;
2465 IF_CONSTEXPR(nDim == 2) {
2466 dist = sqrt(POW2(a_coordinate(cellId, 0) - m_bodyCenter[bodyIds[k] * nDim + 0])
2467 + POW2(a_coordinate(cellId, 1) - m_bodyCenter[bodyIds[k] * nDim + 1]));
2468 }
2469 IF_CONSTEXPR(nDim == 3) {
2470 dist = sqrt(POW2(a_coordinate(cellId, 0) - m_bodyCenter[bodyIds[k] * nDim + 0])
2471 + POW2(a_coordinate(cellId, 1) - m_bodyCenter[bodyIds[k] * nDim + 1])
2472 + POW2(a_coordinate(cellId, 2) - m_bodyCenter[bodyIds[k] * nDim + 2]));
2473 }
2474 if(dist > delta0 && dist > minDist + delta1) {
2475 if(k < bodyCnt - 1) {
2476 bodyIds[k] = bodyIds[bodyCnt - 1];
2477 bodyDist[k] = bodyDist[bodyCnt - 1];
2478 k--;
2479 }
2480 bodyCnt--;
2481 }
2482 minDist = mMin(minDist, dist);
2483 }
2484
2485 if(bodyCnt > 0) descendLevelSetValue(cellId, &bodyIds[0], bodyCnt);
2486
2487 MInt parentId = c_parentId(cellId);
2488 while(parentId > -1) {
2489 for(MInt set = 0; set < m_noSets; set++) {
2490 a_levelSetValuesMb(c_parentId(cellId), set) = a_levelSetValuesMb(cellId, set);
2491 a_associatedBodyIds(parentId, set) = a_associatedBodyIds(cellId, set);
2492 }
2493 parentId = c_parentId(parentId);
2494 }
2495 }
2496}
MLong c_parentId(const MInt cellId) const
Returns the grid parent id of the cell cellId.
void updateBodyProperties()
update properties of the embedded body (mainly forced structural motion)
static constexpr MFloat FD
void descendLevelSetValue(const MInt cellId, const MInt *const bodyIds, const MInt bodyCnt)

◆ constructGFieldCorrector()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::constructGFieldCorrector
Author
Lennart Schneiders

Definition at line 4814 of file fvmbcartesiansolverxd.cpp.

4814 {
4815 TRACE();
4816
4818
4819 if(!m_trackMovingBndry || globalTimeStep < m_trackMbStart || globalTimeStep >= m_trackMbEnd) return true;
4820 if(m_motionEquation == 0) return true;
4822 return true;
4823 }
4824
4825 ASSERT(m_constructGField, "");
4826
4827 NEW_TIMER_GROUP_STATIC(t_initTimer, "GFieldCorrector");
4828 NEW_TIMER_STATIC(t_timertotal, "GFieldCorrector", t_initTimer);
4829 NEW_SUB_TIMER_STATIC(t_init, "init", t_timertotal);
4830 NEW_SUB_TIMER_STATIC(t_advance, "advance", t_timertotal);
4831 NEW_SUB_TIMER_STATIC(t_transfer, "transfer", t_timertotal);
4832 RECORD_TIMER_START(t_timertotal);
4833 RECORD_TIMER_START(t_init);
4834
4835 MFloatScratchSpace oldX(m_noEmbeddedBodies, nDim, AT_, "oldX");
4836 MFloatScratchSpace oldV(m_noEmbeddedBodies, nDim, AT_, "oldV");
4837 MFloatScratchSpace oldQ(m_noEmbeddedBodies, 4, AT_, "oldQ");
4838 MFloatScratchSpace oldW(m_noEmbeddedBodies, 3, AT_, "oldW");
4839
4840 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
4841 for(MInt i = 0; i < nDim; i++)
4842 oldX(k, i) = m_bodyCenter[k * nDim + i];
4843 for(MInt i = 0; i < nDim; i++)
4844 oldV(k, i) = m_bodyVelocity[k * nDim + i];
4845 for(MInt i = 0; i < 3; i++)
4846 oldW(k, i) = m_bodyAngularVelocity[k * 3 + i];
4847 for(MInt i = 0; i < 4; i++)
4848 oldQ(k, i) = m_bodyQuaternion[k * 4 + i];
4849 }
4850
4851 RECORD_TIMER_STOP(t_init);
4852 RECORD_TIMER_START(t_advance);
4853
4854
4855 switch(m_motionEquation) {
4856 // free motion under gravity
4857 case 1: {
4858 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
4859 for(MInt i = 0; i < nDim; i++) {
4860 if(m_fixedBodyComponents[i]) continue;
4861
4862 m_bodyAcceleration[k * nDim + i] = (m_bodyForce[k * nDim + i]) / m_bodyMass[k] + m_gravity[i];
4863 m_bodyCenter[k * nDim + i] =
4864 m_bodyCenterDt1[k * nDim + i]
4865 + timeStep() * m_bodyVelocityDt1[k * nDim + i]
4866 + F1B4 * POW2(timeStep()) * (m_bodyAccelerationDt1[k * nDim + i] + m_bodyAcceleration[k * nDim + i]);
4867 m_bodyVelocity[k * nDim + i] =
4868 m_bodyVelocityDt1[k * nDim + i]
4869 + timeStep() * F1B2 * (m_bodyAccelerationDt1[k * nDim + i] + m_bodyAcceleration[k * nDim + i]);
4870 if(fabs(m_bodyCenter[k * nDim + i] - m_bodyCenterDt1[k * nDim + i])
4872 cerr << "displ " << k << " " << i << " " << m_bodyCenter[k * nDim + i] << " "
4873 << m_bodyCenterDt1[k * nDim + i] << endl;
4874 }
4875 m_bodyTemperature[k] = F1B2
4878 }
4880
4881 break;
4882 }
4883
4884 case 2: {
4885 /*
4886 if ( m_initialCondition == 459 ) {
4887 const MFloat rhosbrhof = 1.05 / 1.0;
4888 const MFloat rhofbrhos = 1.0 / rhosbrhof;
4889 const MFloat Cd = 24.0 * POW2( 9.06/sqrt(m_Re) + 1.0 ) / POW2( 9.06 );
4890 const MFloat ut = sqrt( 4.0/3.0 * m_physicalReferenceLength * 9.81 * (rhosbrhof-1.0) / Cd );
4891 const MFloat Froude = ut / sqrt( 9.81 * m_physicalReferenceLength );
4892 const MFloat g[3] = { F0, F0, -POW2( m_Ma / Froude ) };
4893
4894 dxmax = F0;
4895 dumax = F0;
4896
4897 for ( MInt k = 0; k < m_noEmbeddedBodies; k++ ) {
4898 dx = F0;
4899 du = F0;
4900 for( MInt i=0; i<nDim; i++ ) {
4901 if( m_fixedBodyComponents[ i ] )
4902 continue;
4903
4904 tmpx = m_bodyCenter[ k*nDim+i ];
4905 tmpu = m_bodyVelocity[ k*nDim+i ];
4906
4907 m_bodyAcceleration[ k*nDim+i ] =
4908 ( F1 - rhofbrhos ) * g[ i ] + rhofbrhos * m_bodyForce[ k*nDim+i ] / m_bodyMass[ k ] ;
4909
4910 m_bodyVelocity[ k*nDim+i ] =
4911 m_bodyVelocityDt1[ k*nDim+i ] + timeStep() * 0.5 *
4912 ( m_bodyAcceleration[ k*nDim+i ] + m_bodyAccelerationDt1[ k*nDim+i ] );
4913
4914 m_bodyCenter[ k*nDim+i ] =
4915 m_bodyCenterDt1[ k*nDim+i ] + timeStep() * 0.5 *
4916 ( m_bodyVelocity[ k*nDim+i ] + m_bodyVelocityDt1[ k*nDim+i ] );
4917
4918 // m_bodyVelocity[ k*nDim+i ] =
4919 // ( m_bodyCenter[ k*nDim+i ] - m_bodyCenterDt1[ k*nDim+i ] ) / timeStep();
4920
4921 dx += POW2( m_bodyCenter[ k*nDim+i ] - tmpx );
4922 du += POW2( m_bodyVelocity[ k*nDim+i ] - tmpu );
4923 }
4924 du = sqrt( du );
4925 dx = sqrt( dx );
4926 dumax = mMax( dumax, du );
4927 dxmax = mMax( dxmax, dx );
4928 }
4929
4930 cerr << "corr: " << globalTimeStep << " " << m_structureStep << " " << dxmax << " " << dumax << endl;
4931 }
4932 */
4933
4934 break;
4935 }
4936
4937 // elastically mounted - implicit discretization (Borazjani, JCP(2008))
4938 case 3: {
4939 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
4940 for(MInt i = 0; i < nDim; i++) {
4941 if(m_fixedBodyComponents[i]) continue;
4942
4943 const MFloat A = F4 * PI * m_bodyDampingCoefficient[k] * m_bodyReducedFrequency[k];
4944 const MFloat B = F4 * POW2(PI) * POW2(m_bodyReducedFrequency[k]);
4945 const MFloat C = m_bodyForce[k * nDim + i] / m_bodyReducedMass[k];
4946
4947 m_bodyVelocity[k * nDim + i] =
4948 (m_bodyVelocityDt1[k * nDim + i] * (F1 - F1B2 * POW2(timeStep()) * B) + timeStep() * C
4949 - timeStep() * B * (m_bodyCenterDt1[k * nDim + i] - m_bodyNeutralCenter[k * nDim + i]))
4950 / (F1 + timeStep() * A + F1B2 * POW2(timeStep()) * B);
4951 m_bodyCenter[k * nDim + i] =
4952 m_bodyCenterDt1[k * nDim + i]
4953 + timeStep() * F1B2 * (m_bodyVelocity[k * nDim + i] + m_bodyVelocityDt1[k * nDim + i]);
4954 m_bodyAcceleration[k * nDim + i] =
4955 (m_bodyVelocity[k * nDim + i] - m_bodyVelocityDt1[k * nDim + i]) / timeStep();
4956 }
4957 }
4958
4959 break;
4960 }
4961
4962 // elastically mounted - true Crank Nicolson ( Lennart's modification of Borazjani scheme )
4963 case 4: {
4964 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
4965 for(MInt i = 0; i < nDim; i++) {
4966 if(m_fixedBodyComponents[i]) continue;
4967
4968 const MFloat A = F4 * PI * m_bodyDampingCoefficient[k] * m_bodyReducedFrequency[k];
4969 const MFloat B = F4 * POW2(PI) * POW2(m_bodyReducedFrequency[k]);
4970 const MFloat C = F1B2 * (m_bodyForce[k * nDim + i] + m_bodyForceDt1[k * nDim + i]) / m_bodyReducedMass[k];
4971 const MFloat beta = F1B2 * timeStep() * (A + F1B2 * timeStep() * B);
4972
4973 m_bodyVelocity[k * nDim + i] =
4974 (m_bodyVelocityDt1[k * nDim + i] * (F1 - beta) + timeStep() * C
4975 - timeStep() * B * (m_bodyCenterDt1[k * nDim + i] - m_bodyNeutralCenter[k * nDim + i]))
4976 / (F1 + beta);
4977 m_bodyCenter[k * nDim + i] =
4978 m_bodyCenterDt1[k * nDim + i]
4979 + timeStep() * F1B2 * (m_bodyVelocity[k * nDim + i] + m_bodyVelocityDt1[k * nDim + i]);
4980 m_bodyAcceleration[k * nDim + i] =
4981 (m_bodyVelocity[k * nDim + i] - m_bodyVelocityDt1[k * nDim + i]) / timeStep();
4982 }
4983 }
4984
4985 break;
4986 }
4987
4988 // Beeman scheme
4989 case 5: {
4990 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
4991 for(MInt i = 0; i < nDim; i++) {
4992 if(m_fixedBodyComponents[i]) continue;
4993
4994 m_bodyAcceleration[k * nDim + i] = (m_bodyForce[k * nDim + i] + m_gravity[i]) / m_bodyMass[k];
4995 m_bodyCenter[k * nDim + i] =
4996 m_bodyCenterDt1[k * nDim + i] + timeStep() * m_bodyVelocityDt1[k * nDim + i]
4997 + F1B6 * POW2(timeStep()) * (m_bodyAcceleration[k * nDim + i] + F2 * m_bodyAccelerationDt1[k * nDim + i]);
4998 m_bodyVelocity[k * nDim + i] =
4999 m_bodyVelocityDt1[k * nDim + i]
5000 + timeStep() * F1B2 * (m_bodyAcceleration[k * nDim + i] + m_bodyAccelerationDt1[k * nDim + i]);
5001 }
5002 }
5004
5005 break;
5006 }
5007
5008 // fourth-order Beeman scheme -> JCP 20 (1976)
5009 case 6: {
5010 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
5011 for(MInt i = 0; i < nDim; i++) {
5012 if(m_fixedBodyComponents[i]) continue;
5013
5014 m_bodyAcceleration[k * nDim + i] = (m_bodyForce[k * nDim + i] + m_gravity[i]) / m_bodyMass[k];
5015 m_bodyCenter[k * nDim + i] =
5016 m_bodyCenterDt1[k * nDim + i] + timeStep() * m_bodyVelocityDt1[k * nDim + i]
5017 + F1B24 * POW2(timeStep())
5018 * (F3 * m_bodyAcceleration[k * nDim + i] + F10 * m_bodyAccelerationDt1[k * nDim + i]
5019 - m_bodyAccelerationDt2[k * nDim + i]);
5020 m_bodyVelocity[k * nDim + i] =
5021 m_bodyVelocityDt1[k * nDim + i]
5022 + timeStep() * F1B12
5023 * (F5 * m_bodyAcceleration[k * nDim + i] + F8 * m_bodyAccelerationDt1[k * nDim + i]
5024 - m_bodyAccelerationDt2[k * nDim + i]);
5025 }
5026 }
5028
5029 break;
5030 }
5031
5032 default: {
5033 mTerm(1, AT_, "Invalid motion equation specified!");
5034 }
5035 }
5036
5037 RECORD_TIMER_STOP(t_advance);
5038 RECORD_TIMER_START(t_transfer);
5039
5040#if defined _MB_DEBUG_ || !defined NDEBUG
5041 MBool nan = false;
5042 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
5043 for(MInt i = 0; i < nDim; i++) {
5044 if(std::isnan(m_bodyVelocity[k * nDim + i]) || std::isnan(m_bodyCenter[k * nDim + i])
5045 || std::isnan(m_bodyAcceleration[k * nDim + i])) {
5046 nan = true;
5047 }
5048 }
5049 }
5050 if(nan) {
5051 m_solutionDiverged = true;
5052 cerr << "Solution diverged (SCORR) at solver " << domainId() << endl;
5053 }
5054 MPI_Allreduce(MPI_IN_PLACE, &m_solutionDiverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
5055 "m_solutionDiverged");
5056 if(m_solutionDiverged) {
5057 writeVtkXmlFiles("QOUT", "GEOM", false, true);
5058 MPI_Barrier(mpiComm(), AT_);
5059 mTerm(1, AT_, "Solution diverged after structure corrector handling.");
5060 }
5061#endif
5062
5065
5066 MFloat dxmax = F0;
5067 MFloat dumax = F0;
5068 MFloat drmax = F0;
5069 MFloat dwmax = F0;
5070 MFloat dxavg = F0;
5071 MFloat duavg = F0;
5072 MFloat dravg = F0;
5073 MFloat dwavg = F0;
5074
5075 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
5076 for(MInt i = 0; i < nDim; i++) {
5077 if(m_fixedBodyComponents[i]) continue;
5078 MFloat dx = fabs(m_bodyCenter[k * nDim + i] - oldX(k, i));
5079 MFloat du = fabs(m_bodyVelocity[k * nDim + i] - oldV(k, i));
5080 dumax = mMax(dumax, du);
5081 dxmax = mMax(dxmax, dx);
5082 duavg += du;
5083 dxavg += dx;
5084 }
5085 }
5086
5087 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
5088 for(MInt i = 0; i < 3; i++) {
5089 if(m_fixedBodyComponentsRotation[i]) continue;
5090 MFloat dw = fabs(m_bodyAngularVelocity[k * 3 + i] - oldW(k, i));
5091 dwmax = mMax(dwmax, dw);
5092 dwavg += dw;
5093 }
5094 for(MInt i = 0; i < 4; i++) {
5095 MFloat dr = fabs(m_bodyQuaternion[k * 4 + i] - oldQ(k, i));
5096 drmax = mMax(drmax, dr);
5097 dravg += dr;
5098 }
5099 }
5100
5101 dxavg /= ((MFloat)m_noEmbeddedBodies);
5102 duavg /= ((MFloat)m_noEmbeddedBodies);
5103 dravg /= ((MFloat)m_noEmbeddedBodies);
5104 dwavg /= ((MFloat)m_noEmbeddedBodies);
5105
5106 if(globalTimeStep % 10 == 0 || m_structureStep > 1) {
5107 cerr0 << "corr: " << globalTimeStep << " (" << m_structureStep << "): " << dxmax << " " << dumax << " / " << drmax
5108 << " " << dwmax << " (" << dxavg << " " << duavg << " / " << dravg << " " << dwavg << ")" << endl;
5109 }
5110
5111 RECORD_TIMER_STOP(t_transfer);
5112 RECORD_TIMER_STOP(t_timertotal);
5113 DISPLAY_TIMER_OFFSET(t_timertotal, m_restartInterval);
5114
5115 if((dxmax < m_FSIToleranceX) && (dumax < m_FSIToleranceU) && (drmax < m_FSIToleranceR) && (dwmax < m_FSIToleranceW)) {
5116 return true;
5117 } else {
5118 return false;
5119 }
5120}

◆ constructGFieldPredictor()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::constructGFieldPredictor ( )
Author
Lennart Schneiders

◆ copyFile()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::copyFile ( const MChar fromName,
const MChar toName 
)
Author

Definition at line 26119 of file fvmbcartesiansolverxd.cpp.

26119 {
26120 if(!fileExists(fromName)) {
26121 cerr << "Could not copy file " << fromName << "." << endl;
26122 return -1;
26123 }
26124 if(fileExists(toName)) {
26125 remove(toName);
26126 }
26127 ifstream src(fromName);
26128 ofstream dst(toName);
26129 if(src.good() && dst.good()) {
26130 dst << src.rdbuf();
26131 dst.close();
26132 dst.clear();
26133 src.close();
26134 src.clear();
26135 } else {
26136 cerr << "Could not copy file " << fromName << " (2)." << endl;
26137 return -1;
26138 }
26139 return 0;
26140}
MBool fileExists(const MChar *fileName)

◆ copyVarsToSmallCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::copyVarsToSmallCells
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 12674 of file fvmbcartesiansolverxd.cpp.

12674 {
12675 TRACE();
12676
12677 m_fvBndryCnd->copyVarsToSmallCells();
12678}

◆ correctBoundarySurfaceVariablesMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::correctBoundarySurfaceVariablesMb
Author
Lennart Schneiders

Definition at line 18201 of file fvmbcartesiansolverxd.cpp.

18201 {
18202 TRACE();
18203
18204 m_fvBndryCnd->correctBoundarySurfaceVariables();
18205}

◆ correctCoarsenedBndryCellVolume()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::correctCoarsenedBndryCellVolume
Author
Tim Wegmann

Definition at line 34932 of file fvmbcartesiansolverxd.cpp.

34932 {
34933 TRACE();
34934
34935 for(auto it = m_coarseOldBndryCells.begin(); it != m_coarseOldBndryCells.end(); it++) {
34936 const MInt cellId = *it;
34937 ASSERT(c_isLeafCell(cellId), "");
34938
34939 if(a_isBndryCell(cellId)) {
34940 MFloat dV = F0;
34941 MFloat dt = timeStep(true);
34942 const MInt bndryId = a_bndryId(cellId);
34943 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
34944 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
34945 for(MInt i = 0; i < nDim; i++) {
34946 MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
34947 dV -= dt * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] * nml * area;
34948 }
34949 }
34950
34951 // old values are set based on the current values!
34952 // not exactly mass-conservative, but reduces pressure problems at the newly refined bndry!
34953 const MFloat deltaVol = m_RKalpha[m_noRKSteps - 2] * dV + (F1 - m_RKalpha[m_noRKSteps - 2]) * dV;
34955 m_sweptVolumeDt1[bndryId] = dV;
34956
34957 auto it1 = m_oldBndryCells.find(cellId);
34958 ASSERT(it1 != m_oldBndryCells.end(), "");
34959 m_oldBndryCells.erase(it1);
34960 m_oldBndryCells.insert(make_pair(cellId, dV));
34961 }
34962 }
34963
34964 m_coarseOldBndryCells.clear();
34965}
std::set< MInt > m_coarseOldBndryCells

◆ correctMasterSlaveSurfaces()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::correctMasterSlaveSurfaces
Author
: Claudia Guenther

Definition at line 26022 of file fvmbcartesiansolverxd.cpp.

26022 {
26023 TRACE();
26024
26025 MInt cellId, bndryId, masterCellId;
26026 MInt noSurfaces = a_noSurfaces();
26027 MInt otherId[2] = {1, 0};
26028
26029 for(MInt srfcId = 0; srfcId < noSurfaces; srfcId++) {
26030 for(MInt nghbrId = 0; nghbrId < 2; nghbrId++) {
26031 cellId = a_surfaceNghbrCellId(srfcId, nghbrId);
26032 if(a_bndryId(cellId) < 0) continue;
26033
26034 bndryId = a_bndryId(cellId);
26035 // check whether the cell is a slave cell
26036 if(m_bndryCells->a[bndryId].m_linkedCellId == -1) continue;
26037
26038 masterCellId = m_bndryCells->a[bndryId].m_linkedCellId;
26039
26040 // check whether the other neighbor of the surface is the
26041 // master cell
26042 if(a_surfaceNghbrCellId(srfcId, otherId[nghbrId]) == masterCellId) {
26043 } else {
26044 // shift the Id to the master cell
26045 a_surfaceNghbrCellId(srfcId, nghbrId) = masterCellId;
26046 }
26047 }
26048 }
26049}

◆ correctRefinedBndryCell()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::correctRefinedBndryCell
Author
Tim Wegmann

Definition at line 34785 of file fvmbcartesiansolverxd.cpp.

34785 {
34786 TRACE();
34787
34788 vector<MInt> deletedBndryCells;
34789 vector<MInt> bndryChilds;
34790 std::map<MInt, MFloat> childBndryCells;
34791 std::map<MInt, MFloat> haloBndryCells;
34792
34793 MInt noRefOldBndryCells = m_refOldBndryCells.size();
34794 MPI_Allreduce(MPI_IN_PLACE, &noRefOldBndryCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
34795 "noRefOldBndryCells");
34796
34797 if(noRefOldBndryCells == 0) return;
34798
34799 m_log << "Correcting newly refined BndryCells after adaptation ...";
34800
34801 // NOTE: noChildren on non-leaf-Level cells may differ between window-and halo cells!!!
34802 MIntScratchSpace noRelevantChilds(a_noCells(), AT_, "noRelevantChilds");
34803 noRelevantChilds.fill(-1);
34804
34805 vector<MInt> refOldBndryCellsNew;
34806
34807 for(MInt it = 0; it < (signed)m_refOldBndryCells.size(); it++) {
34808 const MInt cellId = m_refOldBndryCells[it];
34809 ASSERT(c_isLeafCell(cellId), "");
34810
34811 if(a_hasProperty(cellId, SolverCell::IsInactive)) {
34812 // treat inactive oldBndryCells as if they were inactive before!
34813 a_hasProperty(cellId, SolverCell::WasInactive) = true;
34814 m_cellVolumesDt1[cellId] = grid().gridCellVolume(a_level(cellId));
34815 for(MInt v = 0; v < m_noFVars; v++) {
34816 m_rhs0[cellId][v] = 0;
34817 }
34818 auto it1 = m_oldBndryCells.find(cellId);
34819 m_oldBndryCells.erase(it1);
34820 } else {
34821 if(!a_isBndryCell(cellId)) {
34822 // treat uncut oldBndryCells as if they were active before!
34823 a_hasProperty(cellId, SolverCell::WasInactive) = false;
34824 m_cellVolumesDt1[cellId] = grid().gridCellVolume(a_level(cellId));
34825 for(MInt v = 0; v < m_noFVars; v++) {
34826 m_rhs0[cellId][v] = 0;
34827 }
34828 auto it1 = m_oldBndryCells.find(cellId);
34829 m_oldBndryCells.erase(it1);
34830 } else {
34831 // oldBndryCell is also newBndryCell
34832 a_hasProperty(cellId, SolverCell::WasInactive) = false;
34833 // save bndryCells to update m_refOldBndryCells with bndryCells which remain
34834 // bndryCells!
34835 refOldBndryCellsNew.push_back(cellId);
34836 if(a_isHalo(cellId)) continue;
34837 // count other BndryCells from the same parent!
34838 MInt noBndryCellChilds = 0;
34839 const MInt parent = c_parentId(cellId);
34840 for(MInt childId = 0; childId < IPOW2(nDim); childId++) {
34841 const MInt child = c_childId(parent, childId);
34842 if(child == -1) continue;
34843 if(a_isBndryCell(child)) noBndryCellChilds++;
34844 }
34845 ASSERT(noBndryCellChilds > 0, ""); // atleast the cellId
34846 noRelevantChilds(cellId) = noBndryCellChilds;
34847 // for mass-conservity the rhs0 parent (oldBndryCell) value must be split evenly
34848 // between all newBndryCells, as the values in all other cells are resetted!
34849 // setting the old Volume/sweptVolume based on currecnt values as in firstRHS
34850 // reduces pressure waves!
34851 // NOTE: as the boundaryVelocity is not set yet, the value will be updated in
34852 // correctRefinedBndryCellVolume later!
34853 for(MInt v = 0; v < m_noFVars; v++) {
34854 m_rhs0[cellId][v] = m_rhs0[parent][v] / noBndryCellChilds;
34855 }
34856 }
34857 }
34858 }
34859
34860 exchangeData(&noRelevantChilds[0],
34861 1); // Skip azimuthal exchange since infromation on azimuthal windows and halos is not the same
34862
34863 for(MInt cellId = noInternalCells(); cellId < c_noCells(); cellId++) {
34864 ASSERT(a_isHalo(cellId), "");
34865 if(!a_isBndryCell(cellId)) continue;
34866 auto it = std::find(m_refOldBndryCells.begin(), m_refOldBndryCells.end(), cellId);
34867 if(it != m_refOldBndryCells.end()) {
34868 MInt noBndryCellChilds = noRelevantChilds(cellId);
34869 const MInt parent = c_parentId(cellId);
34870 for(MInt v = 0; v < m_noFVars; v++) {
34871 m_rhs0[cellId][v] = m_rhs0[parent][v] / noBndryCellChilds;
34872 }
34873 }
34874 }
34875
34876 m_refOldBndryCells.clear();
34877
34878 // now add old bndryCells which will remain bndryCell!
34879 for(MInt it = 0; it < (signed)refOldBndryCellsNew.size(); it++) {
34880 const MInt cellId = refOldBndryCellsNew[it];
34881 m_refOldBndryCells.push_back(cellId);
34882 }
34883
34884 m_log << " Finished" << endl;
34885}
std::vector< MInt > m_refOldBndryCells

◆ correctRefinedBndryCellVolume()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::correctRefinedBndryCellVolume
Author
Tim Wegmann

Definition at line 34893 of file fvmbcartesiansolverxd.cpp.

34893 {
34894 TRACE();
34895
34896 for(MInt it = 0; it < (signed)m_refOldBndryCells.size(); it++) {
34897 const MInt cellId = m_refOldBndryCells[it];
34898 ASSERT(c_isLeafCell(cellId), "");
34899 ASSERT(a_isBndryCell(cellId), "");
34900
34901 MFloat dV = F0;
34902 MFloat dt = timeStep(true);
34903 const MInt bndryId = a_bndryId(cellId);
34904 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
34905 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
34906 for(MInt i = 0; i < nDim; i++) {
34907 MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
34908 dV -= dt * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] * nml * area;
34909 }
34910 }
34911 const MFloat deltaVol = m_RKalpha[m_noRKSteps - 2] * dV + (F1 - m_RKalpha[m_noRKSteps - 2]) * dV;
34912
34913 // old values are set based on the current values!
34914 // not exactly mass-conservative, but reduces pressure problems at the newly refined bndry!
34916 m_sweptVolumeDt1[bndryId] = dV;
34917
34918 auto it1 = m_oldBndryCells.find(cellId);
34919 ASSERT(it1 != m_oldBndryCells.end(), "");
34920 m_oldBndryCells.erase(it1);
34921 m_oldBndryCells.insert(make_pair(cellId, dV));
34922 }
34923 m_refOldBndryCells.clear();
34924}

◆ correctSrfcsMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::correctSrfcsMb
Author
Lennart Schneiders

Definition at line 31206 of file fvmbcartesiansolverxd.cpp.

31206 {
31207 TRACE();
31208
31209 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
31210 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
31211 for(MInt dir = 0; dir < m_noDirs; dir++) {
31212 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
31213 if(srfcId > -1) {
31215 }
31216 }
31217 }
31218}
void updateCellSurfaceDistanceVector(MInt srfcId)
correct the cell-surface distance vectors for cells near the moving boundary

◆ crankAngleSolutionOutput()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::crankAngleSolutionOutput
Author
Tim Wegmann

Definition at line 15940 of file fvmbcartesiansolverxd.cpp.

15940 {
15941 TRACE();
15942
15943 if(!m_engineSetup) return;
15944
15945 static const MInt cadStart = -10;
15946 static const MInt cadEnd = 725;
15947 static const MInt cadEndSlice = 365;
15948 static const MInt cadInterval = 5;
15949
15950 static const MInt sliceInterval = 1;
15951
15952 const MFloat cad = this->crankAngle(m_physicalTime, 0);
15953 const MFloat cad_prev = this->crankAngle(m_physicalTime - timeStep(), 0);
15954 const MFloat cad_next = this->crankAngle(m_physicalTime + timeStep(), 0);
15955
15956 if(cad > cadEnd) return;
15957
15958 if(cad < cadStart - cadInterval) return;
15959
15960 const MInt cadMaxIter = (cadEnd - cadStart) / cadInterval;
15961 const MInt sliceMaxIter = (cadEndSlice - cadStart) / sliceInterval;
15962
15963 // iterate for full solution output
15964 for(MInt i = 0; i < cadMaxIter; i++) {
15965 const MFloat cadTarget = cadStart + i * cadInterval;
15966
15967 if(cad < cadTarget && cad_next > cadTarget) {
15968 if(fabs(cad - cadTarget) <= fabs(cad_next - cadTarget)) {
15969 if(domainId() == 0) {
15970 cerr << "Saving output at crankAngle " << cad << endl;
15971 }
15972
15973 // trigger full output:
15974 MFloat* backUpCoordinate = NULL;
15975 if(m_vtuCoordinatesThreshold != NULL) {
15976 mAlloc(backUpCoordinate, 6, "backUpCoordinate", F0, AT_);
15977 for(MInt j = 0; j < 2 * nDim; j++) {
15978 backUpCoordinate[j] = m_vtuCoordinatesThreshold[j];
15979 }
15982 }
15983 MString fileName = "FieldData_" + to_string(solverId()) + "_" + to_string((MInt)round(cad));
15984 writeVtkXmlFiles(fileName, "GEO_", false, false);
15985 if(backUpCoordinate != NULL) {
15986 mAlloc(m_vtuCoordinatesThreshold, 6, "backUpCoordinate", F0, AT_);
15987 for(MInt j = 0; j < 2 * nDim; j++) {
15988 m_vtuCoordinatesThreshold[j] = backUpCoordinate[j];
15989 }
15990 }
15991 break;
15992 }
15993 } else if(cad > cadTarget && cad_prev < cadTarget) {
15994 if(abs(cad - cadTarget) < fabs(cad_prev - cadTarget)) {
15995 if(domainId() == 0) {
15996 cerr << "Saving output at crankAngle " << cad << endl;
15997 }
15998 // trigger full output:
15999 MFloat* backUpCoordinate = NULL;
16000 if(m_vtuCoordinatesThreshold != NULL) {
16001 mAlloc(backUpCoordinate, 6, "backUpCoordinate", F0, AT_);
16002 for(MInt j = 0; j < 2 * nDim; j++) {
16003 backUpCoordinate[j] = m_vtuCoordinatesThreshold[j];
16004 }
16007 }
16008 MString fileName = "FieldData_" + to_string(solverId()) + "_" + to_string((MInt)round(cad));
16009 writeVtkXmlFiles(fileName, "GEO_", false, false);
16010 if(backUpCoordinate != NULL) {
16011 mAlloc(m_vtuCoordinatesThreshold, 6, "backUpCoordinate", F0, AT_);
16012 for(MInt j = 0; j < 2 * nDim; j++) {
16013 m_vtuCoordinatesThreshold[j] = backUpCoordinate[j];
16014 }
16015 }
16016 break;
16017 }
16018 }
16019 }
16020
16021 if(cad > cadEndSlice) return;
16022
16023 // iterate for slice output
16024 for(MInt i = 0; i < sliceMaxIter; i++) {
16025 const MFloat sliceTarget = cadStart + i * sliceInterval;
16026
16027 if(cad < sliceTarget && cad_next > sliceTarget) {
16028 if(fabs(cad - sliceTarget) <= fabs(cad_next - sliceTarget)) {
16029 if(domainId() == 0) {
16030 cerr << "Saving output Slice at crankAngle " << cad << endl;
16031 }
16032 MString fileName = "Slice_" + to_string(solverId()) + "_" + to_string((MInt)round(cad));
16033 writeVtkXmlFiles(fileName, "SLICE_GEO", false, false);
16034 break;
16035 }
16036 } else if(cad > sliceTarget && cad_prev < sliceTarget) {
16037 if(abs(cad - sliceTarget) < fabs(cad_prev - sliceTarget)) {
16038 if(domainId() == 0) {
16039 cerr << "Saving output Slice at crankAngle " << cad << endl;
16040 }
16041 MString fileName = "Slice_" + to_string(solverId()) + "_" + to_string((MInt)round(cad));
16042 writeVtkXmlFiles(fileName, "SLICE_GEO", false, false);
16043 break;
16044 }
16045 }
16046 }
16047}
MInt solverId() const
Return the solverId.
Definition: solver.h:425

◆ createBndryCellMb()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::createBndryCellMb ( MInt  cellId)
Author
Lennart Schneiders

Definition at line 19377 of file fvmbcartesiansolverxd.cpp.

19377 {
19378 if(cellId < 0) {
19379 cerr << "Critical error in createBndryCellMb: "
19380 << ", cell: " << cellId << endl;
19382 mTerm(1, AT_, "Critical error in createBndryCellMb");
19383 }
19384
19385 ASSERT(!a_isBndryCell(cellId), "");
19386
19387 MInt bCellId = m_fvBndryCnd->m_bndryCells->size();
19388 m_fvBndryCnd->m_bndryCells->append();
19389
19390#if defined _MB_DEBUG_ || !defined NDEBUG
19392 if(a_levelSetValuesMb(cellId, 0) < F0 && !a_hasProperty(cellId, SolverCell::IsSplitChild)) {
19393 // not surprising during Gap-Closure!
19394 if(!a_isGapCell(cellId)) {
19395 if(!a_hasProperty(cellId, SolverCell::IsInactive)) {
19396 cerr << "not inact " << c_globalId(cellId) << endl;
19397 }
19398 if(m_oldBndryCells.size() > 0 && !m_oldBndryCells.count(cellId)) {
19399 if(!a_hasProperty(cellId, SolverCell::WasInactive)) {
19400 auto it = std::find(m_refOldBndryCells.begin(), m_refOldBndryCells.end(), c_parentId(cellId));
19401 if(it == m_refOldBndryCells.end()) {
19402 cerr << "CellId " << cellId << " " << c_globalId(cellId) << " isHalo " << a_isHalo(cellId)
19403 << " is GapCell " << a_isGapCell(cellId) << " was GapCell " << a_wasGapCell(cellId)
19404 << " was not inactive before and is a new bndryCell with Id " << bCellId << " ls-value "
19405 << a_levelSetValuesMb(cellId, 0) << " at timeStep " << globalTimeStep << endl;
19406 }
19407 }
19408 }
19409 }
19410 }
19411 }
19412#endif
19413
19414 for(MInt face = 0; face < m_noDirs; face++)
19415 m_fvBndryCnd->m_bndryCells->a[bCellId].m_associatedSrfc[face] = -1;
19416
19417 a_bndryId(cellId) = bCellId;
19418 m_fvBndryCnd->m_bndryCells->a[bCellId].m_cellId = cellId;
19419
19420 for(MInt srfc = 0; srfc < FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces; srfc++) {
19421 m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcs[srfc]->m_noCutPoints = 0;
19422 m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_ghostCellId = -1;
19423 for(MInt i = 0; i < nDim; i++)
19424 m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
19425 m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcs[srfc]->m_bndryCndId = -1; // m_movingBndryCndId;
19426 for(MInt v = 0; v < m_noCVars; v++) {
19427 m_fvBndryCnd->m_bndryCell[bCellId].m_srfcVariables[srfc]->m_variablesType[v] = BC_UNSET;
19428 }
19429 m_fvBndryCnd->m_bndryCells->a[bCellId].m_srfcs[srfc]->m_area = F0;
19430 }
19431 m_fvBndryCnd->m_bndryCell[bCellId].m_recNghbrIds.clear();
19432 m_fvBndryCnd->m_bndryCell[bCellId].m_faceVertices.clear();
19433 m_fvBndryCnd->m_bndryCell[bCellId].m_faceStream.resize(0);
19434
19435 m_fvBndryCnd->m_bndryCells->a[bCellId].m_linkedCellId = -1;
19436 m_fvBndryCnd->m_bndryCells->a[bCellId].m_noSrfcs = 1;
19437 m_fvBndryCnd->m_bndryCells->a[bCellId].m_volume = F0;
19438
19439 m_sweptVolume[bCellId] = F0;
19440 m_sweptVolumeDt1[bCellId] = F0;
19441
19442 a_hasProperty(cellId, SolverCell::IsInactive) = false;
19443 a_hasProperty(cellId, SolverCell::IsFlux) = true;
19444 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = true;
19445 a_hasProperty(cellId, SolverCell::IsMovingBnd) = true;
19446
19447 for(MInt i = 0; i < nDim; i++) {
19448 m_fvBndryCnd->m_bndryCells->a[bCellId].m_coordinates[i] = F0;
19449 }
19450
19451 for(MInt dir = 0; dir < m_noDirs; dir++) {
19452 m_cutFaceArea[bCellId][dir] = F0;
19453 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
19454 if(srfcId > -1) {
19455 m_bndryCells->a[bCellId].m_associatedSrfc[dir] = m_cellSurfaceMapping[cellId][dir];
19456 }
19457 }
19458
19460
19461 return bCellId;
19462}
void saveSolverSolution(const MBool forceOutput=false, const MBool finalTimeStep=false) override
Manages solver-specific output.
@ BC_UNSET
Definition: enums.h:334

◆ createBodyTree() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::createBodyTree
Author

Definition at line 7878 of file fvmbcartesiansolverxd.cpp.

7878 {
7879 rebuildKDTree();
7880
7882 const MFloat delta0 = F2 * c_cellLengthAtLevel(maxRefinementLevel());
7883 const MFloat deltaMax = F2 * m_maxBodyRadius + delta0;
7884 MIntScratchSpace nearBodies(m_noEmbeddedBodies, AT_, "nearBodies");
7885 MFloatScratchSpace minDist(m_noLevelSetsUsedForMb, AT_, "minDist");
7886
7887 for(MInt i = 0; i < m_noLevelSetsUsedForMb; i++) {
7888 for(MInt j = 0; j < m_maxNoEmbeddedBodiesPeriodic; j++) {
7889 m_setToBodiesTable[i][j] = -1;
7890 }
7891 m_noBodiesInSet[i] = 0;
7892 }
7893 for(MInt i = 0; i < m_maxNoEmbeddedBodiesPeriodic; i++) {
7894 m_bodyToSetTable[i] = -1;
7895 }
7896 if(m_startSet > 0) {
7897 m_noBodiesInSet[0] = 0;
7898 for(MInt i = 0; i < m_noEmbeddedBodies + m_noPeriodicGhostBodies; i++) {
7900 m_noBodiesInSet[0]++;
7901 }
7902 }
7904
7905
7907 MInt id = m_startSet;
7908
7910 Point<3> pt(m_bodyCenter[p * nDim], m_bodyCenter[p * nDim + 1], m_bodyCenter[p * nDim + 2]);
7911 MInt noNearBodies = locatenear(pt, deltaMax, &nearBodies[0], m_noEmbeddedBodies);
7912 MBool overlap = true;
7913 minDist.fill(c_cellLengthAtLevel(0));
7914
7915 while(overlap && id < m_noLevelSetsUsedForMb) {
7916 overlap = false;
7917 for(MInt b = 0; b < noNearBodies; b++) {
7918 const MInt q = nearBodies[b];
7919 if(p == q) continue;
7920 if(m_bodyToSetTable[q] == id) {
7921 overlap = true;
7922 MFloat dist = sqrt(POW2(m_bodyCenter[p * nDim] - m_bodyCenter[q * nDim])
7923 + POW2(m_bodyCenter[p * nDim + 1] - m_bodyCenter[q * nDim + 1])
7924 + POW2(m_bodyCenter[p * nDim + 2] - m_bodyCenter[q * nDim + 2]))
7925 - F2 * m_maxBodyRadius;
7926 minDist(id) = mMin(minDist(id), dist);
7927 ASSERT(dist < delta0 + m_eps, "");
7928 break;
7929 }
7930 }
7931 if(overlap) id++;
7932 }
7933
7934 if(overlap) {
7935 id = m_startSet;
7936 for(MInt i = m_startSet; i < m_noLevelSetsUsedForMb; i++) {
7937 if(minDist(i) > minDist(id)) id = i;
7938 }
7939
7940 cerr0 << domainId() << ": Not enough level sets to prevent overlap: " << p << " " << id << " "
7941 << minDist(id) / c_cellLengthAtLevel(m_lsCutCellMinLevel) << " " << m_maxBodyRadius << endl;
7942 }
7943
7947 } else {
7948 id = m_startSet + p % (m_noLevelSetsUsedForMb - 1);
7949 if(id >= m_noLevelSetsUsedForMb) mTerm(1, AT_, "Wrong set handling");
7953 }
7954 m_noSets = mMax(m_noSets, id + 1);
7955 }
7956 }
7957
7959}
static MInt locatenear(const Point< nDim > &, MFloat, MInt *, MInt, MBool returnCellId=true)
void updateGeometry()
Updates the member-variables in the geometry-intersection class.
MInt id
Definition: maiatypes.h:71

◆ createBodyTree() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void FvMbCartesianSolverXD< nDim, SysEqn >::createBodyTree ( )

◆ createCutFaceMb()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::createCutFaceMb ( )

◆ createCutFaceMb_MGC() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::createCutFaceMb_MGC
Author
Claudia Guenther
Date
30.07.2013 computes the following moving boundary cell member variables:
  • m_srfcs[0]->m_area
  • m_srfcs[0]->m_coordinates
  • m_srfcs[0]->m_volume
  • m_srfcs[0]->m_normalVector
  • m_noNonFluidsSideIds
  • m_externalFaces

Definition at line 34048 of file fvmbcartesiansolverxd.cpp.

34048 {
34049 TRACE();
34050
34054 if(first) {
34055 bodyFaceJoinMode = Context::getSolverProperty<MInt>("bodyFaceJoinMode", solverId(), AT_, &bodyFaceJoinMode);
34056 maxA = Context::getSolverProperty<MFloat>("bodyFaceJoinCriterion", solverId(), AT_, &maxA);
34057 first = false;
34058 }
34059
34060 const MInt faceOrder[4] = {2, 1, 3, 0};
34061 const MFloat signStencil[8][3] = {{-F1, -F1, -F1}, {F1, -F1, -F1}, {-F1, F1, -F1}, {F1, F1, -F1},
34062 {-F1, -F1, F1}, {F1, -F1, F1}, {-F1, F1, F1}, {F1, F1, F1}};
34063 const MInt edgeCornerCode[4][2] = {{2, 0}, {1, 3}, {0, 1}, {3, 2}};
34064
34065 const MInt maxNoSets = 6;
34066 ASSERT2(m_noLevelSetsUsedForMb < maxNoSets, "");
34067 MIntScratchSpace outcode_set(m_noLevelSetsUsedForMb, AT_, "outcode_set");
34068 MIntScratchSpace noCutPointsFromSet(m_noLevelSetsUsedForMb, AT_, "noCutPointsFromSet");
34069 MIntScratchSpace cutSetPointers(m_noLevelSetsUsedForMb, AT_, "cutSetPointers");
34070
34071 const MInt maxNoVertices = 25;
34072 const MInt maxNoEdges = 25;
34073
34074 stack<MInt> multiEdgeStack;
34075 std::vector<polyVertex> vertices[maxNoSets];
34076 std::vector<polyEdge2D> edges[maxNoSets];
34077 std::vector<polyCutCell> cutCells;
34078
34079 std::vector<CsgPolygon> csg_polygons;
34080 std::vector<CsgVertex> csg_vertices;
34081 std::vector<Csg> csg;
34082 std::vector<CsgPolygon> result;
34083 std::vector<polyVertex> vertices_result;
34084 stack<MInt> edgeStack;
34085 std::vector<MInt> faceVertices;
34086
34087 MIntScratchSpace multiEdgeConnection(maxNoEdges, AT_, "multiEdgeConnection");
34088 MIntScratchSpace vertices_renamed(2, maxNoVertices, AT_, "vertices_renamed");
34089 MIntScratchSpace bodyFaces(maxNoEdges, AT_, "bodyFaces");
34090 MFloatScratchSpace normalDotProduct(maxNoEdges, maxNoEdges, AT_, "normalDotProduct"); // stores 1 - n1*n2 -> in [0;2]
34091 MIntScratchSpace pointEdgeId(2 * m_noEdges, AT_, "pointEdgeId");
34092 MIntScratchSpace newCutPointId(maxNoVertices, AT_, "newCutPointId");
34093 MBoolScratchSpace isPartOfBodySurface(maxNoVertices, AT_, "isPartOfBodySurface");
34094 MIntScratchSpace tmp_Edges(maxNoEdges, AT_, "tmp_Edges");
34095 MIntScratchSpace vertexCutCellPointer(maxNoEdges, AT_, "vertexCutCellPointer");
34096
34097 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
34098 FvBndryCell<2, SysEqn>* bndryCell = &m_fvBndryCnd->m_bndryCells->a[bndryId];
34099 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
34100 const MInt cndId = m_bndryCandidateIds[cellId];
34101 ASSERT(cndId > -1, "");
34102
34103 for(MInt f = 0; f < m_noDirs; f++) {
34104 bndryCell->m_externalFaces[f] = false;
34105 }
34106
34107 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints == 0) {
34108 cerr << "** fvmbsolver2d ERROR" << endl;
34109 cerr << "boundary cell " << bndryId << endl;
34110 cerr << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << endl;
34111 cerr << " -> number of cut points is zero" << endl;
34112 continue;
34113 }
34114
34115 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints % 2 != 0) {
34116 cerr << "** fvmbsolver2d ERROR" << endl;
34117 cerr << "boundary cell " << bndryId << endl;
34118 cerr << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << endl;
34119 cerr << " -> number of cut points uneven" << endl;
34120 continue;
34121 }
34122
34123 const MFloat cellLength0 = c_cellLengthAtLevel(a_level(cellId));
34124 const MFloat cellHalfLength = F1B2 * cellLength0;
34125
34126 // reset some variables
34127 for(MInt s = 0; s < m_noLevelSetsUsedForMb; s++) {
34128 vertices[s].clear();
34129 edges[s].clear();
34130 cutSetPointers[s] = -1;
34131 noCutPointsFromSet[s] = 0;
34132 }
34133 cutCells.clear();
34134
34135 MBool isGapCell = false;
34136 if(m_levelSet && m_closeGaps) {
34137 isGapCell = (a_hasProperty(cellId, SolverCell::IsGapCell));
34138 }
34139 MInt startSet = 0;
34140 MInt endSet = 1;
34141 if(m_complexBoundary && m_noLevelSetsUsedForMb > 1 && (!isGapCell)) {
34142 startSet = 1;
34143 endSet = m_noLevelSetsUsedForMb;
34144 } else if(m_complexBoundary && m_noLevelSetsUsedForMb > 1 && (isGapCell)) {
34145 startSet = 0;
34146 endSet = 1;
34147 }
34148
34149 // preprocess cut points - find out which level set functions contain relevant cut points
34150 // if no relevant cut points are present -> don't cut the cell with the set
34151 MInt noCutSets = 0;
34152 MBool isCompletelyOutside = false;
34153 for(MInt s = startSet; s < endSet; s++) {
34154 // 1.1. get In/Outcode of the corners of the voxel
34155 // 0 -> Corner is outside Fluid Domain
34156 // 1 -> Corner is inside Fluid Domain or on Boundary
34157 unsigned char outcode = 0;
34158 for(MInt c = 0; c < m_noCorners; c++) {
34159 MBool currentOutcode = (!m_pointIsInside[bndryId][IDX_LSSETMB(c, s)]);
34160 if(currentOutcode) outcode = outcode | (1 << c);
34161 }
34162 outcode_set[s] = outcode;
34163 if(outcode == 0) isCompletelyOutside = true;
34164 }
34165 for(MInt cutPoint = 0; cutPoint < bndryCell->m_srfcs[0]->m_noCutPoints; cutPoint++) {
34166 ASSERT(bndryCell->m_srfcs[0]->m_bodyId[cutPoint] > -1
34167 && bndryCell->m_srfcs[0]->m_bodyId[cutPoint] < m_noEmbeddedBodies,
34168 "bodyId out of bounds " + to_string(cellId) + " " + to_string(cutPoint) + " "
34169 + to_string(bndryCell->m_srfcs[0]->m_bodyId[cutPoint]));
34170 MInt set = 0;
34171 if(m_complexBoundary && m_noLevelSetsUsedForMb > 1 && (!isGapCell))
34172 set = m_bodyToSetTable[bndryCell->m_srfcs[0]->m_bodyId[cutPoint]];
34173 ASSERT(set > -1 && set < m_noLevelSetsUsedForMb, "set out of bounds " + to_string(cellId) + " "
34174 + to_string(cutPoint) + " " + to_string(set) + " "
34175 + to_string(bndryCell->m_srfcs[0]->m_bodyId[cutPoint]));
34176 noCutPointsFromSet[set]++;
34177 }
34178 for(MInt set = startSet; set < endSet; set++) {
34179 if(noCutPointsFromSet[set] && !isCompletelyOutside) {
34180 cutSetPointers[set] = noCutSets++;
34181 }
34182 }
34183
34184 // computation of cuts with individual sets
34185 for(MInt set = startSet; set < endSet; set++) {
34186 MInt setIndex = cutSetPointers[set];
34187 if(setIndex < 0) continue;
34188 MInt bodyId = a_associatedBodyIds(cellId, set);
34189 if(bodyId < 0) continue;
34190
34191 // store all cut points in a separate array
34192 // and prepare all vertices for polyeder/polygon datastructure
34193 // vertices = cut points and fluid corners of the cell
34194 MInt cutPoints[4] = {-1, -1, -1, -1};
34195 MInt cutPointToVertexMap[4] = {-1, -1, -1, -1};
34196 MInt noCutPoints = 0;
34197 for(MInt cutPoint = 0; cutPoint < bndryCell->m_srfcs[0]->m_noCutPoints; cutPoint++) {
34198 if(m_complexBoundary && m_noLevelSetsUsedForMb > 1 && (!isGapCell))
34199 if(m_bodyToSetTable[bndryCell->m_srfcs[0]->m_bodyId[cutPoint]] != set) continue;
34200 noCutPoints++;
34201 cutPoints[bndryCell->m_srfcs[0]->m_cutEdge[cutPoint]] = cutPoint;
34202 vertices[setIndex].push_back(polyVertex(bndryCell->m_srfcs[0]->m_cutCoordinates[cutPoint], cutPoint, 1));
34203 cutPointToVertexMap[cutPoint] = vertices[setIndex].size() - 1;
34204 }
34205 MInt cornerToVertexMap[4] = {-1, -1, -1, -1};
34206 for(MInt c = 0; c < m_noCorners; c++) {
34207 if(!m_pointIsInside[bndryId][IDX_LSSETMB(c, set)]) {
34208 MFloat tmp_coords[2];
34209 for(MInt i = 0; i < nDim; i++)
34210 tmp_coords[i] = a_coordinate(cellId, i) + signStencil[c][i] * cellHalfLength;
34211 vertices[setIndex].push_back(polyVertex(tmp_coords, c, 0));
34212 cornerToVertexMap[c] = vertices[setIndex].size() - 1;
34213 }
34214 }
34215
34216 // 1. find correct marching cubes state and substate -> including disambiguation
34217
34218 // 1.1. get In/Outcode of the corners of the voxel
34219 // 0 -> Corner is outside Fluid Domain
34220 // 1 -> Corner is inside Fluid Domain or on Boundary
34221 MInt outcode = outcode_set[set];
34222
34223 // 1.2. determine Case and check if case is implemented
34224 MInt currentCase = (MInt)cases2D[outcode][0];
34225 MInt currentSubCase = (MInt)cases2D[outcode][1];
34226 MInt subConfig = 0;
34227 // 1.2 determine ambiguous cells
34228 if(!caseStates2D[currentCase]) { // ambiguous case -> disambiguate
34229 MBool centerIsFluid = test_face(cndId, 4, set);
34230 if((centerIsFluid && currentSubCase == 1) || (!centerIsFluid && currentCase == 0)) subConfig = 1;
34231 }
34232 // 1.3. decide which tiling should be used, how many triangles are to be created for the cut face(s), etc.
34233 MInt noLines = 0;
34234 const MInt* tilingPointer = nullptr;
34235 noLines = noEdges2D[currentCase];
34236 switch(currentCase) {
34237 case 0:
34238 break;
34239
34240 case 1:
34241 tilingPointer = tiling1_2D[currentSubCase];
34242 break;
34243 case 2:
34244 tilingPointer = tiling2_2D[currentSubCase];
34245 break;
34246 case 3: {
34247 if(subConfig == 0)
34248 tilingPointer = tiling3_A_2D[currentSubCase];
34249 else
34250 tilingPointer = tiling3_B_2D[currentSubCase];
34251 break;
34252 }
34253 default:
34254 mTerm(1, AT_, "invalid MC case, how could this happen? exiting...");
34255 break;
34256 }
34257
34258 // 2. build edges for body surfaces -> MC
34259 for(MInt t = 0; t < noLines; t++) {
34260 // create a new edge
34261 MInt p[2];
34262 MInt cutEdge0 = tilingPointer[t * 2 + 0];
34263 MInt cutEdge1 = tilingPointer[t * 2 + 1];
34264 MInt p0 = cutPoints[cutEdge0];
34265 MInt p1 = cutPoints[cutEdge1];
34266 p[0] = cutPointToVertexMap[p0];
34267 p[1] = cutPointToVertexMap[p1];
34268 MInt newEdge = edges[setIndex].size();
34269 MInt edgeType = 2;
34270 MInt edgeId = -1;
34271 edges[setIndex].push_back(polyEdge2D(p[0], p[1], edgeId, edgeType, bodyId));
34272 vertices[setIndex][p[0]].edges.push_back(newEdge);
34273 vertices[setIndex][p[1]].edges.push_back(newEdge);
34274
34275 // compute normal of edge:
34276 computeNormal(vertices[setIndex][p[0]].coordinates, vertices[setIndex][p[1]].coordinates,
34277 edges[setIndex][newEdge].normal, edges[setIndex][newEdge].w);
34278 }
34279
34280 // 3. prepare basic edges -> between two inside corner vertices or between a corner vertex and a cut point
34281 for(MInt e = 0; e < m_noEdges; e++) {
34282 MInt edge = faceOrder[e];
34283 MBool p0Fluid = !m_pointIsInside[bndryId][IDX_LSSETMB(edgeCornerCode[edge][0], set)];
34284 MBool p1Fluid = !m_pointIsInside[bndryId][IDX_LSSETMB(edgeCornerCode[edge][1], set)];
34285 if(p0Fluid && p1Fluid) { // created a full Cartesian edge
34286 MInt v0 = cornerToVertexMap[edgeCornerCode[edge][0]];
34287 MInt v1 = cornerToVertexMap[edgeCornerCode[edge][1]];
34288 edges[setIndex].push_back(polyEdge2D(v0, v1, edge, 0, -1));
34289 vertices[setIndex][v0].edges.push_back(edges[setIndex].size() - 1);
34290 vertices[setIndex][v1].edges.push_back(edges[setIndex].size() - 1);
34291 computeNormal(vertices[setIndex][v0].coordinates, vertices[setIndex][v1].coordinates,
34292 edges[setIndex][edges[setIndex].size() - 1].normal,
34293 edges[setIndex][edges[setIndex].size() - 1].w);
34294 } else if(p0Fluid) { // create a cut edge from p0 to cut point
34295 MInt v0 = cornerToVertexMap[edgeCornerCode[edge][0]];
34296 MInt v1 = cutPointToVertexMap[cutPoints[edge]];
34297 edges[setIndex].push_back(polyEdge2D(v0, v1, edge, 1, -1));
34298 vertices[setIndex][v0].edges.push_back(edges[setIndex].size() - 1);
34299 vertices[setIndex][v1].edges.push_back(edges[setIndex].size() - 1);
34300 computeNormal(vertices[setIndex][v0].coordinates, vertices[setIndex][v1].coordinates,
34301 edges[setIndex][edges[setIndex].size() - 1].normal,
34302 edges[setIndex][edges[setIndex].size() - 1].w);
34303 } else if(p1Fluid) { // create a cut edge from cut point to p1
34304 MInt v0 = cutPointToVertexMap[cutPoints[edge]];
34305 MInt v1 = cornerToVertexMap[edgeCornerCode[edge][1]];
34306 edges[setIndex].push_back(polyEdge2D(v0, v1, edge, 1, -1));
34307 vertices[setIndex][v0].edges.push_back(edges[setIndex].size() - 1);
34308 vertices[setIndex][v1].edges.push_back(edges[setIndex].size() - 1);
34309 computeNormal(vertices[setIndex][v0].coordinates, vertices[setIndex][v1].coordinates,
34310 edges[setIndex][edges[setIndex].size() - 1].normal,
34311 edges[setIndex][edges[setIndex].size() - 1].w);
34312 } // else create no edge since edge is fully located outside
34313 }
34314 }
34315
34316 // 4.a combine polygons that are computed with different sets to one polygon
34317 // set up the CSG datastructure for each polygon
34318 // MBool error = false;
34319 const MInt startSetIndex = 0;
34320 MInt referenceSet = startSet;
34321 for(MInt set = startSet; set < endSet; set++) {
34322 if(cutSetPointers[set] > -1) {
34323 referenceSet = set;
34324 break;
34325 }
34326 }
34327 for(MInt set = referenceSet + 1; set < endSet; set++) {
34328 MInt setIndex = cutSetPointers[set];
34329 if(setIndex < 0) continue;
34330 csg.clear();
34331 csg_polygons.clear();
34332
34333 for(MInt e = 0; (unsigned)e < edges[startSetIndex].size(); e++) {
34334 csg_vertices.clear();
34335 MInt vertex0 = edges[startSetIndex][e].vertices[0];
34336 MInt vertex1 = edges[startSetIndex][e].vertices[1];
34337 csg_vertices.push_back(
34338 CsgVertex(CsgVector(vertices[startSetIndex][vertex0].coordinates), vertex0, startSetIndex));
34339 csg_vertices.push_back(
34340 CsgVertex(CsgVector(vertices[startSetIndex][vertex1].coordinates), vertex1, startSetIndex));
34341 csg_polygons.push_back(CsgPolygon(csg_vertices, startSetIndex, edges[startSetIndex][e].edgeId,
34342 edges[startSetIndex][e].edgeType, edges[startSetIndex][e].bodyId));
34343 }
34344 csg.push_back(Csg(csg_polygons));
34345
34346 csg_polygons.clear();
34347 for(MInt e = 0; (unsigned)e < edges[setIndex].size(); e++) {
34348 csg_vertices.clear();
34349 MInt vertex0 = edges[setIndex][e].vertices[0];
34350 MInt vertex1 = edges[setIndex][e].vertices[1];
34351 csg_vertices.push_back(CsgVertex(CsgVector(vertices[setIndex][vertex0].coordinates), vertex0, setIndex));
34352 csg_vertices.push_back(CsgVertex(CsgVector(vertices[setIndex][vertex1].coordinates), vertex1, setIndex));
34353 csg_polygons.push_back(CsgPolygon(csg_vertices, setIndex, edges[setIndex][e].edgeId,
34354 edges[setIndex][e].edgeType, edges[setIndex][e].bodyId));
34355 }
34356 csg.push_back(Csg(csg_polygons));
34357
34358 // call intersect
34359 result.clear();
34360 result = csg[0].intersect(csg[1]);
34361 vertices_result.clear();
34362
34363 // post process vertices, edges, faces:
34364 // first: regenerate polyVertices (unique vertices) vector
34365 for(MInt i = 0; i < 2; i++)
34366 for(MInt j = 0; j < maxNoVertices; j++)
34367 vertices_renamed(i, j) = -1;
34368
34369 MInt noVertices = 0;
34370 for(MInt p = 0; (unsigned)p < result.size(); p++) {
34371 for(MInt v = 0; (unsigned)v < result[p].vertices.size(); v++) {
34372 ASSERT(result[p].vertices.size() <= (unsigned)maxNoVertices, "");
34373 MInt vertexId = result[p].vertices[v].vertexId;
34374 MInt vertexSetIndex = result[p].vertices[v].setIndex;
34375 if(vertexId > -1) { // vertex corresponds to an existing vertex
34376 if(vertices_renamed(vertexSetIndex, vertexId) == -1) {
34377 // check if vertex has been added to vertices_result vector
34378 MBool vertexFound = false;
34379 MInt vertexIndex = -1;
34380 for(MInt i = 0; (unsigned)i < vertices_result.size(); i++) {
34381 if(vertices_result[i].pointType != 3) continue;
34382 MFloat coord_diff = F0;
34383 coord_diff += (result[p].vertices[v].pos.xx[0] - vertices_result[i].coordinates[0])
34384 * (result[p].vertices[v].pos.xx[0] - vertices_result[i].coordinates[0]);
34385 coord_diff += (result[p].vertices[v].pos.xx[1] - vertices_result[i].coordinates[1])
34386 * (result[p].vertices[v].pos.xx[1] - vertices_result[i].coordinates[1]);
34387
34388 if(coord_diff < m_eps * 10) {
34389 vertexFound = true;
34390 vertexIndex = i;
34391 break;
34392 }
34393 }
34394 if(vertexFound) {
34395 vertices_renamed(vertexSetIndex, vertexId) = vertexIndex;
34396 } else {
34397 vertices_renamed(vertexSetIndex, vertexId) = noVertices;
34398 vertices_result.push_back(polyVertex(vertices[vertexSetIndex][vertexId].pointId,
34399 vertices[vertexSetIndex][vertexId].pointType));
34400 vertices_result[noVertices].coordinates[0] = vertices[vertexSetIndex][vertexId].coordinates[0];
34401 vertices_result[noVertices].coordinates[1] = vertices[vertexSetIndex][vertexId].coordinates[1];
34402 noVertices++;
34403 }
34404 }
34405 result[p].vertices[v].vertexId = vertices_renamed(vertexSetIndex, vertexId);
34406 result[p].vertices[v].setIndex = -1;
34407 }
34408 }
34409 }
34410 for(MInt p = 0; (unsigned)p < result.size(); p++) {
34411 for(MInt v = 0; (unsigned)v < result[p].vertices.size(); v++) {
34412 MInt vertexId = result[p].vertices[v].vertexId;
34413 if(vertexId == -1) { // remaining vertices...
34414 // check if vertex has been added to vertices_result vector
34415 MBool vertexFound = false;
34416 MInt vertexIndex = -1;
34417 for(MInt i = 0; (unsigned)i < vertices_result.size(); i++) {
34418 MFloat coord_diff = F0;
34419 coord_diff += (result[p].vertices[v].pos.xx[0] - vertices_result[i].coordinates[0])
34420 * (result[p].vertices[v].pos.xx[0] - vertices_result[i].coordinates[0]);
34421 coord_diff += (result[p].vertices[v].pos.xx[1] - vertices_result[i].coordinates[1])
34422 * (result[p].vertices[v].pos.xx[1] - vertices_result[i].coordinates[1]);
34423
34424 if(coord_diff < m_eps * 10) {
34425 vertexFound = true;
34426 vertexIndex = i;
34427 break;
34428 }
34429 }
34430 if(vertexFound) {
34431 result[p].vertices[v].vertexId = vertexIndex;
34432 result[p].vertices[v].setIndex = -1;
34433 } else {
34434 vertices_result.push_back(polyVertex(-1, 3));
34435 vertices_result[noVertices].coordinates[0] = result[p].vertices[v].pos.xx[0];
34436 vertices_result[noVertices].coordinates[1] = result[p].vertices[v].pos.xx[1];
34437 result[p].vertices[v].vertexId = noVertices;
34438 result[p].vertices[v].setIndex = -1;
34439 noVertices++;
34440 }
34441 }
34442 }
34443 }
34444
34445 vertices[startSetIndex].swap(vertices_result);
34446 vertices_result.clear();
34447 edges[startSetIndex].clear();
34448 // second: regenerate edges and faces vectors (unique edges)
34449 MInt noFaces = 0;
34450 MInt noEdges = 0;
34451 for(MInt p = 0; (unsigned)p < result.size(); p++) {
34452 MInt bId = result[p].bodyId;
34453 MInt eId = result[p].faceId;
34454 MInt eType = result[p].faceType;
34455
34456 // add edges
34457 for(MInt v = 0; (unsigned)v < result[p].vertices.size() - 1; v++) {
34458 MInt j = (v + 1) % result[p].vertices.size();
34459 MInt vertexId = result[p].vertices[v].vertexId;
34460 MInt vertexIdNext = result[p].vertices[j].vertexId;
34461 MBool edgeFound = false;
34462 for(MInt e = 0; (unsigned)e < edges[startSetIndex].size(); e++) {
34463 MInt v0 = edges[startSetIndex][e].vertices[0];
34464 MInt v1 = edges[startSetIndex][e].vertices[1];
34465 if(vertexId == v0 && vertexIdNext == v1) {
34466 edgeFound = true;
34467 break;
34468 } else if(vertexId == v1 && vertexIdNext == v0) {
34469 edgeFound = true;
34470 break;
34471 }
34472 }
34473 if(!edgeFound) {
34474 edges[startSetIndex].push_back(polyEdge2D(vertexId, vertexIdNext, eId, eType, bId));
34475 vertices[startSetIndex][vertexId].edges.push_back(noEdges);
34476 vertices[startSetIndex][vertexIdNext].edges.push_back(noEdges);
34477 edges[startSetIndex][noEdges].normal[0] = result[p].plane.normal.xx[0];
34478 edges[startSetIndex][noEdges].normal[1] = result[p].plane.normal.xx[1];
34479 edges[startSetIndex][noEdges].w = -result[p].plane.w;
34480 noEdges++;
34481 }
34482 }
34483 noFaces++;
34484 }
34485 // TODO labels:FVMB change CSG routine such that it works with the present datastructure!
34486 }
34487
34488 // debug: test, if each vertex has exactly 2 edges:
34489 for(MInt v = 0; (unsigned)v < vertices[startSetIndex].size(); v++) {
34490 if(vertices[startSetIndex][v].edges.size() == 2) continue;
34491 cerr << " Error on cell " << cellId << ". Cell has vertex with not 2 edges... " << v << "/"
34492 << vertices[startSetIndex][v].edges.size() << endl;
34493 writeVTKFileOfCell(cellId, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34494 outputPolyData(cellId, &cutCells, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34495 ASSERT(vertices[startSetIndex][v].edges.size() == 2, "");
34496 }
34497
34498 // 4. b compose cell
34499 if(edges[startSetIndex].size() == 0) {
34500 cutCells.push_back(polyCutCell(bndryId, &a_coordinate(cellId, 0)));
34501 }
34502 for(MInt edgeCounter = 0; (unsigned)edgeCounter < edges[startSetIndex].size(); edgeCounter++) {
34503 if(edges[startSetIndex][edgeCounter].cutCell > -1) continue;
34504 edgeStack.push(edgeCounter);
34505 MInt currentCutCell = cutCells.size();
34506 cutCells.push_back(polyCutCell(bndryId, &a_coordinate(cellId, 0)));
34507 edges[startSetIndex][edgeCounter].cutCell = currentCutCell;
34508 cutCells[currentCutCell].faces_edges.push_back(edgeCounter);
34509 while(!edgeStack.empty()) {
34510 MInt currentEdge = edgeStack.top();
34511 edgeStack.pop();
34512 MInt vertex = edges[startSetIndex][currentEdge].vertices[1];
34513 MInt otherEdge = vertices[startSetIndex][vertex].edges[0];
34514 if(otherEdge == currentEdge) otherEdge = vertices[startSetIndex][vertex].edges[1];
34515 if(edges[startSetIndex][otherEdge].cutCell == -1) {
34516 cutCells[currentCutCell].faces_edges.push_back(otherEdge);
34517 edges[startSetIndex][otherEdge].cutCell = currentCutCell;
34518 edgeStack.push(otherEdge);
34519 }
34520 }
34521 }
34522
34523 // 5. compute polyhedron(polyhedra)
34524 compVolumeIntegrals(&cutCells, &edges[startSetIndex], &vertices[startSetIndex]);
34525
34526 // 5.1. if required, join cut surfaces if their normal vectors are similar enough
34527
34528 // 6. relate polyhedron(polyhedra) quantities to Cartesian cell quantities -> finish cell
34529 // 6.0. Currently: Split cells and split Cartesian surfaces are not allowed -> check here!
34530 if(cutCells.size() > 1) {
34531 cerr << "split cell detected. These are not implemented in MB framework yet. cell " << cellId << endl;
34532 writeVTKFileOfCell(cellId, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34533 outputPolyData(cellId, &cutCells, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34534 mTerm(1, AT_, "split cell detected. These are not implemented in MB framework yet. exiting...");
34535 continue;
34536 }
34537 MInt noFacesPerCartesianFace[6] = {0, 0, 0, 0};
34538 MInt noBodySurfaces = 0;
34539 for(MInt e = 0; (unsigned)e < cutCells[0].faces_edges.size(); e++) {
34540 MInt edge = cutCells[0].faces_edges[e];
34541 if(edges[startSetIndex][edge].edgeType == 0 || edges[startSetIndex][edge].edgeType == 1)
34542 noFacesPerCartesianFace[edges[startSetIndex][edge].edgeId]++;
34543 else
34544 noBodySurfaces++;
34545 }
34546 for(MInt i = 0; i < m_noDirs; i++) {
34547 if(noFacesPerCartesianFace[i] > 1) {
34548 cerr << "split face detected. These are not implemented in MB framework yet. cell " << cellId << ", face " << i
34549 << endl;
34550 writeVTKFileOfCell(cellId, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34551 writeVTKFileOfCutCell(cellId, &cutCells, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34552 outputPolyData(cellId, &cutCells, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34553 mTerm(1, AT_, " split face detected. These are not implemented in MB framework yet. exiting...");
34554 continue;
34555 }
34556 }
34557 if(noBodySurfaces > FvBndryCell<2, SysEqn>::m_maxNoSurfaces) {
34558 cerr << "more than FvBndryCell<2,SysEqn>::m_maxNoSurfaces cut surfaces detected for a cell. This is not "
34559 "implemented "
34560 "in MB framework yet. cell "
34561 << cellId << endl;
34562 writeVTKFileOfCell(cellId, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34563 writeVTKFileOfCutCell(cellId, &cutCells, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34564 outputPolyData(cellId, &cutCells, &edges[startSetIndex], &vertices[startSetIndex], startSetIndex);
34565 mTerm(1, AT_,
34566 " more than 3 cut surfaces detected for a cell. This is not implemented in MB framework yet. "
34567 "exiting...");
34568 continue;
34569 }
34570
34571
34572 // 6.1. set bndry cell and surface properties
34573 // deactivate cells with no faces
34574 if(cutCells[0].faces_edges.size() == 0) {
34575 a_hasProperty(cellId, SolverCell::IsInactive) = true;
34576 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = false;
34577 cutCells[0].volume = F0;
34578 cutCells[0].center[0] = a_coordinate(cellId, 0);
34579 cutCells[0].center[1] = a_coordinate(cellId, 1);
34580 }
34581
34582 ASSERT(!(cutCells[0].volume < F0), "");
34583 ASSERT(!(std::isnan(cutCells[0].volume)), "");
34584 ASSERT(!(std::isnan(cutCells[0].center[0])), "");
34585 ASSERT(!(std::isnan(cutCells[0].center[1])), "");
34586 ASSERT(!(std::isinf(cutCells[0].volume)), "");
34587 ASSERT(!(std::isinf(cutCells[0].center[0])), "");
34588 ASSERT(!(std::isinf(cutCells[0].center[1])), "");
34589
34590 // non fluid sides:
34591 for(MInt f = 0; f < m_noDirs; f++) {
34592 if(noFacesPerCartesianFace[f] == 0) { // non fluid face
34593 bndryCell->m_externalFaces[f] = true;
34594 MInt srfcId = m_cellSurfaceMapping[cellId][f];
34595 if(srfcId > -1) {
34596 a_surfaceArea(srfcId) = F0;
34597 // m_isActiveSurface[ srfcId ] = false;
34598 deleteSurface(srfcId);
34599 }
34600 bndryCell->m_associatedSrfc[f] = -1;
34601 m_cutFaceArea[bndryId][f] = F0;
34602
34603 MInt nghbrId = c_neighborId(cellId, f);
34604 MInt nghbrBndryId = -1;
34605 if(nghbrId > -1) nghbrBndryId = a_bndryId(nghbrId);
34606
34607 if(nghbrBndryId > -1) {
34608 m_bndryCells->a[nghbrBndryId].m_associatedSrfc[m_revDir[f]] = -1;
34609 m_cutFaceArea[nghbrBndryId][m_revDir[f]] = F0;
34610 }
34611 }
34612 }
34613 // before reassigning cut points, store the relevant information
34614
34615 ASSERT(vertices[startSetIndex].size() <= (unsigned)maxNoVertices, "");
34616 for(MInt cp = 0; cp < maxNoVertices; cp++)
34617 newCutPointId[cp] = -1;
34618 for(MInt i = 0; (unsigned)i < vertices[startSetIndex].size(); i++)
34619 isPartOfBodySurface[i] = false;
34620 for(MInt e = 0; e < 2 * m_noEdges; e++) {
34621 pointEdgeId[e] = bndryCell->m_srfcs[0]->m_cutEdge[e];
34622 }
34623 noBodySurfaces = 0;
34624 bndryCell->m_volume = cutCells[0].volume;
34625 for(MInt i = 0; i < nDim; i++)
34626 bndryCell->m_coordinates[i] = cutCells[0].center[i] - a_coordinate(cellId, i);
34627 for(MInt f = 0; (unsigned)f < cutCells[0].faces_edges.size(); f++) {
34628 MInt edge = cutCells[0].faces_edges[f];
34629 ASSERT(!(edges[startSetIndex][edge].area < F0), "");
34630 ASSERT(!(std::isnan(edges[startSetIndex][edge].area)), "");
34631 ASSERT(!(std::isnan(edges[startSetIndex][edge].center[0])), "");
34632 ASSERT(!(std::isnan(edges[startSetIndex][edge].center[1])), "");
34633 ASSERT(!(std::isinf(edges[startSetIndex][edge].area)), "");
34634 ASSERT(!(std::isinf(edges[startSetIndex][edge].center[0])), "");
34635 ASSERT(!(std::isinf(edges[startSetIndex][edge].center[1])), "");
34636
34637 if(edges[startSetIndex][edge].edgeType > 1) { // body surface
34638 typename FvBndryCell<2, SysEqn>::BodySurface* bodySurface = bndryCell->m_srfcs[noBodySurfaces];
34639 bodySurface->m_area = edges[startSetIndex][edge].area;
34640 for(MInt i = 0; i < nDim; i++) {
34641 bodySurface->m_coordinates[i] = edges[startSetIndex][edge].center[i];
34642 bodySurface->m_normalVector[i] = edges[startSetIndex][edge].normal[i];
34643 }
34644 bodySurface->m_noCutPoints = 2;
34645 bodySurface->m_bndryCndId = m_movingBndryCndId;
34646 for(MInt cp = 0; (unsigned)cp < 2; cp++) {
34647 MInt vertex = edges[startSetIndex][edge].vertices[cp];
34648 isPartOfBodySurface[vertex] = true;
34649 MInt cutPointId = vertices[startSetIndex][vertex].pointId;
34650 newCutPointId[vertex] = cp;
34651 vertices[startSetIndex][vertex].cartSrfcId = noBodySurfaces;
34652 for(MInt i = 0; i < nDim; i++)
34653 bodySurface->m_cutCoordinates[cp][i] = vertices[startSetIndex][vertex].coordinates[i];
34654 if(cutPointId > -1) {
34655 bodySurface->m_cutEdge[cp] = pointEdgeId[cutPointId];
34656 bodySurface->m_bodyId[cp] = edges[startSetIndex][edge].bodyId;
34657 } else {
34658 bodySurface->m_cutEdge[cp] = -1;
34659 bodySurface->m_bodyId[cp] = edges[startSetIndex][edge].bodyId;
34660 }
34661 }
34662 noBodySurfaces++;
34663 } else { // Cartesian face
34664 MInt dirId = edges[startSetIndex][edge].edgeId;
34665 MInt srfcId = m_cellSurfaceMapping[cellId][dirId];
34666
34667 if(srfcId > -1) {
34668 for(MInt i = 0; i < nDim; i++) {
34669 a_surfaceCoordinate(srfcId, i) = edges[startSetIndex][edge].center[i];
34670 }
34671 a_surfaceArea(srfcId) = edges[startSetIndex][edge].area;
34672 bndryCell->m_associatedSrfc[dirId] = srfcId;
34673 }
34674 m_cutFaceArea[bndryId][dirId] = edges[startSetIndex][edge].area;
34675
34676 MInt nghbrId = c_neighborId(cellId, dirId);
34677 MInt nghbrBndryId = -1;
34678 if(nghbrId > -1) nghbrBndryId = a_bndryId(nghbrId);
34679 if(nghbrBndryId > -1) {
34680 m_bndryCells->a[nghbrBndryId].m_associatedSrfc[m_revDir[dirId]] = srfcId;
34681 m_cutFaceArea[nghbrBndryId][m_revDir[dirId]] = edges[startSetIndex][edge].area;
34682 }
34683 } // end else
34684 }
34685
34686 bndryCell->m_noSrfcs = (MInt)noBodySurfaces;
34687
34688 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
34689 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId = m_movingBndryCndId;
34690 }
34691
34692
34693 // transfer poly information to to output variables m_cutFacePointIds etc.
34694 m_noCutCellFaces[bndryId] = 0;
34695 const MInt maxPointsXD = 12;
34696 for(MInt c = 0; (unsigned)c < cutCells.size(); c++) {
34697 MInt nccf = m_noCutCellFaces[bndryId];
34698 m_noCutFacePoints[bndryId][nccf] = 0;
34699 for(MInt f = 0; (unsigned)f < cutCells[c].faces_edges.size(); f++) {
34700 MInt edge = cutCells[c].faces_edges[f];
34701 MInt vertex = edges[startSetIndex][edge].vertices[0];
34702 if(vertices[startSetIndex][vertex].pointType == 0) {
34703 m_cutFacePointIds[bndryId][maxPointsXD * nccf + m_noCutFacePoints[bndryId][nccf]] =
34704 vertices[startSetIndex][vertex].pointId;
34705 m_noCutFacePoints[bndryId][nccf]++;
34706 } else {
34707 if(!isPartOfBodySurface[vertex]) continue;
34708 MInt numCutPointsPreviousFaces = 0;
34709 for(MInt srfc = 0; srfc < vertices[startSetIndex][vertex].cartSrfcId; srfc++) {
34710 numCutPointsPreviousFaces += m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_noCutPoints;
34711 }
34712 MInt cp = numCutPointsPreviousFaces + newCutPointId[vertex];
34713 m_cutFacePointIds[bndryId][maxPointsXD * nccf + m_noCutFacePoints[bndryId][nccf]] = m_noCellNodes + (cp);
34714 m_noCutFacePoints[bndryId][nccf]++;
34715 }
34716 }
34717 m_noCutCellFaces[bndryId]++;
34718 }
34719 }
34720}
BodySurface ** m_srfcs
MFloat * m_coordinates
static void computeNormal(const MFloat *p0, const MFloat *p1, MFloat *res, MFloat &w)
returns the normal corresponding to the triangle abc and returns the result in res
void writeVTKFileOfCell(MInt, const std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt)
void compVolumeIntegrals(std::vector< polyCutCell > *, std::vector< polyEdge2D > *, const std::vector< polyVertex > *)
MBool test_face(MInt, MInt, MInt)
Test a face (MarchingCubes helper routine) receives MAIA face if face>0 return true if the face conta...
void deleteSurface(MInt srfcId)
removes the surfaces of the given cell
void writeVTKFileOfCutCell(MInt, std::vector< polyCutCell > *, const std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt)
void outputPolyData(const MInt, const std::vector< polyCutCell > *, const std::vector< polyEdge2D > *, const std::vector< polyVertex > *, MInt)
const MInt m_revDir[6]

◆ createCutFaceMb_MGC() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvMbCartesianSolverXD< nDim, SysEqn >::createCutFaceMb_MGC ( )

◆ createInitialSrfcs()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::createInitialSrfcs
Author
Lennart Schneiders

Definition at line 17032 of file fvmbcartesiansolverxd.cpp.

17032 {
17033 TRACE();
17034
17035 m_log << "Creating initial surfaces..." << endl;
17036
17037 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
17038 MFloatScratchSpace surfArea(noBndryCells, m_noDirs, AT_, "surfArea");
17039 MFloatScratchSpace surfCentroid(noBndryCells, m_noDirs, nDim, AT_, "surfCentroid");
17040 surfArea.fill(sqrt(-F1));
17041 surfCentroid.fill(sqrt(-F1));
17042 for(MInt srfcId = 0; srfcId < a_noSurfaces(); srfcId++) {
17043 for(MInt side = 0; side < 2; side++) {
17044 MInt ori = a_surfaceOrientation(srfcId);
17045 MInt cellId = a_surfaceNghbrCellId(srfcId, side);
17046 if(cellId > -1) {
17047 MInt bndryId = a_bndryId(cellId);
17048 if(bndryId > -1) {
17049 MInt dir = (side == 0) ? 2 * ori + 1 : 2 * ori;
17050 surfArea(bndryId, dir) = a_surfaceArea(srfcId);
17051
17052 for(MInt i = 0; i < nDim; i++) {
17053 surfCentroid(bndryId, dir, i) = a_surfaceCoordinate(srfcId, i);
17054 }
17055 }
17056 }
17057 }
17058 }
17059
17060 // store all surfaces that have been generated so far (Cartesian cut surfaces)
17061 // const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
17062
17063 // delete the surfaces that won't be required later
17064 // 1) store the relevant surfaces
17065 MInt counter = 0;
17066 MInt otherDir[] = {1, 0, 3, 2, 5, 4};
17067 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
17068 MInt cell = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
17069
17070 if(!a_hasProperty(cell, SolverCell::IsOnCurrentMGLevel)) continue;
17071 MInt nghbrId = -1;
17072 for(MInt dirId = 0; dirId < m_noDirs; dirId++) {
17073 if(a_hasNeighbor(cell, dirId) > 0) {
17074 nghbrId = c_neighborId(cell, dirId);
17075 } else {
17076 if(c_parentId(cell) > -1) {
17077 if(a_hasNeighbor(c_parentId(cell), dirId) > 0) {
17078 nghbrId = c_neighborId(c_parentId(cell), dirId);
17079 } else {
17080 continue;
17081 }
17082 } else {
17083 continue;
17084 }
17085 }
17086
17087 if(a_bndryId(nghbrId) < 0) continue;
17088 MBool createSrfc = true;
17089 // check conditions for surface generation
17090 // (1) no master-slave interface
17091 // (2) no slave-slave interface if both slave cells have the same master
17092 // (3) no periodic-periodic interface
17093 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
17094 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == nghbrId
17095 || m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId
17096 == m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId) {
17097 createSrfc = false;
17098 }
17099 }
17100 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId > -1) {
17101 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == (MInt)cell
17102 || m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId
17103 == m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId) {
17104 createSrfc = false;
17105 }
17106 }
17107 if(a_isPeriodic(cell) && a_isPeriodic(nghbrId)) createSrfc = false;
17108
17109 // do not create a surface between two halo cells
17110 // create a surface if slave-neighbor are both halo cells but the master is not
17111 if(a_isHalo(cell) && a_isHalo(nghbrId)) {
17112 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId == -1
17113 && m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_linkedCellId == -1) {
17114 createSrfc = false;
17115 }
17116 }
17117
17118 // this is valid for isotropical refinement only!!
17119 if(!createSrfc) continue;
17120
17121 if((a_level(cell) > a_level(nghbrId)) || ((a_level(cell) == a_level(nghbrId)) && dirId % 2 == 0)) {
17122 MInt oldSrfcId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_associatedSrfc[dirId];
17123
17124 if(oldSrfcId < 0) continue;
17125
17126 if(oldSrfcId != counter) {
17127 m_surfaces.copy(oldSrfcId, counter);
17128 m_surfaces.erase(oldSrfcId);
17129 if(a_level(cell) == a_level(nghbrId))
17130 m_fvBndryCnd->m_bndryCells->a[a_bndryId(nghbrId)].m_associatedSrfc[otherDir[dirId]] = counter;
17131 }
17132 counter++;
17133 }
17134 }
17135 }
17136
17137 // delete all other surfaces created in createCutFace
17138 while(a_noSurfaces() > counter) {
17139 MInt size = a_noSurfaces();
17140 m_surfaces.erase(size - 1);
17141 m_surfaces.size(size - 1);
17142 }
17143
17144 // store relevant surface information in scratch space
17145 MInt noSurfaces = a_noSurfaces();
17146 MIntScratchSpace surfaceOrientation(noSurfaces, AT_, "surfaceOrientation");
17147 MFloatScratchSpace surfaceArea(noSurfaces, AT_, "surfaceArea");
17148 MIntScratchSpace surfaceNeighbors(noSurfaces, 2, AT_, "surfaceNeighbors");
17149 MFloatScratchSpace surfaceCentroid(noSurfaces, nDim, AT_, "surfaceCentroid");
17150 for(MInt s = 0; s < noSurfaces; s++) {
17151 surfaceOrientation[s] = a_surfaceOrientation(s);
17152 surfaceArea[s] = a_surfaceArea(s);
17153 surfaceNeighbors(s, 0) = a_surfaceNghbrCellId(s, 0);
17154 surfaceNeighbors(s, 1) = a_surfaceNghbrCellId(s, 1);
17155 for(MInt i = 0; i < nDim; i++) {
17156 surfaceCentroid(s, i) = a_surfaceCoordinate(s, i);
17157 }
17158 }
17159
17160 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
17161 if(a_isBndryGhostCell(cellId)) continue;
17162 if(c_noChildren(cellId) > 0) continue;
17163 removeSurfaces(cellId);
17164 }
17165 m_surfaces.clear();
17166
17167 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
17168 if(a_bndryId(cellId) < -1) continue;
17169 if(a_isBndryGhostCell(cellId)) continue;
17170 if(c_noChildren(cellId) > 0) continue;
17171 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
17172 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17173
17174 restoreSurfaces(cellId);
17175 }
17176
17177 m_log << a_noSurfaces() << endl;
17178
17179 // correct cut surfaces of outer boundary cells with the previously generated surface information
17180 // first set the associatedSrfc pointers correctly
17181 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++)
17182 for(MInt dir = 0; dir < m_noDirs; dir++)
17183 m_fvBndryCnd->m_bndryCells->a[bndryId].m_associatedSrfc[dir] = -1;
17184
17185 for(MInt srfcId = 0; srfcId < a_noSurfaces(); srfcId++) {
17186 MInt nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
17187 MInt nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
17188 ASSERT(nghbr0 > -1 && nghbr1 > -1 && nghbr0 < a_noCells() && nghbr1 < a_noCells(), "");
17189 MInt bndryIdN0 = a_bndryId(nghbr0);
17190 MInt bndryIdN1 = a_bndryId(nghbr1);
17191 if(bndryIdN0 > -1 && bndryIdN1 > -1) {
17192 MInt dirN0 = 2 * a_surfaceOrientation(srfcId) + 1;
17193 MInt dirN1 = 2 * a_surfaceOrientation(srfcId) + 0;
17194 MInt level0 = a_level(nghbr0);
17195 MInt level1 = a_level(nghbr1);
17196 if(level0 >= level1) m_fvBndryCnd->m_bndryCells->a[bndryIdN0].m_associatedSrfc[dirN0] = srfcId;
17197 if(level1 >= level0) m_fvBndryCnd->m_bndryCells->a[bndryIdN1].m_associatedSrfc[dirN1] = srfcId;
17198
17199
17200 a_surfaceArea(srfcId) = surfArea(bndryIdN0, dirN0);
17201 for(MInt i = 0; i < nDim; i++) {
17202 a_surfaceCoordinate(srfcId, i) = surfCentroid(bndryIdN0, dirN0, i);
17203 }
17204 }
17205 }
17206
17207 // then run over the previously created surfaces and correct the information of the newly created surfaces
17208 for(MInt s = 0; s < noSurfaces; s++) {
17209 MInt nghbr0 = surfaceNeighbors(s, 0);
17210 MInt nghbr1 = surfaceNeighbors(s, 1);
17211 if(nghbr0 < 0 || nghbr1 < 0) continue;
17212 ASSERT(nghbr0 > -1 && nghbr1 > -1 && nghbr0 < a_noCells() && nghbr1 < a_noCells(), "");
17213 MInt bndryIdN0 = a_bndryId(nghbr0);
17214 MInt bndryIdN1 = a_bndryId(nghbr1);
17215 if(bndryIdN0 > -1 && bndryIdN1 > -1) {
17216 MInt dirN0 = 2 * surfaceOrientation(s) + 1;
17217 MInt dirN1 = 2 * surfaceOrientation(s) + 0;
17218 MInt level0 = a_level(nghbr0);
17219 MInt level1 = a_level(nghbr1);
17220 if(level0 == level1) {
17221 MInt associatedSrfc0 = m_fvBndryCnd->m_bndryCells->a[bndryIdN0].m_associatedSrfc[dirN0];
17222 MInt associatedSrfc1 = m_fvBndryCnd->m_bndryCells->a[bndryIdN1].m_associatedSrfc[dirN1];
17223 ASSERT(associatedSrfc0 == associatedSrfc1, "");
17224 }
17225 MInt associatedSrfc = (level0 > level1) ? m_fvBndryCnd->m_bndryCells->a[bndryIdN0].m_associatedSrfc[dirN0]
17226 : m_fvBndryCnd->m_bndryCells->a[bndryIdN1].m_associatedSrfc[dirN1];
17227 if(associatedSrfc < 0)
17228 cerr << "surface info " << nghbr0 << " " << nghbr1 << " " << c_globalId(nghbr0) << " " << c_globalId(nghbr1)
17229 << " / " << level0 << " " << level1 << " " << dirN0 << " " << dirN1 << " / "
17230 << m_fvBndryCnd->m_bndryCells->a[bndryIdN0].m_associatedSrfc[dirN0] << " "
17231 << m_fvBndryCnd->m_bndryCells->a[bndryIdN1].m_associatedSrfc[dirN1] << " / "
17232 << a_hasProperty(nghbr0, SolverCell::IsInactive) << " " << a_hasProperty(nghbr1, SolverCell::IsInactive)
17233 << " / " << a_hasProperty(nghbr0, SolverCell::IsNotGradient) << " "
17234 << a_hasProperty(nghbr1, SolverCell::IsNotGradient) << " / " << surfaceCentroid(s, 0) << " "
17235 << surfaceCentroid(s, 1) << " " << surfaceCentroid(s, nDim - 1) << endl;
17236 // ASSERT( associatedSrfc > -1 && associatedSrfc < a_noSurfaces(), to_string(associatedSrfc));
17237 if(associatedSrfc > -1) {
17238 ASSERT(associatedSrfc > -1 && associatedSrfc < a_noSurfaces(), to_string(associatedSrfc));
17239 ASSERT(a_surfaceOrientation(associatedSrfc) == surfaceOrientation(s), "");
17240 ASSERT(a_surfaceNghbrCellId(associatedSrfc, 0) == surfaceNeighbors(s, 0), "");
17241 ASSERT(a_surfaceNghbrCellId(associatedSrfc, 1) == surfaceNeighbors(s, 1), "");
17242 }
17243 }
17244 }
17245
17246 m_log << "...done." << endl;
17247 m_log << a_noSurfaces() << " surfaces created." << endl;
17248}
MInt size()
Definition: collector.h:29
void clear()
Clear tree by invalidating all nodes and setting size to zero.
Definition: container.h:395
void copy(const T &source, const MInt begin, const MInt end, const MInt to)
Copy nodes to another location without changing any parent/child/neighbor information.
Definition: container.h:253

◆ createPeriodicGhostBodies()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::createPeriodicGhostBodies
Author

Definition at line 7976 of file fvmbcartesiansolverxd.cpp.

7976 {
7977 TRACE();
7978
7980 if(grid().periodicCartesianDir(0) + grid().periodicCartesianDir(1) + grid().periodicCartesianDir(2) == 0) return;
7981 if(m_bodyTypeMb == 2) return;
7982 if(grid().azimuthalPeriodicity()) {
7983 return;
7984 }
7985
7986 MFloat dx[3];
7987 for(MInt i = 0; i < nDim; i++) {
7988 dx[i] = m_bbox[nDim + i] - m_bbox[i];
7989 }
7990
7991 for(MInt b = 0; b < m_noEmbeddedBodies; b++) {
7992 // 1. periodic correction of internal body
7993 m_internalBodyId[b] = b;
7994 for(MInt i = 0; i < nDim; i++) {
7995 const MFloat displ = m_bodyCenter[b * nDim + i] - m_bodyCenterDt1[b * nDim + i];
7996 const MFloat displ2 = (m_motionEquation > 1) ? m_bodyCenter[b * nDim + i] - m_bodyCenterDt2[b * nDim + i] : F0;
7997 if(m_bodyCenter[b * nDim + i] < m_bbox[i]) {
7998 m_bodyCenter[b * nDim + i] += dx[i];
7999 } else if(m_bodyCenter[b * nDim + i] > m_bbox[nDim + i]) {
8000 m_bodyCenter[b * nDim + i] -= dx[i];
8001 }
8002 m_bodyCenterDt1[b * nDim + i] = m_bodyCenter[b * nDim + i] - displ;
8003 if(m_motionEquation > 1) {
8004 m_bodyCenterDt2[b * nDim + i] = m_bodyCenter[b * nDim + i] - displ2;
8005 }
8006 }
8007
8008 // 2. add periodic ghost bodies if needed
8009 m_periodicGhostBodies[b].clear();
8010 IF_CONSTEXPR(nDim == 2) {
8015 continue;
8016 }
8017 }
8018 else IF_CONSTEXPR(nDim == 3) {
8025 continue;
8026 }
8027 }
8028 for(MInt s0 = -1; s0 <= 1; s0++) {
8029 if(s0 != 0 && !grid().periodicCartesianDir(0)) continue;
8030 for(MInt s1 = -1; s1 <= 1; s1++) {
8031 if(s1 != 0 && !grid().periodicCartesianDir(1)) continue;
8032 for(MInt s2 = -1; s2 <= 1; s2++) {
8033 if(s2 != 0 && !grid().periodicCartesianDir(2)) continue;
8034 if(s0 == 0 && s1 == 0 && s2 == 0) continue;
8035 MFloat sign[3] = {((MFloat)s0), ((MFloat)s1), ((MFloat)s2)};
8036 MFloat coords[3] = {F0, F0, F0};
8037 MBool tooFar = false;
8038 for(MInt i = 0; i < nDim; i++) {
8039 coords[i] = m_bodyCenter[b * nDim + i] + sign[i] * dx[i];
8040 if(coords[i] < m_bbox[i] - m_periodicGhostBodyDist
8041 || coords[i] > m_bbox[nDim + i] + m_periodicGhostBodyDist)
8042 tooFar = true;
8043 }
8044 if(tooFar) continue;
8047 mTerm(1, AT_,
8048 "Increase m_maxNoEmbeddedBodiesPeriodic " + to_string(m_noEmbeddedBodies) + " "
8049 + to_string(m_noPeriodicGhostBodies));
8050 transferBodyState(k, b);
8051 for(MInt i = 0; i < nDim; i++) {
8052 m_bodyCenter[k * nDim + i] = coords[i];
8053 }
8054 m_internalBodyId[k] = b;
8055 m_periodicGhostBodies[b].push_back(k);
8057 }
8058 }
8059 }
8060 }
8061
8063 m_log << "No periodic ghost bodies: " << m_noPeriodicGhostBodies << " ("
8064 << 100.0 * ((MFloat)m_noPeriodicGhostBodies) / ((MFloat)m_noEmbeddedBodies) << "%)" << endl;
8065 }
8066}
void transferBodyState(MInt k, MInt b)

◆ createSplitCell()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::createSplitCell ( MInt  cellId,
MInt  noSplitChilds 
)
Author
Lennart Schneiders, Update Tim Wegmann

Definition at line 19470 of file fvmbcartesiansolverxd.cpp.

19470 {
19471 TRACE();
19472
19473 const MInt splitId = m_splitCells.size();
19474 m_splitCells.push_back(cellId);
19475 m_splitChilds.resize(m_splitCells.size());
19476 m_splitChilds[splitId].resize(noSplitChilds);
19477 a_hasProperty(cellId, SolverCell::IsSplitCell) = false;
19478
19479 for(MInt n = 0; n < noSplitChilds; n++) {
19480 const MInt splitChildId = a_noCells();
19481
19482 m_cells.append();
19484
19485 ASSERT(splitChildId == a_noCells() - 1, "Error in the cell-count, for splitchilds!");
19486
19487 for(MInt dir = 0; dir < m_noDirs; dir++) {
19488 m_cellSurfaceMapping[splitChildId][dir] = -1;
19489 }
19490 a_cellVolume(splitChildId) = a_cellVolume(cellId);
19491 m_cellVolumesDt1[splitChildId] = m_cellVolumesDt1[cellId];
19492 for(MInt k = 0; k < nDim; k++) {
19493 a_coordinate(splitChildId, k) = a_coordinate(cellId, k);
19494 }
19495 a_level(splitChildId) = a_level(cellId);
19496
19497 a_isBndryGhostCell(splitChildId) = false;
19498 a_noReconstructionNeighbors(splitChildId) = 0;
19499
19500 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
19501 a_associatedBodyIds(splitChildId, set) = a_associatedBodyIds(cellId, set);
19502 a_levelSetValuesMb(splitChildId, set) = a_levelSetValuesMb(cellId, set);
19503 }
19504
19505 a_copyPropertiesSolver(cellId, splitChildId);
19506
19507 a_hasProperty(splitChildId, SolverCell::IsSplitCell) = false;
19508 a_hasProperty(splitChildId, SolverCell::IsSplitChild) = true;
19509 a_hasProperty(splitChildId, SolverCell::IsInactive) = false;
19510 a_hasProperty(splitChildId, SolverCell::WasInactive) = a_hasProperty(cellId, SolverCell::WasInactive);
19511
19512 for(MInt var = 0; var < CV->noVariables; var++) {
19513 a_variable(splitChildId, var) = a_variable(cellId, var);
19514 a_oldVariable(splitChildId, var) = a_variable(cellId, var);
19515 a_pvariable(splitChildId, var) = a_pvariable(cellId, var);
19516 }
19517
19518 a_bndryId(splitChildId) = createBndryCellMb(splitChildId);
19519 ASSERT(a_bndryId(splitChildId) > -1, "");
19520 MInt splitChildBndryId = a_bndryId(splitChildId);
19521 for(MInt dir = 0; dir < m_noDirs; dir++) {
19522 m_bndryCells->a[splitChildBndryId].m_associatedSrfc[dir] = -1;
19523 m_bndryCells->a[splitChildBndryId].m_externalFaces[dir] = false;
19524 }
19525 m_splitChilds[splitId][n] = splitChildId;
19526 m_splitChildToSplitCell.insert(pair<MInt, MInt>(splitChildId, cellId));
19527
19528 m_bndryLayerCells.push_back(splitChildId);
19529 a_hasProperty(splitChildId, SolverCell::NearWall) = true;
19530
19531 ASSERT(a_level(splitChildId) == a_level(m_splitChildToSplitCell.find(splitChildId)->second), "");
19532 }
19533
19534 a_hasProperty(cellId, SolverCell::IsSplitCell) = true;
19535
19536 ASSERT(splitId > -1, "");
19537 return splitId;
19538}
void a_copyPropertiesSolver(const MInt fromCellId, const MInt toCellId)
Returns property p of the cell cellId.

◆ createSurface()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::createSurface ( MInt  srfcId,
MInt  nghbrId0,
MInt  nghbrId1,
MInt  orientation 
)
Author
Lennart Schneiders

Definition at line 16223 of file fvmbcartesiansolverxd.cpp.

16223 {
16224 TRACE();
16225
16226 ASSERT((srfcId > -1) && (nghbrId0 > -1) && (nghbrId1 > -1), "createSurface(..) error");
16227 ASSERT((srfcId < a_noSurfaces()) && (nghbrId0 < a_noCells()) && (nghbrId1 < a_noCells()),
16228 to_string(nghbrId0) + " " + to_string(nghbrId1) + " " + to_string(c_noCells()) + " " + to_string(a_noCells()));
16229 ASSERT(c_noChildren(nghbrId0) == 0 && c_noChildren(nghbrId1) == 0, "");
16230
16231 a_surfaceOrientation(srfcId) = orientation;
16232 a_surfaceNghbrCellId(srfcId, 0) = nghbrId0;
16233 a_surfaceNghbrCellId(srfcId, 1) = nghbrId1;
16234
16235 if(a_bndryId(nghbrId0) > -1) {
16236 m_bndryCells->a[a_bndryId(nghbrId0)].m_associatedSrfc[2 * orientation + 1] = srfcId;
16237 }
16238 if(a_bndryId(nghbrId1) > -1) {
16239 m_bndryCells->a[a_bndryId(nghbrId1)].m_associatedSrfc[2 * orientation] = srfcId;
16240 }
16241
16242 if(a_level(nghbrId1) > a_level(nghbrId0)) {
16243 const MFloat cellLength = c_cellLengthAtLevel(a_level(nghbrId1));
16244 for(MInt i = 0; i < nDim; i++) {
16245 a_surfaceCoordinate(srfcId, i) = a_coordinate(nghbrId1, i);
16246 }
16247 a_surfaceCoordinate(srfcId, orientation) -= F1B2 * cellLength;
16248 a_surfaceArea(srfcId) = F1;
16249 for(MInt i = 0; i < nDim - 1; i++)
16250 a_surfaceArea(srfcId) *= cellLength;
16251 m_cellSurfaceMapping[nghbrId0][2 * orientation + 1] = -1;
16252 m_cellSurfaceMapping[nghbrId1][2 * orientation] = srfcId;
16253 } else {
16254 const MFloat cellLength = c_cellLengthAtLevel(a_level(nghbrId0));
16255 for(MInt i = 0; i < nDim; i++) {
16256 a_surfaceCoordinate(srfcId, i) = a_coordinate(nghbrId0, i);
16257 }
16258 a_surfaceCoordinate(srfcId, orientation) += F1B2 * cellLength;
16259 a_surfaceArea(srfcId) = F1;
16260 for(MInt i = 0; i < nDim - 1; i++)
16261 a_surfaceArea(srfcId) *= cellLength;
16262 m_cellSurfaceMapping[nghbrId0][2 * orientation + 1] = srfcId;
16263 m_cellSurfaceMapping[nghbrId1][2 * orientation] = -1;
16264 }
16265
16266 if(a_level(nghbrId0) == a_level(nghbrId1)) {
16268 a_surfaceFactor(srfcId, 0) = F1B2;
16269 a_surfaceFactor(srfcId, 1) = F1B2;
16270 m_cellSurfaceMapping[nghbrId0][2 * orientation + 1] = srfcId;
16271 m_cellSurfaceMapping[nghbrId1][2 * orientation] = srfcId;
16272 } else {
16274 MFloat tmp = F0;
16275 a_surfaceFactor(srfcId, 0) = F0;
16276 for(MInt i = 0; i < nDim; i++) {
16277 a_surfaceFactor(srfcId, 0) += POW2(a_surfaceCoordinate(srfcId, i) - a_coordinate(nghbrId0, i));
16278 tmp += POW2(a_surfaceCoordinate(srfcId, i) - a_coordinate(nghbrId1, i));
16279 }
16280 a_surfaceFactor(srfcId, 0) = sqrt(a_surfaceFactor(srfcId, 0));
16281 tmp = sqrt(tmp);
16282 a_surfaceFactor(srfcId, 0) = tmp / (a_surfaceFactor(srfcId, 0) + tmp);
16283 a_surfaceFactor(srfcId, 1) = F1 - a_surfaceFactor(srfcId, 0);
16284 }
16285 for(MInt i = 0; i < nDim; i++) {
16286 a_surfaceDeltaX(srfcId, i) = a_surfaceCoordinate(srfcId, i) - a_coordinate(a_surfaceNghbrCellId(srfcId, 0), i);
16287 a_surfaceDeltaX(srfcId, nDim + i) =
16288 a_surfaceCoordinate(srfcId, i) - a_coordinate(a_surfaceNghbrCellId(srfcId, 1), i);
16289 }
16290 MBool flag = false;
16291 for(MInt side = 0; side < 2; side++) {
16292 for(MInt d = 0; d < m_noDirs; d++) {
16293 if(a_hasNeighbor(a_surfaceNghbrCellId(srfcId, side), d) > 0) continue;
16294 if(c_parentId(a_surfaceNghbrCellId(srfcId, side)) == -1) continue;
16295 if(a_hasNeighbor(c_parentId(a_surfaceNghbrCellId(srfcId, side)), d) == 0) continue;
16296 if(c_noChildren(c_neighborId(c_parentId(a_surfaceNghbrCellId(srfcId, side)), d)) > 0) continue;
16297 flag = true;
16298 d = m_noDirs;
16299 }
16300 }
16301
16302 if(flag) a_surfaceUpwindCoefficient(srfcId) = m_chi;
16303 a_surfaceBndryCndId(srfcId) = -1;
16304}

◆ createSurfaceSplit()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::createSurfaceSplit ( MInt  srfcId,
MInt  cellId,
MInt  splitChildId,
MInt  direction 
)
Author
Lennart Schneiders

Definition at line 16312 of file fvmbcartesiansolverxd.cpp.

16313 {
16314 ASSERT((srfcId > -1), "createSurface(..) error");
16315 ASSERT((srfcId < a_noSurfaces()) && (cellId < a_noCells()) && (splitChildId < a_noCells()),
16316 "createSurface(..) error");
16317 ASSERT(c_isLeafCell(cellId), "");
16318
16319 MInt orientation = direction / 2;
16320 a_surfaceOrientation(srfcId) = orientation;
16321 MInt nghbr0 = splitChildId;
16322 MInt nghbr1 = -2;
16323 if(direction % 2 == 0) {
16324 nghbr0 = -2;
16325 nghbr1 = splitChildId;
16326 }
16327 a_surfaceNghbrCellId(srfcId, 0) = nghbr0;
16328 a_surfaceNghbrCellId(srfcId, 1) = nghbr1;
16329
16330 MInt nghbrId = c_neighborId(cellId, direction);
16331 ASSERT(nghbrId > -1, "");
16332
16333 if(nghbr0 == -2) {
16334 nghbr0 = nghbrId;
16335 nghbr1 = cellId;
16336 } else {
16337 nghbr0 = cellId;
16338 nghbr1 = nghbrId;
16339 }
16340
16341 const MFloat cellLength = c_cellLengthAtLevel(a_level(cellId));
16342 for(MInt i = 0; i < nDim; i++) {
16343 a_surfaceCoordinate(srfcId, i) = a_coordinate(cellId, i);
16344 }
16345 a_surfaceCoordinate(srfcId, orientation) += F1B2 * cellLength;
16346 a_surfaceArea(srfcId) = F1;
16347 for(MInt i = 0; i < nDim - 1; i++)
16348 a_surfaceArea(srfcId) *= cellLength;
16350
16351 a_surfaceFactor(srfcId, 0) = F1B2;
16352 a_surfaceFactor(srfcId, 1) = F1B2;
16353
16354 for(MInt i = 0; i < nDim; i++) {
16355 a_surfaceDeltaX(srfcId, i) = a_surfaceCoordinate(srfcId, i) - a_coordinate(nghbr0, i);
16356 a_surfaceDeltaX(srfcId, nDim + i) = a_surfaceCoordinate(srfcId, i) - a_coordinate(nghbr1, i);
16357 }
16358 a_surfaceBndryCndId(srfcId) = -1;
16359
16360 m_splitSurfaces.insert(srfcId);
16361}

◆ crossProduct()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::crossProduct ( MFloat c,
MFloat a,
MFloat b 
)
inlinestatic
Author
Lennart Schneiders

Definition at line 8842 of file fvmbcartesiansolverxd.cpp.

8842 {
8843 c[0] = a[1] * b[2] - a[2] * b[1];
8844 c[1] = a[2] * b[0] - a[0] * b[2];
8845 c[2] = a[0] * b[1] - a[1] * b[0];
8846}

◆ deleteNeighbourLinks()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::deleteNeighbourLinks
Author
Lennart Schneiders, Update Tim Wegmann

Definition at line 20210 of file fvmbcartesiansolverxd.cpp.

20210 {
20211 TRACE();
20212
20213 // 1. delete neighbour links towards inactive levelset region
20214 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
20215 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
20216
20217 // check all directions for neighbours in inactive levelset region
20218 for(MInt dir = 0; dir < m_noDirs; dir++) {
20219 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && a_hasNeighbor(cellId, dir) > 0) {
20220 const MInt nghbrId = c_neighborId(cellId, dir);
20221 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) {
20222 a_hasProperty(cellId, SolverCell::IsBndryActive) = true;
20223 break;
20224 }
20225 }
20226 }
20227 }
20228 m_deleteNeighbour = true;
20229}

◆ deleteSurface()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::deleteSurface ( MInt  srfcId)
Author
Lennart Schneiders

Definition at line 16745 of file fvmbcartesiansolverxd.cpp.

16745 {
16746 const MInt dir = a_surfaceOrientation(srfcId);
16747 const MInt nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
16748 const MInt nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
16749
16750 if(nghbr0 > -1) {
16751 ASSERT(m_cellSurfaceMapping[nghbr0][2 * dir + 1] < 0 || m_cellSurfaceMapping[nghbr0][2 * dir + 1] == srfcId,
16752 to_string(m_cellSurfaceMapping[nghbr0][2 * dir + 1]));
16753 m_cellSurfaceMapping[nghbr0][2 * dir + 1] = -1;
16754 if(a_bndryId(nghbr0) > -1) {
16755 m_bndryCells->a[a_bndryId(nghbr0)].m_associatedSrfc[2 * dir + 1] = -1;
16756 MInt bndryId = a_bndryId(nghbr0);
16757 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
16758 for(MInt i = 0; i < nDim; i++) {
16759 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] == srfcId) {
16760 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
16761 }
16762 }
16763 }
16764 }
16765 }
16766
16767 if(nghbr1 > -1) {
16768 ASSERT(m_cellSurfaceMapping[nghbr1][2 * dir] < 0 || m_cellSurfaceMapping[nghbr1][2 * dir] == srfcId,
16769 to_string(m_cellSurfaceMapping[nghbr1][2 * dir]));
16770 m_cellSurfaceMapping[nghbr1][2 * dir] = -1;
16771 if(a_bndryId(nghbr1) > -1) {
16772 m_bndryCells->a[a_bndryId(nghbr1)].m_associatedSrfc[2 * dir] = -1;
16773 MInt bndryId = a_bndryId(nghbr1);
16774 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
16775 for(MInt i = 0; i < nDim; i++) {
16776 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] == srfcId) {
16777 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
16778 }
16779 }
16780 }
16781 }
16782 }
16783
16784 a_surfaceNghbrCellId(srfcId, 0) = -1;
16785 a_surfaceNghbrCellId(srfcId, 1) = -1;
16786 a_surfaceBndryCndId(srfcId) = -1;
16787 m_splitSurfaces.erase(srfcId);
16788
16789 if(srfcId >= a_noSurfaces()) {
16790 mTerm(1, AT_, "Invalid surface.");
16791 } else if(srfcId == (a_noSurfaces() - 1)) {
16795 } else {
16796 m_freeSurfaceIndices.insert(srfcId);
16797 }
16798}

◆ descendDistance()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::descendDistance ( const MInt  cellId,
const MInt *const  bodyIds,
const MInt  bodyCnt,
MIntScratchSpace nearestBodies,
MFloatScratchSpace nearestDist 
)
Author

Definition at line 1411 of file fvmbcartesiansolverxd.cpp.

1413 {
1414 MInt* const nearBodies = &nearestBodies[cellId * m_maxNearestBodies];
1415 MFloat* const nearDist = &nearestDist[cellId * m_maxNearestBodies];
1416
1417 for(MInt b = 0; b < bodyCnt; b++) {
1418 const MInt k = bodyIds[b];
1419 MFloat dist = getDistance(cellId, k);
1420
1421 for(MInt n = 0; n < m_maxNearestBodies; n++) {
1422 if(fabs(dist) < fabs(nearDist[n])) {
1423 if(n < m_maxNearestBodies - 1) {
1424 std::rotate(nearBodies + n, nearBodies + m_maxNearestBodies - 1, nearBodies + m_maxNearestBodies);
1425 std::rotate(nearDist + n, nearDist + m_maxNearestBodies - 1, nearDist + m_maxNearestBodies);
1426 }
1427 nearDist[n] = dist;
1428 nearBodies[n] = k;
1429 break;
1430 }
1431 }
1432 }
1433
1434 for(MInt child = 0; child < m_noCellNodes; child++) {
1435 if(c_childId(cellId, child) < 0) continue;
1436 descendDistance(c_childId(cellId, child), bodyIds, bodyCnt, nearestBodies, nearestDist);
1437 }
1438}
MFloat getDistance(const MFloat *const, const MInt)

◆ descendLevelSetValue()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::descendLevelSetValue ( const MInt  cellId,
const MInt *const  bodyIds,
const MInt  bodyCnt 
)
Author

Definition at line 1369 of file fvmbcartesiansolverxd.cpp.

1370 {
1371 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
1372 a_associatedBodyIds(cellId, set) = -1;
1373 a_levelSetValuesMb(cellId, set) = m_bodyDistThreshold + 1e-14;
1374 }
1375
1376 for(MInt b = 0; b < bodyCnt; b++) {
1377 const MInt k = bodyIds[b];
1378 const MInt set = m_bodyToSetTable[k];
1379 MFloat dist = getDistance(cellId, k);
1380
1381 if(fabs(dist) < fabs(a_levelSetValuesMb(cellId, set)) || (dist < F0)) {
1382 a_levelSetValuesMb(cellId, set) = dist;
1383 a_associatedBodyIds(cellId, set) = k;
1384 }
1385 }
1386
1387 if(m_startSet > 0) {
1388 a_levelSetValuesMb(cellId, 0) = a_levelSetValuesMb(cellId, m_startSet);
1390 for(MInt i = (m_startSet + 1); i < m_noSets; i++) {
1391 if(a_levelSetValuesMb(cellId, i) < a_levelSetValuesMb(
1392 cellId, 0)) { // a distinction between concave and convex boundaries has to be made here!!!!!
1393 a_levelSetValuesMb(cellId, 0) = a_levelSetValuesMb(cellId, i);
1394 a_associatedBodyIds(cellId, 0) = a_associatedBodyIds(cellId, i);
1395 }
1396 }
1397 }
1398
1399 for(MInt child = 0; child < m_noCellNodes; child++) {
1400 if(c_childId(cellId, child) < 0) continue;
1401 descendLevelSetValue(c_childId(cellId, child), bodyIds, bodyCnt);
1402 }
1403}

◆ determineBndryCandidates()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::determineBndryCandidates
Author
Lennart Schneiders

m_noBndryCandidates : count of boundary-Candidate-cellIds m_bndryCandidates : mapping m_bndryCandidates[candidateId] = cellId m_bndryCandidateIds : mapping m_bndryCandidateIds[ cellId ] = candidateId

Definition at line 5714 of file fvmbcartesiansolverxd.cpp.

5714 {
5715 TRACE();
5716
5717 ASSERT(!m_constructGField, "");
5718
5719 for(MInt cnd = 0; cnd < m_noBndryCandidates; cnd++) {
5721 }
5722
5724 m_bndryCandidates.clear();
5726
5727 const MFloat limitDistance = F2 * c_cellLengthAtLevel(m_lsCutCellBaseLevel);
5728
5729 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
5730 const MInt cellId = m_bndryLayerCells[c];
5731 if(a_bndryId(cellId) < -1) continue;
5732 if(cellId >= a_noCells()) continue;
5733 if(fabs(a_levelSetValuesMb(cellId, 0)) < limitDistance
5734 && a_level(cellId) >= m_lsCutCellMinLevel && c_noChildren(cellId) == 0 && !a_isHalo(cellId)) {
5735 m_bndryCandidates.push_back(cellId);
5738 } else {
5740 // instead of candidates take g0 cells --> no, g0 cells can exlude bndry cell!
5741 // solution: make sure g0 neighbour cell stores cutpoint for those cells !
5742 }
5743 }
5744
5745 ASSERT(m_bndryCandidates.size() <= m_bndryLayerCells.size(), "");
5746 ASSERT(m_noBndryCandidates == (signed)m_bndryCandidates.size(), "");
5747
5748 for(MInt cnd = 0; cnd < m_noBndryCandidates; cnd++) {
5749 ASSERT(cnd == m_bndryCandidateIds[m_bndryCandidates[cnd]],
5750 to_string(cnd) + " " + to_string(m_bndryCandidates[cnd]) + " "
5751 + to_string(m_bndryCandidateIds[m_bndryCandidates[cnd]]) + " "
5752 + to_string(a_isHalo(m_bndryCandidates[cnd])));
5753 }
5754}

◆ determineCoupling()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::determineCoupling ( MFloatScratchSpace coupling)
Author

Definition at line 26381 of file fvmbcartesiansolverxd.cpp.

26381 {
26382 TRACE();
26383
26384 coupling.fill(F0);
26385 const MInt noBCells = m_fvBndryCnd->m_bndryCells->size();
26386 MFloat couplingCheck = F0;
26387
26388 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBCells; bndryId++) {
26389 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
26390
26391 if(a_isHalo(cellId)) continue;
26392 if(a_isBndryGhostCell(cellId)) continue;
26393 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && c_noChildren(cellId) > 0) continue;
26394 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
26395
26396 MFloatScratchSpace dummyPvariables(m_bndryCells->a[bndryId].m_noSrfcs, PV->noVariables, AT_, "dummyPvariables");
26397 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
26398 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area < 1e-14) continue;
26399 MFloat rhoSurface = F0;
26400 MFloat pSurface = F0;
26401 for(MInt s = 0; s < mMin((signed)m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size(),
26402 m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs);
26403 s++) {
26404 dummyPvariables(s, PV->P) = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[s]->m_primVars[PV->P];
26405 dummyPvariables(s, PV->RHO) = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[s]->m_primVars[PV->RHO];
26406 }
26407 for(MInt n = 0; n < (signed)m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size(); n++) {
26408 const MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
26409 const MFloat nghbrPvariableP = (n < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs)
26410 ? dummyPvariables(n, PV->P)
26411 : a_pvariable(nghbrId, PV->P);
26412 const MFloat nghbrPvariableRho = (n < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs)
26413 ? dummyPvariables(n, PV->RHO)
26414 : a_pvariable(nghbrId, PV->RHO);
26415 rhoSurface +=
26416 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariableRho;
26417 pSurface += m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariableP;
26418 }
26419 MFloat normal0[3] = {F0, F0, F0};
26420 for(MInt i = 0; i < nDim; i++) {
26421 normal0[i] = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
26422 }
26423 MFloat T = sysEqn().temperature_ES(rhoSurface, pSurface);
26424 MFloat mue = SUTHERLANDLAW(T);
26425 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
26426 for(MInt i = 0; i < nDim; i++) {
26427 const MFloat dp0 = -pSurface * normal0[i] * area;
26428 MFloat grad = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[i]];
26429 for(MInt j = 0; j < nDim; j++)
26430 grad += F1B3 * normal0[i] * normal0[j]
26431 * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[j]];
26432 MFloat ds0 = mue * grad * area / sysEqn().m_Re0;
26433 coupling(cellId, i) -= (dp0 + ds0);
26434 couplingCheck -= (dp0 + ds0) * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]];
26435 }
26436 }
26437 }
26438 exchangeDataFV(&coupling[0], nDim, false);
26439
26440 MPI_Allreduce(MPI_IN_PLACE, &couplingCheck, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "couplingCheck");
26441 return couplingCheck;
26442}
void fill(T val)
fill the scratch with a given value
Definition: scratch.h:311

◆ determineNearBndryCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::determineNearBndryCells
Author
Lennart Schneiders

Definition at line 13670 of file fvmbcartesiansolverxd.cpp.

13670 {
13671 /*
13672 TRACE();
13673
13674 MInt cellId;
13675
13676 // 1. find near boundary cells
13677 m_noNearBndryCells = 0;
13678 m_nearBndryCells->resetSize(0);
13679
13680 for ( MUint c = 0; c < m_bndryLayerCells.size(); c++ ) {
13681 cellId = m_bndryLayerCells[ c ];
13682 if ( cellId < 0 ) continue;
13683 if ( !a_hasProperty( cellId , SolverCell::IsOnCurrentMGLevel) )
13684 continue; if ( a_hasProperty( cellId , SolverCell::IsInactive ) )
13685 continue; if ( a_isBndryGhostCell( cellId ) ) continue;
13686 //if ( a_level(cellId) != maxRefinementLevel() ) continue;
13687
13688 m_nearBndryCells->append();
13689 m_nearBndryCells->a[ m_noNearBndryCells ] = cellId;
13690 m_noNearBndryCells++;
13691 }*/
13692}

◆ distancePointEllipseSpecial()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::distancePointEllipseSpecial ( const MFloat  e[2],
const MFloat  y[2],
MFloat  x[2] 
)
static

Definition at line 3989 of file fvmbcartesiansolverxd.cpp.

3990 {
3991 constexpr MFloat eps = 1e-14;
3993
3994 if(y[1] > (MFloat)0) {
3995 if(y[0] > (MFloat)0) {
3996 // Bisect to compute the root of F(t) for t >= -e1*e1.
3997 MFloat esqr[2] = {e[0] * e[0], e[1] * e[1]};
3998 MFloat ey[2] = {e[0] * y[0], e[1] * y[1]};
3999 MFloat t0 = -esqr[1] + ey[1];
4000 MFloat t1 = -esqr[1] + sqrt(ey[0] * ey[0] + ey[1] * ey[1]);
4001 MFloat t = t0;
4002 const MInt imax = 2 * std::numeric_limits<MFloat>::max_exponent;
4003 for(MInt i = 0; i < imax; ++i) {
4004 t = ((MFloat)0.5) * (t0 + t1);
4005 if(fabs(t - t0) < eps || fabs(t - t1) < eps) {
4006 break;
4007 }
4008 MFloat r[2] = {ey[0] / (t + esqr[0]), ey[1] / (t + esqr[1])};
4009 MFloat f = r[0] * r[0] + r[1] * r[1] - (MFloat)1;
4010 if(f > (MFloat)0) {
4011 t0 = t;
4012 } else if(f < (MFloat)0) {
4013 t1 = t;
4014 } else {
4015 break;
4016 }
4017 }
4018 if(fabs(t0 - t1) > eps) cerr << "ellipse dist not converged!" << endl;
4019 x[0] = esqr[0] * y[0] / (t + esqr[0]);
4020 x[1] = esqr[1] * y[1] / (t + esqr[1]);
4021 MFloat d[2] = {x[0] - y[0], x[1] - y[1]};
4022 distance = sqrt(d[0] * d[0] + d[1] * d[1]);
4023 } else // y0 == 0
4024 {
4025 x[0] = (MFloat)0;
4026 x[1] = e[1];
4027 distance = fabs(y[1] - e[1]);
4028 }
4029 } else // y1 == 0
4030 {
4031 MFloat denom0 = e[0] * e[0] - e[1] * e[1];
4032 MFloat e0y0 = e[0] * y[0];
4033 if(e0y0 < denom0) {
4034 // y0 is inside the subinterval.
4035 MFloat x0de0 = e0y0 / denom0;
4036 MFloat x0de0sqr = x0de0 * x0de0;
4037 x[0] = e[0] * x0de0;
4038 x[1] = e[1] * sqrt(fabs((MFloat)1 - x0de0sqr));
4039 MFloat d0 = x[0] - y[0];
4040 distance = sqrt(d0 * d0 + x[1] * x[1]);
4041 } else {
4042 // y0 is outside the subinterval. The closest ellipse point has
4043 // x1 == 0 and is on the domain-boundary interval (x0/e0)^2 = 1.
4044 x[0] = e[0];
4045 x[1] = (MFloat)0;
4046 distance = fabs(y[0] - e[0]);
4047 }
4048 }
4049 return distance;
4050}
MFloat distance(const MFloat *a, const MFloat *b)
Definition: maiamath.h:249

◆ distancePointEllipsoid()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::distancePointEllipsoid ( const MFloat  e[3],
const MFloat  y[3],
MFloat  x[3] 
)

Definition at line 3907 of file fvmbcartesiansolverxd.cpp.

3907 {
3908 // Determine reflections for y to the first octant.
3909 MBool reflect[3];
3910 MInt i, j;
3911 for(i = 0; i < 3; ++i) {
3912 reflect[i] = (y[i] < (MFloat)0);
3913 }
3914
3915 // Determine the axis order for decreasing extents.
3916 MInt permute[3];
3917 if(e[0] < e[1]) {
3918 if(e[2] < e[0]) {
3919 permute[0] = 1;
3920 permute[1] = 0;
3921 permute[2] = 2;
3922 } else if(e[2] < e[1]) {
3923 permute[0] = 1;
3924 permute[1] = 2;
3925 permute[2] = 0;
3926 } else {
3927 permute[0] = 2;
3928 permute[1] = 1;
3929 permute[2] = 0;
3930 }
3931 } else {
3932 if(e[2] < e[1]) {
3933 permute[0] = 0;
3934 permute[1] = 1;
3935 permute[2] = 2;
3936 } else if(e[2] < e[0]) {
3937 permute[0] = 0;
3938 permute[1] = 2;
3939 permute[2] = 1;
3940 } else {
3941 permute[0] = 2;
3942 permute[1] = 0;
3943 permute[2] = 1;
3944 }
3945 }
3946 MInt invpermute[3];
3947 for(i = 0; i < 3; ++i) {
3948 invpermute[permute[i]] = i;
3949 }
3950 MFloat locE[3], locY[3];
3951 for(i = 0; i < 3; ++i) {
3952 j = permute[i];
3953 locE[i] = e[j];
3954 locY[i] = y[j];
3955 if(reflect[j]) {
3956 locY[i] = -locY[i];
3957 }
3958 }
3959 MFloat locX[3];
3960#define IMPROVEDDISTELLIPSOID
3961#ifdef IMPROVEDDISTELLIPSOID
3962 for(i = 0; i < 3; ++i) {
3963 ASSERT(!(locY[i] < F0), "");
3964 locY[i] = mMax(1e-15, locY[i]); // guarantee non-zero entries
3965 }
3967#else
3968 MFloat distance = distancePointEllipsoidSpecial(locE, locY, locX);
3969#endif
3970 // Restore the axis order and reflections.
3971 for(i = 0; i < 3; ++i) {
3972 j = invpermute[i];
3973 if(reflect[i]) {
3974 locX[j] = -locX[j];
3975 }
3976 x[i] = locX[j];
3977 }
3978 return distance;
3979}
MFloat distancePointEllipsoidSpecial(const MFloat e[3], const MFloat y[3], MFloat x[3])
MFloat distancePointEllipsoidSpecial2(const MFloat e[3], const MFloat y[3], MFloat x[3])

◆ distancePointEllipsoidSpecial()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::distancePointEllipsoidSpecial ( const MFloat  e[3],
const MFloat  y[3],
MFloat  x[3] 
)

Definition at line 3695 of file fvmbcartesiansolverxd.cpp.

3696 {
3697 constexpr MFloat eps = 1e-14;
3699
3700 if(y[2] > (MFloat)0) {
3701 if(y[1] > (MFloat)0) {
3702 if(y[0] > (MFloat)0) {
3703 // Bisect to compute the root of F(t) for t >= -e2*e2.
3704 MFloat esqr[3] = {e[0] * e[0], e[1] * e[1], e[2] * e[2]};
3705 MFloat ey[3] = {e[0] * y[0], e[1] * y[1], e[2] * y[2]};
3706 MFloat t0 = -esqr[2] + ey[2];
3707 MFloat t1 = -esqr[2] + sqrt(ey[0] * ey[0] + ey[1] * ey[1] + ey[2] * ey[2]);
3708 MFloat t = t0;
3709 const MInt imax = 2 * std::numeric_limits<MFloat>::max_exponent;
3710 for(MInt i = 0; i < imax; ++i) {
3711 t = ((MFloat)0.5) * (t0 + t1);
3712 if(fabs(t - t0) < eps || fabs(t - t1) < eps) {
3713 break;
3714 }
3715 MFloat r[3] = {ey[0] / (t + esqr[0]), ey[1] / (t + esqr[1]), ey[2] / (t + esqr[2])};
3716 MFloat f = r[0] * r[0] + r[1] * r[1] + r[2] * r[2] - (MFloat)1;
3717 if(f > (MFloat)0) {
3718 t0 = t;
3719 } else if(f < (MFloat)0) {
3720 t1 = t;
3721 } else {
3722 break;
3723 }
3724 }
3725 // if ( fabs( t0 - t1 ) > eps ) cerr << "ellipsoid dist not converged!" << endl;
3726 x[0] = esqr[0] * y[0] / (t + esqr[0]);
3727 x[1] = esqr[1] * y[1] / (t + esqr[1]);
3728 x[2] = esqr[2] * y[2] / (t + esqr[2]);
3729 MFloat d[3] = {x[0] - y[0], x[1] - y[1], x[2] - y[2]};
3730 distance = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
3731 } else // y0 == 0
3732 {
3733 x[0] = (MFloat)0;
3734 MFloat etmp[2] = {e[1], e[2]};
3735 MFloat ytmp[2] = {y[1], y[2]};
3736 MFloat xtmp[2];
3737 distance = distancePointEllipseSpecial(etmp, ytmp, xtmp);
3738 x[1] = xtmp[0];
3739 x[2] = xtmp[1];
3740 }
3741 } else // y1 == 0
3742 {
3743 x[1] = (MFloat)0;
3744 if(y[0] > (MFloat)0) {
3745 MFloat etmp[2] = {e[0], e[2]};
3746 MFloat ytmp[2] = {y[0], y[2]};
3747 MFloat xtmp[2];
3748 distance = distancePointEllipseSpecial(etmp, ytmp, xtmp);
3749 x[0] = xtmp[0];
3750 x[2] = xtmp[1];
3751 } else // y0 == 0
3752 {
3753 x[0] = (MFloat)0;
3754 x[2] = e[2];
3755 distance = fabs(y[2] - e[2]);
3756 }
3757 }
3758 } else // y2 == 0
3759 {
3760 MFloat denom[2] = {e[0] * e[0] - e[2] * e[2], e[1] * e[1] - e[2] * e[2]};
3761 MFloat ey[2] = {e[0] * y[0], e[1] * y[1]};
3762 if(ey[0] < denom[0] && ey[1] < denom[1]) {
3763 // (y0,y1) is inside the axis-aligned bounding rectangle of the
3764 // subellipse. This intermediate test is designed to guard
3765 // against the division by zero when e0 == e2 or e1 == e2.
3766 MFloat xde[2] = {ey[0] / denom[0], ey[1] / denom[1]};
3767 MFloat xdesqr[2] = {xde[0] * xde[0], xde[1] * xde[1]};
3768 MFloat discr = (MFloat)1 - xdesqr[0] - xdesqr[1];
3769 if(discr > (MFloat)0) {
3770 // (y0,y1) is inside the subellipse. The closest ellipsoid
3771 // point has x2 > 0.
3772 x[0] = e[0] * xde[0];
3773 x[1] = e[1] * xde[1];
3774 x[2] = e[2] * sqrt(discr);
3775 MFloat d[2] = {x[0] - y[0], x[1] - y[1]};
3776 distance = sqrt(d[0] * d[0] + d[1] * d[1] + x[2] * x[2]);
3777 } else {
3778 // (y0,y1) is outside the subellipse. The closest ellipsoid
3779 // point has x2 == 0 and is on the domain-boundary ellipse
3780 // (x0/e0)^2 + (x1/e1)^2 = 1.
3781 x[2] = (MFloat)0;
3783 }
3784 } else {
3785 // (y0,y1) is outside the subellipse. The closest ellipsoid
3786 // point has x2 == 0 and is on the domain-boundary ellipse
3787 // (x0/e0)^2 + (x1/e1)^2 = 1.
3788 x[2] = (MFloat)0;
3790 }
3791 }
3792 return distance;
3793}
static MFloat distancePointEllipseSpecial(const MFloat e[2], const MFloat y[2], MFloat x[2])

◆ distancePointEllipsoidSpecial2()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::distancePointEllipsoidSpecial2 ( const MFloat  e[3],
const MFloat  y[3],
MFloat  x[3] 
)

Definition at line 3808 of file fvmbcartesiansolverxd.cpp.

3809 {
3810 constexpr MFloat eps0 = 1e-12;
3811 constexpr MFloat eps1 = 1e-6;
3815 // Bisect to compute the root of F(t) for t >= -e2*e2.
3816 MFloat esqr[3] = {e[0] * e[0], e[1] * e[1], e[2] * e[2]};
3817 MFloat ey[3] = {e[0] * y[0], e[1] * y[1], e[2] * y[2]};
3818 MFloat t0 = -esqr[2] + ey[2];
3819 MFloat t1 = -esqr[2] + sqrt(ey[0] * ey[0] + ey[1] * ey[1] + ey[2] * ey[2]);
3820 MFloat t;
3821 const MInt imax = 2 * std::numeric_limits<MFloat>::max_exponent;
3822 MFloat eps = eps1;
3823 if(fabs(t1 - t0) < eps) t1 = t0 + F2 * eps;
3824 t = F1B2 * (t0 + t1);
3825 MInt i = 0;
3827
3828 while(fabs(t1 - t0) > eps && i < imax) {
3829 // loop unrolling
3830 while ( i < imax ) {
3831 i++;
3832 t = F1B2 * (t0 + t1);
3833 MFloat f0 = (t + esqr[0]) * (t + esqr[0]);
3834 MFloat f1 = (t + esqr[1]) * (t + esqr[1]);
3835 MFloat f2 = (t + esqr[2]) * (t + esqr[2]);
3836 MFloat fs = f0 * f1 * f2;
3837 // avoid division
3838 MFloat f = ey[0] * ey[0] * f1 * f2 + ey[1] * ey[1] * f0 * f2 + ey[2] * ey[2] * f0 * f1;
3839 if(f > fs) {
3840 t0 = t;
3841 } else {
3842 t1 = t;
3843 }
3844 if( fabs(t1 - t0) < eps || i >= imax ) break;
3845
3846 i++;
3847 t = F1B2 * (t0 + t1);
3848 f0 = (t + esqr[0])*(t + esqr[0]);
3849 f1 = (t + esqr[1])*(t + esqr[1]);
3850 f2 = (t + esqr[2])*(t + esqr[2]);
3851 fs = f0*f1*f2;
3852 f = ey[0] * ey[0] * f1 * f2 + ey[1] * ey[1] * f0 * f2 + ey[2] * ey[2] * f0 * f1;
3853 if(f > fs) {
3854 t0 = t;
3855 } else {
3856 t1 = t;
3857 }
3858 if(fabs(t1 - t0) < eps || i >= imax) break;
3859
3860 i++;
3861 t = F1B2 * (t0 + t1);
3862 f0 = (t + esqr[0])*(t + esqr[0]);
3863 f1 = (t + esqr[1])*(t + esqr[1]);
3864 f2 = (t + esqr[2])*(t + esqr[2]);
3865 fs = f0 * f1 * f2;
3866 f = ey[0] * ey[0] * f1 * f2 + ey[1] * ey[1] * f0 * f2 + ey[2] * ey[2] * f0 * f1;
3867 if(f > fs) {
3868 t0 = t;
3869 } else {
3870 t1 = t;
3871 }
3872 if(fabs(t1 - t0) < eps || i >= imax) break;
3873
3874 i++;
3875 t = F1B2 * (t0 + t1);
3876 f0 = (t + esqr[0])*(t + esqr[0]);
3877 f1 = (t + esqr[1])*(t + esqr[1]);
3878 f2 = (t + esqr[2])*(t + esqr[2]);
3879 fs = f0*f1*f2;
3880 f = ey[0] * ey[0] * f1 * f2 + ey[1] * ey[1] * f0 * f2 + ey[2] * ey[2] * f0 * f1;
3881 if(f > fs) {
3882 t0 = t;
3883 } else {
3884 t1 = t;
3885 }
3886 if(fabs(t1 - t0) < eps || i >= imax) break;
3887 }
3888 x[0] = esqr[0] * y[0] / (t + esqr[0]);
3889 x[1] = esqr[1] * y[1] / (t + esqr[1]);
3890 x[2] = esqr[2] * y[2] / (t + esqr[2]);
3891 distance = sqrt(POW2(x[0] - y[0]) + POW2(x[1] - y[1]) + POW2(x[2] - y[2]));
3892 // adjust eps: small close to surface, larger further away from surface
3893 eps = eps0 + mMin(F1, mMax(F0, (distance - dist0) / (dist1 - dist0))) * (eps1 - eps0);
3894 }
3895 if(fabs(t0 - t1) > eps) cerr << setprecision(16) << "ellipsoid dist not converged! " << i << " " << t1 - t0 << endl;
3896 return distance;
3897}

◆ distEllipsoidEllipsoid()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::distEllipsoidEllipsoid ( const MInt  k0,
const MInt  k1,
MFloat xc0,
MFloat xc1 
)
Author
Lennart Schneiders

Definition at line 3605 of file fvmbcartesiansolverxd.cpp.

3606 {
3607 MFloatScratchSpace R0(3, 3, AT_, "R0");
3608 MFloatScratchSpace R1(3, 3, AT_, "R1");
3609 MFloat xw[3];
3610 MFloat xb[3];
3611
3614
3615 for(MInt i = 0; i < nDim; i++)
3616 xc0[i] = m_bodyCenter[k0 * nDim + i];
3617 for(MInt i = 0; i < nDim; i++)
3618 xc1[i] = m_bodyCenter[k1 * nDim + i];
3619
3620 MFloat x = xc1[0] - xc0[0];
3621 MFloat y = xc1[1] - xc0[1];
3622 MFloat z = xc1[2] - xc0[2];
3623
3624 MFloat* xc = xc1;
3625 MFloat* xc_next = xc0;
3626
3627 MFloat dist0 = 9999998.0;
3628 MFloat dist = sqrt(x * x + y * y + z * z);
3629 MInt iter = 0;
3630 MInt id = -1;
3631 const MInt maxIter = 200;
3633 while(fabs(dist0 - dist) > eps && iter < maxIter) {
3634 id = (iter % 2 == 0) ? k0 : k1;
3635 xc = (iter % 2 == 0) ? xc1 : xc0;
3636 xc_next = (iter % 2 == 0) ? xc0 : xc1;
3637
3638 x = xc[0] - m_bodyCenter[id * nDim + 0];
3639 y = xc[1] - m_bodyCenter[id * nDim + 1];
3640 z = xc[2] - m_bodyCenter[id * nDim + 2];
3641
3642 xw[0] = x;
3643 xw[1] = y;
3644 xw[2] = z;
3645 if(iter % 2 == 0)
3646 matrixVectorProduct(xb, R0, xw);
3647 else
3648 matrixVectorProduct(xb, R1, xw);
3649 x = xb[0];
3650 y = xb[1];
3651 z = xb[2];
3652
3653 MFloat a = m_bodyRadii[id * nDim + 0];
3654 MFloat b = m_bodyRadii[id * nDim + 1];
3655 MFloat c = m_bodyRadii[id * nDim + 2];
3656
3657 MFloat ee[3] = {a, b, c};
3658 MFloat yy[3] = {x, y, z};
3659 MFloat xx[3] = {F0, F0, F0};
3660
3661 dist0 = dist;
3662 dist = distancePointEllipsoid(ee, yy, xx);
3663 if((POW2(x / a) + POW2(y / b) + POW2(z / c)) < F1) dist = -dist;
3664
3665 xb[0] = xx[0];
3666 xb[1] = xx[1];
3667 xb[2] = xx[2];
3668 if(iter % 2 == 0)
3669 matrixVectorProductTranspose(xw, R0, xb);
3670 else
3671 matrixVectorProductTranspose(xw, R1, xb);
3672
3673 xc_next[0] = xw[0] + m_bodyCenter[id * nDim + 0];
3674 xc_next[1] = xw[1] + m_bodyCenter[id * nDim + 1];
3675 xc_next[2] = xw[2] + m_bodyCenter[id * nDim + 2];
3676
3677 iter++;
3678 }
3679 if(iter >= maxIter && domainId() == 0)
3680 cerr << setprecision(12) << domainId() << ": ellipsoid dist did not converge " << k0 << " " << k1 << " / "
3681 << dist - dist0 << " " << dist << " " << dist0 << " " << iter << " " << endl;
3682
3683 return dist;
3684}
MFloat distancePointEllipsoid(const MFloat e[3], const MFloat y[3], MFloat x[3])

◆ exchangeAzimuthalOuterNodalValues()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::exchangeAzimuthalOuterNodalValues ( std::vector< CutCandidate< nDim > > &  candidates,
std::vector< MInt > &  candidateIds 
)
Author
Thomas Hoesgen

Definition at line 5912 of file fvmbcartesiansolverxd.cpp.

5913 {
5914 TRACE();
5915
5916 const MFloat signStencil[8][3] = {{-F1, -F1, -F1}, {F1, -F1, -F1}, {-F1, F1, -F1}, {F1, F1, -F1},
5917 {-F1, -F1, F1}, {F1, -F1, F1}, {-F1, F1, F1}, {F1, F1, F1}};
5918 const MInt nodeStencil[3][8] = {{0, 1, 0, 1, 0, 1, 0, 1}, {2, 2, 3, 3, 2, 2, 3, 3}, {4, 4, 4, 4, 5, 5, 5, 5}};
5919 const MInt reverseNode[3][8] = {{1, 0, 3, 2, 5, 4, 7, 6}, {2, 3, 0, 1, 6, 7, 4, 5}, {4, 5, 6, 7, 0, 1, 2, 3}};
5920
5921
5922 MIntScratchSpace notGradientIds(a_noCells(), AT_, "notGradientIds");
5923 notGradientIds.fill(-1);
5925 MIntScratchSpace notGradientCells(noAzimuthalHalos, AT_, "notGradientCells");
5926 MIntScratchSpace notGradientDomain(noAzimuthalHalos, AT_, "notGradientDomain");
5927 MIntScratchSpace notGradientOffset(noAzimuthalHalos, AT_, "notGradientOffset");
5928 MInt notGradientCntr = 0;
5929 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
5930 for(MUint j = 0; j < m_azimuthalMaxLevelHaloCells[i].size(); j++) {
5932 if(candidateIds[cellId] < 0) continue;
5933 notGradientCells[notGradientCntr] = cellId;
5934 notGradientDomain[notGradientCntr] = i;
5935 notGradientOffset[notGradientCntr] = j;
5936 notGradientIds[cellId] = notGradientCntr;
5937 notGradientCntr++;
5938 }
5939 }
5940
5941 MIntScratchSpace notGradientCorners(notGradientCntr * m_noCorners, AT_, "notGradientCorners");
5942 notGradientCorners.fill(-2);
5943
5944 MInt outerCnt = notGradientCntr * m_noCorners * (nDim + 1);
5945 MFloatScratchSpace outerNodes(outerCnt, AT_, "outerNodes");
5946 outerNodes.fill(F0);
5947 outerCnt = 0;
5948
5949 MIntScratchSpace sndSize(grid().noAzimuthalNeighborDomains(), AT_, "sndSize");
5950 sndSize.fill(0);
5951
5952 MFloat angle = grid().azimuthalAngle();
5953
5954 const MInt maxNoNghbrs = 56; // IPOW3[nDim];
5955 MIntScratchSpace nghbrList(maxNoNghbrs, AT_, "nghbrList");
5956 MIntScratchSpace nghbrNodes(maxNoNghbrs, AT_, "nghbrNodes");
5957 // MIntScratchSpace layerId(maxNoNghbrs, AT_, "layerList");
5958 nghbrList.fill(-1);
5959 nghbrNodes.fill(-1);
5960 MFloatScratchSpace nodalValue(m_noLevelSetsUsedForMb, AT_, "nodalValue");
5961 MFloat corner[nDim];
5962 for(MInt i = 0; i < notGradientCntr; i++) {
5963 MInt cellId = notGradientCells[i];
5964
5965 MFloat cellHalfLength = F1B2 * c_cellLengthAtCell(cellId);
5966 MInt counter;
5967 for(MInt node = 0; node < m_noCorners; node++) {
5968 counter = 0;
5969 if(notGradientCorners[i * m_noCorners + node] > -2) continue;
5970 MBool isOuter = true;
5971 nghbrList[counter] = cellId;
5972 nghbrNodes[counter] = node;
5973 counter++;
5974
5975 for(MInt d0 = 0; d0 < nDim; d0++) {
5976 MInt dir0 = nodeStencil[d0][node];
5977 MInt nghbrId0 = c_neighborId(cellId, dir0);
5978 if(nghbrId0 < 0) {
5979 MInt parentId = c_parentId(cellId);
5980 if(parentId > -1) nghbrId0 = c_neighborId(parentId, dir0);
5981 }
5982 if(nghbrId0 < 0) continue;
5983 nghbrList[counter] = nghbrId0;
5984 nghbrNodes[counter] = reverseNode[d0][node];
5985 counter++;
5986 for(MInt d1 = 0; d1 < nDim; d1++) {
5987 if(d1 == d0) continue;
5988 MInt dir1 = nodeStencil[d1][node];
5989 MInt nghbrId1 = c_neighborId(nghbrId0, dir1);
5990 if(nghbrId1 < 0) {
5991 MInt parentId = c_parentId(nghbrId0);
5992 if(parentId > -1) nghbrId1 = c_neighborId(parentId, dir1);
5993 }
5994 if(nghbrId1 < 0) continue;
5995 nghbrList[counter] = nghbrId1;
5996 nghbrNodes[counter] = reverseNode[d1][reverseNode[d0][node]];
5997 counter++;
5998 for(MInt d2 = 0; d2 < nDim; d2++) {
5999 if((d2 == d0) || (d2 == d1)) continue;
6000 MInt dir2 = nodeStencil[d2][node];
6001 MInt nghbrId2 = c_neighborId(nghbrId1, dir2);
6002 if(nghbrId2 < 0) {
6003 MInt parentId = c_parentId(nghbrId1);
6004 if(parentId > -1) nghbrId2 = c_neighborId(parentId, dir2);
6005 }
6006 if(nghbrId2 < 0) continue;
6007 nghbrList[counter] = nghbrId2;
6008 nghbrNodes[counter] = reverseNode[d2][reverseNode[d1][reverseNode[d0][node]]];
6009 counter++;
6010 }
6011 }
6012 }
6013
6014 for(MInt n = 0; n < counter; n++) {
6015 MInt nghbrId = nghbrList[n];
6016 if(!a_isPeriodic(nghbrId) && m_bndryCandidateIds[nghbrId] > 1) {
6017 isOuter = false;
6018 MInt nghbrNode = nghbrNodes[n];
6019 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
6020 nodalValue[set] = m_cutCandidates[m_bndryCandidateIds[nghbrId]].nodalValues[set][nghbrNode];
6021 }
6022 break;
6023 }
6024 }
6025
6026 if(isOuter) {
6027 outerNodes[outerCnt * (nDim + 1)] = (MFloat)notGradientOffset[i];
6028 for(MInt d = 0; d < nDim; d++) {
6029 corner[d] = c_coordinate(cellId, d) + signStencil[node][d] * cellHalfLength;
6030 }
6031 MInt side = grid().determineAzimuthalBoundarySide(corner);
6032 grid().rotateCartesianCoordinates(corner, (side * angle));
6033 std::copy_n(&corner[0], nDim, &outerNodes[outerCnt * (nDim + 1) + 1]);
6034 sndSize[notGradientDomain[i]]++;
6035
6036 for(MInt n = 0; n < counter; n++) {
6037 MInt nghbrId = nghbrList[n];
6038 MInt nId = notGradientIds[nghbrId];
6039 if(nId > -1) {
6040 MInt nghbrNode = nghbrNodes[n];
6041 notGradientCorners[nId * m_noCorners + nghbrNode] = outerCnt;
6042 }
6043 }
6044 outerCnt++;
6045 } else {
6046 for(MInt n = 0; n < counter; n++) {
6047 MInt nghbrId = nghbrList[n];
6048 MInt cndId = candidateIds[nghbrId];
6049 MInt nghbrNode = nghbrNodes[n];
6050 MInt nId = notGradientIds[nghbrId];
6051 if(cndId > -1) {
6052 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
6053 candidates[cndId].nodalValues[set][nghbrNode] = nodalValue[set];
6054 }
6055 }
6056 if(nId > -1) {
6057 notGradientCorners[nId * m_noCorners + nghbrNode] = -1;
6058 }
6059 }
6060 }
6061 }
6062 }
6063
6064 ScratchSpace<MPI_Request> mpi_send_req(grid().noAzimuthalNeighborDomains(), AT_, "mpi_send_req");
6065 ScratchSpace<MPI_Request> mpi_recv_req(grid().noAzimuthalNeighborDomains(), AT_, "mpi_recv_req");
6066 MIntScratchSpace rcvSize(grid().noAzimuthalNeighborDomains(), AT_, "rcvBuffSize");
6067
6068 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6069 MPI_Irecv(&rcvSize[i], 1, MPI_INT, grid().azimuthalNeighborDomain(i), 2, grid().mpiComm(), &mpi_recv_req[i], AT_,
6070 "rcvSize[i]");
6071 }
6072 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6073 MPI_Isend(&sndSize[i], 1, MPI_INT, grid().azimuthalNeighborDomain(i), 2, grid().mpiComm(), &mpi_send_req[i], AT_,
6074 "sndSize[i]");
6075 }
6076 MPI_Waitall(grid().noAzimuthalNeighborDomains(), &mpi_recv_req[0], MPI_STATUSES_IGNORE, AT_);
6077 MPI_Waitall(grid().noAzimuthalNeighborDomains(), &mpi_send_req[0], MPI_STATUSES_IGNORE, AT_);
6078
6079 MInt sndNodeCnt = 0;
6080 MInt rcvNodeCnt = 0;
6081 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6082 sndNodeCnt += sndSize[i];
6083 rcvNodeCnt += rcvSize[i];
6084 }
6085
6086 MInt fac = mMax((nDim + 1), m_noLevelSetsUsedForMb);
6087 MFloatScratchSpace rcvBuffers(mMax(sndNodeCnt, rcvNodeCnt) * fac, AT_, "rcvBuffers");
6088 MFloatScratchSpace sndBuffers(rcvNodeCnt * m_noLevelSetsUsedForMb, AT_, "sndBuffers");
6089
6090 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6091 mpi_send_req[i] = MPI_REQUEST_NULL;
6092 mpi_recv_req[i] = MPI_REQUEST_NULL;
6093 }
6094
6095 MInt offset = 0;
6096 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6097 if(rcvSize[i] > 0) {
6098 MInt bufSize = (nDim + 1) * rcvSize[i];
6099 MPI_Irecv(&rcvBuffers[offset], bufSize, MPI_DOUBLE, grid().azimuthalNeighborDomain(i), 2, grid().mpiComm(),
6100 &mpi_recv_req[i], AT_, "rcvBuffers[offset]");
6101 offset += bufSize;
6102 }
6103 }
6104
6105 offset = 0;
6106 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6107 if(sndSize[i] > 0) {
6108 MInt bufSize = (nDim + 1) * sndSize[i];
6109 MPI_Isend(&outerNodes[offset], bufSize, MPI_DOUBLE, grid().azimuthalNeighborDomain(i), 2, grid().mpiComm(),
6110 &mpi_send_req[i], AT_, "outerNodes[offset]");
6111 offset += bufSize;
6112 }
6113 }
6114
6115 MPI_Waitall(grid().noAzimuthalNeighborDomains(), &mpi_recv_req[0], MPI_STATUSES_IGNORE, AT_);
6116 MPI_Waitall(grid().noAzimuthalNeighborDomains(), &mpi_send_req[0], MPI_STATUSES_IGNORE, AT_);
6117
6118 std::function<MBool(const MInt, const MInt)> neighborCheck = [&](const MInt cellId, const MInt id) {
6119 return static_cast<MBool>(grid().tree().hasNeighbor(cellId, id));
6120 };
6121 std::function<MFloat(const MInt, const MInt)> coordinate = [&](const MInt cellId, const MInt id) {
6122 return static_cast<MFloat>(c_coordinate(cellId, id));
6123 };
6124
6125 offset = 0;
6126 MFloat eps = F1 + pow(10, -12);
6127 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
6128 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6129 for(MInt j = 0; j < rcvSize[i]; j++) {
6130 MInt cellId = m_azimuthalMaxLevelWindowCells[i][(MInt)rcvBuffers[(offset + j) * (nDim + 1)]];
6131 for(MInt d = 0; d < nDim; d++) {
6132 corner[d] = rcvBuffers[(offset + j) * (nDim + 1) + 1 + d];
6133 }
6134 if(!this->inCell(cellId, corner, eps)) {
6135 MInt counter = grid().getAdjacentGridCells(cellId, 1, nghbrList, a_level(cellId), 2);
6136 for(MInt n = 0; n < counter; n++) {
6137 MInt nghbrId = nghbrList[n];
6138 if(this->inCell(nghbrId, corner, eps)) {
6139 cellId = nghbrId;
6140 break;
6141 }
6142 }
6143 }
6144 ASSERT(this->inCell(cellId, corner, eps), "Coordindate not in cell!");
6145 MInt position = -1;
6146 position = this->setUpInterpolationStencil(cellId, interpolationCells, corner, neighborCheck, false);
6147 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
6148 if(position > -1) {
6149 MFloat phi = interpolateLevelSet(interpolationCells, corner, set);
6150 sndBuffers[(offset + j) * m_noLevelSetsUsedForMb + set] = phi;
6151 } else {
6152 sndBuffers[(offset + j) * m_noLevelSetsUsedForMb + set] = a_levelSetValuesMb(cellId, set);
6153 }
6154 }
6155 }
6156 offset += rcvSize[i];
6157 }
6158
6159 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6160 mpi_send_req[i] = MPI_REQUEST_NULL;
6161 mpi_recv_req[i] = MPI_REQUEST_NULL;
6162 }
6163
6164
6165 offset = 0;
6166 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6167 if(sndSize[i] > 0) {
6168 MInt bufSize = m_noLevelSetsUsedForMb * sndSize[i];
6169 MPI_Irecv(&rcvBuffers[offset], bufSize, MPI_DOUBLE, grid().azimuthalNeighborDomain(i), 2, grid().mpiComm(),
6170 &mpi_recv_req[i], AT_, "rcvBuffers[offset]");
6171 offset += bufSize;
6172 }
6173 }
6174
6175 offset = 0;
6176 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
6177 if(rcvSize[i] > 0) {
6178 MInt bufSize = m_noLevelSetsUsedForMb * rcvSize[i];
6179 MPI_Isend(&sndBuffers[offset], bufSize, MPI_DOUBLE, grid().azimuthalNeighborDomain(i), 2, grid().mpiComm(),
6180 &mpi_send_req[i], AT_, "sndBuffers[offset]");
6181 offset += bufSize;
6182 }
6183 }
6184
6185 MPI_Waitall(grid().noAzimuthalNeighborDomains(), &mpi_recv_req[0], MPI_STATUSES_IGNORE, AT_);
6186 MPI_Waitall(grid().noAzimuthalNeighborDomains(), &mpi_send_req[0], MPI_STATUSES_IGNORE, AT_);
6187
6188 for(MInt i = 0; i < notGradientCntr; i++) {
6189 MInt cellId = notGradientCells[i];
6190 MInt cndId = candidateIds[cellId];
6191 for(MInt node = 0; node < m_noCorners; node++) {
6192 if(notGradientCorners[i * m_noCorners + node] < 0) continue;
6193 offset = notGradientCorners[i * m_noCorners + node];
6194 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
6195 candidates[cndId].nodalValues[set][node] = rcvBuffers[offset * m_noLevelSetsUsedForMb + set];
6196 }
6197 }
6198 }
6199}
MFloat interpolateLevelSet(MInt *, MFloat *, MInt)
interpolates levelset function to a given coordinate
MInt setUpInterpolationStencil(const MInt cellId, MInt *, const MFloat *, std::function< MBool(MInt, MInt)>, MBool allowIncompleteStencil)
MInt inCell(const MInt cellId, MFloat *point, MFloat fac=F1)
int MPI_Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Isend
int MPI_Irecv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request, const MString &name, const MString &varname)
same as MPI_Irecv

◆ exchangeLevelSetData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::exchangeLevelSetData
Author
Lennart Schneiders, Claudia Guenther

Definition at line 12059 of file fvmbcartesiansolverxd.cpp.

12059 {
12060 TRACE();
12061
12064}

◆ exchangeLinkedHaloCellsForAzimuthalReconstruction()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::exchangeLinkedHaloCellsForAzimuthalReconstruction
Author
Thomas Hoesgen

Definition at line 36884 of file fvmbcartesiansolverxd.cpp.

36884 {
36885 TRACE();
36886
36888 MFloatScratchSpace windowData(sndSize * m_noCVars, AT_, "windowData");
36889 windowData.fill(0);
36891 MFloatScratchSpace haloData(rcvSize * m_noCVars, AT_, "haloData");
36892 haloData.fill(0);
36893
36894 MInt sndCnt = 0;
36895 for(MInt i = 0; i < noNeighborDomains(); i++) {
36896 for(MInt j = 0; j < (signed)m_azimuthalLinkedWindowCells[i].size(); j++) {
36898 std::copy_n(&a_variable(cellId, 0), m_noCVars, &windowData[sndCnt]);
36899 sndCnt += m_noCVars;
36900 }
36901 }
36902
36903 // Exchange
36905 mpiComm(), windowData.getPointer(), haloData.getPointer(), m_noCVars);
36906
36907 // Extract
36908 MInt rcvCnt = 0;
36909 for(MInt i = 0; i < noNeighborDomains(); i++) {
36910 for(MInt j = 0; j < (signed)m_azimuthalLinkedHaloCells[i].size(); j++) {
36912 std::copy_n(&haloData[rcvCnt], m_noCVars, &a_variable(cellId, 0));
36913 rcvCnt += m_noCVars;
36914 }
36915 }
36916}
std::vector< std::vector< MInt > > m_azimuthalLinkedWindowCells
std::vector< std::vector< MInt > > m_azimuthalLinkedHaloCells

◆ exchangeNodalLSValues()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::exchangeNodalLSValues ( )

◆ fileExists()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::fileExists ( const MChar fileName)
Author

Definition at line 26108 of file fvmbcartesiansolverxd.cpp.

26108 {
26109 struct stat buffer;
26110 return (stat(fileName, &buffer) == 0);
26111}

◆ filterFloat()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::filterFloat ( MFloat  number)
inline
Author
Lennart Schneiders

Definition at line 19365 of file fvmbcartesiansolverxd.cpp.

19365 {
19366 // if ( std::isnan( number ) ) return (-1e33);
19367 // else return number;
19368 return number;
19369}

◆ finalizeAdaptation()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::finalizeAdaptation
overridevirtual
Author
Tim Wegmann

! undo addboundarysurfaces !!

Reimplemented from Solver.

Definition at line 15542 of file fvmbcartesiansolverxd.cpp.

15542 {
15543 // set onlineRestart to false for the next initSolutionStep call!
15544 m_onlineRestart = false;
15545
15546 if(isActive()) {
15547 if(maxLevel() != maxRefinementLevel()) {
15548 if(domainId() == 0) {
15549 cerr << "MaxLevel is " << maxLevel() << " and maxRefinementLevel is " << maxRefinementLevel() << endl;
15550 }
15551 }
15552
15554 m_maxLevelChange = false;
15556 m_bndryLevelJumps = false;
15557 if(domainId() == 0) {
15558 cerr << "MaxLevel reached maxRefinementLevel! " << endl;
15559 }
15560 }
15561 }
15562
15564
15565 if(globalTimeStep < 0) return;
15566 if(!isActive()) return;
15567
15568 MFloatScratchSpace oldBCData(a_noCells(), 5, AT_, "oldBCData");
15569 oldBCData.fill(std::numeric_limits<MFloat>::lowest());
15570
15571 exchangeData(&a_cellVolume(0), 1);
15573
15574 // Correction for refined oldBndryCells:
15575 //- add oldBndryCells which are refined to refOldBndryCells and
15576 //- remove them from oldBndryCells!
15577 //- remove further entries (of cells which are uncut or inactive) in correctRefinedBndryCell!
15578 //- correct the swept/old Volume of the remaining bndryCells in correctRefinedBndryCellVolume
15579 // Correction for coarsened oldBndryCells:
15580 //- identify cells as they are marked with -99 sweptVolume
15581 //- correct the swept/old volume in correctCoarseBndryCellsVolume
15582 m_refOldBndryCells.clear();
15583 vector<MInt> deletedBndryCells;
15584 // const MInt noBndryLevelJumps = maxRefinementLevel() - m_lsCutCellMinLevel;
15585 for(auto it = m_oldBndryCells.begin(); it != m_oldBndryCells.end(); it++) {
15586 const MInt cellId = it->first;
15587 ASSERT(!a_isHalo(cellId), "");
15588 const MFloat sweptVol = it->second;
15589 if(!c_isLeafCell(cellId)) {
15590 deletedBndryCells.push_back(cellId);
15591 for(MInt childId = 0; childId < IPOW2(nDim); childId++) {
15592 const MInt child = c_childId(cellId, childId);
15593 if(child < 0) continue;
15594 if(!c_isLeafCell(child)) {
15595 cerr << "Cell is " << c_globalId(child) << " " << c_coordinate(child, 0) << " " << c_coordinate(child, 1)
15596 << " " << c_coordinate(child, nDim - 1) << " parent " << c_globalId(cellId) << " "
15597 << c_coordinate(cellId, 0) << " " << c_coordinate(cellId, 1) << " " << c_coordinate(cellId, nDim - 1)
15598 << endl;
15599 mTerm(1, AT_, "Multiple-levell changes in a bndry-cells not supported yet!");
15600 }
15601 m_refOldBndryCells.push_back(child);
15602 oldBCData(child, 0) = 2;
15603 }
15604 /*} else {
15605 vector<MInt> leafChildIds;
15606 grid().getAllLeafChilds(cellId, leafChildIds);
15607 ASSERT(!leafChildIds.empty(), "");
15608 for(MUint i = 0; i < leafChildIds.size(); i++) {
15609 const MInt child = leafChildIds[i];
15610 ASSERT(c_isLeafCell(child), "");
15611 m_refOldBndryCells.push_back(child);
15612 oldBCData(child, 0) = 2;
15613 }
15614
15615 } */
15616 } else {
15617 auto it1 = m_coarseOldBndryCells.find(cellId);
15618 if(it1 != m_coarseOldBndryCells.end()) {
15619 oldBCData(cellId, 0) = 3;
15620 }
15621 if(oldBCData(cellId, 0) < F0) {
15622 oldBCData(cellId, 0) = 1;
15623 }
15624 oldBCData(cellId, 1) = sweptVol;
15625 }
15626 }
15627
15628 for(MInt i = 0; i < (signed)deletedBndryCells.size(); i++) {
15629 const MInt cellId = deletedBndryCells[i];
15630 auto it = m_oldBndryCells.find(cellId);
15631 m_oldBndryCells.erase(it);
15632 ASSERT(!c_isLeafCell(cellId), "");
15633 ASSERT(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel), "");
15634 }
15635
15636 for(auto it = m_nearBoundaryBackup.begin(); it != m_nearBoundaryBackup.end(); it++) {
15637 const MInt cellId = it->first;
15638 ASSERT(!a_isHalo(cellId), to_string(a_isHalo(cellId)));
15639 oldBCData(cellId, 2) = F1;
15640 }
15641
15642 // set wasInactive/wasGapCell for halo-Cells
15643 for(MInt i = 0; i < noNeighborDomains(); i++) {
15644 for(MInt j = 0; j < noWindowCells(i); j++) {
15645 const MInt cellId = windowCellId(i, j);
15646 oldBCData(cellId, 3) = (MFloat)a_hasProperty(cellId, SolverCell::WasInactive);
15647 oldBCData(cellId, 4) = (MFloat)a_hasProperty(cellId, SolverCell::WasGapCell);
15648 }
15649 }
15650
15651 exchangeData(&oldBCData[0], 5);
15652
15653 // add halo-Cells to oldBndryCell and nearBoundaryBackup
15654 // and set wasInactive and wasGapCell
15655 for(MInt cellId = noInternalCells(); cellId < c_noCells(); cellId++) {
15656 ASSERT(a_isHalo(cellId), "");
15657
15659 for(MInt v = 0; v < m_noCVars; v++) {
15660 a_oldVariable(cellId, v) = a_variable(cellId, v);
15661 }
15662 if(oldBCData(cellId, 3) > -1) {
15663 a_hasProperty(cellId, SolverCell::WasInactive) = (MInt)oldBCData(cellId, 3);
15664 }
15665 if(oldBCData(cellId, 4) > -1) {
15666 a_hasProperty(cellId, SolverCell::WasGapCell) = (MInt)oldBCData(cellId, 4);
15667 }
15668
15669 if((MInt)oldBCData(cellId, 0) > F0) {
15670 ASSERT(c_isLeafCell(cellId), "");
15671 m_oldBndryCells.insert(make_pair(cellId, oldBCData(cellId, 1)));
15672 if((MInt)oldBCData(cellId, 0) == 2) {
15673 m_refOldBndryCells.push_back(cellId);
15674 } else if((MInt)oldBCData(cellId, 0) == 3) {
15675 m_coarseOldBndryCells.insert(cellId);
15676 }
15677 }
15678 if(oldBCData(cellId, 2) > F0) {
15679 vector<MFloat> tmp(max(m_noCVars + m_noFVars, 0) + 1);
15680 tmp[0] = m_cellVolumesDt1[cellId];
15681 for(MInt v = 0; v < m_noCVars; v++) {
15682 tmp[1 + v] = std::numeric_limits<MFloat>::lowest();
15683 }
15684 for(MInt v = 0; v < m_noFVars; v++) {
15685 tmp[1 + m_noCVars + v] = std::numeric_limits<MFloat>::lowest();
15686 }
15687 m_nearBoundaryBackup.insert(make_pair(cellId, tmp));
15688 }
15689 }
15690
15691 // Comm data back from window rank
15692 if(grid().azimuthalPeriodicity()) {
15694 }
15695
15697
15698 m_fvBndryCnd->recorrectCellCoordinates();
15699
15703
15704 for(MInt bndryId = 0; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
15705 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
15706 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = -1;
15707 }
15708 }
15709
15710#if defined _MB_DEBUG_ || !defined NDEBUG
15711
15712 MInt noRefBndryCells = m_refOldBndryCells.size();
15713 MInt noCoBndryCells = m_coarseOldBndryCells.size();
15714
15715 MPI_Allreduce(MPI_IN_PLACE, &noRefBndryCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "noRefBndryCells");
15716 MPI_Allreduce(MPI_IN_PLACE, &noCoBndryCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "noCoBndryCells");
15717
15718 if(noRefBndryCells > 0) {
15719 m_log << "Refining " << noRefBndryCells << " bndryCells in adaptation!" << endl;
15720 }
15721
15722 if(noCoBndryCells > 0) {
15723 m_log << "Coarsening " << noCoBndryCells << " bndryCells in adaptation!" << endl;
15724 }
15725
15726 checkHaloCells(1);
15727#endif
15728}
void finalizeAdaptation() override
MInt windowCellId(const MInt domainId, const MInt cellId) const

◆ finalizeBalance()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::finalizeBalance
overridevirtual
Author
Tim Wegmann

Reimplemented from Solver.

Definition at line 15149 of file fvmbcartesiansolverxd.cpp.

15149 {
15150 TRACE();
15151
15153
15155
15156 if(!grid().isActive()) {
15157 return;
15158 }
15159
15161
15162 if(globalTimeStep > 0) {
15163 if(!m_trackMovingBndry) {
15164 m_fvBndryCnd->m_cellCoordinatesCorrected = false;
15165 // necessary to recreate bndryCells after balance
15166 // if otherwise returning from reInitSolutionStep!!
15167 // TODO labels:FVMB,totest check mode 2, probably best to use mode 0 just after adaptation!
15168 preSolutionStep(0);
15169 // preSolutionStep(2);
15170 }
15171 leastSquaresReconstruction(); // Update slopes
15172 }
15173}
void finalizeBalance() override
Reinitialize solver after all data structures have been recreated.
void preSolutionStep(const MInt=-1) override
step before the solver solution Step
void setRungeKuttaFunctionPointer()
This function sets the function pointers for rungeKutta (also used in splitBalance)

◆ finalizeInitSolver()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::finalizeInitSolver
overridevirtual
Author
Lennart Schneiders, Tim Wegmann

Implements Solver.

Definition at line 11910 of file fvmbcartesiansolverxd.cpp.

11910 {
11911 TRACE();
11912
11913 // Nothing to be done if solver is not active
11914 if(!isActive()) return;
11915
11916 // initialize the solver
11917 ASSERT(!m_onlineRestart, "");
11918 initSolutionStep(-1);
11919
11920 if(!Context::propertyExists("ReLambdaRestart", m_solverId)) {
11922 computePV();
11923 }
11924
11925 // Reallocate solver memory to arrays depending on a_noCells()
11927
11928 if(m_zonal) {
11931 }
11932
11934 setTimeStep();
11935
11936 // First RHS
11937 // compute a first RHS (firstRHS) for the modified runge-kutta time step/solution step method:
11938 if(m_levelSetMb) {
11939 preSolutionStep(1);
11940
11941 // Set cut-off boundary conditions - Moved behind preSolutionStep
11944 if(grid().azimuthalPeriodicity()) {
11946 }
11947
11948 if(!m_levelSetRans && !m_standardRK) {
11949 this->rhs();
11950 this->rhsBnd();
11952 }
11953 }
11954}
void exchangeFloatDataAzimuthal(MFloat *data, MInt noVars, const std::vector< MInt > &rotIndices)
void reInitActiveCellIdsMemory()
Allocate memory to arrays according to the current number of cells.
void initSolutionStep(MInt mode) override
Initializes the solver.
void writeListOfActiveFlowCells() override
stores all cells and surfaces needed for the flux computation
void setTimeStep() override
calls sets() and stores the time step for all cells
void prepareNextTimeStep() override
Updates the old Variables, the body positions and the increases the time.

◆ gapCellExchange()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::gapCellExchange ( MInt  mode)
Author
Tim Wegmann

mode = 0 : only exchanges pvariables else : exchanges pvariables, oldVariable, wasInactive, status : and setConservativeVariables!

Definition at line 29786 of file fvmbcartesiansolverxd.cpp.

29786 {
29787 TRACE();
29788
29789 ASSERT(m_gapCellExchangeInit, "");
29790 if(noNeighborDomains() == 0) return;
29791
29792 MPI_Status statusMpi;
29793
29794 if(mode == 0) { // exchange of pvariables only
29795
29796 // gather
29797 for(MInt i = 0; i < noNeighborDomains(); i++) {
29798 if(m_gapWindowCells[i].empty()) continue;
29799 MInt sendBufferCounter = 0;
29800 for(MInt j = 0; j < (signed)m_gapWindowCells[i].size(); j++) {
29802 memcpy((void*)&m_sendBuffers[i][sendBufferCounter], (void*)&a_pvariable(cellId, 0),
29803 m_dataBlockSize * sizeof(MFloat));
29804 sendBufferCounter += m_dataBlockSize;
29805 }
29806 }
29807
29808 // send
29809 for(MInt i = 0; i < noNeighborDomains(); i++) {
29810 if(m_gapWindowCells[i].empty()) continue;
29811 MInt bufSize = m_gapWindowCells[i].size() * m_dataBlockSize;
29812 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
29813 "m_sendBuffers[i]");
29814 }
29815
29816 // receive
29817 for(MInt i = 0; i < noNeighborDomains(); i++) {
29818 if(m_gapHaloCells[i].empty()) continue;
29819 MInt bufSize = m_gapHaloCells[i].size() * m_dataBlockSize;
29820 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &statusMpi, AT_,
29821 "m_receiveBuffers[i]");
29822 }
29823 for(MInt i = 0; i < noNeighborDomains(); i++) {
29824 MPI_Wait(&g_mpiRequestMb[i], &statusMpi, AT_);
29825 }
29826
29827 // scatter
29828 for(MInt i = 0; i < noNeighborDomains(); i++) {
29829 if(m_gapHaloCells[i].empty()) continue;
29830 MInt receiveBufferCounter = 0;
29831 for(MInt j = 0; j < (signed)m_gapHaloCells[i].size(); j++) {
29832 MInt cellId = m_gapHaloCells[i][j];
29833 memcpy((void*)&a_pvariable(cellId, 0), (void*)&m_receiveBuffers[i][receiveBufferCounter],
29834 m_dataBlockSize * sizeof(MFloat));
29835 receiveBufferCounter += m_dataBlockSize;
29836 }
29837 }
29838
29839 } else { // exchange wasInactive, call gapCellExchange(0), oldVariables and status
29840
29841 // exchange wasInactive
29842 {
29843 MInt reverseExchange = 0;
29844
29846 // NOTE: if the halo-Cell has status -99
29847 // (meaning that the halo-Cell is the only active neighbor for a gapCell on a rank)
29848 // then a reverse exchange is triggered
29849 // and the according-window-Cell is updated based on the haloCell state!
29850
29851 // gather
29852 for(MInt i = 0; i < noNeighborDomains(); i++) {
29853 if(m_gapWindowCells[i].empty()) continue;
29854 MInt sendBufferCounter = 0;
29855 for(MInt j = 0; j < (signed)m_gapWindowCells[i].size(); j++) {
29857 m_sendBuffers[i][sendBufferCounter] = -F1;
29858 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
29859 m_sendBuffers[i][sendBufferCounter] = F1;
29860 }
29861 sendBufferCounter++;
29862 }
29863 }
29864
29865
29866 // send
29867 for(MInt i = 0; i < noNeighborDomains(); i++) {
29868 if(m_gapWindowCells[i].empty()) continue;
29869 MInt bufSize = m_gapWindowCells[i].size();
29870 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
29871 "m_sendBuffers[i]");
29872 }
29873
29874 // receive
29875 for(MInt i = 0; i < noNeighborDomains(); i++) {
29876 if(m_gapHaloCells[i].empty()) continue;
29877 MInt bufSize = m_gapHaloCells[i].size();
29878 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &statusMpi, AT_,
29879 "m_receiveBuffers[i]");
29880 }
29881 for(MInt i = 0; i < noNeighborDomains(); i++) {
29882 MPI_Wait(&g_mpiRequestMb[i], &statusMpi, AT_);
29883 }
29884
29885 // scatter
29886 for(MInt i = 0; i < noNeighborDomains(); i++) {
29887 if(m_gapHaloCells[i].empty()) continue;
29888 MInt receiveBufferCounter = 0;
29889 for(MInt j = 0; j < (signed)m_gapHaloCells[i].size(); j++) {
29890 const MInt cellId = m_gapHaloCells[i][j];
29891 const MInt status = m_gapCells[m_gapCellId[cellId]].status;
29892 if(status == -99) {
29893 reverseExchange = 1;
29894 receiveBufferCounter++;
29895 continue;
29896 }
29897 if(m_receiveBuffers[i][receiveBufferCounter] > 0) {
29898 a_hasProperty(cellId, SolverCell::WasInactive) = true;
29899 } else {
29900 a_hasProperty(cellId, SolverCell::WasInactive) = false;
29901 }
29902 receiveBufferCounter++;
29903 }
29904 }
29905
29906 MPI_Allreduce(MPI_IN_PLACE, &reverseExchange, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
29907 "reverseExchange");
29908
29909 if(reverseExchange > 0) {
29910 // reverse exchange on grid window+halo-cells
29911
29912 vector<MInt> updatedWindowCells;
29913
29914 // gather
29915 for(MInt i = 0; i < noNeighborDomains(); i++) {
29916 if(m_gapHaloCells[i].empty()) continue;
29917 MInt sendBufferCounter = 0;
29918 for(MInt j = 0; j < (signed)m_gapHaloCells[i].size(); j++) {
29919 MInt cellId = m_gapHaloCells[i][j];
29920 m_sendBuffers[i][sendBufferCounter] = -1.0;
29921 if(m_gapCells[m_gapCellId[cellId]].status == -99) {
29922 ASSERT(a_hasProperty(cellId, SolverCell::WasInactive) == false, "");
29923 m_sendBuffers[i][sendBufferCounter] = 2.0;
29924 }
29925 sendBufferCounter++;
29926 }
29927 }
29928
29929 // send
29930 for(MInt i = 0; i < noNeighborDomains(); i++) {
29931 if(m_gapHaloCells[i].empty()) continue;
29932 MInt bufSize = m_gapHaloCells[i].size();
29933 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
29934 "m_sendBuffers[i]");
29935 }
29936
29937 // receive
29938 for(MInt i = 0; i < noNeighborDomains(); i++) {
29939 if(m_gapWindowCells[i].empty()) continue;
29940 MInt bufSize = m_gapWindowCells[i].size();
29941 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &statusMpi, AT_,
29942 "m_receiveBuffers[i]");
29943 }
29944 for(MInt i = 0; i < noNeighborDomains(); i++) {
29945 MPI_Wait(&g_mpiRequestMb[i], &statusMpi, AT_);
29946 }
29947
29948 // scatter
29949 for(MInt i = 0; i < noNeighborDomains(); i++) {
29950 if(m_gapWindowCells[i].empty()) continue;
29951 MInt receiveBufferCounter = 0;
29952 for(MInt j = 0; j < (signed)m_gapWindowCells[i].size(); j++) {
29954 if(m_receiveBuffers[i][receiveBufferCounter] > 1) {
29955 updatedWindowCells.push_back(cellId);
29956 }
29957 receiveBufferCounter++;
29958 }
29959 }
29960
29961 // update cell-variables in the window-Cell:
29962 for(MUint i = 0; i < updatedWindowCells.size(); i++) {
29963 MInt cellId = updatedWindowCells[i];
29964 cerr << "Updating Window-Cell " << c_globalId(cellId) << endl;
29965 MInt masterId = -1;
29966 MFloat maxVol = F0;
29967 const MInt rootId = cellId;
29968 for(MInt dir = 0; dir < m_noDirs; dir++) {
29969 if(!checkNeighborActive(rootId, dir) || a_hasNeighbor(rootId, dir) == 0) continue;
29970 const MInt nghbrId = c_neighborId(rootId, dir);
29971 if(nghbrId < 0) continue;
29972 if(a_hasProperty(nghbrId, SolverCell::WasInactive)) continue;
29973 if(a_hasProperty(nghbrId, SolverCell::IsSplitCell)) continue;
29974 if(a_hasProperty(nghbrId, SolverCell::IsSplitChild)) continue;
29975 if(a_cellVolume(nghbrId) > maxVol) {
29976 masterId = nghbrId;
29977 maxVol = a_cellVolume(nghbrId);
29978 }
29979 }
29980 if(masterId > -1) {
29981 // update variables only if the cell has a valid master!
29982 // for narror gaps it is possible, that cellId does not have
29983 // a fully emerging neighbor!
29984 for(MInt v = 0; v < m_noCVars; v++) {
29985 a_variable(cellId, v) = a_variable(masterId, v);
29986 a_oldVariable(cellId, v) = a_oldVariable(masterId, v);
29987 }
29988 for(MInt v = 0; v < m_noPVars; v++) {
29989 a_pvariable(cellId, v) = a_pvariable(masterId, v);
29990 }
29991 }
29992 for(MInt v = 0; v < m_noFVars; v++) {
29993 a_rightHandSide(cellId, v) = F0;
29994 m_rhs0[cellId][v] = F0;
29995 }
29996 a_hasProperty(cellId, SolverCell::WasInactive) = false;
29997 MInt gapCellId = m_gapCellId[cellId];
29998 MInt region = m_gapCells[gapCellId].region;
29999 ASSERT(region > -1 && region < m_noGapRegions, " ");
30000 if(m_gapState[region] == 3) {
30001 m_gapCells[gapCellId].status = 17;
30002 } else {
30003 m_gapCells[gapCellId].status = 28;
30004 }
30005 }
30006
30007 // re-reverse exchange
30008 // now, that a window-Cell has been updated,
30009 // halo-Cells on other ranks need to be updated as well!
30010
30011 // gather
30012 for(MInt i = 0; i < noNeighborDomains(); i++) {
30013 if(m_gapWindowCells[i].empty()) continue;
30014 MInt sendBufferCounter = 0;
30015 for(MInt j = 0; j < (signed)m_gapWindowCells[i].size(); j++) {
30017 m_sendBuffers[i][sendBufferCounter] = -F1;
30018 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
30019 m_sendBuffers[i][sendBufferCounter] = F1;
30020 }
30021 sendBufferCounter++;
30022 }
30023 }
30024
30025
30026 // send
30027 for(MInt i = 0; i < noNeighborDomains(); i++) {
30028 if(m_gapWindowCells[i].empty()) continue;
30029 MInt bufSize = m_gapWindowCells[i].size();
30030 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
30031 "m_sendBuffers[i]");
30032 }
30033
30034 // receive
30035 for(MInt i = 0; i < noNeighborDomains(); i++) {
30036 if(m_gapHaloCells[i].empty()) continue;
30037 MInt bufSize = m_gapHaloCells[i].size();
30038 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &statusMpi, AT_,
30039 "m_receiveBuffers[i]");
30040 }
30041 for(MInt i = 0; i < noNeighborDomains(); i++) {
30042 MPI_Wait(&g_mpiRequestMb[i], &statusMpi, AT_);
30043 }
30044
30045 // scatter
30046 for(MInt i = 0; i < noNeighborDomains(); i++) {
30047 if(m_gapHaloCells[i].empty()) continue;
30048 MInt receiveBufferCounter = 0;
30049 for(MInt j = 0; j < (signed)m_gapHaloCells[i].size(); j++) {
30050 MInt cellId = m_gapHaloCells[i][j];
30051 if(m_receiveBuffers[i][receiveBufferCounter] > 0) {
30052 a_hasProperty(cellId, SolverCell::WasInactive) = true;
30053 } else {
30054 a_hasProperty(cellId, SolverCell::WasInactive) = false;
30055 }
30056 receiveBufferCounter++;
30057 }
30058 }
30059 }
30060
30061 } // exchange of wasInactive
30062
30063 // exchange of pVariables
30064 gapCellExchange(0);
30065
30066 // exchange of oldVariables
30067
30068 // gather
30069 for(MInt i = 0; i < noNeighborDomains(); i++) {
30070 if(m_gapWindowCells[i].empty()) continue;
30071 MInt sendBufferCounter = 0;
30072 for(MInt j = 0; j < (signed)m_gapWindowCells[i].size(); j++) {
30074 memcpy((void*)&m_sendBuffers[i][sendBufferCounter], (void*)&a_oldVariable(cellId, 0),
30075 m_dataBlockSize * sizeof(MFloat));
30076 sendBufferCounter += m_dataBlockSize;
30077 }
30078 }
30079
30080 // send
30081 for(MInt i = 0; i < noNeighborDomains(); i++) {
30082 if(m_gapWindowCells[i].empty()) continue;
30083 MInt bufSize = m_gapWindowCells[i].size() * m_dataBlockSize;
30084 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
30085 "m_sendBuffers[i]");
30086 }
30087
30088 // receive
30089 for(MInt i = 0; i < noNeighborDomains(); i++) {
30090 if(m_gapHaloCells[i].empty()) continue;
30091 MInt bufSize = m_gapHaloCells[i].size() * m_dataBlockSize;
30092 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &statusMpi, AT_,
30093 "m_receiveBuffers[i]");
30094 }
30095 for(MInt i = 0; i < noNeighborDomains(); i++) {
30096 MPI_Wait(&g_mpiRequestMb[i], &statusMpi, AT_);
30097 }
30098
30099 // scatter
30100 for(MInt i = 0; i < noNeighborDomains(); i++) {
30101 if(m_gapHaloCells[i].empty()) continue;
30102 MInt receiveBufferCounter = 0;
30103 for(MInt j = 0; j < (signed)m_gapHaloCells[i].size(); j++) {
30104 MInt cellId = m_gapHaloCells[i][j];
30105 memcpy((void*)&a_oldVariable(cellId, 0), (void*)&m_receiveBuffers[i][receiveBufferCounter],
30106 m_dataBlockSize * sizeof(MFloat));
30107 receiveBufferCounter += m_dataBlockSize;
30108 }
30109 }
30110
30111 // exchange gap-status:
30112
30113 // gather
30114 for(MInt i = 0; i < noNeighborDomains(); i++) {
30115 if(m_gapWindowCells[i].empty()) continue;
30116 MInt sendBufferCounter = 0;
30117 for(MInt j = 0; j < (signed)m_gapWindowCells[i].size(); j++) {
30119 MInt gapCellId = m_gapCellId[cellId];
30120 m_sendBuffers[i][sendBufferCounter] = (MFloat)m_gapCells[gapCellId].status;
30121 sendBufferCounter++;
30122 }
30123 }
30124
30125
30126 // send
30127 for(MInt i = 0; i < noNeighborDomains(); i++) {
30128 if(m_gapWindowCells[i].empty()) continue;
30129 MInt bufSize = m_gapWindowCells[i].size();
30130 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
30131 "m_sendBuffers[i]");
30132 }
30133
30134 // receive
30135 for(MInt i = 0; i < noNeighborDomains(); i++) {
30136 if(m_gapHaloCells[i].empty()) continue;
30137 MInt bufSize = m_gapHaloCells[i].size();
30138 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &statusMpi, AT_,
30139 "m_receiveBuffers[i]");
30140 }
30141 for(MInt i = 0; i < noNeighborDomains(); i++) {
30142 MPI_Wait(&g_mpiRequestMb[i], &statusMpi, AT_);
30143 }
30144
30145 // scatter
30146 for(MInt i = 0; i < noNeighborDomains(); i++) {
30147 if(m_gapHaloCells[i].empty()) continue;
30148 MInt receiveBufferCounter = 0;
30149 for(MInt j = 0; j < (signed)m_gapHaloCells[i].size(); j++) {
30150 MInt cellId = m_gapHaloCells[i][j];
30151 MInt gapCellId = m_gapCellId[cellId];
30152 m_gapCells[gapCellId].status = (MInt)m_receiveBuffers[i][receiveBufferCounter];
30153 receiveBufferCounter++;
30154 }
30155 }
30156 }
30157}
void gapCellExchange(MInt)
exchanges variables and wasInactive for gapCells

◆ gapHandling()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::gapHandling
Author
Tim Wegmann

Definition at line 27224 of file fvmbcartesiansolverxd.cpp.

27224 {
27225 TRACE();
27226
27227 ASSERT(m_levelSet && m_closeGaps, "");
27228 ASSERT(m_gapInitMethod > 0, "");
27229
27230 m_gapCellExchangeInit = false;
27231
27232 m_gapCellId.clear();
27233 m_gapCellId.resize(a_noCells());
27234 for(MInt i = 0; i < a_noCells(); i++)
27235 m_gapCellId[i] = -1;
27236
27237 // return early if no gapCells were found!
27238 if(m_noneGapRegions) return;
27239
27240 ASSERT(m_initGapCell, "");
27241
27242 // set gapCellId
27243 for(MUint it = 0; it < m_gapCells.size(); it++) {
27244 const MInt cellId = m_gapCells[it].cellId;
27245 m_gapCellId[cellId] = (MInt)it;
27246 }
27247
27248 // check if any gap opens
27249 MBool anyGapOpening = false;
27250 for(MInt region = 0; region < m_noGapRegions; region++) {
27251 if(m_gapState[region] == 2) anyGapOpening = true;
27252 }
27253
27254 // NOTE: split-childs are not yet added as gapCells as a region cann't be found for them immedeatly.
27255 // However, splitcells are still added and used for the interpolation!
27256 // Split-childs will be handeled at the end!
27257
27258 // b) categorise Gap-Cells
27259
27260 // 1) during initGapClosure:
27261 // Types:
27262 // 2 - body-shadowed gap-Cell :
27263 // 3 - gap-shadowed internalCell : delete surfaces
27264 // 4 - gap-shadowed Bndry-Cell : delete surface, remove from oldBndry-Cell-List, set gridVolume
27265 // 5 - Bndry-Cell : correct Bndry-Velocity, and cellVolumes
27266 // 6 - emerging bndryCell : correct Bndry-Velocity, and cellVolumes
27267 // 7 - new Gap-BndryCell : correct Bndry-Velocity, and cellVolumes
27268 // 8 - internal-Cell :
27269 // 9 - emerging internal Cell :
27270 // 99 - new body-bndry-Cell :
27271
27272 // NOTE: for now mass during initGapClosure is lost!
27273 // This mass-loss needs to be approximated!
27274 // Or alternatevly the mass can be redistributed towards sourrounding cells
27275
27276 MInt outInfo1 = 1;
27277 MInt outInfo2 = 1;
27278 for(MInt region = 0; region < m_noGapRegions; region++) {
27279 if(m_gapState[region] != -2) continue;
27280 for(MUint it = 0; it < m_gapCells.size(); it++) {
27281 MInt regionId = m_gapCells[it].region;
27282 if(regionId != region) continue;
27283 MInt cellId = m_gapCells[it].cellId;
27284
27285 // all Gap-Cells in that region (including Halo-Cells!)
27286 // if(a_level(cellId) != maxRefinementLevel()) continue;
27287 if(a_level(cellId) < m_lsCutCellMinLevel || !c_isLeafCell(cellId)) continue;
27288
27289 ASSERT(!a_wasGapCell(cellId), "");
27290 ASSERT(m_gapCells[it].status == 0, "");
27291 MInt flowCornerBodySet = 0;
27292 MInt flowCorner = 0;
27293 MInt bodyId = a_associatedBodyIds(cellId, 0);
27294 MInt bodySet = m_bodyToSetTable[bodyId];
27295
27297
27298
27299 if(cndId < 0) {
27300 if(a_levelSetValuesMb(cellId, bodySet) > F0) {
27301 flowCornerBodySet = m_noCellNodes;
27302 } else {
27303 flowCornerBodySet = 0;
27304 }
27305 if(a_levelSetValuesMb(cellId, 0) > F0) {
27306 flowCorner = m_noCellNodes;
27307 } else {
27308 flowCorner = 0;
27309 }
27310 } else {
27311 for(MInt node = 0; node < m_noCellNodes; node++) {
27312 if(m_candidateNodeValues[IDX_LSSETNODES(cndId, node, bodySet)] > F0) flowCornerBodySet++;
27313 if(m_candidateNodeValues[IDX_LSSETNODES(cndId, node, 0)] > F0) flowCorner++;
27314 }
27315 }
27316
27317
27318 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
27319 // TODO labels:FVMB use a_isBndryCell and IsInactive to differe here!
27320 // check if flowCorner are even nevessary!
27321 if(flowCorner == m_noCellNodes) {
27322 cerr << "UnExpected GapCell (1) at initGapClosure! " << c_globalId(cellId) << " " << a_isBndryCell(cellId)
27323 << " " << a_hasProperty(cellId, SolverCell::IsInactive) << " " << cndId << endl;
27324 } else if(flowCorner > 0 && flowCorner < m_noCellNodes) {
27325 // new bndry-Cell (was body-shadowed before)
27326 m_gapCells[it].status = 99;
27327 } else { // flowCorner == 0
27328 // body-shadowed Gap-Cell
27329 m_gapCells[it].status = 2;
27330 }
27331
27332 } else { // wasActive
27333 if(flowCorner == m_noCellNodes) {
27334 auto it1 = m_oldBndryCells.find(cellId);
27335 if(it1 != m_oldBndryCells.end()) {
27336 // emerging internal-Cell due to body-movement
27337 m_gapCells[it].status = 9;
27338 } else {
27339 // internal-Gap-Cell
27340 m_gapCells[it].status = 8;
27341 }
27342
27343
27344 } else if(flowCorner > 0 && flowCorner < m_noCellNodes) {
27345 if(flowCornerBodySet == 0) {
27346 // emerging-Bndry-Cell
27347 m_gapCells[it].status = 6;
27348 } else if(flowCornerBodySet == m_noCellNodes) {
27349 // new Gap-Bndry-Cell
27350 m_gapCells[it].status = 7;
27351 } else { // flowCornerBodySet > 0 && flowCornerBodySet < m_noCellNodes
27352 // bndry-Cell
27353 m_gapCells[it].status = 5;
27354 }
27355
27356
27357 } else { // flowCorner == 0 (wasActive but will be inactive!)
27358
27359 auto it1 = m_oldBndryCells.find(cellId);
27360 if(it1 != m_oldBndryCells.end()) {
27361 // gap-Shadowed Bndry-Cell
27362 m_gapCells[it].status = 4;
27363 if(outInfo2) {
27364 cerr << "--> Deleting oldBndryCells shadowed by the Gap in region " << regionId << endl;
27365 outInfo2 = 0;
27366 }
27367 removeSurfaces(cellId);
27368 m_oldBndryCells.erase(it1);
27369 a_cellVolume(cellId) = grid().gridCellVolume(a_level(cellId));
27370 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
27371 m_cellVolumesDt1[cellId] = grid().gridCellVolume(a_level(cellId));
27372 if(m_dualTimeStepping) m_cellVolumesDt2[cellId] = grid().gridCellVolume(a_level(cellId));
27373 for(MInt v = 0; v < m_noFVars; v++) {
27374 a_rightHandSide(cellId, v) = F0;
27375 m_rhs0[cellId][v] = F0;
27376 }
27377
27378 } else {
27379 // gap-Shadowed InternalCell
27380 m_gapCells[it].status = 3;
27381 if(outInfo1) {
27382 cerr << "--> Deleting Gap-Shadowed Cells in region " << regionId << endl;
27383 outInfo1 = 0;
27384 }
27385 removeSurfaces(cellId);
27386 ASSERT(fabs(grid().gridCellVolume(a_level(cellId)) - a_cellVolume(cellId)) < 0.00001, "");
27387 for(MInt v = 0; v < m_noFVars; v++) {
27388 a_rightHandSide(cellId, v) = F0;
27389 m_rhs0[cellId][v] = F0;
27390 }
27391 }
27392 }
27393 }
27394 }
27395 }
27396
27397 // 2) during gap-Shrinking
27398 // 30 : internal gap-Cell
27399 // 31 : gap or body-shadowed gapCell
27400 // 32 : new gap Bndry-Cell which used to be inactive (with lost gap-status)
27401 // 33 : new gap Bndry-Cell which used to be inactive (also wasGapCell)
27402 // 34 : gap-Bndry-Cell was bndryCell before
27403 // 35 : gap-Bndry-Cell was internal Cell before
27404 for(MInt region = 0; region < m_noGapRegions; region++) {
27405 if(m_gapState[region] != -1) continue;
27406 for(MUint it = 0; it < m_gapCells.size(); it++) {
27407 const MInt regionId = m_gapCells[it].region;
27408 if(regionId != region) continue;
27409 const MInt cellId = m_gapCells[it].cellId;
27410 const MInt status = m_gapCells[it].status;
27411
27412 if(status == 1) {
27413 // only inactive Cells may loose their gap-property during gap-shrinking!
27414 /*
27415 MInt flowCorner = 0;
27416 MInt cndId = m_bndryCandidateIds[ cellId ];
27417 if(cndId < 0) {
27418 if(a_levelSetValuesMb(cellId, 0) > F0) {
27419 flowCorner = m_noCellNodes;
27420 } else {
27421 flowCorner = 0;
27422 }
27423 } else {
27424 for ( MInt node = 0; node < m_noCellNodes; node++ ) {
27425 if(m_candidateNodeValues[ IDX_LSSETNODES(cndId, node, 0) ] > F0) flowCorner++;
27426 }
27427 }
27428 if(flowCorner > 0) {
27429 cerr << "CAUTION: Gap-Cell-Loss during shrinking " << c_globalId(cellId) << " "
27430 << a_levelSetValuesMb(cellId, 0) << " " << -eps << " "
27431 << a_hasProperty(cellId, SolverCell::WasInactive) << endl;
27432 }
27433 */
27434 } else {
27435 // is GapCell and might be gap-Cell before
27436
27437 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
27438 if(a_isBndryGhostCell(cellId)) continue;
27439
27440 // if(a_level(cellId) != maxRefinementLevel()) continue;
27441 if(a_level(cellId) < m_lsCutCellMinLevel || !c_isLeafCell(cellId)) continue;
27442
27443 MInt flowCornerBodySet = 0;
27444 MInt flowCorner = 0;
27445 MInt bodyId = a_associatedBodyIds(cellId, 0);
27446 MInt bodySet = m_bodyToSetTable[bodyId];
27447
27449
27450
27451 if(cndId < 0) {
27452 if(a_levelSetValuesMb(cellId, bodySet) > F0) {
27453 flowCornerBodySet = m_noCellNodes;
27454 } else {
27455 flowCornerBodySet = 0;
27456 }
27457 if(a_levelSetValuesMb(cellId, 0) > F0) {
27458 flowCorner = m_noCellNodes;
27459 } else {
27460 flowCorner = 0;
27461 }
27462 } else {
27463 for(MInt node = 0; node < m_noCellNodes; node++) {
27464 if(m_candidateNodeValues[IDX_LSSETNODES(cndId, node, bodySet)] > F0) flowCornerBodySet++;
27465 if(m_candidateNodeValues[IDX_LSSETNODES(cndId, node, 0)] > F0) flowCorner++;
27466 }
27467 }
27468
27469 if(flowCorner == m_noCellNodes) {
27470 // internal Gap-Cell
27471 m_gapCells[it].status = 30;
27472
27473
27474 } else if(flowCorner == 0) {
27475 // gap-or Body-shadowed Gap-Cell
27476 m_gapCells[it].status = 31;
27477
27478 } else { // Bndry-Cell
27479
27480 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
27481 // new Bndry-Cell
27482
27483 if(flowCornerBodySet == 8) {
27484 // new Gap-Bndry-Cell
27485
27486 } else {
27487 // new body-Bndry-Cell
27488 }
27489 } else {
27490 // old Bndry-Cell
27491 }
27492 }
27493 }
27494 }
27495 }
27496
27497 // 3) during gap-Widening
27498 // Types:
27499 // 10 : internal gap-Cell
27500 // 11 : gap or body-shadowed gapCell
27501 // 12 : new gap Bndry-Cell which used to be inactive (with lost gap-status)
27502 // 13 : new gap Bndry-Cell which used to be inactive (also wasGapCell)
27503 // 14 : gap-Bndry-Cell was bndryCell before
27504 // 15 : gap-Bndry-Cell was internal Cell before
27505 // 16 : new small gap Bndry-Cell with wasinactive neighbors (-> can't be linked easyly!)
27506
27507 vector<MInt> partialGapOpened;
27508 vector<MInt> fullyGapOpened;
27509 vector<MInt> fullyGapBndry;
27510 for(MInt region = 0; region < m_noGapRegions; region++) {
27511 partialGapOpened.push_back(0);
27512 fullyGapOpened.push_back(0);
27513 fullyGapBndry.push_back(0);
27514 if(m_gapState[region] != 3) continue;
27515 for(MUint it = 0; it < m_gapCells.size(); it++) {
27516 MInt regionId = m_gapCells[it].region;
27517 if(regionId != region) continue;
27518 MInt cellId = m_gapCells[it].cellId;
27519
27520 MInt status = m_gapCells[it].status;
27521
27522 if(status == 0) {
27523 /*
27524 //only inactive Cells may gain gap-property during gap-widening!
27525 MInt flowCorner = 0;
27526 MInt cndId = m_bndryCandidateIds[ cellId ];
27527 if(cndId < 0) {
27528 if(a_levelSetValuesMb(cellId, 0) > F0) {
27529 flowCorner = m_noCellNodes;
27530 } else {
27531 flowCorner = 0;
27532 }
27533 } else {
27534 for ( MInt node = 0; node < m_noCellNodes; node++ ) {
27535 if(m_candidateNodeValues[ IDX_LSSETNODES(cndId, node, 0) ] > F0) flowCorner++;
27536 }
27537 }
27538 if(flowCorner > 0) {
27539 cerr << "CAUTION: Gap-Cell-Gain during widening " << c_globalId(cellId) << " "
27540 << a_levelSetValuesMb(cellId, 0) << " " << -eps << " "
27541 << a_hasProperty(cellId, SolverCell::WasInactive) << endl;
27542 }
27543
27544 */
27545 } else {
27546 // a cell which lost its Gap-status or a remains a gapCell
27547 // now-check if it will be:
27548 // - an internalCell (only if the cell !wasInactive before),
27549 // - an inactive Cell (so still shadowed by a body)
27550 // - an active bndryCell
27551 // (then the Cell needs to be initialised by Cell-linking or its former bndryCell-status)
27552
27553 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
27554 if(a_isBndryGhostCell(cellId)) continue;
27555 // if(a_level(cellId) != maxRefinementLevel() ) continue;
27556 if(a_level(cellId) < m_lsCutCellMinLevel || !c_isLeafCell(cellId)) continue;
27557
27558 MInt flowCornerBodySet = 0;
27559 MInt flowCorner = 0;
27560 MInt bodyId = a_associatedBodyIds(cellId, 0);
27561 MInt bodySet = m_bodyToSetTable[bodyId];
27562
27564
27565
27566 if(cndId < 0) {
27567 if(a_levelSetValuesMb(cellId, bodySet) > F0) {
27568 flowCornerBodySet = m_noCellNodes;
27569 } else {
27570 flowCornerBodySet = 0;
27571 }
27572 if(a_levelSetValuesMb(cellId, 0) > F0) {
27573 flowCorner = m_noCellNodes;
27574 } else {
27575 flowCorner = 0;
27576 }
27577 } else {
27578 for(MInt node = 0; node < m_noCellNodes; node++) {
27579 if(m_candidateNodeValues[IDX_LSSETNODES(cndId, node, bodySet)] > F0) flowCornerBodySet++;
27580 if(m_candidateNodeValues[IDX_LSSETNODES(cndId, node, 0)] > F0) flowCorner++;
27581 }
27582 }
27583
27584
27585 if(flowCorner == m_noCellNodes) {
27586 // internal gap-Cell
27587
27588
27589 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
27590 // if the call was inactive before and is suddenly a completely emergerd cell,
27591 // fullyGapOpening has occoured, this is only possible
27592 // if the cell looses its gap-Status!
27593 // ASSERT(status == 1, "");
27594 if(status != 1) {
27595 cerr << "Incorrect status " << c_globalId(cellId) << a_hasProperty(cellId, SolverCell::WasInactive) << " "
27596 << a_hasProperty(cellId, SolverCell::IsInactive) << " " << a_isGapCell(cellId) << " "
27597 << a_wasGapCell(cellId) << endl;
27598 }
27599 m_gapCells[it].status = 21;
27600 fullyGapOpened[region]++;
27601
27602 } else {
27603 // the cell was an active cell before!
27604 m_gapCells[it].status = 10;
27605 }
27606
27607
27608 } else if(flowCorner == 0) {
27609 // the cell should be inactive
27610 // but can be either body or gap-shadowed
27611 ASSERT(a_hasProperty(cellId, SolverCell::IsInactive), "");
27612 m_gapCells[it].status = 11;
27613 if(status == 1) ASSERT(flowCornerBodySet == 0, "");
27614
27615 } else {
27616 // a gap-bndry-Cell which has lost its Gap-status or is still a Gap-Cell
27617
27618 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
27619 // a gap or body-shadowed Cell has become a new gap-bndry-Cell
27620 // needs to be linked to a master-Cell and thus initialised!
27621 if(status == 1) {
27622 m_gapCells[it].status = 22;
27623 fullyGapBndry[region]++;
27624 } else { // status -1
27625 m_gapCells[it].status = 13;
27626
27627 // check for partial gap-opening:
27628 MInt masterId = -1;
27629 MFloat maxVolActive = F0;
27630 MInt noInternalNghbrs = 0;
27631 const MInt rootId = cellId;
27632 for(MInt dir = 0; dir < m_noDirs; dir++) {
27633 if(!checkNeighborActive(rootId, dir) || a_hasNeighbor(rootId, dir) == 0) continue;
27634 const MInt nghbrId = c_neighborId(rootId, dir);
27635 if(nghbrId < 0) continue;
27636 if(!a_isHalo(nghbrId)) noInternalNghbrs++;
27637 if(a_hasProperty(nghbrId, SolverCell::WasInactive)) continue;
27638 if(a_hasProperty(nghbrId, SolverCell::IsSplitCell)) continue;
27639 if(a_hasProperty(nghbrId, SolverCell::IsSplitChild)) continue;
27640 if(a_cellVolume(nghbrId) > maxVolActive) {
27641 masterId = nghbrId;
27642 maxVolActive = a_cellVolume(nghbrId);
27643 }
27644 }
27645 if(masterId > -1) continue;
27646 if(a_isHalo(cellId) && noInternalNghbrs == 0) continue;
27647 if(a_isHalo(cellId) && a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
27648
27649 m_gapCells[it].status = 16;
27650 partialGapOpened[region]++;
27651 }
27652
27653 } else {
27654 // check if it used to be bndry-Cell before
27655 auto it1 = m_oldBndryCells.find(cellId);
27656 if(it1 != m_oldBndryCells.end()) {
27657 // cell was also a bndry-Cell before
27658 m_gapCells[it].status = 14;
27659 } else {
27660 // former internal Cell
27661 m_gapCells[it].status = 15;
27662 }
27663 }
27664 }
27665 }
27666 }
27667 }
27668
27669 // partial gap-opening occours if
27670 // a) a new bndry-Cell emerges which does not have an active neighbor!
27671
27672 MPI_Allreduce(MPI_IN_PLACE, &partialGapOpened[0], m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
27673 "partialGapOpened[0]");
27674 MPI_Allreduce(MPI_IN_PLACE, &fullyGapOpened[0], m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
27675 "fullyGapOpened[0]");
27676 MPI_Allreduce(MPI_IN_PLACE, &fullyGapBndry[0], m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
27677 "fullyGapBndry[0]");
27678
27679 MBool anyPartialGapOpened = false;
27680 for(MInt region = 0; region < m_noGapRegions; region++) {
27681 if(partialGapOpened[region] > 0) {
27682 anyPartialGapOpened = true;
27683 break;
27684 }
27685 }
27686
27687 MBool anyFullyGapOpened = false;
27688 for(MInt region = 0; region < m_noGapRegions; region++) {
27689 if(fullyGapOpened[region] > 0) {
27690 anyFullyGapOpened = true;
27691 break;
27692 }
27693 }
27694
27695 if(anyPartialGapOpened) {
27696 for(MInt region = 0; region < m_noGapRegions; region++) {
27697 if(domainId() == 0 && partialGapOpened[region] && !fullyGapOpened[region]) {
27698 cerr << "Partial Gap Opening at region " << region << " with " << partialGapOpened[region] << " Cells." << endl;
27699 }
27700 }
27701
27703
27704 for(MInt region = 0; region < m_noGapRegions; region++) {
27705 if(!partialGapOpened[region]) continue;
27706 if(fullyGapOpened[region]) continue;
27707 for(MUint it = 0; it < m_gapCells.size(); it++) {
27708 const MInt regionId = m_gapCells[it].region;
27709 if(regionId != region) continue;
27710 const MInt cellId = m_gapCells[it].cellId;
27711 const MInt status = m_gapCells[it].status;
27712
27713 if(status != 16) continue;
27714
27715 MInt largestNeighbor = checkNeighborActivity(cellId);
27716
27717 if(largestNeighbor >= 0) {
27718 MInt largestNeighborGapCellId = m_gapCellId[largestNeighbor];
27719 m_gapCells[largestNeighborGapCellId].status = 17;
27720 // trigger reverse exchange!
27721 if(a_isHalo(largestNeighbor)) {
27722 m_gapCells[largestNeighborGapCellId].status = -99;
27723 }
27724 }
27725 }
27726 }
27727
27728 gapCellExchange(1);
27729 }
27730
27731
27732 // 4) during initGapOpening
27733 // Types:
27734 // 21: arising gap-Cell : interpolate variables, wasInactive = false, restoreSurfaces,
27735 // 22: new body-Bndry-Cell : interpolate variables ,
27736 // link to !wasInactive neighbor,
27737 // insert in oldBndryCells, dalta-Function for cell velocity
27738 // 23: old Gap-Bndry-Cell : delete from oldBndry-Cell, set oldCellVolume to current-Volume,
27739 // reset rhs0
27740 // 24: gap-bndry-Cel : cellVolumes as in first TimeStep
27741 // 25: internal gap-Cell :
27742 // 26: body-shadowed gap-Cell :
27743 // 27: bndry-Cell/was internal :
27744 // 28: new body-Bndry-Cell : interpolate variables , wasInactive = false,
27745 // (former 22) insert in oldBndryCells,
27746 // 29: large new body-Bndry-Cell : interpolate variables , wasInactive = false,
27747 // (former 22)
27748 // 99: submerging bndry-cell : delte from oldBndryCells without mass-Redistribution
27749 // and reset as inactive cell
27750
27751 // NOTE: currently arising gap-Cells and new body-Bndry-Cells are initialised by linear-Interpolation
27752 // between the cell-staates on both sides of the gap.
27753 // Additionally mass is added to the system though volume increase for oldGap-Bndry-Cells!
27754 // This initialised mass can be weight against the lost mass in initGapClosure!
27755
27756 vector<MInt> noArisingGapCells;
27757 vector<MInt> noArisingGapCellsHalo;
27758 vector<MInt> noNewBndryCells;
27759 vector<MInt> noNewBndryCellsHalo;
27760
27761 vector<MInt> interpolationCells;
27762
27763 for(MInt region = 0; region < m_noGapRegions; region++) {
27764 noArisingGapCells.push_back(0);
27765 noArisingGapCellsHalo.push_back(0);
27766 noNewBndryCells.push_back(0);
27767 noNewBndryCellsHalo.push_back(0);
27768 if(m_gapState[region] != 2) continue;
27769 for(MUint it = 0; it < m_gapCells.size(); it++) {
27770 const MInt regionId = m_gapCells[it].region;
27771 if(regionId != region) continue;
27772 const MInt cellId = m_gapCells[it].cellId; // all previous Gap-Cells in that region
27773
27774 // if(a_isHalo(cellId)) continue;
27775 // if(a_hasProperty( cellId, SolverCell::IsSplitChild)) continue;
27776 if(a_isBndryGhostCell(cellId)) continue;
27777 ASSERT(a_level(cellId) == maxRefinementLevel(), "");
27778 // at gap opening, all previous gap cells should be reined to the highest Level!
27779 if(a_level(cellId) != maxRefinementLevel()) continue;
27780
27781 ASSERT(!a_isGapCell(cellId), "");
27782 ASSERT(m_gapCells[it].status == 1, "");
27783 // G0 now coinsides with the set of the according body!
27784
27785 MInt flowCorner = 0;
27786 MInt bodyId = a_associatedBodyIds(cellId, 0);
27787 MInt bodySet = m_bodyToSetTable[bodyId];
27788
27790
27791 if(cndId < 0) {
27792 if(a_levelSetValuesMb(cellId, bodySet) > F0) {
27793 flowCorner = m_noCellNodes;
27794 } else {
27795 flowCorner = 0;
27796 }
27797 } else {
27798 for(MInt node = 0; node < m_noCellNodes; node++) {
27799 if(m_candidateNodeValues[IDX_LSSETNODES(cndId, node, bodySet)] > F0) flowCorner++;
27800 }
27801 }
27802
27803 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
27804 if(flowCorner == m_noCellNodes) {
27805 // arising gap-Cell
27806 m_gapCells[it].status = 21;
27807 if(a_isHalo(cellId)) {
27808 noArisingGapCellsHalo[region]++;
27809 } else {
27810 noArisingGapCells[region]++;
27811 }
27812
27813 } else if(flowCorner == 0) {
27814 // body-shadowed gap-Cell
27815 m_gapCells[it].status = 26;
27816
27817 } else {
27818 // will be bndry-Cell
27819 if(a_isHalo(cellId)) {
27820 noNewBndryCellsHalo[region]++;
27821 } else {
27822 noNewBndryCells[region]++;
27823 }
27824 m_gapCells[it].status = 22;
27825 }
27826
27827
27828 } else { // was active
27829
27830 auto it1 = m_oldBndryCells.find(cellId);
27831 if(it1 != m_oldBndryCells.end()) {
27832 if(flowCorner == m_noCellNodes) {
27833 // will be internal-Cell
27834 // old-Gap-bndry-Cell
27835 m_gapCells[it].status = 23;
27836
27837 // delete former bndry-Cell
27838 //--> releasing mass into the fluid
27839 // shall be treated just as if the cell had been an internal-Cell before!
27840 for(MInt v = 0; v < m_noFVars; v++) {
27841 a_rightHandSide(cellId, v) = F0;
27842 m_rhs0[cellId][v] = F0;
27843 }
27844
27845 if(m_dualTimeStepping) m_cellVolumesDt2[cellId] = grid().gridCellVolume(a_level(cellId));
27846 a_cellVolume(cellId) = grid().gridCellVolume(a_level(cellId));
27847 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
27848 m_cellVolumesDt1[cellId] = grid().gridCellVolume(a_level(cellId));
27849 m_oldBndryCells.erase(it1);
27850
27851 } else if(flowCorner == 0) {
27852 // submerging bndry-cell
27853 // will be inactive cell, was bndry-Cell
27854 m_gapCells[it].status = 99;
27855
27856 // delete former bndry-Cell
27857 //--> releasing mass into the fluid
27858 // shall be treated just as if the cell had been an internal-Cell before!
27859 for(MInt v = 0; v < m_noFVars; v++) {
27860 a_rightHandSide(cellId, v) = F0;
27861 m_rhs0[cellId][v] = F0;
27862 }
27863 removeSurfaces(cellId);
27864
27865 if(m_dualTimeStepping) m_cellVolumesDt2[cellId] = grid().gridCellVolume(a_level(cellId));
27866 a_cellVolume(cellId) = grid().gridCellVolume(a_level(cellId));
27867 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
27868 m_cellVolumesDt1[cellId] = grid().gridCellVolume(a_level(cellId));
27869 m_oldBndryCells.erase(it1);
27870
27871
27872 } else {
27873 // gap-bndry-cell
27874 m_gapCells[it].status = 24;
27875 // handeled regularly as emerging cell!
27876 }
27877
27878 } else { // not a old Bndry-Cell
27879
27880 // TODO labels:FVMB use a_isBndryCell and IsInactive to differe here!
27881 if(flowCorner == m_noCellNodes) {
27882 // will be internal-Cell
27883 // gap-internal-cell
27884 m_gapCells[it].status = 25;
27885
27886 } else if(flowCorner == 0) {
27887 cerr << "UnExpected GapCell (2) at initGapOpening! " << c_globalId(cellId) << endl;
27888
27889 } else {
27890 // was internal, will be bndry-Cell
27891 // cerr << "UnExpected GapCell (3) at initGapOpening! " << c_globalId(cellId) << endl;
27892 m_gapCells[it].status = 27;
27893 }
27894 }
27895 }
27896 }
27897 }
27898
27899 MPI_Allreduce(MPI_IN_PLACE, &noArisingGapCells[0], m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
27900 "noArisingGapCells[0]");
27901 MPI_Allreduce(MPI_IN_PLACE, &noNewBndryCells[0], m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
27902 "noNewBndryCells[0]");
27903 MPI_Allreduce(MPI_IN_PLACE, &noArisingGapCellsHalo[0], m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_,
27904 "MPI_IN_PLACE", "noArisingGapCellsHalo[0]");
27905 MPI_Allreduce(MPI_IN_PLACE, &noNewBndryCellsHalo[0], m_noGapRegions, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
27906 "noNewBndryCellsHalo[0]");
27907
27908 // c) special Treatment if any Gap Opens:
27909 // meaning either gapState 2 or fullyGapOpening during gap-Widening!
27910 if(anyGapOpening || anyFullyGapOpened) {
27911 for(MInt region = 0; region < m_noGapRegions; region++) {
27912 if(m_gapState[region] == 2 && domainId() == 0) {
27913 cerr << "Number of Arising-Gap-Cells " << noArisingGapCells[region] << " in region " << region << endl;
27914 cerr << "Number of new-Bndry-Cells " << noNewBndryCells[region] << " in region " << region << endl;
27915 } else if(domainId() == 0 && m_gapState[region] == 3) {
27916 cerr << "Number of Fully arising-Gap-Cells " << fullyGapOpened[region] << " in region " << region << endl;
27917 cerr << "Number of new-Bndry-Cells " << fullyGapBndry[region] << " in region " << region << endl;
27918 }
27919 }
27920
27922
27923 // 2) init arising GapCells and new Bndry-Cells
27924 for(MInt region = 0; region < m_noGapRegions; region++) {
27925 if(m_gapState[region] != 2 && !fullyGapOpened[region]) continue;
27926 for(MUint it = 0; it < m_gapCells.size(); it++) {
27927 const MInt regionId = m_gapCells[it].region;
27928 if(regionId != region) continue;
27929 const MInt cellId = m_gapCells[it].cellId;
27930 const MInt status = m_gapCells[it].status;
27931
27932 if(status == 21) {
27933 if(!a_isHalo(cellId)) {
27934 interpolationCells.push_back(cellId);
27935 }
27936
27937 // these are all arings-Gap-Cells:
27938 //(sudden change towards internal Cells)
27939 // they need to be initialised before the cell-linking
27940 ASSERT(!a_hasProperty(cellId, SolverCell::IsInactive), "");
27941
27942 // 1) restore all surfaces
27943 restoreSurfaces(cellId);
27944
27945 // 2) init with the infinity-variables!
27946
27947 a_pvariable(cellId, PV->RHO) = m_rhoInfinity;
27948 a_pvariable(cellId, PV->U) = F0;
27949 a_pvariable(cellId, PV->V) = F0;
27950 IF_CONSTEXPR(nDim == 3) a_pvariable(cellId, PV->W) = F0;
27951 a_pvariable(cellId, PV->P) = m_PInfinity;
27952
27953 // 3) set the correct Volume
27954 a_cellVolume(cellId) = grid().gridCellVolume(a_level(cellId));
27955 m_cellVolumesDt1[cellId] = grid().gridCellVolume(a_level(cellId));
27956 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
27957
27958 // 4) initialise rightHandSide
27959 for(MInt v = 0; v < m_noFVars; v++) {
27960 a_rightHandSide(cellId, v) = F0;
27961 m_rhs0[cellId][v] = F0;
27962 }
27963
27964 // 5) treat as if the cell would have been active before
27965 // this way, no special Linking is necessary!
27966 // and small bndry-cells can be linked to the large arising Gap-Cells
27967 // -> less checkNeighborActive!
27968 ASSERT(a_hasProperty(cellId, SolverCell::WasInactive), "");
27969 a_hasProperty(cellId, SolverCell::WasInactive) = false;
27970
27971 } else if(status == 22) {
27972 if(!a_isHalo(cellId)) {
27973 interpolationCells.push_back(cellId);
27974 }
27975
27976 ASSERT(!a_hasProperty(cellId, SolverCell::IsInactive), "");
27977 // 1) init with the infinity-variables!
27978
27979 a_pvariable(cellId, PV->RHO) = m_rhoInfinity;
27980 a_pvariable(cellId, PV->U) = F0;
27981 a_pvariable(cellId, PV->V) = F0;
27982 IF_CONSTEXPR(nDim == 3) a_pvariable(cellId, PV->W) = F0;
27983 a_pvariable(cellId, PV->P) = m_PInfinity;
27984
27985 // 2) initialise rightHandSide
27986 for(MInt v = 0; v < m_noFVars; v++) {
27987 a_rightHandSide(cellId, v) = F0;
27988 m_rhs0[cellId][v] = F0;
27989 }
27990 }
27991 }
27992 }
27993
27994 // for security/backup reasons!
27995 gapCellExchange(1);
27996
27997 // 3) interpolate primativeVariables for arising GapCells and new bndry-Cells
27998 // status 21,22
27999 vector<MInt> noIterations;
28000 for(MInt region = 0; region < m_noGapRegions; region++) {
28001 noIterations.push_back(0);
28002 noIterations[region] = noArisingGapCells[region] + (MInt)(noNewBndryCells[region] / IPOW2(nDim))
28003 + fullyGapOpened[region] + fullyGapBndry[region];
28004 noIterations[region] = mMax(noIterations[region], 100);
28005 }
28006
28007 MPI_Allreduce(MPI_IN_PLACE, &noIterations[0], m_noGapRegions, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
28008 "noIterations[0]");
28009
28010 for(MInt region = 0; region < m_noGapRegions; region++) {
28011 if(m_gapState[region] != 2 && !fullyGapOpened[region]) continue;
28012#if defined _MB_DEBUG_ || !defined NDEBUG
28013 if(domainId() == 0) {
28014 cerr << "Starting to iterate for region: " << region << " with " << noIterations[region] << " Iterations! "
28015 << endl;
28016 }
28017#endif
28018 // iterate over the global number of arisingGapCells
28019 for(MInt loop = 0; loop < noIterations[region]; loop++) {
28020 for(MUint i = 0; i < interpolationCells.size(); i++) {
28021 const MInt cellId = interpolationCells[i];
28022 const MInt it = m_gapCellId[cellId];
28023 ASSERT(it >= 0, "");
28024 const MInt regionId = m_gapCells[it].region;
28025 if(regionId != region) continue;
28026 const MInt status = m_gapCells[it].status;
28027
28028 ASSERT(status == 21 || status == 22, "");
28029 ASSERT(!a_isHalo(cellId), "");
28030
28031 // all-arising gap-cells in the region:
28032 MInt noNghbrs = 0;
28033 MFloat pVariables[5] = {F0, F0, F0, F0, F0};
28034
28035 for(MInt dir = 0; dir < m_noDirs; dir++) {
28036 if(!checkNeighborActive(cellId, dir) || a_hasNeighbor(cellId, dir) == 0) continue;
28037 MInt nghbrId = c_neighborId(cellId, dir);
28038 if(nghbrId < 0) continue;
28039 ASSERT(!a_hasProperty(nghbrId, SolverCell::IsInactive), "");
28040 if(!a_wasGapCell(nghbrId) && a_hasProperty(nghbrId, SolverCell::WasInactive)) continue;
28041
28042 /*
28043 if(!a_wasGapCell(nghbrId)) {
28044 //TODO labels:FVMB change to ASSERT!
28045 if(loop == 0) {
28046 cerr << "Interpolation from not-gap-Cell -> Strange "
28047 << a_hasProperty(nghbrId, SolverCell::IsInactive)
28048 << a_hasProperty(nghbrId, SolverCell::WasInactive)
28049 << a_isBndryCell(nghbrId) << " " << c_globalId(cellId) << endl;
28050 }
28051 if(!a_hasProperty(cellId, SolverCell::IsInactive) &&
28052 !a_hasProperty(cellId, SolverCell::WasInactive)) {
28053 cerr << "CAUTION: Interpolation-Cell has a active Neighbor which was not a Gap-Cell "
28054 << c_globalId(cellId) << " " << c_globalId(nghbrId) << endl;
28055 }
28056 continue;
28057 }
28058 */
28059 MInt nghbrGapId = m_gapCellId[nghbrId];
28060 if(nghbrGapId >= 0) {
28061 // if the neighbor is a gap-cell further checks can be done:
28062
28063 MInt nghbrStatus = m_gapCells[nghbrGapId].status;
28064 // avoid inactive-neighbors
28065 if(nghbrStatus == 26) continue;
28066
28067 // skip gap-bndry-cells and only use internal cells for interpolation!
28068 if(nghbrStatus == 23 || nghbrStatus == 24) {
28069 // gap-bndry-Cell
28070 //-> find avtive gap-Cell be going one Step further in the same direction!
28071 if(!checkNeighborActive(nghbrId, dir) || a_hasNeighbor(nghbrId, dir) == 0) continue;
28072 nghbrId = c_neighborId(nghbrId, dir);
28073 if(nghbrId < 0) continue;
28074 nghbrGapId = m_gapCellId[nghbrId];
28075 nghbrStatus = m_gapCells[nghbrGapId].status;
28076
28077 if(nghbrStatus == 23) {
28078 // going another Step further
28079 if(!checkNeighborActive(nghbrId, dir) || a_hasNeighbor(nghbrId, dir) == 0) continue;
28080 nghbrId = c_neighborId(nghbrId, dir);
28081 if(nghbrId < 0) continue;
28082 nghbrGapId = m_gapCellId[nghbrId];
28083 nghbrStatus = m_gapCells[nghbrGapId].status;
28084 }
28085 }
28086
28087 // skip gap-bndry-cells and only use internal cells for interpolation!
28088 if(nghbrStatus == 10 || nghbrStatus == 14) {
28089 // gap-bndry-Cell
28090 //-> find avtive gap-Cell be going one Step further in the same direction!
28091 if(!checkNeighborActive(nghbrId, dir) || a_hasNeighbor(nghbrId, dir) == 0) continue;
28092 nghbrId = c_neighborId(nghbrId, dir);
28093 if(nghbrId < 0) continue;
28094 nghbrGapId = m_gapCellId[nghbrId];
28095 nghbrStatus = m_gapCells[nghbrGapId].status;
28096
28097 if(nghbrStatus == 10) {
28098 // going another Step further
28099 if(!checkNeighborActive(nghbrId, dir) || a_hasNeighbor(nghbrId, dir) == 0) continue;
28100 nghbrId = c_neighborId(nghbrId, dir);
28101 if(nghbrId < 0) continue;
28102 nghbrGapId = m_gapCellId[nghbrId];
28103 nghbrStatus = m_gapCells[nghbrGapId].status;
28104 }
28105 }
28106 if(nghbrStatus == 26) continue;
28107
28108 if(m_gapState[region] == 2 && a_wasGapCell(nghbrId) && nghbrStatus != 25 && nghbrStatus != 21
28109 && nghbrStatus != 23 && nghbrStatus != 22 && nghbrStatus != 24) {
28110 cerr << "Caution: using strange neighbor for interpolation: " << c_globalId(cellId) << " " << status
28111 << " " << c_globalId(nghbrId) << " " << a_wasGapCell(nghbrId) << " "
28112 << a_hasProperty(nghbrId, SolverCell::WasInactive) << " " << nghbrStatus << endl;
28113 } else if(m_gapState[region] == 3 && a_wasGapCell(nghbrId) && nghbrStatus != 21 && nghbrStatus != 22
28114 && nghbrStatus != 10 && nghbrStatus != 14) {
28115 cerr << "Caution: using strange neighbor for interpolation: " << c_globalId(cellId) << " " << status
28116 << " " << c_globalId(nghbrId) << " " << a_wasGapCell(nghbrId) << " "
28117 << a_hasProperty(nghbrId, SolverCell::WasInactive) << " " << nghbrStatus << endl;
28118 }
28119 }
28120
28121 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
28122
28123 ASSERT(!a_hasProperty(nghbrId, SolverCell::IsInactive), "");
28124 if(!a_wasGapCell(nghbrId) && a_hasProperty(nghbrId, SolverCell::WasInactive)) continue;
28125
28126 // only use former internal-Cells for interpolation!
28127 auto it1 = m_oldBndryCells.find(nghbrId);
28128 if(it1 != m_oldBndryCells.end()) continue;
28129
28130
28131 noNghbrs++;
28132 pVariables[0] += a_pvariable(nghbrId, PV->RHO);
28133 pVariables[1] += a_pvariable(nghbrId, PV->P);
28134 pVariables[2] += a_pvariable(nghbrId, PV->U);
28135 pVariables[3] += a_pvariable(nghbrId, PV->V);
28136 IF_CONSTEXPR(nDim == 3) pVariables[4] += a_pvariable(nghbrId, PV->W);
28137
28138 // if(!a_isHalo(cellId) && loop == 0)
28139 // cerr << "Neighbors of Arising Gap-Cell " << c_globalId(cellId) << " "
28140 // << c_globalId(nghbrId) << " status " << nghbrStatus << endl;
28141 }
28142 if(noNghbrs > 0) {
28143 a_pvariable(cellId, PV->RHO) = pVariables[0] / noNghbrs;
28144 a_pvariable(cellId, PV->P) = pVariables[1] / noNghbrs;
28145 a_pvariable(cellId, PV->U) = pVariables[2] / noNghbrs;
28146 a_pvariable(cellId, PV->V) = pVariables[3] / noNghbrs;
28147 IF_CONSTEXPR(nDim == 3) a_pvariable(cellId, PV->W) = pVariables[4] / noNghbrs;
28148 }
28149 }
28150
28151 gapCellExchange(0);
28152 }
28153 }
28154
28155 // 2) set wasInactive to false for large bndry-Cells
28156 // some cells with status 22 are changed to status 29!
28157 // (bndry-Cells outside the small-Cell-Treatment and thus should be stable)
28158 // -> the smaller neighboring cells can be linked to them esier!
28159
28160 for(MInt region = 0; region < m_noGapRegions; region++) {
28161 if(m_gapState[region] != 2) continue;
28162 for(MUint it = 0; it < m_gapCells.size(); it++) {
28163 MInt regionId = m_gapCells[it].region;
28164 if(regionId != region) continue;
28165 MInt cellId = m_gapCells[it].cellId;
28166 MInt status = m_gapCells[it].status;
28167
28168 if(status != 22) continue;
28169
28170 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume / grid().gridCellVolume(a_level(cellId)) > 0.5) {
28171 a_hasProperty(cellId, SolverCell::WasInactive) = false;
28172 m_oldBndryCells.insert(make_pair(cellId, F0));
28173 m_gapCells[it].status = 29;
28174 }
28175 if(noArisingGapCells[region] == 0 && fullyGapOpened[region] == 0) {
28176 // if only bndry-cells are arising: (this means that gapWidth < cellLength)
28177 if(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume / grid().gridCellVolume(a_level(cellId))
28178 > (0.5 * 0.5)) {
28179 a_hasProperty(cellId, SolverCell::WasInactive) = false;
28180 m_oldBndryCells.insert(make_pair(cellId, F0));
28181 m_gapCells[it].status = 29;
28182 }
28183 }
28184 }
28185 }
28186
28187
28188 // 4) set conservativeVariables of Gap-Cells
28189 // and set wasInactive accoring to checkNeighborActivity for bndry-Cells
28190 for(MInt region = 0; region < m_noGapRegions; region++) {
28191 if(m_gapState[region] != 2) continue;
28192 for(MUint it = 0; it < m_gapCells.size(); it++) {
28193 MInt regionId = m_gapCells[it].region;
28194 if(regionId != region) continue;
28195 MInt cellId = m_gapCells[it].cellId;
28196 MInt status = m_gapCells[it].status;
28197
28198 if(status != 21 && status != 22 && status != 29) continue;
28199
28201
28202 // init oldVariable
28203 for(MInt varId = 0; varId < CV->noVariables; varId++) {
28204 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
28205 }
28206
28207 if(status != 21) {
28208 //= bndry-Cells
28209 // status == 22 or 29
28210 // activate further neighbors which have small cells with wasInactive
28211 MInt largestNeighbor = checkNeighborActivity(cellId);
28212 if(largestNeighbor > 0) {
28213 MInt largestNeighborGapCellId = m_gapCellId[largestNeighbor];
28214 m_gapCells[largestNeighborGapCellId].status = 28;
28215 if(a_isHalo(largestNeighbor)) {
28216 m_gapCells[largestNeighborGapCellId].status = -99;
28217 }
28218 }
28219 }
28220 }
28221 }
28222
28223 gapCellExchange(1);
28224
28225
28226 // 5) match Cell-types at initGapOpening and estimate total-mass-loss
28227 /*
28228
28229 for(MInt region = 0; region < m_noGapRegions; region++) {
28230 if(m_gapState[region] != 2) continue;
28231 for(MUint it = 0; it < m_gapCells.size(); it++){
28232 MInt regionId = m_gapCells[it].region;
28233 if(regionId != region) continue;
28234 MInt cellId = m_gapCells[it].cellId;
28235 MInt status = m_gapCells[it].status;
28236
28237 if(a_isHalo(cellId)) continue;
28238
28239 //find the status of the cell at initGapClosure
28240 MUint it1 = m_gapCellsBackup.size();
28241 for( MUint it2 = 0; it2 < m_gapCellsBackup.size(); it2++){
28242 if(m_gapCellsBackup[it2].cellId == cellId ) {
28243 it1 = it2;
28244 break;
28245 }
28246 }
28247
28248 if(it1 == m_gapCellsBackup.size()) {
28249 //cerr << "WasGapCell at initGapOpening not found in gapCellBackup " << c_globalId(cellId)
28250 // << " " << status << endl;
28251 continue;
28252 }
28253 MInt oldstatus = m_gapCellsBackup[it1].status;
28254
28255
28256 if(status == 21 && oldstatus != 4) {
28257 cerr << "Arising-Gap-Cell doesn't match gap-shadowed Cell " << c_globalId(cellId) << " "
28258 << oldstatus << endl;
28259
28260 } else if (status == 26 && oldstatus != 9) {
28261 cerr << "Body-shadowed Gap-Cells not matching " << c_globalId(cellId) << " "
28262 << oldstatus << endl;
28263 } else if (status == 23 && oldstatus != 7) {
28264 cerr << "Gap-Bndry-Cells not matching " << c_globalId(cellId) << " " << oldstatus << endl;
28265 } else if(status == 22 && oldstatus != 5) {
28266 cerr << "Body-Bndry-Cells not matching " << c_globalId(cellId) << " " << oldstatus << endl;
28267 }
28268
28269 }
28270 }
28271 */
28272 }
28273
28274
28275 // now add splitChilds and set the correct Gap-state, region and status
28276 // for initGapopening, also update the changes from the splitCell to the splitChilds!
28277 MInt noGapSplitChild = 0;
28278 for(MUint sc = 0; sc < m_splitCells.size(); sc++) {
28279 const MInt cellId = m_splitCells[sc];
28280 if(m_gapCellId[cellId] < 0) continue;
28281 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
28282 const MInt splitChildId = m_splitChilds[sc][ssc];
28283 a_isGapCell(splitChildId) = a_isGapCell(cellId);
28284 a_wasGapCell(splitChildId) = a_wasGapCell(cellId);
28285 if(a_isGapCell(splitChildId) || a_wasGapCell(splitChildId)) {
28286 noGapSplitChild++;
28287 const MInt region = m_gapCells[m_gapCellId[cellId]].region;
28288 const MInt status = m_gapCells[m_gapCellId[cellId]].status;
28289 const MInt body1 = m_gapCells[m_gapCellId[cellId]].bodyIds[0];
28290 const MInt body2 = m_gapCells[m_gapCellId[cellId]].bodyIds[1];
28291 const MInt gapId = m_gapCells.size();
28292 m_gapCells.emplace_back(splitChildId, region, status, body1, body2);
28293 m_gapCellId[splitChildId] = gapId;
28294 a_hasProperty(splitChildId, SolverCell::WasInactive) = a_hasProperty(cellId, SolverCell::WasInactive);
28295
28296 if(region > m_noGapRegions) continue;
28297 // for initGapOpening: update splitchilds variables based on splitcell-values:
28298 if(m_gapState[region] == 2) {
28299 for(MInt var = 0; var < m_noCVars; var++) {
28300 a_variable(splitChildId, var) = a_variable(cellId, var);
28301 a_oldVariable(splitChildId, var) = a_variable(cellId, var);
28302 }
28303 for(MInt var = 0; var < m_noPVars; var++) {
28304 a_pvariable(splitChildId, var) = a_pvariable(cellId, var);
28305 }
28306 for(MInt var = 0; var < m_noFVars; var++) {
28307 a_rightHandSide(splitChildId, var) = a_rightHandSide(cellId, var);
28308 m_rhs0[splitChildId][var] = m_rhs0[cellId][var];
28309 }
28310 } else if(m_gapState[region] == -2) {
28311 // for initGapClosure: remove splitchilds Surfaces
28312 a_hasProperty(splitChildId, SolverCell::IsInactive) = a_hasProperty(cellId, SolverCell::IsInactive);
28313 for(MInt v = 0; v < m_noFVars; v++) {
28314 a_rightHandSide(splitChildId, v) = a_rightHandSide(cellId, v);
28315 m_rhs0[splitChildId][v] = m_rhs0[cellId][v];
28316 }
28317 if(!a_hasProperty(splitChildId, SolverCell::WasInactive)
28318 && a_hasProperty(splitChildId, SolverCell::IsInactive)) {
28319 removeSurfaces(cellId);
28320 }
28321 }
28322 }
28323 }
28324 }
28325 MPI_Allreduce(MPI_IN_PLACE, &noGapSplitChild, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "noGapSplitChild");
28326
28327#if defined _MB_DEBUG_ || !defined NDEBUG
28328 if(domainId() == 0 && anyGapOpening) cerr << " Finished gap-Handling" << endl;
28329#endif
28330
28331 if(noGapSplitChild > 0) {
28333 gapCellExchange(1);
28334
28335#if defined _MB_DEBUG_ || !defined NDEBUG
28336 if(domainId() == 0) {
28337 cerr << "Number of Gap-Split-Childs " << noGapSplitChild << endl;
28338 }
28339#endif
28340 }
28341}
void initGapCellExchange()
creates the gap-cell exchange communicators based on initializeMaxLevelExchange
MInt checkNeighborActivity(MInt)
ckecks that a new bndry-Cell has at least one neighbor which was active before if this is not the cas...
void loop(Functor &&fun, Class *object, const IdType begin, const IdType end, Args... args)

◆ generateBndryCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::generateBndryCells
virtual

Definition at line 20941 of file fvmbcartesiansolverxd.cpp.

20941 {
20942 TRACE();
20943
20944 m_log << "Generating FV boundary cells..." << endl;
20945
20947 // reset isActive/isInactive and isOnCurrentMGLevel for outerBndryCells:
20948 // if the lsValue is in the range of (-limitDistance , 0] and the cell has at least
20949 // one active corner
20950 if(!m_constructGField) {
20951 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
20952 const MFloat limitDistance = c_cellLengthAtLevel(a_level(cellId) + 1) * sqrt(nDim) + 0.0001;
20953 if(a_levelSetValuesMb(cellId, 0) < F0 && a_levelSetValuesMb(cellId, 0) > -limitDistance) {
20954 // check that it is a cell at the outer-domainBoundary
20955 // which means that neither the cell nor its parent has a neighbor in a certain direction!
20956 // and the cell is not a halo cell!
20957 MBool needsCheck = false;
20958 for(MInt dir = 0; dir < m_noDirs; dir++) {
20959 if(a_hasNeighbor(cellId, dir, false)) continue;
20960 if(c_parentId(cellId) > -1 && a_hasNeighbor(c_parentId(cellId), dir, false)) continue;
20961 needsCheck = true;
20962 break;
20963 }
20964 if(!needsCheck) continue;
20965 MInt noActiveCorners = returnNoActiveCorners(cellId);
20966 if(noActiveCorners > 0) {
20967 a_hasProperty(cellId, SolverCell::IsInactive) = false;
20968 if(c_noChildren(cellId) == 0 && c_isLeafCell(cellId)) {
20969 a_hasProperty(cellId, SolverCell::IsActive) = true;
20970 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = true;
20971 }
20972 }
20973 }
20974 }
20975
20976 // exchange the properties to ensure the correct values at all haloCells!
20977 MIntScratchSpace exchangeD(a_noCells(), 3, AT_, "cellCheck");
20978 exchangeD.fill(-1);
20979 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
20980 exchangeD(cellId, 0) = (MInt)a_hasProperty(cellId, SolverCell::IsInactive);
20981 exchangeD(cellId, 1) = (MInt)a_hasProperty(cellId, SolverCell::IsActive);
20982 exchangeD(cellId, 2) = (MInt)a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel);
20983 }
20984
20985 exchangeDataFV(&exchangeD(0), 3, false);
20986
20987 for(MInt cellId = noInternalCells(); cellId < c_noCells(); cellId++) {
20988 a_hasProperty(cellId, SolverCell::IsInactive) = (MBool)exchangeD(cellId, 0);
20989 a_hasProperty(cellId, SolverCell::IsActive) = (MBool)exchangeD(cellId, 1);
20990 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = (MBool)exchangeD(cellId, 2);
20991 }
20992
20993 if(grid().azimuthalPeriodicity()) {
20994 // Correct azimuthal near boundary cells. Azimuthal window/halos are no exact copy
20995 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
20996 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
20997 MInt cellId = grid().azimuthalHaloCell(i, j);
20998 const MFloat limitDistance = c_cellLengthAtLevel(a_level(cellId) + 1) * sqrt(nDim) + 0.0001;
20999 if(a_levelSetValuesMb(cellId, 0) < F0 && a_levelSetValuesMb(cellId, 0) > -limitDistance) {
21000 // check that it is a cell at the outer-domainBoundary
21001 // which means that neither the cell nor its parent has a neighbor in a certain direction!
21002 // and the cell is not a halo cell!
21003 MBool needsCheck = false;
21004 for(MInt dir = 0; dir < m_noDirs; dir++) {
21005 if(a_hasNeighbor(cellId, dir, false)) continue;
21006 if(c_parentId(cellId) > -1 && a_hasNeighbor(c_parentId(cellId), dir, false)) continue;
21007 needsCheck = true;
21008 break;
21009 }
21010 if(!needsCheck) continue;
21011 MInt noActiveCorners = returnNoActiveCorners(cellId);
21012 if(noActiveCorners > 0) {
21013 a_hasProperty(cellId, SolverCell::IsInactive) = false;
21014 if(c_noChildren(cellId) == 0 && c_isLeafCell(cellId)) {
21015 a_hasProperty(cellId, SolverCell::IsActive) = true;
21016 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = true;
21017 }
21018 }
21019 }
21020 }
21021 }
21022 // What about unmapped halos?
21023 // They are irrelevant in fvMb if level-set boundaries are used!
21024 }
21025 }
21026
21028
21029 m_fvBndryCnd->generateBndryCells();
21030
21031 ASSERT(a_noCells() == c_noCells(), "");
21032 }
21033
21034#if defined _MB_DEBUG_ || !defined NDEBUG
21035 MInt noOuterBoundaryCells = m_fvBndryCnd->m_bndryCells->size();
21036 m_log << noOuterBoundaryCells << " boundary cells created" << endl;
21037 MPI_Allreduce(MPI_IN_PLACE, &noOuterBoundaryCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
21038 "noOuterBoundaryCells");
21039 cerr0 << "No of outer-boundary-Cells: " << noOuterBoundaryCells << endl;
21040
21041#endif
21042}
void createBoundaryCells()
identifies bndry cells (Sets a_isInterface for the solver!)
MInt returnNoActiveCorners(MInt)
returns the numer of active Corners for an arbitrary cell (the cell is not a bndryCandidate yet and t...

◆ generateBndryCellsMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::generateBndryCellsMb ( const MInt  mode)
Author
Lennart Schneiders

◆ getAdjacentCells()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::getAdjacentCells ( MInt  cellId,
MInt adjacentCells 
)
Author
Lennart Schneiders

Definition at line 11280 of file fvmbcartesiansolverxd.cpp.

11280 {
11281 MInt cnt = 0;
11282 set<MInt> nghbrs;
11283
11284 for(MInt dir0 = 0; dir0 < m_noDirs; dir0++) {
11285 if(a_hasNeighbor(cellId, dir0) == 0) continue;
11286
11287 const MInt nghbrId0 = c_neighborId(cellId, dir0);
11288
11289 if(nghbrId0 < 0) continue;
11290
11291 if(a_hasProperty(nghbrId0, SolverCell::IsOnCurrentMGLevel) && !a_hasProperty(nghbrId0, SolverCell::IsInactive)
11292 && !a_isBndryGhostCell(nghbrId0)) {
11293 adjacentCells[cnt] = nghbrId0;
11294 cnt++;
11295 }
11296 for(MInt dir1 = 0; dir1 < m_noDirs; dir1++) {
11297 if((dir1 / 2) == (dir0 / 2)) continue;
11298 if(a_hasNeighbor(nghbrId0, dir1) == 0) continue;
11299 const MInt nghbrId1 = c_neighborId(nghbrId0, dir1);
11300 if(nghbrId1 < 0) continue;
11301 if(a_hasProperty(nghbrId1, SolverCell::IsOnCurrentMGLevel) && !a_hasProperty(nghbrId1, SolverCell::IsInactive)
11302 && !a_isBndryGhostCell(nghbrId1))
11303 nghbrs.insert(nghbrId1);
11304#ifdef __REMOVE_TO_USE__
11305 IF_CONSTEXPR(nDim == 3) {
11306 for(MInt dir2 = 0; dir2 < m_noDirs; dir2++) {
11307 if(((dir2 / 2) == (dir0 / 2)) || ((dir2 / 2) == (dir1 / 2))) continue;
11308 if(a_hasNeighbor(nghbrId1, dir2) == 0) continue;
11309 const MInt nghbrId2 = c_neighborId(nghbrId1, dir2);
11310 if(nghbrId2 < 0) continue;
11311 if(a_hasProperty(nghbrId2, SolverCell::IsOnCurrentMGLevel) && !a_hasProperty(nghbrId2, SolverCell::IsInactive)
11312 && !a_isBndryGhostCell(nghbrId2))
11313 nghbrs.insert(nghbrId2);
11314 }
11315 }
11316#endif
11317 }
11318 }
11319 set<MInt>::iterator it = nghbrs.begin();
11320 for(it = nghbrs.begin(); it != nghbrs.end(); it++) {
11321 adjacentCells[cnt] = *it;
11322 cnt++;
11323 }
11324 return cnt;
11325}

◆ getAdjacentCellsAllLevels()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::getAdjacentCellsAllLevels ( MInt  cellId,
MInt adjacentCells 
)
Author
Lennart Schneiders

Definition at line 11333 of file fvmbcartesiansolverxd.cpp.

11333 {
11334 set<MInt> nghbrs;
11335
11336 for(MInt dir0 = 0; dir0 < m_noDirs; dir0++) {
11337 MInt nghbrId0 = -1;
11338
11339 if(a_hasNeighbor(cellId, dir0) > 0)
11340 nghbrId0 = c_neighborId(cellId, dir0);
11341 else if(c_parentId(cellId) > -1)
11342 if(a_hasNeighbor(c_parentId(cellId), dir0) > 0) nghbrId0 = c_neighborId(c_parentId(cellId), dir0);
11343
11344 if(nghbrId0 < 0) continue;
11345
11346 const MInt noC0 = c_noChildren(nghbrId0);
11347
11348 for(MInt c0 = 0; c0 < mMax(1, noC0); c0++) {
11349 if(noC0 && !childCode[dir0][c0]) continue;
11350 MInt nghbrId00 = noC0 ? c_childId(nghbrId0, c0) : nghbrId0;
11351 if(nghbrId00 < 0) continue;
11352 if(a_hasProperty(nghbrId00, SolverCell::IsOnCurrentMGLevel) && !a_hasProperty(nghbrId00, SolverCell::IsInactive)
11353 && !a_isBndryGhostCell(nghbrId00)) {
11354 nghbrs.insert(nghbrId00);
11355 }
11356 for(MInt dir1 = 0; dir1 < m_noDirs; dir1++) {
11357 if((dir1 / 2) == (dir0 / 2)) continue;
11358 MInt nghbrId1 = -1;
11359 if(a_hasNeighbor(nghbrId00, dir1) > 0)
11360 nghbrId1 = c_neighborId(nghbrId00, dir1);
11361 else if(c_parentId(nghbrId00) > -1)
11362 if(a_hasNeighbor(c_parentId(nghbrId00), dir1) > 0) nghbrId1 = c_neighborId(c_parentId(nghbrId00), dir1);
11363 if(nghbrId1 < 0) continue;
11364 const MInt noC1 = c_noChildren(nghbrId1);
11365 for(MInt c1 = 0; c1 < mMax(1, noC1); c1++) {
11366 if(noC1 && !childCode[dir1][c1]) continue;
11367 MInt nghbrId11 = noC1 ? c_childId(nghbrId1, c1) : nghbrId1;
11368 if(nghbrId11 < 0) continue;
11369 MBool facing = true;
11370 for(MInt i = 0; i < nDim; i++) {
11371 if(fabs(a_coordinate(cellId, i) - a_coordinate(nghbrId00, i))
11372 > ((F1 + 1e-8) * c_cellLengthAtLevel(a_level(cellId))
11373 + (F1 + 1e-8) * c_cellLengthAtLevel(a_level(nghbrId00))))
11374 facing = false;
11375 }
11376 if(!facing) continue;
11377 if(a_hasProperty(nghbrId11, SolverCell::IsOnCurrentMGLevel)
11378 && !a_hasProperty(nghbrId11, SolverCell::IsInactive) && !a_isBndryGhostCell(nghbrId11)) {
11379 nghbrs.insert(nghbrId11);
11380 }
11381
11382#ifdef __REMOVE_TO_USE__
11383 IF_CONSTEXPR(nDim == 3) {
11384 mTerm(1, AT_, "TODO");
11385 for(MInt dir2 = 0; dir2 < m_noDirs; dir2++) {
11386 if(((dir2 / 2) == (dir0 / 2)) || ((dir2 / 2) == (dir1 / 2))) continue;
11387 if(a_hasNeighbor(nghbrId1, dir2) == 0) continue;
11388 const MInt nghbrId2 = c_neighborId(nghbrId1, dir2);
11389 if(nghbrId2 < 0) continue;
11390 if(a_hasProperty(nghbrId2, SolverCell::IsOnCurrentMGLevel)
11391 && !a_hasProperty(nghbrId2, SolverCell::IsInactive) && !a_isBndryGhostCell(nghbrId2))
11392 nghbrs.insert(nghbrId2);
11393 }
11394 }
11395#endif
11396 }
11397 }
11398 }
11399 }
11400
11401 MInt cnt = 0;
11402 for(set<MInt>::iterator it = nghbrs.begin(); it != nghbrs.end(); it++) {
11403 adjacentCells[cnt] = *it;
11404 cnt++;
11405 }
11406 return cnt;
11407}

◆ getAdjacentCellsExtended()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::getAdjacentCellsExtended ( MInt  cellId,
MInt adjacentCells 
)
Author
Lennart Schneiders

Definition at line 11415 of file fvmbcartesiansolverxd.cpp.

11415 {
11416 MInt cnt = getAdjacentCells(cellId, adjacentCells);
11417 set<MInt> nghbrs;
11418
11419 for(MInt dir0 = 0; dir0 < m_noDirs; dir0++) {
11420 if(a_hasNeighbor(cellId, dir0) == 0) continue;
11421 const MInt nghbrId00 = c_neighborId(cellId, dir0);
11422 if(a_hasNeighbor(nghbrId00, dir0) == 0) continue;
11423 const MInt nghbrId0 = c_neighborId(nghbrId00, dir0);
11424 if(nghbrId0 < 0) continue;
11425 if(a_hasProperty(nghbrId0, SolverCell::IsOnCurrentMGLevel) && !a_hasProperty(nghbrId0, SolverCell::IsInactive)
11426 && !a_isBndryGhostCell(nghbrId0)) {
11427 adjacentCells[cnt] = nghbrId0;
11428 cnt++;
11429 }
11430
11431 for(MInt dir1 = 0; dir1 < m_noDirs; dir1++) {
11432 if((dir1 / 2) == (dir0 / 2)) continue;
11433 if(a_hasNeighbor(nghbrId0, dir1) == 0) continue;
11434 const MInt nghbrId1 = c_neighborId(nghbrId0, dir1);
11435 if(nghbrId1 < 0) continue;
11436 if(a_hasProperty(nghbrId1, SolverCell::IsOnCurrentMGLevel) && !a_hasProperty(nghbrId1, SolverCell::IsInactive)
11437 && !a_isBndryGhostCell(nghbrId1))
11438 nghbrs.insert(nghbrId1);
11439#ifdef __REMOVE_TO_USE__
11440 IF_CONSTEXPR(nDim == 3) {
11441 for(MInt dir2 = 0; dir2 < m_noDirs; dir2++) {
11442 if(((dir2 / 2) == (dir0 / 2)) || ((dir2 / 2) == (dir1 / 2))) continue;
11443 if(a_hasNeighbor(nghbrId1, dir2) == 0) continue;
11444 const MInt nghbrId2 = c_neighborId(nghbrId1, dir2);
11445 if(nghbrId2 < 0) continue;
11446 if(a_hasProperty(nghbrId2, SolverCell::IsOnCurrentMGLevel) && !a_hasProperty(nghbrId2, SolverCell::IsInactive)
11447 && !a_isBndryGhostCell(nghbrId2))
11448 nghbrs.insert(nghbrId2);
11449 }
11450 }
11451#endif
11452 }
11453 }
11454 set<MInt>::iterator it = nghbrs.begin();
11455 for(it = nghbrs.begin(); it != nghbrs.end(); it++) {
11456 adjacentCells[cnt] = *it;
11457 cnt++;
11458 }
11459 return cnt;
11460}
MInt getAdjacentCells(MInt cellId, MInt *adjacentCells)
retrieves all direct and diagonal fluid cell neighbours of the given cell

◆ getAdjacentGridCells()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::getAdjacentGridCells ( MInt  cellId,
MInt adjacentCells 
)
Author
Lennart Schneiders

Definition at line 11138 of file fvmbcartesiansolverxd.cpp.

11138 {
11139 MInt cnt = 0;
11140 set<MInt> nghbrs;
11141
11142 for(MInt dir0 = 0; dir0 < m_noDirs; dir0++) {
11143 MInt nghbrId0 = -1;
11144
11145 if(a_hasNeighbor(cellId, dir0) > 0)
11146 nghbrId0 = c_neighborId(cellId, dir0);
11147 else if(c_parentId(cellId) > -1)
11148 if(a_hasNeighbor(c_parentId(cellId), dir0) > 0) nghbrId0 = c_neighborId(c_parentId(cellId), dir0);
11149
11150 if(nghbrId0 < 0) continue;
11151
11152 if(c_noChildren(nghbrId0) > 0) {
11153 for(MInt child = 0; child < m_noCellNodes; child++) {
11154 if(!childCode[dir0][child]) continue;
11155 if(c_childId(nghbrId0, child) > -1) nghbrs.insert(c_childId(nghbrId0, child));
11156 }
11157 } else
11158 nghbrs.insert(nghbrId0);
11159
11160 for(MInt dir1 = 0; dir1 < m_noDirs; dir1++) {
11161 if((dir1 / 2) == (dir0 / 2)) continue;
11162
11163 MInt nghbrId1 = -1;
11164
11165 if(a_hasNeighbor(nghbrId0, dir1) > 0)
11166 nghbrId1 = c_neighborId(nghbrId0, dir1);
11167 else if(c_parentId(nghbrId0) > -1)
11168 if(a_hasNeighbor(c_parentId(nghbrId0), dir1) > 0) nghbrId1 = c_neighborId(c_parentId(nghbrId0), dir1);
11169
11170 if(nghbrId1 < 0) continue;
11171
11172 if(c_noChildren(nghbrId1) > 0) {
11173 for(MInt child = 0; child < m_noCellNodes; child++) {
11174 if(!childCode[dir0][child] || !childCode[dir1][child]) continue;
11175 if(c_childId(nghbrId1, child) > -1) nghbrs.insert(c_childId(nghbrId1, child));
11176 }
11177 } else
11178 nghbrs.insert(nghbrId1);
11179 IF_CONSTEXPR(nDim == 3) {
11180 for(MInt dir2 = 0; dir2 < m_noDirs; dir2++) {
11181 if(((dir2 / 2) == (dir0 / 2)) || ((dir2 / 2) == (dir1 / 2))) continue;
11182 MInt nghbrId2 = -1;
11183 if(a_hasNeighbor(nghbrId1, dir2) > 0)
11184 nghbrId2 = c_neighborId(nghbrId1, dir2);
11185 else if(c_parentId(nghbrId1) > -1)
11186 if(a_hasNeighbor(c_parentId(nghbrId1), dir2) > 0) nghbrId2 = c_neighborId(c_parentId(nghbrId1), dir2);
11187 if(nghbrId2 < 0) continue;
11188 // nghbrs.insert( nghbrId2 );
11189 if(c_noChildren(nghbrId2) > 0) {
11190 for(MInt child = 0; child < m_noCellNodes; child++) {
11191 if(!childCode[dir0][child] || !childCode[dir1][child] || !childCode[dir2][child]) continue;
11192 if(c_childId(nghbrId2, child) > -1) nghbrs.insert(c_childId(nghbrId2, child));
11193 }
11194 } else
11195 nghbrs.insert(nghbrId2);
11196 }
11197 }
11198 }
11199 }
11200 set<MInt>::iterator it = nghbrs.begin();
11201 for(it = nghbrs.begin(); it != nghbrs.end(); it++) {
11202 ASSERT(cnt < 27 * m_noCellNodes, "");
11203 adjacentCells[cnt] = *it;
11204 cnt++;
11205 }
11206 return cnt;
11207}

◆ getBodyRotation()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::getBodyRotation ( const MInt  bodyId,
MFloat bodyRotation 
)
Author
Lennart Schneiders

Definition at line 4448 of file fvmbcartesiansolverxd.cpp.

4448 {
4449 TRACE();
4450
4451 if(!m_constructGField) return;
4452
4453 const MFloat qw = m_bodyQuaternion[4 * bodyId + 0];
4454 const MFloat qx = m_bodyQuaternion[4 * bodyId + 1];
4455 const MFloat qy = m_bodyQuaternion[4 * bodyId + 2];
4456 const MFloat qz = m_bodyQuaternion[4 * bodyId + 3];
4457 bodyRotation[0] = atan2(F2 * qw * qx + 2 * qy * qz, F1 - F2 * qw * qw - F2 * qz * qz);
4458 bodyRotation[1] = asin(F2 * qx * qz - F2 * qw * qy);
4459 bodyRotation[2] = atan2(F2 * qx * qy + F2 * qw * qz, F1 - F2 * qy * qy - F2 * qz * qz);
4460}

◆ getBodyRotationDt1()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::getBodyRotationDt1 ( const MInt  bodyId,
MFloat bodyRotation 
)
Author
Lennart Schneiders

Definition at line 4468 of file fvmbcartesiansolverxd.cpp.

4468 {
4469 TRACE();
4470
4471 if(!m_constructGField) return;
4472
4473 const MFloat qw = m_bodyQuaternionDt1[4 * bodyId + 0];
4474 const MFloat qx = m_bodyQuaternionDt1[4 * bodyId + 1];
4475 const MFloat qy = m_bodyQuaternionDt1[4 * bodyId + 2];
4476 const MFloat qz = m_bodyQuaternionDt1[4 * bodyId + 3];
4477 bodyRotation[0] = atan2(F2 * qw * qx + 2 * qy * qz, F1 - F2 * qw * qw - F2 * qz * qz);
4478 bodyRotation[1] = asin(F2 * qx * qz - F2 * qw * qy);
4479 bodyRotation[2] = atan2(F2 * qx * qy + F2 * qw * qz, F1 - F2 * qy * qy - F2 * qz * qz);
4480}

◆ getBoundaryDistance()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::getBoundaryDistance ( MFloatScratchSpace distance)
overridevirtual
Author

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 15736 of file fvmbcartesiansolverxd.cpp.

15736 {
15738 distance.fill(std::numeric_limits<MFloat>::max());
15739
15740 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
15741 ASSERT(!a_isBndryGhostCell(cellId), "");
15742 ASSERT(!a_isHalo(cellId), "");
15743 ASSERT(!c_isToDelete(cellId), "");
15744 distance(cellId) = a_levelSetValuesMb(cellId, 0);
15745 }
15746 } else {
15747 // in this case, distance does not describe the distance to the interface!
15748 // instead it is rather used simular to the inList in the lssolver.
15749
15750 MInt listCount = 0;
15751 distance.fill(0.0);
15752
15753 // mark Interface cells based on the levelset-value!
15754 const MInt linerSet = 1;
15755 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
15756 // for (MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
15757 // only refine around G0-set to avoid unnecessary fv-Cells!
15758 const MInt set = 0;
15759 if((MInt)distance(cellId) == 1) continue;
15760 MBool addParents = false;
15761 if(approx(a_levelSetValuesMb(cellId, set), F0, MFloatEps)) {
15762 if(c_isLeafCell(cellId)) {
15763 const MInt bodySet = m_bodyToSetTable[a_associatedBodyIds(cellId, set)];
15764 MInt maxLvl = m_lsCutCellLevel[bodySet];
15765 if(bodySet == linerSet && m_linerLvlJump && a_coordinate(cellId, 0) > -0.51
15766 && a_coordinate(cellId, 0) < 0.51) {
15767 maxLvl = m_lsCutCellLevel[bodySet] + 1;
15768 }
15769 if(a_level(cellId) < maxLvl) {
15770 distance(cellId) = 1.0;
15771 listCount++;
15772 }
15773 } else {
15774 distance(cellId) = 1.0;
15775 listCount++;
15776 }
15777 addParents = true;
15778 } else {
15779 for(MInt dir = 0; dir < m_noDirs; dir++) {
15780 if(a_hasNeighbor(cellId, dir, false) > 0) {
15781 const MInt nghbrId = c_neighborId(cellId, dir, false);
15782 if((a_levelSetValuesMb(nghbrId, set) * a_levelSetValuesMb(cellId, set) < F0)) {
15783 if(c_isLeafCell(cellId)) {
15784 const MInt bodySet = m_bodyToSetTable[a_associatedBodyIds(cellId, set)];
15785 MInt maxLvl = m_lsCutCellLevel[bodySet];
15786 if(bodySet == linerSet && m_linerLvlJump && a_coordinate(cellId, 0) > -0.51
15787 && a_coordinate(cellId, 0) < 0.51) {
15788 maxLvl = m_lsCutCellLevel[bodySet] + 1;
15789 }
15790 if(a_level(cellId) < maxLvl) {
15791 distance(cellId) = 1.0;
15792 listCount++;
15793 }
15794 } else {
15795 distance(cellId) = 1.0;
15796 listCount++;
15797 }
15798 addParents = true;
15799 dir = m_noDirs;
15800 }
15801 }
15802 }
15803 }
15804 if(addParents) {
15805 MInt parentId = c_parentId(cellId);
15806 while(parentId > -1 && parentId < a_noCells()) {
15807 distance(parentId) = 1.0;
15808 parentId = c_parentId(parentId);
15809 }
15810 }
15811 }
15812
15813#if defined _MB_DEBUG_ || !defined NDEBUG
15814 MPI_Allreduce(MPI_IN_PLACE, &listCount, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "listCount");
15815
15816 if(listCount == 0) mTerm(1, AT_, "No Cells found for fv-mb-refinement!");
15817#endif
15818 }
15819
15820 exchangeDataFV(distance.data());
15821}
MBool c_isToDelete(const MInt cellId) const
Returns the delete of the cell cellId.

◆ getCellDataDlb() [1/2]

template<MInt nDim_, class SysEqn_ >
void FvMbCartesianSolverXD< nDim_, SysEqn_ >::getCellDataDlb ( const MInt  dataId,
const MInt  oldNoCells,
const MInt *const  bufferIdToCellId,
MFloat *const  data 
)
override

Store the solver data for a given data id ordered in the given buffer for DLB.

Definition at line 1882 of file fvmbcartesiansolverxd.h.

1883 {
1884 TRACE();
1885
1886 MInt localBufferId = 0;
1887 for(MInt i = 0; i < oldNoCells; i++) {
1888 const MInt gridCellId = bufferIdToCellId[i];
1889
1890 if(gridCellId < 0) continue;
1891
1892 const MInt cellId = grid().tree().grid2solver(gridCellId);
1893 if(cellId < 0 || cellId >= noInternalCells()) {
1894 continue;
1895 }
1896
1897 switch(dataId) {
1899 std::copy_n(&a_variable(cellId, 0), m_noCVars, &data[localBufferId * m_noCVars]);
1900 break;
1901 }
1903 std::copy_n(&a_cellVolume(cellId), 1, &data[localBufferId]);
1904 break;
1905 }
1907 std::copy_n(&a_rightHandSide(cellId, 0), m_noFVars, &data[localBufferId * m_noFVars]);
1908 break;
1909 }
1911 std::copy_n(&m_cellVolumesDt1[cellId], 1, &data[localBufferId]);
1912 break;
1913 }
1915 MInt bndryId_ = a_bndryId(cellId);
1916 if(bndryId_ > -1) {
1917 data[localBufferId] = m_sweptVolume[bndryId_];
1918 } else {
1919 data[localBufferId] = -1;
1920 }
1921 break;
1922 }
1924 if(grid().azimuthalPeriodicity()) {
1926 std::copy_n(&m_azimuthalNearBoundaryBackupBalFloat[cellId * noFloatData], noFloatData,
1927 &data[localBufferId * noFloatData]);
1928 }
1929 break;
1930 }
1931 default:
1932 TERMM(1, "Unknown data id.");
1933 break;
1934 }
1935 localBufferId++;
1936 }
1937}

◆ getCellDataDlb() [2/2]

template<MInt nDim_, class SysEqn_ >
void FvMbCartesianSolverXD< nDim_, SysEqn_ >::getCellDataDlb ( const MInt  dataId,
const MInt  oldNoCells,
const MInt *const  bufferIdToCellId,
MLong *const  data 
)

Definition at line 1942 of file fvmbcartesiansolverxd.h.

1943 {
1944 TRACE();
1945
1946 MInt localBufferId = 0;
1947 for(MInt i = 0; i < oldNoCells; i++) {
1948 const MInt gridCellId = bufferIdToCellId[i];
1949
1950 if(gridCellId < 0) continue;
1951
1952 const MInt cellId = grid().tree().grid2solver(gridCellId);
1953 if(cellId < 0 || cellId >= noInternalCells()) {
1954 continue;
1955 }
1956
1957 switch(dataId) {
1959 data[localBufferId] = (MLong)a_properties(cellId).to_ulong();
1960 break;
1961 }
1963 if(grid().azimuthalPeriodicity()) {
1965 std::copy_n(&m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData], noLongData,
1966 &data[localBufferId * noLongData]);
1967 }
1968 break;
1969 }
1970 default:
1971 TERMM(1, "Unknown data id.");
1972 break;
1973 }
1974 localBufferId++;
1975 }
1976}

◆ getConservativeVarName()

template<MInt nDim, class SysEqn >
string FvMbCartesianSolverXD< nDim, SysEqn >::getConservativeVarName ( MInt  i)
Author
Lennart Schneiders

Definition at line 12686 of file fvmbcartesiansolverxd.cpp.

12686 {
12687 switch(i) {
12688 case 0:
12689 return "RHO_U";
12690 case 1:
12691 return "RHO_V";
12692 case 2:
12693 IF_CONSTEXPR(nDim == 2)
12694 return "RHO_E";
12695 else
12696 return "RHO_W";
12697 case 3:
12698 IF_CONSTEXPR(nDim == 2)
12699 return "RHO";
12700 else
12701 return "RHO_E";
12702 case 4:
12703 IF_CONSTEXPR(nDim == 2)
12704 return "<< INVALID INDEX FOR CONSERVATIVE VAR >>";
12705 else
12706 return "RHO";
12707 default:
12708 return "<< INVALID INDEX FOR CONSERVATIVE VAR >>";
12709 }
12710}

◆ getDistance() [1/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistance ( const MFloat * const  coordinates,
const MInt  bodyId 
)
Author

Definition at line 2716 of file fvmbcartesiansolverxd.cpp.

2716 {
2718
2719 if(m_bodyTypeMb == 1) {
2720 dist = getDistanceSphere(coordinates, bodyId);
2721 } else if(m_bodyTypeMb == 2) {
2722 dist = getDistancePiston(coordinates, bodyId);
2723 } else if(m_bodyTypeMb == 3) {
2724 dist = getDistanceEllipsoid(coordinates, bodyId);
2725 } else if(m_bodyTypeMb == 7) {
2726 dist = getDistanceTetrahedron(coordinates, bodyId);
2727 } else {
2728 mTerm(1, AT_, "generalize here");
2729 }
2730
2731 return dist;
2732}
MFloat getDistanceEllipsoid(const MFloat *const, const MInt)
MFloat getDistancePiston(const MFloat *const, const MInt)
MFloat getDistanceTetrahedron(const MFloat *const, const MInt)
MFloat getDistanceSphere(const MFloat *const, const MInt)

◆ getDistance() [2/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistance ( const MInt  cellId,
const MInt  bodyId 
)
Author

Definition at line 2740 of file fvmbcartesiansolverxd.cpp.

2740 {
2741 return getDistance(&a_coordinate(cellId, 0), bodyId);
2742}

◆ getDistanceEllipsoid() [1/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistanceEllipsoid ( const MFloat * const  coordinates,
const MInt  bodyId 
)
Author

Definition at line 3555 of file fvmbcartesiansolverxd.cpp.

3555 {
3556 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
3557
3558 MFloatScratchSpace R(3, 3, AT_, "R");
3559 MFloat xw[3];
3560 MFloat xb[3];
3561
3562 computeRotationMatrix(R, &(m_bodyQuaternion[4 * bodyId]));
3563
3564 MFloat x = coordinates[0] - m_bodyCenter[bodyId * nDim + 0];
3565 MFloat y = coordinates[1] - m_bodyCenter[bodyId * nDim + 1];
3566 MFloat z = coordinates[2] - m_bodyCenter[bodyId * nDim + 2];
3567
3568 xw[0] = x;
3569 xw[1] = y;
3570 xw[2] = z;
3571 matrixVectorProduct(xb, R, xw);
3572 x = xb[0];
3573 y = xb[1];
3574 z = xb[2];
3575
3576 const MFloat a = m_bodyRadii[bodyId * nDim + 0];
3577 const MFloat b = m_bodyRadii[bodyId * nDim + 1];
3578 const MFloat c = m_bodyRadii[bodyId * nDim + 2];
3579
3580 MFloat ee[3] = {a, b, c};
3581 MFloat yy[3] = {x, y, z};
3582 MFloat xx[3] = {F0, F0, F0};
3583 MFloat dist = distancePointEllipsoid(ee, yy, xx);
3584 if((POW2(x / a) + POW2(y / b) + POW2(z / c)) < F1) dist = -dist;
3585
3586 return dist;
3587}

◆ getDistanceEllipsoid() [2/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistanceEllipsoid ( const MInt  cellId,
const MInt  bodyId 
)
Author

Definition at line 3595 of file fvmbcartesiansolverxd.cpp.

3595 {
3596 return getDistanceEllipsoid(&a_coordinate(cellId, 0), bodyId);
3597}

◆ getDistanceNaca00XX()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistanceNaca00XX ( const MInt  cellId,
const MInt  bodyId 
)
Author
Lennart Schneiders

Definition at line 3538 of file fvmbcartesiansolverxd.cpp.

3538 {
3539 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
3540 if(bodyId != 0) mTerm(1, AT_, "Extend Naca00XX.");
3541
3542 const MFloat phi0 = getLevelSetValueNaca00XX(&a_coordinate(cellId, 0), -F1);
3543 const MFloat phi1 = getLevelSetValueNaca00XX(&a_coordinate(cellId, 0), F1);
3544 const MFloat phi = (fabs(phi0) < fabs(phi1)) ? phi0 : phi1;
3545
3546 return phi;
3547}
MFloat getLevelSetValueNaca00XX(const MFloat *const, const MFloat sign)

◆ getDistancePiston() [1/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistancePiston ( const MFloat * const  coordinates,
const MInt  bodyId 
)
Author
Lennart Schneiders

Definition at line 3514 of file fvmbcartesiansolverxd.cpp.

3514 {
3515 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
3516
3517 MFloat dist = fabs(coordinates[0] - m_bodyCenter[bodyId * nDim]) - m_bodyRadius[bodyId];
3518
3519 return dist;
3520}

◆ getDistancePiston() [2/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistancePiston ( const MInt  cellId,
const MInt  bodyId 
)
Author

Definition at line 3528 of file fvmbcartesiansolverxd.cpp.

3528 {
3529 return getDistancePiston(&a_coordinate(cellId, 0), bodyId);
3530}

◆ getDistanceSphere() [1/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistanceSphere ( const MFloat * const  coordinates,
const MInt  bodyId 
)
Author

Definition at line 2750 of file fvmbcartesiansolverxd.cpp.

2750 {
2751 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
2752 MFloat dist = F0;
2753 IF_CONSTEXPR(nDim == 2) {
2754 dist = sqrt(POW2(coordinates[0] - m_bodyCenter[bodyId * nDim])
2755 + POW2(coordinates[1] - m_bodyCenter[bodyId * nDim + 1]))
2756 - (m_bodyRadius[bodyId]);
2757 }
2758 else IF_CONSTEXPR(nDim == 3) {
2759 dist =
2760 sqrt(POW2(coordinates[0] - m_bodyCenter[bodyId * nDim]) + POW2(coordinates[1] - m_bodyCenter[bodyId * nDim + 1])
2761 + POW2(coordinates[2] - m_bodyCenter[bodyId * nDim + 2]))
2762 - (m_bodyRadius[bodyId]);
2763 }
2764 return dist;
2765}

◆ getDistanceSphere() [2/2]

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistanceSphere ( const MInt  cellId,
const MInt  bodyId 
)
Author

Definition at line 2773 of file fvmbcartesiansolverxd.cpp.

2773 {
2774 return getDistanceSphere(&a_coordinate(cellId, 0), bodyId);
2775}

◆ getDistanceSplitSphere()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistanceSplitSphere ( const  MInt,
const  MInt 
)
Author
Lennart Schneiders extended to multiple bodies (Lennart Schneiders)

◆ getDistanceTetrahedron()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getDistanceTetrahedron ( const MFloat * const  coordinates,
const MInt  bodyId 
)
Author

Definition at line 4058 of file fvmbcartesiansolverxd.cpp.

4058 {
4059 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
4060
4061 constexpr MFloat eps = 5e-3;
4062 const MFloat fac0 = F1 / sqrt(F3);
4063 const MFloat fac1 = F1B6 * pow(PI / F2, F1B3);
4064 const MFloat fac = fac1 * m_bodyDiameter[bodyId];
4065 constexpr MFloat dirs[4][3] = {{F1, F1, -F1}, {F1, -F1, F1}, {-F1, F1, F1}, {-F1, -F1, -F1}};
4066
4067 MFloat innerDist = std::numeric_limits<MFloat>::lowest();
4068 MFloat outerDist = F0;
4069
4070 MFloatScratchSpace R(3, 3, AT_, "R");
4071 MFloat xw[3];
4072 MFloat xb[3];
4073 computeRotationMatrix(R, &(m_bodyQuaternion[4 * bodyId]));
4074 MFloat x = coordinates[0] - m_bodyCenter[bodyId * nDim + 0];
4075 MFloat y = coordinates[1] - m_bodyCenter[bodyId * nDim + 1];
4076 MFloat z = F0;
4077 IF_CONSTEXPR(nDim == 3) { z = coordinates[2] - m_bodyCenter[bodyId * nDim + 2]; }
4078 xw[0] = x;
4079 xw[1] = y;
4080 IF_CONSTEXPR(nDim == 3) { xw[2] = z; }
4081 matrixVectorProduct(xb, R, xw);
4082 x = xb[0];
4083 y = xb[1];
4084 IF_CONSTEXPR(nDim == 3) { z = xb[2]; }
4085
4086 MFloat dists[4];
4087
4088 for(MInt face = 0; face < 4; face++) {
4089 MFloat dist = F0;
4090 IF_CONSTEXPR(nDim == 2) {
4091 dist = dirs[face][0] * fac0 * (x - fac * dirs[face][0]) + dirs[face][1] * fac0 * (y - fac * dirs[face][1]);
4092 }
4093 else IF_CONSTEXPR(nDim == 3) {
4094 dist = dirs[face][0] * fac0 * (x - fac * dirs[face][0]) + dirs[face][1] * fac0 * (y - fac * dirs[face][1])
4095 + dirs[face][2] * fac0 * (z - fac * dirs[face][2]);
4096 }
4097 innerDist = mMax(innerDist, dist);
4098 outerDist += POW2(mMax(F0, dist));
4099
4100 dists[face] = dist;
4101 }
4102 std::sort(dists, dists + 4, [](const MFloat& a, const MFloat& b) { return fabs(a) < fabs(b); });
4103
4104 if(innerDist < F0) {
4105 if(fabs(dists[1]) < eps * m_bodyDiameter[bodyId]) {
4106 innerDist = F0;
4107 for(MInt face = 0; face < 4; face++) {
4108 if(fabs(dists[face]) < eps * m_bodyDiameter[bodyId]) {
4109 innerDist = -sqrt(POW2(innerDist) + POW2(dists[face]));
4110 }
4111 }
4112 }
4113 } else {
4114 if(fabs(dists[1]) < eps * m_bodyDiameter[bodyId]) {
4115 outerDist = F0;
4116 for(MInt face = 0; face < 4; face++) {
4117 if(fabs(dists[face]) < eps * m_bodyDiameter[bodyId]) {
4118 outerDist += POW2(dists[face]);
4119 }
4120 }
4121 }
4122 }
4123
4124 return (innerDist < F0) ? innerDist : sqrt(outerDist);
4125}

◆ getEqualLevelNeighbors()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::getEqualLevelNeighbors ( MInt  cellId,
MInt(&)  nghbrs[27] 
)
Author
Lennart Schneiders

Definition at line 11215 of file fvmbcartesiansolverxd.cpp.

11215 {
11216 constexpr MInt offs[3] = {1, 3, 9};
11217 auto nbIdx0 = [&]() { return 13; };
11218 auto nbIdx1 = [&](MInt dir0, MInt sign0) { return nbIdx0() + offs[dir0] * sign0; };
11219 auto nbIdx2 = [&](MInt dir0, MInt sign0, MInt dir1, MInt sign1) {
11220 return nbIdx0() + offs[dir0] * sign0 + offs[dir1] * sign1;
11221 };
11222 std::fill_n(nghbrs, 27, -1);
11223 nghbrs[nbIdx0()] = cellId;
11224
11225 for(MInt dir0 = 0; dir0 < m_noDirs; dir0++) {
11226 MInt nghbrId0 = -1;
11227
11228 if(a_hasNeighbor(cellId, dir0) > 0) {
11229 nghbrId0 = c_neighborId(cellId, dir0);
11230 }
11231
11232 if(nghbrId0 < 0) continue;
11233
11234 MInt sign0 = (dir0 % 2 == 0) ? -1 : 1;
11235 ASSERT(nghbrs[nbIdx1(dir0 / 2, sign0)] == -1 || nghbrs[nbIdx1(dir0 / 2, sign0)] == nghbrId0, "");
11236 nghbrs[nbIdx1(dir0 / 2, sign0)] = nghbrId0;
11237
11238 for(MInt dir1 = 0; dir1 < m_noDirs; dir1++) {
11239 if((dir1 / 2) == (dir0 / 2)) continue;
11240 MInt nghbrId1 = -1;
11241 if(a_hasNeighbor(nghbrId0, dir1) > 0) {
11242 nghbrId1 = c_neighborId(nghbrId0, dir1);
11243 }
11244 if(nghbrId1 < 0) continue;
11245 MInt sign1 = (dir1 % 2 == 0) ? -1 : 1;
11246 ASSERT(nghbrs[nbIdx2(dir0 / 2, sign0, dir1 / 2, sign1)] == -1
11247 || nghbrs[nbIdx2(dir0 / 2, sign0, dir1 / 2, sign1)] == nghbrId1,
11248 "");
11249 nghbrs[nbIdx2(dir0 / 2, sign0, dir1 / 2, sign1)] = nghbrId1;
11250 IF_CONSTEXPR(nDim == 3) {
11251 auto nbIdx3 = [&](MInt ldir0, MInt lsign0, MInt ldir1, MInt lsign1, MInt ldir2, MInt lsign2) {
11252 return nbIdx0() + offs[ldir0] * lsign0 + offs[ldir1] * lsign1 + offs[ldir2] * lsign2;
11253 };
11254 for(MInt dir2 = 0; dir2 < m_noDirs; dir2++) {
11255 if(((dir2 / 2) == (dir0 / 2)) || ((dir2 / 2) == (dir1 / 2))) continue;
11256 MInt nghbrId2 = -1;
11257 if(a_hasNeighbor(nghbrId1, dir2) > 0) {
11258 nghbrId2 = c_neighborId(nghbrId1, dir2);
11259 }
11260 if(nghbrId2 < 0) continue;
11261 MInt sign2 = (dir2 % 2 == 0) ? -1 : 1;
11262 ASSERT(nghbrs[nbIdx3(dir0 / 2, sign0, dir1 / 2, sign1, dir2 / 2, sign2)] == -1
11263 || nghbrs[nbIdx3(dir0 / 2, sign0, dir1 / 2, sign1, dir2 / 2, sign2)] == nghbrId2,
11264 "");
11265 nghbrs[nbIdx3(dir0 / 2, sign0, dir1 / 2, sign1, dir2 / 2, sign2)] = nghbrId2;
11266 }
11267 }
11268 }
11269 }
11270
11271 return (std::count_if(nghbrs, nghbrs + 27, [](const MInt& a) { return (a > -1); }));
11272}

◆ getFacingNghbrs()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::getFacingNghbrs ( const MInt  cellId,
const MBool  includeAllChilds 
)
inline
Author
Lennart Schneiders
Date
06.11.2012

Definition at line 16686 of file fvmbcartesiansolverxd.cpp.

16686 {
16687 MInt counter = 0;
16688
16689 for(MInt dir = 0; dir < m_noDirs; dir++) {
16690 if(a_hasNeighbor(cellId, dir) > 0) {
16691 MInt nghbrId = c_neighborId(cellId, dir);
16692 if(c_noChildren(nghbrId) > 0) {
16693 for(MInt child = 0; child < m_noCellNodes; child++) {
16694 if(!includeAllChilds && !childCode[dir][child]) continue;
16695 MInt childId = c_childId(nghbrId, child);
16696 if(childId < 0) continue;
16697 if(a_isBndryGhostCell(childId)) continue;
16698 if(!childCode[dir][child] && c_noChildren(childId) > 0) continue;
16699
16700 if(!((c_noChildren(childId) == 0) || (a_isHalo(cellId)))) {
16701 cerr << cellId << " " << nghbrId << " " << childId << " " << c_childId(childId, 0) << " " << dir << " "
16702 << child << " / " << a_isHalo(cellId) << " " << a_isWindow(cellId) << " " << a_isHalo(childId) << " "
16703 << a_isWindow(childId) << " " << a_isHalo(nghbrId) << " " << a_isWindow(nghbrId) << " // "
16704 << c_noChildren(cellId) << " " << c_noChildren(childId) << " " << a_level(cellId) << " /// "
16705 << (c_childId(childId, 0) > -1 ? c_noChildren(c_childId(childId, 0)) : -1) << " "
16706 << (c_childId(childId, 1) > -1 ? c_noChildren(c_childId(childId, 1)) : -1) << " "
16707 << (c_childId(childId, 2) > -1 ? c_noChildren(c_childId(childId, 2)) : -1) << " "
16708 << (c_childId(childId, 3) > -1 ? c_noChildren(c_childId(childId, 3)) : -1) << " "
16709 << (c_childId(childId, 4) > -1 ? c_noChildren(c_childId(childId, 4)) : -1) << " "
16710 << (c_childId(childId, 5) > -1 ? c_noChildren(c_childId(childId, 5)) : -1) << " "
16711 << (c_childId(childId, 6) > -1 ? c_noChildren(c_childId(childId, 6)) : -1) << " "
16712 << (c_childId(childId, 7) > -1 ? c_noChildren(c_childId(childId, 7)) : -1) << endl;
16713 }
16714 ASSERT((c_noChildren(childId) == 0) || (a_isHalo(cellId)),
16715 "(1) No children expected FvMbCartesianSolverXD::getFacingNghbrs(..) "
16716 << cellId << " " << nghbrId << " " << childId << " " << c_childId(childId, 0) << " " << dir << " "
16717 << child << " " << c_noChildren(childId));
16718 m_nghbrList[counter++] = childId;
16719 }
16720 } else {
16721 ASSERT(nghbrId > -1, "Invalid neighbor id in FvMbCartesianSolverXD::getFacingNghbrs(..)");
16722 if(a_isBndryGhostCell(nghbrId)) continue;
16723 m_nghbrList[counter++] = nghbrId;
16724 }
16725 } else {
16726 if(c_parentId(cellId) > -1) {
16727 if(a_hasNeighbor(c_parentId(cellId), dir) > 0) {
16728 MInt nghbrId = c_neighborId(c_parentId(cellId), dir);
16729 ASSERT(nghbrId > -1, "Invalid neighbor id in FvMbCartesianSolverXD::getFacingNghbrs(..)");
16730 if(a_isBndryGhostCell(nghbrId)) continue;
16731 if(c_noChildren(nghbrId) == 0) m_nghbrList[counter++] = nghbrId;
16732 }
16733 }
16734 }
16735 }
16736 return counter;
16737}

◆ getLevelSetValueNaca00XX()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::getLevelSetValueNaca00XX ( const MFloat * const  ,
const MFloat  sign 
)

◆ getNewSurfaceId()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::getNewSurfaceId
Author
Lennart Schneiders

Definition at line 17005 of file fvmbcartesiansolverxd.cpp.

17005 {
17006 MInt srfcId = -1;
17007
17008 if(m_freeSurfaceIndices.size() > 0) {
17009 set<MInt>::iterator it = m_freeSurfaceIndices.begin();
17010 srfcId = *(it);
17011 m_freeSurfaceIndices.erase(it);
17012 if(srfcId >= a_noSurfaces()) {
17013 srfcId = -1;
17014 m_freeSurfaceIndices.clear();
17015 }
17016 }
17017 if(srfcId < 0) {
17018 srfcId = a_noSurfaces();
17021 }
17022
17023 return srfcId;
17024}

◆ getNormal()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::getNormal ( const MInt  cellId,
const MInt  set,
MFloat  normal[] 
)
Author

Definition at line 2563 of file fvmbcartesiansolverxd.cpp.

2563 {
2564 const MFloat FcellLength = F1 / c_cellLengthAtCell(cellId);
2565 normal[0] = numeric_limits<MFloat>::max();
2566 normal[1] = numeric_limits<MFloat>::max();
2567 IF_CONSTEXPR(nDim == 3) { normal[2] = numeric_limits<MFloat>::max(); }
2568
2569 if(m_bodyTypeMb == 1) {
2570 getNormalSphere(cellId, set, normal);
2571 } else if(m_bodyTypeMb == 3) {
2572 getNormalEllipsoid(cellId, set, normal);
2573 } else {
2574 MInt cndId = (a_hasProperty(cellId, SolverCell::IsSplitChild))
2577 if(cndId < 0) mTerm(1, AT_, "candidate not found");
2578 for(MInt node = 0; node < m_noCellNodes; node++) {
2579 if(!m_candidateNodeSet[cndId * m_noCellNodes + node]) mTerm(1, AT_, "candidate node not set");
2580 }
2581 IF_CONSTEXPR(nDim == 3) {
2582 normal[0] = F1B4 * FcellLength
2583 * (-m_candidateNodeValues[IDX_LSSETNODES(cndId, 0, set)]
2584 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 1, set)]
2585 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 2, set)]
2586 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 3, set)]
2587 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 4, set)]
2588 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 5, set)]
2589 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 6, set)]
2590 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 7, set)]);
2591 normal[1] = F1B4 * FcellLength
2592 * (-m_candidateNodeValues[IDX_LSSETNODES(cndId, 0, set)]
2593 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 1, set)]
2594 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 2, set)]
2595 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 3, set)]
2596 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 4, set)]
2597 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 5, set)]
2598 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 6, set)]
2599 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 7, set)]);
2600 normal[2] = F1B4 * FcellLength
2601 * (-m_candidateNodeValues[IDX_LSSETNODES(cndId, 0, set)]
2602 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 1, set)]
2603 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 2, set)]
2604 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 3, set)]
2605 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 4, set)]
2606 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 5, set)]
2607 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 6, set)]
2608 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 7, set)]);
2609 }
2610 else {
2611 normal[0] = F1B4 * FcellLength
2612 * (-m_candidateNodeValues[IDX_LSSETNODES(cndId, 0, set)]
2613 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 1, set)]
2614 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 2, set)]
2615 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 3, set)]);
2616 normal[1] = F1B4 * FcellLength
2617 * (-m_candidateNodeValues[IDX_LSSETNODES(cndId, 0, set)]
2618 - m_candidateNodeValues[IDX_LSSETNODES(cndId, 1, set)]
2619 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 2, set)]
2620 + m_candidateNodeValues[IDX_LSSETNODES(cndId, 3, set)]);
2621 }
2622 MFloat sum = F0;
2623 for(MInt i = 0; i < nDim; i++) {
2624 sum += POW2(normal[i]);
2625 }
2626 sum = sqrt(sum);
2627 for(MInt i = 0; i < nDim; i++) {
2628 normal[i] /= sum;
2629 }
2630 }
2631}
void getNormalSphere(const MInt, const MInt, MFloat[])
void getNormalEllipsoid(const MInt, const MInt, MFloat[])

◆ getNormalEllipsoid()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::getNormalEllipsoid ( const MInt  cellId,
const MInt  set,
MFloat  normal[] 
)
Author

Definition at line 2663 of file fvmbcartesiansolverxd.cpp.

2663 {
2664 const MInt bodyId = a_associatedBodyIds(cellId, set);
2665 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
2666
2667 MFloatScratchSpace R(3, 3, AT_, "R");
2668 computeRotationMatrix(R, &(m_bodyQuaternion[4 * bodyId]));
2669
2670 // shift centroid to body center
2671 MFloat x = a_coordinate(cellId, 0) - m_bodyCenter[bodyId * nDim + 0];
2672 MFloat y = a_coordinate(cellId, 1) - m_bodyCenter[bodyId * nDim + 1];
2673 MFloat z = a_coordinate(cellId, 2) - m_bodyCenter[bodyId * nDim + 2];
2674
2675 MFloat xw[3];
2676 MFloat xb[3];
2677 xw[0] = x;
2678 xw[1] = y;
2679 xw[2] = z;
2680 matrixVectorProduct(xb, R, xw); // rotate to body principal axes
2681 x = xb[0];
2682 y = xb[1];
2683 z = xb[2];
2684
2685 MFloat a = m_bodyRadii[bodyId * nDim + 0];
2686 MFloat b = m_bodyRadii[bodyId * nDim + 1];
2687 MFloat c = m_bodyRadii[bodyId * nDim + 2];
2688
2689 MFloat ee[3] = {a, b, c};
2690 MFloat yy[3] = {x, y, z};
2691 MFloat xx[3] = {F0, F0, F0};
2692
2693 // query nearest surface point
2694 distancePointEllipsoid(ee, yy, xx);
2695
2696 MFloat norm2[3];
2697 MFloat n2sum = F0;
2698 for(MInt i = 0; i < nDim; i++) {
2699 norm2[i] = F2 * xx[i] / POW2(m_bodyRadii[bodyId * nDim + i]);
2700 n2sum += POW2(norm2[i]);
2701 }
2702 n2sum = sqrt(n2sum);
2703 for(MInt i = 0; i < nDim; i++) {
2704 norm2[i] /= n2sum;
2705 }
2706
2707 matrixVectorProductTranspose(normal, R, norm2); // rotate back
2708}

◆ getNormalSphere()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::getNormalSphere ( const MInt  cellId,
const MInt  set,
MFloat  normal[] 
)
Author

Definition at line 2639 of file fvmbcartesiansolverxd.cpp.

2639 {
2640 const MInt bodyId = a_associatedBodyIds(cellId, set);
2641 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
2642
2643 for(MInt i = 0; i < nDim; i++) {
2644 normal[i] = F0;
2645 }
2646 MFloat cnt = F0;
2647 for(MInt i = 0; i < nDim; i++) {
2648 normal[i] = a_coordinate(cellId, i) - m_bodyCenter[nDim * bodyId + i];
2649 cnt += POW2(normal[i]);
2650 }
2651 cnt = sqrt(cnt);
2652 for(MInt i = 0; i < nDim; i++) {
2653 normal[i] /= cnt;
2654 }
2655}

◆ getNumberOfCells()

template<MInt nDim, class SysEqn >
MLong FvMbCartesianSolverXD< nDim, SysEqn >::getNumberOfCells ( MInt  mode)
Author

Definition at line 19136 of file fvmbcartesiansolverxd.cpp.

19136 {
19137 MLong noCells = 0;
19138 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
19139 if(!a_isHalo(cellId) && c_isLeafCell(cellId)) noCells++;
19140 }
19141
19142 if(mode > -1) {
19143 switch(mode) {
19144 case 0:
19145 MPI_Allreduce(MPI_IN_PLACE, &noCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "noCells");
19146 break;
19147 case 1:
19148 MPI_Allreduce(MPI_IN_PLACE, &noCells, 1, MPI_LONG, MPI_MIN, mpiComm(), AT_, "MPI_IN_PLACE", "noCells");
19149 break;
19150 case 2:
19151 MPI_Allreduce(MPI_IN_PLACE, &noCells, 1, MPI_LONG, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "noCells");
19152 break;
19153 case 3:
19154 MPI_Allreduce(MPI_IN_PLACE, &noCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "noCells");
19155 noCells = (MLong)(((MFloat)noCells) / ((MFloat)noDomains()));
19156 break;
19157 default:
19158 mTerm(1, AT_, "Unknown case.");
19159 }
19160 }
19161
19162 return noCells;
19163}

◆ getPrimitiveVarName()

template<MInt nDim, class SysEqn >
string FvMbCartesianSolverXD< nDim, SysEqn >::getPrimitiveVarName ( MInt  i)
Author
Lennart Schneiders

Definition at line 12718 of file fvmbcartesiansolverxd.cpp.

12718 {
12719 switch(i) {
12720 case 0:
12721 return "U";
12722 case 1:
12723 return "V";
12724 case 2:
12725 IF_CONSTEXPR(nDim == 2)
12726 return "RHO";
12727 else
12728 return "W";
12729 case 3:
12730 IF_CONSTEXPR(nDim == 2)
12731 return "P";
12732 else
12733 return "RHO";
12734 case 4:
12735 IF_CONSTEXPR(nDim == 2)
12736 return "<< INVALID INDEX FOR CONSERVATIVE VAR >>";
12737 else
12738 return "P";
12739 default:
12740 return "<< INVALID INDEX FOR CONSERVATIVE VAR >>";
12741 }
12742}

◆ gridPointIsInside()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::gridPointIsInside ( MInt  exId,
MInt  node 
)
inlineoverridevirtual

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 21168 of file fvmbcartesiansolverxd.cpp.

21168 {
21169 ASSERT(exId > -1 && exId < m_extractedCells->size() && node > -1 && node < IPOW2(nDim), "");
21170
21171 MInt cellId = m_extractedCells->a[exId].m_cellId;
21172 MInt bndryId = a_bndryId(cellId);
21173 if(bndryId < 0) return false;
21174
21175 if(bndryId < m_noOuterBndryCells) {
21177 } else {
21178 return m_pointIsInside[bndryId][IDX_LSSETMB(node, 0)];
21179 }
21180}
Collector< PointBasedCell< nDim > > * m_extractedCells
virtual MBool gridPointIsInside(MInt, MInt)

◆ hasSplitBalancing()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::hasSplitBalancing ( ) const
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 1009 of file fvmbcartesiansolverxd.h.

1009{ return true; }

◆ initAnalyticalLevelSet()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initAnalyticalLevelSet
Author
Thomas Hoesgen

Definition at line 30380 of file fvmbcartesiansolverxd.cpp.

30380 {
30381 TRACE();
30382
30383 ASSERT(m_constructGField, "Wrong function to call for m_constructGField = false!");
30384
30385 m_complexBoundary = Context::getSolverProperty<MBool>("complexBoundaryForMb", m_solverId, AT_, &m_complexBoundary);
30386
30387 m_buildCollectedLevelSetFunction = Context::getSolverProperty<MBool>("buildCollectedLevelSetFunction", m_solverId,
30389
30390 // necessary Dat from the fvmb-solver:
30391
30392 MInt noPeriodicDirs = 0;
30393 for(MInt dir = 0; dir < nDim; dir++) {
30394 if(grid().periodicCartesianDir(dir)) noPeriodicDirs++;
30395 }
30396
30397 if(m_complexBoundary) {
30398 mAlloc(m_bodyToSetTable, m_noEmbeddedBodies, "m_bodyToSetTable", 0, AT_);
30399 mAlloc(m_noBodiesInSet, m_noLevelSetsUsedForMb, "m_noBodiesInSet", 0, AT_);
30400 mAlloc(m_setToBodiesTable, m_noLevelSetsUsedForMb, m_noEmbeddedBodies, "m_setToBodiesTable", 0, AT_);
30401
30403 m_noSets = 1;
30404 m_startSet = 0;
30405 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
30406 m_bodyToSetTable[i] = 0;
30408 m_noBodiesInSet[0]++;
30409 }
30411 m_startSet = 1;
30414 mTerm(1, AT_, "Too many bodies for mode 1, m_noSets would be higher than m_noLevelSetsUsedForMb!");
30415 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
30416 MInt id = m_startSet + i % (m_noLevelSetsUsedForMb - 1);
30417 m_bodyToSetTable[i] = id;
30420 }
30421 m_noBodiesInSet[0] = 0;
30422 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
30424 m_noBodiesInSet[0]++;
30425 }
30426 }
30427
30428 if((m_maxNoEmbeddedBodiesPeriodic > m_noEmbeddedBodies) /*|| ( m_noBodiesInSet == nullptr )*/) {
30429 if(!m_buildCollectedLevelSetFunction) mTerm(1, AT_, "This case is unknown.");
30433 mAlloc(m_bodyToSetTable, m_maxNoEmbeddedBodiesPeriodic, "m_bodyToSetTable", 0, AT_);
30434 mAlloc(m_noBodiesInSet, m_noLevelSetsUsedForMb, "m_noBodiesInSet", 0, AT_);
30436
30437 for(MInt i = 0; i < m_noLevelSetsUsedForMb; i++) {
30438 for(MInt j = 0; j < m_maxNoEmbeddedBodiesPeriodic; j++)
30439 m_setToBodiesTable[i][j] = 0;
30440 m_noBodiesInSet[i] = 0;
30441 }
30442 m_noBodiesInSet[0] = 0;
30443 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
30445 m_bodyToSetTable[i] = 0;
30446 m_noBodiesInSet[0]++;
30447 }
30448 m_startSet = 1;
30451 mTerm(1, AT_, "Too many bodies for mode 0, m_noSets would be higher than m_noLevelSetsUsedForMb!");
30452 for(MInt i = 0; i < m_noLevelSetsUsedForMb; i++) {
30453 for(MInt j = 0; j < m_maxNoEmbeddedBodiesPeriodic; j++)
30454 m_setToBodiesTable[i][j] = 0;
30455 m_noBodiesInSet[i] = 0;
30456 }
30457 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
30458 MInt id = m_startSet + i % (m_noLevelSetsUsedForMb - 1);
30459 m_bodyToSetTable[i] = id;
30462 }
30463 m_noBodiesInSet[0] = 0;
30464 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
30466 m_noBodiesInSet[0]++;
30467 }
30468 }
30469 } else {
30470 if(m_bodyToSetTable == nullptr) mAlloc(m_bodyToSetTable, m_maxNoEmbeddedBodiesPeriodic, "m_bodyToSetTable", 0, AT_);
30471 if(m_noBodiesInSet == nullptr) mAlloc(m_noBodiesInSet, m_noLevelSetsUsedForMb, "m_noBodiesInSet", 0, AT_);
30472 if(m_setToBodiesTable == nullptr)
30474 m_noSets = 1;
30475 m_startSet = 0;
30476 for(MInt i = 0; i < m_noLevelSetsUsedForMb; i++) {
30477 for(MInt j = 0; j < m_maxNoEmbeddedBodiesPeriodic; j++)
30478 m_setToBodiesTable[i][j] = 0;
30479 m_noBodiesInSet[i] = 0;
30480 }
30481 m_noBodiesInSet[0] = 0;
30482 for(MInt i = 0; i < m_noEmbeddedBodies; i++) {
30484 m_bodyToSetTable[i] = 0;
30485 m_noBodiesInSet[0]++;
30486 }
30487 }
30488
30489 if(m_noSets > 0 && domainId() == 0) {
30490 m_log << " m_noSets: " << m_noSets << endl;
30491 m_log << " start set: " << m_startSet << endl;
30492 m_log << " m_bodyToSetTable: ";
30493 for(MInt i = 0; i < mMin(m_noEmbeddedBodies, 10); i++)
30494 m_log << " " << m_bodyToSetTable[i];
30495 m_log << endl;
30496 m_log << " m_noBodiesInSet: ";
30497 for(MInt i = 0; i < m_noLevelSetsUsedForMb; i++)
30498 m_log << " " << m_noBodiesInSet[i];
30499 m_log << endl;
30500 m_log << " m_setToBodiesTable: ";
30501 for(MInt i = 0; i < m_noLevelSetsUsedForMb; i++) {
30502 m_log << " s" << i << ": ";
30503 for(MInt j = 0; j < m_noBodiesInSet[i]; j++)
30504 m_log << " " << m_setToBodiesTable[i][j];
30505 }
30506 m_log << endl;
30507 }
30508}

◆ initAzimuthalLinkedHaloExc()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initAzimuthalLinkedHaloExc
Author
Thomas Hoesgen

Definition at line 36805 of file fvmbcartesiansolverxd.cpp.

36805 {
36806 TRACE();
36807
36808 set<MInt> needsExc;
36809 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36810 for(MUint j = 0; j < m_azimuthalMaxLevelWindowCells[i].size(); j++) {
36811 MInt offset = m_azimuthalMaxLevelWindowMap[i][j];
36812 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36813 for(MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36815 if(a_isHalo(recId)) {
36816 needsExc.insert(recId);
36817 }
36818 }
36819 }
36820 }
36821
36824
36825 for(MInt i = 0; i < noNeighborDomains(); i++) {
36826 m_azimuthalLinkedHaloCells[i].clear();
36828 }
36829
36830 MUint sndSize = maia::mpi::getBufferSize(grid().haloCells());
36831 MIntScratchSpace haloBuff(sndSize, AT_, "haloBuff");
36832 haloBuff.fill(0);
36833 MUint rcvSize = maia::mpi::getBufferSize(grid().windowCells());
36834 MIntScratchSpace windowBuff(rcvSize, AT_, "windowBuff");
36835 windowBuff.fill(0);
36836
36837 MInt sndCnt = 0;
36838 for(MInt i = 0; i < noNeighborDomains(); i++) {
36839 for(MInt j = 0; j < m_noMaxLevelHaloCells[i]; j++) {
36840 const MInt haloCell = m_maxLevelHaloCells[i][j];
36841 if(needsExc.find(haloCell) != needsExc.end()) {
36842 haloBuff[sndCnt] = 1;
36844 } else {
36845 haloBuff[sndCnt] = 0;
36846 }
36847 sndCnt++;
36848 }
36849 }
36850
36851 ScratchSpace<MPI_Request> sndReq(noNeighborDomains(), AT_, "sndReq");
36852 ScratchSpace<MPI_Request> rcvReq(noNeighborDomains(), AT_, "rcvReq");
36853 MInt rcvOffset = 0;
36854 MInt sndOffset = 0;
36855 for(MInt i = 0; i < noNeighborDomains(); i++) {
36856 MPI_Irecv(&windowBuff[rcvOffset], m_noMaxLevelWindowCells[i], MPI_INT, neighborDomain(i), 2, mpiComm(), &rcvReq[i],
36857 AT_, "windowBuff[rcvOffset]");
36858 rcvOffset += m_noMaxLevelWindowCells[i];
36859 }
36860 for(MInt i = 0; i < noNeighborDomains(); i++) {
36861 MPI_Isend(&haloBuff[sndOffset], m_noMaxLevelHaloCells[i], MPI_INT, neighborDomain(i), 2, mpiComm(), &sndReq[i], AT_,
36862 "haloBuff[i]");
36863 sndOffset += m_noMaxLevelHaloCells[i];
36864 }
36865 MPI_Waitall(noNeighborDomains(), &rcvReq[0], MPI_STATUSES_IGNORE, AT_);
36866 MPI_Waitall(noNeighborDomains(), &sndReq[0], MPI_STATUSES_IGNORE, AT_);
36867
36868 MInt rcvCnt = 0;
36869 for(MInt i = 0; i < noNeighborDomains(); i++) {
36870 for(MInt j = 0; j < m_noMaxLevelWindowCells[i]; j++) {
36872 if(windowBuff[rcvCnt] > 0) {
36874 }
36875 rcvCnt++;
36876 }
36877 }
36878}
const MInt & windowCell(const MInt domainId, const MInt cellId) const
const MInt & haloCell(const MInt domainId, const MInt cellId) const

◆ initBndryLayer()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initBndryLayer
Author
Tim Wegmann

Definition at line 1555 of file fvmbcartesiansolverxd.cpp.

1555 {
1556 TRACE();
1557
1558 std::vector<MInt>().swap(m_bndryLayerCells);
1559 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
1560 a_hasProperty(cellId, SolverCell::NearWall) = false;
1561
1562 if(a_bndryId(cellId) < -1) continue;
1563
1564 a_hasProperty(cellId, SolverCell::IsInactive) = false;
1565 a_hasProperty(cellId, SolverCell::WasInactive) = false;
1566
1567 if(c_noChildren(cellId) > 0) {
1568 a_hasProperty(cellId, SolverCell::IsInactive) = true;
1569 a_hasProperty(cellId, SolverCell::WasInactive) = true;
1570 continue;
1571 }
1572
1573 if(a_levelSetValuesMb(cellId, 0) > m_maxBndryLayerDistances[a_level(cellId)][0]
1574 && a_levelSetValuesMb(cellId, 0) < m_maxBndryLayerDistances[a_level(cellId)][1] && c_isLeafCell(cellId)) {
1575 m_bndryLayerCells.push_back(cellId);
1576 a_hasProperty(cellId, SolverCell::NearWall) = true;
1577 }
1578
1579 if(a_levelSetValuesMb(cellId, 0) < F0 || !c_isLeafCell(cellId)) {
1580 a_hasProperty(cellId, SolverCell::IsInactive) = true;
1581 a_hasProperty(cellId, SolverCell::WasInactive) = true;
1582 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = false;
1583 }
1584 }
1585}

◆ initBodyProperties()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initBodyProperties ( )
Author
Lennart Schneiders
Note
extended to multiple bodies (Lennart Schneiders)

◆ initBodyVelocities()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initBodyVelocities ( )

◆ initEmergingGapCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initEmergingGapCells
Author
Claudia Guenther

Definition at line 20433 of file fvmbcartesiansolverxd.cpp.

20433 {
20434 TRACE();
20435
20436 ASSERT(m_gapOpened, "");
20437
20438 MIntScratchSpace gapCells(m_fvBndryCnd->m_maxNoBndryCells, AT_, "gapCells");
20439 MIntScratchSpace DCells(m_fvBndryCnd->m_maxNoBndryCells, AT_, "DCells");
20440 MIntScratchSpace NCells(m_fvBndryCnd->m_maxNoBndryCells, AT_, "NCells");
20441 MIntScratchSpace NNghbrs(m_fvBndryCnd->m_maxNoBndryCells, AT_, "NNghbrs");
20442 MIntScratchSpace NNghbrs2(m_fvBndryCnd->m_maxNoBndryCells * nDim, AT_, "NNghbrs2");
20443 MFloatScratchSpace NFactors(m_fvBndryCnd->m_maxNoBndryCells * nDim, AT_, "NFactors");
20444 MBoolScratchSpace isGapCell(a_noCells(), AT_, "isGapCell");
20445 MBoolScratchSpace isDCell(a_noCells(), AT_, "isDCell");
20446 MBoolScratchSpace isNCell(a_noCells(), AT_, "isNCell");
20447 MInt noGapCells = 0;
20448 MInt noDCells = 0;
20449 MInt noNCells = 0;
20450 MFloat maxNormal = F0;
20451 MInt normalDir = 0;
20452 MInt noSteps = 100;
20453 MBool NeumannVariante = true;
20454 MFloatScratchSpace tmpVars(m_fvBndryCnd->m_maxNoBndryCells * 2, AT_, "tmpVars");
20455
20457
20458 if(domainId() == 0) {
20459 cerr << "Initializing emerging gap cells at time step " << globalTimeStep << endl;
20460 }
20461
20462
20463 // neighbor links are used for FD iteration
20465
20466 // a) initialisation
20467 for(MInt c = 0; c < a_noCells(); c++) {
20468 isGapCell.p[c] = false;
20469 isDCell.p[c] = false;
20470 isNCell.p[c] = false;
20471 }
20472
20473 // b) Identify gap cells
20474 // in this sense all cells with wasGapCell, !IsGapCell, WasInactive, !IsInactive
20475 // and Ls-value above eps
20476 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
20477 if(a_isBndryGhostCell(cellId)) continue;
20478 if(!a_hasProperty(cellId, SolverCell::WasGapCell)) continue;
20479 if(a_levelSetValuesMb(cellId, 0) < -eps) continue;
20480 if(!a_hasProperty(cellId, SolverCell::IsGapCell) && !a_hasProperty(cellId, SolverCell::IsInactive)
20481 && a_hasProperty(cellId, SolverCell::WasInactive)) {
20482 gapCells.p[noGapCells++] = cellId;
20483 isGapCell.p[cellId] = true;
20484 cerr << "initEmergingGapCell: Gap-CellId" << cellId << " " << c_globalId(cellId) << endl;
20485 }
20486 }
20487
20488 // 2.) Identify neighbor cells, of the Gap-Cells and which hold a boundary conditions
20489 for(MInt c = 0; c < noGapCells; c++) {
20490 MInt cellId = gapCells.p[c];
20491 if(a_isHalo(cellId)) continue;
20492 for(MInt dir = 0; dir < m_noDirs; dir++) {
20493 if(!a_hasNeighbor(cellId, dir)) {
20494 cerr << " [" << domainId() << "]: Error in FvMbCartesianSolverXD::initEmergingGapCells(): no nghbr in dir "
20495 << dir << " found for cell " << cellId << ". Please check! " << endl;
20496 continue;
20497 }
20498 MInt nghbrId = c_neighborId(cellId, dir);
20499 if(isGapCell.p[nghbrId]) continue;
20500 if(isDCell.p[nghbrId]) continue;
20501 if(isNCell.p[nghbrId]) continue;
20502 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
20503 if(a_bndryId(nghbrId) > -1) {
20504 if(!a_hasProperty(nghbrId, SolverCell::WasInactive)) {
20505 // a) cell is a bndryCell and has a valid value from previous time step
20506 // -> dirichlet cell!
20507 isDCell.p[nghbrId] = true;
20508 DCells.p[noDCells++] = nghbrId;
20509 cerr << "initEmergingGapCell: D-CellId" << nghbrId << " " << c_globalId(nghbrId) << endl;
20510
20511
20512 continue;
20513 } else if(a_levelSetValuesMb(nghbrId, 0) < F0) {
20514 // b) cell is a bndryCell and has no valid value from previous time step
20515 // -> neumann cell!
20516 isNCell.p[nghbrId] = true;
20517 NCells.p[noNCells++] = nghbrId;
20518 cerr << "initEmergingGapCell: N-CellId" << nghbrId << " " << c_globalId(nghbrId) << endl;
20519
20520 continue;
20521 } else {
20522 cerr << " [" << domainId() << "]: Warning in FvMbCartesianSolverXD::initEmergingGapCells(): nghbr in dir "
20523 << dir << " with id " << nghbrId << " of cell " << cellId
20524 << " is no Gap cell, no D and no N cell (was inactive, is bndryCell, has levelset >= 0 but is no gap "
20525 "cell)! Please check! "
20526 << endl;
20527 mTerm(1, AT_, "Error 1");
20528 }
20529 } else {
20530 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) {
20531 // c) cell is not a bndryCell but is inactive -> neumann cell!
20532 isNCell.p[nghbrId] = true;
20533 NCells.p[noNCells++] = nghbrId;
20534 cerr << "initEmergingGapCell: N-CellId" << nghbrId << " " << c_globalId(nghbrId) << endl;
20535 continue;
20536 } else {
20537 if(!a_hasProperty(nghbrId, SolverCell::WasInactive)) {
20538 // d) cell is not a bndryCell and is/was active before -> dirichlet cell!
20539 isDCell.p[nghbrId] = true;
20540 DCells.p[noDCells++] = nghbrId;
20541 cerr << "initEmergingGapCell: D-CellId" << nghbrId << " " << c_globalId(nghbrId) << endl;
20542 continue;
20543 } else {
20544 cerr << " [" << domainId() << "]: Warning in FvMbCartesianSolverXD::initEmergingGapCells(): nghbr in dir "
20545 << dir << " with id " << nghbrId << " of cell " << cellId
20546 << " is no Gap cell, no D and no N cell (is active, was inactive, but is no gap cell and no bndry "
20547 "cell! Please check! "
20548 << endl;
20549 mTerm(1, AT_, "Error 2");
20550 }
20551 }
20552 }
20553 }
20554 }
20555
20556
20557 // 3) set up Gap-exchange:
20558 // exchangeWindowCells holds all windowCells that are either a Gap-Cell,
20559 // a Dirichlet Cell or a Neumann-Cell
20560 MIntScratchSpace noExchangeWindowCells(noNeighborDomains(), AT_, "noExchangeWindowCells");
20561 MIntScratchSpace noExchangeHaloCells(noNeighborDomains(), AT_, "noExchangeHaloCells");
20562 MIntScratchSpace exchangeWindowCells(noNeighborDomains(), noGapCells + noDCells + noNCells, AT_,
20563 "exchangeWindowCells");
20564
20565 // a) set noExchangeWindowCells and exchangeWindowCells
20566 for(MInt i = 0; i < noNeighborDomains(); i++) {
20567 noExchangeWindowCells[i] = 0;
20568 for(MInt j = 0; j < noWindowCells(i); j++) {
20569 MInt cellId = windowCellId(i, j);
20570 if(isDCell[cellId] || isNCell[cellId] || isGapCell[cellId]) {
20571 exchangeWindowCells(i, noExchangeWindowCells[i]++) = j;
20572 }
20573 }
20574 }
20575 // b) exchange noExchangeWindowCells to determine maxNoExchangeHaloCells
20576 MPI_Status status;
20577 for(MInt i = 0; i < noNeighborDomains(); i++) {
20578 MPI_Issend(&noExchangeWindowCells.p[i], 1, MPI_INT, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
20579 "noExchangeWindowCells.p[i]");
20580 }
20581 for(MInt i = 0; i < noNeighborDomains(); i++) {
20582 MPI_Recv(&noExchangeHaloCells.p[i], 1, MPI_INT, neighborDomain(i), 0, mpiComm(), &status, AT_,
20583 "noExchangeHaloCells.p[i]");
20584 }
20585 for(MInt i = 0; i < noNeighborDomains(); i++) {
20586 MPI_Wait(&g_mpiRequestMb[i], &status, AT_);
20587 }
20588
20589 MInt maxNoExchangeHaloCells = 0;
20590 for(MInt i = 0; i < noNeighborDomains(); i++) {
20591 if(noExchangeHaloCells[i] > maxNoExchangeHaloCells) maxNoExchangeHaloCells = noExchangeHaloCells[i];
20592 }
20593 MIntScratchSpace exchangeHaloCells(noNeighborDomains(), maxNoExchangeHaloCells, AT_, "exchangeHaloCells");
20594
20595 // c) exchange exchangeWindowCells to determine exchangeHaloCells
20596 for(MInt i = 0; i < noNeighborDomains(); i++) {
20597 for(MInt j = 0; j < noExchangeWindowCells[i]; j++) {
20598 m_sendBuffers[i][j] = exchangeWindowCells(i, j);
20599 }
20600 }
20601 for(MInt i = 0; i < noNeighborDomains(); i++) {
20602 MPI_Issend(m_sendBuffers[i], noExchangeWindowCells[i], MPI_DOUBLE, neighborDomain(i), 0, mpiComm(),
20603 &g_mpiRequestMb[i], AT_, "m_sendBuffers[i]");
20604 }
20605 for(MInt i = 0; i < noNeighborDomains(); i++) {
20606 MPI_Recv(m_receiveBuffers[i], noExchangeHaloCells[i], MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &status, AT_,
20607 "m_receiveBuffers[i]");
20608 }
20609 for(MInt i = 0; i < noNeighborDomains(); i++) {
20610 MPI_Wait(&g_mpiRequestMb[i], &status, AT_);
20611 }
20612 for(MInt i = 0; i < noNeighborDomains(); i++) {
20613 for(MInt j = 0; j < noExchangeHaloCells[i]; j++) {
20614 exchangeHaloCells(i, j) = m_receiveBuffers[i][j];
20615 }
20616 }
20617
20618 // 4.) Setup Boundary conditions with 2 options
20619 // default is NeumannVariante = true;
20620 if(!NeumannVariante) {
20621 for(MInt nc = 0; nc < noNCells; nc++) {
20622 MInt cellId = NCells.p[nc];
20623 if(a_bndryId(cellId) > -1) {
20624 MInt bndryId = a_bndryId(cellId);
20625 maxNormal = F0;
20626 normalDir = -1;
20627 for(MInt d = 0; d < nDim; d++) {
20628 if(abs(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[d]) > maxNormal) {
20629 maxNormal = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[d];
20630 normalDir = 2 * d;
20631 if(maxNormal > F0) normalDir += 1;
20632 maxNormal = abs(maxNormal);
20633 }
20634 }
20635 if(!a_hasNeighbor(cellId, normalDir)) {
20636 cerr << " [" << domainId() << "]:"
20637 << " Error in FvMbCartesianSolverXD::initEmergingGapCells(): no nghbr in primary dir " << normalDir
20638 << " found for cell " << cellId << ". Please check! " << endl;
20639 mTerm(1, AT_, "Error 3");
20640 }
20641 NNghbrs.p[nc] = c_neighborId(cellId, normalDir);
20642 } else {
20643 normalDir = -1;
20644 maxNormal = F0;
20645 for(MInt dir = 0; dir < m_noDirs; dir++) {
20646 if(!a_hasNeighbor(cellId, dir)) {
20647 continue;
20648 }
20649 MInt nghbrId = c_neighborId(cellId, dir);
20650 MInt bndryId = a_bndryId(nghbrId);
20651 if(!isGapCell.p[nghbrId] && !isDCell.p[nghbrId]) continue;
20652 if(bndryId < 0) continue;
20653 for(MInt d = 0; d < nDim; d++) {
20654 if(abs(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[d]) > maxNormal) {
20655 maxNormal = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[d];
20656 normalDir = 2 * d;
20657 if(maxNormal > F0) normalDir += 1;
20658 maxNormal = abs(maxNormal);
20659 }
20660 }
20661 }
20662 NNghbrs.p[nc] = c_neighborId(cellId, normalDir);
20663 if(!a_hasNeighbor(cellId, normalDir)) {
20664 cerr << " [" << domainId() << "]:"
20665 << " Error in FvMbCartesianSolverXD::initEmergingGapCells(): no nghbr in primary dir " << normalDir
20666 << " found for cell " << cellId << ". Please check! " << endl;
20667 mTerm(1, AT_, "Error 4");
20668 }
20669 }
20670 }
20671 } else {
20672 // 4.1) NeumannVariante:
20673 // setUp NNghbrs2 and NFactors
20674 // NNghbrs2 are neighbors of N-Cells
20675 for(MInt nc = 0; nc < noNCells; nc++) {
20676 MInt cellId = NCells.p[nc];
20677 if(a_bndryId(cellId) > -1) {
20678 // a) Neumann-Cells which are boundary-Cells
20679 // (cells which used to be inactive and have a negative Ls-value)
20680 MInt bndryId = a_bndryId(cellId);
20681 for(MInt d = 0; d < nDim; d++) {
20682 normalDir = 2 * d;
20683 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[d] > F0) {
20684 normalDir += 1;
20685 }
20686 ASSERT(a_hasNeighbor(cellId, normalDir), "NCell has no neighbor in normalDir!");
20687 NNghbrs2.p[nc * nDim + d] = c_neighborId(cellId, normalDir);
20688 NFactors.p[nc * nDim + d] = POW2(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[d]);
20689 }
20690 } else {
20691 // b) Neumann-Cells which are non boundary-Cells and are inactive
20692 MFloat nablaAbs = F0;
20693 MFloat nablaPhi[nDim];
20694 for(MInt i = 0; i < nDim; i++) {
20695 nablaPhi[i] = (a_levelSetValuesMb(c_neighborId(cellId, 2 * i), 0)
20696 - a_levelSetValuesMb(c_neighborId(cellId, 2 * i + 1), 0))
20697 / (F2 * c_cellLengthAtLevel(a_level(cellId)));
20698 nablaAbs += POW2(nablaPhi[i]);
20699 }
20700 nablaAbs = sqrt(nablaAbs);
20701 for(MInt i = 0; i < nDim; i++) {
20702 nablaPhi[i] /= nablaAbs;
20703 }
20704 for(MInt d = 0; d < nDim; d++) {
20705 normalDir = 2 * d;
20706 if(nablaPhi[d] > F0) {
20707 normalDir += 1;
20708 }
20709 ASSERT(a_hasNeighbor(cellId, normalDir), "NCell has no neighbor in normalDir!");
20710 NNghbrs2.p[nc * nDim + d] = c_neighborId(cellId, normalDir);
20711 NFactors.p[nc * nDim + d] = POW2(nablaPhi[d]);
20712 }
20713 }
20714 }
20715 }
20716
20717 // 5) check all NNghbrs for NCells in all directions
20718 // these neighbors should be either a NCell, DCell or GapCell
20719 for(MInt nc = 0; nc < noNCells; nc++) {
20720 if(!NeumannVariante) {
20721 MInt cellId = NCells.p[nc];
20722 MInt nghbrId = NNghbrs.p[nc];
20723 if(isNCell.p[nghbrId] || (a_hasProperty(nghbrId, SolverCell::WasInactive) && !isGapCell.p[nghbrId])) {
20724 cerr << " [" << domainId() << "]:"
20725 << " Error in FvMbCartesianSolverXD::initEmergingGapCells(): nghbr " << nghbrId << " found for cell "
20726 << cellId << " is no gap cell and no dirichlet cell. Please check! " << endl;
20727 mTerm(1, AT_, "Error 7");
20728 }
20729 } else if(NeumannVariante) {
20730 MInt cellId = NCells.p[nc];
20731 for(MInt d = 0; d < nDim; d++) {
20732 MInt nghbrId = NNghbrs2.p[nc * nDim + d];
20733 if(!isNCell.p[nghbrId] && !isDCell.p[nghbrId] && !isGapCell.p[nghbrId] && a_levelSetValuesMb(nghbrId, 0) < F0) {
20734 cerr << domainId() << ": Warning NNghbrs2 " << nghbrId << " found for cell " << cellId
20735 << " is no gap cell and no dirichlet cell! " << endl;
20736 if(!a_hasProperty(nghbrId, SolverCell::WasInactive)) {
20737 cerr << " Nghbr was not inactive, so has a valid time history. Setting as Dirichlet cell... " << endl;
20738 isDCell.p[nghbrId] = true;
20739 DCells.p[noDCells++] = nghbrId;
20740 } else {
20741 cerr << " Nghbr was inactive, so problem can not be resolved.. try nevertheless..." << endl;
20742 }
20743 }
20744 }
20745 }
20746 }
20747
20748 // 6) Set velocity in Neumann cells as the bodyVelocity!
20749 for(MInt nc = 0; nc < noNCells; nc++) {
20750 const MInt cellId = NCells.p[nc];
20751 const MInt bodyId = a_associatedBodyIds(cellId, 0);
20752 ASSERT(bodyId >= 0, "associated body Id not matching!");
20753 for(MInt dir = 0; dir < nDim; dir++) {
20754 a_pvariable(cellId, PV->VV[dir]) = m_bodyVelocity[bodyId * nDim + dir];
20755 }
20756 }
20757
20758 MFloatScratchSpace resL2(m_noPVars, FUN_, "resL2");
20759 MFloatScratchSpace resMax(m_noPVars, FUN_, "resMax");
20760 MFloatScratchSpace tmp(m_noPVars, FUN_, "tmp");
20761 MFloat lambdaRelax = 1.2;
20762 MInt backupSteps = noSteps;
20763
20764 // 7) Gauss Seidel over-relaxated and neumann boundary conditions
20765 // loop- so that all Gap-Cells will be reached!
20766 for(MInt step = noSteps; step > 0; step--) {
20767 // a) exchange of pvariables in all Gap-, N-, or D-Cells
20768 for(MInt i = 0; i < noNeighborDomains(); i++) {
20769 MInt sendBufferCounter = 0;
20770 for(MInt j = 0; j < noExchangeWindowCells[i]; j++) {
20771 MInt cellId = windowCellId(i, exchangeWindowCells(i, j));
20772 memcpy((void*)&m_sendBuffers[i][sendBufferCounter], (void*)&a_pvariable(cellId, 0),
20773 m_dataBlockSize * sizeof(MFloat));
20774 sendBufferCounter += m_dataBlockSize;
20775 }
20776 }
20777
20778 for(MInt i = 0; i < noNeighborDomains(); i++) {
20779 MInt bufSize = noExchangeWindowCells[i] * m_dataBlockSize;
20780 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
20781 "m_sendBuffers[i]");
20782 }
20783
20784 for(MInt i = 0; i < noNeighborDomains(); i++) {
20785 MInt bufSize = noExchangeHaloCells[i] * m_dataBlockSize;
20786 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &status, AT_,
20787 "m_receiveBuffers[i]");
20788 }
20789 for(MInt i = 0; i < noNeighborDomains(); i++) {
20790 MPI_Wait(&g_mpiRequestMb[i], &status, AT_);
20791 }
20792
20793 for(MInt i = 0; i < noNeighborDomains(); i++) {
20794 MInt receiveBufferCounter = 0;
20795 for(MInt j = 0; j < noExchangeHaloCells[i]; j++) {
20796 MInt cellId = haloCellId(i, exchangeHaloCells(i, j));
20797 memcpy((void*)&a_pvariable(cellId, 0), (void*)&m_receiveBuffers[i][receiveBufferCounter],
20798 m_dataBlockSize * sizeof(MFloat));
20799 receiveBufferCounter += m_dataBlockSize;
20800 }
20801 }
20802
20803 for(MInt var = 0; var < m_noPVars; var++) {
20804 resL2[var] = F0;
20805 resMax[var] = F0;
20806 }
20807
20808
20809 // b) update variables in alle N-Cells based on the variables in NNghbrs2
20810 if(!NeumannVariante) {
20811 for(MInt n = 0; n < noNCells; n++) {
20812 MInt cellId = NCells.p[n];
20813 MInt nghbrId = NNghbrs.p[n];
20814 a_pvariable(cellId, PV->RHO) = a_pvariable(nghbrId, PV->RHO);
20815 a_pvariable(cellId, PV->P) = a_pvariable(nghbrId, PV->P);
20816 }
20817 } else {
20818 // NeumannVariante
20819 for(MInt n = 0; n < noNCells; n++) {
20820 tmpVars.p[n * 2 + 0] = F0;
20821 tmpVars.p[n * 2 + 1] = F0;
20822 for(MInt d = 0; d < nDim; d++) {
20823 MInt nghbrId = NNghbrs2.p[n * nDim + d];
20824 tmpVars.p[n * 2 + 0] += a_pvariable(nghbrId, PV->RHO) * NFactors.p[n * nDim + d];
20825 tmpVars.p[n * 2 + 1] += a_pvariable(nghbrId, PV->P) * NFactors.p[n * nDim + d];
20826 }
20827 }
20828 for(MInt n = 0; n < noNCells; n++) {
20829 MInt cellId = NCells.p[n];
20830 a_pvariable(cellId, PV->RHO) = tmpVars.p[n * 2 + 0];
20831 a_pvariable(cellId, PV->P) = tmpVars.p[n * 2 + 1];
20832 }
20833 }
20834
20835
20836 // c) update variables for all gap cells
20837 for(MInt g = 0; g < noGapCells; g++) {
20838 MInt cellId = gapCells.p[g];
20839 if(a_isHalo(cellId)) continue;
20840 for(MInt var = 0; var < m_noPVars; var++) {
20841 tmp[var] = a_pvariable(cellId, var);
20842 a_pvariable(cellId, var) = F0;
20843 }
20844 for(MInt dir = 0; dir < m_noDirs; dir++) {
20845 MInt nghbrId = c_neighborId(cellId, dir);
20846 for(MInt var = 0; var < m_noPVars; var++) {
20847 a_pvariable(cellId, var) += a_pvariable(nghbrId, var) / m_noDirs;
20848 }
20849 }
20850 for(MInt var = 0; var < m_noPVars; var++) {
20851 a_pvariable(cellId, var) = (F1 - lambdaRelax) * tmp[var] + lambdaRelax * a_pvariable(cellId, var);
20852 resL2[var] += POW2(a_pvariable(cellId, var) - tmp[var]);
20853 resMax[var] = mMax(resMax[var], fabs(a_pvariable(cellId, var) - tmp[var]));
20854 }
20855 }
20856
20857 for(MInt var = 0; var < m_noPVars; var++) {
20858 resL2[var] = sqrt(resL2[var]);
20859 }
20860
20861 if((backupSteps - step) % (backupSteps / 10) == 0) {
20862 m_log << " * " << 100 * (backupSteps - step) / backupSteps << " % - residual (L2) rho: " << resL2[PV->RHO]
20863 << " - residual (max) rho: " << resMax[PV->RHO] << endl;
20864 }
20865 }
20866
20867 m_log << " * "
20868 << "100"
20869 << " % - residual (L2) rho: " << resL2[PV->RHO] << " - residual (max) rho: " << resMax[PV->RHO] << endl;
20870
20871 for(MInt i = 0; i < noNeighborDomains(); i++) {
20872 MInt sendBufferCounter = 0;
20873 for(MInt j = 0; j < noExchangeWindowCells[i]; j++) {
20874 MInt cellId = windowCellId(i, exchangeWindowCells(i, j));
20875 memcpy((void*)&m_sendBuffers[i][sendBufferCounter], (void*)&a_pvariable(cellId, 0),
20876 m_dataBlockSize * sizeof(MFloat));
20877 sendBufferCounter += m_dataBlockSize;
20878 }
20879 }
20880
20881 for(MInt i = 0; i < noNeighborDomains(); i++) {
20882 MInt bufSize = noExchangeWindowCells[i] * m_dataBlockSize;
20883 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
20884 "m_sendBuffers[i]");
20885 }
20886
20887 for(MInt i = 0; i < noNeighborDomains(); i++) {
20888 MInt bufSize = noExchangeHaloCells[i] * m_dataBlockSize;
20889 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &status, AT_,
20890 "m_receiveBuffers[i]");
20891 }
20892 for(MInt i = 0; i < noNeighborDomains(); i++) {
20893 MPI_Wait(&g_mpiRequestMb[i], &status, AT_);
20894 }
20895
20896 for(MInt i = 0; i < noNeighborDomains(); i++) {
20897 MInt receiveBufferCounter = 0;
20898 for(MInt j = 0; j < noExchangeHaloCells[i]; j++) {
20899 MInt cellId = haloCellId(i, exchangeHaloCells(i, j));
20900 memcpy((void*)&a_pvariable(cellId, 0), (void*)&m_receiveBuffers[i][receiveBufferCounter],
20901 m_dataBlockSize * sizeof(MFloat));
20902 receiveBufferCounter += m_dataBlockSize;
20903 }
20904 }
20905
20906 // restore the correct neighboring information for further MB computation
20908
20909 for(MInt g = 0; g < noGapCells; g++) {
20910 MInt cellId = gapCells.p[g];
20911
20913
20914 for(MInt varId = 0; varId < CV->noVariables; varId++) {
20915 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
20916 }
20917
20918 if(m_dualTimeStepping) {
20919 for(MInt varId = 0; varId < CV->noVariables; varId++) {
20920 a_dt2Variable(cellId, varId) = a_variable(cellId, varId);
20921 a_dt1Variable(cellId, varId) = a_variable(cellId, varId);
20922 }
20923 }
20924
20925 if(c_isLeafCell(cellId)) {
20926 a_hasProperty(cellId, SolverCell::IsFlux) = true;
20927 a_hasProperty(cellId, SolverCell::IsActive) = true;
20928 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = true;
20929 }
20930 }
20931}
MFloat & a_dt1Variable(const MInt cellId, const MInt varId)
Returns dt1Variables of the cell CellId variables varId.
MFloat & a_dt2Variable(const MInt cellId, const MInt varId)
Returns dt2Variables of the cell CellId variables varId.
void restoreNeighbourLinks()
restores previously deleted neighbour information and reactivates cells
void deleteNeighbourLinks()
deletes links to neighbours tagged inactive
MInt haloCellId(const MInt domainId, const MInt cellId) const

◆ initGapCellExchange()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initGapCellExchange
Author
Tim Wegmann

Definition at line 29648 of file fvmbcartesiansolverxd.cpp.

29648 {
29649 TRACE();
29650
29651#if defined _MB_DEBUG_ || !defined NDEBUG
29653 checkHaloCells(2);
29654#endif
29655
29656 if(m_gapCellExchangeInit) return;
29657 m_gapCellExchangeInit = true;
29658
29659 if(noNeighborDomains() == 0) return;
29660
29661 for(MInt i = 0; i < noNeighborDomains(); i++) {
29662 m_gapWindowCells[i].clear();
29663 m_gapHaloCells[i].clear();
29664 }
29665
29666 ScratchSpace<MInt> isGap(a_noCells(), AT_, "isGap");
29667 isGap.fill(0);
29668
29669 // 1) setup Gap-exchange:
29670 // for all Gap-Cells which are/were gapCells
29671
29672 // a) set noExchangeWindowCells and exchangeWindowCells
29673 for(MInt i = 0; i < noNeighborDomains(); i++) {
29674 ASSERT(m_gapHaloCells[i].size() == 0, "");
29675 for(MInt j = 0; j < noHaloCells(i); j++) {
29676 MInt cellId = haloCellId(i, j);
29677 if(a_wasGapCell(cellId) || a_isGapCell(cellId)) {
29678 m_gapHaloCells[i].push_back(cellId);
29679 isGap(cellId) = 1;
29680 }
29681 }
29682 }
29683
29684 MUint recvSize = maia::mpi::getBufferSize(grid().windowCells());
29685 ScratchSpace<MInt> recvBuffer(mMax(1u, recvSize), AT_, "recvBuffer");
29686 maia::mpi::reverseExchangeData(grid().neighborDomains(), grid().haloCells(), grid().windowCells(), mpiComm(),
29687 &isGap[0], &recvBuffer[0]);
29688
29689
29690 recvSize = 0;
29691 for(MInt i = 0; i < noNeighborDomains(); i++) {
29692 ASSERT(m_gapWindowCells[i].size() == 0, "");
29693 for(MInt j = 0; j < noWindowCells(i); j++) {
29694 MInt cellId = windowCellId(i, j);
29695 if(recvBuffer[recvSize]) {
29696 ASSERT(a_isGapCell(cellId) || a_wasGapCell(cellId), "");
29697 m_gapWindowCells[i].push_back(cellId);
29698 }
29699 recvSize++;
29700 }
29701 }
29702
29703// verify exchange:
29704#if defined _MB_DEBUG_ || !defined NDEBUG
29705
29706 MPI_Status statusMpi;
29707 ScratchSpace<MInt> check(a_noCells(), AT_, "isOnMaxLevel");
29708 check.fill(0);
29709
29710 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
29711 check[cellId] = 1;
29712 if(a_isGapCell(cellId)) check[cellId] = 2;
29713 if(a_wasGapCell(cellId)) check[cellId] = 3;
29714 if(a_isGapCell(cellId) && a_wasGapCell(cellId)) check[cellId] = 4;
29715 }
29716
29717 // gather
29718 for(MInt i = 0; i < noNeighborDomains(); i++) {
29719 if(m_gapWindowCells[i].empty()) continue;
29720 MInt sendBufferCounter = 0;
29721 for(MInt j = 0; j < (signed)m_gapWindowCells[i].size(); j++) {
29723 m_sendBuffers[i][sendBufferCounter] = (MFloat)check[cellId];
29724 sendBufferCounter++;
29725 }
29726 }
29727
29728
29729 // send
29730 for(MInt i = 0; i < noNeighborDomains(); i++) {
29731 if(m_gapWindowCells[i].empty()) continue;
29732 MInt bufSize = m_gapWindowCells[i].size();
29733 MPI_Issend(m_sendBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i], AT_,
29734 "m_sendBuffers[i]");
29735 }
29736
29737 // receive
29738 for(MInt i = 0; i < noNeighborDomains(); i++) {
29739 if(m_gapHaloCells[i].empty()) continue;
29740 MInt bufSize = m_gapHaloCells[i].size();
29741 MPI_Recv(m_receiveBuffers[i], bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &statusMpi, AT_,
29742 "m_receiveBuffers[i]");
29743 }
29744 for(MInt i = 0; i < noNeighborDomains(); i++) {
29745 MPI_Wait(&g_mpiRequestMb[i], &statusMpi, AT_);
29746 }
29747
29748 // scatter
29749 for(MInt i = 0; i < noNeighborDomains(); i++) {
29750 if(m_gapHaloCells[i].empty()) continue;
29751 MInt receiveBufferCounter = 0;
29752 for(MInt j = 0; j < (signed)m_gapHaloCells[i].size(); j++) {
29753 MInt cellId = m_gapHaloCells[i][j];
29754 check[cellId] = (MInt)m_receiveBuffers[i][receiveBufferCounter];
29755 receiveBufferCounter++;
29756 }
29757 }
29758
29759 for(MInt cellId = noInternalCells(); cellId < a_noCells(); cellId++) {
29760 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
29761 if(a_isGapCell(cellId) && !a_wasGapCell(cellId))
29762 ASSERT(check[cellId] == 2, "");
29763 else if(a_wasGapCell(cellId) && !a_isGapCell(cellId))
29764 ASSERT(check[cellId] == 3, "");
29765 else if(a_isGapCell(cellId) && a_wasGapCell(cellId))
29766 ASSERT(check[cellId] == 4, "");
29767 else
29768 ASSERT(check[cellId] == 0, "");
29769 }
29770
29771
29772#endif
29773}
void exchangeGapInfo()
exchanges the Gap-Information with the solver-own communicators!
void reverseExchangeData(const MInt noNghbrDomains, const MInt *const nghbrDomains, const MInt *const noHaloCells, const MInt **const haloCells, const MInt *const noWindowCells, const MInt **const, const MPI_Comm comm, const U *const data, U *const windowBuffer, const MInt noDat=1)
Generic reverse exchange of data.
Definition: mpiexchange.h:400

◆ initGField()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initGField
Author
Lennart Schneiders

Definition at line 1536 of file fvmbcartesiansolverxd.cpp.

1536 {
1537 TRACE();
1538
1539 ASSERT(m_constructGField, "");
1540
1541 if(m_constructGField && m_bodyTypeMb > 0) {
1544 } else if(m_bodyTypeMb != 0) {
1545 mTerm(1, AT_, "Unknown body type.");
1546 }
1547}
void constructGField(MBool updateBody=true)
manually constructs the level-set field after each time step
void initBodyProperties()
initialize properties of the embedded body at startup

◆ initializeEmergedCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initializeEmergedCells
Author
Lennart Schneiders

Definition at line 20254 of file fvmbcartesiansolverxd.cpp.

20254 {
20255 TRACE();
20256
20257 cerr << globalTimeStep << " Calling initializeEmergedCells(), due to Gap-opening " << endl;
20258
20259 MIntScratchSpace nghbrList(150, AT_, "nghbrList");
20260 MIntScratchSpace layerId(150, AT_, "layerList");
20261 MBoolScratchSpace gapCell(a_noCells(), AT_, "gapCell");
20262
20263 // a) mark all cells which were an inactive GapCell
20264 // and are now an active and are not a GapCell anymore!
20265 // CAUTION: this includes BndryGhostCells!
20266 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
20267 gapCell[cellId] = false;
20268 if(m_levelSet && m_closeGaps) {
20269 if(a_hasProperty(cellId, SolverCell::WasGapCell) && !a_hasProperty(cellId, SolverCell::IsGapCell)
20270 && a_hasProperty(cellId, SolverCell::WasInactive) && !a_hasProperty(cellId, SolverCell::IsInactive)) {
20271 gapCell[cellId] = true;
20272
20273 cerr << "initializeEmergedCells: GapCells are " << cellId << " " << c_globalId(cellId) << " bndry-ghostCell "
20274 << a_isBndryGhostCell(cellId) << endl;
20275 }
20276 }
20277 }
20278
20279 // b) labels:FVMB claudia temporary bugfix for initialization of nan outside cells...
20280
20281 // All cells that are active, but were inactive before are initialized!
20282 // Also non-Gap-Cells!
20283 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
20284 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
20285
20286 if(a_isHalo(cellId)) continue;
20287 if(a_isPeriodic(cellId)) continue;
20288 if(!a_hasProperty(cellId, SolverCell::WasInactive)) continue;
20289 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
20290
20291 // resetting all emerging Cells!
20292 cerr << "initializeEmergedCell: resetting Gap-Cells " << cellId << " " << c_globalId(cellId) << endl;
20293
20294 a_variable(cellId, CV->RHO) = m_rhoInfinity;
20295 a_variable(cellId, CV->RHO_E) = m_rhoEInfinity;
20296 a_pvariable(cellId, PV->RHO) = m_rhoInfinity;
20297 a_pvariable(cellId, PV->P) = m_PInfinity;
20298
20299 for(MInt v = 0; v < nDim; v++) {
20300 a_variable(cellId, CV->RHO_VV[v]) = F0;
20301 a_pvariable(cellId, PV->VV[v]) = F0;
20302 }
20303 }
20304
20305 // Initialize all cells newly created in the valve gap
20306 if(m_gapOpened) {
20308 }
20309
20310 m_noEmergedCells = 0;
20312
20313 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
20314 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
20315 ASSERT(cellId < a_noCells(), "");
20316 if(a_isHalo(cellId)) continue;
20317 if(a_isPeriodic(cellId)) continue;
20318 if(!a_hasProperty(cellId, SolverCell::WasInactive)) continue;
20319 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
20321 if(a_isWindow(cellId)) m_noEmergedWindowCells++;
20322
20323 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) {
20324 for(MInt v = 0; v < m_noCVars; v++) {
20325 a_variable(cellId, v) = F0;
20326 }
20327 for(MInt v = 0; v < m_noPVars; v++) {
20328 a_pvariable(cellId, v) = F0;
20329 }
20330 continue;
20331 }
20332
20333 cerr << "initializeEmergedCell: init Cells " << cellId << " " << c_globalId(cellId) << endl;
20334
20335
20336 if(!gapCell[cellId]) {
20337 MFloatScratchSpace vars(m_noCVars, AT_, "vars");
20338 const MInt counter = this->template getAdjacentLeafCells<2>(cellId, 1, nghbrList, layerId);
20339 MFloat facCnt = F0;
20340 for(MInt v = 0; v < m_noCVars; v++)
20341 vars[v] = F0;
20342
20343 for(MInt n = 0; n < counter; n++) {
20344 MInt nghbrId = nghbrList[n];
20345 if(nghbrId < 0) continue;
20346 if(a_hasProperty(nghbrId, SolverCell::WasInactive)) continue;
20347 MFloat fac = m_cellVolumesDt1[nghbrId];
20348 for(MInt v = 0; v < m_noCVars; v++) {
20349 vars[v] += fac * a_oldVariable(nghbrId, v);
20350 }
20351 facCnt += fac;
20352 }
20353 if(fabs(facCnt) / c_cellLengthAtCell(cellId) > 0.1) {
20354 for(MInt v = 0; v < m_noCVars; v++) {
20355 vars[v] /= facCnt;
20356 a_variable(cellId, v) = vars[v];
20357 }
20358 setPrimitiveVariables(cellId);
20359 } else {
20360 cerr << "Warning cell init " << fabs(facCnt) / c_cellLengthAtCell(cellId) << endl;
20361 if(m_levelSet && m_closeGaps) {
20362 cerr << m_closeGaps << " " << a_hasProperty(cellId, SolverCell::WasGapCell) << " "
20363 << a_hasProperty(cellId, SolverCell::IsGapCell) << " " << a_hasProperty(cellId, SolverCell::WasInactive)
20364 << " " << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
20365 }
20366 a_variable(cellId, CV->RHO) = m_rhoInfinity;
20367 a_variable(cellId, CV->RHO_E) = m_rhoEInfinity;
20368 a_pvariable(cellId, PV->RHO) = m_rhoInfinity;
20369 a_pvariable(cellId, PV->P) = m_PInfinity;
20370 for(MInt v = 0; v < nDim; v++) {
20371 a_variable(cellId, CV->RHO_VV[v]) = F0;
20372 a_pvariable(cellId, PV->VV[v]) = F0;
20373 }
20374 }
20375 MFloat delta = maia::math::deltaFun(m_volumeFraction[bndryId], F0, F1);
20376 for(MInt i = 0; i < nDim; i++) {
20377 a_pvariable(cellId, PV->VV[i]) =
20378 delta * a_pvariable(cellId, PV->VV[i])
20379 + (F1 - delta) * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->VV[i]];
20380 }
20381 }
20382
20384
20385 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
20386 MInt splitParent = getAssociatedInternalCell(cellId);
20387 MInt splitParentBndryId = a_bndryId(splitParent);
20388 ASSERT(splitParentBndryId > -1, " this is too bad... split cells inconsistency");
20389 MFloat factor = m_bndryCells->a[bndryId].m_volume / mMax(m_eps, m_bndryCells->a[splitParentBndryId].m_volume);
20390 for(MInt v = 0; v < m_noCVars; v++) {
20391 a_variable(splitParent, v) += factor * a_variable(cellId, v);
20392 }
20393 for(MInt v = 0; v < m_noPVars; v++) {
20394 a_pvariable(splitParent, v) += factor * a_pvariable(cellId, v);
20395 }
20396 }
20397
20398 // CAUTION: this renders the scheme nonconservative!
20399 for(MInt varId = 0; varId < CV->noVariables; varId++) {
20400 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
20401 }
20402 if(m_dualTimeStepping) {
20403 for(MInt varId = 0; varId < CV->noVariables; varId++) {
20404 // a_dt2Variable( cellId , varId ) = a_variable( cellId , varId );
20405 // a_dt1Variable( cellId , varId ) = a_variable( cellId , varId );
20406 }
20407 }
20408 }
20409
20410 if(globalTimeStep > 0) {
20411 MInt globalNoEmerged = m_noEmergedWindowCells + m_gapOpened;
20412 MPI_Allreduce(MPI_IN_PLACE, &globalNoEmerged, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
20413 "globalNoEmerged");
20414 if(globalNoEmerged > 0) {
20415 exchange();
20416 for(MInt i = 0; i < noNeighborDomains(); i++) {
20417 for(MInt j = 0; j < noHaloCells(i); j++) {
20419 }
20420 }
20421 }
20422 }
20423
20424 cerr << "initializeEmergedCell: noEmergedCells " << m_noEmergedCells << endl;
20425}
void initEmergingGapCells()
initializes variables of cells which occur in a freshly opened gap (valve gap etc....

◆ initializeMaxLevelExchange()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initializeMaxLevelExchange
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 16055 of file fvmbcartesiansolverxd.cpp.

16055 {
16056 TRACE();
16057
16058 if(noNeighborDomains() == 0 && grid().noAzimuthalNeighborDomains() == 0) {
16059 if(noDomains() > 1) mTerm(1, AT_, "Unexpected situation in initializeMaxLevelExchange!");
16060 return;
16061 }
16062
16063#ifndef NDEBUG
16064 MIntScratchSpace sndbuf(noDomains(), AT_, "sndbuf");
16065 MIntScratchSpace rcvbuf(noDomains(), AT_, "rcvbuf");
16066 sndbuf.fill(0);
16067 rcvbuf.fill(-1);
16068 for(MInt i = 0; i < noNeighborDomains(); i++) {
16069 sndbuf[neighborDomain(i)] = 1;
16070 }
16071 MPI_Alltoall(sndbuf.getPointer(), 1, MPI_INT, rcvbuf.getPointer(), 1, MPI_INT, mpiComm(), AT_, "sndbuf.getPointer()",
16072 "rcvbuf.getPointer()");
16073 for(MInt i = 0; i < noDomains(); i++) {
16074 if(i == domainId()) continue;
16075 if(sndbuf[i] != rcvbuf[i]) {
16076 cerr << domainId() << ": warning exchange mismatch with domain " << i << " (" << sndbuf[i] << "/" << rcvbuf[i]
16077 << ") " << endl;
16078 }
16079 }
16080#endif
16081
16082//#define NEW_INITMAXLVLEX
16083#ifdef NEW_INITMAXLVLEX
16084 for(MInt i = 0; i < noNeighborDomains(); i++) {
16085 m_noMaxLevelHaloCells[i] = 0;
16086 for(MInt j = 0; j < noHaloCells(i); j++) {
16087 MInt cellId = haloCellId(i, j);
16088 ASSERT(cellId > -1, "");
16089 MBool structuredCell = a_hasProperty(cellId, SolverCell::AtStructuredRegion);
16090 for(MInt dir = 0; dir < m_noDirs; dir++) {
16091 if(a_hasNeighbor(cellId, dir)) {
16092 if(a_hasProperty(c_neighborId(cellId, dir), SolverCell::AtStructuredRegion)) {
16093 structuredCell = true;
16094 }
16095 }
16096 }
16097 if(c_isLeafCell(cellId) || structuredCell) {
16100 }
16101 }
16102 }
16103 for(MInt i = 0; i < noNeighborDomains(); i++) {
16105 for(MInt j = 0; j < noWindowCells(i); j++) {
16106 MInt cellId = windowCellId(i, j);
16107 ASSERT(cellId > -1, "");
16108 MBool structuredCell = a_hasProperty(cellId, SolverCell::AtStructuredRegion);
16109 for(MInt dir = 0; dir < m_noDirs; dir++) {
16110 if(a_hasNeighbor(cellId, dir)) {
16111 if(a_hasProperty(c_neighborId(cellId, dir), SolverCell::AtStructuredRegion)) {
16112 if(a_isWindow(c_neighborId(cellId, dir))) structuredCell = true;
16113 }
16114 }
16115 }
16116 if(c_isLeafCell(cellId) || structuredCell) {
16119 }
16120 }
16121 }
16122
16123#ifndef NDEBUG
16124 exchange(); // test max level exchange
16125#endif
16126
16127#else
16128
16129 ScratchSpace<MInt> haloCellsCnt(noNeighborDomains(), AT_, "noHaloCells");
16130 ScratchSpace<MInt> windowCellsCnt(noNeighborDomains(), AT_, "noWindowCells");
16131 for(MInt d = 0; d < noNeighborDomains(); d++) {
16132 haloCellsCnt[d] = noHaloCells(d);
16133 windowCellsCnt[d] = noWindowCells(d);
16134 }
16135
16136 if(noNeighborDomains() > 0) {
16138 mAlloc(m_maxLevelHaloCells, noNeighborDomains(), &haloCellsCnt[0], "m_maxLevelHaloCells", AT_);
16140 mAlloc(m_maxLevelWindowCells, noNeighborDomains(), &windowCellsCnt[0], "m_maxLevelWindowCells", AT_);
16141 }
16142
16143 ScratchSpace<MPI_Request> sendReq(noNeighborDomains(), AT_, "sendReq");
16144 ScratchSpace<MPI_Request> recvReq(noNeighborDomains(), AT_, "recvReq");
16145 sendReq.fill(MPI_REQUEST_NULL);
16146 recvReq.fill(MPI_REQUEST_NULL);
16147
16148 // halo cells
16149 for(MInt i = 0; i < noNeighborDomains(); i++) {
16150 m_noMaxLevelHaloCells[i] = 0;
16151 for(MInt j = 0; j < noHaloCells(i); j++) {
16152 MInt cellId = haloCellId(i, j);
16153 m_receiveBuffers[i][j] = -F1;
16154 MBool structuredCell = a_hasProperty(cellId, SolverCell::AtStructuredRegion);
16155 for(MInt dir = 0; dir < m_noDirs; dir++) {
16156 if(a_hasNeighbor(cellId, dir)) {
16157 if(a_hasProperty(c_neighborId(cellId, dir), SolverCell::AtStructuredRegion)) {
16158 structuredCell = true;
16159 }
16160 }
16161 }
16162 if(!c_isLeafCell(cellId) && !structuredCell) continue;
16165 ASSERT(cellId > -1, "");
16166 m_receiveBuffers[i][j] = (MFloat)cellId;
16167 }
16168 }
16169
16170 // send halo cell information
16171 if(noNeighborDomains() > 0) {
16172 if(m_nonBlockingComm) {
16173 for(MInt i = 0; i < noNeighborDomains(); i++) {
16174 MPI_Irecv(m_sendBuffers[i], noWindowCells(i), MPI_DOUBLE, neighborDomain(i), 5, mpiComm(), &recvReq[i], AT_,
16175 "m_sendBuffers[i]");
16176 }
16177 for(MInt i = 0; i < noNeighborDomains(); i++) {
16178 MPI_Isend(m_receiveBuffers[i], noHaloCells(i), MPI_DOUBLE, neighborDomain(i), 5, mpiComm(), &sendReq[i], AT_,
16179 "m_receiveBuffers[i]");
16180 }
16181 MPI_Waitall(noNeighborDomains(), &recvReq[0], MPI_STATUSES_IGNORE, AT_);
16182 MPI_Waitall(noNeighborDomains(), &sendReq[0], MPI_STATUSES_IGNORE, AT_);
16183 } else {
16184 for(MInt i = 0; i < noNeighborDomains(); i++) {
16185 MPI_Issend(m_receiveBuffers[i], noHaloCells(i), MPI_DOUBLE, neighborDomain(i), 5, mpiComm(), &sendReq[i], AT_,
16186 "m_receiveBuffers[i]");
16187 }
16188 for(MInt i = 0; i < noNeighborDomains(); i++) {
16189 MPI_Recv(m_sendBuffers[i], noWindowCells(i), MPI_DOUBLE, neighborDomain(i), 5, mpiComm(), MPI_STATUS_IGNORE,
16190 AT_, "m_sendBuffers[i]");
16191 }
16192 MPI_Waitall(noNeighborDomains(), &sendReq[0], MPI_STATUSES_IGNORE, AT_);
16193 }
16194 }
16195
16196 // write window cell information
16197 for(MInt i = 0; i < noNeighborDomains(); i++) {
16199 for(MInt j = 0; j < noWindowCells(i); j++) {
16200 if(m_sendBuffers[i][j] > -F1B2) {
16201 ASSERT(windowCellId(i, j) > -1, "");
16204 }
16205 }
16206 }
16207#endif
16208
16209
16210 this->prepareMpiExchange();
16211
16212 if(grid().azimuthalPeriodicity()) {
16214 }
16215}

◆ initializeMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initializeMb ( )
Author
Lennart Schneiders

◆ initializeRungeKutta()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initializeRungeKutta
overridevirtual
Author
Daniel Hartmann

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 13753 of file fvmbcartesiansolverxd.cpp.

13753 {
13754 TRACE();
13755
13757
13758 if(!m_restart) {
13759 m_time = 0.0;
13761 }
13762
13763 for(MInt cellId = a_noCells() - 1; cellId >= 0; --cellId) {
13764 for(MInt varId = 0; varId < m_noCVars; varId++) {
13765 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
13766 }
13767 }
13768
13770}

◆ initPointParticleProperties()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initPointParticleProperties ( )

◆ initSolutionStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initSolutionStep ( MInt  mode)
overridevirtual

mode = -1: default argument, call in the initialisation process mode = 0: reinit after mesh adaptation mode = 1: reinit after balance

Author
Lennart Schneiders, Update Tim Wegmann

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 30548 of file fvmbcartesiansolverxd.cpp.

30548 {
30549 TRACE();
30550
30551 NEW_TIMER_GROUP(t_initTimer, "initSolutionStep");
30552 NEW_TIMER(t_timertotal, "initSolutionStep", t_initTimer);
30553 NEW_SUB_TIMER(t_init, "init", t_timertotal);
30554 NEW_SUB_TIMER(t_createBnd, "createBoundaryCells", t_timertotal);
30555 NEW_SUB_TIMER(t_initBnd, "initBoundaryCells", t_timertotal);
30556 NEW_SUB_TIMER(t_stencil, "buildStencil", t_timertotal);
30557 NEW_SUB_TIMER(t_surfaces, "createSurfaces", t_timertotal);
30558 NEW_SUB_TIMER(t_initSurfaces, "initSurfaces", t_timertotal);
30559 NEW_SUB_TIMER(t_finalize, "finalize", t_timertotal);
30560 RECORD_TIMER_START(t_timertotal);
30561 RECORD_TIMER_START(t_init);
30562
30563 grid().updateGridInfo();
30564 if(m_fvBndryCnd->m_cellCoordinatesCorrected) m_fvBndryCnd->recorrectCellCoordinates();
30565
30567 if(mode == -1) {
30568 // should only be called once!
30569 ASSERT(frstrn, "");
30570 ASSERT(!m_onlineRestart, "");
30571 } else if(mode == 1) {
30572 ASSERT(m_onlineRestart, "");
30573 } else {
30574 ASSERT(!m_onlineRestart, "");
30575 }
30576 frstrn = false;
30577
30578 if(!m_restart && mode < 1) {
30581 }
30583 }
30584
30587
30588 RECORD_TIMER_STOP(t_init);
30589 RECORD_TIMER_START(t_createBnd);
30590
30592
30593 IF_CONSTEXPR(nDim == 3) {
30594 if(m_noPointParticles > 0) {
30596 }
30597 }
30598
30599 // initialise cell-volume for all cells for firstRun
30600 // do not reset cellVolumes at balance, the volume has been exchanged!
30601 if(mode < 1) {
30603 }
30604
30605 // generates the outer-boundary-Cells
30607 m_noOuterBndryCells = m_fvBndryCnd->m_bndryCells->size();
30608 IF_CONSTEXPR(nDim == 3) { checkCells(); }
30609
30610 for(MInt bndryId = 0; bndryId < m_noOuterBndryCells; bndryId++) {
30611 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
30612 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
30615 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
30616 m_sweptVolume[bndryId] = F0;
30617 m_sweptVolumeDt1[bndryId] = F0;
30618 }
30619 // NOTE: m_cellVolumesDt1 is set correctly for all cells below!
30620
30621 if(m_restart) {
30622 if(m_dualTimeStepping) {
30623 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
30624 for(MInt varId = 0; varId < CV->noVariables; varId++) {
30625 a_dt2Variable(cellId, varId) = a_variable(cellId, varId);
30626 a_dt1Variable(cellId, varId) = a_variable(cellId, varId);
30627 }
30628 }
30629 }
30630 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
30631 for(MInt varId = 0; varId < CV->noVariables; varId++) {
30632 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
30633 }
30634 }
30635 }
30636
30637
30638 // shift cell center of boundary cells
30639 m_fvBndryCnd->correctCellCoordinates();
30640
30641 // MULTILEVEL
30642 // correct (xyz)cc and body surfaces of coarse boundary cells
30643 // requires that small and master cells are not yet merged!
30644 m_fvBndryCnd->correctCoarseBndryCells();
30645 m_fvBndryCnd->m_smallBndryCells->setSize(0);
30646
30647 RECORD_TIMER_STOP(t_createBnd);
30648 RECORD_TIMER_START(t_initBnd);
30649
30650 if(m_fvBndryCnd->m_cellMerging) {
30651 // detects small cells and identifies a master cell for each
30652 // merges master and small cell(s)
30653 m_fvBndryCnd->detectSmallBndryCells();
30654 m_log << "Connecting master and slave cells...";
30655 m_fvBndryCnd->mergeCells();
30656 m_log << "ok" << endl;
30657 } else {
30658 m_fvBndryCnd->setBCTypes();
30659 m_fvBndryCnd->setNearBoundaryRecNghbrs();
30660 m_fvBndryCnd->computeImagePointRecConst();
30661 if(m_fvBndryCnd->m_smallCellRHSCorrection) {
30662 m_fvBndryCnd->initSmallCellRHSCorrection();
30663 } else {
30664 m_fvBndryCnd->initSmallCellCorrection();
30665 }
30666 }
30667
30668
30669 // write out centerline data
30670 if(m_writeOutData) {
30671 cerr << "Writing out center line data" << endl;
30672 stringstream fileNameCL;
30673 fileNameCL << "centerlineData";
30674 fileNameCL << "_" << domainId();
30675 writeCenterLineVel((fileNameCL.str()).c_str());
30676 mTerm(0, AT_);
30677 }
30678
30679 RECORD_TIMER_STOP(t_initBnd);
30680
30681 RECORD_TIMER_START(t_surfaces);
30682 m_log << "create initial surfaces...";
30685 m_log << "ok" << endl;
30686 RECORD_TIMER_STOP(t_surfaces);
30687
30688 RECORD_TIMER_START(t_stencil);
30691 m_noOuterBoundarySurfaces = m_fvBndryCnd->m_noBoundarySurfaces;
30692
30693 m_log << "Tagging cells needed for the surface flux computation...";
30695 m_log << "ok" << endl;
30696
30697 // TODO labels:FVMB Check if this is necessary in 2D; Testcases pass also if setUpwindCoefficient() is not
30698 // called here
30699
30700 IF_CONSTEXPR(nDim == 2) {
30701 m_log << "Setting upwind coefficient...";
30702 setUpwindCoefficient(); // overrides value of restoreSurfaces()
30703 m_log << "ok" << endl;
30704 }
30705
30706 m_log << "Computing plane vectors...";
30707 m_fvBndryCnd->computePlaneVectors();
30708 m_log << "ok" << endl;
30709
30713 }
30714
30715 m_log << "Initializing the least-squares reconstruction...";
30716 // builds the least-squares stencil and computes the LS constants
30717 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
30718 a_hasProperty(cellId, SolverCell::IsActive) = true;
30719 }
30720 if(m_fvBndryCnd->m_cellMerging) {
30721 // set the neighbor arrays m_storeNghbrIds, m_identNghbrIds
30722 findNghbrIds();
30726 }
30727 m_log << "ok" << endl;
30728
30729 // used for solution output!
30730 IF_CONSTEXPR(nDim == 3) {
30731 if(m_extractedCells != nullptr) {
30732 delete m_extractedCells;
30733 m_extractedCells = nullptr;
30734 } else if(m_gridPoints != nullptr) {
30735 delete m_gridPoints;
30736 m_gridPoints = nullptr;
30737 }
30738 }
30739
30740 m_log << "Initializing the viscous flux computation...";
30742 m_log << "ok" << endl;
30743
30744 // initialize the reconstruction scheme for the boundary and ghost cells
30745 if(m_fvBndryCnd->m_cellMerging) {
30746 m_log << "Initializing boundary conditions...";
30747 findNghbrIds();
30748 m_fvBndryCnd->initBndryCnds();
30751 m_log << "ok" << endl;
30752 } else {
30753 m_fvBndryCnd->setBCTypes();
30754 }
30755
30756 // initCutOffBoundaryCondition();
30757
30758#ifndef NDEBUG
30759 // NOTE: at this point cellVolumeDt1 is not correct on halo-cells, but set correctly below!
30760 checkHaloCells(3);
30761#endif
30762
30763 m_log << "Computing reconstruction constants...";
30764 // Computes the reconstruction constants for each cell
30766 m_log << "ok" << endl;
30767 RECORD_TIMER_STOP(t_stencil);
30768
30769 if(grid().azimuthalPeriodicity()) {
30772 MUint noWindows = maia::mpi::getBufferSize(grid().azimuthalWindowCells());
30774 m_azimuthalWasNearBndryIds.assign(noWindows, -1);
30775 if(mode == 1) cutOffBoundaryCondition();
30776 }
30777 RECORD_TIMER_START(t_initSurfaces);
30779
30780#if defined _MB_DEBUG_ || !defined NDEBUG
30781 // In debug mode exhange() calls maxResidual(), which fails if RHS
30782 // is not set to 0 during init call (contains nans otherwise)
30783 resetRHS();
30784#endif
30785
30786 if(grid().azimuthalPeriodicity()) {
30787 if(mode == 1) {
30788 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
30789 // computePV() is called during loadBalance but RHO is 0 for these cells therefore computePV() results in nans.
30790 for(MInt v = 0; v < PV->noVariables; v++) {
30791 if(!(a_pvariable(cellId, v) >= F0 || a_pvariable(cellId, v) < F0) || std::isnan(a_pvariable(cellId, v))) {
30792 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
30793 mTerm(1, "This should only occur for non-leaf cells!");
30794 }
30795 a_pvariable(cellId, v) = F0;
30796 }
30797 }
30798 }
30799 }
30800 exchangeAll(); // Just so that halo cells on lower levels do not contain nans.
30801 } else {
30802 exchange();
30803 }
30804
30806
30807 // reset m_bndryCandidateIds
30808 m_bndryCandidateIds.clear();
30809 for(MInt i = 0; i < m_bndryGhostCellsOffset; i++) {
30810 m_bndryCandidateIds.push_back(-1);
30811 }
30812 m_bndryCandidates.clear();
30814
30815 MBool found = false;
30816 for(MInt bc = 0; bc < m_fvBndryCnd->m_noBndryCndIds; bc++) {
30817 if(m_fvBndryCnd->m_bndryCndIds[bc] == m_movingBndryCndId) found = true;
30818 }
30819 if(!found) {
30820 m_fvBndryCnd->m_bndryCndIds[m_fvBndryCnd->m_noBndryCndIds] = m_movingBndryCndId;
30821 m_fvBndryCnd->m_noBndryCndIds++;
30823 m_log << "Added moving boundary condition " << m_movingBndryCndId << endl;
30824 }
30825 m_fvBndryCnd->createBndryCndHandler();
30826
30827 for(MInt i = 0; i < a_noCells(); i++) {
30828 a_hasProperty(i, SolverCell::NearWall) = false;
30829 }
30830
30831 // Is the following really necessary? Testcases seem to also work without
30832 IF_CONSTEXPR(nDim == 2) {
30833 m_fvBndryCnd->recorrectCellCoordinates();
30834 const MFloat signStencil[4][2] = {{-F1, -F1}, {F1, -F1}, {-F1, F1}, {F1, F1}};
30835 MFloat tmpPoint[nDim];
30836 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
30837 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
30838 for(MInt p = 0; p < m_noCellNodes; p++) {
30839 for(MInt i = 0; i < nDim; i++) {
30840 tmpPoint[i] = a_coordinate(cellId, i) + signStencil[p][i] * F1B2 * c_cellLengthAtLevel(a_level(cellId));
30841 }
30842 m_pointIsInside[bndryId][IDX_LSSETMB(p, 0)] = m_geometry->pointIsInside(tmpPoint);
30843 }
30844 }
30845 m_fvBndryCnd->rerecorrectCellCoordinates();
30846 }
30847
30849 if(m_restart) firstRun = true;
30850 if(firstRun) {
30851 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
30854 }
30855 firstRun = false;
30856 }
30857
30858 RECORD_TIMER_STOP(t_initSurfaces);
30859 RECORD_TIMER_START(t_finalize);
30860
30861#ifndef NDEBUG
30862 m_log << "_________________________________________________________________" << endl << endl;
30863 m_log << "Grid summary after clean initialization:" << endl;
30864 m_log << "_________________________________________________________________" << endl << endl;
30865 m_log << setfill(' ');
30866 m_log << "number of cells " << setw(7) << a_noCells() << endl;
30867 m_log << "number of surfaces " << setw(7) << a_noSurfaces() << endl;
30868 m_log << "number of small cells " << setw(7) << m_fvBndryCnd->m_smallBndryCells->size() << endl;
30869 m_log << "minimum grid level " << setw(7) << minLevel() << endl;
30870 m_log << "maximum grid level " << setw(7) << maxLevel() << endl << endl;
30871 m_log << "level | total no cells | no of leaf cells | ghost cells" << endl;
30872
30873 MInt total = 0, leaf = 0, ghost = 0;
30874 for(MInt level = maxLevel(); level >= minLevel(); level--) {
30875 total = 0;
30876 leaf = 0;
30877 ghost = 0;
30878 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
30879 if(a_isBndryGhostCell(cellId)) {
30880 if(a_level(cellId) == level) {
30881 total++;
30882 leaf++;
30883 ghost++;
30884 }
30885 } else if(a_level(cellId) == level) {
30886 total++;
30887 if(c_isLeafCell(cellId)) {
30888 leaf++;
30889 }
30890 }
30891 }
30892 m_log << setfill(' ');
30893 m_log << setw(3) << level << " " << setw(12) << total << " " << setw(16) << leaf << " " << setw(14) << ghost
30894 << endl;
30895 }
30896
30897 // check domain boundaries
30898 MInt noCells = noInternalCells();
30899 MFloat cellLength = NAN;
30900 MFloat maxC[3] = {-10000.0, -10000.0, -10000.0};
30901 MFloat minC[3] = {10000.0, 10000.0, 10000.0};
30902 for(MInt c = 0; c < noCells; c++) {
30903 if(!a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) continue;
30904 if(a_isHalo(c)) continue;
30905 if(a_isPeriodic(c)) continue;
30906 cellLength = c_cellLengthAtCell(c);
30907 for(MInt i = 0; i < nDim; i++) {
30908 maxC[i] = mMax(maxC[i], a_coordinate(c, i) + F1B2 * cellLength);
30909 minC[i] = mMin(minC[i], a_coordinate(c, i) - F1B2 * cellLength);
30910 }
30911 }
30912 m_log << "_________________________________________________________________" << endl << endl;
30913
30914 m_log << "Physical domain boundaries: " << endl;
30915 m_log << "min (x,y" << (nDim == 3 ? ",z): (" : "): (") << minC[0] << "," << minC[1];
30916 IF_CONSTEXPR(nDim == 3) m_log << "," << minC[2];
30917 m_log << ")" << endl;
30918 m_log << "max (x,y" << (nDim == 3 ? ",z): (" : "): (") << maxC[0] << "," << maxC[1];
30919 IF_CONSTEXPR(nDim == 3) m_log << "," << maxC[2];
30920 m_log << ")" << endl;
30921
30922 m_log << "_________________________________________________________________" << endl << endl;
30923#endif
30924
30925 m_log << "Process " << domainId() << " finished FV-MB initialization at time step " << globalTimeStep << endl;
30926
30927 if(domainId() == 0 || domainId() == noDomains() - 1)
30928 cerr << "Process " << domainId() << " finished FV-MB initialization at time step " << globalTimeStep << endl;
30929
30930 m_log << endl << endl;
30931
30932 RECORD_TIMER_STOP(t_finalize);
30933 RECORD_TIMER_STOP(t_timertotal);
30934 DISPLAY_TIMER(t_timertotal);
30935}
void buildLeastSquaresStencilSimple()
Determine the least squares stencil.
Collector< CartesianGridPoint< nDim > > * m_gridPoints
void computeAzimuthalReconstructionConstants(MInt mode=0) override
Compute the reconstruction constants for azimuthal periodic exchange using a weighted least squares a...
void initializeMaxLevelExchange() override
update window/halo cell collectors
void computeReconstructionConstants() override
computes the reconstruction constants using inverse distance weighted least squares
void setLevelSetMbCellProperties()
determines relevant cell properties
void createInitialSrfcs()
computes initial set of internal grid surfaces
void setCellProperties() override
set the properties of cells and determines the state of halo cells

◆ initSolver()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::initSolver
overridevirtual
Author
Lennart Schneiders

Implements Solver.

Definition at line 11834 of file fvmbcartesiansolverxd.cpp.

11834 {
11835 TRACE();
11836
11837 ASSERT(!m_onlineRestart, "");
11838
11839 // Nothing further to be done if inactive
11840 if(!isActive()) return;
11841
11842 const MFloat time0 = MPI_Wtime();
11843
11844 // for STL levelset this is called in coupler init!
11845 if(m_constructGField) {
11846 if(m_initialCondition == 465) {
11847 m_initialCondition = -1;
11849 m_initialCondition = 465;
11850 }
11851 initGField();
11853 } else {
11855 }
11856
11857 // initialize the runge kutta integration scheme
11859
11860 if(m_restart) {
11863 if(m_geometryChange == nullptr) {
11865 } else {
11867 }
11868
11869 } else {
11871 for(MInt cellId = a_noCells(); cellId--;) {
11872 setPrimitiveVariables(cellId);
11873 }
11874 }
11875
11876 // THOMAS
11877 if(this->m_zonal) {
11879 if(this->m_STGSponge) this->initSTGSponge();
11880
11882 if(domainId() == 0) cerr << "resetInitialCondition: loadRestartFile for solver " << m_solverId << endl;
11884 }
11885 }
11886
11887 if(grid().azimuthalPeriodicity()) initAzimuthalCartesianHaloInterpolation();
11888
11889 // set data on halo-cells
11890 if(noNeighborDomains() > 0) {
11894 }
11896 exchangeData(&a_cellVolume(0), 1); // Exchanging cell volume for azimuthal periodicity would be incorrect!
11897 }
11898
11899 const MFloat time1 = MPI_Wtime();
11900
11901 if(domainId() == 0) m_log << "Init solution time " << time1 - time0 << endl;
11902}
virtual void initSTGSponge()
Initializes zonal exchange arrays.
void initGField()
initializes the level-set data at startup
void loadRestartFile() override
Loads the restart files.
void initBndryLayer()
initializes the bndryLayer data and is/was inactive at solver initialisation
void initializeRungeKutta() override
This function loads all terms used by Runge Kutta.
void loadBodyRestartFile(MInt)
load restart body file readMode = 0 : do not read the cellVolume from file (read only bodyData) readM...

◆ inside()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::inside ( MFloat  x,
MFloat  a,
MFloat  b 
)
inline

Definition at line 18209 of file fvmbcartesiansolverxd.cpp.

18209 {
18210 return (!(x < a) && !(x > b));
18211}

◆ integrateBodyRotation()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::integrateBodyRotation
Author
Lennart Schneiders

Definition at line 4240 of file fvmbcartesiansolverxd.cpp.

4240 {
4242
4243 MFloatScratchSpace R0(3, 3, AT_, "R0");
4244 MFloatScratchSpace R(3, 3, AT_, "R");
4245 MFloatScratchSpace W(4, 4, AT_, "W");
4246 MFloatScratchSpace iW(4, 4, AT_, "iW");
4247 MFloatScratchSpace iI(3, 3, AT_, "iI");
4248 MFloatScratchSpace tmpM(3, 3, AT_, "tmpM");
4249 MFloatScratchSpace rhs(4, AT_, "rhs");
4250
4251 MFloat tmp[3];
4252 MFloat tmp2[3];
4253 MFloat q0[3];
4254 MFloat q[3];
4255 MFloat tq0[3];
4256 MFloat tq[3];
4257 const MFloat dt2 = F1B2 * timeStep();
4258
4259 MIntScratchSpace recvCnt(noDomains(), AT_, "recvCnt");
4260 MIntScratchSpace recvDispl(noDomains() + 1, AT_, "recvDispl");
4261 MIntScratchSpace bodyOffsets(noDomains() + 1, AT_, "bodyOffsets");
4262 bodyOffsets(0) = 0;
4263 for(MLong i = 0; i < noDomains(); i++) {
4264 MLong tmpv = (((MLong)m_noEmbeddedBodies) * (i + 1)) / ((MLong)noDomains());
4265 if(tmpv > numeric_limits<MInt>::max()) mTerm(1, "MInt overflow");
4266 bodyOffsets(i + 1) = (MInt)tmpv;
4267 }
4268
4269 for(MInt k = bodyOffsets(domainId()); k < bodyOffsets(domainId() + 1); k++) {
4270 ASSERT(k > -1 && k < m_noEmbeddedBodies, "");
4273 const MFloat w = m_bodyQuaternionDt1[4 * k + 0];
4274 const MFloat x = m_bodyQuaternionDt1[4 * k + 1];
4275 const MFloat y = m_bodyQuaternionDt1[4 * k + 2];
4276 const MFloat z = m_bodyQuaternionDt1[4 * k + 3];
4277 for(MInt i = 0; i < 3; i++)
4278 tmp[i] = m_bodyAngularVelocityDt1[k * 3 + i];
4279 matrixVectorProduct(q0, R0, tmp);
4280 for(MInt i = 0; i < 3; i++)
4281 tmp[i] = m_bodyTorqueDt1[k * 3 + i];
4282 matrixVectorProduct(tq0, R0, tmp);
4283
4284 for(MInt i = 0; i < 3; i++)
4285 tmp[i] = m_bodyTorque[k * 3 + i];
4286 matrixVectorProduct(tq, R, tmp);
4287
4288 const MFloat* momi = &(m_bodyMomentOfInertia[3 * k]);
4289 const MFloat f0 = (momi[2] - momi[1]) / momi[0];
4290 const MFloat f1 = (momi[0] - momi[2]) / momi[1];
4291 const MFloat f2 = (momi[1] - momi[0]) / momi[2];
4292
4293 for(MInt i = 0; i < 3; i++)
4294 tmp[i] = m_bodyAngularVelocity[k * 3 + i];
4295 matrixVectorProduct(&(q[0]), R, tmp);
4296
4297 for(MInt i = 0; i < 3; i++) {
4298 if(std::isnan(tq[i]) || std::isnan(tq0[i]) || std::isnan(q[i])) {
4299 if(domainId() == 0) {
4300 cerr << "error rotation omega " << k << " " << i << " " << tq0[i] << " " << tq[i] << " " << q[i] << " ("
4301 << m_bodyTorque[k * 3 + 0] << "," << m_bodyTorque[k * 3 + 1] << "," << m_bodyTorque[k * 3 + 2] << ")"
4302 << endl;
4303 }
4304 if(std::isnan(tq0[i])) tq0[i] = F0;
4305 tq[i] = tq0[i];
4306 q[i] = q0[i];
4307 // mTerm(1,AT_, "Solution diverged at body rotational integration (omega).");
4308 }
4309 }
4310
4311 const MInt maxit = 100;
4312 MFloat delta = F1;
4313 MInt it = 0;
4314
4315 // Newton iterations
4316 while(delta > 1e-10 && it < maxit) {
4317 W(0, 0) = F1;
4318 W(0, 1) = dt2 * q[2] * f0;
4319 W(0, 2) = dt2 * q[1] * f0;
4320 W(1, 0) = dt2 * q[2] * f1;
4321 W(1, 1) = F1;
4322 W(1, 2) = dt2 * q[0] * f1;
4323 W(2, 0) = dt2 * q[1] * f2;
4324 W(2, 1) = dt2 * q[0] * f2;
4325 W(2, 2) = F1;
4326
4327 maia::math::invert(W, iW, 3, 3);
4328
4329 for(MInt i = 0; i < 3; i++)
4330 rhs[i] = q[i] - q0[i] - dt2 * (tq0[i] + tq[i]) / momi[i];
4331 rhs[0] += dt2 * f0 * (q0[1] * q0[2] + q[1] * q[2]);
4332 rhs[1] += dt2 * f1 * (q0[0] * q0[2] + q[0] * q[2]);
4333 rhs[2] += dt2 * f2 * (q0[0] * q0[1] + q[0] * q[1]);
4334 delta = F0;
4335 for(MInt i = 0; i < 3; i++) {
4336 const MFloat qq = q[i];
4337 for(MInt j = 0; j < 3; j++) {
4338 q[i] -= iW(i, j) * rhs(j);
4339 }
4340 delta = mMax(delta, fabs(q[i] - qq));
4341 }
4342 it++;
4343 }
4344 if(it >= maxit && domainId() == 0) {
4345 cerr << "Newton iterations did not converge " << k << endl;
4346 }
4347
4348 for(MInt i = 0; i < 3; i++) {
4349 if(std::isnan(q[i])) {
4350 if(domainId() == 0) {
4351 cerr << "error rotation quaternion " << k << " " << i << " " << q[i] << endl;
4352 cerr << q[0] << " " << q[1] << " " << q[2] << " " << endl;
4353 cerr << tq0[0] << " " << tq0[1] << " " << tq0[2] << endl;
4354 cerr << tq[0] << " " << tq[1] << " " << tq[2] << endl;
4355 }
4356 // MPI_Barrier(mpiComm(), AT_ );
4357 // mTerm(1,AT_, "Solution diverged at body rotational integration (quaternion)" + to_string(q[i]) );
4358 q[i] = q0[i];
4359 }
4360 }
4361
4362
4363 W(0, 0) = F0;
4364 W(0, 1) = -q[0];
4365 W(0, 2) = -q[1];
4366 W(0, 3) = -q[2];
4367 W(1, 0) = q[0];
4368 W(1, 1) = F0;
4369 W(1, 2) = q[2];
4370 W(1, 3) = -q[1];
4371 W(2, 0) = q[1];
4372 W(2, 1) = -q[2];
4373 W(2, 2) = F0;
4374 W(2, 3) = q[0];
4375 W(3, 0) = q[2];
4376 W(3, 1) = q[1];
4377 W(3, 2) = -q[0];
4378 W(3, 3) = F0;
4379 for(MInt i = 0; i < 4; i++)
4380 for(MInt j = 0; j < 4; j++)
4381 W(i, j) = -F1B2 * dt2 * W(i, j);
4382 for(MInt i = 0; i < 4; i++)
4383 W(i, i) = F1;
4384
4385 rhs(0) = w + F1B2 * dt2 * (-x * q0[0] - y * q0[1] - z * q0[2]);
4386 rhs(1) = x + F1B2 * dt2 * (w * q0[0] - z * q0[1] + y * q0[2]);
4387 rhs(2) = y + F1B2 * dt2 * (z * q0[0] + w * q0[1] - x * q0[2]);
4388 rhs(3) = z + F1B2 * dt2 * (-y * q0[0] + x * q0[1] + w * q0[2]);
4389
4390 maia::math::invert(W, iW, 4, 4);
4391
4392 for(MInt i = 0; i < 4; i++) {
4393 m_bodyQuaternion[4 * k + i] = F0;
4394 for(MInt j = 0; j < 4; j++) {
4395 m_bodyQuaternion[4 * k + i] += iW(i, j) * rhs(j);
4396 }
4397 }
4398
4399 MFloat abs = F0;
4400 for(MInt i = 0; i < 4; i++)
4401 abs += POW2(m_bodyQuaternion[4 * k + i]);
4402 for(MInt i = 0; i < 4; i++)
4403 m_bodyQuaternion[4 * k + i] /= sqrt(abs);
4404
4405
4407 matrixVectorProductTranspose(tmp, R, &(q[0]));
4408
4409 for(MInt i = 0; i < 3; i++) {
4410 if(m_fixedBodyComponentsRotation[i]) continue;
4411 m_bodyAngularVelocity[k * 3 + i] = tmp[i];
4412 }
4413 for(MInt i = 0; i < 3; i++) {
4414 tmp[i] = (q[i] - q0[i]) / timeStep();
4415 }
4416 matrixVectorProductTranspose(tmp2, R, &(tmp[0]));
4417 for(MInt i = 0; i < 3; i++) {
4418 if(m_fixedBodyComponentsRotation[i]) continue;
4419 m_bodyAngularAcceleration[k * 3 + i] = tmp2[i];
4420 }
4421 }
4422
4423 recvDispl(0) = 0;
4424 for(MInt i = 0; i < noDomains(); i++) {
4425 recvDispl(i + 1) = 4 * bodyOffsets(i + 1);
4426 recvCnt(i) = recvDispl(i + 1) - recvDispl(i);
4427 }
4428 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, m_bodyQuaternion, &recvCnt[0], &recvDispl[0], MPI_DOUBLE,
4429 mpiComm(), AT_, "MPI_IN_PLACE", "m_bodyQuaternion");
4430
4431 recvDispl(0) = 0;
4432 for(MInt i = 0; i < noDomains(); i++) {
4433 recvDispl(i + 1) = 3 * bodyOffsets(i + 1);
4434 recvCnt(i) = recvDispl(i + 1) - recvDispl(i);
4435 }
4436 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, m_bodyAngularVelocity, &recvCnt[0], &recvDispl[0], MPI_DOUBLE,
4437 mpiComm(), AT_, "MPI_IN_PLACE", "m_bodyAngularVelocity");
4438 MPI_Allgatherv(MPI_IN_PLACE, 0, MPI_DATATYPE_NULL, m_bodyAngularAcceleration, &recvCnt[0], &recvDispl[0], MPI_DOUBLE,
4439 mpiComm(), AT_, "MPI_IN_PLACE", "m_bodyAngularAcceleration");
4440}
int MPI_Allgatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgatherv

◆ interpolateGapBodyVelocity()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::interpolateGapBodyVelocity
Author
Tim Wegmann

Definition at line 17995 of file fvmbcartesiansolverxd.cpp.

17995 {
17996 ASSERT(!m_deleteNeighbour, "");
17997
17998 std::function<MBool(const MInt, const MInt)> alwaysTrue = [&](const MInt, const MInt) { return true; };
17999
18000 for(MUint it = 0; it < m_gapCells.size(); it++) {
18001 const MInt cellId = m_gapCells[it].cellId;
18002 const MInt bndryId = a_bndryId(cellId);
18003 if(bndryId < 0) continue;
18004
18005 MInt gridCellId = cellId;
18006 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
18007 gridCellId = getAssociatedInternalCell(cellId);
18008 }
18009 const MInt regionId = m_gapCells[it].region;
18010 if(m_gapInitMethod > 0 && regionId != m_noGapRegions) continue;
18011
18012 const MInt body1 = a_associatedBodyIds(gridCellId, 0);
18013
18014 for(MInt i = 0; i < nDim; i++) {
18015 m_gapCells[it].surfaceVelocity[i] = m_bodyVelocity[body1 * nDim + i];
18016 }
18017
18018 const MInt body2 = m_gapCells[it].bodyIds[1];
18019 ASSERT(m_gapCells[it].bodyIds[0] == body1, "");
18020 if(body2 == -1) continue;
18021
18022 MFloat vel1 = F0;
18023 MFloat vel2 = F0;
18024 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
18025 this->setUpInterpolationStencil(gridCellId, interpolationCells, m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates,
18026 alwaysTrue, false);
18027
18028 const MFloat dist1 = interpolateLevelSet(interpolationCells, m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates,
18029 m_bodyToSetTable[body1]);
18030
18031 const MFloat dist2 = interpolateLevelSet(interpolationCells, m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates,
18032 m_bodyToSetTable[body2]);
18033
18034 for(MInt i = 0; i < nDim; i++) {
18035 vel1 += m_bodyVelocity[body1 * nDim + i] * m_bodyVelocity[body1 * nDim + i];
18036 vel2 += m_bodyVelocity[body2 * nDim + i] * m_bodyVelocity[body2 * nDim + i];
18037 }
18038
18039 MInt fixedBody = body1;
18040 MInt movingBody = body2;
18041 MFloat distFixed = dist1;
18042
18043 // use the more stationary velocity!
18044 if(m_gapInitMethod > 0 && vel1 < vel2) {
18045 continue;
18046 } else if(m_gapInitMethod > 0) {
18047 for(MInt i = 0; i < nDim; i++) {
18048 m_gapCells[it].surfaceVelocity[i] = m_bodyVelocity[body2 * nDim + i];
18049 }
18050 continue;
18051 }
18052
18053 if(vel1 > vel2) {
18054 fixedBody = body2;
18055 movingBody = body1;
18056 distFixed = dist2;
18057 }
18058
18059 MFloat F = distFixed / (2.0 * c_cellLengthAtLevel(m_lsCutCellBaseLevel));
18060 if(F < F0) F = F0;
18061 if(F > 1.0) F = 1.0;
18062
18063 // velocity interpolation in the cells close to both boundaries
18064 for(MInt i = 0; i < nDim; i++) {
18065 m_gapCells[it].surfaceVelocity[i] =
18066 (F * m_bodyVelocity[movingBody * nDim + i] + (1 - F) * m_bodyVelocity[fixedBody * nDim + i]);
18067 }
18068 }
18069}

◆ interpolateLevelSet()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::interpolateLevelSet ( MInt interpolationCells,
MFloat point,
MInt  referenceSet 
)
Author
Claudia Guenther
Date
03/2012

Definition at line 18078 of file fvmbcartesiansolverxd.cpp.

18079 {
18080 TRACE();
18081
18082 std::function<MFloat(const MInt, const MInt)> scalarField = [&](const MInt cellId, const MInt set) {
18083 return static_cast<MFloat>(a_levelSetValuesMb(cellId, set));
18084 };
18085
18086 std::function<MFloat(const MInt, const MInt)> coordinate = [&](const MInt cellId, const MInt id) {
18087 return static_cast<MFloat>(c_coordinate(cellId, id));
18088 };
18089
18090 return this->template interpolateFieldData<true>(&interpolationCells[0], &point[0], referenceSet, scalarField,
18091 coordinate);
18092}

◆ inverseGJ()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::inverseGJ
Author
Daniel Hartmann
Note
adapted to dxd system (Lennart Schneiders)

Definition at line 11983 of file fvmbcartesiansolverxd.cpp.

11983 {
11984 const MFloat epsilon = 1e-12;
11985 MBool error;
11986 MInt s, pRow; // pivot row
11987 MFloat f, h, maximum;
11988
11989 // add the unity matrix
11990 for(MInt i = 0; i < nDim; i++) {
11991 for(MInt j = 0; j < nDim; j++) {
11992 m_A[i][nDim + j] = F0;
11993 }
11994 m_A[i][nDim + i] = F1;
11995 }
11996
11997 // Gauss algorithm
11998 error = false;
11999 s = 0;
12000 while(s < nDim) {
12001 maximum = fabs(m_A[s][s]);
12002 pRow = s;
12003 for(MInt i = s + 1; i < nDim; i++) {
12004 if(fabs(m_A[i][s]) > maximum) {
12005 maximum = fabs(m_A[i][s]);
12006 pRow = i;
12007 }
12008 }
12009
12010 if(maximum < epsilon) {
12011 error = true;
12012 break;
12013 }
12014
12015 if(pRow != s) { // exchange rows if required
12016 for(MInt j = s; j < 2 * nDim; j++) {
12017 h = m_A[s][j];
12018 m_A[s][j] = m_A[pRow][j];
12019 m_A[pRow][j] = h;
12020 }
12021 }
12022
12023 f = m_A[s][s];
12024 for(MInt j = s; j < 2 * nDim; j++)
12025 m_A[s][j] /= f;
12026
12027 // elimination
12028 for(MInt i = 0; i < nDim; i++) {
12029 if(i != s) {
12030 f = -m_A[i][s];
12031 for(MInt j = s; j < 2 * nDim; j++)
12032 m_A[i][j] += f * m_A[s][j];
12033 }
12034 }
12035 s++;
12036 }
12037
12038 if(error) {
12039 cerr << "Domain " << domainId() << endl;
12040 cerr << "Error in GJ matrix inverse computation " << s << " " << m_A[s][s] << endl;
12041 for(MInt i = 0; i < nDim; i++) {
12042 for(MInt j = 0; j < nDim; j++) {
12043 cerr << m_A[i][j] << " ";
12044 }
12045 cerr << endl;
12046 }
12047 cerr << endl;
12048 return -1;
12049 }
12050 return 0;
12051}

◆ isNan()

template<MInt nDim, class SysEqn >
template<typename T >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::isNan ( val)
inline
Author

Definition at line 13312 of file fvmbcartesiansolverxd.cpp.

13312 {
13313 return (std::isnan(val) || std::isinf(val));
13314}

◆ leastSquaresReconstruction()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::leastSquaresReconstruction
Author
Lennart Schneiders
Date
28.10.2011

Definition at line 17504 of file fvmbcartesiansolverxd.cpp.

17504 {
17505 TRACE();
17506 TERMM_IF_COND(m_reConstSVDWeightMode == 3 || m_reConstSVDWeightMode == 4, "Not yet implemented!");
17507
17508 MFloat* RESTRICT slope = (MFloat*)(&(a_slope(0, 0, 0)));
17509 MFloat* RESTRICT vars = (MFloat*)(&(a_pvariable(0, 0)));
17510 const MInt noCells = a_noCells();
17511
17512 std::fill_n(slope, noCells * m_noSlopes, 0.0);
17513
17514#ifdef _OPENMP
17515#pragma omp parallel for
17516#endif
17517 for(MInt cellId = 0; cellId < noCells; cellId++) {
17518 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) {
17519 continue;
17520 }
17521 if(a_isBndryGhostCell(cellId)) {
17522 continue;
17523 }
17524 if(a_hasProperty(cellId, SolverCell::IsInactive)) {
17525 continue;
17526 }
17527
17528 const MInt k = m_noSlopes * cellId;
17529 const MInt offset = nDim * a_reconstructionData(cellId);
17530 for(MInt n = a_noReconstructionNeighbors(cellId); n--;) {
17531 for(MInt v = 0; v < m_noPVars; v++) {
17532 IF_CONSTEXPR(nDim == 3) {
17533#ifdef _OPENMP
17534#pragma omp atomic
17535#endif
17536 slope[k + nDim * v + 2] +=
17537 m_reconstructionConstants[offset + n * nDim + 2]
17538 * (vars[m_noPVars * a_reconstructionNeighborId(cellId, n) + v] - vars[m_noPVars * cellId + v]);
17539 }
17540#ifdef _OPENMP
17541#pragma omp atomic
17542#endif
17543 slope[k + nDim * v + 1] +=
17544 m_reconstructionConstants[offset + n * nDim + 1]
17545 * (vars[m_noPVars * a_reconstructionNeighborId(cellId, n) + v] - vars[m_noPVars * cellId + v]);
17546#ifdef _OPENMP
17547#pragma omp atomic
17548#endif
17549 slope[k + nDim * v] +=
17550 m_reconstructionConstants[offset + n * nDim]
17551 * (vars[m_noPVars * a_reconstructionNeighborId(cellId, n) + v] - vars[m_noPVars * cellId + v]);
17552 }
17553 }
17554 }
17555
17557 return;
17558 }
17559
17560 MBoolScratchSpace atBnd(noCells, AT_, "atBnd");
17561 MBoolScratchSpace nearBnd(noCells, AT_, "nearBnd");
17562 atBnd.fill(false);
17563 nearBnd.fill(false);
17564 array<MFloat, 20> centralDiffConst;
17565 std::vector<std::vector<MInt>> structuredCells(maxLevel() - minLevel() + 1);
17566 std::vector<MInt> nearBoundaryCells;
17567
17568 for(MInt level = minLevel(); level <= maxLevel(); level++) {
17569 structuredCells[level - minLevel()].clear();
17570 }
17571
17572 for(MInt level = minLevel(); level <= maxRefinementLevel(); level++) {
17573 centralDiffConst[level] = 1.0 / (2.0 * c_cellLengthAtLevel(level));
17574 }
17575
17576#ifdef _OPENMP
17577#pragma omp parallel for
17578#endif
17579 for(MInt bndryId = 0; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
17580 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
17581 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
17582 continue;
17583 }
17584
17585 atBnd(cellId) = true;
17586 MInt parentId = a_hasProperty(cellId, SolverCell::IsSplitChild) ? c_parentId(getAssociatedInternalCell(cellId))
17587 : c_parentId(cellId);
17588 while(parentId > -1) {
17589 atBnd(parentId) = true;
17590 parentId = c_parentId(parentId);
17591 }
17592 }
17593
17594#ifdef _OPENMP
17595#pragma omp parallel for
17596#endif
17597 for(MInt cellId = 0; cellId < noCells; cellId++) {
17598 if(a_bndryId(cellId) < -1) continue;
17599 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
17600 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17601 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
17602 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17603
17604 if(atBnd(cellId)) {
17605 nearBoundaryCells.push_back(cellId);
17606 nearBnd(cellId) = true;
17607 continue;
17608 }
17609 MBool nearb = false;
17610 for(MInt dir = 0; dir < m_noDirs; dir++) {
17611 if(!a_hasNeighbor(cellId, dir)) {
17612 MInt parentId = c_parentId(cellId);
17613 while(parentId > -1) {
17614 if(a_hasNeighbor(parentId, dir)) {
17615 if(atBnd(c_neighborId(parentId, dir))) {
17616 nearb = true;
17617 }
17618 break;
17619 }
17620 parentId = c_parentId(parentId);
17621 }
17622 } else if(atBnd(c_neighborId(cellId, dir))) {
17623 nearb = true;
17624 break;
17625 }
17626 }
17627 if(nearb) {
17628 nearBoundaryCells.push_back(cellId);
17629 nearBnd(cellId) = true;
17630 continue;
17631 }
17632 }
17633
17634#ifdef _OPENMP
17635#pragma omp parallel for
17636#endif
17637 for(MInt cellId = 0; cellId < noCells; cellId++) {
17638 if(a_bndryId(cellId) != -1) continue;
17639 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
17640 if(nearBnd(cellId)) continue;
17641 if(!c_isLeafCell(cellId)) continue;
17642 if(a_hasProperty(cellId, SolverCell::IsInactive)) {
17643 nearBnd(cellId) = true;
17644 MInt parentId = c_parentId(cellId);
17645 while(parentId > -1) {
17646 nearBnd(parentId) = true;
17647 parentId = c_parentId(parentId);
17648 }
17649 }
17650 }
17651
17652 for(MInt level = minLevel(); level <= maxLevel(); level++) {
17653 structuredCells[level - minLevel()].clear();
17654 }
17655#ifdef _OPENMP
17656#pragma omp parallel for
17657#endif
17658 for(MInt cellId = 0; cellId < noCells; cellId++) {
17659 if(a_bndryId(cellId) < -1) continue;
17660 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
17661 if(nearBnd(cellId)) continue;
17662 if(a_hasProperty(cellId, SolverCell::AtStructuredRegion)) {
17663 structuredCells[c_level(cellId) - minLevel()].push_back(cellId);
17664 }
17665 }
17666
17667#ifdef _OPENMP
17668#pragma omp parallel for
17669#endif
17670 // TODO labels:FVMB this is just debug and should only be applied for debug-compilation
17671 for(MInt cellId = 0; cellId < noCells; cellId++) {
17672 if(a_bndryId(cellId) < -1) continue;
17673 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
17674 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17675 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
17676 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17677 if(!a_hasProperty(cellId, SolverCell::AtStructuredRegion) && !nearBnd(cellId)
17678 && !(c_parentId(cellId) > -1 && a_hasProperty(c_parentId(cellId), SolverCell::AtStructuredRegion)))
17679 cerr << "strng " << c_globalId(cellId) << " " << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << " "
17680 << a_hasProperty(cellId, Cell::IsHalo) << " " << c_neighborId(cellId, 0) << " " << c_neighborId(cellId, 1)
17681 << " " << c_neighborId(cellId, 2) << " " << c_neighborId(cellId, 3) << endl;
17682 ASSERT(a_hasProperty(cellId, SolverCell::AtStructuredRegion) || nearBnd(cellId)
17683 || (c_parentId(cellId) > -1 && a_hasProperty(c_parentId(cellId), SolverCell::AtStructuredRegion)),
17684 to_string(c_globalId(cellId)));
17685 }
17686
17687
17688 for(MInt level = minLevel(); level <= maxRefinementLevel(); level++) {
17689 const MFloat fdx = centralDiffConst[level];
17690 for(MUint c = 0; c < structuredCells[level - minLevel()].size(); c++) {
17691 MInt cellId = structuredCells[level - minLevel()][c];
17692 const MInt k = m_noSlopes * cellId;
17693 for(MInt i = 0; i < nDim; i++) {
17694 MInt n0 = c_neighborId(cellId, 2 * i);
17695 MInt n1 = c_neighborId(cellId, 2 * i + 1);
17696 ASSERT(!atBnd(n0) && !atBnd(n1) && !nearBnd(cellId), "");
17697 for(MInt v = 0; v < m_noPVars; v++) {
17698 slope[k + nDim * v + i] = fdx * (a_pvariable(n1, v) - a_pvariable(n0, v));
17699 }
17700 }
17701 if(!c_isLeafCell(cellId)) {
17702 for(MInt child = 0; child < m_noCellNodes; child++) {
17703 const MInt childId = c_childId(cellId, child);
17704 if(childId < 0) continue;
17705 if(a_hasProperty(childId, SolverCell::AtStructuredRegion)) continue;
17706 for(MInt i = 0; i < nDim; i++) {
17707 for(MInt v = 0; v < m_noPVars; v++) {
17708 a_slope(childId, v, i) = a_slope(cellId, v, i);
17709 }
17710 }
17711 }
17712 }
17713 }
17714 }
17715
17716#ifdef _OPENMP
17717#pragma omp parallel for
17718#endif
17719 for(MInt cellId = noCells; cellId > 0; cellId--) {
17720 if(!nearBnd(cellId)) continue;
17721
17722 const MInt k = m_noSlopes * cellId;
17723 const MInt offset = nDim * a_reconstructionData(cellId);
17724 std::fill_n(&slope[k], m_noPVars * nDim, F0);
17725 for(MInt n = a_noReconstructionNeighbors(cellId); n--;) {
17726 for(MInt v = m_noPVars; v--;) {
17727 IF_CONSTEXPR(nDim == 3) {
17728#ifdef _OPENMP
17729#pragma omp atomic
17730#endif
17731 slope[k + nDim * v + 2] +=
17732 m_reconstructionConstants[offset + n * nDim + 2]
17733 * (vars[m_noPVars * a_reconstructionNeighborId(cellId, n) + v] - vars[m_noPVars * cellId + v]);
17734 }
17735#ifdef _OPENMP
17736#pragma omp atomic
17737#endif
17738 slope[k + nDim * v + 1] +=
17739 m_reconstructionConstants[offset + n * nDim + 1]
17740 * (vars[m_noPVars * a_reconstructionNeighborId(cellId, n) + v] - vars[m_noPVars * cellId + v]);
17741#ifdef _OPENMP
17742#pragma omp atomic
17743#endif
17744 slope[k + nDim * v] +=
17745 m_reconstructionConstants[offset + n * nDim]
17746 * (vars[m_noPVars * a_reconstructionNeighborId(cellId, n) + v] - vars[m_noPVars * cellId + v]);
17747 }
17748 }
17749 }
17750
17751#ifndef NDEBUG
17752 static constexpr MBool test1 = false;
17753 static constexpr MBool test2 = false;
17754
17755 // TEST1
17756 if(test1) {
17757 // also central differences when only possible in single direction
17758 for(MInt level = minLevel(); level <= maxRefinementLevel(); level++) {
17759 for(MInt cellId = noCells; cellId--;) {
17760 if(atBnd(cellId)) continue;
17761 if(nearBnd(cellId)) continue;
17762 if(a_bndryId(cellId) < -1) continue;
17763 if(a_hasProperty(cellId, SolverCell::AtStructuredRegion)) continue;
17764 // MInt level = c_level(cellId);
17765 if(level != c_level(cellId)) continue;
17766 const MFloat fdx = centralDiffConst[level];
17767 const MInt k = m_noSlopes * cellId;
17768 for(MInt i = 0; i < nDim; i++) {
17769 MInt n0 = c_neighborId(cellId, 2 * i);
17770 MInt n1 = c_neighborId(cellId, 2 * i + 1);
17771 if(n0 > -1 && n1 > -1) {
17772 if(!atBnd(n0) && !atBnd(n1)) {
17773 ASSERT(!atBnd(n0) && !atBnd(n1) && !nearBnd(cellId), "");
17774 for(MInt v = 0; v < m_noPVars; v++) {
17775 slope[k + nDim * v + i] = fdx * (a_pvariable(n1, v) - a_pvariable(n0, v));
17776 // a_slope( cellId, v, i ) = fdx * ( a_pvariable(n1,v) - a_pvariable(n0,v) );
17777 }
17778
17779 if(!c_isLeafCell(cellId)) {
17780 for(MInt child = 0; child < m_noCellNodes; child++) {
17781 MInt childId = c_childId(cellId, child);
17782 if(childId < 0) continue;
17783 if(a_hasProperty(childId, SolverCell::AtStructuredRegion)) continue;
17784 for(MInt v = 0; v < m_noPVars; v++) {
17785 a_slope(childId, v, i) = a_slope(cellId, v, i);
17786 }
17787 }
17788 }
17789 }
17790 }
17791 }
17792 }
17793 }
17794 }
17795
17796 // TEST2
17797 if(test2) {
17798 // fine to coarse interace use least squares
17799 for(MInt cellId = noCells; cellId--;) {
17800 if(atBnd(cellId)) continue;
17801 if(nearBnd(cellId)) continue;
17802 if(a_bndryId(cellId) < -1) continue;
17803 if(!a_hasProperty(cellId, SolverCell::AtStructuredRegion)) continue;
17804 if(!c_isLeafCell(cellId)) {
17805 for(MInt child = 0; child < m_noCellNodes; child++) {
17806 MInt childId = c_childId(cellId, child);
17807 if(childId < 0) continue;
17808 if(a_hasProperty(childId, SolverCell::AtStructuredRegion)) continue;
17809
17810 const MInt k = m_noSlopes * childId;
17811 // const MInt offset = nDim * m_cells.noRecNghbrs() * childId;
17812 const MInt offset = nDim * a_reconstructionData(childId);
17813 std::fill_n(&slope[k], m_noPVars * nDim, F0);
17814 for(MInt n = a_noReconstructionNeighbors(childId); n--;) {
17815 for(MInt v = m_noPVars; v--;) {
17816 IF_CONSTEXPR(nDim == 3) {
17817 slope[k + nDim * v + 2] +=
17818 m_reconstructionConstants[offset + n * nDim + 2]
17819 * (vars[m_noPVars * a_reconstructionNeighborId(childId, n) + v] - vars[m_noPVars * childId + v]);
17820 }
17821 slope[k + nDim * v + 1] +=
17822 m_reconstructionConstants[offset + n * nDim + 1]
17823 * (vars[m_noPVars * a_reconstructionNeighborId(childId, n) + v] - vars[m_noPVars * childId + v]);
17824 slope[k + nDim * v] +=
17825 m_reconstructionConstants[offset + n * nDim]
17826 * (vars[m_noPVars * a_reconstructionNeighborId(childId, n) + v] - vars[m_noPVars * childId + v]);
17827 }
17828 }
17829 }
17830 }
17831 }
17832 }
17833#endif
17834}

◆ linkBndryCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::linkBndryCells
Author
Lennart Schneiders, extension to triple-Links Update Tim Wegmann

Definition at line 29038 of file fvmbcartesiansolverxd.cpp.

29038 {
29039 TRACE();
29040
29041 if(!m_levelSetMb) return;
29042
29043 ASSERT(m_temporarilyLinkedCells.size() < 1, "");
29044
29045 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
29046 a_hasProperty(cellId, SolverCell::IsTempLinked) = false;
29047 }
29048
29049 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
29050 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
29051 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
29052 if(!a_hasProperty(cellId, SolverCell::WasInactive)) continue;
29053 // a) new boundary cell: was inactive before and is !inactive
29054 // -> emerging BndryCells will be linked
29055
29056 // only link the split parent cell!!
29057 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
29058
29059 // avoid double-linking
29060 if(a_hasProperty(cellId, SolverCell::IsTempLinked)) continue;
29061
29062 // initialise oldVariable, will be resetted below!
29063 for(MInt v = 0; v < m_noCVars; v++) {
29064 a_oldVariable(cellId, v) = F0;
29065 }
29066
29067 // old-version is not linking gapCells!
29068 if(m_levelSet && m_closeGaps && m_gapInitMethod == 0 && a_hasProperty(cellId, SolverCell::WasGapCell)
29069 && !a_hasProperty(cellId, SolverCell::IsGapCell)) {
29070 continue;
29071 }
29072
29073 // Ensure that azimuthal cells are not linked. Otherwise exchange is needed
29074 // Here azimuthal halos are skipped. They are not used in the time step integration
29075 // anyway
29076 if(grid().azimuthalPeriodicity() && a_isPeriodic(cellId)) continue;
29077
29078 // masterId is the the neighbour to the boundary-cell with the largest cell-volume!
29079 MInt masterId = -1;
29080 MInt tripleLink = -1;
29081 MFloat maxVol = F0;
29082 MInt noInternalNghbrs = 0;
29083 MInt noWasActiveNghbrs = 0;
29084 const MInt rootId = cellId;
29085 for(MInt dir = 0; dir < m_noDirs; dir++) {
29086 if(!checkNeighborActive(rootId, dir) || a_hasNeighbor(rootId, dir) == 0) continue;
29087 const MInt nghbrId = c_neighborId(rootId, dir);
29088 if(nghbrId < 0) continue;
29089 if(!a_isHalo(nghbrId)) noInternalNghbrs++;
29090 if(a_hasProperty(nghbrId, SolverCell::WasInactive)) continue;
29091 noWasActiveNghbrs++;
29092 if(a_hasProperty(nghbrId, SolverCell::IsSplitCell)) continue;
29093 if(a_hasProperty(nghbrId, SolverCell::IsSplitChild)) continue;
29094 if(a_cellVolume(nghbrId) > maxVol) {
29095 masterId = nghbrId;
29096 maxVol = a_cellVolume(nghbrId);
29097 }
29098 }
29099
29100
29101 if(a_isHalo(cellId) && noInternalNghbrs == 0) continue;
29102 if(masterId > -1 && a_isHalo(cellId) && a_isHalo(masterId)) continue;
29103
29104 // linking the master-cell and the boundary-cell
29105 //-> copying the masters-variables into the boundary-cell!
29106 if(masterId > -1) {
29107 m_temporarilyLinkedCells.push_back(make_tuple(cellId, masterId, tripleLink));
29108 a_hasProperty(cellId, SolverCell::IsTempLinked) = true;
29109 for(MInt v = 0; v < m_noCVars; v++) {
29110 a_variable(cellId, v) = a_variable(masterId, v);
29111 a_oldVariable(cellId, v) = a_oldVariable(masterId, v);
29112 }
29113 for(MInt v = 0; v < m_noPVars; v++) {
29114 a_pvariable(cellId, v) = a_pvariable(masterId, v);
29115 }
29116
29117 } else { // no-master found
29118
29119 // special treatment for the linking of gapCells
29120 /*
29121 if ( m_levelSet && m_closeGaps && m_gapInitMethod > 0) {
29122 // use levelSet value for masterId determination, so that the same linking is achived on
29123 // all ranks!
29124 MFloat lsValue = -99;
29125 if(m_gapCellId[cellId] > -1){
29126 if(m_gapCells[m_gapCellId[cellId]].status == 22 && false) {
29127 // 1: for initGapOpening
29128 // a) try linking new bndry-Cells(type 22) with arising gap-Cells(type21) in a double-link
29129 for ( MInt dir = 0; dir < m_noDirs; dir++ ) {
29130 if ( !checkNeighborActive (cellId , dir) || a_hasNeighbor(cellId, dir) == 0 )
29131 continue;
29132 MInt nghbrId = c_neighborId( cellId , dir );
29133 if ( nghbrId < 0 ) continue;
29134 if ( a_hasProperty( nghbrId , SolverCell::IsSplitCell ) ) continue;
29135 if ( a_hasProperty( nghbrId , SolverCell::IsSplitChild ) ) continue;
29136 if(m_gapCellId[nghbrId] > -1){
29137 if(m_gapCells[m_gapCellId[nghbrId]].status == 21) {
29138 if(a_levelSetValuesMb(nghbrId, 0) > lsValue) {
29139 masterId = nghbrId;
29140 lsValue = a_levelSetValuesMb(nghbrId, 0);
29141 ASSERT(abs(a_cellVolume(masterId) - grid().gridCellVolume(a_level(cellId))) < 0.00001, "");
29142 }
29143 }
29144 }
29145 }
29146 m_temporarilyLinkedCells.push_back( make_tuple(cellId,masterId, tripleLink) );
29147 a_hasProperty( cellId , SolverCell::IsTempLinked ) = true;
29148 for ( MInt v = 0; v < m_noVars; v++ ) {
29149 a_variable( cellId , v ) = a_variable( masterId , v );
29150 a_oldVariable( cellId , v ) = a_oldVariable( masterId , v );
29151 a_pvariable( cellId , v ) =a_pvariable( masterId , v );
29152 }
29153
29154 if(masterId < 0 ) {
29155 //b) if this is not working create a triple-link
29156 // so first find the direct neighbor with the largest cellVolume
29157 // and second, its masterId which should be an arising gap-Cell and
29158 // finish by creating the triple-link !
29159 maxVol = F0;
29160 lsValue = -99;
29161 //cerr << "Searching neighbor for " << c_globalId(cellId) << endl;
29162 for ( MInt dir = 0; dir < m_noDirs; dir++ ) {
29163 if ( !checkNeighborActive (cellId , dir) || a_hasNeighbor(cellId, dir) == 0 )
29164 continue;
29165 MInt nghbrId = c_neighborId( cellId , dir );
29166 if ( nghbrId < 0 ) continue;
29167 if ( a_hasProperty( nghbrId , SolverCell::IsSplitCell ) ) continue;
29168 if ( a_hasProperty( nghbrId , SolverCell::IsSplitChild ) ) continue;
29169 if ( a_cellVolume( nghbrId ) > maxVol ) {
29170 tripleLink = nghbrId;
29171 maxVol = a_cellVolume( nghbrId );
29172 }
29173 }
29174 if(tripleLink > 0) {
29175 if(a_isHalo(tripleLink)) {
29176
29177 }
29178
29179
29180 //cerr << " Using neighbor " << c_globalId(tripleLink) << endl;
29181 if(a_hasProperty( tripleLink , SolverCell::IsTempLinked )) {
29182 //tripleLink already has a singe-link
29183 MUint it = m_temporarilyLinkedCells.size();
29184 for( MUint it2 = 0; it2 < m_temporarilyLinkedCells.size(); it2++){
29185 if(get<0>(m_temporarilyLinkedCells[it2]) == tripleLink ) {
29186 it = it2;
29187 break;
29188 }
29189 }
29190 ASSERT(it < m_temporarilyLinkedCells.size(), "");
29191 masterId = get<1>(m_temporarilyLinkedCells[it]);
29192 //cerr << " Reusing masterId " << c_globalId(masterId) << endl;
29193 //replace the masterId, and link the two smaller cells with each other!
29194 m_temporarilyLinkedCells.erase(m_temporarilyLinkedCells.begin()+it);
29195 m_temporarilyLinkedCells.push_back( make_tuple(cellId,masterId, tripleLink) );
29196 a_hasProperty( cellId , SolverCell::IsTempLinked ) = true;
29197 for ( MInt v = 0; v < m_noVars; v++ ) {
29198 a_variable( cellId , v ) = a_variable( masterId , v );
29199 a_oldVariable( cellId , v ) = a_oldVariable( masterId , v );
29200 a_pvariable( cellId , v ) =a_pvariable( masterId , v );
29201 }
29202
29203 } else {
29204 // tipleCellId doesn't have a link on this domain yet
29205 // now, due the same procedure from the top
29206 // So firt try to find the largest wasactive neighbor,
29207 // and othwise the gapCell-Neigbor with the largest ls-Value
29208 lsValue = -99;
29209 maxVol = F0;
29210 for ( MInt dir = 0; dir < m_noDirs; dir++ ) {
29211 if ( !checkNeighborActive (rootId , dir) || a_hasNeighbor( rootId , dir ) == 0 ) continue;
29212 const MInt nghbrId = c_neighborId( rootId , dir );
29213 if ( nghbrId < 0 ) continue;
29214 if ( a_hasProperty( nghbrId , SolverCell::WasInactive ) ) continue;
29215 if ( a_hasProperty( nghbrId , SolverCell::IsSplitCell ) ) continue;
29216 if ( a_hasProperty( nghbrId , SolverCell::IsSplitChild ) ) continue;
29217 if ( a_cellVolume( nghbrId ) > maxVol ) {
29218 masterId = nghbrId;
29219 maxVol = a_cellVolume( nghbrId );
29220 }
29221 }
29222 if (masterId < 0) {
29223 for ( MInt dir = 0; dir < m_noDirs; dir++ ) {
29224 if ( !checkNeighborActive (cellId , dir) || a_hasNeighbor(cellId, dir) == 0 )
29225 continue;
29226 MInt nghbrId = c_neighborId( tripleLink , dir );
29227 if ( nghbrId < 0 ) continue;
29228 if ( a_hasProperty( nghbrId , SolverCell::IsSplitCell ) ) continue;
29229 if ( a_hasProperty( nghbrId , SolverCell::IsSplitChild ) ) continue;
29230 if(m_gapCellId[nghbrId] > -1){
29231 if(m_gapCells[m_gapCellId[nghbrId]].status == 21) {
29232 if(a_levelSetValuesMb(nghbrId, 0) > lsValue) {
29233 masterId = nghbrId;
29234 lsValue = a_levelSetValuesMb(nghbrId, 0);
29235 ASSERT(abs(a_cellVolume(masterId) - grid().gridCellVolume(a_level(cellId))) < 0.00001, "");
29236 }
29237 }
29238 }
29239 }
29240 }
29241 if(masterId < 0) {
29242 cerr << "WTF, still no master found?! " << endl;
29243 }
29244 //cerr << " Using masterId " << c_globalId(masterId) << endl;
29245 if( a_isHalo( cellId ) && a_isHalo(masterId) && a_isHalo(tripleLink)) continue;
29246 m_temporarilyLinkedCells.push_back( make_tuple(cellId,masterId, tripleLink) );
29247 a_hasProperty( cellId , SolverCell::IsTempLinked ) = true;
29248 a_hasProperty( tripleLink , SolverCell::IsTempLinked ) = true;
29249 for ( MInt v = 0; v < m_noVars; v++ ) {
29250 a_variable( cellId , v ) = a_variable( masterId , v );
29251 a_oldVariable( cellId , v ) = a_oldVariable( masterId , v );
29252 a_pvariable( cellId , v ) =a_pvariable( masterId , v );
29253
29254 a_variable(tripleLink, v ) = a_variable( masterId , v );
29255 a_oldVariable(tripleLink, v ) = a_oldVariable( masterId , v );
29256 a_pvariable(tripleLink, v ) =a_pvariable( masterId , v );
29257 }
29258 }
29259 }
29260 }
29261
29262 } else if (m_gapCells[m_gapCellId[cellId]].status == 13) {
29263 cerr << "Unlinked new bndry-Cell " << c_globalId(cellId) << endl;
29264 continue;
29265
29266 cerr << "Searching neighbor for " << c_globalId(cellId) << endl;
29267 // 2: for partial gapOpening at gapWidening
29268 // this is nesessary for new bndry-cells, where only the diagonal neighbor wasactive before
29269 // in order to avoid triple-linking the cells without a direct neighbor that wasactive
29270 // are linked to a neighbor that was inactive before!
29271 maxVol = F0;
29272 MInt largestNeighbor = F0;
29273 for ( MInt dir = 0; dir < m_noDirs; dir++ ) {
29274 if ( !checkNeighborActive (cellId , dir) || a_hasNeighbor(cellId, dir) == 0 )
29275 continue;
29276 MInt nghbrId = c_neighborId( cellId , dir );
29277 if ( nghbrId < 0 ) continue;
29278 if ( a_hasProperty( nghbrId , SolverCell::IsSplitCell ) ) continue;
29279 if ( a_hasProperty( nghbrId , SolverCell::IsSplitChild ) ) continue;
29280 if ( a_cellVolume( nghbrId ) > maxVol ) {
29281 largestNeighbor = nghbrId;
29282 maxVol = a_cellVolume( nghbrId );
29283 }
29284 }
29285 //must have at least on acvive neighbor
29286 ASSERT(largestNeighbor > 0, "");
29287 //if the largest neighbor would have been active before, a regular link would have
29288 // been possible
29289 ASSERT(a_hasProperty(largestNeighbor, SolverCell::WasInactive), "");
29290
29291 if(a_hasProperty( largestNeighbor , SolverCell::IsTempLinked )) {
29292
29293
29294 }
29295
29296
29297 if(masterId > 0) {
29298 cerr << "Creating single-link" << endl;
29299 cerr << "Found unlinked neighbor " << c_globalId(masterId) << endl;
29300 tripleLink = -1;
29301 if ( masterId > -1 && a_isHalo( cellId ) && a_isHalo(masterId) ) continue;
29302 m_temporarilyLinkedCells.push_back( make_tuple(cellId,masterId, tripleLink) );
29303 a_hasProperty( cellId , SolverCell::IsTempLinked ) = true;
29304 for ( MInt v = 0; v < m_noVars; v++ ) {
29305 a_variable( cellId , v ) = a_variable( masterId , v );
29306 a_oldVariable( cellId , v ) = a_oldVariable( masterId , v );
29307 a_pvariable( cellId , v ) =a_pvariable( masterId , v );
29308 }
29309 } else if(masterId < 0 && tripleLink > -1 ) {
29310 cerr << "Creating triple-Link" << endl;
29311 cerr << " Using neighbor " << c_globalId(tripleLink) << endl;
29312 if(a_hasProperty( tripleLink , SolverCell::IsTempLinked )) {
29313 //tripleLink already has a singe-link
29314 MUint it = m_temporarilyLinkedCells.size();
29315 for( MUint it2 = 0; it2 < m_temporarilyLinkedCells.size(); it2++){
29316 if(get<0>(m_temporarilyLinkedCells[it2]) == tripleLink ) {
29317 it = it2;
29318 break;
29319 }
29320 }
29321 if(it == m_temporarilyLinkedCells.size()){
29322 cerr << "tripleLink is already part of a triple Link " << endl;
29323 }
29324 masterId = get<1>(m_temporarilyLinkedCells[it]);
29325 cerr << " Reusing masterId " << c_globalId(masterId) << endl;
29326 m_temporarilyLinkedCells.erase(m_temporarilyLinkedCells.begin()+it );
29327 m_temporarilyLinkedCells.push_back( make_tuple(cellId,masterId, tripleLink) );
29328 a_hasProperty( cellId , SolverCell::IsTempLinked ) = true;
29329 for ( MInt v = 0; v < m_noVars; v++ ) {
29330 a_variable( cellId , v ) = a_variable( masterId , v );
29331 a_oldVariable( cellId , v ) = a_oldVariable( masterId , v );
29332 a_pvariable( cellId , v ) =a_pvariable( masterId , v );
29333 }
29334
29335 } else {
29336 //tipleCellId doesn't have a link yet
29337 maxVol = F0;
29338 for ( MInt dir = 0; dir < m_noDirs; dir++ ) {
29339 if ( !checkNeighborActive (tripleLink , dir) ||
29340 a_hasNeighbor(tripleLink, dir) == 0 ) continue;
29341 MInt nghbrId = c_neighborId( tripleLink , dir );
29342 if ( nghbrId < 0 ) continue;
29343 if ( a_hasProperty( nghbrId , SolverCell::WasInactive ) ) continue;
29344 if ( a_hasProperty( nghbrId , SolverCell::IsSplitCell ) ) continue;
29345 if ( a_hasProperty( nghbrId , SolverCell::IsSplitChild ) ) continue;
29346 if ( a_cellVolume( nghbrId ) > maxVol ) {
29347 masterId = nghbrId;
29348 maxVol = a_cellVolume( nghbrId );
29349 }
29350 }
29351 if(masterId > 0) {
29352 cerr << " Using masterId " << c_globalId(masterId) << endl;
29353 if( a_isHalo( cellId ) && a_isHalo(masterId) && a_isHalo(tripleLink)) continue;
29354 m_temporarilyLinkedCells.push_back( make_tuple(cellId,masterId, tripleLink) );
29355 a_hasProperty( cellId , SolverCell::IsTempLinked ) = true;
29356 a_hasProperty(tripleLink, SolverCell::IsTempLinked ) = true;
29357 for ( MInt v = 0; v < m_noVars; v++ ) {
29358 a_variable( cellId , v ) = a_variable( masterId , v );
29359 a_oldVariable( cellId , v ) = a_oldVariable( masterId , v );
29360 a_pvariable( cellId , v ) =a_pvariable( masterId , v );
29361
29362 a_variable(tripleLink, v ) = a_variable( masterId , v );
29363 a_oldVariable(tripleLink, v ) = a_oldVariable( masterId , v );
29364 a_pvariable(tripleLink, v ) =a_pvariable( masterId , v );
29365 }
29366 }
29367 }
29368 }
29369
29370
29371 }
29372 }
29373
29374
29375
29376 }
29377 */
29378 if(masterId < 0) {
29379 cerr << domainId() << " Still no temporary master found for emerged cell " << cellId << " "
29380 << c_globalId(cellId) << " " << a_isHalo(cellId) << " " << a_isWindow(cellId) << " "
29381 << a_hasProperty(cellId, SolverCell::IsNotGradient) << " " << noInternalNghbrs << " " << noWasActiveNghbrs
29382 << " " << a_hasProperty(cellId, SolverCell::IsSplitChild) << " " << a_levelSetValuesMb(cellId, 0) << " "
29383 << a_hasProperty(cellId, SolverCell::IsGapCell) << " " << a_hasProperty(cellId, SolverCell::WasGapCell)
29384 << " "
29385 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_volume / grid().gridCellVolume(a_level(cellId))
29386 << " " << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
29387 if(m_closeGaps && m_gapCellId[cellId] > 0)
29388 cerr << m_gapCellId[cellId] << " " << m_gapCells[m_gapCellId[cellId]].status << endl;
29389 }
29390 }
29391
29392 // the second-halo-layer is not linked!
29393 if(masterId < 0) {
29394 ASSERT(a_isHalo(cellId), "");
29395 ASSERT(a_hasProperty(cellId, SolverCell::IsNotGradient), "");
29396 }
29397
29398 // Do not use azimuthal halo cell as master because azimuthal halos are skipped
29399 // further above.
29400 if(grid().azimuthalPeriodicity() && a_isPeriodic(masterId)) {
29401 if(tripleLink >= 0) {
29402 mTerm(1, AT_, "Triple link with azimuthalPeriodicity");
29403 }
29404 continue;
29405 }
29406
29407
29408 // create linkedHalo- and -Window-Cells list
29409 // a) for single-links
29410 if(tripleLink < 0 && masterId > -1 && a_isHalo(cellId) != a_isHalo(masterId)) {
29411 if(c_globalId(cellId) < 0 || c_globalId(masterId) < 0) {
29412 cerr << domainId() << ": GID " << cellId << " " << masterId << " " << c_globalId(cellId) << " "
29413 << c_globalId(masterId) << " " << a_isPeriodic(cellId) << " " << a_isPeriodic(masterId) << endl;
29414 }
29415 ASSERT(c_globalId(cellId) > -1 && c_globalId(masterId) > -1, "");
29416 if(a_isHalo(cellId)) {
29417 ASSERT(a_isWindow(masterId), "");
29418 MInt ndom = grid().findNeighborDomainId(c_globalId(cellId));
29419 MInt idx = grid().domainIndex(ndom);
29420 ASSERT(neighborDomain(idx) == ndom, "");
29421 m_linkedHaloCells[idx].push_back(cellId);
29422 m_linkedWindowCells[idx].push_back(masterId);
29423 } else {
29424 // masterId is Halo-Cell
29425 ASSERT(a_isHalo(masterId), "");
29426 ASSERT(a_isWindow(cellId), "");
29427 MInt ndom = grid().findNeighborDomainId(c_globalId(masterId));
29428 MInt idx = grid().domainIndex(ndom);
29429 ASSERT(neighborDomain(idx) == ndom, "");
29430 m_linkedHaloCells[idx].push_back(masterId);
29431 m_linkedWindowCells[idx].push_back(cellId);
29432 }
29433
29434 } // b) for triple-links
29435 else if(tripleLink > -1 && masterId > -1
29436 && (a_isHalo(cellId) != a_isHalo(tripleLink) || a_isHalo(tripleLink) != a_isHalo(masterId))) {
29437 // if one of the linked Cells is a halo-Cell and the others are not!
29438 // if they are all halo-Cells, the link is handeled on the other rank!
29439
29440 ASSERT(c_globalId(cellId) > -1 && c_globalId(masterId) > -1 && c_globalId(tripleLink), "");
29441 // split triple-problmen in multiple single-link problems:
29442 // single link between: - tripleLink and masterId
29443 // - tripleLink and cellId
29444
29445 MInt ndom11 = grid().findNeighborDomainId(c_globalId(tripleLink));
29446 MInt ndom22 = grid().findNeighborDomainId(c_globalId(cellId));
29447 MInt ndom33 = grid().findNeighborDomainId(c_globalId(masterId));
29448
29449 cerr << domainId() << "Parallel Triple-Link Halo-Cells: " << c_globalId(cellId) << " " << c_globalId(tripleLink)
29450 << " " << c_globalId(masterId) << " " << a_isHalo(cellId) << " " << a_isHalo(tripleLink) << " "
29451 << a_isHalo(masterId) << " Domains " << ndom22 << " " << ndom11 << " " << ndom33 << endl;
29452
29453
29454 if(a_isHalo(tripleLink) && !a_isHalo(masterId)) {
29455 ASSERT(a_isWindow(masterId), "");
29456 MInt ndom = grid().findNeighborDomainId(c_globalId(tripleLink));
29457 MInt idx = grid().domainIndex(ndom);
29458 ASSERT(neighborDomain(idx) == ndom, "");
29459 m_linkedHaloCells[idx].push_back(tripleLink);
29460 m_linkedWindowCells[idx].push_back(masterId);
29461
29462 } else if(a_isHalo(masterId) && !a_isHalo(tripleLink)) {
29463 ASSERT(a_isWindow(tripleLink), "");
29464 MInt ndom = grid().findNeighborDomainId(c_globalId(masterId));
29465 MInt idx = grid().domainIndex(ndom);
29466 ASSERT(neighborDomain(idx) == ndom, "");
29467 m_linkedHaloCells[idx].push_back(masterId);
29468 m_linkedWindowCells[idx].push_back(tripleLink);
29469 }
29470
29471 if(a_isHalo(tripleLink) && !a_isHalo(cellId)) {
29472 ASSERT(a_isWindow(cellId), "");
29473 MInt ndom = grid().findNeighborDomainId(c_globalId(tripleLink));
29474 MInt idx = grid().domainIndex(ndom);
29475 ASSERT(neighborDomain(idx) == ndom, "");
29476 m_linkedHaloCells[idx].push_back(tripleLink);
29477 m_linkedWindowCells[idx].push_back(cellId);
29478
29479 } else if(!a_isHalo(tripleLink) && a_isHalo(cellId)) {
29480 ASSERT(a_isWindow(tripleLink), "");
29481 MInt ndom = grid().findNeighborDomainId(c_globalId(cellId));
29482 MInt idx = grid().domainIndex(ndom);
29483 ASSERT(neighborDomain(idx) == ndom, "");
29484 m_linkedHaloCells[idx].push_back(cellId);
29485 m_linkedWindowCells[idx].push_back(tripleLink);
29486 }
29487
29488 if(a_isHalo(masterId) && !a_isHalo(cellId)) {
29489 } else if(!a_isHalo(masterId) && a_isHalo(cellId)) {
29490 }
29491 }
29492 }
29493
29494 // sort by globalId to synchronize order across domains
29495 for(MInt i = 0; i < noNeighborDomains(); i++) {
29496 sort(m_linkedHaloCells[i].begin(), m_linkedHaloCells[i].end(),
29497 [this](const MInt& a, const MInt& b) { return c_globalId(a) < c_globalId(b); });
29498 sort(m_linkedWindowCells[i].begin(), m_linkedWindowCells[i].end(),
29499 [this](const MInt& a, const MInt& b) { return c_globalId(a) < c_globalId(b); });
29500 }
29501}

◆ loadBodyRestartFile()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::loadBodyRestartFile ( MInt  readMode)
Author
Lennart Schneiders, Tim Wegmann (minor modifications)

Definition at line 25056 of file fvmbcartesiansolverxd.cpp.

25056 {
25057 TRACE();
25058
25059 if(m_noEmbeddedBodies == 0) return;
25060
25061 stringstream fn;
25062 fn.clear();
25064 if(!m_multipleFvSolver) {
25065 fn << restartDir() << "restartBodyData";
25066 } else {
25067 fn << restartDir() << "restartBodyData_" << solverId();
25068 }
25069 } else {
25070 if(!m_multipleFvSolver) {
25071 fn << restartDir() << "restartBodyData_" << m_restartTimeStep;
25072 } else {
25073 fn << restartDir() << "restartBodyData_" << solverId() << "_" << m_restartTimeStep;
25074 }
25075 }
25076 fn << ParallelIo::fileExt();
25077
25078 MString fileName = fn.str();
25079
25080#ifdef _MB_DEBUG_
25081 MInt cnt = 0;
25082#endif
25083
25084 const MLong DOF = m_noEmbeddedBodies;
25085 const MLong DOF_TRANS = nDim * m_noEmbeddedBodies;
25086 const MLong DOF_ROT = 3 * m_noEmbeddedBodies;
25087 const MLong DOF_QUAT = 4 * m_noEmbeddedBodies;
25088
25089 if(domainId() == 0) {
25090 cerr << "loading body restart file " << fn.str() << " at " << globalTimeStep << "...";
25091 }
25092
25093 int64_t noMbCells = 0;
25094 int64_t domainOffset0 = (int64_t)domainOffset(domainId() + 1);
25095 int64_t domainOffset1 = (int64_t)domainOffset(domainId());
25096
25097 // check that the number of bndry-Cells in the file matches
25098 // the number of already created bndryCells
25099 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
25100 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25101 if(a_isHalo(cellId)) continue;
25102 if(a_isPeriodic(cellId)) continue;
25103 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
25104 domainOffset0 = mMin(domainOffset0, (int64_t)c_globalId(cellId));
25105 domainOffset1 = mMax(domainOffset1, (int64_t)c_globalId(cellId));
25106 noMbCells++;
25107 }
25108 domainOffset1++;
25109 domainOffset0 = mMax(domainOffset0, (int64_t)domainOffset(domainId()));
25110 domainOffset1 = mMin(domainOffset1, (int64_t)domainOffset(domainId() + 1));
25111
25112 if(noMbCells == 0) {
25113 domainOffset0 = (int64_t)domainOffset(domainId());
25114 // NOTE: check the below, this makes hardly any sense!
25115 domainOffset1 = domainOffset0 + 1;
25116 if(readMode == 2) { // working version
25117 domainOffset1 = (int64_t)domainOffset(domainId() + 1);
25118 }
25119 }
25120 if(domainOffset0 > domainOffset1 || m_bodyTypeMb == 3) {
25121 domainOffset0 = (int64_t)domainOffset(domainId());
25122 domainOffset1 = (int64_t)domainOffset(domainId() + 1);
25123 }
25124 int64_t noMbCellsGlobal = noMbCells;
25125
25126 if(noDomains() > 1) {
25127 noMbCellsGlobal = noMbCells;
25128 MPI_Allreduce(MPI_IN_PLACE, &noMbCellsGlobal, 1, MPI_INT64_T, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
25129 "noMbCellsGlobal");
25130 }
25131
25132 using namespace maia::parallel_io;
25133 ParallelIo parallelIo(fileName, PIO_READ, mpiComm());
25134
25135 ParallelIo::size_type size = 0;
25136 ParallelIo::size_type start = 0;
25137 ParallelIo::size_type count = 0;
25138
25139 if(parallelIo.hasDataset("DOF")) {
25140 parallelIo.readScalar(&size, "DOF");
25141 } else {
25142 size = parallelIo.getArraySize("bodyTemperature");
25143 }
25144
25145 if(size != DOF) {
25146 mTerm(1, AT_,
25147 "No embedded bodies mismatch in loadBodyRestartFile(): " + to_string(m_noEmbeddedBodies)
25148 + " != " + to_string(size) + ".");
25149 }
25150
25151 size = parallelIo.getArraySize("bndryCellVolumesIds");
25152
25153 if(noMbCellsGlobal > 0 && size != (MPI_Offset)noMbCellsGlobal && m_geometryChange == nullptr) {
25154 if(domainId() == 0) {
25155 cerr << "Warning: No boundary cells mismatch in loadBodyRestartFile(): " + to_string(noMbCellsGlobal)
25156 + " != " + to_string(size) + ". Might be due to non-converged to fluid-structure iterations."
25157 << endl;
25158 }
25159 }
25160 const MLong DOF_VOL = size;
25161
25162 // read body properties:
25163 count = DOF;
25164 parallelIo.setOffset(count, start);
25165 parallelIo.readArray(m_bodyTemperature, "bodyTemperature");
25166
25167 count = DOF_TRANS;
25168 parallelIo.setOffset(count, start);
25169 parallelIo.readArray(m_bodyCenter, "bodyCenter");
25170 parallelIo.readArray(m_bodyVelocity, "bodyVelocity");
25171 parallelIo.readArray(m_bodyAcceleration, "bodyAcceleration");
25172 parallelIo.readArray(m_bodyForce, "bodyForce");
25173
25174 count = DOF_ROT;
25175 parallelIo.setOffset(count, start);
25176 parallelIo.readArray(m_bodyAngularVelocity, "bodyAngularVelocity");
25177 parallelIo.readArray(m_bodyAngularAcceleration, "bodyAngularAcceleration");
25178 parallelIo.readArray(m_bodyTorque, "bodyTorque");
25179
25180 count = DOF_QUAT;
25181 parallelIo.setOffset(count, start);
25182 parallelIo.readArray(m_bodyQuaternion, "bodyQuaternion");
25183
25184 if(readMode == 2) {
25185 ASSERT(m_geometryChange != nullptr, "");
25186 if(domainId() == 0) {
25187 cerr << "Storing old bndryCell volume for geometryChange!" << endl;
25188 }
25189 m_oldGeomBndryCells.clear();
25190 }
25191
25192 MInt mismatchCnt = 0;
25193 if(readMode > 0 && DOF_VOL > 0 && DOF_VOL < domainOffset(noDomains())) {
25194 MBool readVolStrided = false;
25195 if((readVolStrided || DOF_VOL <= noDomains()) && readMode != 2) {
25196 start = 0;
25197 count = DOF_VOL;
25198 if(readVolStrided) {
25199 MPI_Offset noSamples = (MPI_Offset)max(2, min((MInt)DOF_VOL, noDomains() / 2));
25200 MPI_Offset sampleWidth = ((MPI_Offset)(DOF_VOL - 1)) / (noSamples - 1);
25201 MLongScratchSpace sampledIds(noSamples, AT_, "sampledIds");
25202 start = 0;
25203 count = noSamples;
25204 parallelIo.setOffset(count, start);
25205 parallelIo.readArray(&sampledIds[0], "bndryCellVolumesIds", -1, sampleWidth);
25206 start = 0;
25207 count = 0;
25208 MPI_Offset end = DOF_VOL;
25209 for(MPI_Offset i = 0; i < noSamples; i++) {
25210 if(domainOffset0 >= sampledIds[i])
25211 start = i * sampleWidth;
25212 else
25213 break;
25214 }
25215 for(MPI_Offset i = noSamples - 1; i >= 0; i--) {
25216 if(domainOffset1 < sampledIds[i])
25217 end = i * sampleWidth;
25218 else
25219 break;
25220 }
25221 MInt diff = end - start;
25222 count = (diff > 0) ? (MPI_Offset)diff : 0;
25223 }
25224 MLongScratchSpace bndryCellVolumesIds(count + 1, AT_, "bndryCellVolumesIds");
25225 MFloatScratchSpace bndryCellVolumes(count + 1, AT_, "bndryCellVolumes");
25226
25227 parallelIo.setOffset(count, start);
25228 parallelIo.readArray(&bndryCellVolumesIds[0], "bndryCellVolumesIds");
25229 parallelIo.readArray(&bndryCellVolumes[0], "bndryCellVolumes");
25230
25231 MIntScratchSpace bndCells(domainOffset1 - domainOffset0 + 1, AT_, "bndCells");
25232 bndCells.fill(-1);
25233 for(MInt i = 0; i < count; i++) {
25234 if(bndryCellVolumesIds[i] < domainOffset0 || bndryCellVolumesIds[i] >= domainOffset1) {
25235 continue;
25236 }
25237 bndCells[bndryCellVolumesIds[i] - domainOffset0] = i;
25238 }
25239#ifdef _MB_DEBUG_
25240 cerr << domainId() << ": read " << bndCells.size() << " of " << DOF_VOL
25241 << " volume entries within domain offsets " << domainOffset0 << "-" << domainOffset1 << endl;
25242#endif
25243
25244 mismatchCnt = 0;
25245
25246 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
25247 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25248 if(a_isHalo(cellId)) continue;
25249
25250 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
25251 if(c_globalId(cellId) < domainOffset0 || c_globalId(cellId) >= domainOffset1) continue;
25252 if(bndCells[c_globalId(cellId) - domainOffset0] > -1) {
25253 // const MInt i = it->second;
25254 MInt i = bndCells[c_globalId(cellId) - domainOffset0];
25255 a_cellVolume(cellId) = bndryCellVolumes[i];
25256 m_cellVolumesDt1[cellId] = bndryCellVolumes[i];
25257 if(m_dualTimeStepping) m_cellVolumesDt2[cellId] = bndryCellVolumes[i];
25258 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25259 m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume = bndryCellVolumes[i];
25260
25261#ifdef _MB_DEBUG_
25262 if(a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) < F0
25263 || a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) > F1) {
25264 cerr << domainId() << ": warning volume fraction in loadBodyRestartFile() "
25265 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << " for cell " << cellId << endl;
25266 }
25267#endif
25268 } else {
25269 mismatchCnt++;
25270 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
25273 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25274#ifdef _MB_DEBUG_
25275 if(cnt < 20) {
25276 cerr << domainId() << ": Corresponding boundary id not found. "
25277 << "Might be due to non-converged to fluid-structure iterations: /g " << c_globalId(cellId) << " /c "
25278 << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << " " << a_coordinate(cellId, 2)
25279 << " /ls " << a_levelSetValuesMb(cellId, 0) / c_cellLengthAtCell(cellId) << " /v "
25280 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume / grid().gridCellVolume(a_level(cellId)) << " "
25281 << domainOffset0 << " " << domainOffset1 << endl;
25282 cnt++;
25283 if(cnt == 20) {
25284 cerr << domainId() << ": Exceeding 20, not reporting any more." << endl;
25285 }
25286 }
25287#endif
25288 }
25289 }
25290 MPI_Allreduce(MPI_IN_PLACE, &mismatchCnt, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "mismatchCnt");
25291 if(domainId() == 0) {
25292 cerr << "mismatch cnt: " << mismatchCnt << " out of " << DOF_VOL << endl;
25293 }
25294
25295 } else {
25296 start = (DOF_VOL / noDomains()) * domainId();
25297 count = (domainId() == noDomains() - 1) ? DOF_VOL - start : (DOF_VOL / noDomains());
25298
25299 MLongScratchSpace bndryCellVolumesIdsTmp(count, AT_, "bndryCellVolumesIdsTmp");
25300 MFloatScratchSpace bndryCellVolumesTmp(count, AT_, "bndryCellVolumesTmp");
25301
25302 parallelIo.setOffset(count, start);
25303 parallelIo.readArray(&bndryCellVolumesIdsTmp[0], "bndryCellVolumesIds");
25304 parallelIo.readArray(&bndryCellVolumesTmp[0], "bndryCellVolumes");
25305
25306 MIntScratchSpace sendCnt(noDomains(), AT_, "sendCnt");
25307 MIntScratchSpace recvCnt(noDomains(), AT_, "recvCnt");
25308 MIntScratchSpace recvOffsets(noDomains() + 1, AT_, "recvOffsets");
25309 MIntScratchSpace sendOffsets(noDomains(), AT_, "sendOffsets");
25310 sendCnt.fill(0);
25311 recvCnt.fill(0);
25312 recvOffsets.fill(0);
25313 sendOffsets.fill(-1);
25314 MInt nbDom = noDomains() / 2;
25315 MLong minId = std::numeric_limits<MLong>::max();
25316 MLong bitOffsetBuf = 0;
25317 for(MInt i = 0; i < count; i++) {
25318 minId = mMin(minId, bndryCellVolumesIdsTmp[i]);
25319 }
25320 if(minId < grid().bitOffset()) {
25321 bitOffsetBuf = grid().bitOffset();
25322 } else {
25323 bitOffsetBuf = 0;
25324 }
25325
25326 for(MInt i = 0; i < count; i++) {
25327 bndryCellVolumesIdsTmp[i] += bitOffsetBuf;
25328 }
25329 for(MInt i = 0; i < count; i++) {
25330 if(bndryCellVolumesIdsTmp(i) >= domainOffset(noDomains())) {
25331 cerr << domainId() << ": index out of range " << bndryCellVolumesIdsTmp(i) << " " << domainOffset(noDomains())
25332 << " " << grid().noCellsGlobal() << " " << grid().bitOffset() << " " << bitOffsetBuf << endl;
25333 continue;
25334 }
25335 while(bndryCellVolumesIdsTmp(i) < domainOffset(nbDom) || bndryCellVolumesIdsTmp(i) >= domainOffset(nbDom + 1)) {
25336 if(bndryCellVolumesIdsTmp(i) < domainOffset(nbDom)) nbDom--;
25337 if(bndryCellVolumesIdsTmp(i) >= domainOffset(nbDom + 1)) nbDom++;
25338 }
25339 if(sendCnt(nbDom) == 0) sendOffsets[nbDom] = i;
25340 sendCnt(nbDom)++;
25341 }
25342 for(MInt i = 0; i < noDomains(); i++) {
25343 if(sendCnt(i) > 0 && sendOffsets[i] < 0) {
25344 cerr << domainId() << ": Warning send offset not set: " << i << endl;
25345 }
25346 }
25347 MPI_Alltoall(&sendCnt[0], 1, MPI_INT, &recvCnt[0], 1, MPI_INT, mpiComm(), AT_, "sendCnt[0]", "recvCnt[0]");
25348 MInt totalNoRecv = 0;
25349 recvOffsets[0] = 0;
25350 for(MInt i = 0; i < noDomains(); i++) {
25351 totalNoRecv += recvCnt(i);
25352 recvOffsets[i + 1] = recvOffsets[i] + recvCnt(i);
25353 }
25354 MLongScratchSpace bndryCellVolumesIds(mMax(1, totalNoRecv), AT_, "bndryCellVolumesIds");
25355 MFloatScratchSpace bndryCellVolumes(mMax(1, totalNoRecv), AT_, "bndryCellVolumes");
25356 ScratchSpace<MPI_Request> sendReq(noDomains(), AT_, "sendReq");
25357 sendReq.fill(MPI_REQUEST_NULL);
25358 MInt scnt = 0;
25359 for(MInt i = 0; i < noDomains(); i++) {
25360 if(sendCnt[i] == 0) continue;
25361 MPI_Issend(&(bndryCellVolumesIdsTmp[sendOffsets[i]]), sendCnt[i], MPI_LONG, i, 432, mpiComm(), &sendReq[scnt],
25362 AT_, "(bndryCellVolumesIdsTmp[sendOffsets[i]])");
25363 scnt++;
25364 }
25365 for(MInt i = 0; i < noDomains(); i++) {
25366 if(recvCnt[i] == 0) continue;
25367 MPI_Recv(&(bndryCellVolumesIds[recvOffsets[i]]), recvCnt[i], MPI_LONG, i, 432, mpiComm(), MPI_STATUS_IGNORE,
25368 AT_, "(bndryCellVolumesIds[recvOffsets[i]])");
25369 }
25370 if(scnt > 0) MPI_Waitall(scnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
25371 sendReq.fill(MPI_REQUEST_NULL);
25372 scnt = 0;
25373 for(MInt i = 0; i < noDomains(); i++) {
25374 if(sendCnt[i] == 0) continue;
25375 MPI_Issend(&(bndryCellVolumesTmp[sendOffsets[i]]), sendCnt[i], MPI_DOUBLE, i, 433, mpiComm(), &sendReq[scnt],
25376 AT_, "(bndryCellVolumesTmp[sendOffsets[i]])");
25377 scnt++;
25378 }
25379 for(MInt i = 0; i < noDomains(); i++) {
25380 if(recvCnt[i] == 0) continue;
25381 MPI_Recv(&(bndryCellVolumes[recvOffsets[i]]), recvCnt[i], MPI_DOUBLE, i, 433, mpiComm(), MPI_STATUS_IGNORE, AT_,
25382 "(bndryCellVolumes[recvOffsets[i]])");
25383 }
25384 if(scnt > 0) MPI_Waitall(scnt, &sendReq[0], MPI_STATUSES_IGNORE, AT_);
25385
25386 MIntScratchSpace bndCells(domainOffset1 - domainOffset0 + 1, AT_, "bndCells");
25387 bndCells.fill(-1);
25388 for(MInt i = 0; i < totalNoRecv; i++) {
25389 if(bndryCellVolumesIds[i] < domainOffset0 || bndryCellVolumesIds[i] >= domainOffset1) {
25390 continue;
25391 }
25392 bndCells[bndryCellVolumesIds[i] - domainOffset0] = i;
25393 }
25394
25395 mismatchCnt = 0;
25396
25397 if(readMode == 1) {
25398 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
25399 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25400 if(a_isHalo(cellId)) continue;
25401 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
25402 if(c_globalId(cellId) < domainOffset0 || c_globalId(cellId) >= domainOffset1) continue;
25403 const MInt i = bndCells[c_globalId(cellId) - domainOffset0];
25404 if(i > -1) {
25405 a_cellVolume(cellId) = bndryCellVolumes[i];
25406 m_cellVolumesDt1[cellId] = bndryCellVolumes[i];
25407 if(m_dualTimeStepping) m_cellVolumesDt2[cellId] = bndryCellVolumes[i];
25408 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25409 m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume = bndryCellVolumes[i];
25410#ifdef _MB_DEBUG_
25411 if(a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) < F0
25412 || a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) > F1) {
25413 cerr << domainId() << ": warning volume fraction in loadBodyRestartFile() "
25414 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << " for cell " << cellId << " "
25415 << c_globalId(cellId) << endl;
25416 }
25417#endif
25418 } else {
25419 mismatchCnt++;
25420 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
25423 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25424
25425#ifdef _MB_DEBUG_
25426 if(mismatchCnt < 20) {
25427 cerr << domainId()
25428 << ": Corresponding boundary id not found. Might be due to non-converged to fluid-structure "
25429 "iterations: /g "
25430 << c_globalId(cellId) << " /c " << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << " "
25431 << a_coordinate(cellId, 2) << " /v "
25432 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume / grid().gridCellVolume(a_level(cellId)) << " "
25433 << domainOffset0 << " " << domainOffset1 << endl;
25434 cnt++;
25435 if(cnt == 20) {
25436 cerr << domainId() << ": Exceeding 20, not reporting any more." << endl;
25437 }
25438 }
25439#endif
25440 }
25441 }
25442
25443 MPI_Allreduce(MPI_IN_PLACE, &mismatchCnt, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "mismatchCnt");
25444
25445 if(domainId() == 0) {
25446 cerr << "mismatch cnt: " << mismatchCnt << " out of " << DOF_VOL << endl;
25447 }
25448
25449 // for large missmatch count assume complete irregularity and treat all cells as missmatched!
25450 if(mismatchCnt > 0.5 * DOF_VOL) {
25451 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
25452 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25453 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
25456 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25457 }
25458 }
25459
25460 } else { // read mode 2!
25461
25462 // store volume from file in array,
25463 // which is then correctly keept during the forcedAdaptation
25464 // and set for the bndryCells which remain the same thoughout the geometryChange!
25465 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
25466 const MInt i = bndCells[cellId];
25467 if(i > -1) {
25468 const MFloat volume = bndryCellVolumes[i];
25469 m_oldGeomBndryCells.insert(make_pair(cellId, volume));
25470 }
25471 }
25472 }
25473 }
25474 }
25475
25476 // set volumes on halo cells
25477 exchangeData(&a_cellVolume(0), 1);
25478
25479 // Read cellVolume of azimuthal halo cells
25480 if(grid().azimuthalPeriodicity() && readMode == 1) {
25481 size = parallelIo.getArraySize("azimuthalBndryCellVolumesIds");
25482 const MLong DOF_VOL_AZIMUTHAL = size;
25483 start = (DOF_VOL_AZIMUTHAL / noDomains()) * domainId();
25484 count = (domainId() == noDomains() - 1) ? DOF_VOL_AZIMUTHAL - start : (DOF_VOL_AZIMUTHAL / noDomains());
25485
25486 MLongScratchSpace azimuthalBndryCellVolumesIdsTmp(count, AT_, "azimuthalBndryCellVolumesIdsTmp");
25487 MFloatScratchSpace azimuthalBndryCellVolumesTmp(count, AT_, "azimuthalBndryCellVolumesTmp");
25488 MFloatScratchSpace azimuthalBndryCellCoordinatesTmp(count * nDim, AT_, "azimuthalBndryCellCoordinatesTmp");
25489
25490 parallelIo.setOffset(count, start);
25491 parallelIo.readArray(&azimuthalBndryCellVolumesIdsTmp[0], "azimuthalBndryCellVolumesIds");
25492 parallelIo.readArray(&azimuthalBndryCellVolumesTmp[0], "azimuthalBndryCellVolumes");
25493 parallelIo.setOffset(count * nDim, start * nDim);
25494 parallelIo.readArray(&azimuthalBndryCellCoordinatesTmp[0], "azimuthalBndryCellCoordinates");
25495
25496 MIntScratchSpace sendCntAzimuthal(noDomains(), AT_, "sendCntAzimuthal");
25497 MIntScratchSpace recvCntAzimuthal(noDomains(), AT_, "recvCntAzimuthal");
25498 MIntScratchSpace recvOffsetsAzimuthal(noDomains() + 1, AT_, "recvOffsetsAzimuthal");
25499 MIntScratchSpace sendOffsetsAzimuthal(noDomains(), AT_, "sendOffsetsAzimuthal");
25500 sendCntAzimuthal.fill(0);
25501 recvCntAzimuthal.fill(0);
25502 recvOffsetsAzimuthal.fill(0);
25503 sendOffsetsAzimuthal.fill(-1);
25504 MInt nbDom = noDomains() / 2;
25505 MLong minId = std::numeric_limits<MLong>::max();
25506 MLong bitOffsetBuf = 0;
25507 for(MInt i = 0; i < count; i++) {
25508 minId = mMin(minId, azimuthalBndryCellVolumesIdsTmp[i]);
25509 }
25510 if(minId < grid().bitOffset()) {
25511 bitOffsetBuf = grid().bitOffset();
25512 } else {
25513 bitOffsetBuf = 0;
25514 }
25515
25516 for(MInt i = 0; i < count; i++) {
25517 azimuthalBndryCellVolumesIdsTmp[i] += bitOffsetBuf;
25518 }
25519 for(MInt i = 0; i < count; i++) {
25520 if(azimuthalBndryCellVolumesIdsTmp(i) >= domainOffset(noDomains())) {
25521 cerr << domainId() << ": index out of range " << azimuthalBndryCellVolumesIdsTmp(i) << " "
25522 << domainOffset(noDomains()) << " " << grid().noCellsGlobal() << " " << grid().bitOffset() << " "
25523 << bitOffsetBuf << endl;
25524 continue;
25525 }
25526 while(azimuthalBndryCellVolumesIdsTmp(i) < domainOffset(nbDom)
25527 || azimuthalBndryCellVolumesIdsTmp(i) >= domainOffset(nbDom + 1)) {
25528 if(azimuthalBndryCellVolumesIdsTmp(i) < domainOffset(nbDom)) nbDom--;
25529 if(azimuthalBndryCellVolumesIdsTmp(i) >= domainOffset(nbDom + 1)) nbDom++;
25530 }
25531 if(sendCntAzimuthal(nbDom) == 0) sendOffsetsAzimuthal[nbDom] = i;
25532 sendCntAzimuthal(nbDom)++;
25533 }
25534 for(MInt i = 0; i < noDomains(); i++) {
25535 if(sendCntAzimuthal(i) > 0 && sendOffsetsAzimuthal[i] < 0) {
25536 cerr << domainId() << ": Warning send offset not set: " << i << endl;
25537 }
25538 }
25539 MPI_Alltoall(&sendCntAzimuthal[0], 1, MPI_INT, &recvCntAzimuthal[0], 1, MPI_INT, mpiComm(), AT_,
25540 "sendCntAzimuthal[0]", "recvCntAzimuthal[0]");
25541 MInt totalNoRecv = 0;
25542 recvOffsetsAzimuthal[0] = 0;
25543 for(MInt i = 0; i < noDomains(); i++) {
25544 totalNoRecv += recvCntAzimuthal(i);
25545 recvOffsetsAzimuthal[i + 1] = recvOffsetsAzimuthal[i] + recvCntAzimuthal(i);
25546 }
25547 MLongScratchSpace azimuthalBndryCellVolumesIds(mMax(1, totalNoRecv), AT_, "azimuthalBndryCellVolumesIds");
25548 MFloatScratchSpace azimuthalBndryCellVolumes(mMax(1, totalNoRecv), AT_, "azimuthalBndryCellVolumes");
25549 MFloatScratchSpace azimuthalBndryCellCoordinates(mMax(1, nDim * totalNoRecv), AT_, "azimuthalBndryCellCoordinates");
25550 ScratchSpace<MPI_Request> sendReqAzimuthal(noDomains(), AT_, "sendReqAzimuthal");
25551 sendReqAzimuthal.fill(MPI_REQUEST_NULL);
25552 MInt scnt = 0;
25553 for(MInt i = 0; i < noDomains(); i++) {
25554 if(sendCntAzimuthal[i] == 0) continue;
25555 MPI_Issend(&(azimuthalBndryCellVolumesIdsTmp[sendOffsetsAzimuthal[i]]), sendCntAzimuthal[i], MPI_LONG, i, 432,
25556 mpiComm(), &sendReqAzimuthal[scnt], AT_, "(azimuthalBndryCellVolumesIdsTmp[sendOffsetsAzimuthal[i]])");
25557 scnt++;
25558 }
25559 for(MInt i = 0; i < noDomains(); i++) {
25560 if(recvCntAzimuthal[i] == 0) continue;
25561 MPI_Recv(&(azimuthalBndryCellVolumesIds[recvOffsetsAzimuthal[i]]), recvCntAzimuthal[i], MPI_LONG, i, 432,
25562 mpiComm(), MPI_STATUS_IGNORE, AT_, "(azimuthalBndryCellVolumesIds[recvOffsets[i]])");
25563 }
25564 if(scnt > 0) MPI_Waitall(scnt, &sendReqAzimuthal[0], MPI_STATUSES_IGNORE, AT_);
25565 sendReqAzimuthal.fill(MPI_REQUEST_NULL);
25566 scnt = 0;
25567 for(MInt i = 0; i < noDomains(); i++) {
25568 if(sendCntAzimuthal[i] == 0) continue;
25569 MPI_Issend(&(azimuthalBndryCellVolumesTmp[sendOffsetsAzimuthal[i]]), sendCntAzimuthal[i], MPI_DOUBLE, i, 433,
25570 mpiComm(), &sendReqAzimuthal[scnt], AT_, "(azimuthalBndryCellVolumesTmp[sendOffsetsAzimuthal[i]])");
25571 scnt++;
25572 }
25573 for(MInt i = 0; i < noDomains(); i++) {
25574 if(recvCntAzimuthal[i] == 0) continue;
25575 MPI_Recv(&(azimuthalBndryCellVolumes[recvOffsetsAzimuthal[i]]), recvCntAzimuthal[i], MPI_DOUBLE, i, 433,
25576 mpiComm(), MPI_STATUS_IGNORE, AT_, "(azimuthalBndryCellVolumes[recvOffsetsAzimuthal[i]])");
25577 }
25578 if(scnt > 0) MPI_Waitall(scnt, &sendReqAzimuthal[0], MPI_STATUSES_IGNORE, AT_);
25579 sendReqAzimuthal.fill(MPI_REQUEST_NULL);
25580 scnt = 0;
25581 for(MInt i = 0; i < noDomains(); i++) {
25582 if(sendCntAzimuthal[i] == 0) continue;
25583 MPI_Issend(&(azimuthalBndryCellCoordinatesTmp[nDim * sendOffsetsAzimuthal[i]]), nDim * sendCntAzimuthal[i],
25584 MPI_DOUBLE, i, 434, mpiComm(), &sendReqAzimuthal[scnt], AT_,
25585 "(azimuthalBndryCellCoordinatesTmp[nDim*sendOffsetsAzimuthal[i]])");
25586 scnt++;
25587 }
25588 for(MInt i = 0; i < noDomains(); i++) {
25589 if(recvCntAzimuthal[i] == 0) continue;
25590 MPI_Recv(&(azimuthalBndryCellCoordinates[nDim * recvOffsetsAzimuthal[i]]), nDim * recvCntAzimuthal[i], MPI_DOUBLE,
25591 i, 434, mpiComm(), MPI_STATUS_IGNORE, AT_,
25592 "(azimuthalBndryCellCoordinates[nDim*recvOffsetsAzimuthal[i]])");
25593 }
25594 if(scnt > 0) MPI_Waitall(scnt, &sendReqAzimuthal[0], MPI_STATUSES_IGNORE, AT_);
25595
25596 multimap<MLong, vector<MFloat>> tmpVolAzimuthal;
25597 for(MInt i = 0; i < totalNoRecv; i++) {
25598 MLong cellId = azimuthalBndryCellVolumesIds[i];
25599 if(cellId >= domainOffset(domainId()) && cellId < domainOffset(domainId() + 1)) {
25600 vector<MFloat> tmpFloats(nDim + 1);
25601 for(MInt d = 0; d < nDim; d++) {
25602 tmpFloats[d] = azimuthalBndryCellCoordinates[i * nDim + d];
25603 }
25604 tmpFloats[nDim] = azimuthalBndryCellVolumes[i];
25605 tmpVolAzimuthal.insert(make_pair(cellId, tmpFloats));
25606 } else {
25607 cerr << "ERROR:" << domainId() << " " << cellId << " " << domainOffset(noDomains()) << " "
25608 << domainOffset(noDomains() + 1) << endl;
25609 mTerm(1, AT_, ": azimuthal data is broken.");
25610 }
25611 }
25612 MInt cnt = 0;
25613 MInt noFloatData = 3;
25614 MInt noIntData = 2;
25615 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
25616 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
25617 MInt cellId = grid().azimuthalWindowCell(i, j);
25618 if(tmpVolAzimuthal.count(c_globalId(cellId)) != 0) {
25619 MFloat cellLength = c_cellLengthAtCell(cellId);
25620 auto range = tmpVolAzimuthal.equal_range(c_globalId(cellId));
25621 for(auto it = range.first; it != range.second; ++it) {
25622 MBool isEqual = true;
25623 for(MInt d = 0; d < nDim; d++) {
25624 if(!approx((it->second)[d], this->m_azimuthalCartRecCoord[cnt * nDim + d],
25625 m_azimuthalCornerEps * cellLength)) {
25626 isEqual = false;
25627 }
25628 }
25629 if(isEqual) {
25630 vector<MFloat> tmpF(noFloatData + nDim);
25631 vector<MUlong> tmpI(noIntData);
25632 tmpF[0] = this->m_azimuthalCartRecCoord[cnt * nDim];
25633 tmpF[1] = this->m_azimuthalCartRecCoord[cnt * nDim + 1];
25634 if(nDim == 3) {
25635 tmpF[2] = this->m_azimuthalCartRecCoord[cnt * nDim + 2];
25636 }
25637 tmpF[nDim] = (it->second)[nDim]; // cellVolume
25638 tmpF[nDim + 1] = (it->second)[nDim]; // cellVolume
25639 tmpF[nDim + 2] = 0; // swepVol
25640
25641 tmpI[0] = 1;
25643 props[maia::fv::cell::p(SolverCell::IsMovingBnd)] = true;
25644 props[maia::fv::cell::p(SolverCell::NearWall)] = true;
25645 tmpI[1] = props.to_ulong(); // cell properties
25646 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId, make_pair(tmpF, tmpI)));
25647
25648 continue;
25649 }
25650 }
25651 }
25652 cnt++;
25653 }
25654 }
25656 }
25657
25658 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
25659 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25660 if(a_isHalo(cellId)) {
25663 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25664 if(mismatchCnt < 0.5 * DOF_VOL) {
25665 m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume = a_cellVolume(cellId);
25666 }
25667 }
25668 }
25669
25670 cerr0 << "done" << endl;
25671}
std::map< MInt, MFloat > m_oldGeomBndryCells
MBool m_useNonSpecifiedRestartFile
Definition: solver.h:83
MString restartDir() const
Return the directory for restart files.
Definition: solver.h:410
PARALLELIO_DEFAULT_BACKEND ParallelIo
Definition: parallelio.h:292

◆ loadInitCorrData()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::loadInitCorrData ( const std::vector< MInt > &  saveInitCorrDataTimeSteps,
MFloatScratchSpace bodyVelocityInit,
MFloatScratchSpace bodyAngularVelocityInit,
MFloatScratchSpace bodyQuaternionInit,
MFloatScratchSpace velMeanInit,
MFloatScratchSpace velGradMeanInit,
MFloatScratchSpace particleFluidRotationMeanInit,
MIntScratchSpace corrBodies,
MFloatScratchSpace bodyForceInit,
MFloatScratchSpace bodyTorqueInit,
const MIntScratchSpace bodyOffsets 
)

◆ loadRestartFile()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::loadRestartFile
overridevirtual
Author
: D. Hartmann
Date
May 24, 2006

Reimplemented from Solver.

Definition at line 24729 of file fvmbcartesiansolverxd.cpp.

24729 {
24730 TRACE();
24731
24734
24736
24737 m_log << "ok" << endl;
24738 m_log << "computing conservative variables... ";
24740 m_log << "ok" << endl;
24741 m_log << "restart at time step: " << globalTimeStep << " - solution time: " << m_time << endl;
24742 m_log << m_noSamples << " samples read" << endl;
24743 cerr0 << "finished restart at time step " << globalTimeStep << endl;
24744}
virtual void computeConservativeVariables()
Dispatches the computation of the conservative variables for different number of species.

◆ localToGlobalIds()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::localToGlobalIds
overridevirtual
Author
Thomas Hoesgen

Reimplemented from Solver.

Definition at line 36743 of file fvmbcartesiansolverxd.cpp.

36743 {
36744 TRACE();
36745
36746 // Nothing to do if solver is not active
36747 if(!isActive()) {
36748 return;
36749 }
36750
36751 if(grid().azimuthalPeriodicity()) {
36755 "m_azimuthalNearBoundaryBackupBalFloat", AT_);
36756 mAlloc(m_azimuthalNearBoundaryBackupBalLong, maxNoGridCells() * noLongData, "m_azimuthalNearBoundaryBackupBalLong",
36757 AT_);
36758
36759 m_azimuthalRecConstSet = false;
36762
36763 MInt maxCount = 0;
36764 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
36765 MInt gCellId = c_globalId(cellId);
36766 if((MInt)m_azimuthalNearBoundaryBackup.count(gCellId) > maxCount) {
36767 maxCount = (MInt)m_azimuthalNearBoundaryBackup.count(gCellId);
36768 }
36769 }
36770 MPI_Allreduce(MPI_IN_PLACE, &maxCount, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "maxCount");
36772 mTerm(1, "This is a problem! " + to_string(maxCount) + " " + to_string(m_azimuthalNearBoundaryBackupMaxCount));
36773 }
36774
36775 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
36776 MInt gCellId = c_globalId(cellId);
36777 for(MInt i = 0; i < noLongData; i++) {
36778 m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData + i] = -1;
36779 }
36780 for(MInt i = 0; i < noFloatData; i++) {
36781 m_azimuthalNearBoundaryBackupBalFloat[cellId * noFloatData + i] = -1;
36782 }
36783 if(m_azimuthalNearBoundaryBackup.count(gCellId) != 0) {
36784 MInt indexL = 0;
36785 MInt indexF = 0;
36786 auto range = m_azimuthalNearBoundaryBackup.equal_range(gCellId);
36787 for(auto it_ = range.first; it_ != range.second; ++it_) {
36788 m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData + indexL++] = (MUlong)gCellId;
36789 m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData + indexL++] = (MUlong)(it_->second).second[0];
36790 m_azimuthalNearBoundaryBackupBalLong[cellId * noLongData + indexL++] = (MUlong)(it_->second).second[1];
36791
36792 for(MInt f = 0; f < (nDim + m_noFloatDataBalance); f++) {
36793 m_azimuthalNearBoundaryBackupBalFloat[cellId * noFloatData + indexF++] = (it_->second).first[f];
36794 }
36795 }
36796 }
36797 }
36798 }
36799}
void storeAzimuthalPeriodicData(MInt mode=0)
Stored azimuthal periodic data from halo rank on window rank.

◆ locatenear() [1/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
static MInt FvMbCartesianSolverXD< nDim, SysEqn >::locatenear ( const Point< nDim > &  ,
MFloat  ,
MInt ,
MInt  ,
MBool  returnCellId = true 
)
inlinestatic

Definition at line 560 of file fvmbcartesiansolverxd.h.

561 {
562 std::ignore = returnCellId;
563 return 0;
564 }

◆ locatenear() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
MInt FvMbCartesianSolverXD< nDim, SysEqn >::locatenear ( const Point< nDim > &  pt,
MFloat  r,
MInt list,
MInt  nmax,
MBool  returnCellId = true 
)
inline

Definition at line 567 of file fvmbcartesiansolverxd.h.

567 {
568 return m_bodyTree->locatenear(pt, r, &list[0], nmax, returnCellId);
569 }

◆ logBoundaryData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::logBoundaryData ( const MChar fileName,
MBool  forceOutput 
)
Author
Lennart Schneiders

Definition at line 12750 of file fvmbcartesiansolverxd.cpp.

12750 {
12751 TRACE();
12752
12753 if(!m_logBoundaryData && !forceOutput) return;
12754 if(m_noLsMbBndryCells == 0) return;
12755 IF_CONSTEXPR(nDim == 3) return;
12756
12757 MInt cellId;
12758 const MFloat xOffset = m_bodyCenter[0];
12759 const MFloat yOffset = m_bodyCenter[1];
12760 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
12761 const MFloat radToDeg = 360.0 / (2.0 * PI);
12762 MFloat dist;
12763 MFloat shear[nDim];
12764 MFloat gradV[nDim][nDim];
12765 MFloat gradP[nDim];
12766 MFloat angle, u, v, cp, ma, vorticity, tmp; //, angle2;
12767 MFloat rhoU2 = F0;
12768 for(MInt i = 0; i < nDim; i++) {
12769 rhoU2 += POW2(m_VVInfinity[i]);
12770 }
12771 rhoU2 *= m_rhoInfinity;
12772
12773 MInt iTmp;
12774 MFloat fTmp;
12775 MInt noCells;
12776 MBool centerLine;
12777 ScratchSpace<MInt> sortedList(m_noLsMbBndryCells, AT_, "sortedList");
12778 ScratchSpace<MFloat> sortedAngle(m_noLsMbBndryCells, AT_, "sortedAngle");
12779
12780 noCells = 0;
12781
12782 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
12783 cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
12784 centerLine = false;
12785 IF_CONSTEXPR(nDim == 3) {
12786 if(a_coordinate(cellId, 2) >= F0 && a_hasNeighbor(cellId, 4) > 0
12787 && a_coordinate(c_neighborId(cellId, 4), 2) < F0) {
12788 centerLine = true;
12789 }
12790 }
12791 IF_CONSTEXPR(nDim == 3) {
12792 if(!centerLine) continue;
12793 }
12794
12795 angle = F0;
12796 if(a_coordinate(cellId, 1) - yOffset > 0 && a_coordinate(cellId, 0) - xOffset > 0) {
12797 angle = 180 - radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
12798 } else if(a_coordinate(cellId, 1) - yOffset > 0 && a_coordinate(cellId, 0) - xOffset < 0) {
12799 angle = -radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
12800 } else if(a_coordinate(cellId, 1) - yOffset < 0 && a_coordinate(cellId, 0) - xOffset > 0) {
12801 angle = 180.0 - radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
12802 } else {
12803 angle = 360.0 - radToDeg * atan((a_coordinate(cellId, 1) - yOffset) / (a_coordinate(cellId, 0) - xOffset));
12804 }
12805
12806 MFloat dx = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[0] - xOffset;
12807 MFloat dy = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[1] - yOffset;
12808 angle = 180.0 - (radToDeg * atan2(dy, dx));
12809
12810 sortedAngle.p[noCells] = angle;
12811 sortedList.p[noCells] = cellId;
12812 noCells++;
12813 }
12814
12815 for(MInt i = 0; i < noCells - 1; i++) {
12816 for(MInt j = i + 1; j < noCells; j++) {
12817 if(sortedAngle.p[j] < sortedAngle.p[i]) {
12818 iTmp = sortedList.p[i];
12819 sortedList.p[i] = sortedList.p[j];
12820 sortedList.p[j] = iTmp;
12821 fTmp = sortedAngle.p[i];
12822 sortedAngle.p[i] = sortedAngle.p[j];
12823 sortedAngle.p[j] = fTmp;
12824 }
12825 }
12826 }
12827
12828
12829 ofstream ofl2;
12830 ofl2.open(fileName);
12831 if(ofl2.is_open() && ofl2.good()) {
12832 for(MInt c = 0; c < noCells; c++) {
12833 cellId = sortedList.p[c];
12834
12835 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
12836 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
12837 if(a_isHalo(cellId)) continue;
12838 if(a_isPeriodic(cellId)) continue;
12839
12840 MInt bndryId = a_bndryId(cellId);
12841 angle = sortedAngle.p[c];
12842 MFloat rhoSurface = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->RHO];
12843 MFloat pSurface = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->P];
12844 MFloat T = sysEqn().temperature_ES(rhoSurface, pSurface);
12845 MFloat mue = SUTHERLANDLAW(T);
12846
12847 dist = F0;
12848 for(MInt i = 0; i < nDim; i++) {
12849 dist += (a_coordinate(cellId, i) - m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[i])
12850 * m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i];
12851 }
12852 dist = fabs(dist);
12853
12854 MFloat shear2[3] = {F0, F0, F0};
12855 for(MInt i = 0; i < nDim; i++) {
12856 MFloat grad = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_normalDeriv[PV->VV[i]];
12857 shear[i] = mue * grad;
12858 }
12859
12860 MFloat cf = (m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[1] * shear[0]
12861 - m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[0] * shear[1])
12862 / (F1B2 * rhoU2 * m_referenceLength * sysEqn().m_Re0);
12863
12864 u = a_pvariable(cellId, PV->VV[0]);
12865 v = a_pvariable(cellId, PV->VV[1]);
12866 ma = sqrt(u * u + v * v);
12867 ma /= sysEqn().speedOfSound(rhoSurface, pSurface);
12868 cp = (pSurface - m_PInfinity) / (F1B2 * rhoU2);
12869
12870 MFloat dudn[nDim];
12871 MFloat nablaPhi[nDim];
12872 MFloat nablaAbs = F0;
12873 for(MInt i = 0; i < nDim; i++) {
12874 nablaPhi[i] = (a_levelSetValuesMb(c_neighborId(cellId, 2 * i + 1), 0)
12875 - a_levelSetValuesMb(c_neighborId(cellId, 2 * i), 0))
12876 / (F2 * c_cellLengthAtLevel(a_level(cellId)));
12877 nablaAbs += POW2(nablaPhi[i]);
12878 }
12879 nablaAbs = sqrt(nablaAbs);
12880 for(MInt i = 0; i < nDim; i++) {
12881 nablaPhi[i] /= nablaAbs;
12882 }
12883
12884 for(MInt i = 0; i < nDim; i++) {
12885 for(MInt j = 0; j < nDim; j++) {
12886 gradV[i][j] = F0;
12887 }
12888 gradP[i] = F0;
12889 dudn[i] = F0;
12890 }
12891
12892 MFloat dundn = F0;
12893 for(MInt i = 0; i < nDim; i++) {
12894 dudn[i] = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_normalDeriv[PV->VV[i]];
12895 }
12896
12897 tmp = F0;
12898 for(MInt i = 0; i < nDim; i++) {
12899 tmp += m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i] * gradP[i];
12900 }
12901 for(MInt i = 0; i < nDim; i++) {
12902 gradP[1] = -m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[0] * gradP[1]
12903 + m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[1] * gradP[0];
12904 }
12905 gradP[0] = tmp;
12906
12907 MFloat u2 = m_bodyVelocity[0];
12908 MFloat v2 = m_bodyVelocity[1];
12909 for(MInt j = 0; j < nDim; j++) {
12911 * m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[j] * 0.5
12912 * (a_slope(cellId, PV->U, j) + gradV[PV->U][j]);
12914 * m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[j] * 0.5
12915 * (a_slope(cellId, PV->V, j) + gradV[PV->V][j]);
12916 }
12917
12918
12919 vorticity = (gradV[1][0] - gradV[0][1]) / m_UInfinity;
12920
12921 MFloat bodyRotation[3] = {0};
12922 getBodyRotation(0, bodyRotation);
12923
12924 const MFloat p0 = a_coordinate(cellId, 0);
12925 const MFloat q0 = a_coordinate(cellId, 1);
12926 const MFloat p = cos(-bodyRotation[2]) * p0 - sin(-bodyRotation[2]) * q0 + F1B4;
12927
12928 ofl2 << cellId << " "; // 1
12929 ofl2 << angle << " "; // 2
12930 ofl2 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume << " "; // 3
12931 ofl2 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_area << " "; // 4
12932 ofl2 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[0] << " "; // 5
12933 ofl2 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[1] << " "; // 6
12934 ofl2 << m_volumeFraction[bndryId] << " "; // 7
12935 ofl2 << dist << " "; // 8
12936 ofl2 << pSurface << " "; // 9
12937 ofl2 << rhoSurface << " "; // 10
12938 ofl2 << cp << " "; // 11
12939 ofl2 << shear[0] << " "; // 12
12940 ofl2 << shear[1] << " "; // 13
12941 ofl2 << a_pvariable(cellId, PV->P) << " "; // 14
12942 ofl2 << vorticity << " "; // 15
12943 ofl2 << gradP[0] << " "; // 18
12944 ofl2 << gradP[1] << " "; // 19
12945 ofl2 << dudn[0] << " "; // 20
12946 ofl2 << dudn[1] << " "; // 21
12947 ofl2 << (u - m_bodyVelocity[0]) / dist << " "; // 22
12948 ofl2 << (v - m_bodyVelocity[1]) / dist << " "; // 23
12949 // ofl2 << (u-m_bodyVelocity[0])/getLevelSetValueSphere(cellId) << " "; //24
12950 ofl2 << (u2 - m_bodyVelocity[0]) / (0.5 * c_cellLengthAtLevel(maxRefinementLevel())) << " "; // 25
12951 ofl2 << (v2 - m_bodyVelocity[1]) / (0.5 * c_cellLengthAtLevel(maxRefinementLevel())) << " "; // 26
12952 ofl2 << dundn << " "; // 27
12953 ofl2 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[0] << " "; // 28
12954 ofl2 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[1] << " "; // 29
12955 ofl2 << shear2[0] << " "; // 30
12956 ofl2 << shear2[1] << " "; // 31
12957 ofl2 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->U] << " "; // 32
12958 ofl2 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->V] << " "; // 33
12959 ofl2 << a_coordinate(cellId, 0) << " "; // 34
12960 ofl2 << a_coordinate(cellId, 1) << " "; // 35
12961 ofl2 << cf << " "; // 36
12962 ofl2 << p << " "; // 37
12963 ofl2 << globalTimeStep << " "; // 38
12964 ofl2 << nablaPhi[0] << " "; // 39
12965 ofl2 << nablaPhi[1] << " "; // 40
12966 ofl2 << endl;
12967 }
12968
12969 ofl2.close();
12970 ofl2.clear();
12971 } else {
12972 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing!" << endl;
12973 }
12974}
void getBodyRotation(const MInt bodyId, MFloat *bodyRotation)
T cos(const T a, const T b, const T x)
Cosine slope filter.
Definition: filter.h:125

◆ logData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::logData ( )

◆ logOutput()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::logOutput
Author
Lennart Schneiders

Definition at line 1483 of file fvmbcartesiansolverxd.cpp.

1483 {
1484 TRACE();
1485
1486 MInt noCells_solver = m_cells.size();
1487 MInt noCells_grid = c_noCells();
1488 MInt nosplitchilds = m_totalnosplitchilds;
1489 MInt nosurfaces = m_noSurfaces;
1490 MInt noboundarycells = m_noBndryCells;
1491 MInt nolsmbcells = m_noLsMbBndryCells;
1492
1494 MPI_Allreduce(MPI_IN_PLACE, &noCells_solver, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE ",
1495 "noCells_solver");
1496 MPI_Allreduce(MPI_IN_PLACE, &noCells_grid, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE ", "noCells_grid");
1497 MPI_Allreduce(MPI_IN_PLACE, &nosplitchilds, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE ", "nosplitchilds");
1498 MPI_Allreduce(MPI_IN_PLACE, &nosurfaces, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE ", "nosurfaces");
1499 MPI_Allreduce(MPI_IN_PLACE, &noboundarycells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE ",
1500 "noboundarycells");
1501 MPI_Allreduce(MPI_IN_PLACE, &nolsmbcells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE ", "nolsmbcells");
1502
1503 m_log << "======================================================" << endl << endl;
1504 m_log << "Grid summary at time step " << globalTimeStep << endl << endl;
1505 m_log << setfill(' ');
1506 m_log << "number of grid-cells " << setw(7) << noCells_grid << endl;
1507 m_log << "number of fv-cells " << setw(7) << noCells_solver << endl;
1508 m_log << "number of splitchilds " << setw(7) << nosplitchilds << endl;
1509 m_log << "number of surfaces " << setw(7) << nosurfaces << endl;
1510 m_log << "number of boundary cells " << setw(7) << noboundarycells << endl;
1511 m_log << "number of moving boundary cells " << setw(7) << nolsmbcells << endl;
1512 m_log << "======================================================" << endl << endl;
1513 }
1514}

◆ matrixProduct()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::matrixProduct ( MFloatScratchSpace C,
MFloatScratchSpace A,
MFloatScratchSpace B 
)
inlinestatic
Author
Lennart Schneiders

Definition at line 4152 of file fvmbcartesiansolverxd.cpp.

4153 {
4154 ASSERT(A.size1() == B.size0(), "");
4155 C.fill(F0);
4156 for(MInt i = 0; i < C.size0(); i++) {
4157 for(MInt k = 0; k < C.size1(); k++) {
4158 for(MInt j = 0; j < A.size1(); j++) {
4159 C(i, k) += A(i, j) * B(j, k);
4160 }
4161 }
4162 }
4163}
MInt size1() const
Definition: scratch.h:299
MInt size0() const
Definition: scratch.h:298

◆ matrixProductTranspose()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::matrixProductTranspose ( MFloatScratchSpace C,
MFloatScratchSpace A,
MFloatScratchSpace B 
)
inlinestatic
Author
Lennart Schneiders

Definition at line 4171 of file fvmbcartesiansolverxd.cpp.

4172 {
4173 ASSERT(A.size1() == B.size1(), "");
4174 C.fill(F0);
4175 for(MInt i = 0; i < C.size0(); i++) {
4176 for(MInt k = 0; k < C.size1(); k++) {
4177 for(MInt j = 0; j < A.size1(); j++) {
4178 C(i, k) += A(i, j) * B(k, j);
4179 }
4180 }
4181 }
4182}

◆ matrixProductTranspose2()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::matrixProductTranspose2 ( MFloatScratchSpace C,
MFloatScratchSpace A,
MFloatScratchSpace B 
)
inlinestatic
Author
Lennart Schneiders

Definition at line 4190 of file fvmbcartesiansolverxd.cpp.

4191 {
4192 ASSERT(A.size0() == B.size0(), "");
4193 C.fill(F0);
4194 for(MInt i = 0; i < C.size0(); i++) {
4195 for(MInt k = 0; k < C.size1(); k++) {
4196 for(MInt j = 0; j < A.size0(); j++) {
4197 C(i, k) += A(j, i) * B(j, k);
4198 }
4199 }
4200 }
4201}

◆ matrixVectorProduct()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::matrixVectorProduct ( MFloat c,
MFloatScratchSpace A,
MFloat b 
)
inlinestatic
Author
Lennart Schneiders

Definition at line 4209 of file fvmbcartesiansolverxd.cpp.

4209 {
4210 for(MInt i = 0; i < A.size0(); i++) {
4211 c[i] = F0;
4212 for(MInt j = 0; j < A.size1(); j++) {
4213 c[i] += A(i, j) * b[j];
4214 }
4215 }
4216}

◆ matrixVectorProductTranspose()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::matrixVectorProductTranspose ( MFloat c,
MFloatScratchSpace A,
MFloat b 
)
inlinestatic
Author
Lennart Schneiders

Definition at line 4224 of file fvmbcartesiansolverxd.cpp.

4225 {
4226 for(MInt i = 0; i < A.size1(); i++) {
4227 c[i] = F0;
4228 for(MInt j = 0; j < A.size0(); j++) {
4229 c[i] += A(j, i) * b[j];
4230 }
4231 }
4232}

◆ maxResidual()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::maxResidual ( MInt  mode = 0)
overridevirtual

This function computes the maxResidual using Res = deltaT/(CFL*VolOfCell) * |RHS|

checks if the computed max density residual is below the convergence criterion and returns boolean variable

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 19176 of file fvmbcartesiansolverxd.cpp.

19176 {
19177 TRACE();
19178
19180 return true;
19181 }
19182
19183 if(mode == 0 && (!m_trackMovingBndry || globalTimeStep < m_trackMbStart || globalTimeStep > m_trackMbEnd)) {
19184 // NOTE: calling the original Fv residual function for stationary problems where the residual
19185 // can be used/outputted for convergence studies
19187 }
19188
19189 ScratchSpace<MFloat> bbox(m_noDirs, AT_, "bbox");
19190 for(MInt i = 0; i < nDim; i++) {
19191 bbox[i] = std::numeric_limits<MFloat>::max();
19192 bbox[nDim + i] = -std::numeric_limits<MFloat>::max();
19193 }
19194
19195 const MInt oldRKStep[5] = {4, 0, 1, 2, 3};
19196 MBool nan = false;
19197 MInt counter = 0;
19198 MFloat maxR = -F1;
19199 MInt maxRC = -1;
19200 MInt nanC = -1;
19201
19202 const MInt size = a_noCells();
19203 for(MInt cellId = size; cellId--;) {
19204 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19205 if(a_isBndryGhostCell(cellId)) continue;
19206 if(a_isHalo(cellId)) continue;
19207 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
19208 if(a_bndryId(cellId) == -2) continue;
19209
19210 if(fabs(a_rightHandSide(cellId, CV->RHO)) > maxR) {
19211 maxR = fabs(a_rightHandSide(cellId, CV->RHO));
19212 maxRC = cellId;
19213 }
19214
19215 if((!(a_rightHandSide(cellId, CV->RHO) >= F0 || a_rightHandSide(cellId, CV->RHO) < F0))) {
19216 m_log << "RHS[rho] is " << a_rightHandSide(cellId, CV->RHO) << " in cell " << cellId << "(" << a_bndryId(cellId)
19217 << ") "
19218 " "
19219 << a_hasProperty(cellId, SolverCell::IsInactive) << " " << a_levelSetValuesMb(cellId, 0)
19220 << " vol:" << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << " / ";
19221 for(MInt i = 0; i < nDim; i++)
19222 m_log << " " << a_coordinate(cellId, i);
19223 m_log << " " << a_hasProperty(cellId, SolverCell::NearWall);
19224 m_log << " / " << a_noReconstructionNeighbors(cellId);
19225 m_log << " " << a_isHalo(cellId);
19226 m_log << " " << a_hasProperty(cellId, SolverCell::IsNotGradient);
19227 IF_CONSTEXPR(nDim == 2) {
19228 m_log << " p7: " << a_isHalo(c_neighborId(cellId, 0)) << " " << a_isHalo(c_neighborId(cellId, 1)) << " "
19229 << a_isHalo(c_neighborId(cellId, 2)) << " " << a_isHalo(c_neighborId(cellId, 3));
19230 }
19231 else IF_CONSTEXPR(nDim == 3) {
19232 m_log << " p7: " << a_isHalo(c_neighborId(cellId, 0)) << " " << a_isHalo(c_neighborId(cellId, 1)) << " "
19233 << a_isHalo(c_neighborId(cellId, 2)) << " " << a_isHalo(c_neighborId(cellId, 3)) << " "
19234 << a_isHalo(c_neighborId(cellId, 4)) << " " << a_isHalo(c_neighborId(cellId, 5));
19235 }
19236 m_log << endl;
19237 for(MInt i = 0; i < nDim; i++) {
19238 bbox[i] = mMin(bbox[i], a_coordinate(cellId, i));
19239 bbox[nDim + i] = mMax(bbox[nDim + i], a_coordinate(cellId, i));
19240 }
19241 nan = true;
19242 nanC = cellId;
19243 counter++;
19244 }
19245
19246 if(counter > 1000) {
19247 m_log << "More than 1000 nan's; output suspended." << endl;
19248 break;
19249 }
19250 }
19251
19252#ifdef _MB_DEBUG_
19253 MPI_Allreduce(MPI_IN_PLACE, &bbox[0], nDim, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_, "MPI_IN_PLACE", "bbox[0]");
19254 MPI_Allreduce(MPI_IN_PLACE, &bbox[nDim], nDim, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "bbox[nDim]");
19255#endif
19256
19257 if(nan) {
19258 if(maxRC > -1) {
19259 m_log << "Maximum residual at time step " << globalTimeStep << " is " << maxR << " in cell " << maxRC << " at";
19260 for(MInt i = 0; i < nDim; i++)
19261 m_log << " " << a_coordinate(maxRC, i);
19262 m_log << ", res: " << scientific;
19263 for(MInt v = 0; v < m_noFVars; v++)
19264 m_log << " " << a_rightHandSide(maxRC, v);
19265 m_log << ", vol.: " << a_cellVolume(maxRC);
19266 m_log << ", vol.frac.: " << a_cellVolume(maxRC) / c_cellLengthAtLevel(a_level(maxRC));
19267 m_log << endl;
19268 }
19269
19270 MFloat minVol = std::numeric_limits<MFloat>::max();
19271 MFloat minVolFrac = std::numeric_limits<MFloat>::max();
19272 MInt partitionCell = -1;
19273 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
19274 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
19275 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume < minVol) {
19276 minVolFrac = m_volumeFraction[bndryId];
19277 minVol = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
19278 partitionCell = cellId;
19279 }
19280 }
19281 if(partitionCell > -1) {
19282 IF_CONSTEXPR(nDim == 2) {
19283 m_log << "Smallest cell: " << partitionCell << " " << minVol << " " << minVolFrac << " / "
19284 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(partitionCell)].m_srfcs[0]->m_normalVector[0] << " "
19285 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(partitionCell)].m_srfcs[0]->m_normalVector[1] << " "
19286 << " / " << a_rightHandSide(partitionCell, CV->RHO) << " " << a_rightHandSide(partitionCell, CV->RHO_U)
19287 << endl;
19288 }
19289 else IF_CONSTEXPR(nDim == 3) {
19290 m_log << "Smallest cell: " << partitionCell << " " << minVol << " " << minVolFrac << " / "
19291 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(partitionCell)].m_srfcs[0]->m_normalVector[0] << " "
19292 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(partitionCell)].m_srfcs[0]->m_normalVector[1] << " "
19293 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(partitionCell)].m_srfcs[0]->m_normalVector[2] << " "
19294 << " / " << a_rightHandSide(partitionCell, CV->RHO) << " " << a_rightHandSide(partitionCell, CV->RHO_U)
19295 << endl;
19296 }
19297 }
19298 cerr << "========================" << endl;
19299 cerr << "time step " << globalTimeStep << ", Runge Kutta step " << oldRKStep[m_RKStep] << ", solver " << solverId()
19300 << endl;
19301 cerr << domainId() << ": Solution diverged (e.g. " << c_globalId(nanC) << ") in region ";
19302 for(MInt i = 0; i < nDim; i++) {
19303 cerr << "[" << bbox[i] << "," << bbox[nDim + i] << "]";
19304 if(i < nDim - 1) cerr << "x";
19305 }
19306 cerr << ". Quit." << endl;
19307 m_solutionDiverged = true;
19308 }
19309
19310 MPI_Allreduce(MPI_IN_PLACE, &m_solutionDiverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
19311 "m_solutionDiverged");
19312
19313 if(m_solutionDiverged) {
19314#ifdef _MB_DEBUG_
19315 m_log << "=========== BOUNDARY LOG ================" << endl;
19316 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
19317 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
19318 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
19319 m_log << bndryId << " " << cellId;
19320 for(MInt dir = 0; dir < m_noDirs; dir++) {
19321 MInt cId = (c_neighborId(cellId, dir) > -1) ? m_bndryCandidateIds[c_neighborId(cellId, dir)] : -1;
19322 m_log << " / " << dir << " " << a_hasNeighbor(cellId, dir) << " " << c_neighborId(cellId, dir) << " " << cId;
19323 }
19324 m_log << endl;
19325 }
19326#endif
19328 /*
19329 #ifdef _MB_DEBUG_
19330 for ( MInt cellId = 0; cellId < a_noCells(); cellId++ ) {
19331 a_hasProperty( cellId , SolverCell::IsOnCurrentMGLevel) = true;
19332 }
19333 stringstream filen;
19334 filen << "out/QDIV_" << domainId() << ".vtk";
19335 m_fvBndryCnd->recorrectCellCoordinates();
19336 extractPointIdsFromGrid( m_extractedCells, m_gridPoints, true, m_splitChildToSplitCell);
19337 for( MInt c = 0; c < m_extractedCells->size(); c++ ) {
19338 a_pvariable(m_extractedCells->a[ c ].m_cellId, PV->RHO) = a_levelSetValuesMb(m_extractedCells->a[ c
19339 ].m_cellId, 0);
19340 }
19341 writeVtkOutput( (filen.str()).c_str() );
19342 m_fvBndryCnd->rerecorrectCellCoordinates();
19343 if ( m_extractedCells ) { delete m_extractedCells; m_extractedCells = nullptr; }
19344 if ( m_gridPoints ) { delete m_gridPoints; m_gridPoints = nullptr; }
19345 #endif
19346 */
19347 MPI_Barrier(mpiComm(), AT_);
19348 mTerm(1, AT_, "Solution diverged.");
19349 } else {
19350 // saveSolverSolution(1); MPI_Barrier(mpiComm(), AT_ ); mTerm(0,AT_, "test");
19351 if(nan) mTerm(1, AT_, "Solution diverged.");
19352
19353 return true;
19354 }
19355
19356 return false;
19357}
virtual MBool maxResidual(MInt mode=0)
Computes the global root-mean-square residual. The residual is defined as time derivative of conserva...
MInt m_residualInterval
The number of timesteps before writing the next residual.
Definition: solver.h:87

◆ moveSurface()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::moveSurface ( const MInt  toSrfcId,
const MInt  fromSrfcId 
)
Author
Lennart Schneiders

Definition at line 16369 of file fvmbcartesiansolverxd.cpp.

16369 {
16370 ASSERT((fromSrfcId > -1) && (toSrfcId > -1) && (fromSrfcId < a_noSurfaces()) && (toSrfcId < a_noSurfaces()),
16371 "moveSurface(..) error");
16372
16373 const MInt ori = a_surfaceOrientation(fromSrfcId);
16374 a_surfaceOrientation(toSrfcId) = ori;
16375
16376 const MInt nghbrId0 = a_surfaceNghbrCellId(fromSrfcId, 0);
16377 const MInt nghbrId1 = a_surfaceNghbrCellId(fromSrfcId, 1);
16378 ASSERT(nghbrId0 > -1 && nghbrId1 > -1, "");
16379 ASSERT(nghbrId0 < a_noCells() && nghbrId1 < a_noCells(), "");
16380
16381 // for split faces, m_cellSurfaceMapping[ cell ][ splitFace ] does not point to the surface, connection only
16382 // 1-sided...
16383 ASSERT(((m_cellSurfaceMapping[nghbrId0][2 * ori + 1] > -1) && (m_cellSurfaceMapping[nghbrId1][2 * ori] > -1))
16384 || (a_bndryId(nghbrId0) > -1 && a_bndryId(nghbrId1) > -1) || a_level(nghbrId0) != a_level(nghbrId1),
16385 "");
16386
16387 if(nghbrId0 > -1) {
16388 if(m_cellSurfaceMapping[nghbrId0][2 * ori + 1] > -1) {
16389 ASSERT(m_cellSurfaceMapping[nghbrId0][2 * ori + 1] == fromSrfcId,
16390 to_string(m_cellSurfaceMapping[nghbrId1][2 * ori + 1]));
16391 m_cellSurfaceMapping[nghbrId0][2 * ori + 1] = toSrfcId;
16392 }
16393 }
16394 if(nghbrId1 > -1) {
16395 if(m_cellSurfaceMapping[nghbrId1][2 * ori] > -1) {
16396 ASSERT(m_cellSurfaceMapping[nghbrId1][2 * ori] == fromSrfcId, to_string(m_cellSurfaceMapping[nghbrId1][2 * ori]));
16397 m_cellSurfaceMapping[nghbrId1][2 * ori] = toSrfcId;
16398 }
16399 }
16400
16401 if(a_bndryId(nghbrId0) > -1) {
16402 // for split faces, m_associatedSrfc[ splitFace ] does not point to the surface, connection only 1-sided...
16403 // ASSERT( m_bndryCells->a[ a_bndryId( nghbrId0 ) ].m_associatedSrfc[ 2*ori + 1 ] == fromSrfcId,
16404 // a_bndryId( nghbrId0 ) << " " << m_bndryCells->a[ a_bndryId( nghbrId0 )
16405 // ].m_associatedSrfc[ 2*ori + 1 ] << " " << fromSrfcId );
16406 if(m_bndryCells->a[a_bndryId(nghbrId0)].m_associatedSrfc[2 * ori + 1] == fromSrfcId)
16407 m_bndryCells->a[a_bndryId(nghbrId0)].m_associatedSrfc[2 * ori + 1] = toSrfcId;
16408 MInt bndryId = a_bndryId(nghbrId0);
16409 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
16410 for(MInt i = 0; i < nDim; i++) {
16411 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] == fromSrfcId) {
16412 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = toSrfcId;
16413 }
16414 }
16415 }
16416 }
16417 if(a_bndryId(nghbrId1) > -1) {
16418 // for split faces, m_associatedSrfc[ splitFace ] does not point to the surface, connection only 1-sided...
16419 // ASSERT( m_bndryCells->a[ a_bndryId( nghbrId1 ) ].m_associatedSrfc[ 2*ori ] == fromSrfcId,
16420 // a_bndryId( nghbrId1 ) << " " << m_bndryCells->a[ a_bndryId( nghbrId0 )
16421 // ].m_associatedSrfc[ 2*ori + 1 ] << " " << fromSrfcId );
16422 if(m_bndryCells->a[a_bndryId(nghbrId1)].m_associatedSrfc[2 * ori] == fromSrfcId)
16423 m_bndryCells->a[a_bndryId(nghbrId1)].m_associatedSrfc[2 * ori] = toSrfcId;
16424 MInt bndryId = a_bndryId(nghbrId1);
16425 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
16426 for(MInt i = 0; i < nDim; i++) {
16427 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] == fromSrfcId) {
16428 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = toSrfcId;
16429 }
16430 }
16431 }
16432 }
16433
16434 if(m_splitSurfaces.erase(fromSrfcId)) m_splitSurfaces.insert(toSrfcId);
16435
16436 a_surfaceNghbrCellId(toSrfcId, 0) = nghbrId0;
16437 a_surfaceNghbrCellId(toSrfcId, 1) = nghbrId1;
16438 a_surfaceNghbrCellId(fromSrfcId, 0) = -1;
16439 a_surfaceNghbrCellId(fromSrfcId, 1) = -1;
16440
16441
16442 for(MInt i = 0; i < nDim; i++) {
16443 a_surfaceCoordinate(toSrfcId, i) = a_surfaceCoordinate(fromSrfcId, i);
16444 }
16445 a_surfaceArea(toSrfcId) = a_surfaceArea(fromSrfcId);
16446
16448 a_surfaceFactor(toSrfcId, 0) = a_surfaceFactor(fromSrfcId, 0);
16449 a_surfaceFactor(toSrfcId, 1) = a_surfaceFactor(fromSrfcId, 1);
16450
16451 for(MInt i = 0; i < nDim; i++) {
16452 a_surfaceDeltaX(toSrfcId, i) = a_surfaceDeltaX(fromSrfcId, i);
16453 a_surfaceDeltaX(toSrfcId, nDim + i) = a_surfaceDeltaX(fromSrfcId, nDim + i);
16454 }
16455
16456 a_surfaceBndryCndId(toSrfcId) = a_surfaceBndryCndId(fromSrfcId);
16457
16458 for(MInt v = 0; v < m_noCVars; v++) {
16459 a_surfaceVariable(toSrfcId, 0, v) = a_surfaceVariable(fromSrfcId, 0, v);
16460 a_surfaceVariable(toSrfcId, 1, v) = a_surfaceVariable(fromSrfcId, 1, v);
16461 }
16462
16464}

◆ Muscl()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::Muscl ( MInt  timerId = -1)
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 2207 of file fvmbcartesiansolverxd.cpp.

2207 {
2208 TRACE();
2209
2211
2212 RECORD_TIMER_START(m_timers[Timers::MusclReconst]);
2214 RECORD_TIMER_STOP(m_timers[Timers::MusclReconst]);
2215
2216 RECORD_TIMER_START(m_timers[Timers::MusclCopy]);
2217 m_fvBndryCnd->copySlopesToSmallCells();
2218 RECORD_TIMER_STOP(m_timers[Timers::MusclCopy]);
2219
2220 RECORD_TIMER_START(m_timers[Timers::MusclGhostSlopes]);
2222 RECORD_TIMER_STOP(m_timers[Timers::MusclGhostSlopes]);
2223
2224 RECORD_TIMER_START(m_timers[Timers::MusclCutSlopes]);
2225 m_fvBndryCnd->updateCutOffSlopesInviscid();
2226 RECORD_TIMER_STOP(m_timers[Timers::MusclCutSlopes]);
2227
2228 RECORD_TIMER_START(m_timers[Timers::MusclReconstSrfc]);
2229 (this->*m_reconstructSurfaceData)(-1);
2230 RECORD_TIMER_STOP(m_timers[Timers::MusclReconstSrfc]);
2231
2232#ifdef _MB_DEBUG_
2233 m_solutionDiverged = false;
2234 for(MInt srfcId = a_noSurfaces(); srfcId--;) {
2235 {
2236 MInt nghbr0 = a_surfaceNghbrCellId(srfcId, 0);
2237 MInt nghbr1 = a_surfaceNghbrCellId(srfcId, 1);
2238 MInt ghost =
2239 (a_bndryId(mMin(nghbr0, nghbr1)) > -1)
2240 ? m_fvBndryCnd->m_bndryCells->a[a_bndryId(mMin(nghbr0, nghbr1))].m_srfcVariables[0]->m_ghostCellId
2241 : -2;
2242 MBool divd = false;
2243 for(MInt v = 0; v < m_noCVars; v++) {
2244 if(std::isnan(a_surfaceVariable(srfcId, 0, v)) || std::isnan(a_surfaceVariable(srfcId, 1, v))) divd = true;
2245 }
2246 if(a_surfaceVariable(srfcId, 0, PV->P) < F0 || a_surfaceVariable(srfcId, 1, PV->P) < F0
2247 || a_surfaceVariable(srfcId, 0, PV->RHO) < F0 || a_surfaceVariable(srfcId, 1, PV->RHO) < F0)
2248 divd = true;
2249 if(divd) {
2250 cerr << domainId() << ": surf var " << globalTimeStep << " " << srfcId << " " << c_globalId(nghbr0) << " "
2251 << c_globalId(nghbr1) << " /g " << ghost << " " << a_bndryId(nghbr0) << " " << a_bndryId(nghbr1) << " /bc "
2252 << a_surfaceBndryCndId(srfcId) << " /sp " << a_surfaceVariable(srfcId, 0, PV->P) << " "
2253 << a_surfaceVariable(srfcId, 1, PV->P) << " /vf "
2254 << a_cellVolume(nghbr0) / grid().gridCellVolume(a_level(nghbr0)) << " "
2255 << a_cellVolume(nghbr1) / grid().gridCellVolume(a_level(nghbr1)) << " /l " << a_level(nghbr0) << " "
2256 << a_level(nghbr1) << " /p15 " << a_isHalo(nghbr0) << " " << a_isHalo(nghbr1) << " /p7 "
2257 << a_hasProperty(nghbr0, SolverCell::IsNotGradient) << " "
2258 << a_hasProperty(nghbr1, SolverCell::IsNotGradient) << " /c " << a_surfaceCoordinate(srfcId, 0) << " "
2259 << a_surfaceCoordinate(srfcId, 1) << " " << a_surfaceCoordinate(srfcId, mMin(nDim - 1, 2)) << " /pc "
2260 << a_pvariable(nghbr0, PV->P) << " " << a_pvariable(nghbr1, PV->P) << " /p "
2261 << a_surfaceVariable(srfcId, 0, PV->P) << " " << a_surfaceVariable(srfcId, 1, PV->P) << " /rho "
2262 << a_surfaceVariable(srfcId, 0, PV->RHO) << " " << a_surfaceVariable(srfcId, 1, PV->RHO) << " /sl "
2263 << a_slope(nghbr0, PV->U, a_surfaceOrientation(srfcId)) << " "
2264 << a_slope(nghbr1, PV->U, a_surfaceOrientation(srfcId)) << " /ls " << a_levelSetValuesMb(nghbr0, 0) << " "
2265 << a_levelSetValuesMb(nghbr1, 0) << endl;
2266 m_solutionDiverged = true;
2267 }
2268 }
2269 }
2270 MPI_Allreduce(MPI_IN_PLACE, &m_solutionDiverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
2271 "m_solutionDiverged");
2272 if(m_solutionDiverged) {
2273 writeVtkXmlFiles("QOUT", "GEOM", false, true);
2274 MPI_Barrier(mpiComm(), AT_);
2275 mTerm(1, AT_,
2276 "Solution diverged after surface value computation @ " + to_string(m_RKStep) + "/"
2277 + to_string(globalTimeStep));
2278 }
2279#endif
2280
2281
2282 RECORD_TIMER_START(m_timers[Timers::MusclGhostSlopes]);
2284 m_fvBndryCnd->updateCutOffSlopesViscous();
2285 RECORD_TIMER_STOP(m_timers[Timers::MusclGhostSlopes]);
2286
2288}
void(FvCartesianSolverXD::* m_reconstructSurfaceData)(MInt)
std::array< MInt, Timers::_count > m_timers
void correctBoundarySurfaceVariablesMb()
sets boundary surface variables to their correct values

◆ noCellDataDlb()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::noCellDataDlb ( ) const
inlineoverridevirtual

Reimplemented from Solver.

Definition at line 1012 of file fvmbcartesiansolverxd.h.

1012 {
1013 if(grid().isActive()) {
1014 return CellDataDlb::count;
1015 } else {
1016 return 0;
1017 }
1018 };

◆ outputPolyData() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::outputPolyData ( const MInt  cellId,
const std::vector< polyCutCell > *  cutCells,
const std::vector< polyEdge2D > *  edges,
const std::vector< polyVertex > *  vertices,
MInt  set 
)
private
Author

Definition at line 33888 of file fvmbcartesiansolverxd.cpp.

33890 {
33891 const MChar* fileName = "polyData_";
33892 stringstream fileName2;
33893 fileName2 << fileName << cellId << "_s" << set << "_D" << domainId();
33894 ofstream ofl;
33895 ofl.open((fileName2.str()).c_str(), ofstream::trunc);
33896
33897 if(ofl) {
33898 // set fixed floating point output
33899 ofl.setf(ios::fixed);
33900 ofl.precision(7);
33901
33902 ofl << "VERTICES:" << endl;
33903 for(MInt v = 0; (unsigned)v < (*vertices).size(); v++) {
33904 ofl << v << ": " << endl;
33905 ofl << "coordinates: " << (*vertices)[v].coordinates[0] << " " << (*vertices)[v].coordinates[1] << endl;
33906 ofl << "pointId: " << (*vertices)[v].pointId;
33907 ofl << ", pointType: " << (*vertices)[v].pointType << endl;
33908 ofl << "edges: ";
33909 for(MInt e = 0; (unsigned)e < (*vertices)[v].edges.size(); e++)
33910 ofl << (*vertices)[v].edges[e] << " ";
33911 ofl << endl << endl;
33912 }
33913
33914 ofl << endl << "EDGES:" << endl;
33915 for(MInt e = 0; (unsigned)e < (*edges).size(); e++) {
33916 ofl << e << ": " << endl;
33917 ofl << "vertices: " << (*edges)[e].vertices[0] << " " << (*edges)[e].vertices[1] << endl;
33918 ofl << "edgeId: " << (*edges)[e].edgeId;
33919 ofl << ", edgeType: " << (*edges)[e].edgeType;
33920 ofl << ", bodyId: " << (*edges)[e].bodyId;
33921 ofl << ", cutCell: " << (*edges)[e].cutCell << endl;
33922 ofl << "area: " << (*edges)[e].area << endl;
33923 ofl << "center: " << (*edges)[e].center[0] << " " << (*edges)[e].center[1] << endl;
33924 ofl << "normal: " << (*edges)[e].normal[0] << " " << (*edges)[e].normal[1] << endl;
33925 ofl << "w: " << (*edges)[e].w << endl;
33926 ofl << endl << endl;
33927 }
33928
33929 ofl << endl << "CUT CELLS:" << endl;
33930 for(MInt c = 0; (unsigned)c < (*cutCells).size(); c++) {
33931 ofl << c << ": " << endl;
33932 ofl << "volume: " << (*cutCells)[c].volume << endl;
33933 ofl << "center: " << (*cutCells)[c].center[0] << " " << (*cutCells)[c].center[1] << endl;
33934 ofl << "cartesianCell: " << (*cutCells)[c].cartesianCell << endl;
33935 ofl << "edges: ";
33936 for(MInt f = 0; (unsigned)f < (*cutCells)[c].faces_edges.size(); f++)
33937 ofl << (*cutCells)[c].faces_edges[f] << " ";
33938 ofl << endl << endl;
33939 }
33940
33941 ofl.close();
33942 }
33943}
char MChar
Definition: maiatypes.h:56

◆ outputPolyData() [2/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==3, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::outputPolyData ( const MInt  cellId,
const std::vector< polyCutCell > *  cutCells,
const std::vector< polyFace > *  faces,
const std::vector< polyEdge3D > *  edges,
const std::vector< polyVertex > *  vertices,
MInt  set 
)
private
Author

Definition at line 33952 of file fvmbcartesiansolverxd.cpp.

33955 {
33956 const MChar* fileName = "polyData_";
33957 stringstream fileName2;
33958 fileName2 << fileName << cellId << "_s" << set << "_D" << domainId();
33959 ofstream ofl;
33960 ofl.open((fileName2.str()).c_str(), ofstream::trunc);
33961
33962 if(ofl) {
33963 // set fixed floating point output
33964 ofl.setf(ios::fixed);
33965 ofl.precision(20);
33966
33967 ofl << "VERTICES:" << endl;
33968 for(MInt v = 0; (unsigned)v < (*vertices).size(); v++) {
33969 ofl << v << ": " << endl;
33970 ofl << "coordinates: " << (*vertices)[v].coordinates[0] << " " << (*vertices)[v].coordinates[1] << " "
33971 << (*vertices)[v].coordinates[2] << endl;
33972 ofl << "pointId: " << (*vertices)[v].pointId;
33973 ofl << ", pointType: " << (*vertices)[v].pointType << endl;
33974 ofl << "surfaceIdentificators: ";
33975 for(std::set<MInt>::iterator it = (*vertices)[v].surfaceIdentificators.begin();
33976 it != (*vertices)[v].surfaceIdentificators.end();
33977 it++)
33978 ofl << *it << " ";
33979 ofl << endl;
33980 ofl << "edges: ";
33981 for(MInt e = 0; (unsigned)e < (*vertices)[v].edges.size(); e++)
33982 ofl << (*vertices)[v].edges[e] << " ";
33983 ofl << endl << endl;
33984 }
33985
33986 ofl << endl << "EDGES:" << endl;
33987 for(MInt e = 0; (unsigned)e < (*edges).size(); e++) {
33988 ofl << e << ": " << endl;
33989 ofl << "vertices: " << (*edges)[e].vertices[0] << " " << (*edges)[e].vertices[1] << endl;
33990 ofl << "faces: " << (*edges)[e].face[0] << " " << (*edges)[e].face[1] << endl;
33991 ofl << "edgeId: " << (*edges)[e].edgeId;
33992 ofl << ", edgeType: " << (*edges)[e].edgeType << endl;
33993 ofl << endl << endl;
33994 }
33995
33996 ofl << endl << "FACES:" << endl;
33997 for(MInt f = 0; (unsigned)f < (*faces).size(); f++) {
33998 ofl << f << ": " << endl;
33999 ofl << "area: " << (*faces)[f].area << endl;
34000 ofl << "center: " << (*faces)[f].center[0] << " " << (*faces)[f].center[1] << " " << (*faces)[f].center[2]
34001 << endl;
34002 ofl << "normal: " << (*faces)[f].normal[0] << " " << (*faces)[f].normal[1] << " " << (*faces)[f].normal[2]
34003 << endl;
34004 ofl << "w: " << (*faces)[f].w << endl;
34005 ofl << "faceId: " << (*faces)[f].faceId;
34006 ofl << ", faceType: " << (*faces)[f].faceType << endl;
34007 ofl << "bodyId: " << (*faces)[f].bodyId << endl;
34008 ofl << "setIndex: " << (*faces)[f].tmpSetIndex << endl;
34009 ofl << "cutCell: " << (*faces)[f].cutCell << endl;
34010 ofl << "edges: ";
34011 for(MInt e = 0; (unsigned)e < (*faces)[f].edges.size(); e++)
34012 ofl << (*faces)[f].edges[e].first << ", dir " << (*faces)[f].edges[e].second << " ";
34013 ofl << endl << endl;
34014 }
34015
34016 ofl << endl << "CUT CELLS:" << endl;
34017 for(MInt c = 0; (unsigned)c < (*cutCells).size(); c++) {
34018 ofl << c << ": " << endl;
34019 ofl << "volume: " << (*cutCells)[c].volume << endl;
34020 ofl << "center: " << (*cutCells)[c].center[0] << " " << (*cutCells)[c].center[1] << " "
34021 << (*cutCells)[c].center[2] << endl;
34022 ofl << "cartesianCell: " << (*cutCells)[c].cartesianCell << endl;
34023 ofl << "faces: ";
34024 for(MInt f = 0; (unsigned)f < (*cutCells)[c].faces_edges.size(); f++)
34025 ofl << (*cutCells)[c].faces_edges[f] << " ";
34026 ofl << endl << endl;
34027 }
34028
34029 ofl.close();
34030 }
34031}

◆ postAdaptation()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::postAdaptation
overridevirtual
Author
Tim Wegmann

Reimplemented from Solver.

Definition at line 15527 of file fvmbcartesiansolverxd.cpp.

15527 {
15529
15530 if(grid().azimuthalPeriodicity()) {
15533 }
15534}
void exchangeAzimuthalPer(T *data, MInt dataBlockSize=1, MInt firstBlock=0)
Exchange of sparse data structures on max Level.

◆ postSolutionStep()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::postSolutionStep
overridevirtual
Author
Tim Wegmann

RESIDUAL

Surface Forces:

Structure correction step: -> eventually, level-set update has to be included here for FSI computations with "real" level set

Reimplemented from Solver.

Definition at line 27010 of file fvmbcartesiansolverxd.cpp.

27010 {
27011 TRACE();
27012
27013 RECORD_TIMER_START(m_timers[Timers::PostTime]);
27014 RECORD_TIMER_START(m_timers[Timers::PostSolu]);
27015
27016 MBool convergence = false;
27017
27019 RECORD_TIMER_START(m_timers[Timers::ResidualMb]);
27020 convergence = this->maxResidual();
27021 RECORD_TIMER_STOP(m_timers[Timers::ResidualMb]);
27022
27024 RECORD_TIMER_START(m_timers[Timers::SurfaceForces]);
27026 RECORD_TIMER_STOP(m_timers[Timers::SurfaceForces]);
27027
27031 RECORD_TIMER_START(m_timers[Timers::LevelSetCorr]);
27032 convergence = mMin(convergence, constructGFieldCorrector());
27033 RECORD_TIMER_STOP(m_timers[Timers::LevelSetCorr]);
27034
27035
27036 RECORD_TIMER_STOP(m_timers[Timers::PostSolu]);
27037 RECORD_TIMER_STOP(m_timers[Timers::PostTime]);
27038
27039 return convergence;
27040}
MBool constructGFieldCorrector()
determine the displacement of the embedded body – corrector step
MBool maxResidual(MInt mode=0) override
Computes the maxResiduum for all cells.

◆ postTimeStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::postTimeStep
overridevirtual
Author
Tim Wegmann

Implements Solver.

Definition at line 30341 of file fvmbcartesiansolverxd.cpp.

30341 {
30342 TRACE();
30343
30344 RECORD_TIMER_START(m_timers[Timers::PostTime]);
30345
30346 // finish last RK-step for inter-leaved non-blocking
30348 this->lhsBndFinish();
30349 m_splitMpiCommRecv = false;
30350
30351 this->rhs();
30352
30353 this->rhsBnd();
30354 }
30355
30356
30357 // NOTE: meaning base or instrastep execution recipe!
30358 if(m_maxIterations == 1) {
30359 RECORD_TIMER_STOP(m_timers[Timers::PostTime]);
30361 RECORD_TIMER_START(m_timers[Timers::PostTime]);
30362 }
30363
30365
30366
30369 }
30370
30371 RECORD_TIMER_STOP(m_timers[Timers::PostTime]);
30372}
constexpr MBool isMultilevelLowestSecondary() const
void lhsBndFinish()
Finish the split MPI communication and perform the left out part from lhsBnd().
MBool postSolutionStep() override
step after the solver solution Step
MBool g_splitMpiComm

◆ prepareAdaptation()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::prepareAdaptation
overridevirtual
Author
Tim Wegmann

Reimplemented from Solver.

Definition at line 15420 of file fvmbcartesiansolverxd.cpp.

15420 {
15421 TRACE();
15422
15423 if(!isActive()) return;
15424
15425 if(globalTimeStep > 0) {
15426 // update the time and construct new GField before the adaptation
15428 if(m_constructGField) {
15430 } else if(!m_LsMovement) {
15432 }
15433 ASSERT(m_structureStep == 0, "");
15434
15435 resetSolverMb();
15437
15438 if(grid().azimuthalPeriodicity()) {
15440 }
15441
15442 {
15443 // does halo info need to be recovered after adaptation?
15444 auto oldBndryCellsBak(m_oldBndryCells);
15445 m_oldBndryCells.clear();
15446 for(auto it = oldBndryCellsBak.begin(); it != oldBndryCellsBak.end(); ++it) {
15447 if(it->first >= noInternalCells()) continue;
15448 ASSERT(!a_isHalo(it->first), "");
15449 m_oldBndryCells.insert(*it);
15450 }
15451 }
15452
15453 {
15454 // does halo info need to be recovered after adaptation?
15455 auto nearBoundaryBackupBak(m_nearBoundaryBackup);
15456 m_nearBoundaryBackup.clear();
15457 for(auto it = nearBoundaryBackupBak.begin(); it != nearBoundaryBackupBak.end(); ++it) {
15458 if(it->first >= noInternalCells()) continue;
15459 ASSERT(!a_isHalo(it->first), "");
15460 m_nearBoundaryBackup.insert(*it);
15461 }
15462 }
15463 }
15464
15465 m_coarseOldBndryCells.clear();
15466
15468}
void prepareAdaptation() override
void resetSolverMb()
resets the solver to an empty domain without moving boundary
void constructGFieldPredictor()
determine the displacement of the embedded body – predictor step

◆ prepareNextTimeStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::prepareNextTimeStep
overridevirtual
Author
Thomas Hoesgen

Reimplemented from Solver.

Definition at line 30530 of file fvmbcartesiansolverxd.cpp.

30530 {
30531 TRACE();
30532
30534 advanceBodies();
30535}
void advanceBodies()
advances the time and stores the flow variables
void advanceSolution()
advances the time and stores the flow variables

◆ prepareRestart()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::prepareRestart ( MBool  ,
MBool  
)
overridevirtual

Reimplemented from Solver.

Definition at line 24540 of file fvmbcartesiansolverxd.cpp.

24540 {
24541 TRACE();
24542
24543 writeGridRestart = false;
24544
24545 if(((globalTimeStep % m_restartInterval) == 0 && globalTimeStep > m_restartTimeStep) || writeRestart) {
24546 writeRestart = true;
24547
24548 if(isActive() && m_deleteNeighbour) {
24550 }
24551
24552 if(m_onlineRestartInterval > 0) {
24556 }
24557
24558 if(m_forceRestartGrid) {
24560 if(isActive() && m_recalcIds == nullptr) mAlloc(m_recalcIds, maxNoGridCells(), "m_recalcIds", -1, AT_);
24561 }
24562
24564 writeGridRestart = true;
24565 }
24566 }
24567
24568 if(grid().newMinLevel() > 0) {
24569 writeGridRestart = true;
24570 }
24571
24572 // This needs to happen before the grid and variable-output. Thats why it had to be moved here
24573 // from saveRestartFile()!
24574 if(isActive() && m_useNonSpecifiedRestartFile && writeRestart) {
24575 if(domainId() == 0) {
24577 MString fileName = outputDir() + "restartGrid";
24578 fileName += ".Netcdf";
24579 MString fileNameBak = fileName + ".BAK";
24580#ifdef _MB_DEBUG_
24581 cerr << "rename " << fileName << " " << fileNameBak << endl;
24582#endif
24583 rename(fileName.c_str(), fileNameBak.c_str());
24584 }
24585 {
24586 MString fileName = outputDir() + "restartVariables";
24587 fileName += ".Netcdf";
24588 MString fileNameBak = fileName + ".BAK";
24589#ifdef _MB_DEBUG_
24590 cerr << "rename " << fileName << " " << fileNameBak << endl;
24591#endif
24592 rename(fileName.c_str(), fileNameBak.c_str());
24593 }
24594 {
24595 MString fileName = outputDir() + "restartBodyData";
24596 fileName += ".Netcdf";
24597 MString fileNameBak = fileName + ".BAK";
24598#ifdef _MB_DEBUG_
24599 cerr << "rename " << fileName << " " << fileNameBak << endl;
24600#endif
24601 rename(fileName.c_str(), fileNameBak.c_str());
24602 }
24603 }
24604 MPI_Barrier(mpiComm(), AT_);
24605 }
24606
24607 if(isActive() && m_levelSetMb && writeRestart) {
24608 if(maxLevel() > minLevel()) {
24609 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
24610 if(a_isBndryGhostCell(cellId)) continue;
24611 if(a_isHalo(cellId)) continue;
24612 if(a_level(cellId) != minLevel()) continue;
24613 reduceData(cellId, &a_pvariable(0, 0), PV->noVariables);
24614 if(grid().azimuthalPeriodicity()) {
24615 // Should this be done also for non-periodic cases?
24616 // Else, after restart CV are computed based on PV variables
24617 // In the running simulation PV, however, are simply overwritten to old value in computePV()
24618 reduceData(cellId, &a_variable(0, 0), CV->noVariables);
24619 }
24620 }
24621 }
24622 }
24623
24624#if defined _MB_DEBUG_ || !defined NDEBUG
24625 if(isActive() && writeRestart) {
24626 if(domainId() == 0) {
24627 cerr << "Checking cells before writing restart-file... ";
24628 }
24629 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
24630 for(MInt v = 0; v < CV->noVariables; v++) {
24631 if(std::isnan(a_variable(cellId, v)) && a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
24632 cerr << "Nan in variable when writing restart-File: " << cellId << " "
24633 << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
24634 }
24635 }
24636 }
24637 cerr0 << "finished. " << endl;
24638 }
24639#endif
24640
24641 return writeRestart;
24642}
MString outputDir() const
Return the directory for output files.
Definition: solver.h:407
MInt g_timeSteps

◆ preSolutionStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::preSolutionStep ( const MInt  mode = -1)
overridevirtual
Author
anyone

Reimplemented from Solver.

Definition at line 26991 of file fvmbcartesiansolverxd.cpp.

26991 {
26992 TRACE();
26993
26994 ASSERT(m_levelSetMb, "Wrong Function call, only for m_levelSetMb! Otherwise use preTimeStep in fvsolver.cpp");
26995
26996 RECORD_TIMER_START(m_timers[Timers::PreTime]);
26997
26998 reInitSolutionStep(mode);
27000
27001 RECORD_TIMER_STOP(m_timers[Timers::PreTime]);
27002}
void reInitSolutionStep(const MInt mode)
Re-initializes the solver.

◆ preTimeStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::preTimeStep
overridevirtual
Author
Thomas Hoesgen

Implements Solver.

Definition at line 30232 of file fvmbcartesiansolverxd.cpp.

30232 {
30233 TRACE();
30234
30235 RECORD_TIMER_START(m_timers[Timers::PreTime]);
30236
30237 if(!grid().wasAdapted()) {
30238 // If the mesh was adaped,
30239 // these calls have already been made in prepareAdaptation
30241
30242 if(m_constructGField) {
30244 } else if(!m_LsMovement) {
30246 }
30247 }
30248
30249 // stop timer here, they are re-started in preSolutionStep for iterative runs
30250 RECORD_TIMER_STOP(m_timers[Timers::PreTime]);
30251 if(grid().wasAdapted()) {
30252 if(!isMultilevel() || isMultilevelPrimary()) {
30253 preSolutionStep(0);
30254 }
30255 } else {
30257 }
30258 RECORD_TIMER_START(m_timers[Timers::PreTime]);
30259
30260 if(m_localTS) {
30261 const MInt interval = !m_multilevel ? 500 : 100;
30262 if(globalTimeStep == (m_restartTimeStep + 1) || grid().wasAdapted() || globalTimeStep % interval == 0) {
30263 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
30264 if(!m_fvBndryCnd->m_smallCellRHSCorrection) {
30265 // Q-SCC requires the same time-step in all neighboring small cells!
30266 a_localTimeStep(cellId) = timeStep() * IPOW2(maxLevel() - a_level(cellId));
30267 } else {
30269 }
30270 }
30271 }
30272 }
30273
30274 // TODO labels: FVMB This looks like something that should have been done in the postAdaptation/Balance functions...
30275 if(grid().wasAdapted() || grid().wasBalanced()) {
30277 }
30278
30279 constexpr MBool dbg = false;
30280 if constexpr(dbg) {
30281 if(globalTimeStep == (m_restartTimeStep + 1)) {
30282 // count how many cells have a certain volume
30283 const MInt noVolSteps = 20;
30284 ScratchSpace<MInt> volumes(noVolSteps, AT_, "volumes");
30285 volumes.fill(0);
30286 const MFloat deltaVol = F1 / noVolSteps;
30287
30288 // write cell-volume output
30289 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
30290 if(a_isHalo(cellId)) continue;
30291 if(a_isBndryGhostCell(cellId)) continue;
30292 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
30293 if(!a_isBndryCell(cellId)) continue;
30294
30295 const MFloat vFrac = a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId));
30296 const MInt pos = floor(vFrac / deltaVol);
30297 /* if(pos > noVolSteps - 1) continue; */
30298 volumes(pos)++;
30299 }
30300
30301 // Add from different ranks
30302 MPI_Allreduce(MPI_IN_PLACE, &volumes(0), noVolSteps, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "volumes");
30303
30304 // Write the file
30305 if(domainId() == 0) {
30306 FILE* datei;
30307 struct stat buffer;
30308 std::string name = "Volumes_" + to_string(solverId());
30309 const char* cstr = name.c_str();
30310 if(stat(cstr, &buffer) == 0) {
30311 rename(cstr, "Volumes_BAK");
30312 }
30313 datei = fopen(cstr, "w");
30314 fprintf(datei, "%s", "# 1:volLower 2:volUpper 3:count \n");
30315 for(MInt i = 0; i < noVolSteps; i++) {
30316 const MFloat volLimit1 = i * deltaVol;
30317 const MFloat volLimit2 = i * deltaVol + deltaVol;
30318 fprintf(datei, "%.8g", volLimit1);
30319 fprintf(datei, " %.8g", volLimit2);
30320 fprintf(datei, " %d", volumes(i));
30321 fprintf(datei, "\n");
30322 }
30323 fclose(datei);
30324 }
30325 }
30326 }
30327
30328 m_splitMpiCommRecv = false;
30329
30331
30332 RECORD_TIMER_STOP(m_timers[Timers::PreTime]);
30333}
MBool m_multilevel
Stores whether this solver is part of a multilevel computation.
MFloat & a_localTimeStep(const MInt cellId)
Returns the local time-step of the cell cellId.
void preTimeStep() override
MFloat computeTimeStepEulerDirectional(MInt cellId) const noexcept
constexpr MBool isMultilevel() const
Return true if solver is part of a multilevel computation.
constexpr MBool isMultilevelPrimary() const
Return true if solver is primary solver in multilevel computation.

◆ printDynamicCoefficients()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::printDynamicCoefficients ( MBool  firstRun,
MFloat pressureForce 
)

Definition at line 21392 of file fvmbcartesiansolverxd.cpp.

21392 {
21393 TRACE();
21394
21395 // only the coefficient of the first body will be printed here.
21396 MInt bodyId = 0;
21397 MFloat forceCoeffs[3] = {F0, F0, F0};
21398 MFloat pressureForceCoeffs[3] = {F0, F0, F0};
21399 MFloat momentCoeffs[3] = {F0, F0, F0};
21400 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
21401 forceCoeffs[spaceId] = m_hydroForce[bodyId * nDim + spaceId] / (F1B2 * m_rhoU2);
21402 IF_CONSTEXPR(nDim == 2) {
21403 forceCoeffs[spaceId] /= m_bodyDiameter[bodyId];
21404 pressureForceCoeffs[spaceId] = pressureForce[bodyId * nDim + spaceId] / m_bodyDiameter[bodyId];
21405 }
21406 else IF_CONSTEXPR(nDim == 3) {
21407 forceCoeffs[spaceId] /= PI * POW2(F1B2 * m_bodyDiameter[bodyId]);
21408 pressureForceCoeffs[spaceId] =
21409 pressureForce[bodyId * nDim + spaceId] / (PI * POW2(F1B2 * m_bodyDiameter[bodyId]));
21410 }
21411 }
21412 for(MInt i = 0; i < 3; i++) {
21413 momentCoeffs[i] = m_bodyTorque[bodyId * 3 + i] / (F1B2 * m_rhoU2);
21414 IF_CONSTEXPR(nDim == 2) { momentCoeffs[i] /= m_bodyDiameter[bodyId]; }
21415 else IF_CONSTEXPR(nDim == 3) {
21416 momentCoeffs[i] /= PI * POW3(F1B2 * m_bodyDiameter[bodyId]);
21417 }
21418 }
21419
21420 MString surname;
21421 if(!m_multipleFvSolver) {
21422 surname = "forceCoef";
21423 } else {
21424 surname = "forceCoef_s" + to_string(solverId());
21425 }
21426
21427 ofstream ofl;
21428 if(domainId() == 0) {
21429 if(firstRun && globalTimeStep <= m_dragOutputInterval) {
21430 MString surnameBAK = surname + "_BAK";
21431 MString surnameBAK0 = surname + "_BAK0";
21432 MString surnameBAK1 = surname + "_BAK1";
21433 MString surnameBAK2 = surname + "_BAK2";
21434 rename(surnameBAK1.c_str(), surnameBAK2.c_str());
21435 rename(surnameBAK0.c_str(), surnameBAK1.c_str());
21436 rename(surnameBAK.c_str(), surnameBAK0.c_str());
21437 rename(surname.c_str(), surnameBAK.c_str());
21438 ofl.open(surname.c_str(), ios_base::out | ios_base::trunc);
21439 ofl << "# Header valid for nDim = 3" << endl;
21440 ofl << "#1:ts 2:tf 3:t 4-6:forceCoeffs 7-9:momentCoeffs 10-12:pressureForceCoeffs";
21441 ofl << endl;
21442 } else {
21443 ofl.open(surname.c_str(), ios_base::out | ios_base::app);
21444 }
21445 if(ofl.is_open() && ofl.good()) {
21446 ofl << setprecision(8) << globalTimeStep << " " << m_physicalTime << " " << m_time << " ";
21447 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
21448 ofl << forceCoeffs[spaceId] << " ";
21449 }
21450 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
21451 ofl << momentCoeffs[spaceId] << " ";
21452 }
21453 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
21454 ofl << pressureForceCoeffs[spaceId] << " ";
21455 }
21456 ofl << endl;
21457 ofl.close();
21458 }
21459 }
21460}

◆ printTime()

template<MInt nDim, class SysEqn >
MString FvMbCartesianSolverXD< nDim, SysEqn >::printTime ( const MFloat  t)
Author

Definition at line 25987 of file fvmbcartesiansolverxd.cpp.

25987 {
25988 stringstream time;
25989 time.str("");
25990 MFloat rem = t;
25991 if(rem > 86400.0) {
25992 const MFloat div = floor(rem / 86400.0);
25993 time << ((MInt)div) << " days, ";
25994 rem -= div * 86400.0;
25995 }
25996 if(rem > 3600.0) {
25997 const MFloat div = floor(rem / 3600.0);
25998 time << ((MInt)div) << " hours, ";
25999 rem -= div * 3600.0;
26000 }
26001 if(rem > 60.0) {
26002 const MFloat div = floor(rem / 60.0);
26003 time << ((MInt)div) << " mins, ";
26004 rem -= div * 60.0;
26005 }
26006 time << rem << " secs";
26007 const MString ret = time.str();
26008 return ret;
26009}
MFloat time() const override
returns the time

◆ readStlFile()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::readStlFile ( const MChar fileName,
MBool  readNormals 
)

void FvMbCartesianSolverXD<nDim, SysEqn>::readStlFile()

Author
Lennart Schneiders

Definition at line 24341 of file fvmbcartesiansolverxd.cpp.

24341 {
24342 TRACE();
24343
24344 string line;
24345 ifstream ifile;
24346 MBool isBinary = false;
24347 MFloat a[3];
24348 MFloat b[3];
24349 MFloat c[3];
24350 MInt noPoints;
24351 char cstr[100];
24352 string token;
24354 noPoints = 0;
24355
24356 if(!fileExists(fileName)) {
24357 stringstream errorMessage;
24358 errorMessage << "Error: Unable to find file " << fileName << ". Quit." << endl;
24359 mTerm(1, AT_, errorMessage.str());
24360 } else if(isBinary) {
24361 cerr << "lacking binary stl code" << endl;
24362 } else {
24363 ifile.open(fileName);
24364 if(ifile.is_open()) {
24365 cerr << "Reading " << fileName << "... ";
24366
24367 getline(ifile, line);
24368 strcpy(cstr, line.c_str());
24369 token = strtok(cstr, " ");
24370 if(token.compare(0, 5, "solid", 0, 5) != 0) {
24371 stringstream errorMessage;
24372 errorMessage << "Error 1 reading " << fileName << ". Quit." << endl;
24373 mTerm(1, AT_, errorMessage.str());
24374 }
24375 while(ifile.good()) {
24376 getline(ifile, line);
24377 if(line == "") continue;
24378 strcpy(cstr, line.c_str());
24379 token = strtok(cstr, " ");
24380 if(token.compare(0, 5, "facet", 0, 5) == 0) {
24381 if(noPoints >= m_maxNoSurfacePointSamples) {
24382 mTerm(1, AT_, "Increase m_maxNoSurfacePointSamples. Quit.");
24383 }
24384
24385 // 1. obtain normals
24386 token = strtok(nullptr, " ");
24387 if(token.compare(0, 5, "normal", 0, 5) != 0) {
24388 stringstream errorMessage;
24389 errorMessage << "Error 2 reading " << fileName << ". Quit." << endl;
24390 mTerm(1, AT_, errorMessage.str());
24391 }
24392 if(readNormals) {
24393 token = strtok(nullptr, " ");
24394 m_sampleNormals[3 * noPoints] = atof(token.c_str());
24395 token = strtok(nullptr, " ");
24396 m_sampleNormals[3 * noPoints + 1] = atof(token.c_str());
24397 token = strtok(nullptr, " ");
24398 m_sampleNormals[3 * noPoints + 2] = atof(token.c_str());
24399 }
24400
24401 // skip "outer loop"
24402 getline(ifile, line);
24403
24404 // 2a. obtain point a
24405 getline(ifile, line);
24406 strcpy(cstr, line.c_str());
24407 token = strtok(cstr, " ");
24408 if(token.compare(0, 6, "vertex", 0, 6) != 0) {
24409 stringstream errorMessage;
24410 errorMessage << "Error 3 reading " << fileName << ". Quit." << endl;
24411 mTerm(1, AT_, errorMessage.str());
24412 }
24413 token = strtok(nullptr, " ");
24414 a[0] = atof(token.c_str());
24415 token = strtok(nullptr, " ");
24416 a[1] = atof(token.c_str());
24417 token = strtok(nullptr, " ");
24418 a[2] = atof(token.c_str());
24419
24420 // 2b. obtain point b
24421 getline(ifile, line);
24422 strcpy(cstr, line.c_str());
24423 token = strtok(cstr, " ");
24424 if(token.compare(0, 6, "vertex", 0, 6) != 0) {
24425 stringstream errorMessage;
24426 errorMessage << "Error 4 reading " << fileName << ". Quit." << endl;
24427 mTerm(1, AT_, errorMessage.str());
24428 }
24429 token = strtok(nullptr, " ");
24430 b[0] = atof(token.c_str());
24431 token = strtok(nullptr, " ");
24432 b[1] = atof(token.c_str());
24433 token = strtok(nullptr, " ");
24434 b[2] = atof(token.c_str());
24435
24436 // 2c. obtain point c
24437 getline(ifile, line);
24438 strcpy(cstr, line.c_str());
24439 token = strtok(cstr, " ");
24440 if(token.compare(0, 6, "vertex", 0, 6) != 0) {
24441 stringstream errorMessage;
24442 errorMessage << "Error 5 reading " << fileName << ". Quit." << endl;
24443 mTerm(1, AT_, errorMessage.str());
24444 }
24445 token = strtok(nullptr, " ");
24446 c[0] = atof(token.c_str());
24447 token = strtok(nullptr, " ");
24448 c[1] = atof(token.c_str());
24449 token = strtok(nullptr, " ");
24450 c[2] = atof(token.c_str());
24451
24452 m_sampleCoordinates[3 * noPoints] = F1B3 * (a[0] + b[0] + c[0]);
24453 m_sampleCoordinates[3 * noPoints + 1] = F1B3 * (a[1] + b[1] + c[1]);
24454 m_sampleCoordinates[3 * noPoints + 2] = F1B3 * (a[2] + b[2] + c[2]);
24455
24456 if(!readNormals) {
24457 for(MInt i = 0; i < 3; i++) {
24458 b[i] = b[i] - a[i];
24459 a[i] = c[i] - a[i];
24460 }
24461 crossProduct(c, b, a);
24462 MFloat tmp = F1 / sqrt(POW2(c[0]) + POW2(c[1]) + POW2(c[2]));
24463
24464 m_sampleNormals[3 * noPoints] = c[0] * tmp;
24465 m_sampleNormals[3 * noPoints + 1] = c[1] * tmp;
24466 m_sampleNormals[3 * noPoints + 2] = c[2] * tmp;
24467 }
24468
24469 // skip "endloop"
24470 getline(ifile, line);
24471
24472 // skip "endfacet"
24473 getline(ifile, line);
24474
24475 noPoints++;
24476 } else if(token.compare(0, 8, "endsolid", 0, 8) == 0) {
24477 cerr << "finished ";
24478 break;
24479 } else {
24480 stringstream errorMessage;
24481 errorMessage << "Error 6 reading " << fileName << ". Quit." << endl;
24482 mTerm(1, AT_, errorMessage.str());
24483 }
24484 }
24485
24486 ifile.close();
24487 }
24488 }
24489 m_noSurfacePointSamples = noPoints;
24490
24491 cerr << "(read " << m_noSurfacePointSamples << " samples)." << endl;
24492 cerr << "establishing sample neighborhood...";
24493
24494 const MInt noNghbrs = m_maxNoSampleNghbrs;
24495 MFloat dist[10];
24496 MInt nghbrs[10];
24497 ASSERT(noNghbrs <= 10, "");
24498 MInt offset = 0;
24499 for(MInt p = 0; p < noPoints; p++) {
24500 for(MInt i = 0; i < noNghbrs; i++) {
24501 dist[i] = POW2(c_cellLengthAtLevel(0));
24502 nghbrs[i] = -1;
24503 }
24504 for(MInt q = 0; q < noPoints; q++) {
24505 if(p == q) continue;
24506 MFloat tmpDist = POW2(m_sampleCoordinates[3 * p] - m_sampleCoordinates[3 * q])
24507 + POW2(m_sampleCoordinates[3 * p + 1] - m_sampleCoordinates[3 * q + 1])
24508 + POW2(m_sampleCoordinates[3 * p + 2] - m_sampleCoordinates[3 * q + 2]);
24509 for(MInt i = 0; i < noNghbrs; i++) {
24510 if(tmpDist < dist[i]) {
24511 for(MInt j = noNghbrs - 1; j > i; j--) {
24512 if(nghbrs[j - 1] > -1) {
24513 nghbrs[j] = nghbrs[j - 1];
24514 dist[j] = dist[j - 1];
24515 }
24516 }
24517 dist[i] = tmpDist;
24518 nghbrs[i] = q;
24519 break;
24520 }
24521 }
24522 }
24523 for(MInt i = 0; i < noNghbrs; i++) {
24524 m_sampleNghbrs[offset + i] = nghbrs[i];
24525 }
24526 offset += noNghbrs;
24527 m_sampleNghbrOffsets[p] = offset;
24528 }
24529
24530 cerr << "finished." << endl;
24531}
std::istream & getline(std::istream &input, std::string &line)
Definition: cpptoml.h:1519

◆ rebuildKDTree()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::rebuildKDTree
Author

Definition at line 2318 of file fvmbcartesiansolverxd.cpp.

2318 {
2319 IF_CONSTEXPR(nDim == 3) {
2320 if(m_bodyTree != nullptr) {
2321 delete m_bodyTree;
2322 m_bodyTree = nullptr;
2323 }
2324 m_bodyCenters.clear();
2325
2326 for(MInt k = 0; k < (m_noEmbeddedBodies + m_noPeriodicGhostBodies); k++) {
2327 Point<3> a(m_bodyCenter[k * nDim], m_bodyCenter[k * nDim + 1], m_bodyCenter[k * nDim + 2], k);
2328 if(std::isnan(a.x[0]) || std::isnan(a.x[1]) || std::isnan(a.x[2]) || std::isinf(a.x[0]) || std::isinf(a.x[1])
2329 || std::isinf(a.x[2])) {
2330 mTerm(1, "ERROR body center is NAN " + to_string(k) + " " + to_string(a.x[0]) + " " + to_string(a.x[1]) + " "
2331 + to_string(a.x[2]));
2332 }
2333 m_bodyCenters.push_back(a);
2334 }
2335
2336 if(m_bodyCenters.size() > 0) {
2338 }
2339 }
2340}
std::vector< Point< nDim > > m_bodyCenters
Definition: kdtree.h:73

◆ rebuildKDTreeLocal()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::rebuildKDTreeLocal
Author

Definition at line 2348 of file fvmbcartesiansolverxd.cpp.

2348 {
2349 IF_CONSTEXPR(nDim == 3) {
2350 if(m_bodyTreeLocal != nullptr) {
2351 delete m_bodyTreeLocal;
2352 m_bodyTreeLocal = nullptr;
2353 }
2354 m_bodyCentersLocal.clear();
2355
2356 for(MInt k = 0; k < (m_noEmbeddedBodies + m_noPeriodicGhostBodies); k++) {
2357 if(!m_bodyNearDomain[k]) continue;
2358 Point<nDim> a(m_bodyCenter[k * nDim + 0], m_bodyCenter[k * nDim + 1], m_bodyCenter[k * nDim + 2], k);
2359 if(std::isnan(a.x[0]) || std::isnan(a.x[1]) || std::isnan(a.x[2]) || std::isinf(a.x[0]) || std::isinf(a.x[1])
2360 || std::isinf(a.x[2])) {
2361 mTerm(1, "ERROR body center is NAN " + to_string(k) + " " + to_string(a.x[0]) + " " + to_string(a.x[1]) + " "
2362 + to_string(a.x[2]));
2363 }
2364 m_bodyCentersLocal.push_back(a);
2365 }
2367 }
2368}
std::vector< Point< nDim > > m_bodyCentersLocal

◆ rebuildReconstructionConstants()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::rebuildReconstructionConstants ( MInt  cellId)
Author
Lennart Schneiders

Definition at line 17396 of file fvmbcartesiansolverxd.cpp.

17396 {
17397 const MInt recDim = (m_orderOfReconstruction == 2) ? (IPOW2(nDim) + 1) : nDim;
17398 const MInt maxNoNghbrs = 150;
17399
17400 MIntScratchSpace nghbrList(maxNoNghbrs, AT_, "nghbrList");
17401 MIntScratchSpace layerId(maxNoNghbrs, AT_, "layerList");
17402
17403 if(c_noChildren(cellId) > 0 || a_hasProperty(cellId, SolverCell::IsNotGradient)
17404 || !a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
17405 cerr << domainId() << " Warning: trying to rebuild stencil of cell " << cellId << " with " << c_noChildren(cellId)
17406 << " children and prop-7=" << a_hasProperty(cellId, SolverCell::IsNotGradient)
17407 << ", prop-13=" << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << ", level=" << a_level(cellId)
17408 << ", inact=" << a_hasProperty(cellId, SolverCell::IsInactive) << ". Skipped." << endl;
17409 a_noReconstructionNeighbors(cellId) = 0;
17410 return;
17411 }
17412
17413 const MInt counter = this->template getAdjacentLeafCells<0, true>(cellId, 1, nghbrList, layerId);
17414
17415 if(counter > maxNoNghbrs) {
17416 mTerm(1, AT_, "too many nghbrs " + to_string(counter));
17417 }
17418 a_noReconstructionNeighbors(cellId) = 0;
17419
17420 if(a_bndryId(cellId) > -1) {
17421 for(MInt srfc = 0; srfc < m_bndryCells->a[a_bndryId(cellId)].m_noSrfcs; srfc++) {
17422 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcVariables[srfc]->m_ghostCellId;
17423 if(ghostCellId < 0) cerr << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << endl;
17424 if(ghostCellId < 0)
17425 mTerm(1, AT_,
17426 "ghostCellId not set! " + to_string(cellId) + " " + to_string(a_bndryId(cellId)) + " "
17427 + to_string(ghostCellId) + " " + to_string(srfc) + " " + to_string(a_isHalo(cellId)) + " "
17428 + to_string(a_isBndryGhostCell(cellId)));
17429 a_reconstructionNeighborId(cellId, a_noReconstructionNeighbors(cellId)) = ghostCellId;
17431 }
17432 }
17433
17434 MBool atInterface = false;
17435 for(MInt k = 0; k < counter; k++) {
17436 MInt nghbrId = nghbrList[k];
17437 if(nghbrId < 0) continue;
17438 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17441 if(a_noReconstructionNeighbors(cellId) > m_cells.noRecNghbrs()) {
17442 mTerm(1, AT_, "too many rec nghbrs " + to_string(cellId));
17443 }
17444 if(a_level(nghbrId) < a_level(cellId)) {
17445 atInterface = true;
17446 }
17447 }
17448
17449 // use a different stencil at level-jumps for local-time stepping
17450 //(more stable, i.e. larger CFL!)
17451 if(m_localTS && atInterface) {
17452 const MInt counter2 = this->template getAdjacentLeafCells<2, true>(cellId, 1, nghbrList, layerId);
17453 for(MInt k = 0; k < counter2; k++) {
17454 MInt nghbrId = nghbrList[k];
17455 if(nghbrId < 0) {
17456 continue;
17457 }
17458 if(a_hasProperty(nghbrId, SolverCell::IsInvalid)) {
17459 continue;
17460 }
17461 if(a_level(nghbrId) >= a_level(cellId)) {
17462 continue;
17463 }
17464 MBool exist = false;
17465 for(MInt i = 0; i < a_noReconstructionNeighbors(cellId); i++) {
17466 if(a_reconstructionNeighborId(cellId, i) == nghbrId) {
17467 exist = true;
17468 break;
17469 }
17470 }
17471 if(!exist) {
17474 }
17475 if(a_noReconstructionNeighbors(cellId) > m_cells.noRecNghbrs()) {
17476 mTerm(1, AT_, "too many rec nghbrs " + to_string(cellId) + " " + to_string(counter));
17477 }
17478 }
17479 }
17480
17481
17482 const MInt noNghbrIds = a_noReconstructionNeighbors(cellId);
17483
17484 MFloatScratchSpace tmpA(noNghbrIds, recDim, AT_, "tmpA");
17485 MFloatScratchSpace tmpC(recDim, noNghbrIds, AT_, "tmpC");
17486 MFloatScratchSpace weights(noNghbrIds, AT_, "weights");
17487
17488 ASSERT(!a_hasProperty(cellId, SolverCell::IsNotGradient) && c_isLeafCell(cellId),
17489 "a_hasProperty(cellId, SolverCell::IsNotGradient) "
17490 + std::to_string(a_hasProperty(cellId, SolverCell::IsNotGradient)) + " c_isLeafCell(cellId) "
17491 + std::to_string(c_isLeafCell(cellId)));
17492
17493 const MInt offset = m_cells.noRecNghbrs() * cellId;
17494 computeRecConstSVD(cellId, offset, tmpA, tmpC, weights, recDim, 0, -1);
17495}

◆ recordBodyData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::recordBodyData ( const MBool firstRun)

Definition at line 21463 of file fvmbcartesiansolverxd.cpp.

21463 {
21464 TRACE();
21465 ofstream ofl;
21466
21467 MString surname;
21468 if(!m_multipleFvSolver) {
21469 surname = "bodyPosition";
21470 } else {
21471 surname = "bodyPosition_s" + to_string(solverId());
21472 }
21473
21474 if(domainId() == 0) {
21475 if(firstRun && globalTimeStep <= m_dragOutputInterval) {
21476 MString surnameBAK = surname + "_BAK";
21477 MString surnameBAK0 = surname + "_BAK0";
21478 MString surnameBAK1 = surname + "_BAK1";
21479 MString surnameBAK2 = surname + "_BAK2";
21480 rename(surnameBAK1.c_str(), surnameBAK2.c_str());
21481 rename(surnameBAK0.c_str(), surnameBAK1.c_str());
21482 rename(surnameBAK.c_str(), surnameBAK0.c_str());
21483 rename(surname.c_str(), surnameBAK.c_str());
21484 ofl.open(surname.c_str(), ios_base::out | ios_base::trunc);
21485 ofl << "# 1:ts 2:tf 3:t 4-6:bodyCenter 7-9:bodyVelocity 10-12:bodyOrientation 13-15: bodyAngularVelocity";
21486 ofl << endl;
21487 ofl << "# For more than 2 bodies, the output is performed for the first two bodies" << endl;
21488 ofl << "# (>2bodies) 16-18:bodyCenter 19-21:bodyVelocity 22-24:bodyOrientation 25-27: bodyAngularVelocity";
21489 ofl << endl;
21490 } else {
21491 ofl.open(surname.c_str(), ios_base::out | ios_base::app);
21492 }
21493 if(ofl.is_open() && ofl.good()) {
21494 ofl << setprecision(8) << globalTimeStep << " " << m_physicalTime << " " << m_time << " ";
21495 MFloatScratchSpace R(3, 3, AT_, "R");
21496 MFloat tmp[3] = {F0, F0, F1};
21497 MFloat zHat[3];
21498 for(MInt k = 0; k < mMin(2, m_noEmbeddedBodies); k++) {
21500 matrixVectorProductTranspose(zHat, R, tmp); // orientation of z-principal axis
21501 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
21502 ofl << m_bodyCenter[k * nDim + spaceId] << " ";
21503 }
21504 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
21505 ofl << m_bodyVelocity[k * nDim + spaceId] << " ";
21506 }
21507 for(MInt spaceId = 0; spaceId < 3; spaceId++) {
21508 ofl << zHat[spaceId] << " ";
21509 }
21510 for(MInt spaceId = 0; spaceId < 3; spaceId++) {
21511 ofl << m_bodyAngularVelocity[k * 3 + spaceId] << " ";
21512 }
21513 }
21514 ofl << endl;
21515 ofl.close();
21516 }
21517 }
21518}

◆ redistributeMass()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::redistributeMass
Author
Lennart Schneiders

Definition at line 10110 of file fvmbcartesiansolverxd.cpp.

10110 {
10111 TRACE();
10112
10113 MIntScratchSpace haloBufferCnts(mMax(1, noNeighborDomains()), AT_, "haloBufferCnts");
10114 MIntScratchSpace windowBufferCnts(mMax(1, noNeighborDomains()), AT_, "windowBufferCnts");
10115 MIntScratchSpace haloBufferOffsets(noNeighborDomains() + 1, AT_, "haloBufferOffsets");
10116 MIntScratchSpace windowBufferOffsets(noNeighborDomains() + 1, AT_, "windowBufferOffsets");
10117 ScratchSpace<MPI_Request> haloReq(mMax(1, noNeighborDomains()), AT_, "haloReq");
10118 ScratchSpace<MPI_Request> windowReq(mMax(1, noNeighborDomains()), AT_, "windowReq");
10119
10120 MInt haloSize = 0;
10121 MInt windowSize = 0;
10122 haloBufferCnts.fill(0);
10123 windowBufferCnts.fill(0);
10124 haloBufferOffsets.fill(0);
10125 windowBufferOffsets.fill(0);
10126
10127 for(MInt i = 0; i < noNeighborDomains(); i++) {
10128 haloBufferCnts(i) = (m_noCVars + m_noFVars + 3) * (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size();
10129 windowBufferCnts(i) = (m_noCVars + m_noFVars + 3) * (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size();
10130 haloBufferOffsets(i + 1) = haloBufferOffsets(i) + haloBufferCnts(i);
10131 windowBufferOffsets(i + 1) = windowBufferOffsets(i) + windowBufferCnts(i);
10132 haloSize += haloBufferCnts(i);
10133 windowSize += windowBufferCnts(i);
10134 }
10135
10136 MFloatScratchSpace redistVol(a_noCells(), AT_, "redistVol");
10137 MFloatScratchSpace redistSweptVol(a_noCells(), AT_, "redistSweptVol");
10138 MFloatScratchSpace haloBuffer(haloSize, AT_, "haloBuffer");
10139 MFloatScratchSpace windowBuffer(windowSize, AT_, "windowBuffer");
10140 MIntScratchSpace nghbrList(150, AT_, "nghbrList");
10141 MIntScratchSpace layerId(150, AT_, "layerList");
10142 MFloatScratchSpace weights(150, AT_, "layerList");
10143
10144 const MUint noCVars = (MUint)m_noCVars;
10145 const MUint noFVars = (MUint)m_noFVars;
10146 const MUint noPVars = (MUint)m_noPVars;
10147
10148 // redistribute lost mass
10149 // for ( MInt c = 0; c < m_noNearBndryCells; c++ ) {
10150 // MInt cellId = m_nearBndryCells->a[ c ];
10151 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
10152 const MInt cellId = m_bndryLayerCells[c];
10153 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
10154 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
10155 for(MUint v = 0; v < noPVars; v++) {
10156 a_slope(cellId, v, 0) = F0;
10157 a_slope(cellId, v, 1) = F0;
10158 }
10159 redistVol(cellId) = F0;
10160 redistSweptVol(cellId) = F0;
10161 }
10162
10163 {
10164 for(MInt i = 0; i < noNeighborDomains(); i++) {
10165 for(MInt j = 0; j < (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
10166 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
10167 for(MUint v = 0; v < noPVars; v++) {
10168 a_slope(cellId, v, 0) = F0;
10169 a_slope(cellId, v, 1) = F0;
10170 }
10171 redistVol(cellId) = F0;
10172 redistSweptVol(cellId) = F0;
10173 const MInt offset = haloBufferOffsets(i) + (noCVars + noFVars + 3) * j;
10174 haloBuffer(offset + 2) = -F1;
10175 }
10176 for(MInt j = 0; j < (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size(); j++) {
10177 MInt cellId = m_fvBndryCnd->m_nearBoundaryWindowCells[i][j];
10178 for(MUint v = 0; v < noPVars; v++) {
10179 a_slope(cellId, v, 0) = F0;
10180 a_slope(cellId, v, 1) = F0;
10181 }
10182 redistVol(cellId) = F0;
10183 redistSweptVol(cellId) = F0;
10184 }
10185 }
10186 }
10187
10188 for(MUint i = 0; i < m_massRedistributionIds.size(); ++i) {
10190 ASSERT(!(a_isPeriodic(cellId)), "");
10191 ASSERT(!(a_isHalo(cellId)), "");
10192 if(a_isHalo(cellId)) continue;
10193
10194 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
10195 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
10196
10197 MInt counter = 0;
10198 MFloat volCnt = F0;
10199 for(MInt dir = 0; dir < m_noDirs; dir++) {
10200 if(!checkNeighborActive(cellId, dir) || a_hasNeighbor(cellId, dir) == 0) continue;
10201 const MInt nghbrId = c_neighborId(cellId, dir);
10202 if(nghbrId < 0) continue;
10203 if(!a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel)) continue;
10204 if(a_bndryId(nghbrId) < 0) continue;
10205 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
10206 // if ( a_hasProperty( nghbrId , SolverCell::WasInactive ) ) continue;
10207 // Do not redistribute into azimuthal periodic cells. This is not handled
10208 if(grid().azimuthalPeriodicity() && a_isPeriodic(nghbrId)) continue;
10209
10210 MInt bndryId = (a_bndryId(cellId) > -1) ? a_bndryId(cellId) : a_bndryId(nghbrId);
10211 if(bndryId < 0) mTerm(1, AT_, "not expected");
10212 // const MFloat nml = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_srfcs[0]->m_normalVector[dir/2];
10213 MFloat normal[3];
10214 for(MInt k = 0; k < nDim; k++) {
10215 normal[k] = m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVectorCentroid[k];
10216 }
10217 const MFloat nml = normal[dir / 2];
10218 const MFloat ncut = 0.01;
10219
10220 weights[counter] = mMax(F0, (POW2(nml) - ncut) / (F1 - ncut))
10221 * mMin(F1, mMax(F0, mMin(a_cellVolume(nghbrId), m_cellVolumesDt1[nghbrId]))
10223
10224 volCnt += weights[counter];
10225 nghbrList[counter] = nghbrId;
10226 counter++;
10227 }
10228 for(MInt n = 0; n < counter; n++) {
10229 weights[n] /= mMax(1e-14, volCnt);
10230 }
10231
10232 if(true || volCnt < 0.1) {
10233 counter = this->template getAdjacentLeafCells<2, true>(cellId, 1, nghbrList, layerId);
10234 volCnt = F0;
10235 for(MInt n = 0; n < counter; n++) {
10236 weights[n] = F0;
10237 MInt nghbrId = nghbrList[n];
10238 if(nghbrId < 0) continue;
10239 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
10240 if(a_bndryId(nghbrId) < 0) continue;
10241 // Do not redistribute into azimuthal periodic cells. This is not handled
10242 if(grid().azimuthalPeriodicity() && a_isPeriodic(nghbrId)) continue;
10243
10244 if(a_hasProperty(nghbrId, SolverCell::IsSplitCell)) continue;
10245 if(a_hasProperty(nghbrId, SolverCell::IsSplitChild)) continue;
10246
10247 weights[n] = 1e-5
10248 + mMax(F0, (a_cellVolume(nghbrId) + m_cellVolumesDt1[nghbrId]))
10249 / (F2 * grid().gridCellVolume(a_level(cellId)));
10250
10251
10252 MInt bndryId = a_bndryId(nghbrId);
10253 if(bndryId < 0) mTerm(1, AT_, "not expected");
10254 weights[n] = grid().gridCellVolume(a_level(cellId))
10255 / mMax(1e-10, fabs(a_cellVolume(nghbrId) + m_massRedistributionVolume[i]
10257 - m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume));
10258
10259 volCnt += weights[n];
10260 }
10261 for(MInt n = 0; n < counter; n++) {
10262 weights[n] /= mMax(1e-14, volCnt);
10263 }
10264 }
10265
10266 for(MInt n = 0; n < counter; n++) {
10267 MInt nghbrId = nghbrList[n];
10268 if(nghbrId < 0) continue;
10269 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
10270 if(a_bndryId(nghbrId) < 0) continue;
10271
10272 if(a_hasProperty(nghbrId, SolverCell::IsSplitCell)) continue;
10273 if(a_hasProperty(nghbrId, SolverCell::IsSplitChild)) continue;
10274
10275 const MFloat fac = weights[n];
10276
10277 if(!a_hasProperty(nghbrId, SolverCell::NearWall)) {
10278 cerr << "[" << domainId() << "]: "
10279 << " nghbr " << nghbrId << " of cell " << cellId << " does not lie in bndryLayer! " << endl;
10280 cerr << " nghbr is a split cell: " << a_hasProperty(nghbrId, SolverCell::IsSplitCell)
10281 << " is split child: " << a_hasProperty(nghbrId, SolverCell::IsSplitChild) << endl;
10282 }
10283
10284 for(MUint v = 0; v < noPVars; v++) {
10285 a_slope(nghbrId, v, 0) += fac * m_massRedistributionVolume[i] * m_massRedistributionVariables[i * noPVars + v];
10286 a_slope(nghbrId, v, 1) += fac * m_massRedistributionRhs[i * noPVars + v];
10287 }
10288
10289 redistVol(nghbrId) += fac * m_massRedistributionVolume[i];
10290 redistSweptVol(nghbrId) += fac * m_massRedistributionSweptVol[i];
10291 }
10294 }
10295
10301
10302
10303 {
10304 // 1. send redistributed mass back to window cells
10305 haloReq.fill(MPI_REQUEST_NULL);
10306 windowReq.fill(MPI_REQUEST_NULL);
10307 for(MInt i = 0; i < noNeighborDomains(); i++) {
10308 if(m_fvBndryCnd->m_nearBoundaryHaloCells[i].empty()) continue;
10309 for(MInt j = 0; j < (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
10310 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
10311 MInt offset = haloBufferOffsets(i) + (noPVars + noFVars + 3) * j;
10312 // ASSERT( a_hasProperty( cellId , SolverCell::NearWall ), "" );
10313 haloBuffer(offset) = redistVol(cellId);
10314 haloBuffer(offset + 1) = redistSweptVol(cellId);
10315 for(MInt v = 0; v < (signed)noPVars; v++) {
10316 haloBuffer(offset + 3 + v) = a_slope(cellId, v, 0);
10317 haloBuffer(offset + 3 + noPVars + v) = a_slope(cellId, v, 1);
10318 }
10319 }
10320 }
10321 MInt haloCnt = 0;
10322 MInt windowCnt = 0;
10323 if(m_nonBlockingComm) {
10324 for(MInt i = 0; i < noNeighborDomains(); i++) {
10325 if(windowBufferCnts(i) == 0) continue;
10326 MPI_Irecv(&windowBuffer[windowBufferOffsets[i]], windowBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 17,
10327 mpiComm(), &windowReq[windowCnt], AT_, "windowBuffer[windowBufferOffsets[i]]");
10328 windowCnt++;
10329 }
10330 for(MInt i = 0; i < noNeighborDomains(); i++) {
10331 if(haloBufferCnts(i) == 0) continue;
10332 MPI_Isend(&haloBuffer[haloBufferOffsets[i]], haloBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 17, mpiComm(),
10333 &haloReq[haloCnt], AT_, "haloBuffer[haloBufferOffsets[i]]");
10334 haloCnt++;
10335 }
10336 if(windowCnt > 0) MPI_Waitall(windowCnt, &windowReq[0], MPI_STATUSES_IGNORE, AT_);
10337 } else {
10338 for(MInt i = 0; i < noNeighborDomains(); i++) {
10339 if(haloBufferCnts(i) == 0) continue;
10340 MPI_Issend(&haloBuffer[haloBufferOffsets[i]], haloBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 17, mpiComm(),
10341 &haloReq[haloCnt], AT_, "haloBuffer[haloBufferOffsets[i]]");
10342 haloCnt++;
10343 }
10344 for(MInt i = 0; i < noNeighborDomains(); i++) {
10345 if(windowBufferCnts(i) == 0) continue;
10346 MPI_Recv(&windowBuffer[windowBufferOffsets[i]], windowBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 17,
10347 mpiComm(), MPI_STATUS_IGNORE, AT_, "windowBuffer[windowBufferOffsets[i]]");
10348 windowCnt++;
10349 }
10350 }
10351
10352 for(MInt i = 0; i < noNeighborDomains(); i++) {
10353 if(m_fvBndryCnd->m_nearBoundaryWindowCells[i].empty()) continue;
10354 for(MInt j = 0; j < (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size(); j++) {
10355 MInt cellId = m_fvBndryCnd->m_nearBoundaryWindowCells[i][j];
10356 MInt offset = windowBufferOffsets(i) + (noCVars + noFVars + 3) * j;
10357 // ASSERT( a_hasProperty( cellId , SolverCell::NearWall ), "" );
10358 redistVol(cellId) += windowBuffer(offset);
10359 redistSweptVol(cellId) += windowBuffer(offset + 1);
10360
10361 for(MInt v = 0; v < (signed)noPVars; v++) {
10362 a_slope(cellId, v, 0) += windowBuffer(offset + 3 + v);
10363 a_slope(cellId, v, 1) += windowBuffer(offset + 3 + noPVars + v);
10364 }
10365 }
10366 }
10367 if(haloCnt > 0) MPI_Waitall(haloCnt, &haloReq[0], MPI_STATUSES_IGNORE, AT_);
10368 }
10369
10370 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
10372 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
10373 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
10374 if(a_isPeriodic(cellId)) continue;
10375 if(a_isHalo(cellId)) continue;
10376 if(fabs(redistVol(cellId)) < 1e-12) continue;
10377
10378 MFloat vol = m_cellVolumesDt1[cellId] + redistVol(cellId);
10379 if(fabs(vol) > 1e-14) {
10380 for(MUint v = 0; v < noCVars; v++) {
10381 a_oldVariable(cellId, v) = (a_oldVariable(cellId, v) * m_cellVolumesDt1[cellId] + a_slope(cellId, v, 0))
10382 / (m_cellVolumesDt1[cellId] + redistVol(cellId));
10383 m_rhs0[cellId][v] += a_slope(cellId, v, 1);
10384 }
10385 }
10386 m_cellVolumesDt1[cellId] = vol;
10387#ifdef GEOM_CONS_LAW
10388 if(a_bndryId(cellId) > -1) {
10389 a_cellVolume(cellId) += redistVol(cellId);
10390 m_sweptVolumeDt1[a_bndryId(cellId)] += redistSweptVol(cellId);
10391 if(m_gclIntermediate) {
10392 if(m_levelSetMb) a_cellVolume(cellId) += redistSweptVol(cellId);
10393 } else {
10394 if(m_levelSetMb) a_cellVolume(cellId) += F1B2 * redistSweptVol(cellId);
10395 }
10396 a_cellVolume(cellId) = mMax(m_volumeThreshold, a_cellVolume(cellId));
10397 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
10398 m_volumeFraction[a_bndryId(cellId)] = a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId));
10399 } else {
10400 cerr << "not supposed to happen at redist" << endl;
10401 }
10402#endif
10403 }
10404
10405
10406#ifdef GEOM_CONS_LAW
10408
10409 MBool conserveMass = true;
10410 if(m_gapInitMethod == 0 && m_gapOpened) {
10411 conserveMass = false;
10412 } else if(m_gapInitMethod > 0) {
10413 conserveMass = true;
10414 }
10415
10416 if(!firstRun && conserveMass) {
10417 if(m_gclIntermediate) {
10418 // init with the minium volume to increase stability of small cell treatment
10419 const MInt noBCells = m_fvBndryCnd->m_bndryCells->size();
10420 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBCells; bndryId++) {
10421 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
10422 MFloat dV0 = m_sweptVolumeDt1[bndryId];
10423 MFloat dV1 = m_sweptVolume[bndryId];
10424 MFloat vol = m_cellVolumesDt1[cellId] + dV0;
10425 for(MInt r = 1; r < m_noRKSteps; r++) {
10426 const MFloat deltaVol = m_RKalpha[r - 1] * dV1 + (F1 - m_RKalpha[r - 1]) * dV0;
10427 vol = mMin(m_cellVolumesDt1[cellId] + deltaVol, vol);
10428 }
10429 vol = mMax(F0, vol);
10430 a_cellVolume(cellId) = vol;
10431 a_cellVolume(cellId) = mMax(a_cellVolume(cellId), m_volumeThreshold);
10432 m_volumeFraction[bndryId] = a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId));
10433 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
10434 }
10435 } else {
10436 const MInt noBCells = m_fvBndryCnd->m_bndryCells->size();
10437 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBCells; bndryId++) {
10438 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
10439 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
10440 MFloat dV0 = m_sweptVolumeDt1[bndryId];
10441 MFloat dV1 = m_sweptVolume[bndryId];
10442 a_cellVolume(cellId) =
10443 m_cellVolumesDt1[cellId] + m_RKalpha[m_noRKSteps - 2] * dV1 + (F1 - m_RKalpha[m_noRKSteps - 2]) * dV0;
10444 a_cellVolume(cellId) = mMax(a_cellVolume(cellId), m_volumeThreshold);
10445 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
10446 }
10447 }
10448 }
10449 firstRun = false;
10450#endif
10451
10452
10453 // truncate cell volumes for large deviations due to GCL
10454 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
10455 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
10456 const MFloat V0 = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume - 0.1 * grid().gridCellVolume(a_level(cellId));
10457 const MFloat V1 = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume + 0.1 * grid().gridCellVolume(a_level(cellId));
10458 a_cellVolume(cellId) = mMin(V1, mMax(V0, a_cellVolume(cellId)));
10459 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
10460 }
10461
10462 {
10463 // 2. synchronize cell volumes
10464 haloReq.fill(MPI_REQUEST_NULL);
10465 windowReq.fill(MPI_REQUEST_NULL);
10466 for(MInt i = 0; i < noNeighborDomains(); i++) {
10467 if(m_fvBndryCnd->m_nearBoundaryWindowCells[i].empty()) continue;
10468 for(MInt j = 0; j < (signed)m_fvBndryCnd->m_nearBoundaryWindowCells[i].size(); j++) {
10469 MInt cellId = m_fvBndryCnd->m_nearBoundaryWindowCells[i][j];
10470 MInt offset = windowBufferOffsets(i) + (noCVars + noFVars + 3) * j;
10471 windowBuffer(offset) = a_cellVolume(cellId);
10472 windowBuffer(offset + 1) = m_cellVolumesDt1[cellId];
10473 windowBuffer(offset + 2) = (a_bndryId(cellId) > -1) ? m_sweptVolumeDt1[a_bndryId(cellId)] : F0;
10474 for(MInt v = 0; v < (signed)noCVars; v++) {
10475 windowBuffer(offset + 3 + v) = a_oldVariable(cellId, v);
10476 }
10477 for(MInt v = 0; v < (signed)noFVars; v++) {
10478 windowBuffer(offset + 3 + noCVars + v) = m_rhs0[cellId][v];
10479 }
10480 }
10481 }
10482 MInt windowCnt = 0;
10483 MInt haloCnt = 0;
10484 if(m_nonBlockingComm) {
10485 for(MInt i = 0; i < noNeighborDomains(); i++) {
10486 if(haloBufferCnts(i) == 0) continue;
10487 MPI_Irecv(&haloBuffer[haloBufferOffsets[i]], haloBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 18, mpiComm(),
10488 &haloReq[haloCnt], AT_, "haloBuffer[haloBufferOffsets[i]]");
10489 haloCnt++;
10490 }
10491 for(MInt i = 0; i < noNeighborDomains(); i++) {
10492 if(windowBufferCnts(i) == 0) continue;
10493 MPI_Isend(&windowBuffer[windowBufferOffsets[i]], windowBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 18,
10494 mpiComm(), &windowReq[windowCnt], AT_, "windowBuffer[windowBufferOffsets[i]]");
10495 windowCnt++;
10496 }
10497 if(haloCnt > 0) MPI_Waitall(haloCnt, &haloReq[0], MPI_STATUSES_IGNORE, AT_);
10498 } else {
10499 for(MInt i = 0; i < noNeighborDomains(); i++) {
10500 if(windowBufferCnts(i) == 0) continue;
10501 MPI_Issend(&windowBuffer[windowBufferOffsets[i]], windowBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 18,
10502 mpiComm(), &windowReq[windowCnt], AT_, "windowBuffer[windowBufferOffsets[i]]");
10503 windowCnt++;
10504 }
10505 for(MInt i = 0; i < noNeighborDomains(); i++) {
10506 if(haloBufferCnts(i) == 0) continue;
10507 MPI_Recv(&haloBuffer[haloBufferOffsets[i]], haloBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 18, mpiComm(),
10508 MPI_STATUS_IGNORE, AT_, "haloBuffer[haloBufferOffsets[i]]");
10509 haloCnt++;
10510 }
10511 }
10512 for(MInt i = 0; i < noNeighborDomains(); i++) {
10513 if(m_fvBndryCnd->m_nearBoundaryHaloCells[i].empty()) continue;
10514 for(MInt j = 0; j < (signed)m_fvBndryCnd->m_nearBoundaryHaloCells[i].size(); j++) {
10515 MInt cellId = m_fvBndryCnd->m_nearBoundaryHaloCells[i][j];
10516 MInt offset = haloBufferOffsets(i) + (noCVars + noFVars + 3) * j;
10517 a_cellVolume(cellId) = haloBuffer(offset);
10518 m_cellVolumesDt1[cellId] = haloBuffer(offset + 1);
10519 for(MInt v = 0; v < (signed)noCVars; v++) {
10520 a_oldVariable(cellId, v) = haloBuffer(offset + 3 + v);
10521 }
10522 for(MInt v = 0; v < (signed)noFVars; v++) {
10523 m_rhs0[cellId][v] = haloBuffer(offset + 3 + noCVars + v);
10524 }
10525 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
10526 if(a_bndryId(cellId) > -1) {
10527 m_volumeFraction[a_bndryId(cellId)] = a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId));
10528 m_sweptVolumeDt1[a_bndryId(cellId)] = haloBuffer(offset + 2);
10529 }
10530 }
10531 }
10532 if(windowCnt > 0) MPI_Waitall(windowCnt, &windowReq[0], MPI_STATUSES_IGNORE, AT_);
10533 }
10534
10535#ifndef GEOM_CONS_LAW
10536 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
10537 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
10538 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
10539 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
10540 m_volumeFraction[a_bndryId(cellId)] = a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId));
10541 }
10542#endif
10543
10544
10545//#define LOG_DELTA_VOL
10546#ifdef LOG_DELTA_VOL
10547 MFloat maxdv = -99999.0;
10548 MFloat mindv = 99999.0;
10549 MFloat avgdv = F0;
10550 MFloat cnt = F0;
10551 MInt maxId = 0;
10552 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
10553 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
10554 if(a_isHalo(cellId)) continue;
10555 MFloat dv = (a_cellVolume(cellId) - m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume)
10556 / grid().gridCellVolume(a_level(cellId));
10557 if(dv > maxdv) maxId = cellId;
10558 maxdv = mMax(maxdv, dv);
10559 mindv = mMin(mindv, dv);
10560 avgdv += fabs(dv);
10561 cnt += F1;
10562 }
10563 MPI_Allreduce(MPI_IN_PLACE, &maxdv, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "maxdv");
10564 MPI_Allreduce(MPI_IN_PLACE, &mindv, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_, "MPI_IN_PLACE", "mindv");
10565 MPI_Allreduce(MPI_IN_PLACE, &avgdv, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "avgdv");
10566 MPI_Allreduce(MPI_IN_PLACE, &cnt, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "cnt");
10567 avgdv /= cnt;
10568 if(domainId() == 0) {
10569 cerr << "dv: " << globalTimeStep << " " << avgdv << " " << maxdv << " " << mindv << " -- "
10570 << a_cellVolume(maxId) / grid().gridCellVolume(a_level(maxId)) << " "
10571 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(maxId)].m_volume / grid().gridCellVolume(a_level(maxId)) << " ("
10572 << m_cellVolumesDt1[maxId] / grid().gridCellVolume(a_level(maxId)) << " "
10573 << m_sweptVolume[a_bndryId(maxId)] / grid().gridCellVolume(a_level(maxId)) << " "
10574 << m_sweptVolumeDt1[a_bndryId(maxId)] / grid().gridCellVolume(a_level(maxId)) << " " << maxId << ")" << endl;
10575 ofstream ofl;
10576 ofl.open("vol_err", ios_base::out | ios_base::app);
10577 if(ofl.is_open() && ofl.good()) {
10578 ofl << setprecision(12) << globalTimeStep << " " << avgdv << " " << maxdv << " " << mindv << " "
10579 << a_cellVolume(maxId) / grid().gridCellVolume(a_level(maxId)) << " "
10580 << m_fvBndryCnd->m_bndryCells->a[a_bndryId(maxId)].m_volume / grid().gridCellVolume(a_level(maxId)) << " "
10581 << m_cellVolumesDt1[maxId] / grid().gridCellVolume(a_level(maxId)) << " "
10582 << m_sweptVolume[a_bndryId(maxId)] / grid().gridCellVolume(a_level(maxId)) << " "
10583 << m_sweptVolumeDt1[a_bndryId(maxId)] / grid().gridCellVolume(a_level(maxId)) << " " << maxId << endl;
10584 ofl.close();
10585 }
10586 }
10587#endif
10588
10589 // for ( MInt c = 0; c < m_noNearBndryCells; c++ ) {
10590 // setPrimitiveVariables(m_nearBndryCells->a[c]);
10591 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
10592 const MInt cellId = m_bndryLayerCells[c];
10593 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
10594 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
10595 setPrimitiveVariables(cellId);
10596 }
10597
10598
10599#if defined _MB_DEBUG_ || !defined NDEBUG
10600 m_solutionDiverged = false;
10601 MInt cnt = 0;
10602 for(MInt i = a_noCells(); i--;) {
10603 if(!a_hasProperty(i, SolverCell::IsActive)) continue;
10604 if(!a_hasProperty(i, SolverCell::IsOnCurrentMGLevel)) continue;
10605 if(a_isHalo(i)) continue;
10606 if(a_isBndryGhostCell(i)) continue;
10607 if(a_hasProperty(i, SolverCell::IsInactive)) continue;
10608 for(MInt v = 0; v < m_noCVars; v++) {
10609 if(!(a_variable(i, v) >= F0 || a_variable(i, v) < F0) || std::isnan(a_variable(i, v))) {
10610 if(cnt < 10)
10611 cerr << setprecision(12) << domainId() << ": MRED " << i << " " << a_bndryId(i) << " " << v << " "
10612 << a_variable(i, v) << " "
10613 << "cells[i].b_properties.to_string()"
10614 << " " << c_noChildren(i) << " " << a_hasProperty(i, SolverCell::IsInactive) << " "
10615 << a_hasProperty(i, SolverCell::IsSplitCell) << " " << a_hasProperty(i, SolverCell::IsSplitChild) << " "
10616 << a_cellVolume(i) / grid().gridCellVolume(a_level(i)) << " "
10617 << m_cellVolumesDt1[i] / grid().gridCellVolume(a_level(i));
10618 if(i < c_noCells()) cerr << " " << c_globalId(i) << endl;
10619 m_solutionDiverged = true;
10620 cnt++;
10621 }
10622 }
10623 MFloat pres = F0;
10624 IF_CONSTEXPR(nDim == 2) {
10625 pres =
10626 sysEqn().pressure(1.0, a_pvariable(i, PV->RHO) * (POW2(a_pvariable(i, PV->U)) + POW2(a_pvariable(i, PV->V))),
10627 a_variable(i, CV->RHO_E));
10628 }
10629 else IF_CONSTEXPR(nDim == 3) {
10630 pres = sysEqn().pressure(
10631 1.0,
10632 a_pvariable(i, PV->RHO)
10633 * (POW2(a_pvariable(i, PV->U)) + POW2(a_pvariable(i, PV->V)) + POW2(a_pvariable(i, PV->W))),
10634 a_variable(i, CV->RHO_E));
10635 }
10636 if(a_cellVolume(i) / grid().gridCellVolume(a_level(i)) > m_fvBndryCnd->m_volumeLimitWall) {
10637 if(a_variable(i, CV->RHO) < F0 || pres < F0) {
10638 if(cnt < 10)
10639 cerr << domainId() << ": MRED " << i << " " << a_bndryId(i) << " " << a_level(i) << " /r "
10640 << a_variable(i, CV->RHO) << " /p " << pres << " /v "
10641 << a_cellVolume(i) / grid().gridCellVolume(a_level(i)) << " "
10642 << m_cellVolumesDt1[i] / grid().gridCellVolume(a_level(i)) << " "
10643 << "cells[i].b_properties.to_string()"
10644 << " " << a_hasProperty(i, SolverCell::IsSplitCell) << " " << a_hasProperty(i, SolverCell::IsSplitChild)
10645 << " " << a_isPeriodic(i) << " " << a_coordinate(i, 0) << " " << a_coordinate(i, 1) << " "
10646 << a_coordinate(i, mMin((MInt)FD, 2));
10647 if(i < c_noCells()) cerr << " " << c_globalId(i) << endl;
10648 m_solutionDiverged = true;
10649 cnt++;
10650 }
10651 }
10652 }
10653 if(m_solutionDiverged) {
10654 cerr << "Solution diverged after mass redistribution at solver " << domainId() << " " << globalTimeStep << " "
10655 << m_RKStep << endl;
10656 }
10657 MPI_Allreduce(MPI_IN_PLACE, &m_solutionDiverged, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
10658 "m_solutionDiverged");
10659 if(m_solutionDiverged) {
10660 writeVtkXmlFiles("QOUT", "GEOM", false, true);
10661 MPI_Barrier(mpiComm(), AT_);
10662 mTerm(1, AT_, "Solution diverged after mass redistribution.");
10663 }
10664#endif
10665}

◆ refineCell()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::refineCell ( const MInt  gridCellId)
overridevirtual
Author

Reimplemented from Solver.

Definition at line 15181 of file fvmbcartesiansolverxd.cpp.

15181 {
15183
15184 ASSERT(grid().raw().a_hasProperty(gridCellId, Cell::WasRefined), "");
15185
15186 const MInt childLevel = grid().raw().a_level(gridCellId) + 1;
15187 const MFloat childVolume = grid().cellVolumeAtLevel(childLevel);
15188
15189 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
15190
15191 if(!g_multiSolverGrid) ASSERT(solverCellId == gridCellId, "");
15192
15193 if(solverCellId < 0) return;
15194
15195 // the fv-solver part has already added the cell to the solver!
15196 ASSERT(c_noChildren(solverCellId) > 0, "");
15197
15198 MInt noAddedChilds = 0;
15199
15200 for(MInt c = 0; c < grid().m_maxNoChilds; c++) {
15201 const MInt gridChildId = grid().raw().a_childId(gridCellId, c);
15202
15203 if(gridChildId < 0) continue;
15204
15205 // Skip if cell is a partition level ancestor and its child was not newly created
15206 if(!grid().raw().a_hasProperty(gridChildId, Cell::WasNewlyCreated)
15207 && grid().raw().a_hasProperty(gridCellId, Cell::IsPartLvlAncestor)) {
15208 continue;
15209 }
15210
15211 const MInt solverChildId = grid().tree().grid2solver(gridChildId);
15212
15213 if(solverChildId < 0) continue;
15214
15215 ASSERT(solverChildId == c_childId(solverCellId, c), "");
15216 noAddedChilds++;
15217
15218 for(MInt v = 0; v < m_noFVars; v++) {
15219 m_rhs0[solverChildId][v] = FFPOW2(nDim) * m_rhs0[solverCellId][v];
15220 }
15221
15222 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
15223 a_levelSetValuesMb(solverChildId, set) = a_levelSetValuesMb(solverCellId, set);
15224 a_associatedBodyIds(solverChildId, set) = a_associatedBodyIds(solverCellId, set);
15225 }
15226 m_cellVolumesDt1[solverChildId] = childVolume;
15227 if(m_dualTimeStepping) m_cellVolumesDt2[solverChildId] = childVolume;
15228
15229 a_isGapCell(solverChildId) = a_isGapCell(solverCellId);
15230 a_wasGapCell(solverChildId) = a_wasGapCell(solverCellId);
15231
15232 a_hasProperty(solverChildId, SolverCell::WasInactive) = a_hasProperty(solverCellId, SolverCell::WasInactive);
15233
15234 // if a solverCell is oldBndryCell, all childs are set aswell
15235 // the childs will be corrected later!
15236 // parenta are remaining, to identify the just added cells after the adaptation
15237 auto it = m_oldBndryCells.find(solverCellId);
15238 if(it != m_oldBndryCells.end()) {
15239 const MFloat sweptVol = it->second;
15240 m_oldBndryCells.insert(make_pair(solverChildId, sweptVol));
15241 ASSERT(m_bndryLevelJumps, "");
15242 }
15243
15244 if(grid().azimuthalPeriodicity()) {
15245 // TODO
15246 }
15247 }
15248
15249 if(noAddedChilds > 0) {
15250 a_isGapCell(solverCellId) = false;
15251 a_wasGapCell(solverCellId) = false;
15252 }
15253}
void refineCell(const MInt) override
MBool g_multiSolverGrid

◆ reInitSolutionStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::reInitSolutionStep ( const MInt  mode)
Author
Lennart Schneiders mode = -1: default argument, regular call (each time step) mode = 0: reinit after mesh adaptation mode = 1: initial call before first time step mode = 2: reinit after load balancing (depricated)

Definition at line 1597 of file fvmbcartesiansolverxd.cpp.

1597 {
1598 TRACE();
1599
1600 if((mode < 0) && (!m_trackMovingBndry || globalTimeStep < m_trackMbStart || globalTimeStep > m_trackMbEnd)) {
1601 return;
1602 }
1603
1604 NEW_TIMER_GROUP_STATIC(t_initTimer, "reInitSolutionStep");
1605 NEW_TIMER_STATIC(t_timertotal, "reInitSolutionStep", t_initTimer);
1606 NEW_SUB_TIMER_STATIC(t_resetSolverMb, "resetSolverMb", t_timertotal);
1607 NEW_SUB_TIMER_STATIC(t_trackBoundaryLayer, "trackBoundaryLayer", t_timertotal);
1608 NEW_SUB_TIMER_STATIC(t_generateBndryCellsMb, "generateBndryCellsMb", t_timertotal);
1609 NEW_SUB_TIMER_STATIC(t_imagePointRec, "imagePointRec", t_timertotal);
1610 NEW_SUB_TIMER_STATIC(t_initBndEx, "initBndEx", t_timertotal);
1611 NEW_SUB_TIMER_STATIC(t_massRedist, "massRedist", t_timertotal);
1612 NEW_SUB_TIMER_STATIC(t_initSmallCells, "initSmallCells", t_timertotal);
1613 NEW_SUB_TIMER_STATIC(t_generateSurfaces, "generateSurfaces", t_timertotal);
1614 NEW_SUB_TIMER_STATIC(t_buildLeastSquaresStencil, "buildLeastSquaresStencil", t_timertotal);
1615 NEW_SUB_TIMER_STATIC(t_finalize, "finalize", t_timertotal);
1616 m_tCutGroupTotal = t_timertotal;
1617 m_tCutGroup = t_generateBndryCellsMb;
1618 RECORD_TIMER_START(t_timertotal);
1619
1620 RECORD_TIMER_START(m_timers[Timers::ReinitSolu]);
1621
1622 // update cfl-number and change timeStep
1624 setTimeStep();
1625 }
1626
1627 m_reComputedBndry = true;
1628 RECORD_TIMER_START(t_resetSolverMb);
1629 if(mode != 0) {
1630 resetSolverMb();
1631 }
1632 RECORD_TIMER_STOP(t_resetSolverMb);
1633
1634 RECORD_TIMER_START(t_trackBoundaryLayer);
1636#if defined _MB_DEBUG_ || !defined NDEBUG
1638#endif
1639 RECORD_TIMER_STOP(t_trackBoundaryLayer);
1640
1641 RECORD_TIMER_START(m_timers[Timers::BndryMb]);
1642 RECORD_TIMER_START(t_generateBndryCellsMb);
1644 RECORD_TIMER_STOP(t_generateBndryCellsMb);
1645 RECORD_TIMER_STOP(m_timers[Timers::BndryMb]);
1646
1647 if(m_wmLES) {
1648 m_fvBndryCnd->initWMSurfaces();
1651 }
1652
1653#if defined _MB_DEBUG_ || !defined NDEBUG
1654 // In debug mode exhange() calls maxResidual(), which fails if RHS
1655 // is not set to 0 during init call (contains nans otherwise)
1656 resetRHS();
1657#endif
1658
1661
1662 // possibility for bndryCell distribution over all ranks!
1663 // This is useful to check the balance/distribution
1664 //=> keep the commented code below!
1665 /*
1666 if(mode != -1 || globalTimeStep % 10 == 0) {
1667 MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
1668 MInt maxBndryCells = 0;
1669 MInt minBndryCells = -1;
1670 MInt sumBndryCells = 0;
1671
1672 MPI_Allreduce(&noBndryCells, &maxBndryCells, 1, MPI_INT, MPI_MAX, mpiComm(),
1673 AT_, "maxBndryCells","noBndryCells" );
1674
1675 MPI_Allreduce(&noBndryCells, &minBndryCells, 1, MPI_INT, MPI_MIN, mpiComm(),
1676 AT_, "maxBndryCells","noBndryCells" );
1677 MPI_Allreduce(&noBndryCells, &sumBndryCells, 1, MPI_INT, MPI_SUM, mpiComm(),
1678 AT_, "maxBndryCells","noBndryCells" );
1679
1680
1681 if(domainId() == 0) {
1682 cerr << "Min/Max/Avg Bndry-Cell-Count: " << minBndryCells << " "
1683 << maxBndryCells << " " << sumBndryCells/noDomains() << endl;
1684 }
1685
1686 if(noBndryCells == maxBndryCells) {
1687 cerr << "Rank with max-BndryCells has " << a_noCells() << " cells and "
1688 << m_initialSurfacesOffset << " surfaces!" << endl;
1689 }
1690 }
1691 */
1692
1693 m_fvBndryCnd->correctCellCoordinates();
1694
1695 if((!m_levelSetMb || m_gapOpened) && mode < 1 && m_gapInitMethod == 0) {
1697 }
1698
1699#ifdef _MB_DEBUG_XXX
1700 for(MInt i = 0; i < a_noCells(); i++) {
1701 if((a_levelSetValuesMb(i, 0) > F0 || a_bndryId(i) > -1) && (c_noChildren(i) == 0)
1702 && ((!a_hasProperty(i, SolverCell::IsActive) && !a_isHalo(i))
1703 || ((!a_hasProperty(i, SolverCell::IsOnCurrentMGLevel) || a_hasProperty(i, SolverCell::IsInactive))
1704 && !a_hasProperty(i, SolverCell::IsNotGradient)))) {
1705 cerr << domainId() << ": " << i << " " << c_globalId(i) << " /b " << a_bndryId(i) << " /l "
1706 << a_levelSetValuesMb(i, 0) << " /i " << a_hasProperty(i, SolverCell::IsInactive) << " /p15 " << a_isHalo(i)
1707 << " /p7 " << a_hasProperty(i, SolverCell::IsNotGradient) << " /p10 " << a_hasProperty(i, SolverCell::IsFlux)
1708 << " /p11 " << a_hasProperty(i, SolverCell::IsActive) << " /p13 "
1709 << a_hasProperty(i, SolverCell::IsOnCurrentMGLevel) << endl;
1710 mTerm(1, AT_, "Invalid cell flag.");
1711 }
1712 }
1713#endif
1714
1715 if(m_fvBndryCnd->m_cellMerging) {
1716 findNghbrIds();
1717 if(m_fvBndryCnd->m_multipleGhostCells) {
1718 m_fvBndryCnd->detectSmallBndryCellsMGC();
1719 } else {
1720 m_fvBndryCnd->detectSmallBndryCells();
1721 }
1722 if(m_fvBndryCnd->m_multipleGhostCells) {
1723 m_fvBndryCnd->mergeCellsMGC();
1724 } else {
1725 m_fvBndryCnd->mergeCells();
1726 }
1729 m_log << " found " << m_fvBndryCnd->m_smallBndryCells->size() << "small cells." << endl;
1730 } else {
1731 RECORD_TIMER_START(m_timers[Timers::NearBndry]);
1732 RECORD_TIMER_START(t_initBndEx);
1733 m_fvBndryCnd->setNearBoundaryRecNghbrs(m_movingBndryCndId);
1734 if(grid().azimuthalPeriodicity()) {
1739 }
1741
1742 RECORD_TIMER_STOP(m_timers[Timers::NearBndry]);
1743 RECORD_TIMER_STOP(t_initBndEx);
1744 RECORD_TIMER_START(t_massRedist);
1745#ifdef _ALE_FORM_
1746 if(mode > 0) {
1747 std::vector<MInt>().swap(m_massRedistributionIds);
1748 std::vector<MFloat>().swap(m_massRedistributionVariables);
1749 std::vector<MFloat>().swap(m_massRedistributionRhs);
1750 std::vector<MFloat>().swap(m_massRedistributionVolume);
1751 std::vector<MFloat>().swap(m_massRedistributionSweptVol);
1752 std::vector<std::tuple<MInt, MInt, MInt>>().swap(m_temporarilyLinkedCells);
1753 }
1755 // call before initSmallCellCorrection
1756 // but after correctCellCoordinates and initNearBoundaryExchange !!
1757#endif
1758 RECORD_TIMER_STOP(t_massRedist);
1759
1760 RECORD_TIMER_START(t_imagePointRec);
1761 m_fvBndryCnd->computeImagePointRecConst(m_movingBndryCndId);
1762 RECORD_TIMER_STOP(t_imagePointRec);
1763
1764 RECORD_TIMER_START(m_timers[Timers::InitSmallCorr]);
1765 RECORD_TIMER_START(t_initSmallCells);
1766 if(m_fvBndryCnd->m_smallCellRHSCorrection) {
1767 m_fvBndryCnd->initSmallCellRHSCorrection(m_movingBndryCndId);
1768 } else {
1769 m_fvBndryCnd->initSmallCellCorrection(m_movingBndryCndId);
1770 }
1771 RECORD_TIMER_STOP(t_initSmallCells);
1772 RECORD_TIMER_STOP(m_timers[Timers::InitSmallCorr]);
1773 }
1774
1775 // check surfaces for gapClosing
1776 if(m_levelSet && m_closeGaps) {
1777 for(MInt region = 0; region < m_noGapRegions; region++) {
1778 if(m_gapState[region] != -2) continue;
1779 for(MInt srfcId = 0; srfcId < a_noSurfaces(); srfcId++) {
1780 MInt nghbrId0 = a_surfaceNghbrCellId(srfcId, 0);
1781 MInt nghbrId1 = a_surfaceNghbrCellId(srfcId, 1);
1782 if(nghbrId0 <= 0 || nghbrId1 <= 0) continue;
1783 if(a_isGapCell(nghbrId0) && a_isGapCell(nghbrId1) && a_hasProperty(nghbrId0, SolverCell::IsInactive)
1784 && a_hasProperty(nghbrId1, SolverCell::IsInactive)) {
1785 ASSERT(!a_hasProperty(nghbrId0, SolverCell::WasInactive) && !a_hasProperty(nghbrId1, SolverCell::WasInactive),
1786 "");
1787
1788 ASSERT(a_levelSetValuesMb(nghbrId0, 0) < 0 && a_levelSetValuesMb(nghbrId1, 0) < 0, "");
1789
1790 ASSERT(m_gapInitMethod == 0, "This should have already been done in gapHandling! ");
1791 deleteSurface(srfcId);
1792
1793 cerr << "Deleting Gap-shadowed surfaces in region " << region << " due to Gap-Closure at timestep "
1794 << globalTimeStep << endl;
1795 cerr << " Of Cells: " << c_globalId(nghbrId0) << " and " << c_globalId(nghbrId1) << endl;
1796 }
1797 }
1798 }
1799 }
1800
1801 RECORD_TIMER_START(m_timers[Timers::GhostCells]);
1802 RECORD_TIMER_START(t_generateSurfaces);
1805
1806#if defined _MB_DEBUG_ || !defined NDEBUG
1807 for(MInt srfcId = 0; srfcId < a_noSurfaces(); srfcId++) {
1808 MInt nghbrId0 = a_surfaceNghbrCellId(srfcId, 0);
1809 MInt nghbrId1 = a_surfaceNghbrCellId(srfcId, 1);
1810 ASSERT(nghbrId0 > -1 && nghbrId1 > -1, "");
1811 if(a_hasProperty(nghbrId0, SolverCell::IsInactive) || a_hasProperty(nghbrId1, SolverCell::IsInactive)) {
1812 cerr << "p15/p7: " << a_isHalo(nghbrId0) << " " << a_isHalo(nghbrId1) << " / " << nghbrId0 << " " << nghbrId1
1813 << " / " << c_globalId(nghbrId0) << " " << c_globalId(nghbrId1) << " / "
1814 << a_hasProperty(nghbrId0, SolverCell::IsNotGradient) << " "
1815 << a_hasProperty(nghbrId1, SolverCell::IsNotGradient) << " / " << a_isGapCell(nghbrId0) << " "
1816 << a_isGapCell(nghbrId1) << " / " << a_hasProperty(nghbrId0, SolverCell::IsInactive) << " "
1817 << a_hasProperty(nghbrId1, SolverCell::IsInactive) << endl;
1818 cerr << "ls: " << a_levelSetValuesMb(nghbrId0, 0) << " " << a_levelSetValuesMb(nghbrId1, 0) << endl;
1819 cerr << "coord " << a_coordinate(nghbrId0, 0) << " " << a_coordinate(nghbrId0, 1) << " "
1820 << a_coordinate(nghbrId0, 2) << endl;
1821 }
1822 ASSERT(!a_hasProperty(nghbrId0, SolverCell::IsInactive) && !a_hasProperty(nghbrId1, SolverCell::IsInactive),
1823 to_string(srfcId) << " " << to_string(nghbrId0) << " " << to_string(nghbrId1) << " "
1824 << to_string(a_noCells()) << " " << to_string(c_globalId(nghbrId0)) << " "
1825 << to_string(c_globalId(nghbrId1)));
1826 }
1827#endif
1828
1829
1830 // restore outer boundary ghost cells and outer bounday surfaces
1831 const MInt noBnd = m_fvBndryCnd->m_bndryCells->size();
1832 m_fvBndryCnd->m_bndryCells->resetSize(m_noOuterBndryCells);
1836 m_fvBndryCnd->m_bndryCells->resetSize(noBnd);
1837
1838 // add Mb ghost cells and surfaces
1841 RECORD_TIMER_STOP(t_generateSurfaces);
1842 RECORD_TIMER_STOP(m_timers[Timers::GhostCells]);
1843
1844 RECORD_TIMER_START(t_buildLeastSquaresStencil);
1846 RECORD_TIMER_STOP(t_buildLeastSquaresStencil);
1847
1848 if(grid().azimuthalPeriodicity()) {
1851 if(mode == 0 || m_wasBalanced) {
1852 m_wasBalanced = false;
1853 }
1854 }
1855
1856 // possibility for surface distribution over all ranks!
1857 // This is useful to check the balance/distribution
1858 //=> keep the commented code below!
1859 /*
1860 if(mode != -1 || globalTimeStep % 10 == 0) {
1861 MInt initalSurf = m_initialSurfacesOffset;
1862
1863 MInt maxInital = 0;
1864 MInt minInitial = 0;
1865 MInt sumInitial = 0;
1866
1867 MPI_Allreduce(&initalSurf, &maxInital, 1,MPI_INT, MPI_MAX, mpiComm(),
1868 AT_, "maxInitial","initialSurf" );
1869
1870 MPI_Allreduce(&initalSurf, &minInitial, 1, MPI_INT, MPI_MIN, mpiComm(),
1871 AT_, "minTotal","minInitial" );
1872
1873 MPI_Allreduce(&initalSurf, &sumInitial, 1, MPI_INT, MPI_SUM, mpiComm(),
1874 AT_, "minTotal","totalSurf" );
1875
1876 if(domainId() == 0 ) {
1877 cerr << "Min/Max/Avg inital-Surface-Count: " << minInitial << " " << maxInital << " " << sumInitial/noDomains() <<
1878 endl;
1879 }
1880
1881 if(maxInital == initalSurf) {
1882 cerr << "Rank with max-Surfaces has " << a_noCells() << " cells and "
1883 << m_fvBndryCnd->m_bndryCells->size() << "bndry-Cells" << endl;
1884 }
1885 }
1886 */
1887
1888 RECORD_TIMER_START(t_finalize);
1889 if(m_fvBndryCnd->m_cellMerging) {
1890 m_fvBndryCnd->computePlaneVectors();
1891 }
1892
1893#ifdef SAFOKSAJFKO
1894 const MFloat EPS = 1e-6;
1895 const MInt xdim = a_noCells();
1896 MFloat area[m_noDirs];
1897 MInt errorFlag = false;
1898 for(MInt cellId = xdim; cellId--;) {
1899 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
1900 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
1901 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
1902 if(a_isPeriodic(cellId)) continue;
1903 if(a_isBndryGhostCell(cellId)) continue;
1904 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
1905 if(a_isHalo(cellId) && a_level(cellId) < maxRefinementLevel()) continue;
1906 if(a_isHalo(cellId)) continue;
1907 if(a_isHalo(cellId) && a_bndryId(cellId) > -1 && a_bndryId(cellId) < m_noOuterBndryCells) continue;
1908 MBool skip = false;
1909 if(a_isHalo(cellId) && a_level(cellId) == maxRefinementLevel()) {
1910 for(MInt dir = 0; dir < m_noDirs; dir++) {
1911 if(a_hasNeighbor(cellId, dir) > 0) {
1912 MInt nghbrId = c_neighborId(cellId, dir);
1913 if(a_hasProperty(nghbrId, SolverCell::IsNotGradient)) skip = true;
1914 } else {
1915 skip = true;
1916 }
1917 }
1918 }
1919 if(skip) continue;
1920 // if ( c_noChildren( cellId ) > 0 ) continue;
1921 MFloat test[nDim];
1922 const MFloat sign[2] = {-F1, F1};
1923 for(MInt k = 0; k < nDim; k++)
1924 test[k] = F0;
1925 MBool hasBndrySurface = false;
1926 for(MInt dir = 0; dir < m_noDirs; dir++) {
1927 area[dir] = F0;
1928 if(m_cellSurfaceMapping[cellId][dir] > -1) {
1929 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
1930 // if ( m_isActiveSurface[ srfcId ] ) {
1931 {
1932 MInt id = -1;
1933 if(a_surfaceNghbrCellId(srfcId, 0) == cellId)
1934 id = 1;
1935 else if(a_surfaceNghbrCellId(srfcId, 1) == cellId)
1936 id = 0;
1937 if(id < 0) continue;
1938 test[a_surfaceOrientation(srfcId)] += sign[id] * a_surfaceArea(srfcId);
1939 area[dir] = a_surfaceArea(srfcId);
1940 }
1941 } else if(a_hasNeighbor(cellId, dir) > 0) {
1942 MInt nghbrId = c_neighborId(cellId, dir);
1943 if(c_noChildren(nghbrId) > 0) {
1944 for(MInt child = 0; child < m_noCellNodes; child++) {
1945 if(!childCode[dir][child]) continue;
1946 MInt childId = c_childId(nghbrId, child);
1947 if(childId < 0) continue;
1948 if(m_cellSurfaceMapping[childId][m_revDir[dir]] > -1) {
1949 if(a_surfaceNghbrCellId(m_cellSurfaceMapping[childId][m_revDir[dir]], m_nghbrCellIds[m_revDir[dir] % 2) == cellId) {
1950 MInt srfcId = m_cellSurfaceMapping[childId][m_revDir[dir]];
1951 // if ( m_isActiveSurface[ srfcId ] ) {
1952 {
1953 MInt id = -1;
1954 if(a_surfaceNghbrCellId(srfcId, 0) == cellId)
1955 id = 1;
1956 else if(a_surfaceNghbrCellId(srfcId, 1) == cellId)
1957 id = 0;
1958 if(id < 0) continue;
1959 test[a_surfaceOrientation(srfcId)] += sign[id] * a_surfaceArea(srfcId);
1960 area[dir] = a_surfaceArea(srfcId);
1961 }
1962 }
1963 }
1964 }
1965 } else if(a_hasProperty(cellId, SolverCell::HasSplitFace)) {
1966 for(MInt srfcId = a_noSurfaces(); srfcId--;) {
1967 // if ( !m_isActiveSurface[ srfcId ] ) continue;
1968 if(a_surfaceBndryCndId(srfcId) > -1) continue;
1969 MInt id = -1;
1970 if(a_surfaceNghbrCellId(srfcId, 0) == cellId && dir == 2 * a_surfaceOrientation(srfcId) + 1)
1971 id = 1;
1972 else if(a_surfaceNghbrCellId(srfcId, 1) == cellId && dir == 2 * a_surfaceOrientation(srfcId))
1973 id = 0;
1974 if(id > -1) {
1975 test[a_surfaceOrientation(srfcId)] += sign[id] * a_surfaceArea(srfcId);
1976 area[dir] = a_surfaceArea(srfcId);
1977 }
1978 }
1979 }
1980 }
1981 }
1982 if(a_bndryId(cellId) > -1) {
1983 for(MInt bs = 0; bs < m_fvBndryCnd->m_noBoundarySurfaces; bs++) {
1984 MInt srfcId = m_fvBndryCnd->m_boundarySurfaces[bs];
1985 // if ( m_isActiveSurface[ srfcId ] ) {
1986 {
1987 MInt id = -1;
1988 if(a_surfaceNghbrCellId(srfcId, 0) == cellId)
1989 id = 1;
1990 else if(a_surfaceNghbrCellId(srfcId, 1) == cellId)
1991 id = 0;
1992 if(id < 0) continue;
1993 hasBndrySurface = true;
1994 test[a_surfaceOrientation(srfcId)] += sign[id] * a_surfaceArea(srfcId);
1995 }
1996 }
1997 }
1998 MBool testPassed = true;
1999 for(MInt k = 0; k < nDim; k++) {
2000 if(fabs(test[k]) > EPS * m_gridCellArea[a_level(cellId)]) {
2001 testPassed = false;
2002 }
2003 }
2004
2005 if(!testPassed) {
2006 for(MInt k = 0; k < nDim; k++) {
2007 cerr << domainId() << " " << nDim << ": cell " << cellId << " " << a_bndryId(cellId) << " "
2008 << a_hasProperty(cellId, SolverCell::IsInactive) << " " << (a_bndryId(cellId) < m_noOuterBndryCells)
2009 << " / " << hasBndrySurface << " " << a_isHalo(cellId) << " "
2010 << a_hasProperty(cellId, SolverCell::IsNotGradient) << " / " << k << " " << fabs(test[k]) << endl;
2011 }
2012 cerr << "Cell surface is not closed. Check the surfaces! " << domainId() << " " << cellId << " "
2013 << a_bndryId(cellId) << " " << a_isHalo(cellId) << " " << a_level(cellId) << " "
2014 << a_hasProperty(cellId, SolverCell::IsInactive) << " " << a_hasProperty(cellId, SolverCell::IsSplitCell)
2015 << " " << a_hasProperty(cellId, SolverCell::IsSplitChild) << " "
2016 << a_hasProperty(cellId, SolverCell::HasSplitFace) << endl;
2017 m_log << "Cell surface is not closed. Check the surfaces! " << domainId() << " " << cellId << " "
2018 << a_bndryId(cellId) << " " << a_isHalo(cellId) << " " << a_level(cellId) << endl;
2019 for(MInt dir2 = 0; dir2 < m_noDirs; dir2++) {
2020 cerr << m_cellSurfaceMapping[cellId][dir2] << "(";
2021 MInt nghbrId = (a_hasNeighbor(cellId, dir2) > 0) ? c_neighborId(cellId, dir2) : -1;
2022 MInt state = (nghbrId > -1) ? a_hasProperty(nghbrId, SolverCell::IsInactive) : -1;
2023 cerr << nghbrId << "/" << state << ") ";
2024 }
2025 cerr << endl;
2026 errorFlag = true;
2027 }
2028 }
2029
2030 const MInt xdim0 = a_noCells();
2031 for(MInt i = xdim0; i--;) {
2032 if(a_hasProperty(i, SolverCell::IsCutOff)) continue;
2033 if(a_hasProperty(i, SolverCell::IsNotGradient)) continue;
2034 if(a_isBndryGhostCell(i)) continue;
2035 if(a_hasProperty(i, SolverCell::IsInactive)) continue;
2036 ASSERT((a_noReconstructionNeighbors(i) == 0 || c_noChildren(i) == 0), "No reconstruction nghbrs expected");
2037 if(c_noChildren(i) > 0) continue;
2038 MBool localError = false;
2039 for(MInt n = a_noReconstructionNeighbors(i); n--;) {
2040 if((a_bndryId(a_reconstructionNeighborId(i, n)) > -2)
2042 || a_hasProperty(a_reconstructionNeighborId(i, n), SolverCell::IsInactive)
2043 || !a_hasProperty(a_reconstructionNeighborId(i, n), SolverCell::IsOnCurrentMGLevel))) {
2044 cerr << domainId() << ": Inactive cell used in least squares reconstruction!!!!" << i << " " << n << "/"
2045 << a_noReconstructionNeighbors(i) << " / " << a_reconstructionNeighborId(i, n) << " " << a_isHalo(i) << " "
2046 << a_isBndryGhostCell(i) << " /l " << a_level(i) << " " << a_level(a_reconstructionNeighborId(i, n))
2047 << " / " << a_hasProperty(i, SolverCell::IsInactive) << " " << a_bndryId(i) << " /c "
2048 << a_coordinate(a_reconstructionNeighborId(i, n), 0) << " "
2049 << a_coordinate(a_reconstructionNeighborId(i, n), 1) << " " << a_coordinate(i, 0) << " "
2050 << a_coordinate(i, 1) << " / "
2051 << a_hasProperty(a_reconstructionNeighborId(i, n), SolverCell::IsOnCurrentMGLevel) << " "
2052 << a_isHalo(a_reconstructionNeighborId(i, n)) << " "
2053 << a_hasProperty(a_reconstructionNeighborId(i, n), SolverCell::IsNotGradient) << " "
2055 << a_hasProperty(a_reconstructionNeighborId(i, n), SolverCell::IsInactive) << " "
2056 << a_bndryId(a_reconstructionNeighborId(i, n)) << endl;
2057 // writeVtkErrorFile();
2058 localError = true;
2059 }
2060 }
2061 if(localError) {
2062 for(MInt n = 0; n < a_noReconstructionNeighbors(i); n++) {
2063 m_log << a_reconstructionNeighborId(i, n) << " ";
2064 }
2065 m_log << endl;
2066 errorFlag = true;
2067 }
2068 }
2069 if(errorFlag) {
2070 cerr << domainId() << ": Error in reInitSolutionStep" << endl;
2071 m_log << "Error in reInitSolutionStep" << endl;
2072 }
2073
2074 MPI_Allreduce(MPI_IN_PLACE, &errorFlag, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "errorFlag");
2075
2076 if(errorFlag) {
2077 cerr << "Error in reInitSolutionStep" << endl;
2078 m_log << "Error in reInitSolutionStep" << endl;
2080 MPI_Barrier(mpiComm(), AT_);
2081 mTerm(1, AT_, ".");
2082 }
2083#endif
2084
2085 if((mode == 1)) {
2086 MFloat* RESTRICT slope = (MFloat*)(&(a_slope(0, 0, 0)));
2087 const MInt size = a_noCells() * m_slopeMemory * sizeof(MFloat);
2088 memset(&(slope[0]), 0, size);
2093 if(m_initialCondition == 15 || m_initialCondition == 16) {
2094 if(globalTimeStep == 0 && mode == 1) computeFlowStatistics(true);
2095 }
2096 }
2097
2098 if(m_restart) m_restart = false;
2099
2100#ifdef _MB_DEBUG_
2101 MFloatScratchSpace rhsTest(a_noCells(), AT_, "rhsTest");
2102 rhsTest.fill(F0);
2103 for(MInt srfcId = a_noSurfaces(); srfcId--;) {
2104 rhsTest[a_surfaceNghbrCellId(srfcId, 0)] += a_surfaceArea(srfcId);
2105 rhsTest[a_surfaceNghbrCellId(srfcId, 1)] -= a_surfaceArea(srfcId);
2106 }
2107
2108 for(MInt i = a_noCells(); i--;) {
2109 if(!a_hasProperty(i, SolverCell::IsActive)) continue;
2110 if(!a_hasProperty(i, SolverCell::IsOnCurrentMGLevel)) continue;
2111 if(a_isHalo(i)) continue;
2112 if(a_isBndryGhostCell(i)) continue;
2113 if(a_hasProperty(i, SolverCell::IsInactive)) continue;
2114 if(fabs(rhsTest[i]) > 1e-10) {
2115 cerr << domainId() << " Warning: cell may not be water tight " << i << " " << rhsTest[i] << " "
2116 << a_coordinate(i, 0) << " " << a_coordinate(i, 1) << " " << a_coordinate(i, mMin(nDim - 1, 2)) << endl;
2117 }
2118 }
2119#endif
2120
2121 // memory statistics:
2122 /*
2123 MLong noBndryCells = (MLong)m_fvBndryCnd->m_bndryCells->size();
2124 MLong noSurfaces = (MLong)a_noSurfaces();
2125 MLong noCells = (MLong)a_noCells();
2126
2127 m_log << "Maximum memory-values: " << endl;
2128 m_log << "Cells : " << noCells << endl;
2129 m_log << "Bndry-Cells: " << noBndryCells << endl;
2130 m_log << "Surfaces : " << noSurfaces << endl;
2131
2132 MPI_Allreduce(MPI_IN_PLACE, &noBndryCells, 1, MPI_LONG, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "noBndryCells");
2133 MPI_Allreduce(MPI_IN_PLACE, &noSurfaces, 1, MPI_LONG, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "noSurfaces");
2134 MPI_Allreduce(MPI_IN_PLACE, &noCells, 1, MPI_LONG, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "noCells");
2135
2136 cerr0 << "Maximum memory-values: " << endl;
2137 cerr0 << "Cells : " << noCells << endl;
2138 cerr0 << "Bndry-Cells: " << noBndryCells << endl;
2139 cerr0 << "Surfaces : " << noSurfaces << endl;
2140 */
2141
2142 RECORD_TIMER_STOP(m_timers[Timers::ReinitSolu]);
2143 RECORD_TIMER_STOP(t_finalize);
2144 RECORD_TIMER_STOP(t_timertotal);
2145 DISPLAY_TIMER_OFFSET(t_timertotal, m_restartInterval);
2146}
virtual void initNearBoundaryExchange(const MInt mode=0, const MInt offset=0)
Setup the near-boundary communicator needed for the flux-redistribution method.
void computeFlowStatistics(MBool force)
void initAzimuthalLinkedHaloExc()
Create exchange for all window/halo cells which are used for the azimuthal periodic interpolation.
void buildAdditionalAzimuthalReconstructionStencil(MInt mode=0)
Rebuild azimuthal reconstruction constants for moving boundary cells.
void updateAzimuthalNearBoundaryExchange()
Reset former azimuthal nearBoundaryCells.
void computeGhostCellsMb()
creates a ghost cell for all cells near(!) the moving boundary
void correctSrfcsMb()
correct surfaces intersected by the moving boundary
void generateBndryCellsMb(const MInt mode)
call all routines necessary for the generation of boundary cells mode = -1: default argument,...
void buildAdditionalReconstructionStencil()
correct reconstruction stencil for all cells near moving boundaries
void initializeEmergedCells()
initializes variables of cells which recently became active and therefore have no up-to-date history ...
void addBoundarySurfacesMb()
adds a surface for the ghost-boundary cell intersections
void writeVtkErrorFile()
write flow variables as XML VTK files
void updateAzimuthalMaxLevelRecCoords()
Update reconstruction coordinate for azimuthal halo cells on max level This is done because of moving...

◆ reIntAfterRestart()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::reIntAfterRestart ( MBool  doneRestart)
overridevirtual

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 24651 of file fvmbcartesiansolverxd.cpp.

24651 {
24652 TRACE();
24653
24654 if(doneRestart) {
24657 if(isActive()) {
24659 }
24660 }
24661}

◆ removeChilds()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::removeChilds ( const MInt  gridCellId)
overridevirtual
Author

Reimplemented from Solver.

Definition at line 15261 of file fvmbcartesiansolverxd.cpp.

15261 {
15262 const MInt solverCellId = grid().tree().grid2solver(gridCellId);
15263 ASSERT(solverCellId > -1 && solverCellId < m_cells.size(), "");
15264
15265 if(!g_multiSolverGrid) {
15266 ASSERT(solverCellId == gridCellId, "");
15267 ASSERT((m_cells.size() - grid().raw().treeb().size()) <= grid().m_maxNoChilds, "");
15268 }
15269
15270 ASSERT(grid().raw().a_noChildren(gridCellId) > 0, "");
15271
15272 // reset the solverCell-properties for the new leaf-cell:
15273 //- cellVolumeDt1
15274 //- oldVariable (this time with Dt1-volume!)
15275 //- rhs0
15276 m_cellVolumesDt1[solverCellId] = F0;
15277 for(MInt v = 0; v < m_noCVars; v++) {
15278 a_oldVariable(solverCellId, v) = F0;
15279 }
15280 for(MInt v = 0; v < m_noFVars; v++) {
15281 m_rhs0[solverCellId][v] = F0;
15282 }
15283 // reset solverCell-properties
15284 a_hasProperty(solverCellId, SolverCell::WasInactive) = false;
15285
15286 MBool wasGapCell = false;
15287 MBool isGapCell = false;
15288 MBool hasBndryCell = false;
15289 MFloat sweptVol = 0;
15290
15291 MInt wasInactive = 0;
15292 MInt noRemovedChilds = 0;
15293
15294 for(MInt c = 0; c < grid().m_maxNoChilds; c++) {
15295 const MInt gridChildId = grid().raw().a_childId(gridCellId, c);
15296 const MInt childId = c_childId(solverCellId, c);
15297 if(childId < 0) continue;
15298 noRemovedChilds++;
15299
15300 ASSERT(grid().tree().solver2grid(childId) == gridChildId, "");
15301
15302 if(!g_multiSolverGrid) ASSERT(childId == gridChildId, "");
15303
15304 if(a_wasGapCell(childId)) wasGapCell = true;
15305 if(a_isGapCell(childId)) isGapCell = true;
15306
15307 if(a_hasProperty(childId, SolverCell::WasInactive)) {
15308 wasInactive++;
15309 } else {
15310 MFloat vol1 = m_cellVolumesDt1[childId];
15311 m_cellVolumesDt1[solverCellId] += vol1;
15312 for(MInt v = 0; v < m_noCVars; v++) {
15313 a_oldVariable(solverCellId, v) += vol1 * a_oldVariable(childId, v);
15314 }
15315 for(MInt v = 0; v < m_noFVars; v++) {
15316 m_rhs0[solverCellId][v] += m_rhs0[childId][v];
15317 }
15318 }
15319
15320 {
15321 auto it = m_oldBndryCells.find(childId);
15322 if(it != m_oldBndryCells.end()) {
15323 hasBndryCell = true;
15324 sweptVol += it->second;
15325 ASSERT(!a_hasProperty(childId, SolverCell::WasInactive) || m_maxLevelDecrease, "");
15326 m_oldBndryCells.erase(it);
15327 ASSERT(m_bndryLevelJumps, "");
15328 }
15329 }
15330 {
15331 auto it = m_nearBoundaryBackup.find(childId);
15332 if(it != m_nearBoundaryBackup.end()) {
15333 m_nearBoundaryBackup.erase(it);
15334 }
15335 }
15336
15337 if(grid().azimuthalPeriodicity()) {
15338 // TODO
15339 }
15340 }
15341
15342 // update variables and properties for the new leaf-cell:
15343 if(wasInactive == noRemovedChilds) {
15344 a_hasProperty(solverCellId, SolverCell::WasInactive) = true;
15345
15346 // if of all childs were inactive, default variables are set!
15347 m_cellVolumesDt1[solverCellId] = grid().gridCellVolume(a_level(solverCellId));
15348 for(MInt v = 0; v < m_noFVars; v++) {
15349 m_rhs0[solverCellId][v] = 0;
15350 }
15351
15352 a_oldVariable(solverCellId, CV->RHO) = m_rhoInfinity;
15353 a_oldVariable(solverCellId, CV->RHO_E) = m_rhoEInfinity;
15354 for(MInt dir = 0; dir < nDim; dir++) {
15355 a_oldVariable(solverCellId, CV->RHO_VV[dir]) = m_rhoVVInfinity[dir];
15356 }
15357
15358 } else {
15359 for(MInt v = 0; v < m_noCVars; v++) {
15360 a_oldVariable(solverCellId, v) /= mMax(m_volumeThreshold, m_cellVolumesDt1[solverCellId]);
15361 }
15362 }
15363
15364 if(wasGapCell) a_wasGapCell(solverCellId) = true;
15365 if(isGapCell) a_isGapCell(solverCellId) = true;
15366 // NOTE: insert new bndryCells to coarseOldBndryCell sorted vector and
15367 // update according to current sweptVolume (see correctCoarseBndryCellVolume)
15368 // if they remain a bndryCell
15369 if(hasBndryCell) {
15370 m_coarseOldBndryCells.insert(solverCellId);
15371 m_oldBndryCells.insert(make_pair(solverCellId, sweptVol));
15372 }
15373
15374 // call removeChilds at the end, otherwise link to children is already invalidated!
15376
15377 // only single-solver!
15378 if(!g_multiSolverGrid) ASSERT((m_cells.size() - grid().raw().treeb().size()) <= grid().m_maxNoChilds, "");
15379}
void removeChilds(const MInt) override

◆ removeSurfaces()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::removeSurfaces ( MInt  cellId)
Author
Lennart Schneiders

Definition at line 16806 of file fvmbcartesiansolverxd.cpp.

16806 {
16807 for(MInt dir = 0; dir < m_noDirs; dir++) {
16808 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
16809
16810 if(srfcId > -1) {
16811 deleteSurface(srfcId);
16812 } else {
16813 if(!a_hasProperty(cellId, SolverCell::IsSplitChild) && checkNeighborActive(cellId, dir)
16814 && a_hasNeighbor(cellId, dir) > 0) {
16815 MInt nghbrId = c_neighborId(cellId, dir);
16816 if(c_noChildren(nghbrId) > 0) {
16817 for(MInt child = 0; child < m_noCellNodes; child++) {
16818 if(!childCode[dir][child]) continue;
16819 MInt childId = c_childId(nghbrId, child);
16820 if(childId < 0) continue;
16821 srfcId = m_cellSurfaceMapping[childId][m_revDir[dir]];
16822 if(srfcId > -1) {
16823 deleteSurface(srfcId);
16824 }
16825 }
16826 }
16827 }
16828 }
16829 }
16830}

◆ resetMbBoundaryCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetMbBoundaryCells
Author
Lennart Schneiders

Definition at line 20140 of file fvmbcartesiansolverxd.cpp.

20140 {
20141 TRACE();
20142
20143 MInt size;
20144 MInt noCells = m_fvBndryCnd->m_bndryCells->size();
20145
20146 // delete previous moving boundary cells
20147 for(MInt bndryId = noCells - 1; bndryId >= m_noOuterBndryCells; bndryId--) {
20148 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
20149
20150 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
20151 MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
20152 if(ghostCellId > -1) {
20153 ASSERT(a_bndryId(ghostCellId) == -2, "");
20154 a_bndryId(ghostCellId) = -1;
20155 }
20156 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = -1;
20157 }
20158
20159 a_bndryId(cellId) = -1;
20160
20161 size = m_fvBndryCnd->m_bndryCells->size();
20162 m_fvBndryCnd->m_bndryCells->resetSize(size - 1);
20163
20164 a_hasProperty(cellId, SolverCell::IsSplitCell) = false;
20165 a_hasProperty(cellId, SolverCell::IsSplitChild) = false;
20166 a_hasProperty(cellId, SolverCell::HasSplitFace) = false;
20167 a_hasProperty(cellId, SolverCell::IsTempLinked) = false;
20168 a_hasProperty(cellId, SolverCell::IsMovingBnd) = false;
20169
20170 a_noReconstructionNeighbors(cellId) = 0;
20171 m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.resize(0);
20172 m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst.resize(0);
20173 m_fvBndryCnd->m_bndryCell[bndryId].m_faceVertices.clear();
20174 for(MUint i = 0; i < m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream.size(); i++) {
20175 m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream[i].resize(0);
20176 }
20177 m_fvBndryCnd->m_bndryCell[bndryId].m_faceStream.resize(0);
20178 for(MInt srfc = 0; srfc < FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces; srfc++) {
20179 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.resize(0);
20180 for(MInt v = 0; v < m_noCVars; v++) {
20181 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] = BC_UNSET;
20182 }
20183 }
20184
20185 for(MInt dir = 0; dir < m_noDirs; dir++) {
20186 m_cutFaceArea[bndryId][dir] = F0;
20187 }
20188
20189 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId > -1) {
20190 cerr << "linking not expected" << endl;
20191 MInt pm = m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId;
20192 a_cellVolume(pm) = grid().gridCellVolume(a_level(pm));
20194 m_fvBndryCnd->m_bndryCells->a[bndryId].m_linkedCellId = -1;
20195 }
20196 }
20198
20199 for(MInt cellId = 0; cellId < c_noCells(); cellId++) {
20200 ASSERT(!a_hasProperty(cellId, SolverCell::IsMovingBnd), "");
20201 }
20202}

◆ resetRHSCutOffCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetRHSCutOffCells
overridevirtual
Author

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 19112 of file fvmbcartesiansolverxd.cpp.

◆ resetRHSNonInternalCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetRHSNonInternalCells
overridevirtual
Author

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 5128 of file fvmbcartesiansolverxd.cpp.

5128 {
5129#ifdef _MB_DEBUG_
5130 for(MInt i = 0; i < noNeighborDomains(); i++) {
5131 for(MInt j = 0; j < noHaloCells(i); j++) {
5132 MInt cellId = haloCellId(i, j);
5133
5134 if(c_noChildren(cellId) > 0) continue;
5135 if(!a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
5136
5137 for(MInt var = 0; var < m_noFVars; var++) {
5138 a_rightHandSide(cellId, var) = F0;
5139 }
5140 }
5141 }
5142#endif
5143}

◆ resetSlopes()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetSlopes
Author
Lennart Schneiders

Definition at line 21300 of file fvmbcartesiansolverxd.cpp.

21300 {
21301 TRACE();
21302
21303 std::fill(&a_slope(0, 0, 0), &a_slope(0, 0, 0) + a_noCells() * m_noPVars * nDim, F0);
21304}

◆ resetSolver()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetSolver
overridevirtual
Author
Lennart Schneiders

Reimplemented from Solver.

Definition at line 20060 of file fvmbcartesiansolverxd.cpp.

20060 {
20061 if(m_fvBndryCnd->m_cellCoordinatesCorrected) m_fvBndryCnd->recorrectCellCoordinates();
20062
20065}
void resetSolver() override
Reset the solver prior to load balancing.

◆ resetSolverFull()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetSolverFull
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 20024 of file fvmbcartesiansolverxd.cpp.

20024 {
20025 TRACE();
20026
20028
20029 for(MInt cellId = 0; cellId < maxNoGridCells(); cellId++) {
20030 for(MInt v = 0; v < m_noFVars; v++) {
20031 m_rhs0[cellId][v] = F0;
20032 }
20033 for(MInt dir = 0; dir < m_noDirs; dir++) {
20034 m_cellSurfaceMapping[cellId][dir] = -1;
20035 }
20038 }
20039
20041 m_nearBoundaryBackup.clear();
20042 m_oldBndryCells.clear();
20043
20044 std::map<MInt, std::vector<MFloat>>().swap(m_nearBoundaryBackup);
20045 std::map<MInt, MFloat>().swap(m_oldBndryCells);
20046 std::vector<MInt>().swap(m_bndryCandidateIds);
20047 std::vector<MInt>().swap(m_bndryCandidates);
20048 std::vector<MFloat>().swap(m_candidateNodeValues);
20049 std::vector<MInt>().swap(m_candidateNodeSet);
20050 std::set<MInt>().swap(m_splitSurfaces);
20051 std::vector<CutCandidate<nDim>>().swap(m_cutCandidates);
20052}
virtual void resetSolverFull()

◆ resetSolverMb()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetSolverMb
Author
Lennart Schneiders

Definition at line 20073 of file fvmbcartesiansolverxd.cpp.

20073 {
20074 TRACE();
20075
20076 if(m_deleteNeighbour) {
20078 }
20079
20080 for(MInt bs = 0; bs < m_fvBndryCnd->m_noBoundarySurfaces; bs++) {
20081 MInt srfcId = m_fvBndryCnd->m_boundarySurfaces[bs];
20082 a_surfaceNghbrCellId(srfcId, 0) = -1;
20083 a_surfaceNghbrCellId(srfcId, 1) = -1;
20084 }
20085 m_fvBndryCnd->m_noBoundarySurfaces = 0;
20086
20088
20089 if(m_fvBndryCnd->m_cellCoordinatesCorrected) m_fvBndryCnd->recorrectCellCoordinates();
20090
20091 set<MInt> tmpSplitSurf(m_splitSurfaces);
20092 m_splitSurfaces.clear();
20093 for(set<MInt>::iterator it = tmpSplitSurf.begin(); it != tmpSplitSurf.end(); ++it) {
20094 MInt srfcId = *it;
20095 deleteSurface(srfcId);
20096 }
20097
20098 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
20099 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
20100 if(a_isBndryGhostCell(cellId) || a_hasProperty(cellId, SolverCell::IsSplitChild)) {
20101 removeSurfaces(cellId);
20102 continue;
20103 }
20104 resetSurfaces(cellId);
20105 for(MInt dir = 0; dir < m_noDirs; dir++) {
20106 m_cutFaceArea[bndryId][dir] = F0;
20107 }
20108 }
20109
20112}
virtual void resetBoundaryCells(const MInt offset=0)

◆ resetSurfaces() [1/2]

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetSurfaces
overridevirtual
Author

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 20120 of file fvmbcartesiansolverxd.cpp.

20120 {
20121 TRACE();
20122
20124
20125 for(MInt cellId = 0; cellId < maxNoGridCells(); cellId++) {
20126 for(MInt dir = 0; dir < m_noDirs; dir++) {
20127 m_cellSurfaceMapping[cellId][dir] = -1;
20128 }
20129 }
20130 m_freeSurfaceIndices.clear();
20131 m_noSurfaces = 0;
20132}

◆ resetSurfaces() [2/2]

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::resetSurfaces ( MInt  cellId)
Author
Lennart Schneiders

Definition at line 16514 of file fvmbcartesiansolverxd.cpp.

16514 {
16515 if(a_isBndryGhostCell(cellId)) return;
16516 if(c_noChildren(cellId) > 0) return;
16517 if(a_hasProperty(cellId, SolverCell::IsInactive)) return;
16518
16519 // 1. restore state of existing surfaces on the uncut mesh
16520 for(MInt dir = 0; dir < m_noDirs; dir++) {
16521 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
16522 if(srfcId > -1) {
16523 if((a_surfaceNghbrCellId(srfcId, 0) < 0) || (a_surfaceNghbrCellId(srfcId, 1) < 0)) {
16524 cerr << srfcId << " " << cellId << " " << dir << " " << a_coordinate(cellId, 0) << " "
16525 << a_coordinate(cellId, 1) << " " << c_neighborId(cellId, dir) << endl;
16526 cerr << a_isHalo(cellId) << " " << a_isHalo(c_neighborId(cellId, dir)) << " "
16527 << a_hasProperty(c_neighborId(cellId, dir), SolverCell::IsNotGradient) << endl;
16528 }
16529 createSurface(srfcId, a_surfaceNghbrCellId(srfcId, 0), a_surfaceNghbrCellId(srfcId, 1),
16530 a_surfaceOrientation(srfcId));
16531 } else {
16532 if(a_hasNeighbor(cellId, dir) > 0) {
16533 MInt nghbrId = c_neighborId(cellId, dir);
16534 if(c_noChildren(nghbrId) > 0) {
16535 for(MInt child = 0; child < m_noCellNodes; child++) {
16536 if(!childCode[dir][child]) continue;
16537 MInt childId = c_childId(nghbrId, child);
16538 if(childId < 0) continue;
16539 srfcId = m_cellSurfaceMapping[childId][m_revDir[dir]];
16540 if(srfcId > -1) {
16541 createSurface(srfcId, a_surfaceNghbrCellId(srfcId, 0), a_surfaceNghbrCellId(srfcId, 1),
16542 a_surfaceOrientation(srfcId));
16543 }
16544 }
16545 }
16546 }
16547 }
16548 }
16549
16550 // 2. restore previously deleted surfaces
16551 restoreSurfaces(cellId);
16552}
void createSurface(MInt srfcId, MInt nghbrId0, MInt nghbrId1, MInt orientation)
restores the surfaces of the given cell

◆ restoreNeighbourLinks()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::restoreNeighbourLinks
Author
Lennart Schneiders, Update Tim Wegmann

Definition at line 20237 of file fvmbcartesiansolverxd.cpp.

20237 {
20238 TRACE();
20239
20240 m_deleteNeighbour = false;
20241 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
20242 a_hasProperty(cellId, SolverCell::IsBndryActive) = false;
20243 }
20244}

◆ restoreSurfaces()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::restoreSurfaces ( const MInt  cellId)
Author
Lennart Schneiders

Definition at line 16560 of file fvmbcartesiansolverxd.cpp.

16560 {
16561 if(a_isBndryGhostCell(cellId)) mTerm(1, AT_, "Unexpected situation 0 in FvMbCartesianSolverXD::restoreSurfaces()");
16562 if(c_noChildren(cellId) > 0) return;
16563 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) return;
16564 if(a_hasProperty(cellId, SolverCell::IsInactive)) return;
16565
16566 for(MInt dir = 0; dir < m_noDirs; dir++) {
16567 MInt srfcId = m_cellSurfaceMapping[cellId][dir];
16568
16569 if(srfcId < 0) {
16570 if(a_hasNeighbor(cellId, dir) > 0) {
16571 const MInt nghbrId = c_neighborId(cellId, dir);
16572 if(c_noChildren(nghbrId) > 0) {
16573 for(MInt child = 0; child < m_noCellNodes; child++) {
16574 if(!childCode[dir][child]) continue;
16575 const MInt childId = c_childId(nghbrId, child);
16576 if(childId < 0) continue;
16577 ASSERT(!a_isBndryGhostCell(childId), "");
16578 srfcId = m_cellSurfaceMapping[childId][m_revDir[dir]];
16579 if(srfcId > -1) {
16580 ASSERT(srfcId < a_noSurfaces(), to_string(srfcId) + " " + to_string(a_noSurfaces()));
16581 if(a_surfaceNghbrCellId(srfcId, m_revDir[dir] % 2) != cellId) {
16582 cerr << cellId << " " << nghbrId << " " << srfcId << " " << a_isHalo(cellId) << " " << a_level(cellId)
16583 << " " << a_level(nghbrId) << endl;
16584 cerr << dir << " " << child << " " << childId << endl;
16585 cerr << a_surfaceNghbrCellId(srfcId, 0) << " " << a_surfaceNghbrCellId(srfcId, 1) << " " << endl;
16586 if(a_surfaceNghbrCellId(srfcId, 0) > -1 && a_surfaceNghbrCellId(srfcId, 1) > -1) {
16587 cerr << a_level(a_surfaceNghbrCellId(srfcId, 0)) << " " << a_level(a_surfaceNghbrCellId(srfcId, 1))
16588 << " " << endl;
16589 }
16590 cerr << c_parentId(cellId) << " " << c_noChildren(cellId) << endl;
16591 for(MInt d = 0; d < m_noDirs; d++) {
16592 cerr << d << ": " << a_hasNeighbor(cellId, d) << "/" << c_neighborId(cellId, d);
16593 if(c_parentId(cellId) > -1) {
16594 cerr << " # " << a_hasNeighbor(c_parentId(cellId), d) << "/" << c_neighborId(c_parentId(cellId), d);
16595 }
16596 cerr << endl;
16597 }
16598 // writeVtkErrorFile();
16599 mTerm(1, AT_, "Unexpected situation in restoreSurfaces");
16600 }
16601 } else {
16602 if(a_hasProperty(childId, SolverCell::IsInactive)) continue;
16603 if(a_hasProperty(childId, SolverCell::IsNotGradient)) continue;
16604 if(a_isHalo(cellId) && a_isHalo(childId)) continue;
16605 srfcId = getNewSurfaceId();
16606
16607 ASSERT(a_level(cellId) != a_level(childId), "");
16608
16609 if(dir % 2 == 0)
16610 createSurface(srfcId, childId, cellId, dir / 2);
16611 else
16612 createSurface(srfcId, cellId, childId, dir / 2);
16613 }
16614 }
16615 } else {
16616 ASSERT(!a_isBndryGhostCell(nghbrId), "");
16617 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
16618 if(a_hasProperty(nghbrId, SolverCell::IsNotGradient)) continue;
16619 if(a_isHalo(cellId) && a_isHalo(nghbrId)) continue;
16620 srfcId = getNewSurfaceId();
16621 if(dir % 2 == 0)
16622 createSurface(srfcId, nghbrId, cellId, dir / 2);
16623 else
16624 createSurface(srfcId, cellId, nghbrId, dir / 2);
16625 }
16626 } else {
16627 if(c_parentId(cellId) > -1) {
16628 if(a_hasNeighbor(c_parentId(cellId), dir) > 0) {
16629 const MInt nghbrId = c_neighborId(c_parentId(cellId), dir);
16630 ASSERT(!a_isBndryGhostCell(nghbrId), "");
16631 srfcId = m_cellSurfaceMapping[nghbrId][m_revDir[dir]];
16632 if(srfcId > -1) {
16633 m_log << "nghb surf " << globalTimeStep << " " << srfcId << " " << nghbrId << " " << cellId << " "
16634 << a_noSurfaces() << " / " << c_isToDelete(cellId) << " "
16635 << a_hasProperty(cellId, SolverCell::IsInactive) << " " << c_isToDelete(nghbrId) << " "
16636 << a_hasProperty(nghbrId, SolverCell::IsInactive) << " " << a_surfaceNghbrCellId(srfcId, 0) << " "
16637 << a_surfaceNghbrCellId(srfcId, 1) << endl;
16638 }
16639 ASSERT(srfcId < a_noSurfaces(), "");
16640 if(srfcId > -1) {
16641 cerr << domainId() << ": " << srfcId << " " << cellId << " " << nghbrId << " / "
16642 << a_surfaceNghbrCellId(srfcId, 0) << " " << a_surfaceNghbrCellId(srfcId, 1) << " / "
16643 << a_level(cellId) << " " << a_level(nghbrId) << " / " << a_coordinate(cellId, 0) << " "
16644 << a_coordinate(cellId, 1) << " / " << a_coordinate(nghbrId, 0) << " " << a_coordinate(nghbrId, 1)
16645 << endl;
16646 }
16647 ASSERT(srfcId < 0, "");
16648 if(a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
16649 if(a_hasProperty(nghbrId, SolverCell::IsNotGradient)) continue;
16650 if(a_isHalo(cellId) && a_isHalo(nghbrId)) continue;
16651 if(c_noChildren(nghbrId) > 0) {
16652 cerr << domainId() << ": error surf " << dir << " " << cellId << " " << nghbrId << " "
16653 << c_globalId(cellId) << " " << c_globalId(nghbrId) << " " << c_neighborId(cellId, dir, false) << " "
16654 << c_noChildren(nghbrId) << " " << c_childId(nghbrId, 0) << " " << a_level(cellId) << " "
16655 << a_level(nghbrId) << " " << a_isHalo(cellId) << " " << a_isHalo(nghbrId) << " "
16656 << a_levelSetValuesMb(cellId, 0) / c_cellLengthAtCell(cellId) << " "
16657 << a_levelSetValuesMb(nghbrId, 0) / c_cellLengthAtCell(nghbrId) << endl;
16658 }
16659 ASSERT(c_noChildren(nghbrId) == 0, "");
16660 if(srfcId < 0) srfcId = getNewSurfaceId();
16661
16662 ASSERT(a_level(cellId) != a_level(nghbrId), "");
16663 if(dir % 2 == 0)
16664 createSurface(srfcId, nghbrId, cellId, dir / 2);
16665 else
16666 createSurface(srfcId, cellId, nghbrId, dir / 2);
16667 }
16668 }
16669 }
16670 } else {
16671 if(a_surfaceNghbrCellId(srfcId, 0) < 0 || a_surfaceNghbrCellId(srfcId, 1) < 0) {
16672 cerr << "srcf neighbors: " << srfcId << " " << cellId << " " << a_surfaceNghbrCellId(srfcId, 0) << " "
16673 << a_surfaceNghbrCellId(srfcId, 0) << endl;
16674 }
16675 }
16676 }
16677}
MInt getNewSurfaceId()
returns a new surface id

◆ returnNoActiveCorners()

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::returnNoActiveCorners ( MInt  cellId)
Author
Tim Wegmann
Date
02/2019

Definition at line 21052 of file fvmbcartesiansolverxd.cpp.

21052 {
21053 TRACE();
21054
21055 MInt nghbrIds[m_noCorners];
21056 MFloat lsValues[m_noCorners];
21057 MInt noActiveCorners = 0;
21058 const MInt nodeStencil[3][8] = {{0, 1, 0, 1, 0, 1, 0, 1}, {2, 2, 3, 3, 2, 2, 3, 3}, {4, 4, 4, 4, 5, 5, 5, 5}};
21059 std::set<std::pair<MInt, MInt>> nghbrSet;
21060
21061 for(MInt node = 0; node < m_noCorners; node++) {
21062 // a) Add all neighbors and the corresponding nodes from the node-loop to the list
21063 nghbrSet.clear();
21064 nghbrSet.insert(std::make_pair(cellId, node));
21065
21066 for(MInt i = 0; i < nDim; i++) {
21067 MInt firstDir = nodeStencil[i][node];
21068 MInt firstNghbrId = c_neighborId(cellId, firstDir);
21069 if(firstNghbrId > -1) {
21070 nghbrSet.insert(make_pair(firstNghbrId, node));
21071 for(MInt j = 0; j < nDim; j++) {
21072 MInt secondDir = nodeStencil[j][node];
21073 if(secondDir == firstDir) continue;
21074 MInt secondNghbrId = c_neighborId(firstNghbrId, secondDir);
21075 if(secondNghbrId > -1) {
21076 nghbrSet.insert(make_pair(secondNghbrId, node));
21077 IF_CONSTEXPR(nDim == 3) {
21078 for(MInt k = 0; k < nDim; k++) {
21079 MInt thirdDir = nodeStencil[k][node];
21080 if(thirdDir == firstDir || thirdDir == secondDir) continue;
21081 MInt thirdNghbrId = c_neighborId(secondNghbrId, thirdDir);
21082 if(thirdNghbrId > -1) {
21083 nghbrSet.insert(make_pair(thirdNghbrId, node));
21084 }
21085 }
21086 }
21087 }
21088 }
21089 }
21090 }
21091
21092 // b) reorder list by nodes, and calculate noNeighborsPerNode
21093 // note: previously determined neighbors might be added multiple-times to the map
21094 // and overwrite existing and identical information...
21095 MInt noNeighborsPerNode = 0;
21096 for(const auto& it : nghbrSet) {
21097 nghbrIds[noNeighborsPerNode] = it.first;
21098 noNeighborsPerNode++;
21099 }
21100
21101 // c) interpolate the levelSet value at the node, based on the levelSet values at
21102 // the neighboring cell-centers
21103 MFloat phi = F0;
21104 for(MInt nghbrNode = 0; nghbrNode < noNeighborsPerNode; nghbrNode++) {
21105 phi += a_levelSetValuesMb(nghbrIds[nghbrNode], 0);
21106 }
21107 phi /= noNeighborsPerNode;
21108 lsValues[node] = phi;
21109 }
21110
21111 // d) return the number of active notes
21112 for(MInt node = 0; node < m_noCorners; node++) {
21113 if(lsValues[node] > F0) {
21114 noActiveCorners++;
21115 }
21116 }
21117 ASSERT(noActiveCorners >= 0 && noActiveCorners <= m_noCorners, " ");
21118
21119 return noActiveCorners;
21120}

◆ rungeKuttaStep()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::rungeKuttaStep
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 19122 of file fvmbcartesiansolverxd.cpp.

19122 {
19123 return (this->*execRungeKuttaStep)();
19124}
MBool(FvMbCartesianSolverXD::* execRungeKuttaStep)()

◆ saveBodyRestartFile()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::saveBodyRestartFile ( const MBool  backup)
Author
Lennart Schneiders

Definition at line 24753 of file fvmbcartesiansolverxd.cpp.

24753 {
24754 TRACE();
24755
24757 cerr0 << "Not saving body-restart-data, as the cell volume might not have been created yet!" << endl;
24758 return;
24759 }
24760
24761 // force calculation before writing the restartFile!
24763
24764 cerr0 << "writing body-restart-data for the fv-mb-solver... ";
24765
24766 int64_t noMbCells = 0;
24767 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
24768 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
24769 if(a_isHalo(cellId)) continue;
24770 if(a_isPeriodic(cellId)) continue;
24771 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
24772 noMbCells++;
24773 }
24774
24775 int64_t noMbCellsGlobal = noMbCells;
24776 ScratchSpace<MPI_Offset> volOffsets(noDomains() + 1, AT_, "volOffsets");
24777 volOffsets(0) = 0;
24778
24779 if(noDomains() > 1) {
24780 volOffsets(domainId() + 1) = (MPI_Offset)noMbCells;
24781 MPI_Allgather(&noMbCells, 1, MPI_INT64_T, &volOffsets[1], 1, MPI_INT64_T, mpiComm(), AT_, "noMbCells",
24782 "volOffsets[1]");
24783 for(MInt d = 0; d < noDomains(); d++) {
24784 volOffsets(d + 1) += volOffsets(d);
24785 }
24786 noMbCellsGlobal = noMbCells;
24787 MPI_Allreduce(MPI_IN_PLACE, &noMbCellsGlobal, 1, MPI_INT64_T, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
24788 "noMbCellsGlobal");
24789 if(noMbCellsGlobal != volOffsets(noDomains())) mTerm(1, AT_, "Dimension mismatch.");
24790 }
24791 volOffsets(noDomains()) = (MPI_Offset)noMbCellsGlobal;
24792
24793 // Azimuthal periodicity. Boundary cell volume of halo cells musst be saved!
24794 int64_t noAzimuthalMbCells = 0;
24795 int64_t noAzimuthalMbCellsGlobal = 0;
24796 ScratchSpace<MPI_Offset> volOffsetsAzimuthal(grid().azimuthalPeriodicity() ? (noDomains() + 1) : 1, AT_,
24797 "volOffsetsAzimuthal");
24798 if(grid().azimuthalPeriodicity()) {
24800 noAzimuthalMbCells = m_azimuthalNearBoundaryBackup.size();
24801 noAzimuthalMbCellsGlobal = noAzimuthalMbCells;
24802 volOffsetsAzimuthal(0) = 0;
24803 if(noDomains() > 1) {
24804 volOffsetsAzimuthal(domainId() + 1) = (MPI_Offset)noAzimuthalMbCells;
24805 MPI_Allgather(&noAzimuthalMbCells, 1, MPI_INT64_T, &volOffsetsAzimuthal[1], 1, MPI_INT64_T, mpiComm(), AT_,
24806 "noAzimuthalMbCells", "volOffsetsAzimuthal[1]");
24807 for(MInt d = 0; d < noDomains(); d++) {
24808 volOffsetsAzimuthal(d + 1) += volOffsetsAzimuthal(d);
24809 }
24810 noAzimuthalMbCellsGlobal = noAzimuthalMbCells;
24811 MPI_Allreduce(MPI_IN_PLACE, &noAzimuthalMbCellsGlobal, 1, MPI_INT64_T, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
24812 "noAzimuthalMbCellsGlobal");
24813 if(noAzimuthalMbCellsGlobal != volOffsetsAzimuthal(noDomains())) mTerm(1, AT_, "Dimension mismatch.");
24814 }
24815 volOffsetsAzimuthal(noDomains()) = (MPI_Offset)noAzimuthalMbCellsGlobal;
24816 }
24817
24818 const MLong DOF = m_noEmbeddedBodies;
24819 const MLong DOF_TRANS = nDim * m_noEmbeddedBodies;
24820 const MLong DOF_ROT = 3 * m_noEmbeddedBodies;
24821 const MLong DOF_QUAT = 4 * m_noEmbeddedBodies;
24822 const MLong DOF_VOL = (MLong)noMbCellsGlobal;
24823 const MLong DOF_VOL_AZIMUTHAL = (MLong)noAzimuthalMbCellsGlobal;
24824
24825 stringstream fn;
24826 fn.clear();
24827 if(backup) {
24828 fn << outputDir() << "restartBodyDataBackup_" << getIdentifier(m_multipleFvSolver) << globalTimeStep;
24829 } else {
24831 fn << outputDir() << "restartBodyData" << getIdentifier(m_multipleFvSolver, "_", "");
24832 } else {
24833 fn << outputDir() << "restartBodyData_" << getIdentifier(m_multipleFvSolver) << globalTimeStep;
24834 }
24835 }
24836 fn << ParallelIo::fileExt();
24837
24838 MString fileName = fn.str();
24839
24840 MLongScratchSpace bndryCellVolumesIds(noMbCells, AT_, "bndryCellVolumesIds");
24841 MFloatScratchSpace bndryCellVolumes(noMbCells, AT_, "bndryCellVolumes");
24842 MInt cnt = 0;
24843 if(grid().newMinLevel() < 0) {
24844 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
24845 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
24846 if(a_isHalo(cellId)) continue;
24847 if(a_isPeriodic(cellId)) continue;
24848 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
24849 ASSERT(c_globalId(cellId) >= domainOffset(domainId())
24850 && c_globalId(cellId) < domainOffset(domainId()) + noInternalCells(),
24851 "");
24852 bndryCellVolumesIds[cnt] = c_globalId(cellId);
24853 bndryCellVolumes[cnt] = a_cellVolume(cellId);
24854 if(bndryCellVolumesIds[cnt] >= domainOffset(noDomains())) {
24855 cerr << domainId() << ": index out of range " << bndryCellVolumes[cnt] << " " << domainOffset(noDomains())
24856 << " " << grid().noCellsGlobal() << " " << grid().bitOffset() << endl;
24857 }
24858 cnt++;
24859 }
24860 } else {
24861 vector<MInt> reOrderedCells;
24862 vector<MLong> newGlobalIds;
24863 cerr0 << "Updating globalIds for bodyRestartFile!" << endl;
24864 this->reOrderCellIds(reOrderedCells);
24865 // recompute the globalIds
24866 this->recomputeGlobalIds(reOrderedCells, newGlobalIds);
24867
24868 // store bndryCellVolume and new globalId
24869 for(MUint id = 0; id < reOrderedCells.size(); id++) {
24870 const MInt cellId = reOrderedCells[id];
24871 if(a_isHalo(cellId)) continue;
24872 if(a_isPeriodic(cellId)) continue;
24873 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
24874 const MInt bndryId = a_bndryId(cellId);
24875 if(bndryId < m_noOuterBndryCells) continue;
24876 bndryCellVolumesIds[cnt] = newGlobalIds[id];
24877 bndryCellVolumes[cnt] = a_cellVolume(cellId);
24878 cnt++;
24879 }
24880 ASSERT(cnt == noMbCells, "");
24881 }
24882
24883 MLongScratchSpace azimuthalBndryCellVolumesIds(mMax(noAzimuthalMbCells, (int64_t)1), AT_,
24884 "azimuthalndryCellVolumesIds");
24885 MFloatScratchSpace azimuthalBndryCellVolumes(mMax(noAzimuthalMbCells, (int64_t)1), AT_, "azimuthalndryCellVolumes");
24886 MFloatScratchSpace azimuthalBndryCellCoordinates(mMax(noAzimuthalMbCells * nDim, (int64_t)1), AT_,
24887 "azimuthalndryCellCoordinates");
24888 if(grid().azimuthalPeriodicity()) {
24889 cnt = 0;
24890 for(auto it = m_azimuthalNearBoundaryBackup.begin(); it != m_azimuthalNearBoundaryBackup.end(); ++it) {
24891 MInt cellId = it->first;
24892 azimuthalBndryCellVolumesIds[cnt] = c_globalId(cellId);
24893 azimuthalBndryCellVolumes[cnt] = (it->second).first[nDim]; // cellVolume
24894 for(MInt d = 0; d < nDim; d++) {
24895 azimuthalBndryCellCoordinates[cnt * nDim + d] = (it->second).first[d];
24896 }
24897 cnt++;
24898 }
24899 }
24900
24901 MFloatScratchSpace bodyRotation(m_noEmbeddedBodies, 3, AT_, "bodyRotation");
24902 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
24903 getBodyRotation(k, &bodyRotation[3 * k]);
24904 }
24905
24906 {
24907 map<MLong, MFloat> tmpVol;
24908 for(MInt i = 0; i < noMbCells; i++) {
24909 tmpVol.insert(make_pair(bndryCellVolumesIds[i], bndryCellVolumes[i]));
24910 }
24911 cnt = 0;
24912 for(map<MLong, MFloat>::iterator it = tmpVol.begin(); it != tmpVol.end(); it++) {
24913 bndryCellVolumesIds[cnt] = it->first;
24914 bndryCellVolumes[cnt] = it->second;
24915 cnt++;
24916 }
24917
24918 if(grid().azimuthalPeriodicity()) {
24919 multimap<MLong, vector<MFloat>> tmpVolAzimuthal;
24920 for(MInt i = 0; i < noAzimuthalMbCells; i++) {
24921 vector<MFloat> tmpFloats(nDim + 1);
24922 for(MInt d = 0; d < nDim; d++) {
24923 tmpFloats[d] = azimuthalBndryCellCoordinates[i * nDim + d];
24924 }
24925 tmpFloats[nDim] = azimuthalBndryCellVolumes[i];
24926 tmpVolAzimuthal.insert(make_pair(azimuthalBndryCellVolumesIds[i], tmpFloats));
24927 }
24928 cnt = 0;
24929 for(multimap<MLong, vector<MFloat>>::iterator it = tmpVolAzimuthal.begin(); it != tmpVolAzimuthal.end(); it++) {
24930 azimuthalBndryCellVolumesIds[cnt] = it->first;
24931 for(MInt d = 0; d < nDim; d++) {
24932 azimuthalBndryCellCoordinates[cnt * nDim + d] = (it->second)[d];
24933 }
24934 azimuthalBndryCellVolumes[cnt] = (it->second)[nDim];
24935 cnt++;
24936 }
24937 }
24938
24939 ParallelIo::size_type start = 0;
24940 ParallelIo::size_type count = 0;
24941
24942 using namespace maia::parallel_io;
24943 ParallelIo parallelIo(fileName, PIO_REPLACE, mpiComm());
24944
24945 // Creating file header.
24946 parallelIo.defineScalar(PIO_INT, "DOF");
24947
24948 count = DOF;
24949 parallelIo.defineArray(PIO_FLOAT, "bodyTemperature", count);
24950
24951 count = DOF_TRANS;
24952 parallelIo.defineArray(PIO_FLOAT, "bodyCenter", count);
24953 parallelIo.defineArray(PIO_FLOAT, "bodyVelocity", count);
24954 parallelIo.defineArray(PIO_FLOAT, "bodyAcceleration", count);
24955 parallelIo.defineArray(PIO_FLOAT, "bodyForce", count);
24956
24957 count = DOF_ROT;
24958 parallelIo.defineArray(PIO_FLOAT, "bodyRotation", count);
24959 parallelIo.defineArray(PIO_FLOAT, "bodyAngularVelocity", count);
24960 parallelIo.defineArray(PIO_FLOAT, "bodyAngularAcceleration", count);
24961 parallelIo.defineArray(PIO_FLOAT, "bodyTorque", count);
24962
24963 count = DOF_QUAT;
24964 parallelIo.defineArray(PIO_FLOAT, "bodyQuaternion", count);
24965
24966 count = DOF_VOL;
24967 parallelIo.defineArray(PIO_LONG, "bndryCellVolumesIds", count);
24968 parallelIo.defineArray(PIO_FLOAT, "bndryCellVolumes", count);
24969
24970 if(grid().azimuthalPeriodicity()) {
24971 count = DOF_VOL_AZIMUTHAL;
24972 parallelIo.defineArray(PIO_LONG, "azimuthalBndryCellVolumesIds", count);
24973 parallelIo.defineArray(PIO_FLOAT, "azimuthalBndryCellVolumes", count);
24974 count *= nDim;
24975 parallelIo.defineArray(PIO_FLOAT, "azimuthalBndryCellCoordinates", count);
24976 }
24977
24978 parallelIo.writeScalar(DOF, "DOF");
24979
24980
24981 start = 0;
24982 count = DOF;
24983 parallelIo.setOffset(count, start);
24984 parallelIo.writeArray(m_bodyTemperature, "bodyTemperature");
24985
24986 count = DOF_TRANS;
24987 parallelIo.setOffset(count, start);
24988 parallelIo.writeArray(m_bodyCenter, "bodyCenter");
24989 parallelIo.writeArray(m_bodyVelocity, "bodyVelocity");
24990 parallelIo.writeArray(m_bodyAcceleration, "bodyAcceleration");
24991 parallelIo.writeArray(m_bodyForce, "bodyForce");
24992
24993 count = DOF_ROT;
24994 parallelIo.setOffset(count, start);
24995 parallelIo.writeArray(&bodyRotation[0], "bodyRotation");
24996
24998 // This can occur for multisolver where the lsSolver is inactive on some ranks
24999 MIntScratchSpace invalid(noDomains(), AT_, "invalid");
25000 invalid.fill(-1);
25001 MInt validRoot = -1;
25002 if(std::isnan(m_bodyAngularVelocity[0])) invalid[domainId()] = 1;
25003 MPI_Allreduce(MPI_IN_PLACE, invalid.getPointer(), noDomains(), MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
25004 "invalid");
25005 for(MInt d = 0; d < noDomains(); d++) {
25006 if(invalid[d] < 0) validRoot = d;
25007 }
25008 MPI_Bcast(&m_bodyAngularVelocity[0], m_noEmbeddedBodies * nDim, MPI_DOUBLE, validRoot, mpiComm(), AT_,
25009 "m_bodyAngularVelocity");
25010 MPI_Bcast(&m_bodyAngularAcceleration[0], m_noEmbeddedBodies * nDim, MPI_DOUBLE, validRoot, mpiComm(), AT_,
25011 "m_bodyAngularAcceleration");
25012 }
25013
25014 parallelIo.writeArray(m_bodyAngularVelocity, "bodyAngularVelocity");
25015 parallelIo.writeArray(m_bodyAngularAcceleration, "bodyAngularAcceleration");
25016 parallelIo.writeArray(m_bodyTorque, "bodyTorque");
25017
25018 count = DOF_QUAT;
25019 parallelIo.setOffset(count, start);
25020 parallelIo.writeArray(m_bodyQuaternion, "bodyQuaternion");
25021
25022 start = volOffsets(domainId());
25023 count = noMbCells;
25024 parallelIo.setOffset(count, start);
25025 parallelIo.writeArray(bndryCellVolumesIds.begin(), "bndryCellVolumesIds");
25026 parallelIo.writeArray(bndryCellVolumes.begin(), "bndryCellVolumes");
25027
25028 if(grid().azimuthalPeriodicity()) {
25029 start = volOffsetsAzimuthal(domainId());
25030 count = noAzimuthalMbCells;
25031 parallelIo.setOffset(count, start);
25032 parallelIo.writeArray(azimuthalBndryCellVolumesIds.begin(), "azimuthalBndryCellVolumesIds");
25033 parallelIo.writeArray(azimuthalBndryCellVolumes.begin(), "azimuthalBndryCellVolumes");
25034 start = volOffsetsAzimuthal(domainId()) * nDim;
25035 count = noAzimuthalMbCells * nDim;
25036 parallelIo.setOffset(count, start);
25037 parallelIo.writeArray(azimuthalBndryCellCoordinates.begin(), "azimuthalBndryCellCoordinates");
25038 }
25039 }
25040
25041 if(domainId() == 0) cerr << "ok" << endl;
25042}
void reOrderCellIds(std::vector< MInt > &reOrderedCells)
reOrder cellIds before writing the restart file! This is necessary for example if the minLevel shall ...
void recomputeGlobalIds(std::vector< MInt > &, std::vector< MLong > &)
reOrder cellIds before writing the restart file! This is necessary for example if the minLevel shall ...
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgather

◆ saveBodySamples()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::saveBodySamples
Author
Lennart Schneiders

Definition at line 25754 of file fvmbcartesiansolverxd.cpp.

25754 {
25755 TRACE();
25756
25757 if(m_noEmbeddedBodies == 0) return;
25758
25759 const MInt noNearBodyState = 5;
25760 MFloatScratchSpace particleFluidVel(m_noEmbeddedBodies, nDim, AT_, "particleFluidVel");
25761 MFloatScratchSpace particleFluidVelDt(m_noEmbeddedBodies, nDim, AT_, "particleFluidVelDt");
25762 MFloatScratchSpace particleFluidVelGrad(m_noEmbeddedBodies, nDim * nDim, AT_, "particleFluidVelGrad");
25763 MFloatScratchSpace particleFluidPressure(m_noEmbeddedBodies, AT_, "particleFluidPressure");
25764 MFloatScratchSpace particleFluidRotation(m_noEmbeddedBodies, nDim, AT_, "particleFluidRotation");
25765 MFloatScratchSpace particleFluidRotationDt(m_noEmbeddedBodies, nDim, AT_, "particleFluidRotationDt");
25766 MFloatScratchSpace particleFluidState(m_noEmbeddedBodies, noNearBodyState, AT_, "particleFluidState");
25767 MFloatScratchSpace bodyRotation(m_noEmbeddedBodies, 3, AT_, "bodyRotation");
25768 for(MInt k = 0; k < m_noEmbeddedBodies; k++) {
25769 getBodyRotation(k, &bodyRotation[3 * k]);
25770 }
25771 MFloat* vel = &(particleFluidVel[0]);
25772 MFloat* velDt = &(particleFluidVelDt[0]);
25773 MFloat* velGradient = &(particleFluidVelGrad[0]);
25774 MFloat* pressure = &(particleFluidPressure[0]);
25775 MFloat* rotation = &(particleFluidRotation[0]);
25776 MFloat* rotationDt = &(particleFluidRotationDt[0]);
25777 MFloat* state = &(particleFluidState[0]);
25778
25779 MIntScratchSpace nearestBodies(m_maxNearestBodies * a_noCells(), AT_, "nearestBodies");
25780 MFloatScratchSpace nearestDist(m_maxNearestBodies * a_noCells(), AT_, "nearestDist");
25781 nearestBodies.fill(-1);
25782 nearestDist.fill(numeric_limits<MFloat>::max());
25783 const MFloat maxDist = 5.0 * m_bodyDiameter[0];
25784 MInt maxBodyCnt = constructDistance(maxDist, nearestBodies, nearestDist);
25785 if(maxBodyCnt > m_maxNearestBodies && domainId() == 0) {
25786 cerr << "constructDistance: maxBodyCnt " << maxBodyCnt << " exceeds m_maxNearestBodies " << m_maxNearestBodies
25787 << ". Retry with higher value." << endl;
25788 }
25789
25790 computeNearBodyFluidVelocity(nearestBodies, nearestDist, vel, velGradient, rotation, vector<MFloat>(), nullptr, state,
25791 pressure, velDt, rotationDt);
25792
25793 const MLong DOF = m_noEmbeddedBodies;
25794 const MLong DOF_TRANS = nDim * m_noEmbeddedBodies;
25795 const MLong DOF_ROT = 3 * m_noEmbeddedBodies;
25796 const MLong DOF_QUAT = 4 * m_noEmbeddedBodies;
25797 const MLong DOF_GRAD = nDim * nDim * m_noEmbeddedBodies;
25798 const MLong DOF_STATE = (MLong)particleFluidState.size();
25799
25800 MString fileName = outputDir() + "bodySamples_00" + to_string(globalTimeStep) + ParallelIo::fileExt();
25801
25802 if(domainId() == 0) {
25803 ParallelIo::size_type count = 0;
25804 ParallelIo parallelIo(fileName, maia::parallel_io::PIO_REPLACE, MPI_COMM_SELF);
25805
25806 parallelIo.defineScalar(maia::parallel_io::PIO_INT, "DOF");
25807 parallelIo.defineScalar(maia::parallel_io::PIO_FLOAT, "bodyDiameter");
25808
25809 count = DOF;
25810 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyTemperature", count);
25811 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "fluidPressure", count);
25812
25813 count = DOF_TRANS;
25814 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyCenter", count);
25815 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyCenterDt1", count);
25816 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyVelocity", count);
25817 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyVelocityDt1", count);
25818 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyAcceleration", count);
25819 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyForce", count);
25820 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "fluidVelocity", count);
25821 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "fluidVelocityDt1", count);
25822
25823 count = DOF_ROT;
25824 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyRotation", count);
25825 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyAngularVelocity", count);
25826 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyAngularVelocityDt1", count);
25827 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyAngularAcceleration", count);
25828 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyTorque", count);
25829 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "fluidRotation", count);
25830 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "fluidRotationDt1", count);
25831
25832 count = DOF_QUAT;
25833 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyQuaternion", count);
25834
25835 count = DOF_GRAD;
25836 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "velocityGradient", count);
25837
25838 count = DOF_STATE;
25839 parallelIo.defineArray(maia::parallel_io::PIO_FLOAT, "bodyState", count);
25840
25841
25842 parallelIo.writeScalar(DOF, "DOF");
25843 parallelIo.writeScalar(m_bodyDiameter[0], "bodyDiameter");
25844
25845 count = DOF;
25846 parallelIo.setOffset(count, 0);
25847 parallelIo.writeArray(m_bodyTemperature, "bodyTemperature");
25848 parallelIo.writeArray(&(pressure[0]), "fluidPressure");
25849
25850 count = DOF_TRANS;
25851 parallelIo.setOffset(count, 0);
25852 parallelIo.writeArray(m_bodyCenter, "bodyCenter");
25853 parallelIo.writeArray(m_bodyCenterDt1, "bodyCenterDt1");
25854 parallelIo.writeArray(&(m_bodyVelocity[0]), "bodyVelocity");
25855 parallelIo.writeArray(&(m_bodyVelocityDt1[0]), "bodyVelocityDt1");
25856 parallelIo.writeArray(&(m_bodyAcceleration[0]), "bodyAcceleration");
25857 parallelIo.writeArray(&(m_bodyForce[0]), "bodyForce");
25858 parallelIo.writeArray(&(vel[0]), "fluidVelocity");
25859 parallelIo.writeArray(&(velDt[0]), "fluidVelocityDt1");
25860
25861 count = DOF_ROT;
25862 parallelIo.setOffset(count, 0);
25863 parallelIo.writeArray(&(bodyRotation[0]), "bodyRotation");
25864 parallelIo.writeArray(&(m_bodyAngularVelocity[0]), "bodyAngularVelocity");
25865 parallelIo.writeArray(&(m_bodyAngularVelocityDt1[0]), "bodyAngularVelocityDt1");
25866 parallelIo.writeArray(&(m_bodyAngularAcceleration[0]), "bodyAngularAcceleration");
25867 parallelIo.writeArray(&(m_bodyTorque[0]), "bodyTorque");
25868 parallelIo.writeArray(&(rotation[0]), "fluidRotation");
25869 parallelIo.writeArray(&(rotationDt[0]), "fluidRotationDt1");
25870
25871 count = DOF_QUAT;
25872 parallelIo.setOffset(count, 0);
25873 parallelIo.writeArray(&(m_bodyQuaternion[0]), "bodyQuaternion");
25874
25875 count = DOF_GRAD;
25876 parallelIo.setOffset(count, 0);
25877 parallelIo.writeArray(&(velGradient[0]), "velocityGradient");
25878
25879 count = DOF_STATE;
25880 parallelIo.setOffset(count, 0);
25881 parallelIo.writeArray(&(state[0]), "bodyState");
25882 }
25883}
const MInt PIO_REPLACE
Definition: parallelio.h:36
const MInt PIO_INT
Definition: parallelio.h:48
const MInt PIO_FLOAT
Definition: parallelio.h:46

◆ saveInitCorrData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::saveInitCorrData ( const std::vector< MInt > &  saveInitCorrDataTimeSteps,
const MFloatScratchSpace bodyVelocityInit,
const MFloatScratchSpace bodyAngularVelocityInit,
const MFloatScratchSpace bodyQuaternionInit,
const MFloatScratchSpace velMeanInit,
const MFloatScratchSpace velGradMeanInit,
const MFloatScratchSpace particleFluidRotationMeanInit,
const MIntScratchSpace corrBodies,
const MFloatScratchSpace bodyForceInit,
const MFloatScratchSpace bodyTorqueInit,
const MIntScratchSpace bodyOffsets 
)

◆ saveParticleSamples()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::saveParticleSamples
Author
Lennart Schneiders

Definition at line 25892 of file fvmbcartesiansolverxd.cpp.

25892 {
25893 TRACE();
25894
25895 if(m_noPointParticles == 0) return;
25896
25897 MIntScratchSpace partOffsets(noDomains() + 1, AT_, "partOffsets");
25898 partOffsets(0) = 0;
25899 partOffsets(domainId() + 1) = m_noPointParticlesLocal;
25900 MPI_Allgather(&m_noPointParticlesLocal, 1, MPI_INT, &partOffsets[1], 1, MPI_INT, mpiComm(), AT_,
25901 "m_noPointParticlesLocal", "partOffsets[1]");
25902 for(MInt d = 0; d < noDomains(); d++)
25903 partOffsets(d + 1) += partOffsets(d);
25904
25905 MFloatScratchSpace particleFluidPressure(m_noPointParticles, AT_, "particleFluidPressure");
25906 setParticleFluidVelocities(&(particleFluidPressure[0]));
25907
25908 const MLong DOF = m_noPointParticles;
25909 const MLong DOF_LOC = m_noPointParticlesLocal;
25910 const MLong DOF_TRANS = nDim * m_noPointParticles;
25911 const MLong DOF_TRANS_LOC = nDim * m_noPointParticlesLocal;
25912 const MLong DOF_ROT = 3 * m_noPointParticles;
25913 const MLong DOF_ROT_LOC = 3 * m_noPointParticlesLocal;
25914 const MLong DOF_QUAT = 4 * m_noPointParticles;
25915 const MLong DOF_QUAT_LOC = 4 * m_noPointParticlesLocal;
25916 const MLong DOF_GRAD = nDim * nDim * m_noPointParticles;
25917 const MLong DOF_GRAD_LOC = nDim * nDim * m_noPointParticlesLocal;
25918
25919 MString fileName = outputDir() + "partSamples_00" + to_string(globalTimeStep) + ParallelIo::fileExt();
25920
25921 ParallelIo::size_type start = 0;
25922 ParallelIo::size_type count = 0;
25923
25924 using namespace maia::parallel_io;
25925 ParallelIo parallelIo(fileName, PIO_REPLACE, mpiComm());
25926
25927 // Creating file header.
25928 parallelIo.defineScalar(PIO_INT, "DOF");
25929
25930 count = DOF;
25931 parallelIo.defineArray(PIO_FLOAT, "partFluidPressure", count);
25932
25933 count = DOF_TRANS;
25934 parallelIo.defineArray(PIO_FLOAT, "partCenter", count);
25935 parallelIo.defineArray(PIO_FLOAT, "partVelocity", count);
25936 parallelIo.defineArray(PIO_FLOAT, "partAcceleration", count);
25937 parallelIo.defineArray(PIO_FLOAT, "partVelocityFluid", count);
25938
25939 count = DOF_ROT;
25940 parallelIo.defineArray(PIO_FLOAT, "partAngularVelocity", count);
25941 parallelIo.defineArray(PIO_FLOAT, "partAngularAcceleration", count);
25942
25943 count = DOF_QUAT;
25944 parallelIo.defineArray(PIO_FLOAT, "partQuaternion", count);
25945
25946 count = DOF_GRAD;
25947 parallelIo.defineArray(PIO_FLOAT, "partVelocityGradientFluid", count);
25948
25949 parallelIo.writeScalar(DOF, "DOF");
25950
25951 start = (ParallelIo::size_type)(partOffsets(domainId()));
25952 count = (ParallelIo::size_type)DOF_LOC;
25953 parallelIo.setOffset(count, start);
25954 parallelIo.writeArray(&(particleFluidPressure[0]), "partFluidPressure");
25955
25956 start = (ParallelIo::size_type)(nDim * partOffsets(domainId()));
25957 count = (ParallelIo::size_type)DOF_TRANS_LOC;
25958 parallelIo.setOffset(count, start);
25959 parallelIo.writeArray(m_particleCoords.data(), "partCenter");
25960 parallelIo.writeArray(m_particleVelocity.data(), "partVelocity");
25961 parallelIo.writeArray(m_particleAcceleration.data(), "partAcceleration");
25962 parallelIo.writeArray(m_particleVelocityFluid.data(), "partVelocityFluid");
25963
25964 start = (ParallelIo::size_type)(3 * partOffsets(domainId()));
25965 count = (ParallelIo::size_type)DOF_ROT_LOC;
25966 parallelIo.setOffset(count, start);
25967 parallelIo.writeArray(m_particleAngularVelocity.data(), "partAngularVelocity");
25968 parallelIo.writeArray(m_particleAngularAcceleration.data(), "partAngularAcceleration");
25969
25970 start = (ParallelIo::size_type)(4 * partOffsets(domainId()));
25971 count = (ParallelIo::size_type)DOF_QUAT_LOC;
25972 parallelIo.setOffset(count, start);
25973 parallelIo.writeArray(m_particleQuaternions.data(), "partQuaternion");
25974
25975 start = (ParallelIo::size_type)(nDim * nDim * partOffsets(domainId()));
25976 count = (ParallelIo::size_type)DOF_GRAD_LOC;
25977 parallelIo.setOffset(count, start);
25978 parallelIo.writeArray(m_particleVelocityGradientFluid.data(), "partVelocityGradientFluid");
25979}

◆ saveParticleSlipData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::saveParticleSlipData
Author

Definition at line 26746 of file fvmbcartesiansolverxd.cpp.

26746 {
26747 TRACE();
26748
26749 MInt noTimeStepsSaved = m_slipDataTimeSteps.size();
26750 if(noTimeStepsSaved == 0) return;
26751 MInt noLocalParticles = m_particleOffsets[domainId() + 1] - m_particleOffsets[domainId()];
26752 MInt noGlobalParticles = m_noEmbeddedBodies;
26753 MInt noSetups = m_noAngleSetups * m_noDistSetups;
26754 MFloatScratchSpace outputParticleVel(mMax(1, noLocalParticles) * nDim * noTimeStepsSaved, AT_, "outputParticleVel");
26755 MFloatScratchSpace outputParticleAngularVel(mMax(1, noLocalParticles) * nDim * noTimeStepsSaved, AT_,
26756 "outputParticleAngularVel");
26757 MFloatScratchSpace outputParticleQuaternion(mMax(1, noLocalParticles) * 4 * noTimeStepsSaved, AT_,
26758 "outputParticleQuaternion");
26759 MFloatScratchSpace outputVel(mMax(1, noLocalParticles) * nDim * noTimeStepsSaved * noSetups, AT_, "outputVel");
26760 MFloatScratchSpace outputVelGrad(mMax(1, noLocalParticles) * POW2(nDim) * noTimeStepsSaved * noSetups, AT_,
26761 "outputVelGrad");
26762 MFloatScratchSpace outputParticleFluidRotation(mMax(1, noLocalParticles) * nDim * noTimeStepsSaved * noSetups, AT_,
26763 "outputParticleFluidRotation");
26764 MFloatScratchSpace outputParticleForce(mMax(1, noLocalParticles) * nDim * noTimeStepsSaved, AT_,
26765 "outputParticleForce");
26766 MFloatScratchSpace outputParticleTorque(mMax(1, noLocalParticles) * nDim * noTimeStepsSaved, AT_,
26767 "outputParticleTorque");
26768 MFloatScratchSpace outputParticlePosition(mMax(1, noLocalParticles) * nDim * noTimeStepsSaved, AT_,
26769 "outputParticlePosition");
26770 MIntScratchSpace outputCollision(mMax(1, noLocalParticles) * noTimeStepsSaved, AT_, "outputCollision");
26771 outputParticleVel.fill(F0);
26772 outputParticleAngularVel.fill(F0);
26773 outputParticleQuaternion.fill(-F1);
26774 outputVel.fill(F0);
26775 outputVelGrad.fill(F0);
26776 outputParticleFluidRotation.fill(F0);
26777 outputParticleForce.fill(F0);
26778 outputParticlePosition.fill(F0);
26779 outputParticleTorque.fill(F0);
26780 outputCollision.fill(0);
26781
26782 MIntScratchSpace localToGlobal(mMax(1, noLocalParticles) * noTimeStepsSaved, AT_, "localToGlobal");
26783 MIntScratchSpace particleGlobalId(mMax(1, noLocalParticles), AT_, "particleGlobalId");
26784 for(MInt p = 0; p < noLocalParticles; p++) {
26785 particleGlobalId(p) = p + m_particleOffsets[domainId()];
26786 }
26787 for(MInt ts = 0; ts < noTimeStepsSaved; ts++) {
26788 for(MInt p = 0; p < noLocalParticles; p++) {
26789 localToGlobal(ts * noLocalParticles + p) = ts * noGlobalParticles + particleGlobalId(p);
26790 }
26791 }
26792 MIntScratchSpace dataOffsets(noDomains() + 1, AT_, "dataOffsets");
26793 for(MLong dom = 0; dom < noDomains() + 1; dom++) {
26794 dataOffsets(dom) = noTimeStepsSaved * m_particleOffsets[dom];
26795 }
26796
26797 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleVel[0], noLocalParticles * noTimeStepsSaved,
26798 noGlobalParticles * noTimeStepsSaved, 1, nDim, noDomains(), domainId(),
26799 mpiComm(), localToGlobal, dataOffsets, outputParticleVel);
26800 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleAngularVel[0], noLocalParticles * noTimeStepsSaved,
26801 noGlobalParticles * noTimeStepsSaved, 1, nDim, noDomains(), domainId(),
26802 mpiComm(), localToGlobal, dataOffsets, outputParticleAngularVel);
26803 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleQuaternion[0], noLocalParticles * noTimeStepsSaved,
26804 noGlobalParticles * noTimeStepsSaved, 1, 4, noDomains(), domainId(),
26805 mpiComm(), localToGlobal, dataOffsets, outputParticleQuaternion);
26806 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleFluidVel[0], noLocalParticles * noTimeStepsSaved,
26807 noGlobalParticles * noTimeStepsSaved, 1, nDim * noSetups, noDomains(),
26808 domainId(), mpiComm(), localToGlobal, dataOffsets, outputVel);
26809 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleFluidVelGrad[0], noLocalParticles * noTimeStepsSaved,
26810 noGlobalParticles * noTimeStepsSaved, 1, POW2(nDim) * noSetups, noDomains(),
26811 domainId(), mpiComm(), localToGlobal, dataOffsets, outputVelGrad);
26813 &m_slipDataParticleFluidVelRot[0], noLocalParticles * noTimeStepsSaved, noGlobalParticles * noTimeStepsSaved, 1,
26814 nDim * noSetups, noDomains(), domainId(), mpiComm(), localToGlobal, dataOffsets, outputParticleFluidRotation);
26815 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleForce[0], noLocalParticles * noTimeStepsSaved,
26816 noGlobalParticles * noTimeStepsSaved, 1, nDim, noDomains(), domainId(),
26817 mpiComm(), localToGlobal, dataOffsets, outputParticleForce);
26818 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticlePosition[0], noLocalParticles * noTimeStepsSaved,
26819 noGlobalParticles * noTimeStepsSaved, 1, nDim, noDomains(), domainId(),
26820 mpiComm(), localToGlobal, dataOffsets, outputParticlePosition);
26821 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleTorque[0], noLocalParticles * noTimeStepsSaved,
26822 noGlobalParticles * noTimeStepsSaved, 1, nDim, noDomains(), domainId(),
26823 mpiComm(), localToGlobal, dataOffsets, outputParticleTorque);
26824 maia::mpi::communicateGlobalyOrderedData(&m_slipDataParticleCollision[0], noLocalParticles * noTimeStepsSaved,
26825 noGlobalParticles * noTimeStepsSaved, 1, 1, noDomains(), domainId(),
26826 mpiComm(), localToGlobal, dataOffsets, outputCollision);
26827
26828 MLongScratchSpace totalOffsetsDOF(noDomains() + 1, AT_, "totalOffsetsDOF_TRANS");
26829 MLongScratchSpace totalOffsetsDOF_TRANS(noDomains() + 1, AT_, "totalOffsetsDOF_TRANS");
26830 MLongScratchSpace totalOffsetsDOF_QUAT(noDomains() + 1, AT_, "totalOffsetsDOF_QUAT");
26831 MLongScratchSpace totalOffsetsDOF_ROT(noDomains() + 1, AT_, "totalOffsetsDOF_ROT");
26832 MLongScratchSpace totalOffsetsDOF_GRAD_Fluid(noDomains() + 1, AT_, "totalOffsetsDOF_GRAD_Fluid");
26833 MLongScratchSpace totalOffsetsDOF_TRANS_Fluid(noDomains() + 1, AT_, "totalOffsetsDOF_TRANS_Fluid");
26834 MLongScratchSpace totalOffsetsDOF_ROT_Fluid(noDomains() + 1, AT_, "totalOffsetsDOF_ROT_Fluid");
26835 for(MLong dom = 0; dom < noDomains() + 1; dom++) {
26836 totalOffsetsDOF(dom) = dataOffsets(dom);
26837 totalOffsetsDOF_QUAT(dom) = dataOffsets(dom) * 4;
26838 totalOffsetsDOF_TRANS(dom) = dataOffsets(dom) * nDim;
26839 totalOffsetsDOF_ROT(dom) = dataOffsets(dom) * nDim;
26840 totalOffsetsDOF_TRANS_Fluid(dom) = dataOffsets(dom) * nDim * noSetups;
26841 totalOffsetsDOF_ROT_Fluid(dom) = dataOffsets(dom) * nDim * noSetups;
26842 totalOffsetsDOF_GRAD_Fluid(dom) = dataOffsets(dom) * POW2(nDim) * noSetups;
26843 }
26844 const ParallelIo::size_type DOF = totalOffsetsDOF(domainId() + 1) - totalOffsetsDOF(domainId());
26845 const ParallelIo::size_type DOF_start = totalOffsetsDOF(domainId());
26846 const ParallelIo::size_type DOF_QUAT = totalOffsetsDOF_QUAT(domainId() + 1) - totalOffsetsDOF_QUAT(domainId());
26847 const ParallelIo::size_type DOF_QUAT_start = totalOffsetsDOF_QUAT(domainId());
26848 const ParallelIo::size_type DOF_TRANS = totalOffsetsDOF_TRANS(domainId() + 1) - totalOffsetsDOF_TRANS(domainId());
26849 const ParallelIo::size_type DOF_TRANS_start = totalOffsetsDOF_TRANS(domainId());
26850 const ParallelIo::size_type DOF_ROT = totalOffsetsDOF_ROT(domainId() + 1) - totalOffsetsDOF_ROT(domainId());
26851 const ParallelIo::size_type DOF_ROT_start = totalOffsetsDOF_ROT(domainId());
26852 const ParallelIo::size_type DOF_TRANS_Fluid =
26853 totalOffsetsDOF_TRANS_Fluid(domainId() + 1) - totalOffsetsDOF_TRANS_Fluid(domainId());
26854 const ParallelIo::size_type DOF_TRANS_Fluid_start = totalOffsetsDOF_TRANS_Fluid(domainId());
26855 const ParallelIo::size_type DOF_ROT_Fluid =
26856 totalOffsetsDOF_ROT_Fluid(domainId() + 1) - totalOffsetsDOF_ROT_Fluid(domainId());
26857 const ParallelIo::size_type DOF_ROT_Fluid_start = totalOffsetsDOF_ROT_Fluid(domainId());
26858 const ParallelIo::size_type DOF_GRAD_Fluid =
26859 totalOffsetsDOF_GRAD_Fluid(domainId() + 1) - totalOffsetsDOF_GRAD_Fluid(domainId());
26860 const ParallelIo::size_type DOF_GRAD_Fluid_start = totalOffsetsDOF_GRAD_Fluid(domainId());
26861 stringstream fn;
26862 fn.clear();
26863 fn << outputDir() << "correlationData_" << to_string(globalTimeStep);
26864 fn << ParallelIo::fileExt();
26865 MString fileName = fn.str();
26866 ParallelIo::size_type start = 0;
26867 ParallelIo::size_type count = 0;
26868 if(ParallelIo::fileExists(fileName, mpiComm()) && domainId() == 0) {
26869 stringstream fn2;
26870 fn2 << outputDir() << "correlationData_" << to_string(globalTimeStep);
26871 fn2 << ParallelIo::fileExt();
26872 time_t now = std::time(0);
26873 tm* ltm = localtime(&now);
26874 fn2 << "_" << ltm->tm_year << "_" << ltm->tm_mon << "_" << ltm->tm_mday << "_" << ltm->tm_hour << "_" << ltm->tm_min
26875 << "_" << ltm->tm_sec;
26876 MString fileName2 = fn2.str();
26877 rename(fileName.c_str(), fileName2.c_str());
26878 }
26879
26880 using namespace maia::parallel_io;
26881 ParallelIo parallelIo(fileName, PIO_REPLACE, mpiComm());
26882
26883 count = m_slipDataTimeSteps.size();
26884 parallelIo.defineArray(PIO_INT, "slipDataTimeSteps", count);
26885
26886 count = totalOffsetsDOF(noDomains());
26887 parallelIo.defineArray(PIO_INT, "bodyInCollision", count);
26888
26889 count = totalOffsetsDOF_TRANS(noDomains());
26890 parallelIo.defineArray(PIO_FLOAT, "particleVelocity", count);
26891 parallelIo.defineArray(PIO_FLOAT, "particleForce", count);
26892 parallelIo.defineArray(PIO_FLOAT, "particlePosition", count);
26893
26894 count = totalOffsetsDOF_ROT(noDomains());
26895 parallelIo.defineArray(PIO_FLOAT, "particleAngularVelocity", count);
26896 parallelIo.defineArray(PIO_FLOAT, "particleTorque", count);
26897
26898 count = totalOffsetsDOF_QUAT(noDomains());
26899 parallelIo.defineArray(PIO_FLOAT, "particleQuaternion", count);
26900
26901 count = totalOffsetsDOF_TRANS_Fluid(noDomains());
26902 parallelIo.defineArray(PIO_FLOAT, "particleFluidVel", count);
26903
26904 count = totalOffsetsDOF_ROT_Fluid(noDomains());
26905 parallelIo.defineArray(PIO_FLOAT, "particleFluidVelRot", count);
26906
26907 count = totalOffsetsDOF_GRAD_Fluid(noDomains());
26908 parallelIo.defineArray(PIO_FLOAT, "particleFluidVelGrad", count);
26909
26910 start = 0;
26911 count = m_slipDataTimeSteps.size();
26912 parallelIo.setOffset(count, start);
26913 parallelIo.writeArray(&m_slipDataTimeSteps[0], "slipDataTimeSteps");
26914
26915 start = DOF_start;
26916 count = DOF;
26917 parallelIo.setOffset(count, start);
26918 parallelIo.writeArray(&outputCollision[0], "bodyInCollision");
26919
26920 start = DOF_TRANS_start;
26921 count = DOF_TRANS;
26922 parallelIo.setOffset(count, start);
26923 parallelIo.writeArray(&outputParticleVel[0], "particleVelocity");
26924 parallelIo.writeArray(&outputParticleForce[0], "particleForce");
26925 parallelIo.writeArray(&outputParticlePosition[0], "particlePosition");
26926
26927 start = DOF_ROT_start;
26928 count = DOF_ROT;
26929 parallelIo.setOffset(count, start);
26930 parallelIo.writeArray(&outputParticleAngularVel[0], "particleAngularVelocity");
26931 parallelIo.writeArray(&outputParticleTorque[0], "particleTorque");
26932
26933 start = DOF_QUAT_start;
26934 count = DOF_QUAT;
26935 parallelIo.setOffset(count, start);
26936 parallelIo.writeArray(&outputParticleQuaternion[0], "particleQuaternion");
26937
26938 start = DOF_TRANS_Fluid_start;
26939 count = DOF_TRANS_Fluid;
26940 parallelIo.setOffset(count, start);
26941 parallelIo.writeArray(&outputVel[0], "particleFluidVel");
26942
26943 start = DOF_ROT_Fluid_start;
26944 count = DOF_ROT_Fluid;
26945 parallelIo.setOffset(count, start);
26946 parallelIo.writeArray(&outputParticleFluidRotation[0], "particleFluidVelRot");
26947
26948 start = DOF_GRAD_Fluid_start;
26949 count = DOF_GRAD_Fluid;
26950 parallelIo.setOffset(count, start);
26951 parallelIo.writeArray(&outputVelGrad[0], "particleFluidVelGrad");
26952
26953 m_slipDataTimeSteps.clear();
26954 MInt dim = 1;
26955 for(MInt i = 0; i < dim * m_noSlipDataOutputs; i++) {
26957 }
26958 dim = 4;
26959 for(MInt i = 0; i < dim * m_noSlipDataOutputs; i++) {
26961 }
26962 dim = nDim;
26963 for(MInt i = 0; i < dim * m_noSlipDataOutputs; i++) {
26965 m_slipDataParticleTorque[i] = -F1;
26966 }
26967 for(MInt i = 0; i < dim * m_noSlipDataOutputs * noSetups; i++) {
26969 }
26970 dim = nDim;
26971 for(MInt i = 0; i < dim * m_noSlipDataOutputs; i++) {
26972 m_slipDataParticleVel[i] = -F1;
26973 m_slipDataParticleForce[i] = -F1;
26975 }
26976 for(MInt i = 0; i < dim * m_noSlipDataOutputs * noSetups; i++) {
26978 }
26979 dim = POW2(nDim);
26980 for(MInt i = 0; i < dim * m_noSlipDataOutputs * noSetups; i++) {
26982 }
26983}
void communicateGlobalyOrderedData(DataType const *const sendData, const MInt noLocIds, const MInt noGlobalIds, const MInt nRows, const MInt nCols, const MInt noDomains, const MInt domainId, const MPI_Comm mpiComm, const MIntScratchSpace &localToGlobal, const MIntScratchSpace &dataOffsets, ScratchSpace< DataType > &recvData)
Communicate (optionally) solver-structured data sorted by a global Id.
Definition: mpiexchange.h:919

◆ saveRestartFile()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::saveRestartFile ( const MBool  writeBackup)
overridevirtual
Author
D. Hartmann, Update Tim Wegmann

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 24711 of file fvmbcartesiansolverxd.cpp.

24711 {
24712 TRACE();
24713
24715
24716 if(m_noEmbeddedBodies > 0) {
24717 saveBodyRestartFile(writeBackup);
24718 }
24719}
virtual void saveRestartFile(const MBool)
void saveBodyRestartFile(const MBool backup)
save restart body file

◆ saveSolverSolution()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::saveSolverSolution ( const MBool  forceOutput = false,
const MBool  finalTimeStep = false 
)
override
Author
Daniel Hartmann \comment edited by Lennart Schneiders (04.11.2011)

Definition at line 21341 of file fvmbcartesiansolverxd.cpp.

21341 {
21342 TRACE();
21343
21344
21347 }
21348
21350 if(m_restartFile) firstRun = false;
21351
21354 }
21357 }
21358
21359 // Taylor Green vortex or DHIT
21360 if(m_initialCondition == 15 || m_initialCondition == 16) {
21361 computeFlowStatistics(false);
21362 }
21363
21366 MString fileName = "centerLineData_" + to_string(globalTimeStep);
21367 writeCenterLineVel(fileName.c_str());
21368 }
21369
21370 MFloat bodyRotation[3] = {F0, F0, F0};
21371 MFloatScratchSpace pressureForce(mMax(1, nDim * m_noEmbeddedBodies), AT_, "pressureForce");
21372 getBodyRotation(0, bodyRotation);
21373 computeBodySurfaceData(&pressureForce[0]);
21374 printDynamicCoefficients(firstRun, &pressureForce[0]);
21375 if(m_recordBodyData) recordBodyData(firstRun);
21376 }
21377 // solution output
21378 MInt noComputedTimeSteps = globalTimeStep - m_solutionOffset;
21379 if(((noComputedTimeSteps % m_solutionInterval) == 0 && globalTimeStep >= m_solutionOffset && m_solutionInterval > -1)
21380 || forceOutput || (m_solutionTimeSteps.count(globalTimeStep) > 0)) {
21381 writeVtkXmlFiles("QOUT", "GEOM", !forceOutput, m_solutionDiverged);
21383 mTerm(1, AT_, "NETCDF output not defined, see FvMbCartesianSolverXD::saveGridFlowVariablesMB");
21384 }
21385 }
21386
21387 firstRun = false;
21388}
void printDynamicCoefficients(MBool firstRun, MFloat *pressureForce)
void recordBodyData(const MBool &firstRun)
void crankAngleSolutionOutput()
save a full solutionOutput at timeSteps closesed to a specified crankAngle Interval save a solution s...
std::set< MInt > m_solutionTimeSteps
Definition: solver.h:76
MInt m_solutionOffset
Definition: solver.h:75
MBool m_restartFile
Definition: solver.h:98
MInt m_solutionInterval
The number of timesteps before writing the next solution file.
Definition: solver.h:74
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
Definition: enums.cpp:20
@ NETCDF
Definition: enums.h:18

◆ sensorPatch()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::sensorPatch ( std::vector< std::vector< MFloat > > &  sensors,
std::vector< std::bitset< 64 > > &  sensorCellFlag,
std::vector< MFloat > &  sensorWeight,
MInt  sensorOffset,
MInt  sen 
)
overridevirtual

Reimplemented from maia::CartesianSolver< nDim_, FvCartesianSolverXD< nDim_, SysEqn > >.

Definition at line 34732 of file fvmbcartesiansolverxd.cpp.

34734 {
34735 if(!m_engineSetup || !m_closeGaps) {
34736 this->patchRefinement(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
34737 } else {
34738 // patch refinement only for certain crankAngles
34739 const MFloat cad = this->crankAngle(m_physicalTime, 0);
34740
34741 // define crank angles for which the patch is necesary
34742 const MFloat duration = 5;
34743 if(m_forceNoGaps == 2
34744 && ((cad > m_gapAngleOpen[0] && cad < m_gapAngleOpen[0] + duration) || // first Opening
34745 (cad > m_gapAngleClose[0] - duration && cad < m_gapAngleClose[0]) // first Closure
34746 )) {
34747 if(domainId() == 0) {
34748 cerr << "Setting sensor Patch-refinement for current CA!" << endl;
34749 }
34750
34751 this->patchRefinement(sensors, sensorCellFlag, sensorWeight, sensorOffset, sen);
34752
34753 const MInt valveBodyId = 2;
34754 const MInt bodySet = m_bodyToSetTable[valveBodyId];
34755 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
34756 const MInt gridCellId = grid().tree().solver2grid(cellId);
34757 if(sensors[sensorOffset + sen][gridCellId] > 0) {
34758 const MFloat valveDist = a_levelSetValuesMb(cellId, bodySet);
34759 if(fabs(valveDist) < 0.06757) continue;
34760 sensors[sensorOffset + sen][gridCellId] = 0;
34761 sensorCellFlag[gridCellId][sensorOffset + sen] = 0;
34762 }
34763 if(a_wasGapCell(cellId)) {
34764 sensors[sensorOffset + sen][gridCellId] = 1;
34765 sensorCellFlag[gridCellId][sensorOffset + sen] = 1;
34766 }
34767 }
34768 } else {
34769 if(domainId() == 0) {
34770 cerr << "Surpressing Patch-refinement for current CA!" << endl;
34771 }
34772 }
34773 }
34774}
void patchRefinement(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen)

◆ setAdditionalActiveFlag()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setAdditionalActiveFlag ( MIntScratchSpace activeFlag)
overridevirtual
Author

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 10673 of file fvmbcartesiansolverxd.cpp.

10673 {
10674 for(MUint it = 0; it < m_temporarilyLinkedCells.size(); it++) {
10675 activeFlag(get<0>(m_temporarilyLinkedCells[it])) = 1;
10676 activeFlag(get<1>(m_temporarilyLinkedCells[it])) = 1;
10677 if(get<2>(m_temporarilyLinkedCells[it]) > 0) {
10678 activeFlag(get<2>(m_temporarilyLinkedCells[it])) = 1;
10679 }
10680 }
10681}

◆ setAdditionalCellProperties()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setAdditionalCellProperties
static
Author
Lennart Schneiders

Definition at line 11973 of file fvmbcartesiansolverxd.cpp.

11973 {
11974 // dummy currently
11975}

◆ setBodyQuaternions()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setBodyQuaternions ( const MInt  bodyId,
MFloat bodyRotation 
)
Author
Lennart Schneiders

Definition at line 4488 of file fvmbcartesiansolverxd.cpp.

4488 {
4489 TRACE();
4490
4491 if(!m_constructGField) return;
4492
4493 m_bodyQuaternion[bodyId * 4 + 0] = cos(F1B2 * bodyRotation[1]) * cos(F1B2 * (bodyRotation[2] + bodyRotation[0]));
4494 m_bodyQuaternion[bodyId * 4 + 1] = sin(F1B2 * bodyRotation[1]) * sin(F1B2 * (bodyRotation[2] - bodyRotation[0]));
4495 m_bodyQuaternion[bodyId * 4 + 2] = sin(F1B2 * bodyRotation[1]) * cos(F1B2 * (bodyRotation[2] - bodyRotation[0]));
4496 m_bodyQuaternion[bodyId * 4 + 3] = cos(F1B2 * bodyRotation[1]) * sin(F1B2 * (bodyRotation[2] + bodyRotation[0]));
4497}

◆ setBoundaryVelocity()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setBoundaryVelocity
Author
Lennart Schneiders, Tim Wegmann

Definition at line 17884 of file fvmbcartesiansolverxd.cpp.

17884 {
17885 TRACE();
17886
17887 if(!m_constructGField) {
17888 // levelset forced motion
17889
17890 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
17891 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
17892 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
17893
17894 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
17895 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
17896 const MInt bodyId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0];
17897 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
17898 for(MInt i = 0; i < nDim; i++) {
17899 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] =
17900 m_bodyVelocity[bodyId * nDim + i];
17901 }
17902
17903 if(m_LsRotate) {
17904 MFloat vrad[3] = {F0, F0, F0};
17905 MFloat dx[3] = {F0, F0, F0};
17906 MFloat omega[3] = {F0, F0, F0};
17907 for(MInt i = 0; i < nDim; i++) {
17908 dx[i] = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i]
17909 - m_bodyCenter[bodyId * nDim + i];
17910 }
17911
17912 for(MInt i = 0; i < 3; i++) {
17913 omega[i] = m_bodyAngularVelocity[bodyId * 3 + i];
17914 }
17915
17916 vrad[0] = omega[1] * dx[2] - omega[2] * dx[1];
17917 vrad[1] = omega[2] * dx[0] - omega[0] * dx[2];
17918
17919 IF_CONSTEXPR(nDim == 3) { vrad[2] = omega[0] * dx[1] - omega[1] * dx[0]; }
17920 else {
17921 mTerm(1, AT_, "TODO");
17922 }
17923
17924 for(MInt i = 0; i < nDim; i++) {
17925 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] += vrad[i];
17926 }
17927 }
17928
17929 if(m_closeGaps && m_gapInitMethod == 0 && a_isGapCell(cellId)) {
17930 const MInt gapCellId = m_gapCellId[cellId];
17931 ASSERT(gapCellId > -1, "");
17932 for(MInt i = 0; i < nDim; i++) {
17933 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] =
17934 m_gapCells[gapCellId].surfaceVelocity[i];
17935 }
17936 }
17937 }
17938 }
17939 }
17940 } else {
17941 // translation and rotational body based on the fv-solver!
17942 const MInt noBndryCells = m_fvBndryCnd->m_bndryCells->size();
17943 for(MInt bndryId = m_noOuterBndryCells; bndryId < noBndryCells; bndryId++) {
17944 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
17945 const MInt bodyId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0];
17946 ASSERT(bodyId > -1 && bodyId < m_noEmbeddedBodies + m_noPeriodicGhostBodies, "");
17947 for(MInt i = 0; i < nDim; i++) {
17948 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] =
17949 m_bodyVelocity[bodyId * nDim + i];
17950 }
17951 MFloat dx[3] = {F0, F0, F0};
17952 MFloat omega[3] = {F0, F0, F0};
17953 MFloat vrad[3] = {F0, F0, F0};
17954 for(MInt i = 0; i < nDim; i++) {
17955 dx[i] =
17956 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i] - m_bodyCenter[bodyId * nDim + i];
17957 }
17958 for(MInt i = 0; i < 3; i++) {
17959 omega[i] = m_bodyAngularVelocity[bodyId * 3 + i];
17960 }
17961 vrad[0] = omega[1] * dx[2] - omega[2] * dx[1];
17962 vrad[1] = omega[2] * dx[0] - omega[0] * dx[2];
17963 IF_CONSTEXPR(nDim == 3) { vrad[2] = omega[0] * dx[1] - omega[1] * dx[0]; }
17964 for(MInt i = 0; i < nDim; i++) {
17965 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] += vrad[i];
17966 }
17967
17968 if(m_euler) {
17969 MFloat vel[3];
17970 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
17971 for(MInt i = 0; i < nDim; i++) {
17972 vel[i] = a_pvariable(cellId, PV->VV[i]);
17973 for(MInt j = 0; j < nDim; j++) {
17974 vel[i] += m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
17975 * (m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]]
17976 - a_pvariable(cellId, PV->VV[j]))
17977 * m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[j];
17978 }
17979 }
17980 for(MInt i = 0; i < nDim; i++) {
17981 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = vel[i];
17982 }
17983 }
17984 }
17985 }
17986 }
17987}

◆ setCellDataDlb() [1/2]

template<MInt nDim_, class SysEqn_ >
void FvMbCartesianSolverXD< nDim_, SysEqn_ >::setCellDataDlb ( const MInt  dataId,
const MFloat *const  data 
)
override

Set the solver cell data after DLB.

Definition at line 1981 of file fvmbcartesiansolverxd.h.

1981 {
1982 TRACE();
1983
1984 // Nothing to do if solver is not active
1985 if(!isActive()) {
1986 return;
1987 }
1988
1989 // Set the variables if this is the correct reinitialization stage
1991 switch(dataId) {
1993 std::copy_n(data, noInternalCells() * m_noCVars, &a_variable(0, 0));
1994 break;
1995 }
1997 std::copy_n(data, noInternalCells(), &a_cellVolume(0));
1998 break;
1999 }
2001 std::copy_n(data, noInternalCells() * m_noFVars, &a_rightHandSide(0, 0));
2002 break;
2003 }
2005 std::copy_n(data, noInternalCells(), &m_cellVolumesDt1[0]);
2006 break;
2007 }
2009 std::copy_n(data, noInternalCells(), &m_sweptVolumeBal[0]);
2010 break;
2011 }
2013 if(grid().azimuthalPeriodicity()) {
2015 std::copy_n(data, noInternalCells() * noFloatData, &m_azimuthalNearBoundaryBackupBalFloat[0]);
2016 }
2017 break;
2018 }
2019 default:
2020 TERMM(1, "Unknown data id.");
2021 }
2022 }
2023}

◆ setCellDataDlb() [2/2]

template<MInt nDim_, class SysEqn_ >
void FvMbCartesianSolverXD< nDim_, SysEqn_ >::setCellDataDlb ( const MInt  dataId,
const MLong *const  data 
)

Definition at line 2028 of file fvmbcartesiansolverxd.h.

2028 {
2029 TRACE();
2030
2031 // Nothing to do if solver is not active
2032 if(!isActive()) {
2033 return;
2034 }
2035
2036 // Set the variables if this is the correct reinitialization stage
2038 switch(dataId) {
2040 for(MInt i = 0; i < noInternalCells(); i++) {
2042 }
2043 break;
2044 }
2046 if(grid().azimuthalPeriodicity()) {
2048 std::copy_n(data, noInternalCells() * noLongData, &m_azimuthalNearBoundaryBackupBalLong[0]);
2049 }
2050 break;
2051 }
2052 default:
2053 TERMM(1, "Unknown data id.");
2054 }
2055 }
2056}

◆ setCellProperties()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setCellProperties
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 11962 of file fvmbcartesiansolverxd.cpp.

11962 {
11965}
virtual void setCellProperties()
static void setAdditionalCellProperties()
set the properties of cells and determines the state of halo cells

◆ setCellWeights()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setCellWeights ( MFloat solverCellWeight)
overridevirtual
Author
Tim Wegmann

Reimplemented from Solver.

Definition at line 24670 of file fvmbcartesiansolverxd.cpp.

24670 {
24671 TRACE();
24672
24673 const MInt noCellsGrid = grid().raw().treeb().size();
24674 const MInt offset = noCellsGrid * solverId();
24675
24676 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
24677 if(a_isBndryGhostCell(cellId)) continue;
24678 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
24679 if(a_hasProperty(cellId, SolverCell::IsSplitClone)) continue;
24680 assertValidGridCellId(cellId);
24681 const MInt gridCellId = grid().tree().solver2grid(cellId);
24682 const MInt id = gridCellId + offset;
24683 if(a_isHalo(cellId)) continue;
24684 if(c_noChildren(cellId) > 0) {
24685 solverCellWeight[id] = m_weightBaseCell * m_weightMulitSolverFactor;
24686 continue;
24687 }
24688 if(a_hasProperty(cellId, SolverCell::IsInactive)) {
24689 solverCellWeight[id] = m_weightLeafCell * m_weightMulitSolverFactor;
24690 } else {
24691 solverCellWeight[id] = m_weightActiveCell * m_weightMulitSolverFactor;
24692 }
24693
24694 MFloat dist = fabs(a_levelSetValuesMb(cellId, 0));
24695 if(dist < 2 * grid().cellLengthAtLevel(maxRefinementLevel())) {
24696 solverCellWeight[id] += m_weightNearBndryCell * m_weightMulitSolverFactor;
24697 }
24698 if(a_bndryId(cellId) > -1 && c_isLeafCell(cellId)) {
24699 solverCellWeight[id] += m_weightBndryCell * m_weightMulitSolverFactor;
24700 }
24701 }
24702}

◆ setGapCellId()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setGapCellId
Author
Tim Wegmann

Definition at line 28598 of file fvmbcartesiansolverxd.cpp.

28598 {
28599 TRACE();
28600
28601 ASSERT(m_gapInitMethod == 0, "");
28602
28603 m_gapCellId.clear();
28604 m_gapCellId.resize(a_noCells());
28605 for(MInt i = 0; i < a_noCells(); i++)
28606 m_gapCellId[i] = -1;
28607
28608 for(MUint it = 0; it < m_gapCells.size(); it++) {
28609 const MInt cellId = m_gapCells[it].cellId;
28610 m_gapCellId[cellId] = (MInt)it;
28611 }
28612
28613 for(MUint sc = 0; sc < m_splitCells.size(); sc++) {
28614 const MInt cellId = m_splitCells[sc];
28615 if(m_gapCellId[cellId] < 0) continue;
28616 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
28617 const MInt splitChildId = m_splitChilds[sc][ssc];
28618 if(a_isGapCell(splitChildId) || a_wasGapCell(splitChildId)) {
28619 const MInt gapId = m_gapCells.size();
28620 const MInt region = m_gapCells[m_gapCellId[cellId]].region;
28621 const MInt status = m_gapCells[m_gapCellId[cellId]].status;
28622 const MInt body1 = m_gapCells[m_gapCellId[cellId]].bodyIds[0];
28623 const MInt body2 = m_gapCells[m_gapCellId[cellId]].bodyIds[1];
28624 m_gapCells.emplace_back(splitChildId, region, status, body1, body2);
28625 m_gapCellId[splitChildId] = gapId;
28626 }
28627 }
28628 }
28629}

◆ setGapOpened()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setGapOpened
Author
Claudia Guenter, cleanup Tim Wegmann

Definition at line 27161 of file fvmbcartesiansolverxd.cpp.

27161 {
27162 TRACE();
27163
27164 ASSERT(m_gapInitMethod == 0, "");
27165 if(!m_closeGaps) return;
27166
27168
27169 ASSERT(!m_gapOpened, "");
27170 ASSERT(m_levelSet, "");
27171
27172 // set the m_gapOpened-property and initialize emerging-Gap-Cells!
27174
27175 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
27176 if(a_isBndryGhostCell(cellId)) continue;
27177 // if ( a_isHalo( cellId ) ) continue;
27178 if(!a_hasProperty(cellId, SolverCell::WasGapCell)) continue;
27179 if(a_level(cellId) != maxRefinementLevel()) continue;
27180 if(!a_hasProperty(cellId, SolverCell::WasInactive)) continue;
27181 if(a_hasProperty(cellId, SolverCell::IsGapCell)) continue;
27182
27183 if(a_levelSetValuesMb(cellId, 0) < -eps) continue;
27184
27185 // for all cells with: WasGapCell, WasInactive, !IsGapCell and small ls-values!
27186 // would be more accurate to use the cornerLs-Values instead of eps-approach!
27187
27188 // set variables to initial value, which will be corrected later in initEmergingGapCells()!
27189 a_variable(cellId, CV->RHO) = m_rhoInfinity;
27190 a_variable(cellId, CV->RHO_E) = m_rhoEInfinity;
27191 a_variable(cellId, CV->RHO_VV[0]) = F0;
27192 a_variable(cellId, CV->RHO_VV[1]) = F0;
27193 IF_CONSTEXPR(nDim == 3) a_variable(cellId, CV->RHO_VV[2]) = F0;
27194 a_pvariable(cellId, PV->RHO) = m_rhoInfinity;
27195 a_pvariable(cellId, PV->U) = F0;
27196 a_pvariable(cellId, PV->V) = F0;
27197 IF_CONSTEXPR(nDim == 3) a_pvariable(cellId, PV->W) = F0;
27198 a_pvariable(cellId, PV->P) = m_PInfinity;
27199
27200 cerr << domainId() << ": old gap cell activated at timeStep " << globalTimeStep << ": cellId " << cellId << " "
27201 << c_globalId(cellId) << " lvsVal: " << a_levelSetValuesMb(cellId, 0)
27202 << " inactive: " << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
27203
27204 m_gapOpened = true;
27205 }
27206
27207 MInt gapOpened = (MInt)m_gapOpened;
27208 MPI_Allreduce(MPI_IN_PLACE, &gapOpened, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "gapOpened");
27209 m_gapOpened = (MBool)gapOpened;
27210
27211 if(domainId() == 0 && m_gapOpened) {
27212 cerr << "Gap Opening Initialized at timestep " << globalTimeStep << endl;
27213 }
27214}
@ IsInactive
cell is outside fluid domain

◆ setLevelSetMbCellProperties()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setLevelSetMbCellProperties
Author
Lennart Schneiders

Definition at line 1300 of file fvmbcartesiansolverxd.cpp.

1300 {
1301 TRACE();
1302
1303 constructGField(false);
1304
1305 std::vector<MInt>().swap(m_bndryLayerCells);
1306 set<MInt> rebuildCells;
1307 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
1308 if(a_bndryId(cellId) < -1) continue;
1309
1310 ASSERT(!a_isBndryGhostCell(cellId), "");
1311
1312 if(c_noChildren(cellId) > 0) {
1313 ASSERT(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel), "Non leaf cell is on current mg level!");
1314 a_hasProperty(cellId, SolverCell::NearWall) = false;
1315 }
1316
1317 MBool oldStatus = a_hasProperty(cellId, SolverCell::NearWall);
1318
1319 ASSERT(a_level(cellId) > -1 && a_level(cellId) <= maxRefinementLevel(),
1320 "unexpected cell level " << a_level(cellId) << " for cell " << cellId << endl);
1321
1322 if((a_level(cellId) >= m_lsCutCellMinLevel)
1323 && a_levelSetValuesMb(cellId, 0) > m_maxBndryLayerDistances[a_level(cellId)][0]
1324 && a_levelSetValuesMb(cellId, 0) < m_maxBndryLayerDistances[a_level(cellId)][1] && c_isLeafCell(cellId)) {
1325 m_bndryLayerCells.push_back(cellId);
1326 a_hasProperty(cellId, SolverCell::NearWall) = true;
1327 } else {
1328 a_hasProperty(cellId, SolverCell::NearWall) = false;
1329 }
1330 if(a_levelSetValuesMb(cellId, 0) < F0) {
1331 a_hasProperty(cellId, SolverCell::IsInactive) = true;
1332 a_hasProperty(cellId, SolverCell::IsActive) = false; // change_1a
1333 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = false; // change_1a
1334 } else {
1335 a_hasProperty(cellId, SolverCell::IsInactive) = false;
1336 if(c_isLeafCell(cellId)) {
1337 a_hasProperty(cellId, SolverCell::IsActive) = true;
1338 a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = true;
1339 }
1340 if(oldStatus && (!a_hasProperty(cellId, SolverCell::NearWall))
1341 && !a_hasProperty(cellId, SolverCell::IsNotGradient)) {
1342 a_hasProperty(cellId, SolverCell::IsFlux) = true;
1343 rebuildCells.insert(cellId);
1344 // rebuildReconstructionConstants( cellId );
1345 }
1346 }
1347 }
1348
1349 m_fvBndryCnd->correctCellCoordinates();
1350 for(auto it = rebuildCells.begin(); it != rebuildCells.end(); ++it) {
1352 }
1353 rebuildCells.clear();
1354 m_fvBndryCnd->recorrectCellCoordinates();
1355
1356 // TODO labels:FVMB update IsInactive on cells at a Leveljump!
1357 // the coarser cell needs to have a neighbor in the direction of the finer cell
1358 // if any of the neighboring fine cells is !IsInactive.
1359 // => IsInactive of the parent must be set to false, but the cell must not be
1360 // IsOnCurrentMGLevel!
1361}

◆ setOldGeomBndryCellVolume()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setOldGeomBndryCellVolume
Author
Tim Wegmann

Definition at line 25681 of file fvmbcartesiansolverxd.cpp.

25681 {
25682 TRACE();
25683
25684 MFloatScratchSpace oldVolumes(a_noCells(), 2, AT_, "oldVolumes");
25685 oldVolumes.fill(-1);
25686
25687 for(auto it = m_oldGeomBndryCells.begin(); it != m_oldGeomBndryCells.end(); it++) {
25688 const MInt cellId = it->first;
25689 const MFloat vol = it->second;
25690 oldVolumes(cellId, 0) = vol;
25691 }
25692
25693 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
25694 oldVolumes(cellId, 1) = a_cellVolume(cellId);
25695 }
25696
25697 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
25698 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25699 if(a_isHalo(cellId)) continue;
25700 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
25701 auto it0 = m_oldGeomBndryCells.find(cellId);
25702 if(it0 != m_oldGeomBndryCells.end()) {
25703 const MFloat vol = it0->second;
25704 m_oldGeomBndryCells.erase(it0);
25705 // only set volume from file, if it matches the current volume
25706 const MFloat volDif = fabs(a_cellVolume(cellId) - vol);
25707 if(volDif > 0.0001 * vol) {
25708 m_oldGeomBndryCells.insert(make_pair(cellId, -1));
25709 } else {
25710 a_cellVolume(cellId) = vol;
25711 m_cellVolumesDt1[cellId] = vol;
25713 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25714 m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume = vol;
25715 }
25716 }
25717 }
25718
25719 // set volumes on halo cells
25720 exchangeData(&a_cellVolume(0), 1);
25721 exchangeData(&oldVolumes[0], 2);
25722
25723 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
25724 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
25725 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
25726 if(!a_isHalo(cellId)) continue;
25729 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
25730 // only update bndryCell-volume for oldGeomBndryCells
25731 if(oldVolumes(cellId, 0) > 0) {
25732 // check if the halo cell is in the list and remove the entry
25733 auto it0 = m_oldGeomBndryCells.find(cellId);
25734 if(it0 != m_oldGeomBndryCells.end()) m_oldGeomBndryCells.erase(it0);
25735 // only update for low volume difference
25736 const MFloat volDif = fabs(oldVolumes(cellId, 1) - oldVolumes(cellId, 0));
25737 if(volDif > 0.0001 * oldVolumes(cellId, 0)) {
25738 // add entry if volume differs greatly
25739 m_oldGeomBndryCells.insert(make_pair(cellId, -1));
25740 } else {
25741 m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume = oldVolumes(cellId, 0);
25742 }
25743 }
25744 }
25745}

◆ setOuterBoundaryGhostCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setOuterBoundaryGhostCells
Author
Lennart Schneiders

Definition at line 19546 of file fvmbcartesiansolverxd.cpp.

19546 {
19547 TRACE();
19548
19550 m_fvBndryCnd->computeGhostCells();
19551
19552 for(MInt bndryId = 0; bndryId < m_noOuterBndryCells; bndryId++) {
19553 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
19554 const MInt noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
19555 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
19556 a_reconstructionNeighborId(cellId, srfc) =
19557 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
19558 }
19559 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
19560 const MInt ghostCellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
19561 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
19562 a_associatedBodyIds(ghostCellId, set) = -1;
19563 }
19564 }
19565 }
19566}

◆ setOuterBoundarySurfaces()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setOuterBoundarySurfaces
Author
Lennart Schneiders

Definition at line 19574 of file fvmbcartesiansolverxd.cpp.

19574 {
19575 TRACE();
19576
19579 m_fvBndryCnd->addBoundarySurfaces();
19580
19581 for(MInt srfcId = m_bndrySurfacesOffset; srfcId < a_noSurfaces(); srfcId++) {
19583 a_surfaceFactor(srfcId, 0) = F1B2;
19584 a_surfaceFactor(srfcId, 1) = F1B2;
19585 for(MInt i = 0; i < nDim; i++) {
19586 a_surfaceDeltaX(srfcId, i) = a_surfaceCoordinate(srfcId, i) - a_coordinate(a_surfaceNghbrCellId(srfcId, 0), i);
19587 a_surfaceDeltaX(srfcId, nDim + i) =
19588 a_surfaceCoordinate(srfcId, i) - a_coordinate(a_surfaceNghbrCellId(srfcId, 1), i);
19589 }
19590 }
19591 m_noOuterBoundarySurfaces = m_fvBndryCnd->m_noBoundarySurfaces;
19592}
void correctMasterSlaveSurfaces()
Removes surfaces between master-slave pairs and reassigns slave cell surfaces required in order to ma...

◆ setParticleFluidVelocities()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setParticleFluidVelocities ( MFloat pressure = nullptr)
Author

Definition at line 7744 of file fvmbcartesiansolverxd.cpp.

7744 {
7745 IF_CONSTEXPR(nDim == 2) mTerm(1, AT_, "Go for 3D.");
7746
7747 const MBool fourthOrder = false;
7748 const MInt maxNoNghbrs = 150;
7749 const MInt recDim = fourthOrder ? 19 : 10;
7750
7751 MIntScratchSpace nghbrList(maxNoNghbrs, AT_, "nghbrList");
7752 MIntScratchSpace layerId(maxNoNghbrs, AT_, "layerList");
7753 MFloatScratchSpace mat(maxNoNghbrs, recDim, AT_, "mat");
7754
7755 nghbrList.fill(-1);
7756 for(MUint p = 0; p < m_particleCellLink.size(); p++) {
7758 const MFloat normalizationFactor =
7759 F1 / c_cellLengthAtCell(cellId); // scaling factor to reduce the condition number of the resulting eq. sys.
7760 const MInt counter = 1 + this->template getAdjacentLeafCells<2>(cellId, 1, nghbrList, layerId);
7761 for(MInt i = counter - 1; i > 0; i--)
7762 nghbrList[i] = nghbrList[i - 1];
7763 nghbrList[0] = cellId;
7764 mat.fill(F0);
7765 for(MInt c = 0; c < counter; c++) {
7766 const MInt nghbrId = nghbrList(c);
7767 MFloat deltaX[3];
7768
7769 for(MInt i = 0; i < nDim; i++) {
7770 deltaX[i] = (a_coordinate(nghbrId, i) - m_particleCoords[nDim * p + i]) * normalizationFactor;
7771 }
7772
7773 MInt cnt = 0;
7774 mat(c, cnt) = F1;
7775 cnt++;
7776 for(MInt i = 0; i < nDim; i++) {
7777 mat(c, cnt) = deltaX[i];
7778 cnt++;
7779 }
7780 for(MInt i = 0; i < nDim; i++) {
7781 for(MInt j = i; j < nDim; j++) {
7782 const MFloat fac = (i == j) ? F1B2 : F1;
7783 mat(c, cnt) = fac * deltaX[i] * deltaX[j];
7784 cnt++;
7785 }
7786 }
7787 if(fourthOrder) {
7788 for(MInt i = 0; i < nDim; i++) {
7789 for(MInt j = i; j < nDim; j++) {
7790 for(MInt k = j; k < nDim; k++) {
7791 const MFloat fac = (i == j && i == k) ? F1B6 : ((i == j || i == k || j == k) ? F1B2 : F1);
7792 mat(c, cnt) = fac * deltaX[i] * deltaX[j] * deltaX[k];
7793 cnt++;
7794 }
7795 }
7796 }
7797 }
7798 }
7799 maia::math::invert(&mat(0, 0), counter, recDim);
7800
7801 for(MInt c = 0; c < counter; c++) {
7802 MInt cnt = 1;
7803 for(MInt i = 0; i < nDim; i++) {
7804 mat(cnt, c) *= normalizationFactor;
7805 cnt++;
7806 }
7807 for(MInt i = 0; i < nDim; i++) {
7808 for(MInt j = i; j < nDim; j++) {
7809 mat(cnt, c) *= POW2(normalizationFactor);
7810 cnt++;
7811 }
7812 }
7813 if(fourthOrder) {
7814 for(MInt i = 0; i < nDim; i++) {
7815 for(MInt j = i; j < nDim; j++) {
7816 for(MInt k = j; k < nDim; k++) {
7817 mat(cnt, c) *= POW3(normalizationFactor);
7818 cnt++;
7819 }
7820 }
7821 }
7822 }
7823 }
7824
7825 MFloatScratchSpace R(3, 3, AT_, "R");
7827
7828 for(MInt i = 0; i < nDim; i++) {
7829 m_particleVelocityFluid[nDim * p + i] = F0;
7830 }
7832 for(MInt c = 0; c < counter; c++) {
7833 for(MInt i = 0; i < nDim; i++) {
7834 m_particleVelocityFluid[nDim * p + i] += mat(0, c) * a_pvariable(nghbrList[c], PV->VV[i]);
7835 }
7837 mat(0, c) * sysEqn().temperature_ES(a_pvariable(nghbrList[c], PV->RHO), a_pvariable(nghbrList[c], PV->P));
7838 }
7839
7840 MFloat velGrad[3][3] = {{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}};
7841 for(MInt c = 0; c < counter; c++) {
7842 MFloat coeffs0[3] = {mat(1, c), mat(2, c), mat(3, c)};
7843 MFloat vel0[3] = {a_pvariable(nghbrList[c], PV->U), a_pvariable(nghbrList[c], PV->V),
7844 a_pvariable(nghbrList[c], PV->W)};
7845 MFloat coeffs[3];
7846 MFloat vel[3];
7847 matrixVectorProduct(coeffs, R, coeffs0);
7848 matrixVectorProduct(vel, R, vel0);
7849 for(MInt i = 0; i < nDim; i++) {
7850 for(MInt j = 0; j < nDim; j++) {
7851 velGrad[i][j] += coeffs[j] * vel[i];
7852 }
7853 }
7854 }
7855
7856 for(MInt i = 0; i < nDim; i++) {
7857 for(MInt j = 0; j < nDim; j++) {
7858 m_particleVelocityGradientFluid[9 * p + 3 * i + j] = velGrad[i][j];
7859 }
7860 }
7861
7862 if(pressure != nullptr) {
7863 pressure[p] = F0;
7864 for(MInt c = 0; c < counter; c++) {
7865 pressure[p] += mat(0, c) * a_pvariable(nghbrList[c], PV->P);
7866 }
7867 }
7868 }
7869}

◆ setRungeKuttaFunctionPointer()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setRungeKuttaFunctionPointer ( )
Author
Jannik Borgelt

◆ setSensors()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setSensors ( std::vector< std::vector< MFloat > > &  sensors,
std::vector< MFloat > &  sensorWeight,
std::vector< std::bitset< 64 > > &  sensorCellFlag,
std::vector< MInt > &  sensorSolverId 
)
overridevirtual
Author
Tim Wegmann

Reimplemented from Solver.

Definition at line 15476 of file fvmbcartesiansolverxd.cpp.

15479 {
15482 }
15483
15484 const auto sensorOffset = (signed)sensors.size();
15485 FvCartesianSolverXD<nDim, SysEqn>::setSensors(sensors, sensorWeight, sensorCellFlag, sensorSolverId);
15486
15487 // ensure only a single-level change during an adaptation run at the bndry!
15488 // use an additional adaptation after some time steps to ensure smooth transition
15490 // prevent coarsening of bndry-cells by more than 1 level
15491 for(auto it = m_coarseOldBndryCells.begin(); it != m_coarseOldBndryCells.end(); it++) {
15492 const MInt cellId = *it;
15493 const MInt gridId = grid().tree().solver2grid(cellId);
15494 for(MInt s = 0; s < this->m_noSensors; s++) {
15495 sensorCellFlag[gridId][sensorOffset + s] = false;
15496 sensors[sensorOffset + s][gridId] = 0.0;
15497 }
15498 const MInt parentId = c_parentId(cellId);
15499 if(parentId < 0) continue;
15500 const MInt gridParent = grid().tree().solver2grid(parentId);
15501 sensorCellFlag[gridParent][sensorOffset] = true;
15502 sensors[sensorOffset][gridParent] = 1.0;
15503 }
15504 // prevent refinement of bndry-cells by more than 1 level
15505 for(auto it = m_oldBndryCells.begin(); it != m_oldBndryCells.end(); it++) {
15506 const MInt cellId = it->first;
15507 if(c_isLeafCell(cellId)) continue;
15508 for(MInt childId = 0; childId < IPOW2(nDim); childId++) {
15509 const MInt child = c_childId(cellId, childId);
15510 if(child < 0) continue;
15511 const MInt gridId = grid().tree().solver2grid(child);
15512 for(MInt s = 0; s < this->m_noSensors; s++) {
15513 sensorCellFlag[gridId][sensorOffset + s] = false;
15514 sensors[sensorOffset + s][gridId] = 0.0;
15515 }
15516 }
15517 }
15518 }
15519}
void setSensors(std::vector< std::vector< MFloat > > &sensors, std::vector< MFloat > &sensorWeight, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MInt > &sensorSolverId) override
set the sensors for the adaptation (i.e. which cell should be refined/removed?)

◆ setTimeStep()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setTimeStep
overridevirtual
Author
Lennart Schneiders

Reimplemented from Solver.

Definition at line 11071 of file fvmbcartesiansolverxd.cpp.

11071 {
11072 TRACE();
11073
11075 adaptTimeStep();
11076 }
11077
11080 const MFloat newTimeStep = timeStep(true);
11081
11082 // update periodicGhostBody-Distance
11083 if(m_constructGField) {
11084 MFloat maxDispl = F2 * newTimeStep * m_UInfinity;
11085 if(m_adaptation) {
11087 1.1
11090 } else {
11092 1.1 * (((MFloat)noHaloLayers()) * c_cellLengthAtLevel(minLevel()) + m_maxBodyRadius + maxDispl);
11093 }
11094 }
11095
11096 // log information for possible maximum cfl-number
11097 MFloat cflMax = F0;
11098 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
11099 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
11100 if(a_bndryId(cellId) < -1) continue;
11101 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
11102 const MFloat a = sysEqn().speedOfSound(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
11103 for(MInt i = 0; i < nDim; i++) {
11104 cflMax = mMax(cflMax, newTimeStep * (fabs(a_pvariable(cellId, PV->VV[i])) + a) / c_cellLengthAtCell(cellId));
11105 }
11106 }
11107
11108 MPI_Allreduce(MPI_IN_PLACE, &cflMax, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "cflMax");
11109 m_log << "Maximum CFL number: " << cflMax << " (" << m_cfl << ")" << endl;
11110
11111 // update swept volume after timeStep change:
11112 auto oldBndryCellsBak(m_oldBndryCells);
11113 m_oldBndryCells.clear();
11114 for(auto it = oldBndryCellsBak.begin(); it != oldBndryCellsBak.end(); ++it) {
11115 const MInt cellId = it->first;
11116 const MFloat sweptVol = it->second;
11117 const MFloat sweptVolUpdate = sweptVol * (newTimeStep / m_previousTimeStep);
11118 m_oldBndryCells.insert(make_pair(cellId, sweptVolUpdate));
11119 }
11120
11121 // update external source terms after timeStep change for conservation!
11123 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
11124 if(!a_hasProperty(cellId, SolverCell::IsActive)) continue;
11125 for(MInt var = 0; var < CV->noVariables; var++) {
11126 a_externalSource(cellId, var) *= m_previousTimeStep / newTimeStep;
11127 }
11128 }
11129 }
11130}
void adaptTimeStep()
computes the time step

◆ setupBoundaryCandidatesAnalytical()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::setupBoundaryCandidatesAnalytical
Author
Lennart Schneiders

Definition at line 5582 of file fvmbcartesiansolverxd.cpp.

5582 {
5583 TRACE();
5584
5585 MFloat dummyCoord[3];
5586 const MFloat cellHalfLength = F1B2 * c_cellLengthAtLevel(m_lsCutCellBaseLevel);
5587 const MFloat limitDistance = F2 * c_cellLengthAtLevel(m_lsCutCellBaseLevel);
5588 const MFloat nodeStencil[3][8] = {
5589 {-F1, F1, -F1, F1, -F1, F1, -F1, F1}, {-F1, -F1, F1, F1, -F1, -F1, F1, F1}, {-F1, -F1, -F1, -F1, F1, F1, F1, F1}};
5590 const MInt dirStencil[8][3] = {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}, {1, 1, 0},
5591 {0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {1, 1, 1}};
5592
5594 for(MInt c = 0; c < a_noCells(); c++)
5595 m_bndryCandidateIds[c] = -1;
5596 m_bndryCandidates.clear();
5597 m_candidateNodeSet.clear();
5598 m_candidateNodeValues.clear();
5600
5601 for(MUint c = 0; c < m_bndryLayerCells.size(); c++) {
5602 const MInt cellId = m_bndryLayerCells[c];
5603
5604 if(a_level(cellId) < m_lsCutCellMinLevel || !c_isLeafCell(cellId)) continue;
5605
5606 ASSERT(m_bodyTypeMb > 0, "");
5607 MFloat phi = a_levelSetValuesMb(cellId, 0);
5608
5610 MInt candidate = -1;
5611 if(fabs(phi) < limitDistance) {
5612 candidate = m_noBndryCandidates;
5613 m_bndryCandidates.push_back(cellId);
5614 m_bndryCandidateIds[cellId] = candidate;
5616 }
5617 }
5620 for(MInt candidate = 0; candidate < m_noBndryCandidates; candidate++) {
5621 for(MInt node = 0; node < m_noCellNodes; node++) {
5622 m_candidateNodeSet[candidate * m_noCellNodes + node] = false;
5623 }
5624 }
5625
5626 for(MInt candidate = 0; candidate < m_noBndryCandidates; candidate++) {
5627 MInt cellId = m_bndryCandidates[candidate];
5628
5629 for(MInt node = 0; node < m_noCellNodes; node++) {
5630 if(m_candidateNodeSet[candidate * m_noCellNodes + node]) continue;
5631 for(MInt i = 0; i < nDim; i++) {
5632 dummyCoord[i] = a_coordinate(cellId, i) + nodeStencil[i][node] * cellHalfLength;
5633 }
5634 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
5635 const MInt b = a_associatedBodyIds(cellId, set);
5636 MFloat phi = m_bodyDistThreshold + 1e-14;
5637 if(b > -1) {
5638 phi = getDistance(&dummyCoord[0], b);
5639 }
5640 m_candidateNodeValues[IDX_LSSETNODES(candidate, node, set)] = phi;
5641 }
5642 m_candidateNodeSet[candidate * m_noCellNodes + node] = true;
5643
5644 // update neighbor candidates
5645 for(MInt i = 0; i < nDim; i++) {
5646 MInt dir0 = 2 * i + dirStencil[node][i];
5647 if(a_hasNeighbor(cellId, dir0) == 0) continue;
5648 MInt nghbrId0 = c_neighborId(cellId, dir0);
5649 MInt n0 = (dirStencil[node][i] == 0) ? node + IPOW2(i) : node - IPOW2(i);
5650 MInt cand0 = m_bndryCandidateIds[nghbrId0];
5651 if(cand0 > -1) {
5652 MBool match = true;
5653 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
5654 if(a_associatedBodyIds(nghbrId0, set) == a_associatedBodyIds(cellId, set)) {
5655 m_candidateNodeValues[IDX_LSSETNODES(cand0, n0, set)] =
5656 m_candidateNodeValues[IDX_LSSETNODES(candidate, node, set)];
5657 } else
5658 match = false;
5659 }
5660 if(match) m_candidateNodeSet[cand0 * m_noCellNodes + n0] = true;
5661 }
5662 for(MInt j = i + 1; j < nDim; j++) {
5663 MInt dir1 = 2 * j + dirStencil[node][j];
5664 if(a_hasNeighbor(nghbrId0, dir1) == 0) continue;
5665 MInt nghbrId1 = c_neighborId(nghbrId0, dir1);
5666 MInt n1 = (dirStencil[node][j] == 0) ? n0 + IPOW2(j) : n0 - IPOW2(j);
5667 MInt cand1 = m_bndryCandidateIds[nghbrId1];
5668 if(cand1 > -1) {
5669 MBool match = true;
5670 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
5671 if(a_associatedBodyIds(nghbrId1, set) == a_associatedBodyIds(cellId, set)) {
5672 m_candidateNodeValues[IDX_LSSETNODES(cand1, n1, set)] =
5673 m_candidateNodeValues[IDX_LSSETNODES(candidate, node, set)];
5674 } else
5675 match = false;
5676 }
5677 if(match) m_candidateNodeSet[cand1 * m_noCellNodes + n1] = true;
5678 }
5679 for(MInt k = j + 1; k < nDim; k++) {
5680 MInt dir2 = 2 * k + dirStencil[node][k];
5681 if(a_hasNeighbor(nghbrId1, dir2) == 0) continue;
5682 MInt nghbrId2 = c_neighborId(nghbrId1, dir2);
5683 MInt n2 = (dirStencil[node][k] == 0) ? n1 + IPOW2(k) : n1 - IPOW2(k);
5684 MInt cand2 = m_bndryCandidateIds[nghbrId2];
5685 if(cand2 > -1) {
5686 MBool match = true;
5687 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
5688 if(a_associatedBodyIds(nghbrId2, set) == a_associatedBodyIds(cellId, set)) {
5689 m_candidateNodeValues[IDX_LSSETNODES(cand2, n2, set)] =
5690 m_candidateNodeValues[IDX_LSSETNODES(candidate, node, set)];
5691 } else
5692 match = false;
5693 }
5694 if(match) m_candidateNodeSet[cand2 * m_noCellNodes + n2] = true;
5695 }
5696 }
5697 }
5698 }
5699 }
5700 }
5701}

◆ sgn()

template<MInt nDim, class SysEqn >
static MFloat FvMbCartesianSolverXD< nDim, SysEqn >::sgn ( MFloat  val)
inlinestaticprivate

Definition at line 1261 of file fvmbcartesiansolverxd.h.

1261{ return (val < F0) ? -F1 : F1; }

◆ solutionStep()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::solutionStep
overridevirtual
Author
Thomas Hoesgen

LHS computation: Navier-Stokes integration step timeStep update is also done here

LHS Boundary Condition: set boundary conditions and exchange data

RHS computation:

RHS Boundary Condition (boundary treatment):

Reimplemented from Solver.

Definition at line 30166 of file fvmbcartesiansolverxd.cpp.

30166 {
30167 TRACE();
30168
30169 NEW_TIMER_GROUP_STATIC(tg_solutionStep, "solution step");
30170 NEW_TIMER_STATIC(t_solutionStep, "time integration", tg_solutionStep);
30171 NEW_SUB_TIMER_STATIC(t_timeIntegration, "time integration", t_solutionStep);
30172 NEW_SUB_TIMER_STATIC(t_lhs, "lhs", t_timeIntegration);
30173 NEW_SUB_TIMER_STATIC(t_lhsBnd, "lhsBnd", t_timeIntegration);
30174 NEW_SUB_TIMER_STATIC(t_rhs, "rhs", t_timeIntegration);
30175 NEW_SUB_TIMER_STATIC(t_rhsBnd, "rhsBnd", t_timeIntegration);
30176
30177 RECORD_TIMER_START(t_solutionStep);
30178 RECORD_TIMER_START(t_timeIntegration);
30179
30180 // finish previous RK step for inter-leafed non-blocking
30182 RECORD_TIMER_START(t_lhsBnd);
30183 this->lhsBndFinish();
30184 RECORD_TIMER_STOP(t_lhsBnd);
30185
30186 RECORD_TIMER_START(t_rhs);
30187 this->rhs();
30188 RECORD_TIMER_STOP(t_rhs);
30189
30190 RECORD_TIMER_START(t_rhsBnd);
30191 this->rhsBnd();
30192 RECORD_TIMER_STOP(t_rhsBnd);
30193 }
30194 // Receive data in the next substep
30195 m_splitMpiCommRecv = true;
30196
30199 RECORD_TIMER_START(t_lhs);
30200 MBool timeStepCompleted = this->solverStep();
30201 RECORD_TIMER_STOP(t_lhs);
30202
30204 RECORD_TIMER_START(t_lhsBnd);
30205 this->lhsBnd();
30206 RECORD_TIMER_STOP(t_lhsBnd);
30207
30208 if(!g_splitMpiComm) {
30210 RECORD_TIMER_START(t_rhs);
30211 this->rhs();
30212 RECORD_TIMER_STOP(t_rhs);
30213
30215 RECORD_TIMER_START(t_rhsBnd);
30216 this->rhsBnd();
30217 RECORD_TIMER_STOP(t_rhsBnd);
30218 }
30219
30220 RECORD_TIMER_STOP(t_timeIntegration);
30221 RECORD_TIMER_STOP(t_solutionStep);
30222
30223 return timeStepCompleted;
30224}

◆ storeAzimuthalPeriodicData()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::storeAzimuthalPeriodicData ( MInt  mode = 0)
Author
Thomas Hoesgen

Definition at line 36461 of file fvmbcartesiansolverxd.cpp.

36461 {
36462 TRACE();
36463
36465 if(grid().noAzimuthalNeighborDomains() > 0) {
36466 MInt noFloatData = (mode == 0 ? m_noFloatDataAdaptation : m_noFloatDataBalance);
36467 MInt noIntData = m_noLongData;
36468
36469 MUint sndSize = maia::mpi::getBufferSize(grid().azimuthalWindowCells());
36470 MFloatScratchSpace windowFData(sndSize * noFloatData, AT_, "windowIData");
36471 windowFData.fill(-1.0);
36472 ScratchSpace<MUlong> windowIData(sndSize * noIntData, AT_, "windowIData");
36473 windowIData.fill(0);
36474 MUint rcvSize = maia::mpi::getBufferSize(grid().azimuthalHaloCells());
36475 MFloatScratchSpace haloFData(rcvSize * noFloatData, AT_, "haloFData");
36476 haloFData.fill(-1.0);
36477 ScratchSpace<MUlong> haloIData(rcvSize * noIntData, AT_, "haloIData");
36478 haloIData.fill(0);
36479
36480 MInt sndCnt = 0;
36481 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36482 for(MInt j = 0; j < grid().noAzimuthalHaloCells(i); j++) {
36483 MInt cellId = grid().azimuthalHaloCell(i, j);
36484 if(m_oldBndryCells.count(cellId) != 0 || mode == 1) {
36485 auto it = m_oldBndryCells.find(cellId);
36486 haloFData[sndCnt * noFloatData] = a_cellVolume(cellId);
36487 haloFData[sndCnt * noFloatData + 1] = m_cellVolumesDt1[cellId];
36488 haloFData[sndCnt * noFloatData + 2] = it != m_oldBndryCells.end() ? it->second : F0;
36489 if(mode == 1) {
36490 for(MInt v = 0; v < CV->noVariables; v++) {
36491 haloFData[sndCnt * noFloatData + 3 + v] = a_variable(cellId, v);
36492 }
36493 }
36494
36495 haloIData[sndCnt * noIntData] = (unsigned)m_oldBndryCells.count(cellId);
36496 haloIData[sndCnt * noIntData + 1] = (a_properties(cellId)).to_ulong();
36497 }
36498
36499 sndCnt++;
36500 }
36501 }
36502
36503 // Exchange
36504 maia::mpi::exchangeBuffer(grid().azimuthalNeighborDomains(), grid().azimuthalWindowCells(),
36505 grid().azimuthalHaloCells(), mpiComm(), haloFData.getPointer(), windowFData.getPointer(),
36506 noFloatData);
36507 maia::mpi::exchangeBuffer(grid().azimuthalNeighborDomains(), grid().azimuthalWindowCells(),
36508 grid().azimuthalHaloCells(), mpiComm(), haloIData.getPointer(), windowIData.getPointer(),
36509 noIntData);
36510
36511 MInt rcvCnt = 0;
36512 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36513 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
36514 MInt cellId = grid().azimuthalWindowCell(i, j);
36515 if(windowIData[rcvCnt * noIntData] > 0 || mode == 1) {
36516 MBool isEqual = false;
36517 MLong gCellId = cellId;
36518 if(mode == 1) gCellId = c_globalId(cellId);
36519 if(m_azimuthalNearBoundaryBackup.count(gCellId) > 0) {
36520 MFloat recCoord[nDim];
36521 MFloat cellLength = c_cellLengthAtCell(cellId);
36522 auto range = m_azimuthalNearBoundaryBackup.equal_range(gCellId);
36523 for(auto it = range.first; it != range.second; ++it) {
36524 for(MInt d = 0; d < nDim; d++) {
36525 recCoord[d] = (it->second).first[d];
36526 }
36527 if(approx(this->m_azimuthalCartRecCoord[rcvCnt * nDim + 0], recCoord[0],
36528 (m_azimuthalCornerEps * cellLength))
36529 && approx(this->m_azimuthalCartRecCoord[rcvCnt * nDim + 1], recCoord[1],
36530 (m_azimuthalCornerEps * cellLength))
36531 && approx(this->m_azimuthalCartRecCoord[rcvCnt * nDim + (nDim - 1)], recCoord[nDim - 1],
36532 (m_azimuthalCornerEps * cellLength))) {
36533 isEqual = true;
36534 }
36535 }
36536 }
36537 if(isEqual) {
36538 rcvCnt++;
36539 continue;
36540 }
36541
36542 vector<MFloat> tmpF(mMax(noFloatData + nDim, nDim + 3));
36543 vector<MUlong> tmpI(noIntData);
36544 tmpF[0] = this->m_azimuthalCartRecCoord[rcvCnt * nDim];
36545 tmpF[1] = this->m_azimuthalCartRecCoord[rcvCnt * nDim + 1];
36546 if(nDim == 3) {
36547 tmpF[2] = this->m_azimuthalCartRecCoord[rcvCnt * nDim + 2];
36548 }
36549 tmpF[nDim] = windowFData[rcvCnt * noFloatData]; // cellVol
36550 tmpF[nDim + 1] = windowFData[rcvCnt * noFloatData + 1]; // cellVolDt1
36551 tmpF[nDim + 2] = windowFData[rcvCnt * noFloatData + 2]; // sweptVol
36552
36553 if(mode == 1) {
36554 for(MInt v = 0; v < CV->noVariables; v++) {
36555 tmpF[nDim + 3 + v] = windowFData[rcvCnt * noFloatData + 3 + v]; // a_variables
36556 }
36557 }
36558
36559 tmpI[0] = windowIData[rcvCnt * noIntData]; // oldBndryCnt
36560 tmpI[1] = windowIData[rcvCnt * noIntData + 1]; // cell properties
36561
36562 m_azimuthalNearBoundaryBackup.insert(make_pair(gCellId, make_pair(tmpF, tmpI)));
36563 }
36564
36565 rcvCnt++;
36566 }
36567 }
36568 }
36569
36570#ifndef NDEBUG
36571 MInt cntMax = 0;
36572 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36573 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
36574 MInt cellId = grid().azimuthalWindowCell(i, j);
36575 MLong gCellId = cellId;
36576 if(mode == 1) gCellId = c_globalId(cellId);
36577 if(cntMax < (signed)m_azimuthalNearBoundaryBackup.count(gCellId))
36578 cntMax = m_azimuthalNearBoundaryBackup.count(gCellId);
36579 if(mode == 0 && m_azimuthalNearBoundaryBackup.count(gCellId) > 2) {
36580 MFloat recCoord[nDim];
36581 auto range = m_azimuthalNearBoundaryBackup.equal_range(gCellId);
36582 for(auto it = range.first; it != range.second; ++it) {
36583 for(MInt d = 0; d < nDim; d++) {
36584 recCoord[d] = (it->second).first[d];
36585 }
36586 cerr << "W:" << domainId() << " " << cellId << "/" << c_globalId(cellId) << " " << gCellId << " "
36587 << c_level(cellId) << " " << mode << " " << m_azimuthalNearBoundaryBackup.count(gCellId) << " " << j
36588 << "/" << grid().noAzimuthalWindowCells(i) << " " << grid().azimuthalNeighborDomain(i) << " "
36589 << c_coordinate(cellId, 0) << " " << c_coordinate(cellId, 1) << " " << c_coordinate(cellId, 2) << " "
36590 << recCoord[0] << " " << recCoord[1] << " " << recCoord[nDim - 1] << endl;
36591 }
36592 }
36593 }
36594 }
36595 MPI_Allreduce(MPI_IN_PLACE, &cntMax, 1, MPI_INT, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE", "cntMax");
36596 if(domainId() == 0) cerr << "cntMax: " << cntMax << endl;
36597#endif
36598}

◆ swapCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::swapCells ( const MInt  cellId0,
const MInt  cellId1 
)
overridevirtual
Author

Reimplemented from Solver.

Definition at line 16838 of file fvmbcartesiansolverxd.cpp.

16838 {
16839 if(cellId1 == cellId0) return;
16840
16842
16843 for(MInt v = 0; v < m_noFVars; v++) {
16844 std::swap(m_rhs0[cellId1][v], m_rhs0[cellId0][v]);
16845 }
16846
16847 for(MInt set = 0; set < m_noLevelSetsUsedForMb; set++) {
16848 std::swap(a_levelSetValuesMb(cellId1, set), a_levelSetValuesMb(cellId0, set));
16849 std::swap(a_associatedBodyIds(cellId1, set), a_associatedBodyIds(cellId0, set));
16850 }
16851
16852 std::swap(m_cellVolumesDt1[cellId1], m_cellVolumesDt1[cellId0]);
16853 if(m_dualTimeStepping) std::swap(m_cellVolumesDt2[cellId1], m_cellVolumesDt2[cellId0]);
16854
16855 if(!m_oldBndryCells.empty()) {
16856 auto it0 = m_oldBndryCells.find(cellId0);
16857 auto it1 = m_oldBndryCells.find(cellId1);
16858 if(it0 != m_oldBndryCells.end() && it1 != m_oldBndryCells.end()) {
16859 std::swap(it0->second, it1->second);
16860 } else if(it0 != m_oldBndryCells.end()) {
16861 MFloat val = it0->second;
16862 m_oldBndryCells.erase(it0);
16863 m_oldBndryCells.insert(make_pair(cellId1, val));
16864 } else if(it1 != m_oldBndryCells.end()) {
16865 MFloat val = it1->second;
16866 m_oldBndryCells.erase(it1);
16867 m_oldBndryCells.insert(make_pair(cellId0, val));
16868 }
16869 }
16870
16871 if(!m_nearBoundaryBackup.empty()) {
16872 auto it0 = m_nearBoundaryBackup.find(cellId0);
16873 auto it1 = m_nearBoundaryBackup.find(cellId1);
16874 if(it0 != m_nearBoundaryBackup.end() && it1 != m_nearBoundaryBackup.end()) {
16875 std::swap(it0->second, it1->second);
16876 } else if(it0 != m_nearBoundaryBackup.end()) {
16877 vector<MFloat> val(it0->second);
16878 m_nearBoundaryBackup.erase(it0);
16879 m_nearBoundaryBackup.insert(make_pair(cellId1, val));
16880 } else if(it1 != m_nearBoundaryBackup.end()) {
16881 vector<MFloat> val(it1->second);
16882 m_nearBoundaryBackup.erase(it1);
16883 m_nearBoundaryBackup.insert(make_pair(cellId0, val));
16884 }
16885 }
16886
16887 if(!m_coarseOldBndryCells.empty()) {
16888 auto it0 = m_coarseOldBndryCells.find(cellId0);
16889 auto it1 = m_coarseOldBndryCells.find(cellId1);
16890 if(it0 != m_coarseOldBndryCells.end() && it1 == m_coarseOldBndryCells.end()) {
16891 // nothing to be done
16892 } else if(it0 != m_coarseOldBndryCells.end()) {
16893 m_coarseOldBndryCells.erase(it0);
16894 m_coarseOldBndryCells.insert(cellId1);
16895 } else if(it1 != m_coarseOldBndryCells.end()) {
16896 m_coarseOldBndryCells.erase(it1);
16897 m_coarseOldBndryCells.insert(cellId0);
16898 }
16899 }
16900
16901 if(!m_oldGeomBndryCells.empty()) {
16902 auto it0 = m_oldGeomBndryCells.find(cellId0);
16903 auto it1 = m_oldGeomBndryCells.find(cellId1);
16904 if(it0 != m_oldGeomBndryCells.end() && it1 == m_oldGeomBndryCells.end()) {
16905 std::swap(it0->second, it1->second);
16906 } else if(it0 != m_oldGeomBndryCells.end()) {
16907 const MFloat volume = it0->second;
16908 m_oldGeomBndryCells.erase(it0);
16909 m_oldGeomBndryCells.insert(make_pair(cellId1, volume));
16910 } else if(it1 != m_oldGeomBndryCells.end()) {
16911 const MFloat volume = it1->second;
16912 m_oldGeomBndryCells.erase(it1);
16913 m_oldGeomBndryCells.insert(make_pair(cellId0, volume));
16914 }
16915 }
16916
16917 // Swap stored azimuthal near boundary data
16918 if(grid().azimuthalPeriodicity()) {
16919 MInt cnt0 = m_azimuthalNearBoundaryBackup.count(cellId0);
16920 MInt cnt1 = m_azimuthalNearBoundaryBackup.count(cellId1);
16921 ASSERT(cnt0 < 3 && cnt1 < 3, "cnt should not exceed 2");
16922 if(cnt0 == 2) {
16923 auto range = m_azimuthalNearBoundaryBackup.equal_range(cellId0);
16924 auto it00 = range.first;
16925 auto it01 = it00++;
16926 if(cnt1 == 0) {
16927 {
16928 pair<vector<MFloat>, vector<MUlong>> tmp(it00->second.first, it00->second.second);
16930 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId1, tmp));
16931 }
16932 {
16933 pair<vector<MFloat>, vector<MUlong>> tmp(it01->second.first, it01->second.second);
16935 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId1, tmp));
16936 }
16937 } else if(cnt1 == 1) {
16938 {
16939 auto it10 = m_azimuthalNearBoundaryBackup.find(cellId1);
16940 std::swap(it00->second, it10->second);
16941 }
16942 {
16943 pair<vector<MFloat>, vector<MUlong>> tmp(it01->second.first, it01->second.second);
16945 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId1, tmp));
16946 }
16947 } else { // cnt1 == 2
16948 auto range2 = m_azimuthalNearBoundaryBackup.equal_range(cellId1);
16949 auto it10 = range2.first;
16950 auto it11 = it10++;
16951 std::swap(it00->second, it10->second);
16952 std::swap(it01->second, it11->second);
16953 }
16954 } else if(cnt0 == 1) {
16955 auto it00 = m_azimuthalNearBoundaryBackup.find(cellId0);
16956 if(cnt1 == 0) {
16957 pair<vector<MFloat>, vector<MUlong>> tmp(it00->second.first, it00->second.second);
16959 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId1, tmp));
16960 } else if(cnt1 == 1) {
16961 auto it10 = m_azimuthalNearBoundaryBackup.find(cellId1);
16962 std::swap(it00->second, it10->second);
16963 } else { // cnt1 == 2
16964 auto range = m_azimuthalNearBoundaryBackup.equal_range(cellId1);
16965 auto it10 = range.first;
16966 auto it11 = it10++;
16967 std::swap(it00->second, it10->second);
16968 pair<vector<MFloat>, vector<MUlong>> tmp(it11->second.first, it11->second.second);
16970 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId0, tmp));
16971 }
16972 } else { // cnt0 == 0
16973 if(cnt1 == 0) {
16974 // Nothing to be done
16975 } else if(cnt1 == 1) {
16976 auto it10 = m_azimuthalNearBoundaryBackup.find(cellId1);
16977 pair<vector<MFloat>, vector<MUlong>> tmp(it10->second.first, it10->second.second);
16979 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId0, tmp));
16980 } else { // cnt1 == 2
16981 auto range = m_azimuthalNearBoundaryBackup.equal_range(cellId1);
16982 auto it10 = range.first;
16983 auto it11 = it10++;
16984 {
16985 pair<vector<MFloat>, vector<MUlong>> tmp(it10->second.first, it10->second.second);
16987 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId0, tmp));
16988 }
16989 {
16990 pair<vector<MFloat>, vector<MUlong>> tmp(it11->second.first, it11->second.second);
16992 m_azimuthalNearBoundaryBackup.insert(make_pair(cellId0, tmp));
16993 }
16994 }
16995 }
16996 }
16997}
void swapCells(const MInt, const MInt) override

◆ temperature()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::temperature ( MInt  cellId)
inline
Author
Lennart Schneiders

Definition at line 14345 of file fvmbcartesiansolverxd.cpp.

14345 {
14346 return sysEqn().temperature_ES(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
14347}

◆ test_face()

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::test_face ( MInt  cndId,
MInt  face,
MInt  set 
)
private

Definition at line 31505 of file fvmbcartesiansolverxd.cpp.

31505 {
31506 const MInt faceCornerMapping[6][4] = {{2, 6, 4, 0}, {1, 5, 7, 3}, {0, 4, 5, 1},
31507 {3, 7, 6, 2}, {2, 3, 1, 0}, {6, 7, 5, 4}};
31508
31509 MFloat A = m_candidateNodeValues[IDX_LSSETNODES(cndId, faceCornerMapping[face][0], set)];
31510 MFloat B = m_candidateNodeValues[IDX_LSSETNODES(cndId, faceCornerMapping[face][1], set)];
31511 MFloat C = m_candidateNodeValues[IDX_LSSETNODES(cndId, faceCornerMapping[face][2], set)];
31512 MFloat D = m_candidateNodeValues[IDX_LSSETNODES(cndId, faceCornerMapping[face][3], set)];
31513
31514 MFloat testSum = A * C - B * D;
31515 if(fabs(testSum) < m_eps) return true;
31516 return A * testSum >= F0; // A being negative inverts signs
31517}

◆ transferBodyState()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::transferBodyState ( MInt  k,
MInt  b 
)
Author

Definition at line 8074 of file fvmbcartesiansolverxd.cpp.

8074 {
8075 // TRACE();
8076
8079 for(MInt i = 0; i < nDim; i++) {
8080 m_bodyVelocity[k * nDim + i] = m_bodyVelocity[b * nDim + i];
8082 }
8083 for(MInt i = 0; i < 3; i++) {
8084 m_bodyRadii[k * 3 + i] = m_bodyRadii[b * 3 + i];
8085 m_bodyAngularVelocity[k * 3 + i] = m_bodyAngularVelocity[b * 3 + i];
8087 }
8088 for(MInt i = 0; i < 4; i++) {
8089 m_bodyQuaternion[k * 4 + i] = m_bodyQuaternion[b * 4 + i];
8090 }
8091}

◆ transferLevelSetFieldValues()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::transferLevelSetFieldValues ( MBool  )

◆ updateAzimuthalMaxLevelRecCoords()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateAzimuthalMaxLevelRecCoords
Author
Thomas Hoesgen

Definition at line 36341 of file fvmbcartesiansolverxd.cpp.

36341 {
36342 TRACE();
36343
36344 if(grid().noAzimuthalNeighborDomains() == 0) return;
36345
36347 MFloatScratchSpace windowData(rcvSize * (nDim + 1), AT_, "windowData");
36348 windowData.fill(0);
36350 MFloatScratchSpace haloData(sndSize * (nDim + 1), AT_, "haloData");
36351 haloData.fill(0);
36352
36353 MInt sndCnt = 0;
36354 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36355 for(MUint j = 0; j < m_azimuthalMaxLevelHaloCells[i].size(); j++) {
36357 for(MInt d = 0; d < nDim; d++) {
36358 haloData[sndCnt++] = a_coordinate(cellId, d);
36359 }
36360 haloData[sndCnt++] = (MFloat)a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel);
36361 }
36362 }
36363
36365 m_azimuthalMaxLevelHaloCells, mpiComm(), haloData.getPointer(), windowData.getPointer(),
36366 nDim + 1);
36367
36368 MFloat angle = grid().azimuthalAngle();
36369 MFloat recCoord[3];
36370 MInt rcvCnt = 0;
36371 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36372 for(MUint j = 0; j < m_azimuthalMaxLevelWindowCells[i].size(); j++) {
36373 MInt offset = m_azimuthalMaxLevelWindowMap[i][j];
36374 for(MInt d = 0; d < nDim; d++) {
36375 recCoord[d] = windowData[rcvCnt++];
36376 }
36377
36378 MInt side = m_azimuthalBndrySide[offset];
36379 grid().rotateCartesianCoordinates(recCoord, (side * angle));
36380
36381 for(MInt d = 0; d < nDim; d++) {
36382 m_azimuthalCutRecCoord[offset * nDim + d] = recCoord[d];
36383 }
36384 m_azimuthalHaloActive[offset] = (MInt)windowData[rcvCnt++];
36385 }
36386 }
36387
36388 MInt offset = 0;
36389 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36390 for(MInt j = 0; j < grid().noAzimuthalWindowCells(i); j++) {
36391 MInt cellId = grid().azimuthalWindowCell(i, j);
36392 if(m_azimuthalHaloActive[offset] > 0) {
36393 // m_azimuthalWasNearBndryIds[offset] = cellId;
36394 } else {
36396 m_noAzimuthalReconstNghbrs[offset] = 1;
36398 m_azimuthalWasNearBndryIds[offset] = -1;
36399 }
36400 offset++;
36401 }
36402 }
36403}

◆ updateAzimuthalNearBoundaryExchange()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateAzimuthalNearBoundaryExchange
Author
Thomas Hoesgen

Definition at line 36300 of file fvmbcartesiansolverxd.cpp.

36300 {
36301 TRACE();
36302
36303 for(MInt i = 0; i < grid().noAzimuthalNeighborDomains(); i++) {
36304 for(MUint j = 0; j < m_azimuthalMaxLevelWindowCells[i].size(); j++) {
36306 MInt offset = m_azimuthalMaxLevelWindowMap[i][j];
36307 MInt noNghbrIds = m_noAzimuthalReconstNghbrs[offset];
36308 MBool rebuild = false;
36309 for(MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
36311 if(a_bndryId(recId) > -1) {
36312 rebuild = true;
36313 break;
36314 }
36315 }
36316 if(a_levelSetValuesMb(cellId, 0) <= F0 && m_azimuthalHaloActive[offset]) {
36317 rebuild = true;
36318 }
36319 if(rebuild) {
36320 // Rebuild reconstruction constants if stencil contains bndry cells
36322 } else {
36323 if(m_azimuthalWasNearBndryIds[offset] > -1) {
36324 // Reset reconstruction constants if stencil does not contain bndry cells anymore
36326 } else {
36327 // Else keep old reconstruction constants
36328 m_azimuthalWasNearBndryIds[offset] = -1;
36329 }
36330 }
36331 }
36332 }
36333}

◆ updateBodyProperties()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateBodyProperties ( )
Author
Lennart Schneiders

◆ updateCellSurfaceDistanceVector()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateCellSurfaceDistanceVector ( MInt  srfcId)
Author
Lennart Schneiders

Definition at line 21147 of file fvmbcartesiansolverxd.cpp.

21147 {
21148 MFloat fac0 = F0;
21149 MFloat fac1 = F0;
21150
21151 for(MInt i = 0; i < nDim; i++) {
21152 a_surfaceDeltaX(srfcId, i) = a_surfaceCoordinate(srfcId, i) - a_coordinate(a_surfaceNghbrCellId(srfcId, 0), i);
21153 a_surfaceDeltaX(srfcId, nDim + i) =
21154 a_surfaceCoordinate(srfcId, i) - a_coordinate(a_surfaceNghbrCellId(srfcId, 1), i);
21155 fac0 += POW2(a_surfaceDeltaX(srfcId, i));
21156 fac1 += POW2(a_surfaceDeltaX(srfcId, nDim + i));
21157 }
21158 fac0 = sqrt(fac0);
21159 fac1 = sqrt(fac1);
21160 IF_CONSTEXPR(nDim == 3) { // TODO_rmxd labels:FVMB
21161 a_surfaceFactor(srfcId, 0) = fac1 / (fac0 + fac1);
21162 a_surfaceFactor(srfcId, 1) = F1 - a_surfaceFactor(srfcId, 0);
21163 }
21164}

◆ updateCellSurfaceDistanceVectors()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateCellSurfaceDistanceVectors
Author
Lennart Schneiders

Definition at line 21128 of file fvmbcartesiansolverxd.cpp.

21128 {
21129 TRACE();
21130
21131 const MInt noSrfcs = a_noSurfaces();
21132
21133 for(MInt s = m_bndrySurfacesOffset; s < noSrfcs; s++) {
21134 for(MInt i = 0; i < nDim; i++) {
21137 }
21138 }
21139}

◆ updateCellVolumeGCL()

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::updateCellVolumeGCL ( MInt  bndryId)

Definition at line 10878 of file fvmbcartesiansolverxd.cpp.

10878 {
10879 TRACE();
10880
10881 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
10882
10883 MFloat dV = F0;
10884 if(m_dualTimeStepping) {
10885 mTerm(1, AT_, "TODO DTS");
10886 a_cellVolume(cellId) = F4B3 * m_cellVolumesDt1[cellId] - F1B3 * m_cellVolumesDt2[cellId];
10887 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
10888 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
10889 for(MInt i = 0; i < nDim; i++) {
10890 MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
10891 dV -= F2B3 * m_physicalTimeStep
10892 * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] * nml * area;
10893 }
10894 }
10895 } else {
10896 MFloat dt = timeStep(true);
10897 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
10898 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
10899 for(MInt i = 0; i < nDim; i++) {
10900 MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
10901 dV -= dt * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] * nml * area;
10902 }
10903 }
10904 }
10905
10906
10907 m_sweptVolume[bndryId] = dV;
10908
10909 MFloat deltaVol = dV;
10910 if(m_gclIntermediate) {
10911 if(m_levelSetMb) {
10912 // deltaVol = ( m_RKStep == 0 ) ? m_sweptVolumeDt1[ bndryId ] : m_RKalpha[ m_RKStep-1 ] * m_sweptVolume[ bndryId ]
10913 // + (F1-m_RKalpha[ m_RKStep-1 ]) * m_sweptVolumeDt1[ bndryId ] ;
10914 deltaVol = m_RKalpha[m_noRKSteps - 2] * m_sweptVolume[bndryId]
10915 + (F1 - m_RKalpha[m_noRKSteps - 2]) * m_sweptVolumeDt1[bndryId];
10916 }
10917 } else {
10918 // deltaVol = ( m_levelSetMb ) ? F1B2 * ( m_sweptVolume[ bndryId ] + m_sweptVolumeDt1[ bndryId ] ) : dV;
10919 deltaVol = (m_levelSetMb) ? m_RKalpha[m_noRKSteps - 2] * m_sweptVolume[bndryId]
10920 + (F1 - m_RKalpha[m_noRKSteps - 2]) * m_sweptVolumeDt1[bndryId]
10921 : dV;
10922 }
10923 a_cellVolume(cellId) = m_cellVolumesDt1[cellId] + deltaVol;
10924
10925 const MFloat V0 = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume - 0.1 * grid().gridCellVolume(a_level(cellId));
10926 const MFloat V1 = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume + 0.1 * grid().gridCellVolume(a_level(cellId));
10927 a_cellVolume(cellId) = mMin(V1, mMax(V0, a_cellVolume(cellId)));
10928
10929 a_cellVolume(cellId) = mMax(a_cellVolume(cellId), m_volumeThreshold);
10930 a_FcellVolume(cellId) = F1 / mMax(m_volumeThreshold, a_cellVolume(cellId));
10931
10932 /*
10933 if ( a_hasProperty( cellId , SolverCell::IsSplitCell ) || a_hasProperty( cellId , SolverCell::IsSplitChild ) ) {
10934 a_cellVolume( cellId ) = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_volume;
10935 m_cellVolumesDt1[ cellId ] = a_cellVolume( cellId ) - deltaVol;
10936 }*/
10937 if(m_levelSet && m_closeGaps) {
10938 if(a_wasGapCell(cellId) || a_isGapCell(cellId)) {
10939 // TODO-Timw labels:FVMB set volume of new-Gap-Bndry-Cells!
10940 // only change during initGapOpen
10941 if(m_gapInitMethod > 0) {
10942 MInt regionId = m_gapCells[m_gapCellId[cellId]].region;
10943 ASSERT(regionId > -1, "Negative region in Cell" << to_string(c_globalId(cellId)) << " " << m_gapCellId[cellId]);
10944
10945 // labels:FVMB G0-hack
10946 if(regionId == m_noGapRegions) {
10947 // ASSERT(a_wasGapCell(cellId) == a_isGapCell(cellId ), "");
10948 // zero-volume change in G0-region cells:
10950 m_sweptVolume[bndryId] = 0;
10951 m_sweptVolumeDt1[bndryId] = 0;
10952
10953 } else {
10954 if(m_gapState[regionId] == -2 || m_gapState[regionId] == 3 || m_gapState[regionId] == -1) {
10955 // for gap-Closure, gap-Widening and gap-Shrinking, static initialisation!
10956 // handeled in updateGapBoundaryCells, just some checks here
10957 // for gapCells, not for old gapCells, which are handeled regularly!
10958 if(a_isGapCell(cellId)) {
10959 if(fabs(a_cellVolume(cellId) - m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume)
10960 > m_volumeThreshold * 10) {
10961 // if(a_cellVolume( cellId ) > m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_volume ||
10962 // a_cellVolume( cellId ) < m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_volume) {
10963
10964 // if(a_cellVolume( cellId ) > m_volumeThreshold * 10) {
10965 /*
10966 cerr << "Incorrect Volume-Initialisation " << a_cellVolume(cellId) << " "
10967 << m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume << " "
10968 << a_hasProperty(cellId, SolverCell::IsSplitCell) << " "
10969 << a_hasProperty(cellId, SolverCell::IsSplitChild) << " " << a_isHalo(cellId) << " "
10970 << m_gapCells[m_gapCellId[cellId]].status << endl;
10971 */
10972 //}
10973 }
10974
10975 if(m_sweptVolume[bndryId] > 0 || m_sweptVolume[bndryId] < 0 || m_sweptVolumeDt1[bndryId] < 0
10976 || m_sweptVolumeDt1[bndryId] < 0) {
10977 cerr << " Incorrect swetVolume-Innitialisation " << m_sweptVolume[bndryId] << m_sweptVolumeDt1[bndryId]
10978 << endl;
10979 }
10980 }
10981
10982 } else if(m_gapState[regionId] == 2) {
10983 ASSERT(a_wasGapCell(cellId) && !a_isGapCell(cellId), "");
10984 MInt status = m_gapCells[m_gapCellId[cellId]].status;
10985 // status 27: former internal, now bndry-Cell -> handeled regularly
10986
10987 if(status != 27) {
10988 if(status != 22 && status != 24 && status != 28 && status != 29 && status != 99 && status != 98) {
10989 cerr << "UnExpected Status for Volume (1) " << c_globalId(cellId) << " " << status << endl;
10990 }
10991
10992 // for gap-Opening, just as a restart!
10993 // THIS IS NOT FULLY WORKING YET!!!!
10994
10995 if(deltaVol > m_sweptVolumeDt1[bndryId] || deltaVol < m_sweptVolumeDt1[bndryId]) {
10996 if(m_gapCells[m_gapCellId[cellId]].status != 98)
10997 cerr << "Incorrect Initialisation " << c_globalId(cellId) << " "
10998 << m_gapCells[m_gapCellId[cellId]].status << endl;
10999 }
11000
11001 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
11002
11003 if(deltaVol > a_cellVolume(cellId)) {
11004 deltaVol = a_cellVolume(cellId);
11005 m_sweptVolume[bndryId] = deltaVol;
11006 }
11007 m_cellVolumesDt1[cellId] = a_cellVolume(cellId) - deltaVol;
11008 m_sweptVolumeDt1[bndryId] = m_sweptVolume[bndryId];
11009 }
11010 }
11011 // some additional and more generalised checks:
11012
11013 if(a_cellVolume(cellId) < 0 || m_cellVolumesDt1[cellId] < 0) {
11014 cerr << "Negative Cell-Volume : " << c_globalId(cellId) << " " << a_cellVolume(cellId) << " "
11015 << m_cellVolumesDt1[cellId] << " " << deltaVol << " " << dV << " " << m_sweptVolume[bndryId]
11016 << " status " << m_gapCells[m_gapCellId[cellId]].status << endl;
11017 }
11018
11019 if(a_cellVolume(cellId) > 1.03 * grid().gridCellVolume(a_level(cellId))) {
11020 cerr << "Volume exeeds Limit " << c_globalId(cellId) << " "
11021 << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " "
11022 << a_cellVolume(cellId) / grid().gridCellVolume(a_level(cellId)) << " status "
11023 << m_gapCells[m_gapCellId[cellId]].status << endl;
11024 }
11025
11026 if(m_cellVolumesDt1[cellId] > 1.03 * grid().gridCellVolume(a_level(cellId))) {
11027 cerr << "Dt-Volume exeeds Limit " << c_globalId(cellId) << " "
11028 << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " "
11029 << m_cellVolumesDt1[cellId] / grid().gridCellVolume(a_level(cellId)) << " " << deltaVol << " "
11030 << m_gapCells[m_gapCellId[cellId]].status << endl;
11031 }
11032 }
11033
11034 } else {
11035 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
11036 m_cellVolumesDt1[cellId] = a_cellVolume(cellId) - deltaVol;
11037 }
11038 }
11039 }
11040
11041 return deltaVol;
11042}

◆ updateGapBoundaryCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateGapBoundaryCells
Author
Tim Wegmann

Definition at line 28641 of file fvmbcartesiansolverxd.cpp.

28641 {
28642 TRACE();
28643
28644 ASSERT(m_levelSet && m_closeGaps, "");
28645 ASSERT(m_gapInitMethod > 0, "");
28646
28647 // during initGapClosure
28648 for(MInt region = 0; region < m_noGapRegions; region++) {
28649 if(m_gapState[region] != -2) continue;
28650
28651 // easy-first try: static initialisation:
28652 // sweptVolume = sweptVolumeDt = 0
28653 // cellVolume = cellVolumeDt = bndry-Cell-volume
28654 // velocity = 0
28655
28656 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
28657 const MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
28658 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
28659 const MInt gapCellId = m_gapCellId[cellId];
28660 if(gapCellId < 0) continue;
28661 const MInt regionId = m_gapCells[gapCellId].region;
28662 if(regionId != region) continue;
28663
28664 const MInt status = m_gapCells[gapCellId].status;
28665
28666 // do cell-Volume update based on split-cell volumes
28667 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
28668 for(MInt v = 0; v < m_noFVars; v++) {
28669 a_rightHandSide(cellId, v) = F0;
28670 m_rhs0[cellId][v] = F0;
28671 }
28672 m_sweptVolumeDt1[bndryId] = 0;
28673 m_sweptVolume[bndryId] = 0;
28674 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28675 for(MInt i = 0; i < nDim; i++) {
28676 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = 0;
28677 }
28678 }
28679 continue;
28680 }
28681 // change to ASSERT!
28682 if(status != 5 && status != 6 && status != 7 && status != 99) {
28683 cerr << "UnExpected Bndry-Cell-Status (1) " << c_globalId(cellId) << " " << status << endl;
28684 }
28685
28686 // all active gap-bndry-Cells, now reseted:
28687 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
28689 m_sweptVolumeDt1[bndryId] = 0;
28690 m_sweptVolume[bndryId] = 0;
28691 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28692 for(MInt i = 0; i < nDim; i++) {
28693 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = 0;
28694 }
28695 }
28696 for(MInt v = 0; v < m_noFVars; v++) {
28697 a_rightHandSide(cellId, v) = F0;
28698 m_rhs0[cellId][v] = F0;
28699 }
28700 }
28701 }
28702
28703 // during gap-widening or shrinking
28704 for(MInt region = 0; region < m_noGapRegions; region++) {
28705 if(m_gapState[region] != 3 && m_gapState[region] != -1) continue;
28706
28707 // easy-first try: static initialisation:
28708 // sweptVolume = sweptVolumeDt = 0
28709 // cellVolume = cellVolumeDt = bndry-Cell-volume
28710 // velocity = 0
28711
28712 for(MUint it = 0; it < m_gapCells.size(); it++) {
28713 const MInt regionId = m_gapCells[it].region;
28714 if(regionId != region) continue;
28715 const MInt cellId = m_gapCells[it].cellId;
28716 const MInt status = m_gapCells[it].status;
28717
28718 if(!a_isBndryCell(cellId)) continue;
28719 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
28720 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
28721
28722 if(a_wasGapCell(cellId) && !a_isGapCell(cellId)) continue;
28723
28724 // do this on split-Child-basis
28725 // if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
28726
28727 MInt bndryId = a_bndryId(cellId);
28728 if(bndryId < -1) continue;
28729
28730 // do cell-Volume update based on split-cell volumes
28731 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) {
28732 for(MInt v = 0; v < m_noFVars; v++) {
28733 a_rightHandSide(cellId, v) = F0;
28734 m_rhs0[cellId][v] = F0;
28735 }
28736 m_sweptVolumeDt1[bndryId] = 0;
28737 m_sweptVolume[bndryId] = 0;
28738 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28739 for(MInt i = 0; i < nDim; i++) {
28740 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = 0;
28741 }
28742 }
28743 continue;
28744 }
28745
28746 a_cellVolume(cellId) = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
28748 m_sweptVolumeDt1[bndryId] = 0;
28749 m_sweptVolume[bndryId] = 0;
28750 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28751 for(MInt i = 0; i < nDim; i++) {
28752 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = 0;
28753 }
28754 }
28755
28756 // for partial-Gap-Opening:
28757 // largestNeighbor of a new small gap Cell
28758 if(status == 17) {
28759 MFloat dV = F0;
28760 MFloat dt = timeStep(true);
28761
28762 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28763 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
28764 for(MInt i = 0; i < nDim; i++) {
28765 MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
28766 dV -= dt * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] * nml * area;
28767 }
28768 }
28769
28770 MFloat cellVolume = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
28771
28772 if(dV > cellVolume) {
28773 dV = cellVolume;
28774 // get<2>(m_gapCells[gapCellId]) = 99;
28775 }
28776
28777 m_sweptVolume[bndryId] = dV;
28778 m_sweptVolumeDt1[bndryId] = dV;
28779
28780 // reduce bndry-Cell velocity to fit the boundary-Condition!
28781 MFloat delta = maia::math::deltaFun(m_volumeFraction[bndryId], F0, F1);
28782 for(MInt i = 0; i < nDim; i++) {
28783 a_pvariable(cellId, PV->VV[i]) =
28784 delta * a_pvariable(cellId, PV->VV[i])
28785 + (F1 - delta) * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->VV[i]];
28786 }
28788 for(MInt varId = 0; varId < CV->noVariables; varId++) {
28789 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
28790 }
28791 }
28792
28793 // Plan-B: estimate the interface-velocity based on the volume-change!
28794 /*
28795 //compute the surface-velocity based on the volume-change of the cell
28796 MFloat vol = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_volume;
28797 MFloat volDt1 = m_cellVolumesDt1[ cellId ];
28798
28799 auto it1 = m_oldBndryCells.find( cellId );
28800 if(a_hasProperty(cellId, SolverCell::WasInactive)) {
28801 cerr << "WasInactive " << m_cellVolumesDt1[ cellId ]/grid().gridCellVolume( a_level(cellId) ) << endl;
28802 } else if(it1 != m_oldBndryCells.end()) {
28803 cerr << "WasBndryCell " << m_cellVolumesDt1[ cellId ]/grid().gridCellVolume( a_level(cellId) )
28804 << " " << m_sweptVolumeDt1[a_bndryId( cellId )] << endl;
28805 } else {
28806 cerr << "WasActive " << m_cellVolumesDt1[ cellId ]/grid().gridCellVolume( a_level(cellId) ) << endl;
28807 }
28808
28809 MFloat dV = vol - volDt1;
28810 MFloat dt = timeStep(true);
28811 MFloat sign = (dV > 0) ? 1.0 : -1.0;
28812
28813 for( MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++){
28814 MFloat area = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_srfcs[srfc]->m_area;
28815 MFloat absVel = abs(dV / (area * dt));
28816 for( MInt i=0; i<nDim; i++ ) {
28817 MFloat nml = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_srfcs[srfc]->m_normalVector[ i ];
28818
28819 MFloat velocity = sign * absVel *nml;
28820 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = velocity;
28821
28822 cerr << globalTimeStep << " " << c_globalId(cellId) << " "
28823 << vol /grid().gridCellVolume( a_level(cellId) ) << " "
28824 << volDt1 / grid().gridCellVolume( a_level(cellId) ) << " " << i << " " << velocity
28825 << " " << nml << " " << m_sweptVolumeDt1[a_bndryId( cellId )] << endl;
28826
28827 }
28828 }
28829 */
28830 }
28831 }
28832
28833 // during initGapOpening (handeled in updateCellVolumeGCL! )
28834
28835 // easy-first try: just as upon-restart
28836 // sweptVolume = sweptVolumeDt = dV
28837 // cellVolume = bndry-Cell-volume
28838 // cellVolumeDt1 = cellVolume - deltaVolume
28839 // velocity = body-velocity
28840
28841 for(MInt region = 0; region < m_noGapRegions; region++) {
28842 if(m_gapState[region] != 2) continue;
28843
28844 // Plan-A
28845
28846 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
28847 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
28848 MInt gapCellId = m_gapCellId[cellId];
28849 if(gapCellId < 0) continue;
28850
28851 const MInt regionId = m_gapCells[gapCellId].region;
28852 if(regionId != region) continue;
28853
28854 ASSERT(a_wasGapCell(cellId), "");
28855
28856 // do this on split-Child-basis
28857 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
28858
28859 MInt status = m_gapCells[gapCellId].status;
28860
28861 if(status == 27) {
28862 // wasInternal Cell before
28863 // treated regularly
28864 continue;
28865 }
28866
28867 if(status != 22 && status != 24 && status != 28 && status != 29) {
28868 cerr << "UnExpected Bndry-Cell-Status (2) " << c_globalId(cellId) << " " << status << endl;
28869 }
28870
28871 MFloat dV = F0;
28872 MFloat dt = timeStep(true);
28873
28874 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28875 MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
28876 for(MInt i = 0; i < nDim; i++) {
28877 MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
28878 dV -= dt * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] * nml * area;
28879 }
28880 }
28881
28882 MFloat cellVolume = m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
28883
28884 if(dV > cellVolume) {
28885 dV = cellVolume;
28886 // gap-Cells, for which dV needs to be limited!
28887 m_gapCells[gapCellId].status = 98;
28888 }
28889
28890 m_sweptVolume[bndryId] = dV;
28891 m_sweptVolumeDt1[bndryId] = dV;
28892
28893
28894 if(status == 22 || status == 28 || status == 29) {
28895 // reduce velocity in the cells to fit the boundary-Condition!
28896 // as the values are interpolated from non-boundary cells, this is necessary for all
28897 // new bndry-cells!
28898 MFloat delta = maia::math::deltaFun(m_volumeFraction[bndryId], F0, F1);
28899 for(MInt i = 0; i < nDim; i++) {
28900 a_pvariable(cellId, PV->VV[i]) =
28901 delta * a_pvariable(cellId, PV->VV[i])
28902 + (F1 - delta) * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->VV[i]];
28903 }
28905 for(MInt varId = 0; varId < CV->noVariables; varId++) {
28906 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
28907 }
28908 }
28909 }
28910
28911 gapCellExchange(1);
28912
28913
28914 // Plan-B: static initialisation:
28915 // not working!
28916 /*
28917 for(MUint it = 0; it < m_gapCells.size(); it++){
28918 MInt regionId = m_gapCells[it].region;
28919 if(regionId != region) continue;
28920 MInt cellId = m_gapCells[it].cellId;
28921
28922 if(!a_isBndryCell(cellId)) continue;
28923 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
28924 if (a_hasProperty( cellId , SolverCell::IsInactive ) ) continue;
28925
28926
28927 MInt bndryId = a_bndryId( cellId );
28928 if(bndryId < -1 ) continue;
28929
28930 a_cellVolume( cellId ) = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_volume;
28931 m_cellVolumesDt1[ cellId ] = a_cellVolume( cellId );
28932 m_sweptVolumeDt1[bndryId] = 0;
28933 m_sweptVolume[bndryId] = 0;
28934 for( MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++){
28935 for( MInt i=0; i<nDim; i++ ) {
28936 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = 0;
28937 }
28938 }
28939 }
28940
28941 gapCellExchange(1);
28942 */
28943 /*
28944 if(status == 24 ) {
28945 //a bndry-Cell which was active before
28946
28947 MInt bndryId = a_bndryId( cellId );
28948 if(bndryId < -1 ) continue;
28949
28950 MFloat cellVolumes = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_volume;
28951 MFloat deltaVol = cellVolumes - m_cellVolumesDt1[ cellId ];
28952 MFloat sweptVolume = (deltaVol - (F1-m_RKalpha[ m_noRKSteps-2 ]) * m_sweptVolumeDt1[ bndryId ]) /
28953 m_RKalpha[ m_noRKSteps-2 ]; MFloat velocity = F0; MFloat dt = timeStep(true); MFloat noSurfaces = 0;
28954 MFloat surfaceVel = F0;
28955
28956 for( MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++ ){
28957
28958 surfaceVel = F0;
28959 for( MInt i = 0; i<nDim; i++) {
28960 surfaceVel += m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]];
28961 }
28962 //if(surfaceVel > 0 ) {
28963 noSurfaces++;
28964 MFloat area = m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_srfcs[srfc]->m_area;
28965 velocity -= sweptVolume / (dt*area);
28966 // }
28967 }
28968 velocity = velocity / noSurfaces;
28969
28970 cerr << "Velocity calculation: " << c_globalId(cellId) << " " << velocity << " "
28971 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->VV[0]] << " "
28972 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->VV[1]] << " "
28973 << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->VV[2]] << " "
28974 << surfaceVel << endl;
28975
28976 */
28977 }
28978
28979
28980 // g0-region-velocity:
28981 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
28982 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
28983 MInt gapCellId = m_gapCellId[cellId];
28984 if(gapCellId < 0) continue;
28985
28986 const MInt regionId = m_gapCells[gapCellId].region;
28987 if(regionId != m_noGapRegions) continue;
28988
28989 MFloat vel[3];
28990 for(MInt i = 0; i < nDim; i++) {
28991 vel[i] = m_gapCells[gapCellId].surfaceVelocity[i];
28992 }
28993
28994 MFloat dV = 0;
28995 const MFloat dt = timeStep(true);
28996 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
28997 const MFloat area = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
28998 for(MInt i = 0; i < nDim; i++) {
28999 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = vel[i];
29000 //= 0;
29001 const MFloat nml = m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
29002 dV -= dt * vel[i] * nml * area;
29003 }
29004 }
29005 if(dV * 100 / 5 > grid().gridCellVolume(a_level(cellId))) {
29006 cerr << "Large Volume change in G0-region cell! " << dV << " " << dV / m_cellVolumesDt1[cellId] << endl;
29007 }
29008 }
29009
29010 // update-Split-childs based on split-cell volumes
29011
29012 for(MUint sc = 0; sc < m_splitCells.size(); sc++) {
29013 const MInt cellId = m_splitCells[sc];
29014 if(m_gapCellId[cellId] > -1) continue;
29015 MFloat cvol = F0;
29016 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
29017 const MInt splitChildId = m_splitChilds[sc][ssc];
29018 MFloat vol = m_fvBndryCnd->m_bndryCells->a[a_bndryId(splitChildId)].m_volume;
29019 cvol += vol;
29020 a_cellVolume(splitChildId) = vol * a_cellVolume(cellId);
29021 m_cellVolumesDt1[splitChildId] = vol * m_cellVolumesDt1[cellId];
29022 }
29023 cvol = mMax(1e-15, cvol);
29024 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
29025 const MInt splitChildId = m_splitChilds[sc][ssc];
29026 a_cellVolume(splitChildId) /= cvol;
29027 m_cellVolumesDt1[splitChildId] /= cvol;
29028 }
29029 }
29030}

◆ updateGeometry()

◆ updateGhostCellSlopesInviscid()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateGhostCellSlopesInviscid
Author
Lennart Schneiders

Definition at line 18180 of file fvmbcartesiansolverxd.cpp.

18180 {
18181 m_fvBndryCnd->updateGhostCellSlopesInviscid();
18182}

◆ updateGhostCellSlopesViscous()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateGhostCellSlopesViscous
Author
Lennart Schneiders

Definition at line 18190 of file fvmbcartesiansolverxd.cpp.

18190 {
18191 if(m_euler) return;
18192 m_fvBndryCnd->updateGhostCellSlopesViscous();
18193}

◆ updateInfinityVariables()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateInfinityVariables
Author
Lennart Schneiders

Definition at line 14236 of file fvmbcartesiansolverxd.cpp.

14236 {
14237 TRACE();
14238
14239 if(m_initialCondition == 22) { // If Pipe (case 22) change also IC in fvcartesiansolver
14240 MFloat noPeriodicDirs = 0;
14241 for(MInt dim = 0; dim < nDim; dim++) {
14242 if(grid().periodicCartesianDir(dim)) {
14243 m_volumeForcingDir = dim;
14244 noPeriodicDirs++;
14245 }
14246 }
14247 if(noPeriodicDirs > 1) mTerm(1, AT_, "Only one periodic direction is implemented for the pipe case");
14248 if(m_volumeForcingDir == -1) mTerm(-1, AT_, "IC 22 requires a volumeForcingDir");
14249
14250 // Reynolds set in properties is based on unit length L=1
14251 MInt Re_r = Context::getSolverProperty<MFloat>("Re", m_solverId, AT_) * m_pipeRadius;
14252 m_pipeRadius = Context::getSolverProperty<MFloat>("pipeRadius", m_solverId, AT_);
14253
14254 // Any other perpendicular direction indicates the pipe diameter
14255 const MInt rDir1 = ((m_volumeForcingDir + 1) % nDim);
14256 const MInt rDir2 = ((rDir1 + 1) % nDim);
14257 if(rDir1 == rDir2 || rDir1 == m_volumeForcingDir || rDir2 == m_volumeForcingDir)
14258 mTerm(-1, AT_, "Inconsistent dirs.");
14259
14260 const MFloat pipeLength = computeDomainLength(m_volumeForcingDir);
14261
14262 cerr0 << "Update infinity state for IC 22: found pipeRadius = " << m_pipeRadius
14263 << " and pipeLength = " << pipeLength << endl;
14264
14265 MFloat lambda = F0;
14266 if(Re_r < 1500) {
14267 lambda = 32.0 / Re_r;
14268 if(domainId() == 0) cerr << "IC 22, using case Re<1500" << endl;
14269 } else {
14270 lambda = 0.316 / pow(Re_r * F2, 0.25);
14271 if(domainId() == 0) cerr << "IC 22, using case Re>=1500" << endl;
14272 }
14273 MFloat reTau = Re_r * sqrt(lambda / F8);
14274 MFloat uTau = reTau * m_Ma * sqrt(m_TInfinity) / Re_r;
14275 MFloat deltaP = F2 * m_rhoInfinity * POW2(uTau) * (pipeLength) / m_pipeRadius;
14276 m_volumeAcceleration[m_volumeForcingDir] = deltaP / (m_rhoInfinity * pipeLength);
14277 }
14278
14279 // Not used in combination with the levelSet-solver!
14280 if(!m_constructGField) return;
14281
14282 if(m_initialCondition == 15 || m_initialCondition == 16 || m_initialCondition == 467) {
14283 m_rhoInfinity = F1;
14284 m_TInfinity = F1;
14285 m_PInfinity = sysEqn().pressure_ES(m_TInfinity, m_rhoInfinity);
14286 m_UInfinity = m_Ma;
14287 m_VInfinity = F0;
14288 m_WInfinity = F0;
14289
14293 m_rhoEInfinity = sysEqn().internalEnergy(m_PInfinity, m_rhoInfinity, POW2(m_Ma));
14295 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
14296 sysEqn().m_muInfinity = SUTHERLANDLAW(m_TInfinity);
14297 m_timeRef = m_Ma;
14304
14305 if(m_restartFile) {
14306 m_log << "Restart Reynolds number: " << setprecision(15) << m_Re << " (Re_L=" << m_Re * (m_bbox[3] - m_bbox[0])
14307 << ")"
14308 << " " << sysEqn().m_Re0 << endl;
14309 }
14310 }
14311
14312 if((m_initialCondition == 465 || m_initialCondition == 466) && m_constructGField) {
14313 m_rhoInfinity = F1;
14314 m_TInfinity = F1;
14315 m_PInfinity = sysEqn().pressure_ES(m_TInfinity, m_rhoInfinity);
14316 m_UInfinity = m_Ma;
14317 m_VInfinity = F0;
14318 m_WInfinity = F0;
14325 m_rhoEInfinity = sysEqn().internalEnergy(m_PInfinity, m_rhoInfinity, POW2(m_Ma));
14327 sysEqn().m_Re0 = m_Re * SUTHERLANDLAW(m_TInfinity) / (m_rhoInfinity * m_UInfinity);
14328 m_timeRef = m_Ma;
14329 }
14330
14331
14332 m_U2 = F0;
14333 for(MInt i = 0; i < nDim; i++) {
14334 m_U2 += POW2(m_VVInfinity[i]);
14335 }
14337}
MFloat computeDomainLength(MInt direction)

◆ updateLevelSetOutsideBand()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateLevelSetOutsideBand
Author
Claudia Guenther

Definition at line 3033 of file fvmbcartesiansolverxd.cpp.

3033 {
3034 TRACE();
3035
3036
3037 MIntScratchSpace flag(a_noCells(), AT_, "flag");
3038 multimap<MFloat, MInt> approximateLSV;
3039 multimap<MFloat, MInt> initLSV;
3040 MFloat eps = 1.0e-10;
3041 const MInt _far = 2;
3042 const MInt band = 1;
3043 const MInt accepted = 0;
3044
3045 findNghbrIds();
3046
3047 // find first layer of halo cells:
3048 MBoolScratchSpace isFirstLayerHalo(a_noCells(), AT_, "isFirstLayerHalo");
3049 MIntScratchSpace firstLayerHalos(a_noCells(), AT_, "firstLayerHalos");
3050 MBoolScratchSpace isFarHalo(a_noCells(), AT_, "isFarHalo");
3051 MInt firstLayerHaloCount = 0;
3052 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3053 isFirstLayerHalo[cellId] = false;
3054 isFarHalo[cellId] = false;
3055 if(!a_isHalo(cellId)) continue;
3056 isFarHalo[cellId] = true;
3057 for(MInt direction = 0; direction < (2 * nDim); direction++) {
3058 for(MInt j = m_identNghbrIds[2 * cellId * nDim + direction];
3059 j < m_identNghbrIds[2 * cellId * nDim + direction + 1];
3060 j++) {
3061 MInt nghbrId = m_storeNghbrIds[j];
3062 if(a_isWindow(nghbrId)) {
3063 isFirstLayerHalo[cellId] = true;
3064 isFarHalo[cellId] = false;
3065 firstLayerHalos[firstLayerHaloCount++] = cellId;
3066 break;
3067 }
3068 }
3069 }
3070 }
3071
3072 // initialize flag:
3073 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3074 flag[cellId] = _far;
3075 }
3076
3077 // Initialize: Search calculated Points , create NarrowBand with approximated levelSetValues
3078 MBoolScratchSpace isStartCell(a_noCells(), AT_, "isStartCell");
3079 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3080 isStartCell[cellId] = false;
3081 if(c_noChildren(cellId)) {
3083 continue;
3084 }
3085 if(isFarHalo[cellId] || isFirstLayerHalo[cellId]) {
3087 continue;
3088 }
3089 MFloat limitValue = c_cellLengthAtLevel(a_level(cellId)) * sqrt(nDim);
3090 if(a_levelSetValuesMb(cellId, 0) < 0 || (false && a_levelSetValuesMb(cellId, 0) < limitValue)) {
3091 flag[cellId] = accepted;
3092 initLSV.insert(make_pair(a_levelSetValuesMb(cellId, 0), cellId));
3093 isStartCell[cellId] = true;
3094 } else {
3096 }
3097 }
3098
3099 while(!initLSV.empty()) {
3100 multimap<MFloat, MInt>::iterator it = initLSV.begin();
3101 MInt cellId = it->second;
3102 initLSV.erase(it);
3103 for(MInt direction = 0; direction < (2 * nDim); direction++) {
3104 for(MInt j = m_identNghbrIds[2 * cellId * nDim + direction];
3105 j < m_identNghbrIds[2 * cellId * nDim + direction + 1];
3106 j++) {
3107 MInt nghbrId = m_storeNghbrIds[j];
3108 if(isFarHalo[nghbrId]) continue;
3109 if(flag[nghbrId] == accepted) continue;
3110 if(!isFirstLayerHalo[nghbrId] && !isStartCell[nghbrId]) { // for halos a new value can't be computed!
3111 a_levelSetValuesMb(nghbrId, 0) = CalculateLSV(nghbrId, flag);
3112 }
3113 approximateLSV.insert(make_pair(a_levelSetValuesMb(nghbrId, 0), nghbrId));
3114 flag[nghbrId] = band; // halo cells may be included in the narrow band!
3115 }
3116 }
3117 }
3118
3119 MBool somethingOnBoundaryChanged = true;
3120 MInt count = 0;
3121 while(somethingOnBoundaryChanged) {
3122 count++;
3123 somethingOnBoundaryChanged = false;
3124 MFloatScratchSpace oldLVS(a_noCells(), AT_, "oldLVS");
3125 for(MInt cellId = 0; cellId < a_noCells(); cellId++)
3126 oldLVS[cellId] = a_levelSetValuesMb(cellId, 0);
3127
3128 // main loop of the algorithm: take the cell with the smallest approximate value out of the band, update its
3129 // neighbors and put them into the band if necessary
3130 while(!approximateLSV.empty()) {
3131 multimap<MFloat, MInt>::iterator it = approximateLSV.begin();
3132 MInt cellId = it->second;
3133 approximateLSV.erase(it);
3134 if(flag[cellId] == accepted) continue;
3135 flag[cellId] = accepted;
3136 for(MInt direction = 0; direction < (m_noDirs); direction++) {
3137 for(MInt j = m_identNghbrIds[2 * cellId * nDim + direction];
3138 j < m_identNghbrIds[2 * cellId * nDim + direction + 1];
3139 j++) {
3140 MInt nghbrId = m_storeNghbrIds[j];
3141 if(isFarHalo[nghbrId]) continue;
3142 if(flag[nghbrId] == accepted) continue;
3143 if(!isFirstLayerHalo[nghbrId]
3144 && !isStartCell[nghbrId]) { // for halos and start cells a new value can't be computed!
3145 a_levelSetValuesMb(nghbrId, 0) = CalculateLSV(nghbrId, flag);
3146 }
3147 approximateLSV.insert(make_pair(a_levelSetValuesMb(nghbrId, 0), nghbrId));
3148 flag[nghbrId] = band; // halo cells may be included in the narrow band!
3149 }
3150 }
3151 }
3152
3153 // compute changes in the field after main loop
3154 MFloat change = F0;
3155 MInt noCells = 0;
3156 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3157 if(isFirstLayerHalo[cellId] || isFarHalo[cellId]) continue;
3158 if(c_noChildren(cellId) > 0) continue;
3159 MFloat tmpChange =
3160 (a_levelSetValuesMb(cellId, 0) - oldLVS[cellId]) * (a_levelSetValuesMb(cellId, 0) - oldLVS[cellId]);
3161 if(tmpChange > F0) {
3162 change += tmpChange;
3163 noCells++;
3164 }
3165 }
3166 if(noCells > 0) change = sqrt(change) / noCells;
3167
3168 // special part for parallel execution
3169 if(noNeighborDomains() > 0) {
3170 // exchange values of halo cells
3171 MBoolScratchSpace valueChanged(a_noCells(), AT_, "valueChanged");
3172 MInt sendCount = 0;
3173 MInt receiveCount = 0;
3174 for(MInt i = 0; i < noNeighborDomains(); i++) {
3175 sendCount += (signed)noWindowCells(i);
3176 receiveCount += (signed)noHaloCells(i);
3177 }
3178 ScratchSpace<MFloat> sendBuffer(sendCount, AT_, "sendBuffer");
3179 ScratchSpace<MFloat> receiveBuffer(receiveCount, AT_, "receiveBuffer");
3180
3181 // 1. gather
3182 sendCount = 0;
3183 for(MInt i = 0; i < noNeighborDomains(); i++) {
3184 for(MInt j = 0; j < (signed)noWindowCells(i); j++) {
3185 sendBuffer.p[sendCount] = a_levelSetValuesMb(windowCellId(i, j), 0);
3186 sendCount++;
3187 }
3188 }
3189 // 2. send
3190 sendCount = 0;
3191 for(MInt i = 0; i < noNeighborDomains(); i++) {
3192 MInt bufSize = (signed)noWindowCells(i);
3193 MPI_Issend(&(sendBuffer.p[sendCount]), bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &g_mpiRequestMb[i],
3194 AT_, "(sendBuffer.p[sendCount])");
3195 sendCount += noWindowCells(i);
3196 }
3197 // 3. receive
3198 MPI_Status status;
3199 receiveCount = 0;
3200 for(MInt i = 0; i < noNeighborDomains(); i++) {
3201 MInt bufSize = (signed)noHaloCells(i);
3202 MPI_Recv(&(receiveBuffer.p[receiveCount]), bufSize, MPI_DOUBLE, neighborDomain(i), 0, mpiComm(), &status, AT_,
3203 "(receiveBuffer.p[ receiveCount ])");
3204 receiveCount += noHaloCells(i);
3205 }
3206 for(MInt i = 0; i < noNeighborDomains(); i++) {
3207 MPI_Wait(&g_mpiRequestMb[i], &status, AT_);
3208 }
3209
3210 // 4. scatter
3211 receiveCount = 0;
3212 for(MInt i = 0; i < noNeighborDomains(); i++) {
3213 for(MInt j = 0; j < (signed)noHaloCells(i); j++) {
3214 MInt cellId = haloCellId(i, j);
3215 valueChanged[cellId] = false;
3216 if(abs(a_levelSetValuesMb(cellId, 0) - receiveBuffer.p[receiveCount]) > eps) {
3217 valueChanged[cellId] = true;
3218 }
3219 a_levelSetValuesMb(cellId, 0) = receiveBuffer.p[receiveCount];
3220 receiveCount++;
3221 }
3222 }
3223
3224 // check if halo acts as a source for at least one close halo cell
3225 MBoolScratchSpace isSource(firstLayerHaloCount, AT_, "isSource");
3226 for(MInt hc = 0; hc < firstLayerHaloCount; hc++) {
3227 isSource[hc] = false;
3228 MInt haloId = firstLayerHalos[hc];
3229 for(MInt direction = 0; direction < (2 * nDim); direction++) {
3230 for(MInt j = m_identNghbrIds[2 * haloId * nDim + direction];
3231 j < m_identNghbrIds[2 * haloId * nDim + direction + 1];
3232 j++) {
3233 MInt nghbrId = m_storeNghbrIds[j];
3234 if(!isFarHalo[nghbrId] && !isFirstLayerHalo[nghbrId]
3235 && !isStartCell[nghbrId]) { // nghbr is internal cell and not start cell
3236 if(a_levelSetValuesMb(haloId, 0) < a_levelSetValuesMb(nghbrId, 0)) {
3237 isSource[hc] = true;
3238 }
3239 }
3240 }
3241 }
3242 }
3243
3244 // compute min val of source halos that changed their value
3245 MFloat minHaloVal = c_cellLengthAtLevel(0);
3246 for(MInt hc = 0; hc < firstLayerHaloCount; hc++) {
3247 MInt haloId = firstLayerHalos[hc];
3248 if(isSource[hc] && valueChanged[haloId]) {
3249 minHaloVal = mMin(minHaloVal, a_levelSetValuesMb(haloId, 0));
3250 somethingOnBoundaryChanged = true;
3251 }
3252 if(isSource[hc]) {
3253 flag[haloId] = band;
3254 approximateLSV.insert(make_pair(a_levelSetValuesMb(haloId, 0), haloId));
3255 } else {
3256 flag[haloId] = _far;
3257 }
3258 }
3259
3260 // exchange somethingChanged globally
3261 MIntScratchSpace globalSomethingChanged(1, AT_, "globalSomethingChanged");
3262 MIntScratchSpace somethingChangedExchange(1, AT_, "somethingChangedExchange");
3263 somethingChangedExchange[0] = somethingOnBoundaryChanged;
3264 MPI_Allreduce(somethingChangedExchange.getPointer(), globalSomethingChanged.getPointer(), 1, MPI_INT, MPI_MAX,
3265 mpiComm(), AT_, "somethingChangedExchange.getPointer()", "globalSomethingChanged.getPointer()");
3266 somethingOnBoundaryChanged = globalSomethingChanged[0];
3267
3268 // reassign flags for all cells and reset their value if necessary
3269 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3270 if(isFarHalo[cellId] || isFirstLayerHalo[cellId]) continue;
3271 if(c_noChildren(cellId) > 0) continue;
3272 if(isStartCell[cellId]) {
3273 flag[cellId] = accepted;
3274 } else if(abs(a_levelSetValuesMb(cellId, 0) - minHaloVal) < eps) {
3275 flag[cellId] = band;
3276 approximateLSV.insert(make_pair(a_levelSetValuesMb(cellId, 0), cellId));
3277 } else if(a_levelSetValuesMb(cellId, 0) < minHaloVal) {
3278 flag[cellId] = accepted;
3279 } else {
3280 flag[cellId] = _far;
3281 }
3282 }
3283 // set all neighbors of accepted cells (that are not accepted themselves) in band
3284 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3285 if(flag[cellId] != accepted) continue;
3286 for(MInt direction = 0; direction < (2 * nDim); direction++) {
3287 for(MInt j = m_identNghbrIds[2 * cellId * nDim + direction];
3288 j < m_identNghbrIds[2 * cellId * nDim + direction + 1];
3289 j++) {
3290 MInt nghbrId = m_storeNghbrIds[j];
3291 if(isFarHalo[nghbrId]) continue;
3292 if(flag[nghbrId] == _far) {
3293 flag[nghbrId] = band;
3294 approximateLSV.insert(make_pair(a_levelSetValuesMb(nghbrId, 0), nghbrId));
3295 }
3296 }
3297 }
3298 }
3299 // reset the value of all far cells to c_cellLengthAtLevel(0)
3300 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3301 if(flag[cellId] != _far) continue;
3302 if(isFarHalo[cellId] || isFirstLayerHalo[cellId]) continue;
3304 }
3305 }
3306 }
3307
3308 // make sure, parent cells have a meaningful value:
3309 for(MInt level = maxRefinementLevel() - 1; level >= maxUniformRefinementLevel(); level--) {
3310 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
3311 if(a_level(cellId) != level) continue;
3312 if(c_isLeafCell(cellId)) continue;
3313 a_levelSetValuesMb(cellId, 0) = F0;
3314 for(MInt child = 0; child < IPOW2(nDim); child++) {
3315 MInt childId = c_childId(cellId, child);
3316 if(childId > -1) a_levelSetValuesMb(cellId, 0) += a_levelSetValuesMb(childId, 0);
3317 }
3318 a_levelSetValuesMb(cellId, 0) /= c_noChildren(cellId);
3319 }
3320 }
3321
3324}
MFloat CalculateLSV(MInt, MIntScratchSpace &)
Calculate LevelSetValue with an Approximation of the Neighbours for a grid in the NarrowBand.

◆ updateLinkedCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateLinkedCells
Author
Lennart Schneiders, extension to triple-linking Tim Wegmann
Date

Definition at line 12472 of file fvmbcartesiansolverxd.cpp.

12472 {
12473 MFloat* RESTRICT cVars = (MFloat*)(&(a_variable(0, 0)));
12474 const MInt ydim = m_noCVars;
12475 const MUint noCVars = (MUint)m_noCVars;
12476
12477 MIntScratchSpace haloBufferCnts(mMax(1, noNeighborDomains()), AT_, "haloBufferCnts");
12478 MIntScratchSpace windowBufferCnts(mMax(1, noNeighborDomains()), AT_, "windowBufferCnts");
12479 MIntScratchSpace haloBufferOffsets(noNeighborDomains() + 1, AT_, "haloBufferOffsets");
12480 MIntScratchSpace windowBufferOffsets(noNeighborDomains() + 1, AT_, "windowBufferOffsets");
12481 ScratchSpace<MPI_Request> haloReq(mMax(1, noNeighborDomains()), AT_, "haloReq");
12482 ScratchSpace<MPI_Request> windowReq(mMax(1, noNeighborDomains()), AT_, "windowReq");
12483
12484 MInt haloSize = 0;
12485 MInt windowSize = 0;
12486 haloBufferCnts.fill(0);
12487 windowBufferCnts.fill(0);
12488 haloBufferOffsets.fill(0);
12489 windowBufferOffsets.fill(0);
12490
12491 for(MInt i = 0; i < noNeighborDomains(); i++) {
12492 haloBufferCnts(i) = m_noCVars * (signed)m_linkedHaloCells[i].size();
12493 windowBufferCnts(i) = m_noCVars * (signed)m_linkedWindowCells[i].size();
12494 haloBufferOffsets(i + 1) = haloBufferOffsets(i) + haloBufferCnts(i);
12495 windowBufferOffsets(i + 1) = windowBufferOffsets(i) + windowBufferCnts(i);
12496 haloSize += haloBufferCnts(i);
12497 windowSize += windowBufferCnts(i);
12498 }
12499
12500 MFloatScratchSpace haloBuffer(haloSize, AT_, "haloBuffer");
12501 MFloatScratchSpace windowBuffer(windowSize, AT_, "windowBuffer");
12502
12504
12505 haloReq.fill(MPI_REQUEST_NULL);
12506 windowReq.fill(MPI_REQUEST_NULL);
12507 for(MInt i = 0; i < noNeighborDomains(); i++) {
12508 if(m_linkedWindowCells[i].empty()) continue;
12509 for(MInt j = 0; j < (signed)m_linkedWindowCells[i].size(); j++) {
12511 MInt offset = windowBufferOffsets(i) + noCVars * j;
12512 for(MInt v = 0; v < (signed)noCVars; v++) {
12513 windowBuffer(offset + v) = a_variable(cellId, v);
12514 }
12515 }
12516 }
12517 MInt windowCnt = 0;
12518 MInt haloCnt = 0;
12519 if(m_nonBlockingComm) {
12520 for(MInt i = 0; i < noNeighborDomains(); i++) {
12521 if(haloBufferCnts(i) == 0) continue;
12522 MPI_Irecv(&haloBuffer[haloBufferOffsets[i]], haloBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 23, mpiComm(),
12523 &haloReq[haloCnt], AT_, "haloBuffer[haloBufferOffsets[i]]");
12524 haloCnt++;
12525 }
12526 for(MInt i = 0; i < noNeighborDomains(); i++) {
12527 if(windowBufferCnts(i) == 0) continue;
12528 MPI_Isend(&windowBuffer[windowBufferOffsets[i]], windowBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 23,
12529 mpiComm(), &windowReq[windowCnt], AT_, "windowBuffer[windowBufferOffsets[i]]");
12530 windowCnt++;
12531 }
12532 if(haloCnt > 0) MPI_Waitall(haloCnt, &haloReq[0], MPI_STATUSES_IGNORE, AT_);
12533 } else {
12534 for(MInt i = 0; i < noNeighborDomains(); i++) {
12535 if(windowBufferCnts(i) == 0) continue;
12536 MPI_Issend(&windowBuffer[windowBufferOffsets[i]], windowBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 23,
12537 mpiComm(), &windowReq[windowCnt], AT_, "windowBuffer[windowBufferOffsets[i]]");
12538 windowCnt++;
12539 }
12540 for(MInt i = 0; i < noNeighborDomains(); i++) {
12541 if(haloBufferCnts(i) == 0) continue;
12542 MPI_Recv(&haloBuffer[haloBufferOffsets[i]], haloBufferCnts(i), MPI_DOUBLE, neighborDomain(i), 23, mpiComm(),
12543 MPI_STATUS_IGNORE, AT_, "haloBuffer[haloBufferOffsets[i]]");
12544 haloCnt++;
12545 }
12546 }
12547 for(MInt i = 0; i < noNeighborDomains(); i++) {
12548 if(m_linkedHaloCells[i].empty()) continue;
12549 for(MInt j = 0; j < (signed)m_linkedHaloCells[i].size(); j++) {
12551 MInt offset = haloBufferOffsets(i) + noCVars * j;
12552 for(MInt v = 0; v < (signed)noCVars; v++) {
12553 a_variable(cellId, v) = haloBuffer(offset + v);
12554 }
12555 }
12556 }
12557 if(windowCnt > 0) MPI_Waitall(windowCnt, &windowReq[0], MPI_STATUSES_IGNORE, AT_);
12558
12559 if(grid().azimuthalPeriodicity()) {
12562 }
12563
12564 for(MUint it = 0; it < m_temporarilyLinkedCells.size(); it++) {
12565 const MInt cellId = get<0>(m_temporarilyLinkedCells[it]);
12566 const MInt masterId = get<1>(m_temporarilyLinkedCells[it]);
12567 const MInt tripleLink = get<2>(m_temporarilyLinkedCells[it]);
12568 if(tripleLink < 0) {
12569 const MFloat fac0 = a_cellVolume(cellId) / (a_cellVolume(cellId) + a_cellVolume(masterId));
12570 const MFloat fac1 = F1 - fac0;
12571 if(false && m_RKStep == 0) {
12572 for(MInt v = 0; v < m_noCVars; v++) {
12573 const MFloat var = fac1 * cVars[ydim * masterId + v];
12574 cVars[ydim * cellId + v] = var;
12575 cVars[ydim * masterId + v] = var;
12576 }
12577 } else {
12578 for(MInt v = 0; v < m_noCVars; v++) {
12579 // If two emerged cells share the same master cell, this formulation is incorrect!
12580 // If the order of the cells changes, e.g., when during DLB one of the cells becomes a halo cell, this even
12581 // results in different solutions.
12582 const MFloat var = fac0 * cVars[ydim * cellId + v] + fac1 * cVars[ydim * masterId + v];
12583 cVars[ydim * cellId + v] = var;
12584 cVars[ydim * masterId + v] = var;
12585 }
12586
12587 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) {
12588 vector<MInt>::iterator it0 = find(m_splitCells.begin(), m_splitCells.end(), cellId);
12589 if(it0 == m_splitCells.end()) mTerm(1, AT_, "split cells inconsistency.");
12590 const MInt pos = distance(m_splitCells.begin(), it0);
12591 ASSERT(m_splitCells[pos] == cellId, "");
12592 for(MUint s = 0; s < m_splitChilds[pos].size(); s++) {
12593 MInt splitChildId = m_splitChilds[pos][s];
12594 for(MInt v = 0; v < m_noCVars; v++) {
12595 cVars[ydim * splitChildId + v] = cVars[ydim * cellId + v];
12596 }
12597 }
12598 }
12599 if(a_hasProperty(masterId, SolverCell::IsSplitCell)) {
12600 vector<MInt>::iterator it0 = find(m_splitCells.begin(), m_splitCells.end(), masterId);
12601 if(it0 == m_splitCells.end()) mTerm(1, AT_, "split cells inconsistency.");
12602 const MInt pos = distance(m_splitCells.begin(), it0);
12603 ASSERT(m_splitCells[pos] == masterId, "");
12604 for(MUint s = 0; s < m_splitChilds[pos].size(); s++) {
12605 MInt splitChildId = m_splitChilds[pos][s];
12606 for(MInt v = 0; v < m_noCVars; v++) {
12607 cVars[ydim * splitChildId + v] = cVars[ydim * masterId + v];
12608 }
12609 }
12610 }
12611 }
12612 } else {
12613 // triple-Links
12614 const MFloat fac0 =
12615 a_cellVolume(cellId) / (a_cellVolume(cellId) + a_cellVolume(tripleLink) + a_cellVolume(masterId));
12616 const MFloat fac1 =
12617 a_cellVolume(tripleLink) / (a_cellVolume(cellId) + a_cellVolume(tripleLink) + a_cellVolume(masterId));
12618 const MFloat fac2 = F1 - fac0 - fac1;
12619
12620 for(MInt v = 0; v < m_noCVars; v++) {
12621 const MFloat var =
12622 fac0 * cVars[ydim * cellId + v] + fac1 * cVars[ydim * tripleLink + v] + fac2 * cVars[ydim * tripleLink + v];
12623 cVars[ydim * cellId + v] = var;
12624 cVars[ydim * tripleLink + v] = var;
12625 cVars[ydim * masterId + v] = var;
12626 }
12627
12628 if(a_hasProperty(cellId, SolverCell::IsSplitCell)) {
12629 vector<MInt>::iterator it0 = find(m_splitCells.begin(), m_splitCells.end(), cellId);
12630 if(it0 == m_splitCells.end()) mTerm(1, AT_, "split cells inconsistency.");
12631 const MInt pos = distance(m_splitCells.begin(), it0);
12632 ASSERT(m_splitCells[pos] == cellId, "");
12633 for(MUint s = 0; s < m_splitChilds[pos].size(); s++) {
12634 MInt splitChildId = m_splitChilds[pos][s];
12635 for(MInt v = 0; v < m_noCVars; v++) {
12636 cVars[ydim * splitChildId + v] = cVars[ydim * cellId + v];
12637 }
12638 }
12639 }
12640 if(a_hasProperty(masterId, SolverCell::IsSplitCell)) {
12641 vector<MInt>::iterator it0 = find(m_splitCells.begin(), m_splitCells.end(), masterId);
12642 if(it0 == m_splitCells.end()) mTerm(1, AT_, "split cells inconsistency.");
12643 const MInt pos = distance(m_splitCells.begin(), it0);
12644 ASSERT(m_splitCells[pos] == masterId, "");
12645 for(MUint s = 0; s < m_splitChilds[pos].size(); s++) {
12646 MInt splitChildId = m_splitChilds[pos][s];
12647 for(MInt v = 0; v < m_noCVars; v++) {
12648 cVars[ydim * splitChildId + v] = cVars[ydim * masterId + v];
12649 }
12650 }
12651 }
12652 if(a_hasProperty(tripleLink, SolverCell::IsSplitCell)) {
12653 vector<MInt>::iterator it0 = find(m_splitCells.begin(), m_splitCells.end(), tripleLink);
12654 if(it0 == m_splitCells.end()) mTerm(1, AT_, "split cells inconsistency.");
12655 const MInt pos = distance(m_splitCells.begin(), it0);
12656 ASSERT(m_splitCells[pos] == tripleLink, "");
12657 for(MUint s = 0; s < m_splitChilds[pos].size(); s++) {
12658 MInt splitChildId = m_splitChilds[pos][s];
12659 for(MInt v = 0; v < m_noCVars; v++) {
12660 cVars[ydim * splitChildId + v] = cVars[ydim * tripleLink + v];
12661 }
12662 }
12663 }
12664 }
12665 }
12666}
void updateSplitParentVariables() override
void exchangeLinkedHaloCellsForAzimuthalReconstruction()
Create exchange for all window/halo cells which are used for the azimuthal periodic interpolation.

◆ updateMultiSolverInformation()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateMultiSolverInformation ( MBool  fullReset = false)
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 11806 of file fvmbcartesiansolverxd.cpp.

11806 {
11807 if(noNeighborDomains() == 0) {
11808 if(noDomains() > 1) mTerm(1, AT_, "Unexpected situation in updateMultiSolverInformation");
11809 return;
11810 }
11811
11812 if(fullReset) {
11818 mAlloc(g_mpiRequestMb, noNeighborDomains(), "g_mpiRequestMb", MPI_REQ_NULL, AT_);
11819 mAlloc(m_linkedWindowCells, noNeighborDomains(), "m_linkedWindowCells", AT_);
11820 mAlloc(m_linkedHaloCells, noNeighborDomains(), "m_linkedHaloCells", AT_);
11821 mAlloc(m_gapWindowCells, noNeighborDomains(), "m_gapWindowCells", AT_);
11822 mAlloc(m_gapHaloCells, noNeighborDomains(), "m_gapHaloCells", AT_);
11823 }
11824
11826}
virtual void updateMultiSolverInformation(MBool fullReset=false)

◆ updateSplitParentVariables()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateSplitParentVariables
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 2154 of file fvmbcartesiansolverxd.cpp.

2154 {
2155 for(MUint sc = 0; sc < m_splitCells.size(); sc++) {
2156 const MInt cellId = m_splitCells[sc];
2157 MFloat volCnt = F0;
2158
2159 for(MInt v = 0; v < m_noCVars; v++) {
2160 a_variable(cellId, v) = F0;
2161 }
2162
2163 for(MInt v = 0; v < m_noFVars; v++) {
2164 a_rightHandSide(cellId, v) = F0;
2165 m_rhs0[cellId][v] = F0;
2166 }
2167
2168 for(MUint ssc = 0; ssc < m_splitChilds[sc].size(); ssc++) {
2169 const MInt splitChildId = m_splitChilds[sc][ssc];
2170 for(MInt v = 0; v < m_noCVars; v++) {
2171 a_variable(cellId, v) += a_cellVolume(splitChildId) * a_variable(splitChildId, v);
2172 }
2173
2174 for(MInt v = 0; v < m_noFVars; v++) {
2175 a_rightHandSide(cellId, v) += a_rightHandSide(splitChildId, v);
2176 m_rhs0[cellId][v] += m_rhs0[splitChildId][v];
2177 }
2178 volCnt += a_cellVolume(splitChildId);
2179 }
2180 volCnt = mMax(volCnt, m_eps);
2181
2182 for(MInt v = 0; v < m_noCVars; v++) {
2183 a_variable(cellId, v) /= volCnt;
2184 }
2185 }
2186
2188 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
2189 if(a_bndryId(cellId) != -1) continue;
2190 if(a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
2191 if(c_isLeafCell(cellId)) continue;
2192
2193 if(a_level(cellId) == minLevel()) {
2194 reduceData(cellId, &a_pvariable(0, 0), m_noPVars);
2195 reduceData(cellId, &a_variable(0, 0), m_noCVars);
2196 }
2197 }
2198 }
2199}

◆ updateSpongeLayer()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateSpongeLayer ( )
overridevirtual

◆ updateViscousFluxComputation()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::updateViscousFluxComputation
Author
Lennart Schneiders

Definition at line 18219 of file fvmbcartesiansolverxd.cpp.

18219 {
18220 TRACE();
18221
18222 const MInt noSrfcs = a_noSurfaces();
18223 MInt nghbrCells[2];
18224 MFloat eps = 1e-10;
18225 MFloat totalDistance, distance;
18226 MFloat factor0, factor1;
18227 MFloat coords[2][nDim];
18228 MInt srfcId;
18229
18230 // compute the factors 0 and 1 for all surfaces
18231 // for( srfcId = m_initialSurfacesOffset; srfcId < noSrfcs; srfcId++ ) {
18232 for(srfcId = m_bndrySurfacesOffset; srfcId < noSrfcs; srfcId++) {
18233 nghbrCells[0] = a_surfaceNghbrCellId(srfcId, 0);
18234 nghbrCells[1] = a_surfaceNghbrCellId(srfcId, 1);
18235 distance = F0;
18236 totalDistance = F0;
18237
18238 for(MInt i = 0; i < nDim; i++) {
18239 coords[0][i] = a_coordinate(nghbrCells[0], i);
18240 coords[1][i] = a_coordinate(nghbrCells[1], i);
18241 }
18242
18243 for(MInt i = 0; i < nDim; i++) {
18244 distance += POW2(a_surfaceCoordinate(srfcId, i) - coords[0][i]);
18245 totalDistance += POW2(a_surfaceCoordinate(srfcId, i) - coords[1][i]);
18246 }
18247 distance = sqrt(distance);
18248 totalDistance = sqrt(totalDistance) + distance;
18249 factor1 = distance / mMax(eps, totalDistance);
18250 factor0 = F1 - factor1;
18251 a_surfaceFactor(srfcId, 0) = factor0;
18252 a_surfaceFactor(srfcId, 1) = factor1;
18253 }
18254
18255
18256 for(MInt bs = 0; bs < m_fvBndryCnd->m_noBoundarySurfaces; bs++) {
18257 srfcId = m_fvBndryCnd->m_boundarySurfaces[bs];
18258 if(a_surfaceBndryCndId(srfcId) != m_movingBndryCndId) continue;
18259
18260 a_surfaceFactor(srfcId, 0) = F1B2;
18261 a_surfaceFactor(srfcId, 1) = F1B2;
18262 }
18263}

◆ writeCenterLineVel()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeCenterLineVel ( const MChar fileName)
Author
Lennart Schneiders

Definition at line 19696 of file fvmbcartesiansolverxd.cpp.

19696 {
19697 TRACE();
19698
19699 if(noDomains() > 1) {
19700 const MFloat Y0 = F1B2 * (m_bbox[4] + m_bbox[1]);
19702 const MInt bodyId = 0;
19703 const MInt noPoints = (MInt)((m_bbox[3] - m_bbox[0]) / DX);
19704 const MInt noAngles = (MInt)(m_bodyDiameter[bodyId] / DX);
19705 const MFloat DA = PI / ((MFloat)noAngles);
19706
19707 ScratchSpace<MFloat> lineData(noPoints, m_noPVars, AT_, "lineData");
19708 ScratchSpace<MFloat> lineCoords(noPoints, nDim, AT_, "lineCoords");
19709 ScratchSpace<MFloat> lineCnt(noPoints, AT_, "lineCnt");
19710 ScratchSpace<MFloat> angleData(noAngles, 3, AT_, "angleData");
19711 ScratchSpace<MFloat> angleCnt(noAngles, AT_, "angleCnt");
19712
19713 lineData.fill(F0);
19714 lineCoords.fill(F0);
19715 lineCnt.fill(F0);
19716 angleData.fill(F0);
19717 angleCnt.fill(F0);
19718 MFloat TfluidMean = F0;
19719 MFloat meanBodyTemp = F0;
19720
19721 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
19722 if(a_isBndryGhostCell(cellId)) continue;
19723 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19724 if(a_isHalo(cellId)) continue;
19725 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19726
19727 MBool isInside = false;
19728 IF_CONSTEXPR(nDim == 2) {
19729 if(fabs(a_coordinate(cellId, 1) - Y0) < c_cellLengthAtCell(cellId)) {
19730 isInside = true;
19731 }
19732 }
19733 IF_CONSTEXPR(nDim == 3) {
19734 const MFloat Z0 = F1B2 * (m_bbox[5] + m_bbox[2]);
19735 if(fabs(a_coordinate(cellId, 1) - Y0) < c_cellLengthAtCell(cellId)
19736 && fabs(a_coordinate(cellId, 2) - Z0) < c_cellLengthAtCell(cellId)) {
19737 isInside = true;
19738 }
19739 }
19740
19741 if(isInside) {
19742 if(fabs(a_coordinate(cellId, 1) - Y0) < c_cellLengthAtCell(cellId)) {
19743 MInt id = (MInt)((a_coordinate(cellId, 0) - m_bbox[0]) / DX);
19744 if(id < 0 || id >= noPoints) {
19745 continue;
19746 // mTerm(1,AT_, "index out of range (line data).");
19747 }
19748 for(MInt i = 0; i < nDim; i++)
19749 lineCoords(id, i) += a_coordinate(cellId, i);
19750 for(MInt i = 0; i < nDim; i++)
19751 lineData(id, i) += a_pvariable(cellId, PV->VV[i]) / m_UInfinity;
19752 lineData(id, nDim) += a_pvariable(cellId, PV->P) / m_PInfinity;
19753 lineData(id, nDim + 1) += a_pvariable(cellId, PV->RHO) / m_rhoInfinity;
19754 lineCnt(id) += F1;
19755 }
19756 }
19757 }
19758
19759 for(MInt bndryId = m_noOuterBndryCells; bndryId < m_fvBndryCnd->m_bndryCells->size(); bndryId++) {
19760 MInt cellId = m_fvBndryCnd->m_bndryCells->a[bndryId].m_cellId;
19761 if(a_isHalo(cellId)) continue;
19762 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
19763 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0] != bodyId) continue;
19764 MFloat dx =
19765 m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[0] - m_bodyCenter[bodyId * nDim];
19766 // if ( fabs(m_fvBndryCnd->m_bndryCells->a[ bndryId ].m_srfcs[srfc]->m_coordinates[2]) > 0.8*DX ) continue;
19767 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area < 0.001 * m_gridCellArea[maxRefinementLevel()])
19768 continue;
19769 MFloat dr = F0;
19770 IF_CONSTEXPR(nDim == 2) {
19771 dr = sqrt(POW2(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[1]
19772 - m_bodyCenter[bodyId * nDim + 1]));
19773 }
19774 else IF_CONSTEXPR(nDim == 3) {
19775 dr = sqrt(POW2(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[1]
19776 - m_bodyCenter[bodyId * nDim + 1])
19777 + POW2(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[2]
19778 - m_bodyCenter[bodyId * nDim + 2]));
19779 }
19780 MFloat angle = atan2(dr, dx);
19781 MInt id = (MInt)(angle / DA);
19782 if(id < 0 || id >= noAngles) mTerm(1, AT_, "index out of range (angle data): " + to_string(id));
19783 MFloat rhoU2 = F0;
19784 for(MInt i = 0; i < nDim; i++) {
19785 rhoU2 += POW2(m_VVInfinity[i]);
19786 }
19787 rhoU2 *= m_rhoInfinity;
19788 MFloat rhoSurface = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO];
19789 MFloat pSurface = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P];
19790 MFloat T = sysEqn().temperature_ES(rhoSurface, pSurface);
19791 MFloat cp = (pSurface - m_PInfinity) / (F1B2 * rhoU2);
19792
19793 MFloat shear[3]{};
19794 MFloat mue = SUTHERLANDLAW(T) / sysEqn().m_Re0;
19795 for(MInt i = 0; i < nDim; i++) {
19796 MFloat grad = m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->VV[i]];
19797 shear[i] = mue * grad;
19798 }
19799
19800 MFloat cf = sqrt(POW2(shear[0]) + POW2(shear[1]) + POW2(shear[2])) / (F1B2 * rhoU2);
19801 if(m_euler) cf = (a_pvariable(cellId, PV->P) - m_PInfinity) / (F1B2 * rhoU2);
19802
19803 MFloat weight = F1;
19804 angleData(id, 0) += weight * cp;
19805 angleData(id, 1) += weight * cf;
19806 angleData(id, 2) += weight * m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
19807 angleCnt(id) += weight;
19808 }
19809 }
19810
19811 MPI_Allreduce(MPI_IN_PLACE, &lineCoords[0], noPoints * nDim, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
19812 "lineCoords[0]");
19813 MPI_Allreduce(MPI_IN_PLACE, &lineData[0], noPoints * m_noPVars, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
19814 "lineData[0]");
19815 MPI_Allreduce(MPI_IN_PLACE, &lineCnt[0], noPoints, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
19816 "lineCnt[0]");
19817 MPI_Allreduce(MPI_IN_PLACE, &angleData[0], noAngles * 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
19818 "angleData[0]");
19819 MPI_Allreduce(MPI_IN_PLACE, &angleCnt[0], noAngles, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
19820 "angleCnt[0]");
19821
19822 if(domainId() == 0) {
19823 ofstream ofl;
19824 ofl.open(fileName);
19825 if(ofl.is_open() && ofl.good()) {
19826 const MInt maxSkipCnt = IPOW2(maxRefinementLevel() - maxUniformRefinementLevel());
19827 MInt skipCnt = 0;
19828 for(MInt p = 0; p < noPoints; p++) {
19829 if(lineCnt(p) < F1) {
19830 skipCnt++;
19831 if(skipCnt == maxSkipCnt) ofl << endl;
19832 continue;
19833 }
19834 skipCnt = 0;
19835 // ofl << m_bbox[0] + ((MFloat)p)*DX + F1B2*DX;
19836 for(MInt i = 0; i < nDim; i++) {
19837 ofl << " " << lineCoords(p, i) / lineCnt(p);
19838 }
19839 for(MInt i = 0; i < m_noPVars; i++) {
19840 ofl << " " << lineData(p, i) / lineCnt(p);
19841 }
19842 ofl << " " << lineCnt(p) << endl;
19843 }
19844 ofl.close();
19845 ofl.clear();
19846 } else {
19847 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing!" << endl;
19848 }
19849 }
19850 if(domainId() == 1) {
19851 ofstream ofl;
19852 ofl.open("surfaceData");
19853 if(ofl.is_open() && ofl.good()) {
19854 for(MInt p = 0; p < noAngles; p++) {
19855 if(angleCnt(p) < 1e-10) continue;
19856 MFloat angle = PI - (((MFloat)p) * DA + F1B2 * DA);
19857 ofl << angle;
19858 ofl << " " << angleData(p, 0) / angleCnt(p);
19859 ofl << " " << angleData(p, 1) / angleCnt(p);
19860 ofl << " " << angleData(p, 2) / (angleCnt(p) * m_gridCellArea[maxRefinementLevel()]);
19861 ofl << " " << angleCnt(p) << endl;
19862 }
19863 ofl.close();
19864 ofl.clear();
19865 }
19866 if(globalTimeStep == 0) {
19867 ofl.open("surfaceTemp", ios_base::out | ios_base::trunc);
19868 ofl << "# 1:ts 2:t 3:tf 4:Tf 5:Tp" << endl;
19869 } else
19870 ofl.open("surfaceTemp", ios_base::out | ios_base::app);
19871 if(ofl.is_open() && ofl.good()) {
19872 ofl << globalTimeStep << " " << m_time << " " << m_physicalTime // <-- time (1-3)
19873 << " " << setprecision(12) << TfluidMean / m_TInfinity << " " << setprecision(12)
19874 << meanBodyTemp / m_TInfinity // (69-70)
19875 << endl;
19876 ofl.close();
19877 } else {
19878 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing!" << endl;
19879 }
19880 }
19881 } else {
19882 MInt noCells = a_noCells();
19883 // MInt cellId, counter, nghbrId;
19884 ofstream ofl;
19885 MBool centerLine, centerLine2;
19886 MFloat u, v;
19887 ScratchSpace<MFloat> cellIdList(2, noCells, AT_, "cellIdList");
19888 MFloat tmpCellId, tmpCellCoordinate;
19889
19890 MInt counter = 0;
19891 for(MInt cellId = 0; cellId < noCells; cellId++) {
19892 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19893 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19894 if(a_isBndryGhostCell(cellId)) continue;
19895 centerLine = false;
19896 centerLine2 = false;
19897
19898 if(a_coordinate(cellId, 1) >= F0 && a_hasNeighbor(cellId, 2) > 0
19899 && a_coordinate(c_neighborId(cellId, 2), 1) < F0) {
19900 centerLine = true;
19901 // nghbrId = c_neighborId( cellId , 2 );
19902 }
19903 IF_CONSTEXPR(nDim == 2) { centerLine2 = true; }
19904 IF_CONSTEXPR(nDim == 3) {
19905 if(a_coordinate(cellId, 2) >= F0 && a_hasNeighbor(cellId, 4) > 0
19906 && a_coordinate(c_neighborId(cellId, 4), 2) < F0) {
19907 centerLine2 = true;
19908 }
19909 }
19910 if(!centerLine || !centerLine2) continue;
19911
19912 cellIdList(0, counter) = (MFloat)cellId;
19913 cellIdList(1, counter) = a_coordinate(cellId, 0);
19914 counter++;
19915 }
19916
19917 for(MInt c = 0; c < counter; c++) {
19918 for(MInt d = c + 1; d < counter; d++) {
19919 if(cellIdList(1, d) < cellIdList(1, c)) {
19920 tmpCellId = cellIdList(0, c);
19921 tmpCellCoordinate = cellIdList(1, c);
19922 cellIdList(0, c) = cellIdList(0, d);
19923 cellIdList(1, c) = cellIdList(1, d);
19924 cellIdList(0, d) = tmpCellId;
19925 cellIdList(1, d) = tmpCellCoordinate;
19926 }
19927 }
19928 }
19929
19930 ofl.open(fileName);
19931 if(ofl.is_open() && ofl.good()) {
19932 for(MInt c = 0; c < counter; c++) {
19933 MInt cellId = (MInt)cellIdList(0, c);
19934
19935 u = a_variable(cellId, 0) / a_variable(cellId, CV->RHO) - a_coordinate(cellId, 1) * a_slope(cellId, PV->U, 1);
19936 v = a_variable(cellId, 1) / a_variable(cellId, CV->RHO) - a_coordinate(cellId, 1) * a_slope(cellId, PV->V, 1);
19937
19938 IF_CONSTEXPR(nDim == 3) {
19939 u -= a_coordinate(cellId, 2) * a_slope(cellId, PV->U, 2);
19940 v -= a_coordinate(cellId, 2) * a_slope(cellId, PV->V, 2);
19941 }
19942
19943 ofl << a_coordinate(cellId, 0) << " ";
19944 ofl << u / m_UInfinity << " ";
19945 ofl << v / m_UInfinity << " ";
19946 ofl << a_variable(cellId, CV->RHO) << " ";
19947 ofl << a_pvariable(cellId, PV->P) << " ";
19948 ofl << a_variable(cellId, CV->RHO) / m_rhoInfinity << " ";
19949 ofl << a_pvariable(cellId, PV->P) / m_PInfinity << " ";
19950 ofl << endl;
19951 }
19952 ofl.close();
19953 ofl.clear();
19954 } else {
19955 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing!" << endl;
19956 }
19957
19958 MFloat pavg = F0;
19959 MFloat rhoavg = F0;
19960 MFloat uavg = F0;
19961 MFloat cnt = F0;
19962 MFloat pavg2 = F0;
19963 MFloat rhoavg2 = F0;
19964 MFloat uavg2 = F0;
19965 MFloat vol = F0;
19966 MFloat vel = F0;
19967 MFloat temp = F0;
19968 MFloat xsa = F0;
19969 MFloat p0 = F0;
19970 MFloat p00 = F0;
19971 MFloat p00cnt = F0;
19972 const MFloat vs = m_Ma * (m_gamma + F1) / F4 + sqrt(POW2(m_Ma * (m_gamma + F1) / F4) + F1);
19973 const MFloat xs = F1B2 + vs * (m_physicalTime - timeStep());
19974 const MFloat xp = m_Ma * (m_physicalTime - timeStep());
19975
19976 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
19977 if(!a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19978 if(a_hasProperty(cellId, SolverCell::IsCutOff)) continue;
19979 if(a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
19980 if(a_isPeriodic(cellId)) continue;
19981 if(a_isBndryGhostCell(cellId)) continue;
19982 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19983 if(a_coordinate(cellId, 0) > xp) {
19984 xsa += a_pvariable(cellId, PV->U) * a_cellVolume(cellId);
19985 }
19986 if(a_coordinate(cellId, 0) < xp) {
19987 p0 += a_pvariable(cellId, PV->P) * a_cellVolume(cellId);
19988 if(!checkNeighborActive(cellId, 1) || a_hasNeighbor(cellId, 1) == 0) {
19989 p00 += a_pvariable(cellId, PV->P);
19990 p00cnt += F1;
19991 }
19992 }
19993 if(a_coordinate(cellId, 0) > xp && a_coordinate(cellId, 0) < xs) {
19994 vel += a_cellVolume(cellId) * a_pvariable(cellId, PV->U);
19995 temp +=
19996 a_cellVolume(cellId) * sysEqn().temperature_ES(a_pvariable(cellId, PV->RHO), a_pvariable(cellId, PV->P));
19997 vol += a_cellVolume(cellId);
19998 }
19999 if(a_coordinate(cellId, 0) < xp || a_coordinate(cellId, 0) > xp + 5.0) continue;
20000 pavg += a_pvariable(cellId, PV->P);
20001 rhoavg += a_pvariable(cellId, PV->RHO);
20002 uavg += a_pvariable(cellId, PV->U);
20003 cnt += F1;
20004 if(a_coordinate(cellId, 0) < xp || a_coordinate(cellId, 0) > xp + 2.5) continue;
20005 pavg2 += a_pvariable(cellId, PV->P);
20006 rhoavg2 += a_pvariable(cellId, PV->RHO);
20007 uavg2 += a_pvariable(cellId, PV->U);
20008 }
20009 cerr << "piston front vars: " << setprecision(14) << xp << " " << xs << " "
20010 << timeStep() * m_Ma / c_cellLengthAtLevel(maxRefinementLevel()) << " " << pavg / cnt << " " << rhoavg / cnt
20011 << " "
20012 << uavg / cnt
20013 << " " << vel / mMax(1e-14, vol) << " " << temp / mMax(1e-14, vol) << " " << xp + F1B2 + xsa / (m_Ma * 16.0)
20014 << " " << p0 / 16.0 << " " << p00 / p00cnt << endl;
20015 }
20016}

◆ writeGeometryToVtkXmlFile() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==3, _ * > >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::writeGeometryToVtkXmlFile ( const MString fileName)
Author
Lennart Schneiders

Definition at line 33694 of file fvmbcartesiansolverxd.cpp.

33694 {
33695 TRACE();
33696
33697 ofstream ofl;
33698 ofl.open(fileName.c_str());
33699
33700 if(ofl.is_open() && ofl.good()) {
33701 ofl << "<?xml version=\"1.0\"?>" << endl;
33702 ofl << R"(<VTKFile type="PolyData" version="0.1")" << endl;
33703 ofl << "<PolyData>" << endl;
33704 ofl << "<Piece NumberOfPoints=\"" << 0 << "\" NumberOfCells=\"" << 0 << "\">" << endl;
33705 ofl << "</Piece>" << endl;
33706 ofl << "</PolyData>" << endl;
33707 ofl << "</VTKFile>" << endl;
33708 ofl.close();
33709 ofl.clear();
33710 return 0;
33711 }
33712 return 0;
33713}

◆ writeGeometryToVtkXmlFile() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
static MInt FvMbCartesianSolverXD< nDim, SysEqn >::writeGeometryToVtkXmlFile ( const MString fileName)
static

◆ writeListOfActiveFlowCells()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeListOfActiveFlowCells
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 1446 of file fvmbcartesiansolverxd.cpp.

1446 {
1447 TRACE();
1448
1449 // 1. update collector sizes
1452 m_noBndryCells = m_fvBndryCnd->m_bndryCells->size();
1453
1454 // 2. set active cells
1455 const MInt noAllCells = a_noCells();
1456
1457 m_noActiveCells = 0;
1458 for(MInt cellId = 0; cellId < noInternalCells(); cellId++) {
1459 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
1462 }
1463 }
1464
1466 for(MInt cellId = noInternalCells(); cellId < noAllCells; cellId++) {
1467 if(a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
1470 }
1471 }
1472
1473 // 3. log statistics
1474 logOutput();
1475}
void logOutput()
logs several collector sizes

◆ writeStencil()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeStencil ( const MInt  bndryId)
Author
Lennart Schneiders

Definition at line 26148 of file fvmbcartesiansolverxd.cpp.

26148 {
26149 TRACE();
26150
26151#ifdef DOUBLE_PRECISION_OUTPUT
26152 const char* const dataType = "Float64";
26153#else
26154 const char* const dataType = "Float32";
26155#endif
26156 const char* const iDataType = "Int32";
26157 const char* const uIDataType = "UInt32";
26158
26159 const MString fileName = "stencil_b" + to_string(bndryId) + "_D" + to_string(domainId()) + ".vtp";
26160 const MUint noPoints = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size();
26161 const MUint noLines = noPoints - 1;
26162 const MUint noSrfcs = m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs;
26163 const MUint noRecNghbrs = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds.size();
26164 for(MInt srfc = 0; srfc < mMin((signed)noRecNghbrs, (signed)noSrfcs); srfc++) {
26165 for(MInt v = 0; v < m_noPVars; v++) {
26166 a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[srfc], v) =
26167 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v];
26168 }
26169 }
26170
26171 ofstream ofl;
26172 ofl.open(fileName.c_str(), ios_base::out | ios_base::trunc);
26173
26174 if(ofl.is_open() && ofl.good()) {
26175 // VTKFile
26176 ofl << "<?xml version=\"1.0\"?>" << endl;
26177 ofl << "<VTKFile type=\"PolyData\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
26178 ofl << "<PolyData>" << endl;
26179
26180 // Dimensions
26181 ofl << "<Piece NumberOfPoints=\"" << noPoints << "\" NumberOfVerts=\"" << 1 << "\" NumberOfLines=\"" << noLines
26182 << "\">" << endl;
26183
26184 // Points
26185 ofl << "<Points>" << endl;
26186 ofl << "<DataArray type=\"" << dataType << "\" NumberOfComponents=\"3\" format=\"ascii\">" << endl;
26187 for(MInt i = 0; i < nDim; i++) {
26188 ofl << a_coordinate(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[noSrfcs], i) << " ";
26189 }
26190 IF_CONSTEXPR(nDim == 2) ofl << "0.0 ";
26191 ofl << endl;
26192 for(MUint srfc = 0; srfc < noSrfcs; srfc++) {
26193 for(MInt i = 0; i < nDim; i++) {
26194 ofl << a_coordinate(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId, i) << " ";
26195 }
26196 IF_CONSTEXPR(nDim == 2) ofl << "0.0 ";
26197 ofl << endl;
26198 }
26199 for(MUint n = noSrfcs + 1; n < noPoints; n++) {
26200 MInt nghbrId = m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n];
26201 for(MInt i = 0; i < nDim; i++) {
26202 ofl << a_coordinate(nghbrId, i) << " ";
26203 }
26204 IF_CONSTEXPR(nDim == 2) ofl << "0.0 ";
26205 ofl << endl;
26206 }
26207 ofl << "</DataArray>" << endl;
26208 ofl << "</Points>" << endl;
26209
26210 // Verts
26211 ofl << "<Verts>" << endl;
26212 ofl << "<DataArray type=\"" << iDataType << "\" Name=\"connectivity\" format=\"ascii\">" << endl;
26213 ofl << "0" << endl;
26214 ofl << "</DataArray>" << endl;
26215 ofl << "<DataArray type=\"" << uIDataType << "\" Name=\"offsets\" format=\"ascii\">" << endl;
26216 ofl << "1" << endl;
26217 ofl << "</DataArray>" << endl;
26218 ofl << "</Verts>" << endl;
26219
26220 // Lines
26221 ofl << "<Lines>" << endl;
26222 ofl << "<DataArray type=\"" << iDataType << "\" Name=\"connectivity\" format=\"ascii\">" << endl;
26223 for(MUint n = 0; n < noLines; n++) {
26224 ofl << "0 " << n + 1 << " ";
26225 }
26226 ofl << endl;
26227 ofl << "</DataArray>" << endl;
26228 ofl << "<DataArray type=\"" << uIDataType << "\" Name=\"offsets\" format=\"ascii\">" << endl;
26229 for(MUint n = 0; n < noLines; n++) {
26230 ofl << 2 * (n + 1) << " ";
26231 }
26232 ofl << endl;
26233 ofl << "</DataArray>" << endl;
26234 ofl << "</Lines>" << endl;
26235
26236 // CellData
26237 ofl << "<CellData Scalars=\"scalars\">" << endl;
26238
26239 ofl << "<DataArray type=\"" << dataType << "\" Name=\"weights0\" format=\"ascii\">" << endl;
26240 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * noSrfcs] << " ";
26241 for(MUint srfc = 0; srfc < noSrfcs; srfc++)
26242 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * srfc] << " ";
26243 for(MUint n = noSrfcs + 1; n < noPoints; n++)
26244 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * n] << " ";
26245 ofl << endl;
26246 ofl << "</DataArray>" << endl;
26247
26248 ofl << "<DataArray type=\"" << dataType << "\" Name=\"weights1\" format=\"ascii\">" << endl;
26249 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * noSrfcs + IPOW2(noSrfcs) - 1] << " ";
26250 for(MUint srfc = 0; srfc < noSrfcs; srfc++)
26251 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * srfc + IPOW2(noSrfcs) - 1] << " ";
26252 for(MUint n = noSrfcs + 1; n < noPoints; n++)
26253 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * n + IPOW2(noSrfcs) - 1] << " ";
26254 ofl << endl;
26255 ofl << "</DataArray>" << endl;
26256
26257 ofl << "<DataArray type=\"" << dataType << "\" Name=\"weights\" format=\"ascii\">" << endl;
26258 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_imagePointRecConst[noSrfcs] << " ";
26259 for(MUint n = 0; n < noSrfcs; n++)
26260 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_imagePointRecConst[n] << " ";
26261 for(MUint n = noSrfcs + 1; n < noPoints; n++)
26262 ofl << m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_imagePointRecConst[n] << " ";
26263 ofl << endl;
26264 ofl << "</DataArray>" << endl;
26265
26266 ofl << "<DataArray type=\"" << dataType << "\" Name=\"u\" format=\"ascii\">" << endl;
26267 ofl << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[noSrfcs], PV->U) << " ";
26268 for(MUint n = 0; n < noSrfcs; n++)
26269 ofl << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->U) << " ";
26270 for(MUint n = noSrfcs + 1; n < noPoints; n++)
26271 ofl << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->U) << " ";
26272 ofl << endl;
26273 ofl << "</DataArray>" << endl;
26274
26275 ofl << "<DataArray type=\"" << dataType << "\" Name=\"v\" format=\"ascii\">" << endl;
26276 ofl << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[noSrfcs], PV->V) << " ";
26277 for(MUint n = 0; n < noSrfcs; n++)
26278 ofl << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->V) << " ";
26279 for(MUint n = noSrfcs + 1; n < noPoints; n++)
26280 ofl << a_pvariable(m_fvBndryCnd->m_bndryCell[bndryId].m_recNghbrIds[n], PV->V) << " ";
26281 ofl << endl;
26282 ofl << "</DataArray>" << endl;
26283
26284 ofl << "<DataArray type=\"" << iDataType << "\" Name=\"id\" format=\"ascii\">" << endl;
26285 ofl << noSrfcs << " ";
26286 for(MUint n = 0; n < noSrfcs; n++)
26287 ofl << n << " ";
26288 for(MUint n = noSrfcs + 1; n < noPoints; n++)
26289 ofl << n << " ";
26290 ofl << endl;
26291 ofl << "</DataArray>" << endl;
26292 ofl << "</CellData>" << endl;
26293
26294 ofl << "</Piece>" << endl;
26295 ofl << "</PolyData>" << endl;
26296
26297 ofl << "</VTKFile>" << endl;
26298 ofl.close();
26299 ofl.clear();
26300 } else {
26301 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing! (3)" << endl;
26302 }
26303}

◆ writeVtkDebug()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVtkDebug ( const MString  suffix)
Author

Definition at line 15829 of file fvmbcartesiansolverxd.cpp.

15829 {
15830 TRACE();
15831
15832 const MInt noCells = a_noCells();
15833 ScratchSpace<MBool> prop13(noCells, AT_, "prop13");
15834 ScratchSpace<MBool> inact(noCells, AT_, "inact");
15835 ScratchSpace<MBool> bghost(noCells, AT_, "bghost");
15836 for(MInt c = 0; c < noCells; c++) {
15837 prop13.p[c] = a_hasProperty(c, SolverCell::IsOnCurrentMGLevel);
15838 bghost.p[c] = a_isBndryGhostCell(c);
15839 inact.p[c] = a_hasProperty(c, SolverCell::IsInactive);
15840 if(c_isToDelete(c)) continue;
15841 a_hasProperty(c, SolverCell::IsOnCurrentMGLevel) = true;
15842 a_hasProperty(c, SolverCell::IsInactive) = false;
15843 if(a_isHalo(c)) {
15844 a_isBndryGhostCell(c) = false;
15845 }
15846 }
15847 const MInt haloCellOutput = m_haloCellOutput;
15848 const MInt vtuGeometryOutputExtended = m_vtuGeometryOutputExtended;
15849 const MInt vtuGlobalIdOutput = m_vtuGlobalIdOutput;
15850 const MInt vtuDomainIdOutput = m_vtuDomainIdOutput;
15851 const MInt vtuLevelSetOutput = m_vtuLevelSetOutput;
15852 const MInt vtuVelocityGradientOutput = m_vtuVelocityGradientOutput;
15853
15854 m_haloCellOutput = true;
15856 m_vtuGlobalIdOutput = true;
15857 m_vtuDomainIdOutput = true;
15858 m_vtuLevelSetOutput = false;
15860
15861 writeVtkXmlFiles("QOUT_" + suffix, "GEOM_" + suffix, 0, 0);
15862
15863 m_haloCellOutput = haloCellOutput;
15864 m_vtuGeometryOutputExtended = vtuGeometryOutputExtended;
15865 m_vtuGlobalIdOutput = vtuGlobalIdOutput;
15866 m_vtuDomainIdOutput = vtuDomainIdOutput;
15867 m_vtuLevelSetOutput = vtuLevelSetOutput;
15868 m_vtuVelocityGradientOutput = vtuVelocityGradientOutput;
15869
15870 for(MInt c = 0; c < noCells; c++) {
15871 a_hasProperty(c, SolverCell::IsOnCurrentMGLevel) = prop13.p[c];
15872 a_hasProperty(c, SolverCell::IsInactive) = inact.p[c];
15873 a_isBndryGhostCell(c) = bghost.p[c];
15874 }
15875 const MInt cellId = -1;
15876 if(domainId() == 0 && cellId > -1) {
15877 m_log << "CLOG " << globalTimeStep << " " << cellId << " " << a_level(cellId) << " " << c_noChildren(cellId)
15878 << " # " << a_isBndryGhostCell(cellId) << " " << a_isHalo(cellId) << " " << a_noCells() << " # "
15879 << a_coordinate(cellId, 0) << " " << a_coordinate(cellId, 1) << " " << a_coordinate(cellId, 2) << " # ";
15880 for(MInt dir = 0; dir < m_noDirs; dir++) {
15881 MInt cId = (c_neighborId(cellId, dir) > -1) ? m_bndryCandidateIds[c_neighborId(cellId, dir)] : -1;
15882 MInt bId = (c_neighborId(cellId, dir) > -1) ? a_isBndryGhostCell(c_neighborId(cellId, dir)) : -1;
15883 m_log << " / (" << dir << ") " << a_hasNeighbor(cellId, dir) << " " << c_neighborId(cellId, dir) << " " << cId
15884 << " " << bId;
15885 }
15886 m_log << endl;
15887 }
15888
15889
15890 ScratchSpace<MInt> noLsMbCells(noDomains(), AT_, "noLsMbCells");
15891 if(noDomains() > 1)
15892 MPI_Gather(&m_noLsMbBndryCells, 1, MPI_INT, &(noLsMbCells[0]), 1, MPI_INT, 0, mpiComm(), AT_, "m_noLsMbBndryCells",
15893 "(noLsMbCells[0])");
15894 if(domainId() == 0) {
15895 ofstream ofile(("out/QOUT_" + suffix + ".pvd").c_str(), ios_base::out | ios_base::trunc);
15896 if(ofile.is_open() && ofile.good()) {
15897 ofile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
15898 ofile << "<Collection>" << endl;
15899 for(MInt p = 0; p < noDomains(); p++) {
15900 ofile << "<DataSet part=\"" << p << "\" timestep=\"" << globalTimeStep << "\" file=\""
15901 << "./solver_data/"
15902 << "QOUT_" << suffix << "_B" << p << ".vtu\"/>" << endl;
15903 }
15904 ofile << "</Collection>" << endl;
15905 ofile << "</VTKFile>" << endl;
15906 ofile.close();
15907 ofile.clear();
15908 } else {
15909 cerr << "Error opening file out/QOUT_" << suffix << ".pvd" << endl;
15910 }
15911 ofstream ofile2(("out/GEOM_" + suffix + ".pvd").c_str(), ios_base::out | ios_base::trunc);
15912 if(ofile2.is_open() && ofile2.good()) {
15913 ofile2 << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
15914 ofile2 << "<Collection>" << endl;
15915 for(MInt p = 0; p < noDomains(); p++) {
15916 if(noLsMbCells(p) > 0) {
15917 ofile2 << "<DataSet part=\"" << p << "\" timestep=\"" << globalTimeStep << "\" file=\""
15918 << "./solver_data/"
15919 << "GEOM_" << suffix << "_B" << p << ".vtp\"/>" << endl;
15920 }
15921 }
15922 ofile2 << "</Collection>" << endl;
15923 ofile2 << "</VTKFile>" << endl;
15924 ofile2.close();
15925 ofile2.clear();
15926 } else {
15927 cerr << "Error opening file out/GEOM_" << suffix << ".pvd" << endl;
15928 }
15929 }
15930}
int MPI_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gather

◆ writeVtkErrorFile()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVtkErrorFile
Author
Lennart Schneiders

Definition at line 23733 of file fvmbcartesiansolverxd.cpp.

23733 {
23734 writeVtkXmlFiles("Q_ERR", "G_ERR", 0, 0);
23735}

◆ writeVTKFileOfCell()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVTKFileOfCell ( MInt  cellId,
const std::vector< polyEdge2D > *  edges,
const std::vector< polyVertex > *  vertices,
MInt  set 
)
private
Author

Definition at line 33733 of file fvmbcartesiansolverxd.cpp.

33734 {
33735 const MChar* fileName = "cell_";
33736 stringstream fileName2;
33737 fileName2 << fileName << cellId << "_s" << set << "_D" << domainId() << ".vtk";
33738 ofstream ofl;
33739 ofl.open((fileName2.str()).c_str(), ofstream::trunc);
33740
33741 if(ofl) {
33742 // set fixed floating point output
33743 ofl.setf(ios::fixed);
33744 ofl.precision(7);
33745
33746 ofl << "# vtk DataFile Version 3.0" << endl
33747 << "MAIAD cutsurface file" << endl
33748 << "ASCII" << endl
33749 << endl
33750 << "DATASET UNSTRUCTURED_GRID" << endl
33751 << endl;
33752
33753 ofl << "POINTS " << (*vertices).size() << " float" << endl;
33754
33755 for(MInt v = 0; (unsigned)v < (*vertices).size(); v++) {
33756 for(MInt i = 0; i < nDim; i++)
33757 ofl << (*vertices)[v].coordinates[i] << " ";
33758 ofl << F0 << " ";
33759 ofl << endl;
33760 }
33761
33762 ofl << endl;
33763 MInt numPoints = 0;
33764 MInt noEdges = (*edges).size();
33765 numPoints += noEdges * 2;
33766 ofl << "CELLS " << noEdges << " " << noEdges + numPoints << endl;
33767
33768
33769 for(MInt i = 0; i < noEdges; i++) {
33770 unsigned noVerts = 2;
33771 ofl << noVerts << " ";
33772 ofl << (*edges)[i].vertices[0] << " ";
33773 ofl << (*edges)[i].vertices[1] << " ";
33774 ofl << endl;
33775 }
33776 ofl << endl;
33777
33778 ofl << "CELL_TYPES " << noEdges << endl;
33779 for(MInt i = 0; i < noEdges; i++) {
33780 ofl << 3 << endl;
33781 }
33782
33783 ofl.close();
33784 }
33785}

◆ writeVTKFileOfCutCell()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVTKFileOfCutCell ( MInt  cellId,
std::vector< polyCutCell > *  cutCells,
const std::vector< polyEdge2D > *  edges,
const std::vector< polyVertex > *  vertices,
MInt  set 
)
private
Author

Definition at line 33794 of file fvmbcartesiansolverxd.cpp.

33796 {
33797 const MChar* fileName = "cutCell_";
33798 stringstream fileName2;
33799 fileName2 << fileName << cellId << "_s" << set << "_D" << domainId() << ".vtk";
33800 ofstream ofl;
33801 ofl.open((fileName2.str()).c_str(), ofstream::trunc);
33802
33803 if(ofl) {
33804 // set fixed floating point output
33805 ofl.setf(ios::fixed);
33806 ofl.precision(7);
33807
33808 ofl << "# vtk DataFile Version 3.0" << endl
33809 << "MAIAD cutsurface file" << endl
33810 << "ASCII" << endl
33811 << endl
33812 << "DATASET UNSTRUCTURED_GRID" << endl
33813 << endl;
33814
33815 ofl << "POINTS " << (*vertices).size() << " float" << endl;
33816
33817 for(MInt v = 0; (unsigned)v < (*vertices).size(); v++) {
33818 for(MInt i = 0; i < nDim; i++)
33819 ofl << (*vertices)[v].coordinates[i] << " ";
33820 ofl << F0 << " ";
33821 ofl << endl;
33822 }
33823
33824 ofl << endl;
33825 MInt numPoints = 0;
33826 MInt noEdges = 0;
33827 for(MInt c = 0; (unsigned)c < (*cutCells).size(); c++) {
33828 MInt noEdgesCC = (*cutCells)[c].faces_edges.size();
33829 numPoints += noEdgesCC * 2;
33830 noEdges += noEdgesCC;
33831 }
33832 ofl << "CELLS " << noEdges << " " << noEdges + numPoints << endl;
33833
33834
33835 for(MInt c = 0; (unsigned)c < (*cutCells).size(); c++) {
33836 for(MInt i = 0; (unsigned)i < (*cutCells)[c].faces_edges.size(); i++) {
33837 MInt edge = (*cutCells)[c].faces_edges[i];
33838 unsigned noVerts = 2;
33839 ofl << noVerts << " ";
33840 ofl << (*edges)[edge].vertices[0] << " ";
33841 ofl << (*edges)[edge].vertices[1] << " ";
33842 ofl << endl;
33843 }
33844 ofl << endl;
33845 }
33846 ofl << endl;
33847
33848 ofl << "CELL_TYPES " << noEdges << endl;
33849 for(MInt i = 0; i < noEdges; i++) {
33850 ofl << 3 << endl;
33851 }
33852
33853 ofl << endl;
33854 ofl << "CELL_DATA " << noEdges << endl;
33855 ofl << "FIELD FieldData " << 2 << endl;
33856 ofl << "cutCell"
33857 << " " << 1 << " " << noEdges << " "
33858 << "int" << endl;
33859 for(MInt c = 0; (unsigned)c < (*cutCells).size(); c++) {
33860 for(MInt f = 0; (unsigned)f < (*cutCells)[c].faces_edges.size(); f++) {
33861 MInt edge = (*cutCells)[c].faces_edges[f];
33862 ofl << (*edges)[edge].cutCell << " ";
33863 }
33864 }
33865 ofl << endl;
33866 ofl << "bodyId"
33867 << " " << 1 << " " << noEdges << " "
33868 << "int" << endl;
33869 for(MInt c = 0; (unsigned)c < (*cutCells).size(); c++) {
33870 for(MInt f = 0; (unsigned)f < (*cutCells)[c].faces_edges.size(); f++) {
33871 MInt edge = (*cutCells)[c].faces_edges[f];
33872 ofl << (*edges)[edge].bodyId << " ";
33873 }
33874 }
33875 ofl << endl;
33876
33877 ofl.close();
33878 }
33879}

◆ writeVtkXmlFiles()

template<MInt nDim, class SysEqn >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVtkXmlFiles ( const MString  fileName,
const MString  GFileName,
MBool  regularOutput,
MBool  diverged 
)
overridevirtual
Author
Lennart Schneiders

Reimplemented from FvCartesianSolverXD< nDim, SysEqn >.

Definition at line 23743 of file fvmbcartesiansolverxd.cpp.

23744 {
23745 TRACE();
23746
23748
23749 const MBool correctCoords = m_fvBndryCnd->m_cellCoordinatesCorrected;
23750 if(correctCoords) m_fvBndryCnd->recorrectCellCoordinates();
23751
23752 if(diverged) {
23753 m_haloCellOutput = true;
23755 m_vtuGlobalIdOutput = true;
23756 m_vtuDomainIdOutput = true;
23757 m_vtuLevelSetOutput = false;
23759 }
23761 IF_CONSTEXPR(nDim == 3) {
23762 if(true || regularOutput || noDomains() > 24) {
23767 MInt noSolverSpecificVars = (m_vtuLevelSetOutput > 0 ? 1 : 0);
23768 MFloatScratchSpace levelSetOutput((noSolverSpecificVars > 0 ? a_noCells() : 1), AT_, "levelSetOutput");
23770 noSolverSpecificVars = 1;
23771 for(MInt cellId = 0; cellId < a_noCells(); cellId++) {
23772 levelSetOutput(cellId) = a_levelSetValuesMb(cellId, 0);
23773 }
23774 }
23775 MString fName;
23776 MString gName;
23777 if(!m_multipleFvSolver) {
23778 fName = m_solutionOutput + fileName + "_00" + to_string(globalTimeStep) + ".vtu";
23779 gName = m_solutionOutput + GFileName + "_00" + to_string(globalTimeStep) + ".vtp";
23780 } else {
23781 fName = m_solutionOutput + fileName + "_s" + to_string(solverId()) + "_00" + to_string(globalTimeStep) + ".vtu";
23782 gName =
23783 m_solutionOutput + GFileName + "_s" + to_string(solverId()) + "_00" + to_string(globalTimeStep) + ".vtp";
23784 }
23786 fName = m_solutionOutput + fileName + "_diverged_00" + to_string(globalTimeStep) + ".vtu";
23787 gName = m_solutionOutput + GFileName + "_diverged_00" + to_string(globalTimeStep) + ".vtp";
23788 } else if(m_solutionDiverged) {
23789 fName = m_solutionOutput + fileName + "_s" + to_string(solverId()) + "_diverged_00" + to_string(globalTimeStep)
23790 + ".vtu";
23791 gName = m_solutionOutput + GFileName + "_s" + to_string(solverId()) + "_diverged_00" + to_string(globalTimeStep)
23792 + ".vtp";
23793 }
23794 if(domainId() == 0) {
23795 cerr << "Writing " << fName << " at time step " << globalTimeStep << "... ";
23796 }
23797
23798 VtkIo.writeVtuOutputParallel(fName.c_str(), gName.c_str(), noSolverSpecificVars, levelSetOutput);
23799
23800 cerr0 << "finished." << endl;
23801 } else {
23803 MString fName = m_solutionOutput + fileName + "_B" + to_string(domainId());
23804 MString gName = m_solutionOutput + GFileName + "_B" + to_string(domainId());
23805 if(diverged) fName += "_diverged";
23806 if(diverged) gName += "_diverged";
23807 fName += ".vtu";
23808 gName += ".vtp";
23809 cerr << endl << "Saving '" << fName << "' at time " << setprecision(6) << m_physicalTime << "...";
23810 writeVtkXmlOutput(fName.c_str(), (diverged || !regularOutput));
23811 writeGeometryToVtkXmlFile(gName.c_str());
23812 cerr << " finished." << endl;
23813 }
23814 }
23815 else {
23818
23819 stringstream QName;
23820 QName << m_solutionOutput << "solver_data/" << fileName << "_B" << domainId();
23821 if(regularOutput) QName << "_00" << globalTimeStep;
23822 if(diverged) QName << "_diverged";
23823 QName << ".vtu";
23824
23825 DEBUG_LOG("Rank " << domainId() << " saving '" << QName.str() << "' at time " << setprecision(6) << m_physicalTime
23826 << "...");
23827 if(domainId() == 0)
23828 cerr << endl << "Saving '" << QName.str() << "' at time " << setprecision(6) << m_physicalTime << "...";
23829
23830 writeVtkXmlOutput((QName.str()).c_str(), (diverged || !regularOutput));
23831
23832 DEBUG_LOG(" finished (" << domainId() << ").");
23833 cerr0 << " finished." << endl;
23834
23835
23836 MInt noPolygons = 0;
23837 ScratchSpace<MInt> noPolys2(noDomains(), AT_, "noPolys2");
23838 MInt* noPolysGlobal = noPolys2.getPointer();
23839 IF_CONSTEXPR(nDim == 3 && m_vtuWriteGeometryFile) {
23840 stringstream GName;
23841 GName << m_solutionOutput << "solver_data/" << GFileName << "_B" << domainId();
23842 if(regularOutput) GName << "_00" << globalTimeStep;
23843 if(diverged) GName << "_diverged";
23844 GName << ".vtp";
23845
23846 DEBUG_LOG("Rank " << domainId() << " saving '" << GName.str() << "' at time " << setprecision(6) << m_physicalTime
23847 << "...");
23848
23849 noPolygons = writeGeometryToVtkXmlFile(GName.str());
23850
23851 DEBUG_LOG(" .. finished (" << domainId() << ").");
23852 }
23853 if(regularOutput) {
23854 ScratchSpace<MInt> noPolys(noDomains(), AT_, "noPolys");
23855 MInt* noPolysLocal = noPolys.getPointer();
23856 for(MInt c = 0; c < noDomains(); c++) {
23857 noPolysLocal[c] = 0;
23858 }
23859 noPolysLocal[domainId()] = noPolygons;
23860 MPI_Reduce(noPolysLocal, noPolysGlobal, noDomains(), MPI_INT, MPI_SUM, 0, mpiComm(), AT_, "noPolysLocal",
23861 "noPolysGlobal");
23862 } else {
23863 noPolysGlobal[0] = noPolygons;
23864 }
23865
23866
23867 ScratchSpace<MInt> noLsMbCells(noDomains(), AT_, "noLsMbCells");
23868 if(noDomains() > 1)
23869 MPI_Gather(&m_noLsMbBndryCells, 1, MPI_INT, &(noLsMbCells[0]), 1, MPI_INT, 0, mpiComm(), AT_,
23870 "m_noLsMbBndryCells", "(noLsMbCells[0])");
23871
23872
23873 if(domainId() == 0 && regularOutput) {
23874 //------ QOUT.pvd -------
23875
23876 if(true) {
23877 DEBUG_LOG("Writing QOUT.pvd file...");
23878
23880 if(firstCall) {
23881 if(fileExists("out/QOUT.pvd")) {
23882 rename("out/QOUT.pvd", "out/QOUT_BU.pvd");
23883 }
23884 if(fileExists("out/QOUT.pvd.tmp")) {
23885 remove("out/QOUT.pvd.tmp");
23886 }
23887 ofstream ofile("out/QOUT.pvd.tmp", ios_base::out | ios_base::trunc);
23888 if(ofile.is_open() && ofile.good()) {
23889 ofile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
23890 ofile << "<Collection>" << endl;
23891 if(m_restart) {
23892 if(m_solutionTimeSteps.empty()) {
23894 for(MInt p = 0; p < noDomains(); p++) {
23895 stringstream tmp;
23896 tmp << "out/solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu";
23897 if(fileExists((tmp.str()).c_str())) {
23898 ofile << "<DataSet part=\"" << p << "\" timestep=\"" << t << "\" file=\""
23899 << "./solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu\"/>" << endl;
23900 }
23901 }
23902 }
23903 } else {
23904 for(std::set<MInt>::iterator it = m_solutionTimeSteps.begin(); it != m_solutionTimeSteps.end(); it++) {
23905 MInt t = *it;
23906 for(MInt p = 0; p < noDomains(); p++) {
23907 stringstream tmp;
23908 tmp << "out/solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu";
23909 if(fileExists((tmp.str()).c_str())) {
23910 ofile << "<DataSet part=\"" << p << "\" timestep=\"" << t << "\" file=\""
23911 << "./solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu\"/>" << endl;
23912 }
23913 }
23914 }
23915 }
23916 }
23917 ofile.close();
23918 ofile.clear();
23919 } else {
23920 cerr << "Error opening file out/QOUT.pvd.tmp" << endl;
23921 }
23922 }
23923 if(firstCall) {
23924 ofstream ofile("out/QOUT_all.pvd", ios_base::out | ios_base::trunc);
23925 if(ofile.is_open() && ofile.good()) {
23926 ofile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
23927 ofile << "<Collection>" << endl;
23928 if(m_solutionTimeSteps.empty()) {
23930 MBool found = true;
23931 while(found) {
23932 for(MInt p = 0; p < noDomains(); p++) {
23933 stringstream tmp;
23934 tmp << "out/solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu";
23935 if(fileExists((tmp.str()).c_str())) {
23936 ofile << "<DataSet part=\"" << p << "\" timestep=\"" << t << "\" file=\""
23937 << "./solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu\"/>" << endl;
23938 } else {
23939 found = false;
23940 }
23941 }
23942 t += m_solutionInterval;
23943 }
23944 } else {
23945 std::set<MInt>::iterator it = m_solutionTimeSteps.begin();
23946 MInt t = *it;
23947 MBool found = true;
23948 while(found) {
23949 for(MInt p = 0; p < noDomains(); p++) {
23950 stringstream tmp;
23951 tmp << "out/solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu";
23952 if(fileExists((tmp.str()).c_str())) {
23953 ofile << "<DataSet part=\"" << p << "\" timestep=\"" << t << "\" file=\""
23954 << "./solver_data/" << fileName << "_B" << p << "_00" << t << ".vtu\"/>" << endl;
23955 } else {
23956 found = false;
23957 }
23958 }
23959 it++;
23960 }
23961 }
23962 ofile << "</Collection>" << endl;
23963 ofile << "</VTKFile>" << endl;
23964 ofile.close();
23965 ofile.clear();
23966 } else {
23967 cerr << "Error opening file out/QOUT_all.pvd" << endl;
23968 }
23969 }
23970 ofstream ofile("out/QOUT.pvd.tmp", ios_base::out | ios_base::app);
23971 if(ofile.is_open() && ofile.good()) {
23972 for(MInt p = 0; p < noDomains(); p++) {
23973 ofile << "<DataSet part=\"" << p << "\" timestep=\"" << globalTimeStep << "\" file=\""
23974 << "./solver_data/" << fileName << "_B" << p << "_00" << globalTimeStep << ".vtu\"/>" << endl;
23975 }
23976 ofile.close();
23977 ofile.clear();
23978 } else {
23979 cerr << "Error opening file out/QOUT.pvd.tmp" << endl;
23980 }
23981
23982 if(fileExists("out/QOUT.pvd")) {
23983 remove("out/QOUT.pvd");
23984 }
23985 copyFile("out/QOUT.pvd.tmp", "out/QOUT.pvd");
23986 ofstream ofile2("out/QOUT.pvd", ios_base::out | ios_base::app);
23987 if(ofile2.is_open() && ofile2.good()) {
23988 ofile2 << "</Collection>" << endl;
23989 ofile2 << "</VTKFile>" << endl;
23990 ofile2.close();
23991 } else {
23992 cerr << "Error opening file out/QOUT.pvd" << endl;
23993 }
23994 firstCall = false;
23995
23996 DEBUG_LOG("finished.");
23997 }
23998
23999
24000 //------ GEOM.pvd -------
24001
24002 IF_CONSTEXPR(nDim == 3 && m_vtuWriteGeometryFile) {
24003 DEBUG_LOG("Writing GEOM.pvd file...");
24004
24006 if(firstCall2) {
24007 if(fileExists("out/GEOM.pvd")) {
24008 rename("out/GEOM.pvd", "out/GEOM_BU.pvd");
24009 }
24010 if(fileExists("out/GEOM.pvd.tmp")) {
24011 remove("out/GEOM.pvd.tmp");
24012 }
24013 ofstream ofile("out/GEOM.pvd.tmp", ios_base::out | ios_base::trunc);
24014 if(ofile.is_open() && ofile.good()) {
24015 ofile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
24016 ofile << "<Collection>" << endl;
24017 if(m_restart) {
24018 if(m_solutionTimeSteps.empty()) {
24020 MInt cnt = 0;
24021 for(MInt p = 0; p < noDomains(); p++) {
24022 stringstream fn;
24023 fn << "out/solver_data/" << GFileName << "_B" << p << "_00" << t;
24024 if(fileExists((fn.str()).c_str())) {
24025 ofile << "<DataSet part=\"" << cnt << "\" group=\"\" timestep=\"" << t << "\" file=\""
24026 << "./solver_data/" << GFileName << "_B" << p << "_00" << t << ".vtp\"/>" << endl;
24027 cnt++;
24028 }
24029 }
24030 }
24031 } else {
24032 for(std::set<MInt>::iterator it = m_solutionTimeSteps.begin(); it != m_solutionTimeSteps.end(); it++) {
24033 MInt t = *it;
24034 MInt cnt = 0;
24035 for(MInt p = 0; p < noDomains(); p++) {
24036 stringstream fn;
24037 fn << "out/solver_data/" << GFileName << "_B" << p << "_00" << t;
24038 if(fileExists((fn.str()).c_str())) {
24039 ofile << "<DataSet part=\"" << cnt << "\" group=\"\" timestep=\"" << t << "\" file=\""
24040 << "./solver_data/" << GFileName << "_B" << p << "_00" << t << ".vtp\"/>" << endl;
24041 cnt++;
24042 }
24043 }
24044 }
24045 }
24046 }
24047 ofile.close();
24048 ofile.clear();
24049 } else {
24050 cerr << "Error opening file out/GEOM.pvd.tmp" << endl;
24051 }
24052 }
24053 if(firstCall2) {
24054 ofstream ofile("out/GEOM_all.pvd", ios_base::out | ios_base::trunc);
24055 if(ofile.is_open() && ofile.good()) {
24056 ofile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
24057 ofile << "<Collection>" << endl;
24058 if(m_solutionTimeSteps.empty()) {
24060 MBool found = true;
24061 while(found) {
24062 MInt cnt = 0;
24063 for(MInt p = 0; p < noDomains(); p++) {
24064 stringstream fn;
24065 fn << "out/solver_data/" << GFileName << "_B" << p << "_00" << t << ".vtp";
24066 if(fileExists((fn.str()).c_str())) {
24067 ofile << "<DataSet part=\"" << cnt << "\" group=\"\" timestep=\"" << t << "\" file=\""
24068 << "./solver_data/" << GFileName << "_B" << p << "_00" << t << ".vtp\"/>" << endl;
24069 cnt++;
24070 }
24071 }
24072 if(cnt == 0) {
24073 found = false;
24074 }
24075 t += m_solutionInterval;
24076 }
24077 } else {
24078 std::set<MInt>::iterator it = m_solutionTimeSteps.begin();
24079 MInt t = *it;
24080 MBool found = true;
24081 while(found) {
24082 MInt cnt = 0;
24083 for(MInt p = 0; p < noDomains(); p++) {
24084 stringstream fn;
24085 fn << "out/solver_data/" << GFileName << "_B" << p << "_00" << t << ".vtp";
24086 if(fileExists((fn.str()).c_str())) {
24087 ofile << "<DataSet part=\"" << cnt << "\" group=\"\" timestep=\"" << t << "\" file=\""
24088 << "./solver_data/" << GFileName << "_B" << p << "_00" << t << ".vtp\"/>" << endl;
24089 cnt++;
24090 }
24091 }
24092 if(cnt == 0) {
24093 found = false;
24094 }
24095 it++;
24096 }
24097 }
24098 ofile << "</Collection>" << endl;
24099 ofile << "</VTKFile>" << endl;
24100 ofile.close();
24101 ofile.clear();
24102 } else {
24103 cerr << "Error opening file out/GEOM_all.pvd" << endl;
24104 }
24105 }
24106 ofstream ofile("out/GEOM.pvd.tmp", ios_base::out | ios_base::app);
24107 if(ofile.is_open() && ofile.good()) {
24108 MInt cnt = 0;
24109 for(MInt p = 0; p < noDomains(); p++) {
24110 if(noPolysGlobal[p] > 0) {
24111 ofile << "<DataSet part=\"" << cnt << "\" group=\"\" timestep=\"" << globalTimeStep << "\" file=\""
24112 << "./solver_data/" << GFileName << "_B" << p << "_00" << globalTimeStep << ".vtp\"/>" << endl;
24113 cnt++;
24114 }
24115 }
24116 ofile.close();
24117 ofile.clear();
24118 } else {
24119 cerr << "Error opening file out/GEOM.pvd.tmp" << endl;
24120 }
24121
24122 if(fileExists("out/GEOM.pvd")) {
24123 remove("out/GEOM.pvd");
24124 }
24125 copyFile("out/GEOM.pvd.tmp", "out/GEOM.pvd");
24126 ofstream ofile2("out/GEOM.pvd", ios_base::out | ios_base::app);
24127 if(ofile2.is_open() && ofile2.good()) {
24128 ofile2 << "</Collection>" << endl;
24129 ofile2 << "</VTKFile>" << endl;
24130 ofile2.close();
24131 } else {
24132 cerr << "Error opening file out/GEOM.pvd" << endl;
24133 }
24134 firstCall2 = false;
24135
24136 DEBUG_LOG("finished.");
24137 }
24138 }
24139
24140
24141 if(domainId() == 0 && diverged) {
24142 // QOUT_diverged.pvd
24143 if(fileExists("out/QOUT_diverged.pvd")) {
24144 remove("out/QOUT_diverged.pvd");
24145 }
24146 ofstream ofile("out/QOUT_diverged.pvd", ios_base::out | ios_base::trunc);
24147 if(ofile.is_open() && ofile.good()) {
24148 ofile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
24149 ofile << "<Collection>" << endl;
24150 for(MInt p = 0; p < noDomains(); p++) {
24151 stringstream tmp;
24152 tmp << "out/solver_data/" << fileName << "_B" << p << "_diverged.vtu";
24153 if(fileExists((tmp.str()).c_str())) {
24154 ofile << "<DataSet part=\"" << p << "\" timestep=\"" << globalTimeStep << "\" file=\""
24155 << "./solver_data/" << fileName << "_B" << p << "_diverged.vtu\"/>" << endl;
24156 }
24157 }
24158 ofile << "</Collection>" << endl;
24159 ofile << "</VTKFile>" << endl;
24160 ofile.close();
24161 ofile.clear();
24162 } else {
24163 cerr << "Error opening file out/QOUT_diverged.pvd" << endl;
24164 }
24165
24166
24167 // GEOM_diverged.pvd
24168 if(fileExists("out/GEOM_diverged.pvd")) {
24169 remove("out/GEOM_diverged.pvd");
24170 }
24171 ofstream ofile2("out/GEOM_diverged.pvd", ios_base::out | ios_base::trunc);
24172 if(ofile2.is_open() && ofile2.good()) {
24173 ofile2 << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
24174 ofile2 << "<Collection>" << endl;
24175 for(MInt p = 0; p < noDomains(); p++) {
24176 if(noLsMbCells(p) > 0) {
24177 ofile2 << "<DataSet part=\"" << p << "\" timestep=\"" << globalTimeStep << "\" file=\""
24178 << "./solver_data/" << GFileName << "_B" << p << "_diverged.vtp\"/>" << endl;
24179 }
24180 }
24181 ofile2 << "</Collection>" << endl;
24182 ofile2 << "</VTKFile>" << endl;
24183 ofile2.close();
24184 ofile2.clear();
24185 } else {
24186 cerr << "Error opening file out/GEOM_diverged.pvd" << endl;
24187 }
24188 }
24189 }
24190
24191 if(correctCoords) m_fvBndryCnd->rerecorrectCellCoordinates();
24192
24193
24194 if(m_extractedCells) {
24195 delete m_extractedCells;
24196 m_extractedCells = nullptr;
24197 }
24198 if(m_gridPoints) {
24199 delete m_gridPoints;
24200 m_gridPoints = nullptr;
24201 }
24202
24203 if(diverged) {
24204 const MInt noBytes = maxNoGridCells() * m_noCVars * sizeof(MFloat);
24205 MFloat* RESTRICT cVars = (MFloat*)(&(a_variable(0, 0)));
24206 MFloat* RESTRICT oCVars = (MFloat*)(&(a_oldVariable(0, 0)));
24207 memcpy(cVars, oCVars, noBytes);
24209 cerr0 << "deactivate m_useNonSpecifiedRestartFile" << endl;
24212 saveRestartFile(false);
24213 }
24214 }
24215
24216
24217 // point particle output
24218 if(m_noPointParticles > 0 && m_noPointParticles < 1000000) {
24219 MFloatScratchSpace partCoord(m_noPointParticles, nDim, AT_, "partCoord");
24220 MFloatScratchSpace partVel(m_noPointParticles, nDim, AT_, "partVel");
24221 MFloatScratchSpace partVelFluid(m_noPointParticles, nDim, AT_, "partVelFluid");
24222 MFloatScratchSpace partRadii(m_noPointParticles, nDim, AT_, "partVevRadii");
24223 MIntScratchSpace noPartData(noDomains(), AT_, "noPartData");
24224 MIntScratchSpace partDataOffsets(noDomains(), AT_, "partDataOffsets");
24225 noPartData(domainId()) = nDim * m_noPointParticlesLocal;
24226 MPI_Allreduce(MPI_IN_PLACE, &noPartData[0], noDomains(), MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
24227 "noPartData[0]");
24228 partDataOffsets[0] = 0;
24229 for(MInt i = 1; i < noDomains(); i++)
24230 partDataOffsets[i] = partDataOffsets[i - 1] + noPartData[i - 1];
24231 MPI_Gatherv(&m_particleCoords[0], noPartData(domainId()), MPI_DOUBLE, &partCoord[0], &noPartData[0],
24232 &partDataOffsets[0], MPI_DOUBLE, 0, mpiComm(), AT_, "m_particleCoords[0]", "partCoord[0]");
24233 MPI_Gatherv(&m_particleVelocity[0], noPartData(domainId()), MPI_DOUBLE, &partVel[0], &noPartData[0],
24234 &partDataOffsets[0], MPI_DOUBLE, 0, mpiComm(), AT_, "m_particleVelocity[0]", "partVel[0]");
24235 MPI_Gatherv(&m_particleVelocityFluid[0], noPartData(domainId()), MPI_DOUBLE, &partVelFluid[0], &noPartData[0],
24236 &partDataOffsets[0], MPI_DOUBLE, 0, mpiComm(), AT_, "m_particleVelocityFluid[0]", "partVelFluid[0]");
24237 MPI_Gatherv(&m_particleRadii[0], noPartData(domainId()), MPI_DOUBLE, &partRadii[0], &noPartData[0],
24238 &partDataOffsets[0], MPI_DOUBLE, 0, mpiComm(), AT_, "m_particleRadii[0]", "partRadii[0]");
24239
24240 if(domainId() == 0) {
24241 typedef uint32_t uint_t;
24242 const char* const uIDataType = (std::is_same<uint_t, uint64_t>::value) ? "UInt64" : "UInt32";
24243 const char* const dataType = "Float32";
24244 ofstream ofl;
24245 const MString partFileName = m_solutionOutput + "PPOUT_00" + to_string(globalTimeStep) + ".vtp";
24246 ofl.open(partFileName.c_str(), ios_base::out | ios_base::trunc);
24247 if(ofl.is_open() && ofl.good()) {
24248 // VTKFile
24249 ofl << "<?xml version=\"1.0\"?>" << endl;
24250 ofl << "<VTKFile type=\"PolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">" << endl;
24251 ofl << "<PolyData>" << endl;
24252
24253 // FieldData
24254 ofl << "<FieldData>" << endl;
24255 ofl << "<DataArray type=\"" << uIDataType
24256 << "\" Name=\"globalTimeStep\" format=\"ascii\" NumberOfTuples=\"1\" > " << globalTimeStep
24257 << " </DataArray>" << endl;
24258 ofl << "<DataArray type=\"" << dataType << "\" Name=\"time\" format=\"ascii\" NumberOfTuples=\"1\" > " << m_time
24259 << " </DataArray>" << endl;
24260 ofl << "<DataArray type=\"" << dataType << "\" Name=\"physicalTime\" format=\"ascii\" NumberOfTuples=\"1\" > "
24261 << m_physicalTime << " </DataArray>" << endl;
24262 ofl << "</FieldData>" << endl;
24263
24264 // Dimensions
24265 ofl << "<Piece NumberOfPoints=\"" << m_noPointParticles << "\" NumberOfVerts=\"" << m_noPointParticles << "\">"
24266 << endl;
24267
24268 // Points
24269 ofl << "<Points>" << endl;
24270 ofl << setprecision(12);
24271 ofl << "<DataArray type=\"" << dataType << "\" NumberOfComponents=\"3\" format=\"ascii\">" << endl;
24272 for(MInt k = 0; k < m_noPointParticles; k++) {
24273 for(MInt i = 0; i < nDim; i++) {
24274 ofl << partCoord(k, i) << " ";
24275 }
24276 ofl << endl;
24277 }
24278 ofl << "</DataArray>" << endl;
24279 ofl << "</Points>" << endl;
24280
24281 // Verts
24282 ofl << "<Verts>" << endl;
24283 ofl << "<DataArray type=\"" << uIDataType << "\" Name=\"connectivity\" format=\"ascii\">" << endl;
24284 for(MInt k = 0; k < m_noPointParticles; k++) {
24285 ofl << k << " ";
24286 }
24287 ofl << endl;
24288 ofl << "</DataArray>" << endl;
24289 ofl << "<DataArray type=\"" << uIDataType << "\" Name=\"offsets\" format=\"ascii\">" << endl;
24290 for(MInt k = 0; k < m_noPointParticles; k++) {
24291 ofl << k + 1 << " ";
24292 }
24293 ofl << endl;
24294 ofl << "</DataArray>" << endl;
24295 ofl << "</Verts>" << endl;
24296
24297 // PointData
24298 ofl << "<PointData Scalars=\"scalars\">" << endl;
24299 ofl << "<DataArray type=\"" << dataType << "\" Name=\"velocity\" NumberOfComponents=\"3\" format=\"ascii\">"
24300 << endl;
24301 for(MInt k = 0; k < m_noPointParticles; k++) {
24302 for(MInt i = 0; i < nDim; i++) {
24303 ofl << partVel(k, i) << " ";
24304 }
24305 ofl << endl;
24306 }
24307 ofl << "</DataArray>" << endl;
24308 ofl << "<DataArray type=\"" << dataType << "\" Name=\"Re_p\" NumberOfComponents=\"1\" format=\"ascii\">"
24309 << endl;
24310 for(MInt k = 0; k < m_noPointParticles; k++) {
24311 MFloat diameter = F2 * pow(partRadii[3 * k] * partRadii[3 * k + 1] * partRadii[3 * k + 2], F1B3);
24312 MFloat Rep = F0;
24313 for(MInt i = 0; i < nDim; i++) {
24314 Rep += POW2(partVelFluid(k, i) - partVel(k, i));
24315 }
24316 Rep = sqrt(Rep) * diameter * m_rhoInfinity * sysEqn().m_Re0 / sysEqn().m_muInfinity;
24317 ofl << Rep << " ";
24318 }
24319 ofl << endl;
24320 ofl << "</DataArray>" << endl;
24321 ofl << "</PointData>" << endl;
24322
24323 ofl << "</Piece>" << endl;
24324 ofl << "</PolyData>" << endl;
24325 ofl << "</VTKFile>" << endl;
24326 ofl.close();
24327 ofl.clear();
24328 } else {
24329 cerr << "ERROR! COULD NOT OPEN FILE " << partFileName << " for writing! (1)" << endl;
24330 }
24331 }
24332 }
24333}
virtual void computePrimitiveVariables()
Dispatches the computation of the primitive variables for different number of species.
void reduceVariables()
Check whether any of the extracted cells lie below the halo cell level and interpolate their variable...
MInt writeGeometryToVtkXmlFile(const MString &fileName)
Writes VTK file for the embedded geometry.
void saveRestartFile(const MBool) override
Saves the restart file.
void writeVtkXmlOutput(const MString &fileName, MBool debugOutput=false)
write flow variables as XML VTK
MInt copyFile(const MChar *fromName, const MChar *toName)
Definition: iovtk.h:24
void writeVtuOutputParallel(const MString fileName, const MString geomFileName, const MInt noSolverSpecificVars=0, const MFloatScratchSpace &solverSpecificVars=MFloatScratchSpace(1, "writeVtuOutputParallel", "defaultParameter1"), const MInt noUserVars=0, const MFloatScratchSpace &userVars=MFloatScratchSpace(1, "writeVtuOutputParallel", "defaultParameter2"))
Definition: iovtk.cpp:2818
void extractPointIdsFromGrid(Collector< PointBasedCell< nDim > > *&, Collector< CartesianGridPoint< nDim > > *&, const MBool, const std::map< MInt, MInt > &, MInt levelThreshold=999999, MFloat *bBox=nullptr, MBool levelSetMb=false) const
Creates a list of unique corner points for all cells using a hash map levelThreshold optionally speci...
int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gatherv

◆ writeVtkXmlOutput() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==3, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVtkXmlOutput ( const MString fileName,
MBool  debugOutput = false 
)
Author
Lennart Schneiders

Definition at line 32665 of file fvmbcartesiansolverxd.cpp.

32665{}

◆ writeVtkXmlOutput() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVtkXmlOutput ( const MString fileName,
MBool  debugOutput = false 
)

◆ writeVtkXmlOutput_MGC()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvMbCartesianSolverXD< nDim, SysEqn >::writeVtkXmlOutput_MGC ( const MString fileName)
Author
Lennart Schneiders

Definition at line 32674 of file fvmbcartesiansolverxd.cpp.

32674 {
32675 TRACE();
32676
32677 MInt noCells = 1;
32678 MInt noPoints = 1;
32679
32680 MBool writePointData = false;
32681 writePointData = Context::getSolverProperty<MBool>("writePointData", solverId(), AT_, &writePointData);
32682
32683#ifdef _MB_DEBUG_
32684 MBool sensorOutput = m_adaptation;
32685#endif
32686 MBool QThresholdOutput = true;
32687 MBool entropyChangeOutput = true;
32688
32689 const MInt baseCellType = 8;
32690 const MInt polyCellType = 7;
32691 MInt cellId, ghostCellId, counter;
32692
32693 const string dataType64 = "Float64";
32694#ifdef DOUBLE_PRECISION_OUTPUT
32695 const string dataType = "Float64";
32696#else
32697 const string dataType = "Float32";
32698#endif
32699 const string iDataType = "Int32";
32700 const string uIDataType = "UInt32";
32701 const string uI8DataType = "UInt8";
32702 const string uI16DataType = "UInt16";
32703
32704 MUint uinumber;
32705#ifdef DOUBLE_PRECISION_OUTPUT
32706 MFloat fnumber;
32707 typedef MFloat flt;
32708#else
32709 // float fnumber;
32710 typedef float flt;
32711#endif
32712
32713 if(noDomains() == 1) {
32714 cerr << "extracted";
32715 cerr << "(" << m_extractedCells->size() << ")...";
32716 }
32717
32718 noPoints = m_gridPoints->size();
32719 MInt noExtractedCells = m_extractedCells->size();
32720 noCells = noExtractedCells;
32721
32722 // 4 node ids for each direction
32723 const MInt ltable[4][3] = {{2, 3}, {0, 2}, {1, 0}, {3, 1}};
32724 const MInt pointOrder[4] = {0, 1, 3, 2};
32725 const MInt dirOrder[4] = {2, 1, 3, 0};
32726 const MInt reverseDir[4] = {1, 0, 3, 2};
32727
32728 MInt centerId;
32729
32730 ScratchSpace<MInt> cellTypes(noExtractedCells, AT_, "cellTypes");
32731 ScratchSpace<MInt> polyIds(noExtractedCells, AT_, "polyIds");
32732 ScratchSpace<MInt> reverseMapping(a_noCells(), AT_, "reverseMapping");
32733 ScratchSpace<MInt> cutPointIds(2 * m_noDirs * m_fvBndryCnd->m_bndryCells->size(), AT_, "cutPointIds");
32734
32735 MInt noPolyCells;
32736
32737 // integrity check 1
32738 for(MInt c = 0; c < noExtractedCells; c++) {
32739 cellId = m_extractedCells->a[c].m_cellId;
32740 for(MInt k = 0; k < m_noCellNodes; k++) {
32741 MInt pid = m_extractedCells->a[c].m_pointIds[k];
32742 if(pid < 0 || pid >= noPoints) {
32743 mTerm(1, AT_,
32744 "Error A in FvMbSolver2D::writeVtkXmlOutput_MGC(..). Quit. " + to_string(cellId) + " " + to_string(k)
32745 + " " + to_string(pid));
32746 }
32747 }
32748 }
32749
32750 for(MInt i = 0; i < 2 * m_noDirs * m_fvBndryCnd->m_bndryCells->size(); i++) {
32751 cutPointIds.p[i] = -1;
32752 }
32753
32754 if(noDomains() == 1) {
32755 cerr << "prepare...";
32756 }
32757 for(MInt c = 0; c < a_noCells(); c++) {
32758 reverseMapping.p[c] = -1;
32759 }
32760 for(MInt c = 0; c < noExtractedCells; c++) {
32761 reverseMapping.p[m_extractedCells->a[c].m_cellId] = c;
32762 }
32763
32764 MBool isPolyCell;
32765 noPolyCells = 0;
32766
32767 for(MInt c = 0; c < noExtractedCells; c++) {
32768 cellId = m_extractedCells->a[c].m_cellId;
32769 cellTypes.p[c] = baseCellType;
32770 polyIds.p[c] = -1;
32771 isPolyCell = false;
32772 if(a_bndryId(cellId) > -1) {
32773 isPolyCell = true;
32774 } else {
32775 for(MInt i = 0; i < m_noDirs; i++) {
32776 if(checkNeighborActive(cellId, i) && a_hasNeighbor(cellId, i) > 0) {
32777 if(c_noChildren(c_neighborId(cellId, i)) > 0) {
32778 isPolyCell = true;
32779 MInt nghbrId = c_neighborId(cellId, i);
32780 if(nghbrId < 0) continue;
32781 for(MInt j = 0; j < m_noCellNodes; j++) {
32782 MInt childId = c_childId(nghbrId, j);
32783 if(reverseMapping.p[childId] < 0) {
32784 isPolyCell = false;
32785 }
32786 }
32787 }
32788 }
32789 }
32790 }
32791 if(isPolyCell) {
32792 cellTypes.p[c] = polyCellType;
32793 polyIds.p[c] = noPolyCells;
32794 noPolyCells++;
32795 }
32796 }
32797
32798 MBool isPolyFace;
32799 MInt eCell, nghbrId;
32800 const MInt maxNoExtraPoints = 8;
32801 const MInt maxNoPolyCells = noPolyCells;
32802 ScratchSpace<MInt> polyCellLink(maxNoPolyCells, AT_, "polyCellLink");
32803 ScratchSpace<MInt> extraPoints(maxNoPolyCells * maxNoExtraPoints, AT_, "extraPoints");
32804 ScratchSpace<MInt> noExtraPoints(maxNoPolyCells, AT_, "noExtraPoints");
32805 ScratchSpace<MInt> noInternalPoints(maxNoPolyCells, AT_, "noInternalPoints");
32806 MInt offset, pointCount;
32807
32808 for(MInt c = 0; c < noExtractedCells; c++) {
32809 if(cellTypes.p[c] == polyCellType) {
32810 polyCellLink.p[polyIds.p[c]] = c;
32811 }
32812 }
32813
32814
32815 const MInt noInternalGridPoints = m_gridPoints->size();
32816 const MInt maxPointsXD = 12;
32817
32818 for(MInt pc = 0; pc < noPolyCells; pc++) {
32819 eCell = polyCellLink.p[pc];
32820 cellId = m_extractedCells->a[eCell].m_cellId;
32821 noInternalPoints.p[pc] = m_noCellNodes;
32822 noExtraPoints.p[pc] = 0;
32823
32824 // a) cut cells at the boundary
32825 if(a_bndryId(cellId) > -1) {
32826 if(a_bndryId(cellId) < m_noOuterBndryCells) {
32827 MInt bndryId = a_bndryId(cellId);
32828
32829 noInternalPoints.p[pc] = 0;
32830
32831 for(MInt i = 0; i < m_noDirs; i++) {
32832 MInt p = pointOrder[i];
32833 MInt dir = dirOrder[i];
32834
32835 // 0. determine internal vertices
32836 if(!m_pointIsInside[bndryId][IDX_LSSETMB(p, 0)]) {
32837 extraPoints.p[pc * maxNoExtraPoints + noExtraPoints.p[pc]] = m_extractedCells->a[eCell].m_pointIds[p];
32838 noExtraPoints.p[pc]++;
32839 }
32840
32841 // 1. add cut points
32842 for(MInt cp = 0; cp < m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints; cp++) {
32843 if(m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[cp] == dir) {
32844 MInt gridPointId = -1;
32845 if(checkNeighborActive(cellId, dir) && a_hasNeighbor(cellId, dir) > 0) {
32846 if(a_bndryId(c_neighborId(cellId, dir)) > -1) {
32847 gridPointId = cutPointIds.p[m_noDirs * a_bndryId(c_neighborId(cellId, dir)) + reverseDir[dir]];
32848 if(gridPointId > -1) {
32849 m_gridPoints->a[gridPointId].m_cellIds[m_gridPoints->a[gridPointId].m_noAdjacentCells] = cellId;
32850 m_gridPoints->a[gridPointId].m_noAdjacentCells++;
32851 }
32852 }
32853 }
32854 if(gridPointId >= noPoints) {
32855 mTerm(1, AT_, "Error 0 in FvMbSolver3D::writeVtkXmlOutput(..). Quit.");
32856 }
32857 if(gridPointId < 0) {
32858 gridPointId = m_gridPoints->size();
32860 noPoints++;
32861 m_gridPoints->a[gridPointId].m_noAdjacentCells = 1;
32862 m_gridPoints->a[gridPointId].m_cellIds[0] = cellId;
32863 for(MInt j = 0; j < nDim; j++) {
32864 m_gridPoints->a[gridPointId].m_coordinates[j] =
32865 m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcs[0]->m_cutCoordinates[cp][j];
32866 }
32867 }
32868 cutPointIds.p[m_noDirs * bndryId + dir] = gridPointId;
32869
32870 extraPoints.p[pc * maxNoExtraPoints + noExtraPoints.p[pc]] = gridPointId;
32871 noExtraPoints.p[pc]++;
32872 }
32873 }
32874 }
32875 } else {
32876 MInt bndryId = a_bndryId(cellId);
32877 noInternalPoints.p[pc] = 0;
32878 for(MInt f = 0; f < m_noCutCellFaces[bndryId]; f++) {
32879 for(MInt fp = 0; fp < m_noCutFacePoints[bndryId][f]; fp++) {
32880 MInt point = m_cutFacePointIds[bndryId][maxPointsXD * f + fp];
32881 if(point < m_noCellNodes) { // is grid point
32882 extraPoints.p[pc * maxNoExtraPoints + noExtraPoints.p[pc]] = m_extractedCells->a[eCell].m_pointIds[point];
32883 noExtraPoints.p[pc]++;
32884 } else { // is cut point
32885 point -= m_noCellNodes;
32886 // first try: just add cut point!
32887 MInt gridPointId = m_gridPoints->size();
32889 noPoints++;
32890 m_gridPoints->a[gridPointId].m_noAdjacentCells = 1;
32891 m_gridPoints->a[gridPointId].m_cellIds[0] = cellId;
32892
32893 // find right cut point:
32894 MInt previousCutPoints = -1;
32895 MInt pointFound = false;
32896 for(MInt srfc = 0; srfc < m_fvBndryCnd->m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
32897 for(MInt cp = 0; cp < m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[srfc]->m_noCutPoints; cp++) {
32898 previousCutPoints++;
32899 if(previousCutPoints == point) {
32900 for(MInt j = 0; j < nDim; j++) {
32901 m_gridPoints->a[gridPointId].m_coordinates[j] =
32902 m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcs[srfc]->m_cutCoordinates[cp][j];
32903 }
32904 pointFound = true;
32905 break;
32906 }
32907 }
32908 if(pointFound) break;
32909 }
32910 extraPoints.p[pc * maxNoExtraPoints + noExtraPoints.p[pc]] = gridPointId;
32911 noExtraPoints.p[pc]++;
32912 }
32913 }
32914 }
32915 }
32916 }
32917 // b) cells at fine/coarse mesh interfaces
32918 else {
32919 noInternalPoints.p[pc] = 0;
32920
32921 for(MInt i = 0; i < m_noDirs; i++) {
32922 MInt p = pointOrder[i];
32923 MInt dir = dirOrder[i];
32924
32925 extraPoints.p[pc * maxNoExtraPoints + noExtraPoints.p[pc]] = m_extractedCells->a[eCell].m_pointIds[p];
32926 noExtraPoints.p[pc]++;
32927
32928 isPolyFace = false;
32929 if(checkNeighborActive(cellId, dir) && a_hasNeighbor(cellId, dir) > 0) {
32930 nghbrId = c_neighborId(cellId, dir);
32931 if(c_noChildren(nghbrId) > 0) {
32932 isPolyFace = true;
32933 for(MInt child = 0; child < m_noCellNodes; child++) {
32934 if(!childCode[dir][child]) continue;
32935 MInt childId = c_childId(nghbrId, child);
32936 if(childId < 0) {
32937 isPolyFace = false;
32938 }
32939 if(reverseMapping.p[childId] < 0) {
32940 isPolyFace = false;
32941 }
32942 }
32943 }
32944 }
32945
32946 if(isPolyFace) {
32947 // store four faces (polygon numbering!)
32948 nghbrId = reverseMapping.p[c_childId(c_neighborId(cellId, dir), ltable[i][0])];
32949 if(nghbrId < 0) {
32950 cerr << "=== VTK XML ERROR LOG === " << domainId() << endl;
32951 cerr << endl
32952 << cellId << " " << a_bndryId(cellId) << " " << c_childId(c_neighborId(cellId, dir), ltable[i][0])
32953 << endl;
32954 cerr << endl << a_noCells() << " " << dir << " " << ltable[i][0] << endl;
32955 cerr << a_levelSetValuesMb(cellId, 0) << " " << a_hasProperty(cellId, SolverCell::IsInactive) << endl;
32956 cerr << "props: " << a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) << " " << a_isHalo(cellId) << " "
32957 << a_hasProperty(cellId, SolverCell::IsNotGradient) << " "
32958 << a_hasProperty(c_neighborId(cellId, dir), SolverCell::IsOnCurrentMGLevel) << " "
32959 << a_hasProperty(c_childId(c_neighborId(cellId, dir), ltable[i][0]), SolverCell::IsOnCurrentMGLevel)
32960 << endl;
32961 cerr << endl
32962 << cellId << " " << c_neighborId(cellId, dir) << " "
32963 << c_childId(c_neighborId(cellId, dir), ltable[i][0]) << " / " << a_level(cellId) << " "
32964 << a_level(c_neighborId(cellId, dir)) << " "
32965 << a_level(c_childId(c_neighborId(cellId, dir), ltable[i][0])) << " / " << c_noChildren(cellId) << " "
32966 << c_noChildren(c_neighborId(cellId, dir)) << " "
32967 << c_noChildren(c_childId(c_neighborId(cellId, dir), ltable[i][0])) << endl;
32968 cerr << c_childId(c_neighborId(cellId, dir), 0) << " " << c_childId(c_neighborId(cellId, dir), 1) << " "
32969 << c_childId(c_neighborId(cellId, dir), 2) << " " << c_childId(c_neighborId(cellId, dir), 3) << endl;
32970 cerr << a_coordinate(c_neighborId(cellId, dir), 0) << " " << a_coordinate(c_neighborId(cellId, dir), 1)
32971 << endl;
32972 for(MInt j = 0; j < m_noCellNodes; j++) {
32973 cerr << a_hasProperty(c_childId(c_neighborId(cellId, dir), j), SolverCell::IsInactive) << " ";
32974 }
32975 cerr << endl;
32976 for(MInt j = 0; j < m_noCellNodes; j++) {
32977 cerr << a_hasProperty(c_childId(c_neighborId(cellId, dir), j), SolverCell::IsOnCurrentMGLevel) << " ";
32978 }
32979 cerr << endl;
32980 mTerm(1, AT_, "Error 1 in FvMbSolver2D::writeVtkXmlOutput_MGC(..). Quit.");
32981 }
32982 centerId = m_extractedCells->a[nghbrId].m_pointIds[ltable[i][1]];
32983 extraPoints.p[pc * maxNoExtraPoints + noExtraPoints.p[pc]] = centerId;
32984 noExtraPoints.p[pc]++;
32985
32986 if(m_gridPoints->a[centerId].m_noAdjacentCells < m_noCellNodes) {
32987 m_gridPoints->a[centerId].m_cellIds[m_gridPoints->a[centerId].m_noAdjacentCells] = cellId;
32988 m_gridPoints->a[centerId].m_noAdjacentCells++;
32989 } else {
32990 cerr << endl << cellId << " / ";
32991 for(MInt c = 0; c < m_gridPoints->a[centerId].m_noAdjacentCells; c++)
32992 cerr << m_gridPoints->a[centerId].m_cellIds[c] << " ";
32993 cerr << endl;
32994 mTerm(1, AT_, "Error 2 in FvMbSolver2D::writeVtkXmlOutput_MGC(..). Quit.");
32995 }
32996 }
32997 }
32998 }
32999 }
33000
33001 pointCount = 0;
33002 for(MInt c = 0; c < noExtractedCells; c++) {
33003 MInt pc = polyIds.p[c];
33004 if(pc > -1) {
33005 pointCount += noInternalPoints.p[pc];
33006 pointCount += noExtraPoints.p[pc];
33007 } else {
33008 pointCount += m_noCellNodes;
33009 }
33010 }
33011
33012 MInt qDataSize = 2;
33013 if(QThresholdOutput) qDataSize++;
33014 ScratchSpace<MFloat> qData(qDataSize, a_noCells(), AT_, "qData");
33015 MFloat gradU[2][2];
33016 for(MInt c = 0; c < noExtractedCells; c++) {
33017 cellId = m_extractedCells->a[c].m_cellId;
33018
33019 for(MInt i = 0; i < nDim; i++) {
33020 for(MInt j = 0; j < nDim; j++) {
33021 gradU[i][j] = a_slope(cellId, PV->VV[i], j) * m_referenceLength / m_UInfinity;
33022 }
33023 }
33024 MFloat omega = F1B2 * (gradU[1][0] - gradU[0][1]);
33025 MFloat omega2 = POW2(omega);
33026 MFloat S2 = 0;
33027 for(MInt i = 0; i < nDim; i++) {
33028 for(MInt j = 0; j < nDim; j++) {
33029 S2 += POW2(F1B2 * (gradU[i][j] + gradU[j][i]));
33030 }
33031 }
33032 MFloat Q = F1B2 * (omega2 - S2);
33033 qData(0, cellId) = Q;
33034 qData(1, cellId) = omega;
33035 if(QThresholdOutput) qData(2, cellId) = F1B2 * ((omega2 / mMax(m_eps, S2)) - F1);
33036 }
33037
33038 // GATHER
33039 if(noDomains() == 1) {
33040 cerr << "gather...";
33041 }
33042
33043 // points
33044 ScratchSpace<flt> points(3 * noPoints, AT_, "points");
33045 for(MInt p = 0; p < noPoints; p++) {
33046 for(MInt i = 0; i < nDim; i++) {
33047 points.p[3 * p + i] = (flt)m_gridPoints->a[p].m_coordinates[i];
33048 }
33049 points.p[3 * p + 2] = (flt)F0;
33050 }
33051
33052 // connectivity
33053 ScratchSpace<MUint> connectivity(pointCount, AT_, "connectivity");
33054 counter = 0;
33055 for(MInt c = 0; c < noExtractedCells; c++) {
33056 MInt pc = polyIds.p[c];
33057 if(pc > -1) {
33058 for(MInt p = 0; p < noExtraPoints.p[pc]; p++) {
33059 connectivity.p[counter] = (MUint)extraPoints.p[pc * maxNoExtraPoints + p];
33060 counter++;
33061 }
33062 } else {
33063 for(MInt p = 0; p < m_noCellNodes; p++) {
33064 connectivity.p[counter] = (MUint)m_extractedCells->a[c].m_pointIds[p];
33065 counter++;
33066 }
33067 }
33068 }
33069
33070 if(counter != pointCount) {
33071 mTerm(1, AT_, "E1");
33072 }
33073
33074 // offsets
33075 ScratchSpace<MUint> offsets(noCells, AT_, "offsets");
33076 counter = 0;
33077 for(MInt c = 0; c < noExtractedCells; c++) {
33078 MInt pc = polyIds.p[c];
33079 if(pc > -1)
33080 counter += noInternalPoints.p[pc] + noExtraPoints.p[pc];
33081 else
33082 counter += m_noCellNodes;
33083
33084 offsets.p[c] = (MUint)counter;
33085 }
33086
33087 // types
33088 ScratchSpace<unsigned char> types(noCells, AT_, "types");
33089 for(MInt c = 0; c < noExtractedCells; c++) {
33090 types.p[c] = (unsigned char)cellTypes.p[c];
33091 }
33092
33093 // cellIds
33094 ScratchSpace<MInt> cellIds(noCells, AT_, "cellIds");
33095 for(MInt c = 0; c < noExtractedCells; c++) {
33096 cellIds.p[c] = c_globalId(m_extractedCells->a[c].m_cellId);
33097 }
33098
33099 // vtkGhostLevels
33100 const MInt noCh = (m_haloCellOutput) ? noCells : 1;
33101 ScratchSpace<unsigned char> vtkGhostLevels(noCh, AT_, "vtkGhostLevels");
33102 if(m_haloCellOutput) {
33103 for(MInt c = 0; c < noExtractedCells; c++) {
33104 vtkGhostLevels.p[c] = (unsigned char)0;
33105 if(a_isHalo(m_extractedCells->a[c].m_cellId)) vtkGhostLevels.p[c] = (unsigned char)1;
33106 if(a_hasProperty(m_extractedCells->a[c].m_cellId, SolverCell::IsNotGradient))
33107 vtkGhostLevels.p[c] = (unsigned char)2;
33108 }
33109 }
33110
33111#ifdef _MB_DEBUG_
33112
33113 // bndryIds
33114 ScratchSpace<MInt> bndryIds(noCells, AT_, "bndryIds");
33115 for(MInt c = 0; c < noExtractedCells; c++) {
33116 bndryIds.p[c] = a_bndryId(m_extractedCells->a[c].m_cellId);
33117 if(bndryIds.p[c] < 0 && a_hasProperty(m_extractedCells->a[c].m_cellId, SolverCell::IsInactive)) bndryIds.p[c] = -3;
33118 }
33119
33120 // drho_dt
33121 ScratchSpace<MFloat> drho_dt(noCells, AT_, "drho_dt");
33122 for(MInt c = 0; c < noExtractedCells; c++) {
33123 drho_dt.p[c] =
33124 a_FcellVolume(m_extractedCells->a[c].m_cellId) * a_rightHandSide(m_extractedCells->a[c].m_cellId, CV->RHO);
33125 }
33126
33127 // drhou_dt
33128 ScratchSpace<MFloat> drhou_dt(noCells, AT_, "drhou_dt");
33129 for(MInt c = 0; c < noExtractedCells; c++) {
33130 drhou_dt.p[c] =
33131 a_FcellVolume(m_extractedCells->a[c].m_cellId) * a_rightHandSide(m_extractedCells->a[c].m_cellId, CV->RHO_U);
33132 }
33133
33134 // levelSetFunction
33135 ScratchSpace<flt> levelSetFunction(noCells, AT_, "levelSetFunction");
33136 for(MInt c = 0; c < noExtractedCells; c++) {
33137 levelSetFunction.p[c] = (flt)a_levelSetValuesMb(m_extractedCells->a[c].m_cellId, 0);
33138 }
33139
33140 // volume
33141 ScratchSpace<flt> volume(noCells, AT_, "volume");
33142 for(MInt c = 0; c < noExtractedCells; c++) {
33143 volume.p[c] = (flt)a_cellVolume(m_extractedCells->a[c).m_cellId]
33144 / grid().gridCellVolume(a_level(m_extractedCells->a[c].m_cellId));
33145 }
33146
33147 // spongeFac
33148 ScratchSpace<flt> spongeFac(noCells, AT_, "spongeFac");
33149 for(MInt c = 0; c < noExtractedCells; c++) {
33150 spongeFac.p[c] = (flt)a_spongeFactor(m_extractedCells->a[c].m_cellId);
33151 }
33152
33153 const MInt sensorSize = sensorOutput ? noCells : 1;
33154 ScratchSpace<flt> tauC(sensorSize, AT_, "tauC");
33155 ScratchSpace<flt> tauE(sensorSize, AT_, "tauE");
33156 if(sensorOutput) {
33157 for(MInt c = 0; c < noExtractedCells; c++) {
33158 tauC.p[c] = (flt)m_tauC[m_extractedCells->a[c].m_cellId];
33159 tauE.p[c] = (flt)m_tauE[m_extractedCells->a[c].m_cellId];
33160 }
33161 }
33162#endif
33163
33164 // additional cellData/pointData
33165 MInt asize = noCells;
33166 if(writePointData) {
33167 asize = noPoints;
33168 }
33169 ScratchSpace<flt> pressure(asize, AT_, "pressure");
33170 ScratchSpace<flt> velocity(3 * asize, AT_, "velocity");
33171 ScratchSpace<flt> density(asize, AT_, "density");
33172 ScratchSpace<flt> vorticity(asize, AT_, "vorticity");
33173 ScratchSpace<flt> Qcriterion(asize, AT_, "Qcriterion");
33174 const MInt dSSize = entropyChangeOutput ? asize : 1;
33175 ScratchSpace<flt> dS(dSSize, AT_, "dS");
33176#ifdef _MB_DEBUG_
33177 ScratchSpace<flt> rhoE(asize, AT_, "rhoE");
33178 const MInt qtSize = QThresholdOutput ? asize : 1;
33179 ScratchSpace<flt> QThreshold(qtSize, AT_, "QThreshold");
33180#endif
33181
33182 MFloat tmp;
33183 MFloat weights[m_noCellNodes];
33184 if(writePointData) {
33185 for(MInt p = 0; p < noInternalGridPoints; p++) {
33186 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33187 weights[n] = F0;
33188 }
33189 tmp = F0;
33190 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33191 cellId = m_gridPoints->a[p].m_cellIds[n];
33192 if(a_bndryId(cellId) > -1) {
33193 weights[n] =
33194 F1
33195 / (sqrt(POW2(a_coordinate(cellId, 0) + m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_coordinates[0]
33196 - m_gridPoints->a[p].m_coordinates[0])
33197 + POW2(a_coordinate(cellId, 1) + m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_coordinates[1]
33198 - m_gridPoints->a[p].m_coordinates[1])));
33199 tmp += weights[n];
33200 } else {
33201 weights[n] = F1
33202 / (sqrt(POW2(a_coordinate(cellId, 0) - m_gridPoints->a[p].m_coordinates[0])
33203 + POW2(a_coordinate(cellId, 1) - m_gridPoints->a[p].m_coordinates[1])));
33204 tmp += weights[n];
33205 }
33206 }
33207 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33208 weights[n] /= tmp;
33209 }
33210
33211 pressure.p[p] = (flt)F0;
33212 density.p[p] = (flt)F0;
33213 vorticity.p[p] = (flt)F0;
33214 Qcriterion.p[p] = (flt)F0;
33215 if(entropyChangeOutput) dS.p[p] = (flt)F0;
33216 for(MInt i = 0; i < nDim; i++) {
33217 velocity.p[3 * p + i] = (flt)F0;
33218 }
33219 velocity.p[3 * p + 2] = (flt)F0;
33220#ifdef _MB_DEBUG_
33221 rhoE.p[p] = (flt)F0;
33222 if(QThresholdOutput) QThreshold.p[p] = (flt)F0;
33223#endif
33224 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33225 cellId = m_gridPoints->a[p].m_cellIds[n];
33226 pressure.p[p] += (flt)weights[n] * a_pvariable(cellId, PV->P);
33227 density.p[p] += (flt)weights[n] * a_pvariable(cellId, PV->RHO);
33228 vorticity.p[p] += (flt)weights[n] * qData(1, cellId); // a_slope( cellId , 0 , 0 );
33229 Qcriterion.p[p] += (flt)weights[n] * qData(0, cellId); // a_slope( cellId , 2 , 0 );
33230 if(entropyChangeOutput) dS.p[p] += (flt)weights[n] * (entropy(cellId) - m_SInfinity) / m_SInfinity;
33231 for(MInt i = 0; i < nDim; i++) {
33232 velocity.p[3 * p + i] += (flt)weights[n] * a_pvariable(cellId, PV->VV[i]);
33233 }
33234#ifdef _MB_DEBUG_
33235 rhoE.p[p] += (flt)weights[n] * a_variable(cellId, CV->RHO_E);
33236 if(QThresholdOutput) QThreshold.p[p] += (flt)weights[n] * qData(2, cellId);
33237#endif
33238 }
33239 }
33240 for(MInt p = noInternalGridPoints; p < noPoints; p++) {
33241 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33242 weights[n] = F0;
33243 }
33244 tmp = F0;
33245 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33246 cellId = m_gridPoints->a[p].m_cellIds[n];
33247 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
33248 if(a_bndryId(cellId) < 0) continue;
33249 weights[n] = F1
33250 / (sqrt(POW2(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcs[0]->m_coordinates[0]
33251 - m_gridPoints->a[p].m_coordinates[0])
33252 + POW2(m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcs[0]->m_coordinates[1]
33253 - m_gridPoints->a[p].m_coordinates[1])));
33254 tmp += weights[n];
33255 }
33256 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33257 weights[n] /= tmp;
33258 }
33259 pressure.p[p] = (flt)F0;
33260 density.p[p] = (flt)F0;
33261 vorticity.p[p] = (flt)F0;
33262 Qcriterion.p[p] = (flt)F0;
33263 if(entropyChangeOutput) dS.p[p] = (flt)F0;
33264 for(MInt i = 0; i < nDim; i++) {
33265 velocity.p[3 * p + i] = (flt)F0;
33266 }
33267 velocity.p[3 * p + 2] = F0;
33268#ifdef _MB_DEBUG_
33269 rhoE.p[p] = (flt)F0;
33270 if(QThresholdOutput) QThreshold.p[p] = (flt)F0;
33271#endif
33272 for(MInt n = 0; n < m_gridPoints->a[p].m_noAdjacentCells; n++) {
33273 cellId = m_gridPoints->a[p].m_cellIds[n];
33274 if(a_hasProperty(cellId, SolverCell::IsInactive)) continue;
33275 if(a_bndryId(cellId) < 0) continue;
33276 ghostCellId = m_fvBndryCnd->m_bndryCells->a[a_bndryId(cellId)].m_srfcVariables[0]->m_ghostCellId;
33277 if(a_bndryId(cellId) < m_noOuterBndryCells) {
33278 MFloat pb = F1B2 * (a_pvariable(cellId, PV->P) + a_pvariable(ghostCellId, PV->P));
33279 MFloat rhob = F1B2 * (a_pvariable(cellId, PV->RHO) + a_pvariable(ghostCellId, PV->RHO));
33280 pressure.p[p] += (flt)weights[n] * pb;
33281 density.p[p] += (flt)weights[n] * rhob;
33282 vorticity.p[p] += (flt)weights[n] * qData(1, cellId); // a_slope( cellId , 0 , 0 );
33283 Qcriterion.p[p] += (flt)weights[n] * qData(0, cellId); // a_slope( cellId , 2 , 0 );
33284 MFloat SG = sysEqn().entropy(pb, rhob);
33285 if(entropyChangeOutput) dS.p[p] += (flt)weights[n] * (SG - m_SInfinity) / m_SInfinity;
33286 for(MInt i = 0; i < nDim; i++) {
33287 velocity.p[3 * p + i] +=
33288 (flt)weights[n] * F1B2 * (a_pvariable(cellId, PV->VV[i]) + a_pvariable(ghostCellId, PV->VV[i]));
33289 }
33290#ifdef _MB_DEBUG_
33291 rhoE.p[p] += (flt)weights[n] * a_variable(cellId, CV->RHO_E);
33292 if(QThresholdOutput) QThreshold.p[p] += (flt)weights[n] * qData(2, cellId);
33293#endif
33294 } else {
33295 MInt bndryId = a_bndryId(cellId);
33296 pressure.p[p] += (flt)weights[n] * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->P];
33297 density.p[p] += (flt)weights[n] * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->RHO];
33298 vorticity.p[p] += (flt)weights[n] * qData(1, cellId); // a_slope( cellId , 0 , 0 );
33299 Qcriterion.p[p] += (flt)weights[n] * qData(0, cellId); // a_slope( cellId , 2 , 0 );
33300 MFloat SG = sysEqn().entropy(m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->P],
33301 m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->RHO]);
33302 if(entropyChangeOutput) dS.p[p] += (flt)weights[n] * (SG - m_SInfinity) / m_SInfinity;
33303 for(MInt i = 0; i < nDim; i++) {
33304 velocity.p[3 * p + i] +=
33305 (flt)weights[n] * m_fvBndryCnd->m_bndryCell[bndryId].m_srfcVariables[0]->m_primVars[PV->VV[i]];
33306 }
33307#ifdef _MB_DEBUG_
33308 rhoE.p[p] += (flt)weights[n] * a_variable(cellId, CV->RHO_E);
33309 if(QThresholdOutput) QThreshold.p[p] += (flt)weights[n] * qData(2, cellId);
33310#endif
33311 }
33312 }
33313 }
33314 } else {
33315 for(MInt c = 0; c < noExtractedCells; c++) {
33316 cellId = m_extractedCells->a[c].m_cellId;
33317 pressure.p[c] = (flt)a_pvariable(cellId, PV->P);
33318 density.p[c] = (flt)a_pvariable(cellId, PV->RHO);
33319 vorticity.p[c] = (flt)qData(1, cellId); // a_slope( cellId , 0 , 0 ) ;
33320 Qcriterion.p[c] = (flt)qData(0, cellId); // a_slope( cellId , 2 , 0 ) ;
33321 if(entropyChangeOutput) dS.p[c] = (flt)(entropy(cellId) - m_SInfinity) / m_SInfinity;
33322 for(MInt i = 0; i < nDim; i++) {
33323 velocity.p[3 * c + i] = (flt)a_pvariable(cellId, PV->VV[i]);
33324 }
33325 velocity.p[3 * c + 2] = (flt)F0;
33326#ifdef _MB_DEBUG_
33327 rhoE.p[c] = (flt)a_variable(cellId, CV->RHO_E);
33328 if(QThresholdOutput) QThreshold.p[c] = (flt)qData(2, cellId);
33329#endif
33330 }
33331 }
33332
33333 // WRITE
33334 if(domainId() == 0) {
33335 cerr << "write...";
33336 }
33337
33338 ofstream ofl;
33339 ofl.open(fileName.c_str(), ios_base::out | ios_base::trunc);
33340 if(ofl.is_open() && ofl.good()) {
33341 offset = 0;
33342
33343 // VTKFile
33344 ofl << "<?xml version=\"1.0\"?>" << endl;
33345 ofl << "<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\">" << endl;
33346 ofl << "<UnstructuredGrid>" << endl;
33347
33348 // FieldData
33349 ofl << "<FieldData>" << endl;
33350
33351 ofl << "<DataArray type=\"" << dataType << "\" Name=\"time\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33352 << m_time << "\" RangeMax=\"" << m_time << "\">" << endl;
33353 ofl << m_time << endl;
33354 ofl << "</DataArray>" << endl;
33355 ofl << "<DataArray type=\"" << dataType
33356 << "\" Name=\"physicalTime\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\"" << m_physicalTime
33357 << "\" RangeMax=\"" << m_physicalTime << "\">" << endl;
33358 ofl << m_physicalTime << endl;
33359 ofl << "</DataArray>" << endl;
33360 ofl << "<DataArray type=\"" << dataType << "\" Name=\"timeStep\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33361 << timeStep() << "\" RangeMax=\"" << timeStep() << "\">" << endl;
33362 ofl << timeStep() << endl;
33363 ofl << "</DataArray>" << endl;
33364 ofl << "<DataArray type=\"" << iDataType
33365 << "\" Name=\"globalTimeStep\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\"" << globalTimeStep
33366 << "\" RangeMax=\"" << globalTimeStep << "\">" << endl;
33367 ofl << globalTimeStep << endl;
33368 ofl << "</DataArray>" << endl;
33369 ofl << "<DataArray type=\"" << dataType << "\" Name=\"Ma\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33370 << m_Ma << "\" RangeMax=\"" << m_Ma << "\">" << endl;
33371 ofl << m_Ma << endl;
33372 ofl << "</DataArray>" << endl;
33373 ofl << "<DataArray type=\"" << dataType << "\" Name=\"Re\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33374 << m_Re << "\" RangeMax=\"" << m_Re << "\">" << endl;
33375 ofl << m_Re << endl;
33376 ofl << "</DataArray>" << endl;
33377 ofl << "<DataArray type=\"" << dataType << "\" Name=\"Pr\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33378 << m_Pr << "\" RangeMax=\"" << m_Pr << "\">" << endl;
33379 ofl << m_Pr << endl;
33380 ofl << "</DataArray>" << endl;
33381 ofl << "<DataArray type=\"" << dataType << "\" Name=\"gamma\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33382 << m_gamma << "\" RangeMax=\"" << m_gamma << "\">" << endl;
33383 ofl << m_gamma << endl;
33384 ofl << "</DataArray>" << endl;
33385 ofl << "<DataArray type=\"" << dataType << "\" Name=\"CFL\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33386 << m_cfl << "\" RangeMax=\"" << m_cfl << "\">" << endl;
33387 ofl << m_cfl << endl;
33388 ofl << "</DataArray>" << endl;
33389 ofl << "<DataArray type=\"" << dataType << "\" Name=\"uInf\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33390 << m_UInfinity << "\" RangeMax=\"" << m_UInfinity << "\">" << endl;
33391 ofl << m_UInfinity << endl;
33392 ofl << "</DataArray>" << endl;
33393 ofl << "<DataArray type=\"" << dataType << "\" Name=\"vInf\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33394 << m_VInfinity << "\" RangeMax=\"" << m_VInfinity << "\">" << endl;
33395 ofl << m_VInfinity << endl;
33396 ofl << "</DataArray>" << endl;
33397 ofl << "<DataArray type=\"" << dataType << "\" Name=\"pInf\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33398 << m_PInfinity << "\" RangeMax=\"" << m_PInfinity << "\">" << endl;
33399 ofl << m_PInfinity << endl;
33400 ofl << "</DataArray>" << endl;
33401 ofl << "<DataArray type=\"" << dataType << "\" Name=\"rhoInf\" format=\"ascii\" NumberOfTuples=\"1\" RangeMin=\""
33402 << m_rhoInfinity << "\" RangeMax=\"" << m_rhoInfinity << "\">" << endl;
33403 ofl << m_rhoInfinity << endl;
33404 ofl << "</DataArray>" << endl;
33405 ofl << "</FieldData>" << endl;
33406
33407 // Dimensions
33408 ofl << "<Piece NumberOfPoints=\"" << noPoints << "\" NumberOfCells=\"" << noCells << "\">" << endl;
33409
33410 // Points
33411 ofl << "<Points>" << endl;
33412 ofl << "<DataArray type=\"" << dataType << "\" NumberOfComponents=\"3\" format=\"appended\" offset=\"" << offset
33413 << "\"/>" << endl;
33414 offset += points.m_memsize + sizeof(MUint);
33415 ofl << "</Points>" << endl;
33416
33417 // Cells
33418 ofl << "<Cells>" << endl;
33419
33420 ofl << "<DataArray type=\"" << uIDataType << "\" Name=\"connectivity\" format=\"appended\" offset=\"" << offset
33421 << "\"/>" << endl;
33422 offset += connectivity.m_memsize + sizeof(MUint);
33423
33424 ofl << "<DataArray type=\"" << uIDataType << "\" Name=\"offsets\" format=\"appended\" offset=\"" << offset << "\"/>"
33425 << endl;
33426 offset += offsets.m_memsize + sizeof(MUint);
33427
33428 ofl << "<DataArray type=\"" << uI8DataType << "\" Name=\"types\" format=\"appended\" offset=\"" << offset << "\"/>"
33429 << endl;
33430 offset += types.m_memsize + sizeof(MUint);
33431
33432 ofl << "</Cells>" << endl;
33433
33434 // CellData/PointData
33435 ofl << "<CellData Scalars=\"scalars\">" << endl;
33436
33437 ofl << "<DataArray type=\"" << iDataType << "\" Name=\"cellIds\" format=\"appended\" offset=\"" << offset << "\"/>"
33438 << endl;
33439 offset += cellIds.m_memsize + sizeof(MUint);
33440
33441 if(m_haloCellOutput) {
33442 ofl << "<DataArray type=\"" << uI8DataType << "\" Name=\"vtkGhostLevels\" format=\"appended\" offset=\"" << offset
33443 << "\"/>" << endl;
33444 offset += vtkGhostLevels.m_memsize + sizeof(MUint);
33445 }
33446
33447#ifdef _MB_DEBUG_
33448 ofl << "<DataArray type=\"" << iDataType << "\" Name=\"bndryIds\" format=\"appended\" offset=\"" << offset << "\"/>"
33449 << endl;
33450 offset += bndryIds.m_memsize + sizeof(MUint);
33451
33452 ofl << "<DataArray type=\"" << dataType64 << "\" Name=\"drho_dt\" format=\"appended\" offset=\"" << offset << "\"/>"
33453 << endl;
33454 offset += drho_dt.m_memsize + sizeof(MUint);
33455
33456 ofl << "<DataArray type=\"" << dataType64 << "\" Name=\"drhou_dt\" format=\"appended\" offset=\"" << offset
33457 << "\"/>" << endl;
33458 offset += drhou_dt.m_memsize + sizeof(MUint);
33459
33460 ofl << "<DataArray type=\"" << dataType << "\" Name=\"levelSetFunction\" format=\"appended\" offset=\"" << offset
33461 << "\"/>" << endl;
33462 offset += levelSetFunction.m_memsize + sizeof(MUint);
33463
33464 ofl << "<DataArray type=\"" << dataType << "\" Name=\"volume\" format=\"appended\" offset=\"" << offset << "\"/>"
33465 << endl;
33466 offset += volume.m_memsize + sizeof(MUint);
33467
33468 ofl << "<DataArray type=\"" << dataType << "\" Name=\"spongeFactor\" format=\"appended\" offset=\"" << offset
33469 << "\"/>" << endl;
33470 offset += spongeFac.m_memsize + sizeof(MUint);
33471
33472 if(sensorOutput) {
33473 ofl << "<DataArray type=\"" << dataType << "\" Name=\"tauC\" format=\"appended\" offset=\"" << offset << "\"/>"
33474 << endl;
33475 offset += tauC.m_memsize + sizeof(MUint);
33476 ofl << "<DataArray type=\"" << dataType << "\" Name=\"tauE\" format=\"appended\" offset=\"" << offset << "\"/>"
33477 << endl;
33478 offset += tauE.m_memsize + sizeof(MUint);
33479 }
33480
33481#endif
33482
33483 if(writePointData) {
33484 ofl << "</CellData>" << endl;
33485 ofl << "<PointData Scalars=\"scalars\">" << endl;
33486 }
33487
33488 ofl << "<DataArray type=\"" << dataType << "\" Name=\"pressure\" format=\"appended\" offset=\"" << offset << "\"/>"
33489 << endl;
33490 offset += pressure.m_memsize + sizeof(MUint);
33491
33492 ofl << "<DataArray type=\"" << dataType
33493 << "\" Name=\"velocity\" NumberOfComponents=\"3\" format=\"appended\" offset=\"" << offset << "\"/>" << endl;
33494 offset += velocity.m_memsize + sizeof(MUint);
33495
33496 ofl << "<DataArray type=\"" << dataType << "\" Name=\"density\" format=\"appended\" offset=\"" << offset << "\"/>"
33497 << endl;
33498 offset += density.m_memsize + sizeof(MUint);
33499
33500 ofl << "<DataArray type=\"" << dataType << "\" Name=\"vorticity\" format=\"appended\" offset=\"" << offset << "\"/>"
33501 << endl;
33502 offset += vorticity.m_memsize + sizeof(MUint);
33503
33504 ofl << "<DataArray type=\"" << dataType << "\" Name=\"Qcriterion\" format=\"appended\" offset=\"" << offset
33505 << "\"/>" << endl;
33506 offset += Qcriterion.m_memsize + sizeof(MUint);
33507
33508 if(entropyChangeOutput) {
33509 ofl << "<DataArray type=\"" << dataType << "\" Name=\"dS\" format=\"appended\" offset=\"" << offset << "\"/>"
33510 << endl;
33511 offset += dS.m_memsize + sizeof(MUint);
33512 }
33513
33514#ifdef _MB_DEBUG_
33515 ofl << "<DataArray type=\"" << dataType << "\" Name=\"rhoE\" format=\"appended\" offset=\"" << offset << "\"/>"
33516 << endl;
33517 offset += rhoE.m_memsize + sizeof(MUint);
33518
33519 if(QThresholdOutput) {
33520 ofl << "<DataArray type=\"" << dataType << "\" Name=\"QThreshold\" format=\"appended\" offset=\"" << offset
33521 << "\"/>" << endl;
33522 offset += QThreshold.m_memsize + sizeof(MUint);
33523 }
33524
33525#endif
33526
33527 if(writePointData) {
33528 ofl << "</PointData>" << endl;
33529 } else {
33530 ofl << "</CellData>" << endl;
33531 }
33532
33533 ofl << "</Piece>" << endl;
33534 ofl << "</UnstructuredGrid>" << endl;
33535
33536 ofl << "<AppendedData encoding=\"raw\">" << endl;
33537 ofl << "_";
33538 ofl.close();
33539 ofl.clear();
33540 } else {
33541 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing! (1)" << endl;
33542 }
33543 ofl.open(fileName.c_str(), ios_base::out | ios_base::app | ios_base::binary);
33544
33545 if(ofl.is_open() && ofl.good()) {
33546 // point coordinates
33547 uinumber = (MUint)points.m_memsize;
33548 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(MUint));
33549 ofl.write(reinterpret_cast<const char*>(points.getPointer()), uinumber);
33550
33551 // connectivity
33552 uinumber = (MUint)connectivity.m_memsize;
33553 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(MUint));
33554 ofl.write(reinterpret_cast<const char*>(connectivity.getPointer()), uinumber);
33555
33556 // offsets
33557 uinumber = (MUint)offsets.m_memsize;
33558 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33559 ofl.write(reinterpret_cast<const char*>(offsets.getPointer()), uinumber);
33560
33561 // cell types
33562 uinumber = (MUint)types.m_memsize;
33563 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33564 ofl.write(reinterpret_cast<const char*>(types.getPointer()), uinumber);
33565
33566 // cellIds
33567 uinumber = (MUint)cellIds.m_memsize;
33568 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33569 ofl.write(reinterpret_cast<const char*>(cellIds.getPointer()), uinumber);
33570
33571 // vtkGhostLevels
33572 if(m_haloCellOutput) {
33573 uinumber = (MUint)vtkGhostLevels.m_memsize;
33574 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33575 ofl.write(reinterpret_cast<const char*>(vtkGhostLevels.getPointer()), uinumber);
33576 }
33577
33578#ifdef _MB_DEBUG_
33579 // bndryIds
33580 uinumber = (MUint)bndryIds.m_memsize;
33581 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33582 ofl.write(reinterpret_cast<const char*>(bndryIds.getPointer()), uinumber);
33583
33584 // drho_dt
33585 uinumber = (MUint)drho_dt.m_memsize;
33586 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33587 ofl.write(reinterpret_cast<const char*>(drho_dt.getPointer()), uinumber);
33588
33589 // drhou_dt
33590 uinumber = (MUint)drhou_dt.m_memsize;
33591 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33592 ofl.write(reinterpret_cast<const char*>(drhou_dt.getPointer()), uinumber);
33593
33594 // levelSetFunction
33595 uinumber = (MUint)levelSetFunction.m_memsize;
33596 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33597 ofl.write(reinterpret_cast<const char*>(levelSetFunction.getPointer()), uinumber);
33598
33599 // volume
33600 uinumber = (MUint)volume.m_memsize;
33601 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33602 ofl.write(reinterpret_cast<const char*>(volume.getPointer()), uinumber);
33603
33604 // spongeFac
33605 uinumber = (MUint)spongeFac.m_memsize;
33606 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33607 ofl.write(reinterpret_cast<const char*>(spongeFac.getPointer()), uinumber);
33608
33609 // tauC / tauE
33610 if(sensorOutput) {
33611 uinumber = (MUint)tauC.m_memsize;
33612 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33613 ofl.write(reinterpret_cast<const char*>(tauC.getPointer()), uinumber);
33614 uinumber = (MUint)tauE.m_memsize;
33615 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33616 ofl.write(reinterpret_cast<const char*>(tauE.getPointer()), uinumber);
33617 }
33618
33619#endif
33620
33621 // pressure
33622 uinumber = (MUint)pressure.m_memsize;
33623 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33624 ofl.write(reinterpret_cast<const char*>(pressure.getPointer()), uinumber);
33625
33626 // velocity
33627 uinumber = (MUint)velocity.m_memsize;
33628 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33629 ofl.write(reinterpret_cast<const char*>(velocity.getPointer()), uinumber);
33630
33631 // density
33632 uinumber = (MUint)density.m_memsize;
33633 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33634 ofl.write(reinterpret_cast<const char*>(density.getPointer()), uinumber);
33635
33636 // vorticity
33637 uinumber = (MUint)vorticity.m_memsize;
33638 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33639 ofl.write(reinterpret_cast<const char*>(vorticity.getPointer()), uinumber);
33640
33641 // Qcriterion
33642 uinumber = (MUint)Qcriterion.m_memsize;
33643 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33644 ofl.write(reinterpret_cast<const char*>(Qcriterion.getPointer()), uinumber);
33645
33646 // dS
33647 if(entropyChangeOutput) {
33648 uinumber = (MUint)dS.m_memsize;
33649 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33650 ofl.write(reinterpret_cast<const char*>(dS.getPointer()), uinumber);
33651 }
33652
33653#ifdef _MB_DEBUG_
33654
33655 // rhoE
33656 uinumber = (MUint)rhoE.m_memsize;
33657 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33658 ofl.write(reinterpret_cast<const char*>(rhoE.getPointer()), uinumber);
33659
33660 if(QThresholdOutput) {
33661 uinumber = (MUint)QThreshold.m_memsize;
33662 ofl.write(reinterpret_cast<const char*>(&uinumber), sizeof(uinumber));
33663 ofl.write(reinterpret_cast<const char*>(QThreshold.getPointer()), uinumber);
33664 }
33665
33666#endif
33667
33668 ofl.close();
33669 ofl.clear();
33670 } else {
33671 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing! (2)" << endl;
33672 }
33673
33674 ofl.open(fileName.c_str(), ios_base::out | ios_base::app);
33675 if(ofl.is_open() && ofl.good()) {
33676 ofl << endl;
33677 ofl << "</AppendedData>" << endl;
33678
33679 ofl << "</VTKFile>" << endl;
33680 ofl.close();
33681 ofl.clear();
33682 } else {
33683 cerr << "ERROR! COULD NOT OPEN FILE " << fileName << " for writing! (3)" << endl;
33684 }
33685}
void append()
Definition: collector.h:153
MFloat & a_spongeFactor(const MInt cellId)
Returns the spongeFactor of the cell cellId.
virtual MFloat entropy(MInt cellId)

Member Data Documentation

◆ execRungeKuttaStep

template<MInt nDim, class SysEqn >
MBool(FvMbCartesianSolverXD::* FvMbCartesianSolverXD< nDim, SysEqn >::execRungeKuttaStep) ()

Definition at line 1105 of file fvmbcartesiansolverxd.h.

◆ FD

template<MInt nDim, class SysEqn >
constexpr MFloat FvMbCartesianSolverXD< nDim, SysEqn >::FD = nDim
staticconstexpr

Definition at line 676 of file fvmbcartesiansolverxd.h.

◆ FvBndryCndXD< nDim, SysEqn >

template<MInt nDim, class SysEqn >
friend FvMbCartesianSolverXD< nDim, SysEqn >::FvBndryCndXD< nDim, SysEqn >

Definition at line 548 of file fvmbcartesiansolverxd.h.

◆ g_mpiRequestMb

template<MInt nDim, class SysEqn >
MPI_Request* FvMbCartesianSolverXD< nDim, SysEqn >::g_mpiRequestMb = nullptr

Definition at line 812 of file fvmbcartesiansolverxd.h.

◆ m_addedMassCoefficient

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_addedMassCoefficient {}

Definition at line 700 of file fvmbcartesiansolverxd.h.

◆ m_alwaysResetCutOff

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_alwaysResetCutOff {}

Definition at line 621 of file fvmbcartesiansolverxd.h.

◆ m_applyCollisionModel

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_applyCollisionModel {}

Definition at line 618 of file fvmbcartesiansolverxd.h.

◆ m_applyRotationalCollisionModel

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_applyRotationalCollisionModel {}

Definition at line 619 of file fvmbcartesiansolverxd.h.

◆ m_area

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_area = nullptr

Definition at line 842 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalBndryCandidateIds

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalBndryCandidateIds

Definition at line 779 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalBndryCandidates

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalBndryCandidates

Definition at line 778 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalCornerEps

template<MInt nDim, class SysEqn >
const MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalCornerEps = 0.01

Definition at line 838 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalLinkedHaloCells

template<MInt nDim, class SysEqn >
std::vector<std::vector<MInt> > FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalLinkedHaloCells

Definition at line 828 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalLinkedWindowCells

template<MInt nDim, class SysEqn >
std::vector<std::vector<MInt> > FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalLinkedWindowCells

Definition at line 829 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalNearBoundaryBackup

template<MInt nDim, class SysEqn >
std::multimap<MLong, std::pair<std::vector<MFloat>, std::vector<MUlong> > > FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalNearBoundaryBackup

Definition at line 830 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalNearBoundaryBackupBalFloat

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalNearBoundaryBackupBalFloat

Definition at line 832 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalNearBoundaryBackupBalLong

template<MInt nDim, class SysEqn >
MLong* FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalNearBoundaryBackupBalLong

Definition at line 833 of file fvmbcartesiansolverxd.h.

◆ m_azimuthalWasNearBndryIds

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_azimuthalWasNearBndryIds

Definition at line 831 of file fvmbcartesiansolverxd.h.

◆ m_bbox

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bbox = nullptr

Definition at line 808 of file fvmbcartesiansolverxd.h.

◆ m_bboxLocal

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bboxLocal = nullptr

Definition at line 809 of file fvmbcartesiansolverxd.h.

◆ m_bndryCandidateIds

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_bndryCandidateIds

Definition at line 776 of file fvmbcartesiansolverxd.h.

◆ m_bndryCandidates

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_bndryCandidates

Definition at line 774 of file fvmbcartesiansolverxd.h.

◆ m_bndryLayerCells

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_bndryLayerCells

Definition at line 782 of file fvmbcartesiansolverxd.h.

◆ m_bodyAccelerationDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyAccelerationDt1 = nullptr

Definition at line 712 of file fvmbcartesiansolverxd.h.

◆ m_bodyAccelerationDt2

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyAccelerationDt2 = nullptr

Definition at line 713 of file fvmbcartesiansolverxd.h.

◆ m_bodyAccelerationDt3

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyAccelerationDt3 = nullptr

Definition at line 714 of file fvmbcartesiansolverxd.h.

◆ m_bodyAngularAccelerationDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyAngularAccelerationDt1 = nullptr

Definition at line 722 of file fvmbcartesiansolverxd.h.

◆ m_bodyAngularVelocityDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyAngularVelocityDt1 = nullptr

Definition at line 721 of file fvmbcartesiansolverxd.h.

◆ m_bodyCenterDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyCenterDt1 = nullptr

Definition at line 724 of file fvmbcartesiansolverxd.h.

◆ m_bodyCenterDt2

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyCenterDt2 = nullptr

Definition at line 725 of file fvmbcartesiansolverxd.h.

◆ m_bodyCenterInitial

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyCenterInitial = nullptr

Definition at line 726 of file fvmbcartesiansolverxd.h.

◆ m_bodyCenters

template<MInt nDim, class SysEqn >
std::vector<Point<nDim> > FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyCenters

Definition at line 545 of file fvmbcartesiansolverxd.h.

◆ m_bodyCentersLocal

template<MInt nDim, class SysEqn >
std::vector<Point<nDim> > FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyCentersLocal

Definition at line 546 of file fvmbcartesiansolverxd.h.

◆ m_bodyDampingCoefficient

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDampingCoefficient = nullptr

Definition at line 786 of file fvmbcartesiansolverxd.h.

◆ m_bodyDataAverage

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDataAverage = nullptr

Definition at line 734 of file fvmbcartesiansolverxd.h.

◆ m_bodyDataAverage2

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDataAverage2 = nullptr

Definition at line 735 of file fvmbcartesiansolverxd.h.

◆ m_bodyDataCollision

template<MInt nDim, class SysEqn >
MBool* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDataCollision = nullptr

Definition at line 738 of file fvmbcartesiansolverxd.h.

◆ m_bodyDataDevAverage

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDataDevAverage = nullptr

Definition at line 736 of file fvmbcartesiansolverxd.h.

◆ m_bodyDensity

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDensity = nullptr

Definition at line 710 of file fvmbcartesiansolverxd.h.

◆ m_bodyDiameter

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDiameter = nullptr

Definition at line 696 of file fvmbcartesiansolverxd.h.

◆ m_bodyDistThreshold

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyDistThreshold {}

Definition at line 686 of file fvmbcartesiansolverxd.h.

◆ m_bodyEquation

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyEquation = nullptr

Definition at line 731 of file fvmbcartesiansolverxd.h.

◆ m_bodyForce

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyForce = nullptr

Definition at line 719 of file fvmbcartesiansolverxd.h.

◆ m_bodyForceDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyForceDt1 = nullptr

Definition at line 720 of file fvmbcartesiansolverxd.h.

◆ m_bodyInCollision

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyInCollision = nullptr

Definition at line 732 of file fvmbcartesiansolverxd.h.

◆ m_bodyMass

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyMass = nullptr

Definition at line 698 of file fvmbcartesiansolverxd.h.

◆ m_bodyMomentOfInertia

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyMomentOfInertia = nullptr

Definition at line 711 of file fvmbcartesiansolverxd.h.

◆ m_bodyNearDomain

template<MInt nDim, class SysEqn >
MBool* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyNearDomain = nullptr

Definition at line 733 of file fvmbcartesiansolverxd.h.

◆ m_bodyNeutralCenter

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyNeutralCenter = nullptr

Definition at line 730 of file fvmbcartesiansolverxd.h.

◆ m_bodyQuaternion

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyQuaternion = nullptr

Definition at line 708 of file fvmbcartesiansolverxd.h.

◆ m_bodyQuaternionDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyQuaternionDt1 = nullptr

Definition at line 709 of file fvmbcartesiansolverxd.h.

◆ m_bodyRadii

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyRadii = nullptr

Definition at line 695 of file fvmbcartesiansolverxd.h.

◆ m_bodyRadius

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyRadius = nullptr

Definition at line 692 of file fvmbcartesiansolverxd.h.

◆ m_bodyReducedFrequency

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyReducedFrequency = nullptr

Definition at line 785 of file fvmbcartesiansolverxd.h.

◆ m_bodyReducedMass

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyReducedMass = nullptr

Definition at line 784 of file fvmbcartesiansolverxd.h.

◆ m_bodyReducedVelocity

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyReducedVelocity = nullptr

Definition at line 783 of file fvmbcartesiansolverxd.h.

◆ m_bodySamplingInterval

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_bodySamplingInterval {}

Definition at line 584 of file fvmbcartesiansolverxd.h.

◆ m_bodySumAverage

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodySumAverage = nullptr

Definition at line 737 of file fvmbcartesiansolverxd.h.

◆ m_bodyTerminalVelocity

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyTerminalVelocity = nullptr

Definition at line 727 of file fvmbcartesiansolverxd.h.

◆ m_bodyTorque

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyTorque = nullptr

Definition at line 717 of file fvmbcartesiansolverxd.h.

◆ m_bodyTorqueDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyTorqueDt1 = nullptr

Definition at line 718 of file fvmbcartesiansolverxd.h.

◆ m_bodyToSetTable

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyToSetTable = nullptr

Definition at line 672 of file fvmbcartesiansolverxd.h.

◆ m_bodyTree

template<MInt nDim, class SysEqn >
KDtree<nDim>* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyTree = nullptr

Definition at line 543 of file fvmbcartesiansolverxd.h.

◆ m_bodyTreeLocal

template<MInt nDim, class SysEqn >
KDtree<nDim>* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyTreeLocal = nullptr

Definition at line 544 of file fvmbcartesiansolverxd.h.

◆ m_bodyTypeMb

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyTypeMb {}

Definition at line 592 of file fvmbcartesiansolverxd.h.

◆ m_bodyVelocityDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyVelocityDt1 = nullptr

Definition at line 715 of file fvmbcartesiansolverxd.h.

◆ m_bodyVelocityDt2

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyVelocityDt2 = nullptr

Definition at line 716 of file fvmbcartesiansolverxd.h.

◆ m_bodyVolume

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyVolume = nullptr

Definition at line 697 of file fvmbcartesiansolverxd.h.

◆ m_bodyWasActuallyInCollision

template<MInt nDim, class SysEqn >
std::set<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyWasActuallyInCollision

Definition at line 771 of file fvmbcartesiansolverxd.h.

◆ m_bodyWasInCollision

template<MInt nDim, class SysEqn >
std::set<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_bodyWasInCollision

Definition at line 770 of file fvmbcartesiansolverxd.h.

◆ m_boundaryDensityDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_boundaryDensityDt1 = nullptr

Definition at line 800 of file fvmbcartesiansolverxd.h.

◆ m_boundaryPressureDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_boundaryPressureDt1 = nullptr

Definition at line 799 of file fvmbcartesiansolverxd.h.

◆ m_buildCollectedLevelSetFunction

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_buildCollectedLevelSetFunction = false

Definition at line 668 of file fvmbcartesiansolverxd.h.

◆ m_candidateNodeSet

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_candidateNodeSet

Definition at line 781 of file fvmbcartesiansolverxd.h.

◆ m_candidateNodeValues

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_candidateNodeValues

Definition at line 780 of file fvmbcartesiansolverxd.h.

◆ m_capacityConstantVolumeRatio

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_capacityConstantVolumeRatio {}

Definition at line 702 of file fvmbcartesiansolverxd.h.

◆ m_cellCoordinates

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_cellCoordinates = nullptr

Definition at line 844 of file fvmbcartesiansolverxd.h.

◆ m_cellSlopes

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_cellSlopes = nullptr

Definition at line 846 of file fvmbcartesiansolverxd.h.

◆ m_cellVolumesDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_cellVolumesDt1 = nullptr

Definition at line 797 of file fvmbcartesiansolverxd.h.

◆ m_cellVolumesDt2

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_cellVolumesDt2 = nullptr

Definition at line 798 of file fvmbcartesiansolverxd.h.

◆ m_centralizeSurfaceVariables

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_centralizeSurfaceVariables {}

Definition at line 616 of file fvmbcartesiansolverxd.h.

◆ m_cflInitial

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_cflInitial {}

Definition at line 613 of file fvmbcartesiansolverxd.h.

◆ m_cflTarget

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_cflTarget {}

Definition at line 614 of file fvmbcartesiansolverxd.h.

◆ m_coarseOldBndryCells

template<MInt nDim, class SysEqn >
std::set<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_coarseOldBndryCells

Definition at line 826 of file fvmbcartesiansolverxd.h.

◆ m_complexBoundary

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_complexBoundary {}

Definition at line 605 of file fvmbcartesiansolverxd.h.

◆ m_conservationCheck

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_conservationCheck {}

Definition at line 606 of file fvmbcartesiansolverxd.h.

◆ m_coupling

template<MInt nDim, class SysEqn >
MFloat** FvMbCartesianSolverXD< nDim, SysEqn >::m_coupling = nullptr

Definition at line 704 of file fvmbcartesiansolverxd.h.

◆ m_couplingRate

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_couplingRate {}

Definition at line 703 of file fvmbcartesiansolverxd.h.

◆ m_couplingRateLinear

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_couplingRateLinear {}

Definition at line 705 of file fvmbcartesiansolverxd.h.

◆ m_couplingRatePressure

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_couplingRatePressure {}

Definition at line 706 of file fvmbcartesiansolverxd.h.

◆ m_couplingRateViscous

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_couplingRateViscous {}

Definition at line 707 of file fvmbcartesiansolverxd.h.

◆ m_cutCandidates

template<MInt nDim, class SysEqn >
std::vector<CutCandidate<nDim> > FvMbCartesianSolverXD< nDim, SysEqn >::m_cutCandidates

Definition at line 775 of file fvmbcartesiansolverxd.h.

◆ m_cutFaceArea

template<MInt nDim, class SysEqn >
MFloat** FvMbCartesianSolverXD< nDim, SysEqn >::m_cutFaceArea = nullptr

Definition at line 805 of file fvmbcartesiansolverxd.h.

◆ m_cutFacePointIds

template<MInt nDim, class SysEqn >
MInt** FvMbCartesianSolverXD< nDim, SysEqn >::m_cutFacePointIds = nullptr

Definition at line 804 of file fvmbcartesiansolverxd.h.

◆ m_densityRatio

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_densityRatio {}

Definition at line 701 of file fvmbcartesiansolverxd.h.

◆ m_distThresholdStat

template<MInt nDim, class SysEqn >
constexpr MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_distThresholdStat = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0}
staticconstexpr

Definition at line 853 of file fvmbcartesiansolverxd.h.

◆ m_dynamicStencil

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_dynamicStencil {}

Definition at line 629 of file fvmbcartesiansolverxd.h.

◆ m_firstStats

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_firstStats = true

Definition at line 851 of file fvmbcartesiansolverxd.h.

◆ m_fixedBodyComponents

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_fixedBodyComponents = nullptr

Definition at line 728 of file fvmbcartesiansolverxd.h.

◆ m_fixedBodyComponentsRotation

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_fixedBodyComponentsRotation = nullptr

Definition at line 729 of file fvmbcartesiansolverxd.h.

◆ m_forceAdaptation

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_forceAdaptation = false

Definition at line 740 of file fvmbcartesiansolverxd.h.

◆ m_forceFVMBStatistics

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_forceFVMBStatistics

Definition at line 1167 of file fvmbcartesiansolverxd.h.

◆ m_forceNoGaps

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_forceNoGaps

Definition at line 883 of file fvmbcartesiansolverxd.h.

◆ m_Fr

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_Fr {}

Definition at line 602 of file fvmbcartesiansolverxd.h.

◆ m_freeSurfaceIndices

template<MInt nDim, class SysEqn >
std::set<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_freeSurfaceIndices

Definition at line 815 of file fvmbcartesiansolverxd.h.

◆ m_FSIStart

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_FSIStart {}

Definition at line 590 of file fvmbcartesiansolverxd.h.

◆ m_FSIToleranceR

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_FSIToleranceR {}

Definition at line 596 of file fvmbcartesiansolverxd.h.

◆ m_FSIToleranceU

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_FSIToleranceU {}

Definition at line 593 of file fvmbcartesiansolverxd.h.

◆ m_FSIToleranceW

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_FSIToleranceW {}

Definition at line 595 of file fvmbcartesiansolverxd.h.

◆ m_FSIToleranceX

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_FSIToleranceX {}

Definition at line 594 of file fvmbcartesiansolverxd.h.

◆ m_fvBndryCnd

template<MInt nDim, class SysEqn >
FvBndryCndXD<nDim, SysEqn>* FvMbCartesianSolverXD< nDim, SysEqn >::m_fvBndryCnd = nullptr

Definition at line 1257 of file fvmbcartesiansolverxd.h.

◆ m_g

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_g {}

Definition at line 603 of file fvmbcartesiansolverxd.h.

◆ m_gammaMinusOne

template<MInt nDim, class SysEqn >
const MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_gammaMinusOne

Definition at line 682 of file fvmbcartesiansolverxd.h.

◆ m_gapAngleClose

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_gapAngleClose = nullptr

Definition at line 880 of file fvmbcartesiansolverxd.h.

◆ m_gapAngleOpen

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_gapAngleOpen = nullptr

Definition at line 881 of file fvmbcartesiansolverxd.h.

◆ m_gapCellExchangeInit

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_gapCellExchangeInit = false

Definition at line 637 of file fvmbcartesiansolverxd.h.

◆ m_gapHaloCells

template<MInt nDim, class SysEqn >
std::vector<MInt>* FvMbCartesianSolverXD< nDim, SysEqn >::m_gapHaloCells = nullptr

Definition at line 636 of file fvmbcartesiansolverxd.h.

◆ m_gapOpened

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_gapOpened {}

Definition at line 666 of file fvmbcartesiansolverxd.h.

◆ m_gapSign

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_gapSign = nullptr

Definition at line 882 of file fvmbcartesiansolverxd.h.

◆ m_gapState

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_gapState = nullptr

Definition at line 640 of file fvmbcartesiansolverxd.h.

◆ m_gapWindowCells

template<MInt nDim, class SysEqn >
std::vector<MInt>* FvMbCartesianSolverXD< nDim, SysEqn >::m_gapWindowCells = nullptr

Definition at line 635 of file fvmbcartesiansolverxd.h.

◆ m_gclIntermediate

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_gclIntermediate {}

Definition at line 608 of file fvmbcartesiansolverxd.h.

◆ m_generateOuterBndryCells

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_generateOuterBndryCells {}

Definition at line 617 of file fvmbcartesiansolverxd.h.

◆ m_geometryChange

template<MInt nDim, class SysEqn >
MBool* FvMbCartesianSolverXD< nDim, SysEqn >::m_geometryChange = nullptr

Definition at line 632 of file fvmbcartesiansolverxd.h.

◆ m_geometryIntersection

template<MInt nDim, class SysEqn >
GeometryIntersection<nDim>* FvMbCartesianSolverXD< nDim, SysEqn >::m_geometryIntersection = nullptr

Definition at line 1256 of file fvmbcartesiansolverxd.h.

◆ m_gravity

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_gravity = nullptr

Definition at line 689 of file fvmbcartesiansolverxd.h.

◆ m_gridCellArea

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_gridCellArea = nullptr

Definition at line 688 of file fvmbcartesiansolverxd.h.

◆ m_haloCellOutput

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_haloCellOutput {}

Definition at line 604 of file fvmbcartesiansolverxd.h.

◆ m_hydroForce

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_hydroForce = nullptr

Definition at line 723 of file fvmbcartesiansolverxd.h.

◆ m_initGapCell

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_initGapCell = true

Definition at line 639 of file fvmbcartesiansolverxd.h.

◆ m_initialSurfacesOffset

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_initialSurfacesOffset {}

Definition at line 649 of file fvmbcartesiansolverxd.h.

◆ m_killSwitchCheckInterval

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_killSwitchCheckInterval {}

Definition at line 598 of file fvmbcartesiansolverxd.h.

◆ m_linkedHaloCells

template<MInt nDim, class SysEqn >
std::vector<MInt>* FvMbCartesianSolverXD< nDim, SysEqn >::m_linkedHaloCells = nullptr

Definition at line 795 of file fvmbcartesiansolverxd.h.

◆ m_linkedWindowCells

template<MInt nDim, class SysEqn >
std::vector<MInt>* FvMbCartesianSolverXD< nDim, SysEqn >::m_linkedWindowCells = nullptr

Definition at line 794 of file fvmbcartesiansolverxd.h.

◆ m_logBoundaryData

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_logBoundaryData {}

Definition at line 580 of file fvmbcartesiansolverxd.h.

◆ m_loggingInterval

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_loggingInterval {}

Definition at line 583 of file fvmbcartesiansolverxd.h.

◆ m_lsCutCellLevel

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_lsCutCellLevel = nullptr

Definition at line 627 of file fvmbcartesiansolverxd.h.

◆ m_lsCutCellMinLevel

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_lsCutCellMinLevel

Definition at line 626 of file fvmbcartesiansolverxd.h.

◆ m_LsMovement

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_LsMovement {}

Definition at line 620 of file fvmbcartesiansolverxd.h.

◆ m_massRedistributionIds

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_massRedistributionIds

Definition at line 820 of file fvmbcartesiansolverxd.h.

◆ m_massRedistributionRhs

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_massRedistributionRhs

Definition at line 822 of file fvmbcartesiansolverxd.h.

◆ m_massRedistributionSweptVol

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_massRedistributionSweptVol

Definition at line 824 of file fvmbcartesiansolverxd.h.

◆ m_massRedistributionVariables

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_massRedistributionVariables

Definition at line 821 of file fvmbcartesiansolverxd.h.

◆ m_massRedistributionVolume

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_massRedistributionVolume

Definition at line 823 of file fvmbcartesiansolverxd.h.

◆ m_maxBndryLayerDistances

template<MInt nDim, class SysEqn >
MFloat** FvMbCartesianSolverXD< nDim, SysEqn >::m_maxBndryLayerDistances = nullptr

Definition at line 787 of file fvmbcartesiansolverxd.h.

◆ m_maxBndryLayerLevel

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_maxBndryLayerLevel {}

Definition at line 587 of file fvmbcartesiansolverxd.h.

◆ m_maxBndryLayerWidth

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_maxBndryLayerWidth {}

Definition at line 588 of file fvmbcartesiansolverxd.h.

◆ m_maxBodyRadius

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_maxBodyRadius {}

Definition at line 694 of file fvmbcartesiansolverxd.h.

◆ m_maxLevelChange

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_maxLevelChange = false

Definition at line 628 of file fvmbcartesiansolverxd.h.

◆ m_maxLevelDecrease

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_maxLevelDecrease = false

Definition at line 601 of file fvmbcartesiansolverxd.h.

◆ m_maxNoEmbeddedBodiesPeriodic

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_maxNoEmbeddedBodiesPeriodic {}

Definition at line 648 of file fvmbcartesiansolverxd.h.

◆ m_maxNoSampleNghbrs

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_maxNoSampleNghbrs {}

Definition at line 683 of file fvmbcartesiansolverxd.h.

◆ m_maxNoSurfacePointSamples

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_maxNoSurfacePointSamples {}

Definition at line 661 of file fvmbcartesiansolverxd.h.

◆ m_maxStructureSteps

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_maxStructureSteps {}

Definition at line 659 of file fvmbcartesiansolverxd.h.

◆ m_minBodyRadius

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_minBodyRadius {}

Definition at line 693 of file fvmbcartesiansolverxd.h.

◆ m_motionEquation

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_motionEquation {}

Definition at line 581 of file fvmbcartesiansolverxd.h.

◆ m_movingBndryCndId

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_movingBndryCndId {}

Definition at line 582 of file fvmbcartesiansolverxd.h.

◆ m_movingPosDiff

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_movingPosDiff

Definition at line 573 of file fvmbcartesiansolverxd.h.

◆ m_nearBoundaryBackup

template<MInt nDim, class SysEqn >
std::map<MInt, std::vector<MFloat> > FvMbCartesianSolverXD< nDim, SysEqn >::m_nearBoundaryBackup

Definition at line 818 of file fvmbcartesiansolverxd.h.

◆ m_nghbrList

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_nghbrList = nullptr

Definition at line 810 of file fvmbcartesiansolverxd.h.

◆ m_noAngleSetups

template<MInt nDim, class SysEqn >
constexpr MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noAngleSetups = 3
staticconstexpr

Definition at line 857 of file fvmbcartesiansolverxd.h.

◆ m_noAzimuthalBndryCandidates

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noAzimuthalBndryCandidates {}

Definition at line 655 of file fvmbcartesiansolverxd.h.

◆ m_noBndryCandidates

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noBndryCandidates {}

Definition at line 654 of file fvmbcartesiansolverxd.h.

◆ m_noBndryCells

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noBndryCells {}

Definition at line 647 of file fvmbcartesiansolverxd.h.

◆ m_noBodiesInSet

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_noBodiesInSet = nullptr

Definition at line 671 of file fvmbcartesiansolverxd.h.

◆ m_noCellNodes

template<MInt nDim, class SysEqn >
constexpr MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noCellNodes = IPOW2(nDim)
staticconstexpr

Definition at line 677 of file fvmbcartesiansolverxd.h.

◆ m_noCutCellFaces

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_noCutCellFaces = nullptr

Definition at line 802 of file fvmbcartesiansolverxd.h.

◆ m_noCutFacePoints

template<MInt nDim, class SysEqn >
MInt** FvMbCartesianSolverXD< nDim, SysEqn >::m_noCutFacePoints = nullptr

Definition at line 803 of file fvmbcartesiansolverxd.h.

◆ m_noCVars

template<MInt nDim, class SysEqn >
const MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noCVars

Definition at line 678 of file fvmbcartesiansolverxd.h.

◆ m_noDistSetups

template<MInt nDim, class SysEqn >
constexpr MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noDistSetups = 3
staticconstexpr

Definition at line 858 of file fvmbcartesiansolverxd.h.

◆ m_noEmergedCells

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noEmergedCells {}

Definition at line 652 of file fvmbcartesiansolverxd.h.

◆ m_noEmergedWindowCells

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noEmergedWindowCells {}

Definition at line 653 of file fvmbcartesiansolverxd.h.

◆ m_noFloatDataAdaptation

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noFloatDataAdaptation = 0

Definition at line 835 of file fvmbcartesiansolverxd.h.

◆ m_noFloatDataBalance

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noFloatDataBalance = 0

Definition at line 834 of file fvmbcartesiansolverxd.h.

◆ m_noFlowCells

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noFlowCells {}

Definition at line 644 of file fvmbcartesiansolverxd.h.

◆ m_noFVars

template<MInt nDim, class SysEqn >
const MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noFVars

Definition at line 679 of file fvmbcartesiansolverxd.h.

◆ m_noGCells

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noGCells {}

Definition at line 645 of file fvmbcartesiansolverxd.h.

◆ m_noLongData

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noLongData = 0

Definition at line 836 of file fvmbcartesiansolverxd.h.

◆ m_noLongDataBalance

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noLongDataBalance = 0

Definition at line 837 of file fvmbcartesiansolverxd.h.

◆ m_noLsMbBndryCells

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noLsMbBndryCells {}

Definition at line 651 of file fvmbcartesiansolverxd.h.

◆ m_noMeanStatistics

template<MInt nDim, class SysEqn >
constexpr MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noMeanStatistics = 6
staticconstexpr

Definition at line 852 of file fvmbcartesiansolverxd.h.

◆ m_noNearBndryCells

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noNearBndryCells {}

Definition at line 656 of file fvmbcartesiansolverxd.h.

◆ m_noneGapRegions

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_noneGapRegions = true

Definition at line 638 of file fvmbcartesiansolverxd.h.

◆ m_noOuterBoundarySurfaces

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noOuterBoundarySurfaces {}

Definition at line 650 of file fvmbcartesiansolverxd.h.

◆ m_noPointParticles

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noPointParticles {}

Definition at line 662 of file fvmbcartesiansolverxd.h.

◆ m_noPointParticlesLocal

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noPointParticlesLocal {}

Definition at line 663 of file fvmbcartesiansolverxd.h.

◆ m_noPVars

template<MInt nDim, class SysEqn >
const MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noPVars

Definition at line 680 of file fvmbcartesiansolverxd.h.

◆ m_noSlipDataOutputs

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noSlipDataOutputs

Definition at line 862 of file fvmbcartesiansolverxd.h.

◆ m_noSlopes

template<MInt nDim, class SysEqn >
const MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noSlopes

Definition at line 681 of file fvmbcartesiansolverxd.h.

◆ m_noSurfacePointSamples

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noSurfacePointSamples {}

Definition at line 660 of file fvmbcartesiansolverxd.h.

◆ m_noSurfaces

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_noSurfaces {}

Definition at line 646 of file fvmbcartesiansolverxd.h.

◆ m_oldBndryCells

template<MInt nDim, class SysEqn >
std::map<MInt, MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_oldBndryCells

Definition at line 817 of file fvmbcartesiansolverxd.h.

◆ m_oldBodyPosition

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_oldBodyPosition

Definition at line 571 of file fvmbcartesiansolverxd.h.

◆ m_oldGeomBndryCells

template<MInt nDim, class SysEqn >
std::map<MInt, MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_oldGeomBndryCells

Definition at line 631 of file fvmbcartesiansolverxd.h.

◆ m_oldMeanState

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_oldMeanState[m_noMeanStatistics][4] {}

Definition at line 854 of file fvmbcartesiansolverxd.h.

◆ m_oldVars

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_oldVars = nullptr

Definition at line 848 of file fvmbcartesiansolverxd.h.

◆ m_onlineRestart

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_onlineRestart {}

Definition at line 609 of file fvmbcartesiansolverxd.h.

◆ m_onlineRestartInterval

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_onlineRestartInterval {}

Definition at line 586 of file fvmbcartesiansolverxd.h.

◆ m_outsideFactor

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_outsideFactor {}

Definition at line 597 of file fvmbcartesiansolverxd.h.

◆ m_particleAcceleration

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleAcceleration

Definition at line 756 of file fvmbcartesiansolverxd.h.

◆ m_particleAccelerationDt1

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleAccelerationDt1

Definition at line 757 of file fvmbcartesiansolverxd.h.

◆ m_particleAngularAcceleration

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleAngularAcceleration

Definition at line 763 of file fvmbcartesiansolverxd.h.

◆ m_particleAngularAccelerationDt1

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleAngularAccelerationDt1

Definition at line 764 of file fvmbcartesiansolverxd.h.

◆ m_particleAngularVelocity

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleAngularVelocity

Definition at line 760 of file fvmbcartesiansolverxd.h.

◆ m_particleAngularVelocityDt1

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleAngularVelocityDt1

Definition at line 761 of file fvmbcartesiansolverxd.h.

◆ m_particleCellLink

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleCellLink

Definition at line 767 of file fvmbcartesiansolverxd.h.

◆ m_particleCoords

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleCoords

Definition at line 746 of file fvmbcartesiansolverxd.h.

◆ m_particleCoordsDt1

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleCoordsDt1

Definition at line 747 of file fvmbcartesiansolverxd.h.

◆ m_particleCoordsInitial

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleCoordsInitial

Definition at line 748 of file fvmbcartesiansolverxd.h.

◆ m_particleFluidTemperature

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleFluidTemperature

Definition at line 755 of file fvmbcartesiansolverxd.h.

◆ m_particleGlobalId

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleGlobalId

Definition at line 768 of file fvmbcartesiansolverxd.h.

◆ m_particleHeatFlux

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleHeatFlux

Definition at line 752 of file fvmbcartesiansolverxd.h.

◆ m_particleOffsets

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleOffsets

Definition at line 863 of file fvmbcartesiansolverxd.h.

◆ m_particleQuaternions

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleQuaternions

Definition at line 758 of file fvmbcartesiansolverxd.h.

◆ m_particleQuaternionsDt1

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleQuaternionsDt1

Definition at line 759 of file fvmbcartesiansolverxd.h.

◆ m_particleRadii

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleRadii

Definition at line 766 of file fvmbcartesiansolverxd.h.

◆ m_particleSamplingInterval

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_particleSamplingInterval {}

Definition at line 585 of file fvmbcartesiansolverxd.h.

◆ m_particleShapeParams

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleShapeParams

Definition at line 765 of file fvmbcartesiansolverxd.h.

◆ m_particleTemperature

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleTemperature

Definition at line 750 of file fvmbcartesiansolverxd.h.

◆ m_particleTemperatureDt1

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleTemperatureDt1

Definition at line 751 of file fvmbcartesiansolverxd.h.

◆ m_particleTerminalVelocity

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_particleTerminalVelocity = nullptr

Definition at line 745 of file fvmbcartesiansolverxd.h.

◆ m_particleVelocity

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleVelocity

Definition at line 749 of file fvmbcartesiansolverxd.h.

◆ m_particleVelocityDt1

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleVelocityDt1

Definition at line 753 of file fvmbcartesiansolverxd.h.

◆ m_particleVelocityFluid

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleVelocityFluid

Definition at line 754 of file fvmbcartesiansolverxd.h.

◆ m_particleVelocityGradientFluid

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_particleVelocityGradientFluid

Definition at line 762 of file fvmbcartesiansolverxd.h.

◆ m_periodicGhostBodies

template<MInt nDim, class SysEqn >
std::vector<MInt>* FvMbCartesianSolverXD< nDim, SysEqn >::m_periodicGhostBodies = nullptr

Definition at line 769 of file fvmbcartesiansolverxd.h.

◆ m_periodicGhostBodyDist

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_periodicGhostBodyDist {}

Definition at line 687 of file fvmbcartesiansolverxd.h.

◆ m_physicalTimeDt1

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_physicalTimeDt1 {}

Definition at line 610 of file fvmbcartesiansolverxd.h.

◆ m_pointIsInside

template<MInt nDim, class SysEqn >
MBool** FvMbCartesianSolverXD< nDim, SysEqn >::m_pointIsInside = nullptr

Definition at line 801 of file fvmbcartesiansolverxd.h.

◆ m_pointParticleTwoWayCoupling

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_pointParticleTwoWayCoupling {}

Definition at line 743 of file fvmbcartesiansolverxd.h.

◆ m_pointParticleType

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_pointParticleType {}

Definition at line 744 of file fvmbcartesiansolverxd.h.

◆ m_previousTimeStep

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_previousTimeStep {}

Definition at line 615 of file fvmbcartesiansolverxd.h.

◆ m_printHeaderCorr

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_printHeaderCorr = true

Definition at line 855 of file fvmbcartesiansolverxd.h.

◆ m_printHeaderSlip

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_printHeaderSlip = true

Definition at line 856 of file fvmbcartesiansolverxd.h.

◆ m_projectedArea

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_projectedArea = nullptr

Definition at line 699 of file fvmbcartesiansolverxd.h.

◆ m_receiveBufferSize

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_receiveBufferSize = nullptr

Definition at line 814 of file fvmbcartesiansolverxd.h.

◆ m_reconstructionOffset

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_reconstructionOffset {}

Definition at line 657 of file fvmbcartesiansolverxd.h.

◆ m_reConstSVDWeightMode

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_reConstSVDWeightMode {}

Definition at line 624 of file fvmbcartesiansolverxd.h.

◆ m_refOldBndryCells

template<MInt nDim, class SysEqn >
std::vector<MInt> FvMbCartesianSolverXD< nDim, SysEqn >::m_refOldBndryCells

Definition at line 825 of file fvmbcartesiansolverxd.h.

◆ m_rhoU2

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_rhoU2 {}

Definition at line 685 of file fvmbcartesiansolverxd.h.

◆ m_rhsViscous

template<MInt nDim, class SysEqn >
MFloat** FvMbCartesianSolverXD< nDim, SysEqn >::m_rhsViscous = nullptr

Definition at line 793 of file fvmbcartesiansolverxd.h.

◆ m_sampleCoordinates

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_sampleCoordinates = nullptr

Definition at line 806 of file fvmbcartesiansolverxd.h.

◆ m_sampleNghbrOffsets

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_sampleNghbrOffsets = nullptr

Definition at line 665 of file fvmbcartesiansolverxd.h.

◆ m_sampleNghbrs

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_sampleNghbrs = nullptr

Definition at line 664 of file fvmbcartesiansolverxd.h.

◆ m_sampleNormals

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_sampleNormals = nullptr

Definition at line 807 of file fvmbcartesiansolverxd.h.

◆ m_saveSlipData

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_saveSlipData

Definition at line 859 of file fvmbcartesiansolverxd.h.

◆ m_saveSlipInterval

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_saveSlipInterval

Definition at line 861 of file fvmbcartesiansolverxd.h.

◆ m_sendBufferSize

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_sendBufferSize = nullptr

Definition at line 813 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleAngularVel

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleAngularVel = nullptr

Definition at line 867 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleCollision

template<MInt nDim, class SysEqn >
MInt* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleCollision = nullptr

Definition at line 864 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleFluidVel

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleFluidVel = nullptr

Definition at line 870 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleFluidVelGrad

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleFluidVelGrad = nullptr

Definition at line 871 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleFluidVelGradRnd

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleFluidVelGradRnd = nullptr

Definition at line 874 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleFluidVelRnd

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleFluidVelRnd = nullptr

Definition at line 873 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleFluidVelRot

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleFluidVelRot = nullptr

Definition at line 872 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleFluidVelRotRnd

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleFluidVelRotRnd = nullptr

Definition at line 875 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleForce

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleForce = nullptr

Definition at line 868 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticlePosition

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticlePosition = nullptr

Definition at line 876 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleQuaternion

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleQuaternion = nullptr

Definition at line 865 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleTorque

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleTorque = nullptr

Definition at line 869 of file fvmbcartesiansolverxd.h.

◆ m_slipDataParticleVel

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataParticleVel = nullptr

Definition at line 866 of file fvmbcartesiansolverxd.h.

◆ m_slipDataTimeSteps

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvMbCartesianSolverXD< nDim, SysEqn >::m_slipDataTimeSteps

Definition at line 877 of file fvmbcartesiansolverxd.h.

◆ m_slipInterval

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_slipInterval

Definition at line 860 of file fvmbcartesiansolverxd.h.

◆ m_slope

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_slope = nullptr

Definition at line 841 of file fvmbcartesiansolverxd.h.

◆ m_solutionDiverged

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_solutionDiverged {}

Definition at line 599 of file fvmbcartesiansolverxd.h.

◆ m_solverType

template<MInt nDim, class SysEqn >
SolverType FvMbCartesianSolverXD< nDim, SysEqn >::m_solverType

Definition at line 600 of file fvmbcartesiansolverxd.h.

◆ m_stableCellVolume

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_stableCellVolume = nullptr

Definition at line 790 of file fvmbcartesiansolverxd.h.

◆ m_stableVolumeFraction

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_stableVolumeFraction {}

Definition at line 789 of file fvmbcartesiansolverxd.h.

◆ m_standardRK

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_standardRK = false

Definition at line 623 of file fvmbcartesiansolverxd.h.

◆ m_startSet

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_startSet {}

Definition at line 669 of file fvmbcartesiansolverxd.h.

◆ m_static_createCutFaceMb_MGC_bodyFaceJoinMode

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_static_createCutFaceMb_MGC_bodyFaceJoinMode = 1
private

Definition at line 1780 of file fvmbcartesiansolverxd.h.

◆ m_static_createCutFaceMb_MGC_first

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_static_createCutFaceMb_MGC_first = true
private

Definition at line 1782 of file fvmbcartesiansolverxd.h.

◆ m_static_createCutFaceMb_MGC_maxA

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_static_createCutFaceMb_MGC_maxA = 0.1
private

Definition at line 1781 of file fvmbcartesiansolverxd.h.

◆ m_static_initSolutionStep_firstRun

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_static_initSolutionStep_firstRun = true
private

Definition at line 1778 of file fvmbcartesiansolverxd.h.

◆ m_static_initSolutionStep_frstrn

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_static_initSolutionStep_frstrn = true
private

Definition at line 1779 of file fvmbcartesiansolverxd.h.

◆ m_structureStep

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_structureStep {}

Definition at line 658 of file fvmbcartesiansolverxd.h.

◆ m_surfaceCoordinates

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_surfaceCoordinates = nullptr

Definition at line 845 of file fvmbcartesiansolverxd.h.

◆ m_surfaceVariables

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_surfaceVariables = nullptr

Definition at line 843 of file fvmbcartesiansolverxd.h.

◆ m_sweptVolumeDt1

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_sweptVolumeDt1 = nullptr

Definition at line 792 of file fvmbcartesiansolverxd.h.

◆ m_t0

template<MInt nDim, class SysEqn >
const clock_t FvMbCartesianSolverXD< nDim, SysEqn >::m_t0

Definition at line 675 of file fvmbcartesiansolverxd.h.

◆ m_tCutGroup

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_tCutGroup {}

Definition at line 575 of file fvmbcartesiansolverxd.h.

◆ m_tCutGroupTotal

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_tCutGroupTotal {}

Definition at line 576 of file fvmbcartesiansolverxd.h.

◆ m_temporarilyLinkedCells

template<MInt nDim, class SysEqn >
std::vector<std::tuple<MInt, MInt, MInt> > FvMbCartesianSolverXD< nDim, SysEqn >::m_temporarilyLinkedCells

Definition at line 819 of file fvmbcartesiansolverxd.h.

◆ m_timeStepAdaptationEnd

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_timeStepAdaptationEnd {}

Definition at line 612 of file fvmbcartesiansolverxd.h.

◆ m_timeStepAdaptationStart

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_timeStepAdaptationStart {}

Definition at line 611 of file fvmbcartesiansolverxd.h.

◆ m_trackBodySurfaceData

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_trackBodySurfaceData = true

Definition at line 667 of file fvmbcartesiansolverxd.h.

◆ m_trackMbEnd

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_trackMbEnd {}

Definition at line 591 of file fvmbcartesiansolverxd.h.

◆ m_trackMbStart

template<MInt nDim, class SysEqn >
MInt FvMbCartesianSolverXD< nDim, SysEqn >::m_trackMbStart {}

Definition at line 589 of file fvmbcartesiansolverxd.h.

◆ m_trackMovingBndry

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_trackMovingBndry {}

Definition at line 579 of file fvmbcartesiansolverxd.h.

◆ m_U2

template<MInt nDim, class SysEqn >
MFloat FvMbCartesianSolverXD< nDim, SysEqn >::m_U2 {}

Definition at line 684 of file fvmbcartesiansolverxd.h.

◆ m_vars

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_vars = nullptr

Definition at line 847 of file fvmbcartesiansolverxd.h.

◆ m_volumeFraction

template<MInt nDim, class SysEqn >
MFloat* FvMbCartesianSolverXD< nDim, SysEqn >::m_volumeFraction = nullptr

Definition at line 788 of file fvmbcartesiansolverxd.h.

◆ m_wasBalanced

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_wasBalanced = false

Definition at line 777 of file fvmbcartesiansolverxd.h.

◆ m_writeCenterLineData

template<MInt nDim, class SysEqn >
MBool FvMbCartesianSolverXD< nDim, SysEqn >::m_writeCenterLineData {}

Definition at line 607 of file fvmbcartesiansolverxd.h.

◆ s_cellDataTypeDlb

template<MInt nDim, class SysEqn >
const std::array< MInt, FvMbCartesianSolverXD< nDim, SysEqn >::CellDataDlb::count > FvMbCartesianSolverXD< nDim, SysEqn >::s_cellDataTypeDlb
staticprivate
Initial value:
= {
@ MFLOAT
Definition: enums.h:269
@ MLONG
Definition: enums.h:269

Definition at line 1786 of file fvmbcartesiansolverxd.h.


The documentation for this class was generated from the following files: