MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
FvBndryCndXD< nDim, SysEqn > Class Template Reference

#include <fvcartesianbndrycndxd.h>

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

Public Types

using Cell = GridCell
 
using SolverCell = FvCell
 
typedef void(FvBndryCndXD::* BndryCndHandler) (MInt)
 
typedef void(FvBndryCndXD::* BndryCndHandlerVar) (MInt)
 

Public Member Functions

 FvBndryCndXD (FvCartesianSolverXD< nDim, SysEqn > *solver)
 
virtual ~FvBndryCndXD ()
 
SysEqn sysEqn () const
 
virtual void writeStlFileOfCell (MInt, const MChar *)
 
void addBoundarySurfaces ()
 adds a surface for the ghost-boundary cell intersections More...
 
void addBoundarySurfacesMGC ()
 adds a surface for the ghost-boundary cell intersections More...
 
void correctBoundarySurfaceVariablesMGC ()
 corrects the left and right variables values on the boundary surface More...
 
void correctBoundarySurfaceVariablesMGCSurface ()
 corrects the left and right variables values on the boundary surface More...
 
void applyNonReflectingBCCutOff ()
 
void applyNonReflectingBCAfterTreatmentCutOff ()
 
void computeGhostCells ()
 
void computeGhostCellsMGC ()
 Computes one ghost cell for each boundary surface. More...
 
void computeMirrorCoordinates (MInt, MFloat *, MInt)
 
void computeMirrorCoordinates (MInt, MFloat *)
 
void computeReverseMap ()
 Creates a mapping (boundary cell id) -> (cell id) in m_bndryCellIds. More...
 
void initWMBndryCells ()
 
void initWMSurfaces ()
 
template<MBool MGC>
void bc3399 (MInt)
 
void copyRHSIntoGhostCells ()
 
void correctCellCoordinates ()
 
void createSortedBndryCellList ()
 
void createBndryCndHandler ()
 creates pointers to the boundary conditions More...
 
void createSpongeAtSpongeBndryCnds ()
 creates Sponge Cells at spongeBndryCnds More...
 
void recorrectCellCoordinates ()
 
void rerecorrectCellCoordinates ()
 
void applyNeumannBoundaryCondition ()
 
void storeBoundaryVariables ()
 
void updateGhostCellVariables ()
 
void updateCutOffCellVariables ()
 
void initCutOffBndryCnds ()
 
void allocateCutOffMemory ()
 allocates the cut off list memory More...
 
void exchangeCutOffBoundaryCells ()
 exchanges the cut off boundary cells and adds them to the accordings cut off boundary lists More...
 
void updateGhostCellSlopesInviscid ()
 
void updateCutOffSlopesInviscid ()
 
void updateGhostCellSlopesViscous ()
 
void correctGhostCellSlopesViscous ()
 
void updateCutOffSlopesViscous ()
 
void initBndryCnds ()
 
void setBCTypes (MInt updateOnlyBndryCndId=-1)
 
virtual void cmptGhostCells ()
 
void saveBc7901 ()
 
void bc0 (MInt)
 
void bc0Var (MInt)
 
void bcInit0001 (MInt)
 Sets up the reconstruction stencil for boundary cells. More...
 
template<MBool MGC>
void bcInit0002 (MInt)
 Sets up the reconstruction stencil for boundary cells. More...
 
template<MBool MGC>
void bcInit4000 (MInt)
 
void bcInit0004 (MInt)
 Sets up the reconstruction stencil for boundary cells (quadratic least-squares reconstruction) More...
 
void bcNeumann (MInt)
 
void bcNeumannIso (MInt)
 
void initBndryCommunications ()
 inits the commnicators for the boundaries More...
 
void createBoundaryAtCutoff ()
 
MInt isCutOffInterface (MInt cellId)
 
void markCutOff (MIntScratchSpace &cutOffCells)
 
template<MBool MGC>
void sbc2000 (MInt)
 
template<MInt dir>
void sbc2001 (MInt)
 Solid wall Navier-Stokes boundary condition Computes ghost cell slopes for the viscous flux computation Set of variables: primitive (u,v,rho,p,Z) More...
 
template<MInt dir>
void sbc2901 (MInt)
 
void bc17110 (MInt)
 
void bc17516 (MInt)
 
void bc19516 (MInt)
 
void bc1753 (MInt)
 
void bc1755 (MInt)
 
void bc1251 (MInt)
 
virtual void bc2770 (MInt)
 
virtual void sbc2710co (MInt)
 
virtual void bc1001coflowY (MInt)
 
virtual void bc10910 (MInt)
 
virtual void bc10990 (MInt)
 
virtual void bc1901 (MInt)
 
virtual void bc1801 (MInt)
 
virtual void bc19520 (MInt)
 
virtual void bc1003 (MInt)
 
virtual void bc1004 (MInt)
 
virtual void bc1005 (MInt)
 
virtual void bc1401 (MInt)
 
virtual void bc1791 (MInt)
 
virtual void bc2001 (MInt)
 
virtual void bc2002 (MInt)
 
virtual void bc2003 (MInt)
 
void bc3002 (MInt)
 
void bc30021 (MInt)
 
template<MBool MGC>
void bc3003 (MInt)
 
void bc3011 (MInt)
 
void bc4000 (MInt)
 
void bc4001 (MInt)
 
void plotAllCutPoints ()
 writes a .vtk file containing all cut points stored on the cut cells More...
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void writeStlFileOfCell (MInt, const char *)
 Only 3D ///. More...
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void plotSurface ()
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void plotEdges (MInt &, MFloat **&)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void plotIntersectionPoints (MInt *, MFloat ***&)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void writeStlOfNodes (MInt, MInt *&, const char *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void plotTriangle (std::ofstream &, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
MFloatvecSub (MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
MFloatvecScalarMul (MFloat, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computeTri (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computeTri (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computeTrapez (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computePoly3 (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computePoly4 (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computePoly5 (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computePoly6 (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computeTetra (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void computePyra (MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void correctFace (MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void correctCell (MFloat *, MFloat *, MFloat *, MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void correctNormal (MFloat *)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void getFeatureEdges (MInt &, MFloat **&, MInt, MInt *&, MFloat *&, MFloat *&)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void getIntersectionPoints (MFloat **&, MFloat **&, MInt, MInt, MFloat **&, MInt &)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void getSortedElements (const std::vector< MInt > &, MInt &, MInt *&, MInt &, MInt *&, MInt)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void correctInflowBoundary (MInt)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void correctInflowBoundary (MInt, MFloat *&, MFloat *&)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void correctInflowBoundary (MInt, MBool=false)
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void correctInflowBoundary (MInt, MFloat *&, MFloat *&, MBool=false)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
MInt createSplitCell_MGC (MInt, MInt)
 produces an exact copy of a fvcell and the respective boundary cell More...
 
MBool checkInside (MInt)
 checks if all corners of a cell are located in the computational domain More...
 
MBool checkOutside (MInt)
 
MBool checkOutside (const MFloat *, const MInt)
 
virtual void generateBndryCells ()
 generate finite-volume boundary cells More...
 
void createBndryCells ()
 
void computeCutPoints ()
 computes the cut points where a boundary cell intersects with the geometry computes the following boundary cell member variables: More...
 
void exchangeComputedCutPoints ()
 
void checkCutPointsValidity ()
 checks the validity of a boundary cell More...
 
void checkCutPointsValidityParGeom ()
 checks the validity of a boundary cell using parallel geometry More...
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void createCutFace ()
 computes the geometry of each the cut cells (2D version) 2 cut points are assumed for each boundary cell this restriction is required since the remainder of the 2D code is not able to work with multiply cut cellls this algorithm can easily be modified to account for 4 cut points (multiply cut cell or split cells) computes the following boundary cell member variables: More...
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void createCutFace ()
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void createCutFaceMGC ()
 ONLY 3D VERSIONS. More...
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void createCutFaceMGC ()
 
void checkBoundaryCells ()
 
void computePlaneVectors ()
 uses Gram-Schmidt to compute orthonormal vectors in the cut plane More...
 
void deleteBndryCell (MInt)
 Deletes a boundary cell (without collector fragmentation) More...
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_FLATTEN) void copySlopesToSmallCells()
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_FLATTEN) void copyVarsToSmallCells()
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_FLATTEN) void correctBoundarySurfaceVariables()
 
void correctCoarseBndryCells ()
 
void correctMasterSlaveSurfaces ()
 Removes surfaces between master-slave pairs and reassigns slave cell surfaces. More...
 
void detectSmallBndryCells ()
 Detects small cells and identifies a master cell Calls mergeCell to merge master and small cell. More...
 
void detectSmallBndryCellsMGC ()
 Detects small cells and identifies a master cell Calls mergeCell to merge master and small cell. More...
 
void setNearBoundaryRecNghbrs (MInt updateOnlyBndryCndId=-1)
 
void computeImagePointRecConst (MInt updateOnlyBndryCndId=-1)
 
void initSmallCellCorrection (MInt updateOnlyBndryCndId=-1)
 Initialize the small-cell correction for the flux-redistribution method The cell vars are computed using a weighted least squares approach 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 If bndryCndId is specified (standard value=-1) only boundary cells corresponding to the stated boundary are initialized. More...
 
void initSmallCellRHSCorrection (MInt updateOnlyBndryCndId=-1)
 
void mergeCells ()
 
void mergeCellsMGC ()
 merges master and small cells - for multiple ghost cells formulation More...
 
void updateRHSSmallCells ()
 
void resetCutOff ()
 reset sorterdCutOff Cells and cutOff communicator before balancing and adaptation! More...
 
void resetCutOffFirst ()
 reset first for cutOffBndryCnd, this is necessary after a balance! More...
 
void resetBndryCommunication ()
 
void cutOffBcMissingNeighbor (const MInt cellId, const MString bcName)
 
void setGapGhostCellVariables (MInt bcId)
 update ghostCell variables for gap-Cells More...
 
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void computePolygon (MFloat *x, const MInt N, MFloat *centroid, MFloat *area)
 
void computeNeumannLSConstants (MInt)
 Sets up the reconstruction stencil for boundary cells. More...
 
void computeReconstructionConstants_interpolation ()
 
void bcNeumann3600 (MInt)
 Simple and fast fixed adiabatic wall boundary condition for use with the flux-redistribution method. More...
 
void bcNeumannIsothermal (MInt)
 Computes the p and rho slopes on boundary cells using the least-squares method and setting implicitely TInfinity burnt. More...
 
void bcNeumannIsothermalBurntProfile (MInt)
 Computes the p and rho slopes on boundary cells using the least-squares method and setting implicitely TInfinity burnt as a tanh profile from the tube edges rising up to the desired burnt temperature (dump boundaries) More...
 
void bcNeumannIsothermalBurntProfileH (MInt)
 Computes the p and rho slopes on boundary cells using the least-squares method and setting implicitely TInfinity burnt as a tanh profile from the tube edges rising up to the desired burnt temperature (dump boundaries) More...
 
void bcNeumannIsothermalUnburnt (MInt)
 Computes the p and rho slopes on boundary cells using the least-squares method, and setting implicitely TInfinity unburnt (tube wall boundaries) More...
 
void bcNeumannIsothermalUnburntProfile (MInt)
 Computes the p and rho slopes on boundary cells using the least-squares method and setting implicitely TInfinity as a tanh profile rising up to the desired burnt temperature at the tube edges (tube inflow boundary!) More...
 
void bcNeumannIsothermalUnburntProfileH (MInt)
 Computes the p and rho slopes on boundary cells using the least-squares method and setting implicitely TInfinity as a tanh profile rising up to the desired half burnt temperature at the tube edges (tube inflow boundary!) More...
 
void bcNeumannMb (MInt)
 Moving boundary Neumann condition. More...
 
MFloat updateImagePointVariables (MInt)
 Updates the image point variables used with multiple ghost cell formulation. More...
 
 ATTRIBUTES2 (ATTRIBUTE_HOT, ATTRIBUTE_FLATTEN) void sbc1000(const MInt)
 
void sbc1000co (const MInt)
 Cut off condition for the slopes. More...
 
void sbc00co (const MInt)
 Cut off condition for the slopes. More...
 
void sbc1002 (MInt)
 Symmetry boundary condition about x-axis (slopes) More...
 
void sbc2801x (MInt)
 Solid wall Navier-Stokes boundary condition Computes ghost cell slopes for the viscous flux computation Set of variables: primitive (u,v,rho,p,Z) More...
 
void sbc2801y (MInt)
 Solid wall Navier-Stokes boundary condition Computes ghost cell slopes for the viscous flux computation Set of variables: primitive (u,v,rho,p,Z) More...
 
void bc1001 (MInt)
 
void bc100100 (MInt)
 
void bc1000 (MInt)
 
void bc1009 (MInt)
 
void bc01 (MInt)
 
void bc1002 (MInt)
 
void bc1091 (MInt)
 
void bc1101 (MInt)
 
void bc1102 (MInt)
 
void bc1601 (MInt)
 
void bc1602 (MInt)
 
void bc1603 (MInt)
 
void bc1604 (MInt)
 
void bc1606 (MInt)
 
void bcInit1601 (MInt)
 Initialize bc1601. More...
 
void bc10970 (MInt)
 
void bc10980 (MInt)
 
void bc11110 (MInt)
 
void bc16010 (MInt)
 
void bc16011 (MInt)
 
void bc16012 (MInt)
 
void bc16013 (MInt)
 
void bc16014 (MInt)
 
void bc16015 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bcInit7901 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bcInit7902 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bcInit7905 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bcInit7909 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bcInit7809 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bc7901 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bc7902 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bc7905 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bc7903 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bc7909 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==3, _ * > = nullptr>
void bc7809 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bcInit7901 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bcInit7902 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bcInit7905 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bcInit7909 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bcInit7809 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bc7901 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bc7902 (MInt)
 
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bc7905 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bc7903 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bc7909 (MInt)
 
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void bc7809 (MInt)
 
void bcInit30022 (MInt)
 
void bc30022 (MInt)
 
void bc1792 (MInt)
 
void bc1156 (MInt)
 
void bc1952 (MInt)
 Subsonic outflow boundary condition (applied directly to the (boundary) cell). Set of variables: Standard CV + passive scalar du/dn=dv/dn=dw/dn=0; drho/dn=0; p=pIF; dZ/dn=0. More...
 
void bcInit1050 (MInt)
 
void initModes (MInt)
 
void addModes (MInt)
 supersonic inflow with imposed onlique shock wave version: cut-off boundary condition author: Thomas Schilden, 7.3.2016 More...
 
void initBesselModes (MInt)
 
void addBesselModes (MInt)
 
void calcBesselFractions (const MFloat, const MFloat, const MFloat, MFloat &, MFloat &)
 
void precomputeBesselTrigonometry (MInt)
 
void bc2700 (MInt)
 
void bcInit1251 (MInt)
 
void bcInit2770 (MInt)
 supersonic inflow with imposed onlique shock wave and linear waves version: cut-off boundary condition author: Thomas Schilden, 7.3.2016 More...
 
void bcInit2700 (MInt)
 init for the acoustic and entropy waves More...
 
void bc2710 (MInt)
 
void bc2720 (MInt)
 
void sbc2720co (MInt)
 Cut off condition for the slopes copys the slopes, and sets pressure slope to sero NOTIMPLEMENTED version: cut-off boundary condition author: Thomas Schilden, 12.2.2015. More...
 
void bc3006 (MInt)
 
void bc3007 (MInt)
 
void bc2907 (MInt)
 
void bc29050 (MInt)
 
void bc3466 (MInt)
 
void bc3600 (MInt)
 
MFloat computeCutoffBoundaryGeometry (const MInt, const MInt, MFloat *)
 computes centroid and radius (return parameter) of a cut-off boundary surface assumes that the surface is circular in 3D More...
 
void cbcTurbulenceInjection (MInt, MFloat *, MInt)
 Turbulence injection (identical to bc1601) adjusted for Taylor's Hypothesis for cbc. More...
 
void cbcRHS (MInt, MInt, MFloat *, MFloat *, MFloat *)
 Calculates the right hand side. More...
 
void cbcDampingOutflow (MInt, MInt, MFloat, MFloat *)
 Calculates the outflow damping terms. More...
 
void cbcDampingInflow (MInt, MInt, MFloat, MFloat *, MString)
 Calculates the inflow damping terms. More...
 
template<unsigned char vTerms>
void cbcViscousTerms (MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MInt *, MFloat *)
 Calculates the outgoing viscous terms V. More...
 
template<unsigned char tTerms>
void cbcTransversalTerms (MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 Calculates the transversal correction terms T. More...
 
template<MInt side>
void cbcOutgoingAmplitudeVariation (MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
 Calculates the outgoing terms wave amplitude variation L. More...
 
void cbcGradients (MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *)
 Calculates the gradients of the cbcCell. More...
 
void cbcGradientsViscous (MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MInt *)
 Calculates the viscous gradients of the cbcCell. More...
 
void cbcTauQ (MInt, MFloat *, MFloat *, MInt *)
 Calculates the stress tensor tau and the heat flux q and the mean velocity on the construction stencils of all cbc cells. More...
 
void cbcMachCo (MInt, MFloat *)
 Returns the mean and maximum Mach number of the cut off cells. More...
 
void cbcMeanPressureCo (MInt, MFloat *)
 
void bcInitCbc (MInt)
 
void cbc1099 (MInt)
 
void cbc109910 (MInt)
 Characteristic boundary condition. Outflow. Prescribed: p. Partially Refelecting. More...
 
void cbc109911 (MInt)
 Characteristic boundary condition. Outflow. Prescribed: p. Partially Refelecting. More...
 
void cbc109921 (MInt)
 Characteristic boundary condition. Outflow. Prescribed: p. Partially Refelecting. More...
 
void cbc1099a (MInt)
 
void cbc1099a_after (MInt)
 Subsonic fully reflecting characteristic outflow condition - cut off - sets pstat to prescribed value after rkstep. More...
 
void cbc1091 (MInt)
 
void cbc1091a (MInt)
 
void cbc3091a (MInt)
 
void cbc1091b (MInt)
 
void cbc1091c (MInt)
 
void cbc1091d (MInt)
 
void cbc1091b_after (MInt)
 Subsonic fully reflecting characteristic inflow condition - cut off - sets T0,u,v to prescribed value after rkstep. More...
 
void cbc1091c_after (MInt)
 Subsonic fully reflecting characteristic inflow condition - cut off - sets T0,u,v to prescribed value after rkstep. More...
 
void cbc1091d_after (MInt)
 Subsonic fully reflecting characteristic inflow condition - cut off - sets un to prescribed value after rkstep. More...
 
void cbc1091e (MInt)
 
void cbc1091e_after (MInt)
 Subsonic fully reflecting characteristic inflow condition - cut off - sets T0,u,v to prescribed value after rkstep. More...
 
void cbc1099_1091_local (MInt)
 
void cbc1099_1091_local_comb (MInt)
 
void cbc1291 (MInt)
 
void cbc1291a (MInt)
 
void cbc1291b (MInt)
 
void cbc1291tm (MInt)
 
void cbc1291tma (MInt)
 
void cbc1291tmb (MInt)
 
void cbc1291tmc (MInt)
 
void cbc1299 (MInt)
 
void cbc1299tm (MInt)
 
void cbc1299a (MInt)
 
void cbc2091a (MInt)
 
void cbc2091b (MInt)
 
void cbc2091b_after (MInt)
 Subsonic fully reflecting characteristic inflow condition - cut off - sets T0,u,v to prescribed value after rkstep. More...
 
void cbc2091d (MInt)
 
void cbc2091d_after (MInt)
 Subsonic fully reflecting characteristic inflow condition - cut off - sets un to prescribed value after rkstep. More...
 
void cbc2099_1091_local_comb (MInt)
 
void cbc1099_1091_engine (MInt)
 
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void cbc1099_1091_engineOld (MInt)
 
virtual void bc3037MGC (MInt)
 
void bc1091MGC (MInt)
 
void bc1099MGC (MInt)
 
void cbc1099_1091d (MInt)
 
void cbc1099_1091d_after (MInt)
 
void cbc1099_1091d (MInt)
 
void sbc2801x (MInt)
 

Public Attributes

MInt m_noDirs = 2 * nDim
 
MInt m_noEdges = nDim == 2 ? 4 : 12
 
MInt m_noCorners = nDim == 2 ? 4 : 8
 
maia::fv::collector::FvCellCollector< nDim > & m_cells
 
maia::fv::surface_collector::FvSurfaceCollector< nDim > & m_surfaces
 
List< MInt > * m_smallBndryCells = nullptr
 
List< MInt > * m_sortedBndryCells = nullptr
 
List< MInt > * m_sortedSpongeBndryCells = nullptr
 
std::vector< List< MInt > * > m_sortedCutOffCells {}
 
FvCartesianSolverXD< nDim, SysEqn > * m_solver = nullptr
 
FvBndryCell< nDim, SysEqn > * m_bndryCell = nullptr
 
MIntm_splitSurfaces = nullptr
 
MIntm_bndryNghbrs = nullptr
 
MIntm_splitParents = nullptr
 
MIntm_splitChildren = nullptr
 
MInt m_solverId = -1
 
MBool m_changeAdiabBCToTemp
 
MInt m_noLevelSetsUsedForMb
 
MBool m_complexBoundaryMB
 
MBool m_cellCoordinatesCorrected
 
SysEqn::ConservativeVariables * CV {}
 
SysEqn::FluxVariables * FV {}
 
SysEqn::PrimitiveVariables * PV {}
 
SysEqn::AdditionalVariables * AV {}
 
MInt m_minLevel
 
MInt m_maxLevel
 
Collector< FvBndryCell< nDim, SysEqn > > * m_bndryCells = nullptr
 
std::list< std::pair< MInt, MInt > > m_wmSrfcToCellId
 
BndryCndHandlerbndryCndHandlerInit = nullptr
 
BndryCndHandlerbndryCndHandlerCutOffInit = nullptr
 
BndryCndHandlerVarbndryCndHandlerNeumann = nullptr
 
BndryCndHandlerbndryCndHandlerVariables = nullptr
 
BndryCndHandlerbndryCndHandlerCutOffVariables = nullptr
 
BndryCndHandlerbndryCndHandlerSpongeVariables = nullptr
 
BndryCndHandlernonReflectingBoundaryConditionAfterTreatmentCutOff = nullptr
 
BndryCndHandlernonReflectingCutOffBoundaryCondition = nullptr
 
BndryCndHandlerbndryCndHandlerSlopesInviscid = nullptr
 
BndryCndHandlerbndryCndHandlerCutOffSlopesInviscid = nullptr
 
BndryCndHandlerbndryViscousSlopes = nullptr
 
BndryCndHandlerbndryCutOffViscousSlopes = nullptr
 
MFloat ** m_reconstructionConstants = nullptr
 
MInt ** m_reconstructionNghbrs = nullptr
 
std::vector< MIntm_smallCutCells
 
std::vector< MInt > * m_nearBoundaryWindowCells = nullptr
 
std::vector< MInt > * m_nearBoundaryHaloCells = nullptr
 
std::vector< std::vector< MInt > > m_azimuthalNearBoundaryWindowCells
 
std::vector< std::vector< MInt > > m_azimuthalNearBoundaryWindowMap
 
std::vector< std::vector< MInt > > m_azimuthalNearBoundaryHaloCells
 
MBool m_cellMerging = false
 
MBool m_secondOrderRec
 
MInt m_noFluxRedistributionLayers
 
MFloat m_4000timeStepOffset
 
MFloat m_4000timeInterval
 
MFloat m_wFactor
 
MFloat m_pressureRatioChannel
 
MFloat m_sigmaNonRefl
 
MFloat m_sigmaNonReflInflow
 
MBool m_createBoundaryAtCutoff
 
MBool m_createSpongeBoundary
 
MBool m_outputIGPoints
 
MIntm_bndryCndIds = nullptr
 
MIntm_cutOffBndryCndIds = nullptr
 
MIntm_cellsInsideSpongeLayer = nullptr
 
MInt m_noCellsInsideSpongeLayer
 
MIntm_spongeBndryCndIds = nullptr
 holds the sponge boundary IDs More...
 
MFloatm_spongeFactor = nullptr
 
MIntm_spongeDirections = nullptr
 
MFloatm_sigmaSpongeBndryId = nullptr
 
MFloatm_sigmaEndSpongeBndryId = nullptr
 
MFloat m_spongeLayerThickness
 
MInt m_spongeLayerLayout
 
MBool m_spongeTimeDep
 
MFloatm_spongeStartIteration = nullptr
 
MFloatm_spongeEndIteration = nullptr
 
MIntm_spongeTimeDependent = nullptr
 
MIntm_bndryCndCells = nullptr
 
MIntm_spongeBndryCells = nullptr
 
MIntm_boundarySurfaces = nullptr
 
MInt m_multipleGhostCells = 0
 
MInt m_ipVariableIterative
 
MInt m_surfaceGhostCell
 
MInt m_noBoundarySurfaces {}
 
MInt m_noBndryCndIds
 
MInt m_noSpongeBndryCndIds
 number of sponge boundary condition IDs More...
 
MInt m_noCutOffBndryCndIds
 
MBool m_cbcCutOff = false
 
MBool m_cbcSmallCellCorrection = false
 
MInt m_noMaxSpongeBndryCells
 
MFloat m_spongeBeta
 
MFloatm_spongeCoord = nullptr
 
MInt m_maxNoBndryCells
 
MInt m_maxNoBndryCndIds
 
MInt m_noImagePointIterations
 
MFloat m_volumeLimitWall
 
MBool m_smallCellRHSCorrection = false
 
MFloat m_volumeLimitOther
 
MFloat m_meanCoord [3] {}
 
MFloat ** m_shockBcVars = nullptr
 
MInt m_noShockBcCells {}
 
MBool m_shockFromInnerSolution {}
 
MIntm_Bc2770TargetCells = nullptr
 
MFloat m_sigmaShock {}
 
MFloat m_ys {}
 
MFloatm_modeOmega = nullptr
 
MFloatm_modeAmp = nullptr
 
MIntm_modeType = nullptr
 
MFloat ** m_modeK = nullptr
 
MBool m_clusterCutOffBcs {}
 
MIntm_nmbrOfModes = nullptr
 
MFloatm_modePhi = nullptr
 
MFloatm_modeEtaMin = nullptr
 
MInt m_modes {}
 
MInt m_besselModes
 
MFloatm_besselTrig = nullptr
 
MFloat m_Bc3011WallTemperature = NAN
 
MFloat m_radiusFlameTube
 
MFloat m_radiusVelFlameTube
 
MFloat m_shearLayerThickness
 
MFloat m_jetHeight
 
MFloat m_primaryJetRadius
 
MFloat m_secondaryJetRadius
 
MFloat m_targetVelocityFactor
 
MFloat m_momentumThickness
 
MFloat m_shearLayerStrength
 
MFloat m_Ma
 
MFloat m_deltaP {}
 
MFloat m_deltaPL {}
 
MFloat m_inflowTemperatureRatio
 
MInt m_noSpecies
 
MInt m_noRansEquations
 
MBool m_combustion
 
MBool m_isEEGas
 
MFloat m_nu [10] {}
 
MInt m_bc1601_bcId = -1
 
Bc1601Class< nDim > * m_bc1601 = nullptr
 
MBool m_bc1601MoveGenOutOfSponge = false
 
MBool m_jetInletTurbulence = false
 
MFloat m_bc1251ForcingAmplitude
 
MFloat m_bc1251ForcingWavelength
 
MFloat m_bc1251ForcingFrequency
 
MInt m_bc1251ForcingDirection
 
MInt m_7901faceNormalDir
 
MInt m_7901BcActive
 
MInt m_7901StartTimeStep
 
MInt m_7901periodicDir
 
MInt m_7901wallDir
 
MInt m_7901globalNoWallNormalLocations = -1
 
MIntm_7901globalNoPeriodicLocations = nullptr
 
MFloat ** m_7901LESAverage = nullptr
 
MFloat ** m_7901LESAverageOld = nullptr
 
MIntm_7901periodicIndex = nullptr
 
std::vector< MFloat > * m_7901periodicLocations = nullptr
 
std::vector< MFloatm_7901wallNormalLocations
 
std::vector< MFloatm_7901globalWallNormalLocations
 
MInt m_rntRoot
 
MInt m_7902faceNormalDir
 
MInt m_7902BcActive
 
MInt m_7902StartTimeStep
 
MInt m_7902periodicDir
 
MInt m_7902wallDir
 
MInt m_7902globalNoWallNormalLocations = -1
 
MIntm_7902globalNoPeriodicLocations = nullptr
 
MFloat ** m_7902LESAverage = nullptr
 
MFloat ** m_7902LESAverageOld = nullptr
 
MIntm_7902periodicIndex = nullptr
 
std::vector< MFloat > * m_7902periodicLocations = nullptr
 
std::vector< MFloatm_7902wallNormalLocations
 
std::vector< MFloatm_7902globalWallNormalLocations
 
std::map< MInt, MSTG< nDim, MAIA_FINITE_VOLUME, MAIA_FINITE_VOLUME > * > m_stgBC
 
std::map< MInt, MSTG< nDim, MAIA_STRUCTURED, MAIA_FINITE_VOLUME > * > m_stgBCStrcd
 
std::map< MInt, MBoolm_stgLocal
 
std::vector< MIntm_stgBcCells
 
MInt m_startSTGTimeStep
 
MPI_Comm m_commStg
 
std::vector< MFloatm_cbcInflowArea
 
std::vector< std::vector< MFloat > > m_cbcReferencePoint
 
std::vector< MIntm_cbcBndryCndIds
 
std::vector< std::vector< MFloat > > m_cbcRelax
 
std::vector< std::vector< MFloat > > m_dirTangent
 
std::vector< std::vector< MFloat > > m_dirNormal
 
std::vector< MFloatm_cbcLref
 
std::vector< std::vector< MInt > > m_cbcDir
 
std::vector< MIntm_cbcDomainMin
 
MBool m_cbcTurbulence = false
 
MBool m_cbcViscous = false
 
MFloat ** m_oldFluctChol = nullptr
 
MFloat m_oldTime = F0
 

Protected Member Functions

MPI_Comm mpiComm () const
 Return the MPI communicator used by the corresponding solver. More...
 
MInt domainId () const
 Return the domain id of this solver on the current MPI communicator. More...
 
MInt noDomains () const
 Return the total number of domains (total number of ranks in current MPI communicator) More...
 

Protected Attributes

MString m_gridCutTest
 
MPI_Comm * m_comm_bc = nullptr
 
MInt m_comm_bc_init = 0
 
MIntm_bc_comm_pointer = nullptr
 
MPI_Comm * m_comm_bcCo = nullptr
 
MInt m_comm_bcCo_init = 0
 
MIntm_bcCo_comm_pointer = nullptr
 
std::vector< CutCandidate< nDim > > m_cutCandidates
 
GeometryIntersection< nDim > * m_geometryIntersection
 
MBool m_static_sbc1000co_first = true
 
MInt m_static_sbc1000co_directions [s_sbc1000co_fixedMaxNoBndryCndIds] {}
 
MBool m_static_initSmallCellCorrection_firstRun = true
 
MBool m_static_computeImagePointRecConst_firstRun = true
 

Static Protected Attributes

static constexpr MInt s_sbc1000co_fixedMaxNoBndryCndIds = 10
 

Private Attributes

SysEqn * m_sysEqn
 
MBool m_firstUseSetBCTypes = true
 
MInt m_static_plotEdges_iter = 0
 Only 3D ///. More...
 
MInt m_static_plotIntersectionPoints_iter = 0
 
MInt m_static_writeStlOfNodes_iter = 0
 
MInt m_static_correctInflowBoundary_iter = 0
 
MInt m_static_bc1091MGC_minTimeSteps = 0
 
MInt m_static_bc1091MGC_nghbrDir = -1
 
MInt m_static_bc1091MGC_edgeCellCounter = 0
 
MInt m_static_bc1091MGC_first = true
 
MInt m_static_bc1091MGC_first2 = true
 
MFloat m_static_bc1099MGC_timeOfMaxPdiff = 0
 
bool m_static_bc1099MGC_first = true
 
MBool m_firstUseBc10970 = true
 Only 3D ends ///. More...
 
MInt m_dirNBc10970 = -1
 
MInt m_pModeBc10970 = 0
 
MBool m_firstUseBc10980 = true
 
MInt m_dirNBc10980 = -1
 
MFloat ** m_targetValuesBC11110 = nullptr
 
MIntm_dirNBc11110 = nullptr
 
MBool m_firstUseBc11110 = true
 
MBool m_static_cbc1099_first = true
 
MInt m_static_cbc1099_dirN = -1
 
MInt m_static_cbc1099_dimN = -1
 
MInt m_static_cbc1099_dimT1 = -1
 
MInt m_static_cbc1099_dimT2 = -1
 
MFloat m_static_cbc1099_outFlowArea
 
MFloat m_static_cbc1099_referencePoint [3]
 
MInt m_static_cbc1099_domainMin
 
MBool m_static_cbc1099_1091_local_first = true
 
MInt m_static_cbc1099_1091_local_dirN = -1
 
MInt m_static_cbc1099_1091_local_dimN = -1
 
MInt m_static_cbc1099_1091_local_dimT1 = -1
 
MInt m_static_cbc1099_1091_local_dimT2 = -1
 
MFloat m_static_cbc1099_1091_local_inflowArea
 
MFloat m_static_cbc1099_1091_local_referencePoint [3]
 
MFloat m_static_cbc1099_1091_local_targetPressure
 
MInt m_static_cbc1099_1091_local_domainMin = 0
 
MFloat m_static_cbc1099_1091_local_R = 0
 
MFloat m_static_cbc1099_1091_local_H
 
MBool m_static_cbc1099_1091_local_comb_first = true
 
MInt m_static_cbc1099_1091_local_comb_dirN = -1
 
MInt m_static_cbc1099_1091_local_comb_dimN = -1
 
MInt m_static_cbc1099_1091_local_comb_dimT1 = -1
 
MInt m_static_cbc1099_1091_local_comb_dimT2 = -1
 
MFloat m_static_cbc1099_1091_local_comb_outFlowArea
 
MFloat m_static_cbc1099_1091_local_comb_referencePoint [3]
 
MBool m_static_cbc1091_first = true
 
MInt m_static_cbc1091_dirN = -1
 
MInt m_static_cbc1091_dimN = -1
 
MInt m_static_cbc1091_dimT1 = -1
 
MInt m_static_cbc1091_dimT2 = -1
 
MFloat m_static_cbc1091_inflowArea
 
MFloat m_static_cbc1091_referencePoint [3]
 
MInt m_static_cbc1091_domainMin
 
MBool m_static_cbc1091a_solverProfile = false
 
MBool m_static_cbc3091a_first = true
 
MInt m_static_cbc3091a_dirN = -1
 
MInt m_static_cbc3091a_dimN = -1
 
MInt m_static_cbc3091a_dimT1 = -1
 
MInt m_static_cbc3091a_dimT2 = -1
 
MBool m_static_cbc3091a_solverProfile = false
 
MFloat m_static_cbc3091a_inflowArea
 
MFloat m_static_cbc3091a_R
 
MFloat m_static_cbc3091a_referencePoint [3]
 
MBool m_static_cbc1091b_first = true
 
MInt m_static_cbc1091b_dirN = -1
 
MInt m_static_cbc1091b_dimN = -1
 
MInt m_static_cbc1091b_dimT1 = -1
 
MBool m_static_cbc1091b_solverProfile = false
 
MFloat m_static_cbc1091b_inflowArea
 
MFloat m_static_cbc1091b_referencePoint [3]
 
MBool m_static_cbc1091c_first = true
 
MInt m_static_cbc1091c_dirN = -1
 
MInt m_static_cbc1091c_dimN = -1
 
MInt m_static_cbc1091c_dimT1 = -1
 
MFloat m_static_cbc1091c_inflowArea
 
MFloat m_static_cbc1091c_referencePoint [3]
 
MBool m_static_cbc1091c_after_first = true
 
MInt m_static_cbc1091c_after_dirN = -1
 
MInt m_static_cbc1091c_after_dimN = -1
 
MInt m_static_cbc1091c_after_dimT1 = -1
 
MInt m_static_cbc1091c_after_dimT2 = -1
 
MBool m_static_cbc1091d_first = true
 
MInt m_static_cbc1091d_dirN = -1
 
MInt m_static_cbc1091d_dimN = -1
 
MInt m_static_cbc1091d_dimT1 = -1
 
MFloat m_static_cbc1091d_inflowArea
 
MFloat m_static_cbc1091d_referencePoint [3]
 
MBool m_static_cbc1091d_solverProfile = false
 
MInt m_static_cbc1091d_minDom = 0
 
MBool m_static_cbc1091d_after_first = true
 
MInt m_static_cbc1091d_after_dirN = -1
 
MInt m_static_cbc1091d_after_dimN = -1
 
MInt m_static_cbc1091d_after_dimT1 = -1
 
MInt m_static_cbc1091d_after_dimT2 = -1
 
MBool m_static_cbc1091e_first = true
 
MInt m_static_cbc1091e_dirN = -1
 
MInt m_static_cbc1091e_dimN = -1
 
MInt m_static_cbc1091e_dimT1 = -1
 
MBool m_static_cbc1091e_solverProfile = false
 
MFloat m_static_cbc1091e_inflowArea
 
MBool m_static_cbc2091a_first = true
 
MInt m_static_cbc2091a_dirN = -1
 
MInt m_static_cbc2091a_dimN = -1
 
MInt m_static_cbc2091a_dimT1 = -1
 
MBool m_static_cbc2091a_solverProfile = false
 
MFloat m_static_cbc2091a_inflowArea
 
MFloat m_static_cbc2091a_H
 
MFloat m_static_cbc2091a_referencePoint [nDim]
 
MBool m_static_cbc2091b_first = true
 
MInt m_static_cbc2091b_dirN = -1
 
MInt m_static_cbc2091b_dimN = -1
 
MInt m_static_cbc2091b_dimT1 = -1
 
MBool m_static_cbc2091b_solverProfile = false
 
MFloat m_static_cbc2091b_inflowArea
 
MFloat m_static_cbc2091b_H
 
MFloat m_static_cbc2091b_referencePoint [nDim]
 
MBool m_static_cbc2091d_first = true
 
MInt m_static_cbc2091d_dirN = -1
 
MInt m_static_cbc2091d_dimN = -1
 
MInt m_static_cbc2091d_dimT1 = -1
 
MFloat m_static_cbc2091d_inflowArea
 
MFloat m_static_cbc2091d_H
 
MFloat m_static_cbc2091d_referencePoint [nDim]
 
MBool m_static_cbc2091d_solverProfile = false
 
MBool m_static_cbc2091d_after_first = true
 
MInt m_static_cbc2091d_after_dirN = -1
 
MInt m_static_cbc2091d_after_dimN = -1
 
MInt m_static_cbc2091d_after_dimT1 = -1
 
MBool m_static_cbc2099_1091_local_comb_first = true
 
MInt m_static_cbc2099_1091_local_comb_dirN = -1
 
MInt m_static_cbc2099_1091_local_comb_dimN = -1
 
MInt m_static_cbc2099_1091_local_comb_dimT1 = -1
 
MFloat m_static_cbc2099_1091_local_comb_outFlowArea
 
MFloat m_static_cbc2099_1091_local_comb_referencePoint [nDim]
 
MBool m_static_cbc1099_1091d_first = true
 
MInt m_static_cbc1099_1091d_dirN = -1
 
MInt m_static_cbc1099_1091d_dimN = -1
 
MInt m_static_cbc1099_1091d_dimT1 = -1
 
MInt m_static_cbc1099_1091d_dimT2 = -1
 
MFloat m_static_cbc1099_1091d_inflowArea
 
MFloat m_static_cbc1099_1091d_referencePoint [nDim]
 
MFloat m_static_cbc1099_1091d_targetPressure
 
MBool m_static_cbc1099_1091d_after_first = true
 
MInt m_static_cbc1099_1091d_after_dirN = -1
 
MInt m_static_cbc1099_1091d_after_dimN = -1
 
MFloat m_static_cbc1099_1091d_after_interpolationFactor
 
MBool m_static_cbc1099_1091_engine_first = true
 
MInt m_static_cbc1099_1091_engine_dirN
 
MInt m_static_cbc1099_1091_engine_dimN
 
MInt m_static_cbc1099_1091_engine_dimT1
 
MFloat m_static_cbc1099_1091_engine_inflowArea
 
MInt m_static_cbc1099_1091_engine_domainMin = 0
 
MInt m_static_cbc1099_1091_engine_dimT2
 
MFloat m_static_cbc1099_1091_engine_normal [3]
 
MFloat m_static_cbc1099_1091_engine_tangent [3]
 
std::pair< MFloat, MFloat > * m_unTargetData = nullptr
 
std::pair< MFloat, MFloat > * m_vnTargetData = nullptr
 
MInt m_unTargetDataCount
 
MInt m_vnTargetDataCount
 
MFloat ** m_horTargetData = nullptr
 
MInt m_horTargetDataCount
 

Friends

class FvCartesianSolverXD< nDim, SysEqn >
 
class FvZonalSTG< nDim, SysEqn >
 

Detailed Description

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

Definition at line 113 of file fvcartesianbndrycndxd.h.

Member Typedef Documentation

◆ BndryCndHandler

template<MInt nDim, class SysEqn >
typedef void(FvBndryCndXD::* FvBndryCndXD< nDim, SysEqn >::BndryCndHandler) (MInt)

Definition at line 274 of file fvcartesianbndrycndxd.h.

◆ BndryCndHandlerVar

template<MInt nDim, class SysEqn >
typedef void(FvBndryCndXD::* FvBndryCndXD< nDim, SysEqn >::BndryCndHandlerVar) (MInt)

Definition at line 275 of file fvcartesianbndrycndxd.h.

◆ Cell

template<MInt nDim, class SysEqn >
using FvBndryCndXD< nDim, SysEqn >::Cell = GridCell

Definition at line 116 of file fvcartesianbndrycndxd.h.

◆ SolverCell

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

Definition at line 117 of file fvcartesianbndrycndxd.h.

Constructor & Destructor Documentation

◆ FvBndryCndXD()

template<MInt nDim, class SysEqn >
FvBndryCndXD< nDim, SysEqn >::FvBndryCndXD ( FvCartesianSolverXD< nDim, SysEqn > *  solver)

◆ ~FvBndryCndXD()

template<MInt nDim, class SysEqn >
FvBndryCndXD< nDim, SysEqn >::~FvBndryCndXD
virtual

Definition at line 449 of file fvcartesianbndrycndxd.cpp.

449 {
450 TRACE();
451
452 // Clean up allocated memory
467}
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
Definition: alloc.h:544
List< MInt > * m_sortedBndryCells
Collector< FvBndryCell< nDim, SysEqn > > * m_bndryCells
List< MInt > * m_smallBndryCells
std::vector< MInt > * m_nearBoundaryHaloCells
List< MInt > * m_sortedSpongeBndryCells
MFloat ** m_reconstructionConstants
MInt ** m_reconstructionNghbrs
std::vector< MInt > * m_nearBoundaryWindowCells

Member Function Documentation

◆ addBesselModes()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::addBesselModes ( MInt  bcId)

Definition at line 7586 of file fvcartesianbndrycndxd.cpp.

7586 {
7587 TRACE();
7588 const MInt noCutOffCells = m_sortedCutOffCells[bcId]->size();
7589
7590 for(MInt mode = 0; mode < m_modes; mode++) {
7591 // speed of sound
7592 const MFloat a = sysEqn().speedOfSound(m_solver->m_TInfinity);
7593
7594 // 1. pressure
7595 const MFloat pressure_f = m_modeAmp[mode] * m_solver->m_PInfinity * (MFloat)(m_modeType[mode]);
7596
7597 // 2. density
7598 const MFloat density_f = m_modeType[mode] ? pressure_f / POW2(a) : m_modeAmp[mode] * m_solver->m_rhoInfinity;
7599
7600 // 3. velocity
7601 const MFloat acImp = a * m_solver->m_rhoInfinity;
7602 const MFloat velocity_f = (MFloat)(m_modeType[mode]) * pressure_f / acImp;
7603 const MFloat cosIncl = cos(atan2(m_modeK[mode][1], m_modeK[mode][0]));
7604 const MFloat sinIncl = sin(atan2(m_modeK[mode][1], m_modeK[mode][0]));
7605
7606 for(MInt id = 0; id < noCutOffCells; id++) {
7607 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
7608
7609 const MFloat phi = atan2(m_solver->a_coordinate(cellId, 1), m_solver->a_coordinate(cellId, 2));
7610
7611 const MInt offset = mode * noCutOffCells + 2 * id;
7612 const MFloat trig_P_RHO_U = m_besselTrig[offset];
7613 const MFloat trig_V_W = m_besselTrig[offset + 1];
7614
7615 // density
7616 m_solver->a_pvariable(cellId, PV->RHO) += density_f * trig_P_RHO_U;
7617
7618 // axial velocity
7619 m_solver->a_pvariable(cellId, PV->U) += velocity_f * cosIncl * trig_P_RHO_U;
7620
7621 // radial velocity
7622 const MFloat radialVelocity = velocity_f * sinIncl * trig_V_W;
7623 m_solver->a_pvariable(cellId, PV->V) += radialVelocity * sin(phi);
7624 m_solver->a_pvariable(cellId, PV->W) += radialVelocity * cos(phi);
7625
7626 // pressure
7627 m_solver->a_pvariable(cellId, PV->P) += pressure_f * trig_P_RHO_U;
7628 }
7629 }
7630}
SysEqn::PrimitiveVariables * PV
FvCartesianSolverXD< nDim, SysEqn > * m_solver
SysEqn sysEqn() const
std::vector< List< MInt > * > m_sortedCutOffCells
MFloat & a_coordinate(const MInt cellId, const MInt dir)
Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir.
MFloat & a_pvariable(const MInt cellId, const MInt varId)
Returns primitive variable v of the cell cellId for variables varId.
constexpr Real POW2(const Real x)
Definition: functions.h:119
int32_t MInt
Definition: maiatypes.h:62
double MFloat
Definition: maiatypes.h:52
MInt id
Definition: maiatypes.h:71
void const MInt cellId
Definition: collector.h:239
T cos(const T a, const T b, const T x)
Cosine slope filter.
Definition: filter.h:125
Definition: contexttypes.h:19

◆ addBoundarySurfaces()

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

Definition at line 963 of file fvcartesianbndrycndxd.cpp.

963 {
964 TRACE();
965
966 MBool cellOk = false;
967 MInt cellId, ghostCellId;
968 MInt noCells = m_bndryCells->size();
969 MInt srfcId = 0;
970 MFloat epsilon = pow(10.0, -13.0);
971 //---
972
974
975 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
976 cellOk = false;
977
978 for(MInt srfc = 0; srfc < FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces; srfc++) {
979 for(MInt i = 0; i < nDim; i++)
980 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
981 }
982
983 // do not consider grid halo cells; only those which have a non-halo cell as master
984 // do not consider small cells with a boundary cell as master
985 if(m_solver->a_isHalo(m_bndryCells->a[bndryId].m_cellId)) {
986 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) {
987 if(m_solver->a_bndryId(m_bndryCells->a[bndryId].m_linkedCellId) == -1
988 && !m_solver->a_isHalo(m_bndryCells->a[bndryId].m_linkedCellId))
989 cellOk = true;
990 }
991 } else {
992 if(m_bndryCells->a[bndryId].m_linkedCellId == -1) {
993 cellOk = true;
994 } else {
995 if(m_solver->a_bndryId(m_bndryCells->a[bndryId].m_linkedCellId) == -1) {
996 cellOk = true;
997 }
998 }
999 }
1000
1001 if(cellOk) {
1002 ASSERT(m_bndryCells->a[bndryId].m_noSrfcs == 1, "noSrfc: " << m_bndryCells->a[bndryId].m_noSrfcs
1003 << " bndryId: " << bndryId << " noCutPoints "
1004 << m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints);
1005 cellId = m_bndryCells->a[bndryId].m_cellId;
1006 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
1007 if((m_solver->c_noChildren(cellId) == 0 && m_solver->a_level(cellId) <= m_solver->maxRefinementLevel())
1008 || (m_solver->c_noChildren(cellId) > 0 && m_solver->a_level(cellId) == m_solver->maxRefinementLevel())) {
1009 // create one surface per space direction
1010 for(MInt i = 0; i < nDim; i++) {
1011 // if the surface is inclined, replace it by its projections into the
1012 // Cartesian frame of reference
1013 if(fabs(m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i]) > epsilon) {
1014 m_surfaces.append();
1015 srfcId = m_solver->a_noSurfaces() - 1;
1016
1017 // add the boundary surface
1020
1021 // set the boundary condition
1022 m_solver->a_surfaceBndryCndId(srfcId) = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
1023
1024 // the coordinates of the new surface are shifted...
1025 for(MInt j = 0; j < nDim; j++) {
1026 m_solver->a_surfaceCoordinate(srfcId, j) = m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[j];
1027 }
1028
1029 // projection to compute the area of the surface
1030 m_solver->a_surfaceArea(srfcId) = m_bndryCells->a[bndryId].m_srfcs[0]->m_area
1031 * fabs(m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i]);
1032
1033 // set the surface orientation
1034 m_solver->a_surfaceOrientation(srfcId) = i;
1035
1036 ASSERT(ghostCellId > -1, "");
1037
1038 // set the surface neigbors
1039 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i] > F0) {
1040 m_solver->a_surfaceNghbrCellId(srfcId, 0) = ghostCellId;
1041 m_solver->a_surfaceNghbrCellId(srfcId, 1) = cellId;
1042 } else {
1043 m_solver->a_surfaceNghbrCellId(srfcId, 1) = ghostCellId;
1044 m_solver->a_surfaceNghbrCellId(srfcId, 0) = cellId;
1045 }
1046
1047 // set the pointer from the body surface to the cartesian surfaces
1048 m_bndryCells->a[bndryId].m_srfcVariables[0]->m_srfcId[i] = srfcId;
1049 }
1050 }
1051 }
1052 }
1053 }
1054}
MInt size()
Definition: collector.h:29
maia::fv::surface_collector::FvSurfaceCollector< nDim > & m_surfaces
MInt a_noSurfaces()
Returns the number of surfaces.
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.
MInt c_noChildren(const MInt cellId) const
Returns the number of children of the cell cellId.
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.
MInt & a_bndryId(const MInt cellId)
Returns the bndryId of the cell cellId.
MInt maxRefinementLevel() const
bool MBool
Definition: maiatypes.h:58

◆ addBoundarySurfacesMGC()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::addBoundarySurfacesMGC

version is able to work with multiple boundary surfaces per cell it adds one surface for each boundary surface

Author
Claudia Guenther, April 2009

Definition at line 1068 of file fvcartesianbndrycndxd.cpp.

1068 {
1069 TRACE();
1070
1071 MBool cellOk;
1072 MInt cellId, ghostCellId;
1073 MInt noCells = m_bndryCells->size();
1074 MInt srfcId = 0;
1075 MFloat epsilon = pow(10.0, -20.0);
1076 //---
1077
1079
1080 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
1081 cellOk = false;
1082
1083 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
1084 for(MInt i = 0; i < nDim; i++) {
1085 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = -1;
1086 }
1087 }
1088
1089 if(m_solver->a_hasProperty(m_bndryCells->a[bndryId].m_cellId, SolverCell::IsInvalid)) continue;
1090
1091 // do not consider grid halo cells; only those which have a non-halo cell as master
1092 if(m_solver->a_isHalo(m_bndryCells->a[bndryId].m_cellId)) {
1093 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) {
1094 if(!m_solver->a_isHalo(m_bndryCells->a[bndryId].m_linkedCellId)) cellOk = true;
1095 }
1096 } else {
1097 cellOk = true;
1098 }
1099
1100 if(cellOk) {
1101 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
1102 cellId = m_bndryCells->a[bndryId].m_cellId;
1103 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
1104 MInt gridcellId = cellId;
1105 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitClone)) {
1106 gridcellId = m_solver->m_splitChildToSplitCell.find(cellId)->second;
1107 }
1108 if((m_solver->c_noChildren(gridcellId) == 0 && m_solver->a_level(cellId) <= m_solver->maxRefinementLevel())
1109 || (m_solver->c_noChildren(gridcellId) > 0 && m_solver->a_level(cellId) == m_solver->maxRefinementLevel())) {
1110 // create one surface per space direction
1111 for(MInt i = 0; i < nDim; i++) {
1112 // if the surface is inclined, replace it by its projections into the
1113 // Cartesian frame of reference
1114 if(fabs(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]) > epsilon) {
1115 m_surfaces.append();
1116 srfcId = m_solver->a_noSurfaces() - 1;
1117
1118 // add the boundary surface
1121
1122 // set the boundary condition
1123 m_solver->a_surfaceBndryCndId(srfcId) = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId;
1124
1125 // the coordinates of the new surface are shifted...
1126 for(MInt j = 0; j < nDim; j++) {
1127 m_solver->a_surfaceCoordinate(srfcId, j) = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[j];
1128 }
1129
1130 // projection to compute the area of the surface
1131 m_solver->a_surfaceArea(srfcId) = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
1132 * fabs(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]);
1133
1134 // set the surface orientation
1135 m_solver->a_surfaceOrientation(srfcId) = i;
1136
1137 // set the surface neigbors
1138 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] > F0) {
1139 m_solver->a_surfaceNghbrCellId(srfcId, 0) = ghostCellId;
1140 m_solver->a_surfaceNghbrCellId(srfcId, 1) = cellId;
1141 } else {
1142 m_solver->a_surfaceNghbrCellId(srfcId, 1) = ghostCellId;
1143 m_solver->a_surfaceNghbrCellId(srfcId, 0) = cellId;
1144 }
1145
1146 // set the pointer from the body surface to the cartesian surfaces
1147 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_srfcId[i] = srfcId;
1148 }
1149 }
1150 }
1151 }
1152 }
1153 }
1154}
std::map< MInt, MInt > m_splitChildToSplitCell
MBool a_hasProperty(const MInt cellId, const Cell p) const
Returns grid cell property p of the cell cellId.

◆ addModes()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::addModes ( MInt  bcId)

Definition at line 7055 of file fvcartesianbndrycndxd.cpp.

7055 {
7056 TRACE();
7057 const MFloat time = m_solver->m_time;
7058 const MInt bcNum = m_cutOffBndryCndIds[bcId];
7059
7060 for(MInt mode = 0; mode < m_modes; mode++) {
7061 const MFloat modeEtaMin = m_modeEtaMin[mode];
7062 const MFloat modePhi = m_modePhi[mode];
7063 const MFloat modeOmega = m_modeOmega[mode];
7064
7065 // 0. set the end of the wave(s)
7066 const MFloat modeEtaMax = -(MFloat)(m_nmbrOfModes[mode]) * PI;
7067
7068 // 1. pressure
7069 const MFloat pressure_f = m_modeAmp[mode] * m_solver->m_PInfinity * (MFloat)(m_modeType[mode]);
7070
7071 // 2. density
7072 const MFloat a = sysEqn().speedOfSound(m_solver->m_TInfinity);
7073 const MFloat density_f = m_modeType[mode] ? pressure_f / POW2(a) : m_modeAmp[mode] * m_solver->m_rhoInfinity;
7074
7075 // 3. velocity
7076 MFloat K = F0;
7077 for(MInt i = 0; i < nDim; i++) {
7078 K += pow(m_modeK[mode][i], 2);
7079 }
7080 K = sqrt(K);
7081 const MFloat acImp = a * m_solver->m_rhoInfinity;
7082 const MFloat modeVelocity = (MFloat)(m_modeType[mode]) * pressure_f / acImp;
7083 MFloat velocity_f[3];
7084 for(MInt i = 0; i < nDim; i++) {
7085 velocity_f[i] = (m_modeK[mode][i] * modeVelocity) / K;
7086 }
7087
7088 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
7089 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
7090 if(bcNum == 2770) {
7091 if(m_solver->a_coordinate(cellId, 1)
7092 < m_ys + (tan(m_solver->m_angle[0] + m_sigmaShock) * m_solver->a_coordinate(cellId, 0))) {
7093 continue;
7094 }
7095 }
7096 // 1. calculate cell dependant trigonometry
7097 MFloat trigTerm = F0;
7098 for(MInt i = 0; i < nDim; i++) {
7099 trigTerm += m_modeK[mode][i] * m_solver->a_coordinate(cellId, i);
7100 }
7101 trigTerm -= modeOmega * time;
7102 trigTerm += modePhi;
7103
7104 // 2. filter the wave
7105 if(bcNum == 2800) {
7106 // 2.a calculate the difference to the reference starting min value (trigTerm decreases in time)
7107 trigTerm -= modeEtaMin;
7108
7109 // 2.b apply the filter to the phase
7110 if(trigTerm > F0 || trigTerm < modeEtaMax) {
7111 trigTerm = F0;
7112 }
7113 }
7114
7115 // 3. convert phase to amplitude
7116 trigTerm = sin(trigTerm);
7117
7118 // 4. add fluctuations
7119 // density
7120 m_solver->a_pvariable(cellId, PV->RHO) += trigTerm * density_f;
7121
7122 // velocities
7123 for(MInt dim = 0; dim < m_solver->nDim; dim++) {
7124 m_solver->a_pvariable(cellId, PV->VV[dim]) += trigTerm * velocity_f[dim];
7125 }
7126
7127 // pressure
7128 m_solver->a_pvariable(cellId, PV->P) += trigTerm * pressure_f;
7129 }
7130 }
7131}
static constexpr MInt nDim

◆ allocateCutOffMemory()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::allocateCutOffMemory
Author
Stephan Schlimpert
Date
April 2014

Definition at line 1823 of file fvcartesianbndrycndxd.cpp.

1823 {
1824 TRACE();
1826 // ASSERT(m_noCutOffBndryCndIds>0,"noCutOffBndryCndIds ==0");
1827 if(m_noCutOffBndryCndIds == 0) TERMM(1, "cut off is on, but no boundary conditions are available! ");
1828
1829 if(m_noCutOffBndryCndIds >= m_maxNoBndryCndIds) TERMM(1, "too many cut off bndryIds! ");
1830
1831 // Cleanup anything already present in m_sortedCutOffCells
1832 for(auto& i : m_sortedCutOffCells) {
1833 delete i;
1834 }
1835 m_sortedCutOffCells.clear();
1836
1837 m_log << "no cut off bcs " << m_noCutOffBndryCndIds << endl;
1838 for(MInt n = 0; n < m_noCutOffBndryCndIds; n++) {
1839 auto* sortedList = new List<MInt>(m_maxNoBndryCells);
1840 sortedList->setSize(0);
1841 m_sortedCutOffCells.push_back(sortedList);
1842 }
1843
1844 m_cbcCutOff = false;
1845 m_cbcCutOff = Context::getSolverProperty<MBool>("cutOffcbc", m_solverId, AT_, &m_cbcCutOff);
1846
1849 Context::getSolverProperty<MBool>("cbcSmallCellCorrection", m_solverId, AT_, &m_cbcSmallCellCorrection);
1850
1851 if(m_cbcCutOff) {
1861 }
1862 }
1863}
std::vector< MInt > m_cbcBndryCndIds
std::vector< std::vector< MFloat > > m_dirNormal
std::vector< MInt > m_cbcDomainMin
std::vector< std::vector< MFloat > > m_cbcReferencePoint
std::vector< std::vector< MFloat > > m_dirTangent
std::vector< std::vector< MFloat > > m_cbcRelax
std::vector< std::vector< MInt > > m_cbcDir
std::vector< MFloat > m_cbcLref
std::vector< MFloat > m_cbcInflowArea
Definition: list.h:16
InfoOutFile m_log

◆ applyNeumannBoundaryCondition()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::applyNeumannBoundaryCondition

Definition at line 1297 of file fvcartesianbndrycndxd.cpp.

1297 {
1298 TRACE();
1299
1300 // loop over all different boundary conditions
1301 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
1302 (this->*bndryCndHandlerNeumann[bcId])(bcId);
1303 }
1304
1305 copySlopesToSmallCells();
1306
1308}
BndryCndHandlerVar * bndryCndHandlerNeumann

◆ applyNonReflectingBCAfterTreatmentCutOff()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::applyNonReflectingBCAfterTreatmentCutOff

Definition at line 2077 of file fvcartesianbndrycndxd.cpp.

2077 {
2078 TRACE();
2079
2080 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++)
2082}
BndryCndHandler * nonReflectingBoundaryConditionAfterTreatmentCutOff

◆ applyNonReflectingBCCutOff()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::applyNonReflectingBCCutOff

Definition at line 2065 of file fvcartesianbndrycndxd.cpp.

2065 {
2066 TRACE();
2067
2068 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++)
2069 (this->*nonReflectingCutOffBoundaryCondition[bcId])(bcId);
2070}
BndryCndHandler * nonReflectingCutOffBoundaryCondition

◆ ATTRIBUTES2() [1/4]

template<MInt nDim, class SysEqn >
FvBndryCndXD< nDim, SysEqn >::ATTRIBUTES2 ( ATTRIBUTE_HOT  ,
ATTRIBUTE_FLATTEN   
)

◆ ATTRIBUTES2() [2/4]

template<MInt nDim, class SysEqn >
FvBndryCndXD< nDim, SysEqn >::ATTRIBUTES2 ( ATTRIBUTE_HOT  ,
ATTRIBUTE_FLATTEN   
)

◆ ATTRIBUTES2() [3/4]

template<MInt nDim, class SysEqn >
FvBndryCndXD< nDim, SysEqn >::ATTRIBUTES2 ( ATTRIBUTE_HOT  ,
ATTRIBUTE_FLATTEN   
)

◆ ATTRIBUTES2() [4/4]

template<MInt nDim, class SysEqn >
FvBndryCndXD< nDim, SysEqn >::ATTRIBUTES2 ( ATTRIBUTE_HOT  ,
ATTRIBUTE_FLATTEN   
) const

◆ bc0()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc0 ( MInt  )
inline

Definition at line 217 of file fvcartesianbndrycndxd.h.

217{/*do nothing*/};

◆ bc01()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc01 ( MInt  bcId)

Zero boundary condition: ghost cells set to infinity flow conditions (initial condition)
Debug boundary condition
Set of variables: Standard CV
u=v=w=0, rho=1, p=1/gamma

Author
Claudia Guenther

Definition at line 13774 of file fvcartesianbndrycndxd.cpp.

13774 {
13775 TRACE();
13776
13777#ifdef _OPENMP
13778#pragma omp parallel for
13779#endif
13780 // loop over all concerning boundary cells
13781 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13782 const MInt cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
13783 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13784 const MInt ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
13785
13786 // set the density
13787 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13788 2.0 * m_solver->m_rhoInfinity - m_solver->a_pvariable(cellId, PV->RHO);
13789
13790
13791 // set the velocities
13792 for(MInt i = 0; i < nDim; i++) {
13793 m_solver->a_pvariable(ghostCellId, PV->VV[i]) =
13794 2.0 * m_solver->m_VVInfinity[i] - m_solver->a_pvariable(cellId, PV->VV[i]);
13795 }
13796
13797 // set the pressure of the ghost cell equal to that of the boundary cell
13798 m_solver->a_pvariable(ghostCellId, PV->P) = 2.0 * m_solver->m_PInfinity;
13799 }
13800 }
13801}
T * a
Definition: list.h:28

◆ bc0Var()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc0Var ( MInt  )
inline

Definition at line 218 of file fvcartesianbndrycndxd.h.

218{/*do nothing*/};

◆ bc1000()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1000 ( MInt  bcId)

Zero boundary condition: ghost cells set to quiescent flow (initial condition)
Set of variables: Standard CV
u=v=w=0, rho=1, p=1/gamma

Author
Claudia Guenther

Definition at line 13812 of file fvcartesianbndrycndxd.cpp.

13812 {
13813 TRACE();
13814
13815#ifdef _OPENMP
13816#pragma omp parallel for
13817#endif
13818 // loop over all concerning boundary cells
13819 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13820 const MInt cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
13821 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13822 const MInt ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
13823
13824 // set the density
13825 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
13826
13827 // set the velocities
13828 for(MInt i = 0; i < nDim; i++) {
13829 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = -m_solver->a_pvariable(cellId, PV->VV[i]);
13830 }
13831
13832 // set the pressure of the ghost cell equal to that of the boundary cell
13833 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13834
13835 for(MInt s = 0; s < m_noSpecies; s++) {
13836 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
13837 }
13838 }
13839 }
13840}

◆ bc1001()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1001 ( MInt  bcId)

Subsonic inflow boundary condition.
Set of variables: Standard CV
u=v=w=IF; rho=rhoIF; dp/dn=0;

Author
Daniel Hartmann
Date
November 11, 2006 (3D)

Definition at line 13853 of file fvcartesianbndrycndxd.cpp.

13853 {
13854 TRACE();
13855
13856#ifdef _OPENMP
13857#pragma omp parallel for
13858#endif
13859 // loop over all concerning boundary cells
13860 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13861 const MInt cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
13862 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13863 const MInt ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
13864
13865 // set the density
13866 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13867 2.0 * m_solver->m_rhoInfinity - m_solver->a_pvariable(cellId, PV->RHO);
13868
13869 // set the velocities
13870 for(MInt i = 0; i < nDim; i++) {
13871 m_solver->a_pvariable(ghostCellId, PV->VV[i]) =
13872 F2 * m_solver->m_VVInfinity[i] - m_solver->a_pvariable(cellId, PV->VV[i]);
13873 }
13874
13875 // set the pressure of the ghost cell equal to that of the boundary cell
13876 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13877 IF_CONSTEXPR(hasPV_C<SysEqn>::value) {
13878 if(m_combustion) {
13879 m_solver->a_pvariable(ghostCellId, PV->C) = -m_solver->a_pvariable(cellId, PV->C);
13880 }
13881 }
13882 IF_CONSTEXPR(isDetChem<SysEqn>) {
13883 for(MInt s = 0; s < m_noSpecies; s++) {
13884 m_solver->a_pvariable(ghostCellId, PV->Y[s]) =
13885 2.0 * m_solver->m_YInfinity[s] - m_solver->a_pvariable(cellId, PV->Y[s]);
13886 }
13887 }
13888 else {
13889 if(m_isEEGas) {
13890 m_solver->a_pvariable(ghostCellId, PV->Y[0]) =
13891 2.0 * m_solver->m_EEGas.alphaIn - m_solver->a_pvariable(cellId, PV->Y[0]);
13892 } else {
13893 for(MInt s = 0; s < m_noSpecies; s++) {
13894 m_solver->a_pvariable(cellId, PV->Y[s]) = 1.0;
13895 }
13896 }
13897 }
13898 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
13899 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_SA_DV || SysEqn::m_ransModel == RANS_FS) {
13900 m_solver->a_pvariable(ghostCellId, PV->N) =
13901 2.0 * m_solver->m_nuTildeInfinity - m_solver->a_pvariable(cellId, PV->N);
13902 }
13903 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_KOMEGA || SysEqn::m_ransModel == RANS_SST) {
13904 m_solver->a_pvariable(ghostCellId, PV->K) =
13905 2.0 * m_solver->m_kInfinity - m_solver->a_pvariable(cellId, PV->K);
13906 m_solver->a_pvariable(ghostCellId, PV->OMEGA) =
13907 2.0 * m_solver->m_omegaInfinity - m_solver->a_pvariable(cellId, PV->OMEGA);
13908 }
13909 }
13910 }
13911 }
13912}
struct FvCartesianSolverXD::@8 m_EEGas
Checks if the primitive variable C exists.
@ RANS_SA_DV
Definition: enums.h:54
@ RANS_SST
Definition: enums.h:57
@ RANS_FS
Definition: enums.h:55
@ RANS_KOMEGA
Definition: enums.h:56

◆ bc100100()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc100100 ( MInt  bcId)

Symmetry boundary condition about x-axis

Author
Claudia Guenther
Date
01/2014

Definition at line 17777 of file fvcartesianbndrycndxd.cpp.

17777 {
17778 TRACE();
17779
17780#ifdef _OPENMP
17781#pragma omp parallel for
17782#endif
17783 // loop over all concerning boundary cells
17784 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
17785 const MInt cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
17786 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
17787 const MInt ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
17788
17789 // set the density
17790 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
17791
17792 // set the velocities
17793 m_solver->a_pvariable(ghostCellId, PV->U) = m_solver->a_pvariable(cellId, PV->U);
17794 m_solver->a_pvariable(ghostCellId, PV->V) = -m_solver->a_pvariable(cellId, PV->V);
17795
17796 // set the pressure of the ghost cell equal to that of the boundary cell
17797 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
17798
17799 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
17800 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
17801 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = m_solver->a_pvariable(cellId, PV->N);
17802 }
17803 }
17804 }
17805 }
17806}

◆ bc1001coflowY()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1001coflowY ( MInt  )
inlinevirtual

Definition at line 250 of file fvcartesianbndrycndxd.h.

250{};

◆ bc1002()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1002 ( MInt  bcId)

Subsonic outflow boundary condition. Set of variables: Standard CV
du/dn=dv/dn=dw/dn=0; drho/dn=0; p=pIF;

3D version

Author
Daniel Hartmann
Date
November 11, 2006 (3D)

Definition at line 13925 of file fvcartesianbndrycndxd.cpp.

13925 {
13926 TRACE();
13927
13928#ifdef _OPENMP
13929#pragma omp parallel for
13930#endif
13931 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13932 const MInt cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
13933 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13934 const MInt ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
13935
13936 // set the density
13937 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
13938
13939 // set the velocities
13940 for(MInt i = 0; i < nDim; i++) {
13941 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = m_solver->a_pvariable(cellId, PV->VV[i]);
13942 }
13943
13944 // set the pressure
13945 m_solver->a_pvariable(ghostCellId, PV->P) = 2.0 * m_solver->m_PInfinity - m_solver->a_pvariable(cellId, PV->P);
13946
13947 if(isDetChem<SysEqn> || m_isEEGas) {
13948 for(MInt s = 0; s < m_noSpecies; s++) {
13949 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
13950 }
13951 } else {
13952 for(MInt s = 0; s < m_noSpecies; s++) {
13953 m_solver->a_pvariable(cellId, PV->Y[s]) = 0.0;
13954 }
13955 }
13956
13957
13958 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
13959 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
13960 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = m_solver->a_pvariable(cellId, PV->NN[r]);
13961 }
13962 }
13963 }
13964 }
13965}

◆ bc1003()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1003 ( MInt  )
inlinevirtual

Definition at line 256 of file fvcartesianbndrycndxd.h.

256{};

◆ bc1004()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1004 ( MInt  )
inlinevirtual

Definition at line 257 of file fvcartesianbndrycndxd.h.

257{};

◆ bc1005()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1005 ( MInt  )
inlinevirtual

Definition at line 258 of file fvcartesianbndrycndxd.h.

258{};

◆ bc1009()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1009 ( MInt  bcId)

Subsonic inflow boundary condition for cavity flow with different Mach number.
Set of variables: Standard CV
u=v=w=IF; rho=rhoIF; dp/dn=0;

Author
Jannik Borgelt
Date
November 01, 2020 (3D)

Definition at line 13977 of file fvcartesianbndrycndxd.cpp.

13977 {
13978 TRACE();
13979
13980#ifdef _OPENMP
13981#pragma omp parallel for
13982#endif
13983 // loop over all concerning boundary cells
13984 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13985 const MInt cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
13986 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13987 const MInt ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
13988
13989 // Density
13990 m_solver->a_pvariable(ghostCellId, PV->RHO) = 2.0 * m_solver->m_rhoCg - m_solver->a_pvariable(cellId, PV->RHO);
13991
13992 // Velocities
13993 m_solver->a_pvariable(ghostCellId, PV->VV[0]) = 2.0 * m_solver->m_UCg - m_solver->a_pvariable(cellId, PV->U);
13994 m_solver->a_pvariable(ghostCellId, PV->VV[1]) = 2.0 * m_solver->m_VCg - m_solver->a_pvariable(cellId, PV->V);
13995 m_solver->a_pvariable(ghostCellId, PV->VV[2]) = 2.0 * m_solver->m_WCg - m_solver->a_pvariable(cellId, PV->W);
13996
13997 // Pressure
13998 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13999
14000 // Species
14001 if(!m_isEEGas) {
14002 for(MInt s = 0; s < m_noSpecies; s++) {
14003 m_solver->a_pvariable(cellId, PV->Y[s]) = 1.0;
14004 }
14005 }
14006
14007 // RANS
14008 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
14009 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_SA_DV || SysEqn::m_ransModel == RANS_FS) {
14010 m_solver->a_pvariable(ghostCellId, PV->N) =
14011 2.0 * m_solver->m_nuTildeInfinity - m_solver->a_pvariable(cellId, PV->N);
14012 }
14013 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_KOMEGA || SysEqn::m_ransModel == RANS_SST) {
14014 m_solver->a_pvariable(ghostCellId, PV->K) =
14015 2.0 * m_solver->m_kInfinity - m_solver->a_pvariable(cellId, PV->K);
14016 m_solver->a_pvariable(ghostCellId, PV->OMEGA) =
14017 2.0 * m_solver->m_omegaInfinity - m_solver->a_pvariable(cellId, PV->OMEGA);
14018 }
14019 }
14020 }
14021 }
14022}

◆ bc1091()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1091 ( MInt  bcId)

Subsonic laminar tube inflow boundary condition normal to the boundary
Set of variables: Standard PV
prescribes a constant stagnation pressure
density and pressure are computed according to massflux
velocity is computed according to massflux such that a parabolic profile is attained
only valid for circular tubes

multiple ghost cells can be handled but MGC formulation is not used surface ghost cells can not be handled

no 2D version available

Author
Claudia Guenther
Date
June 2009, modified Mai 2010

Definition at line 14084 of file fvcartesianbndrycndxd.cpp.

14084 {
14085 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1091 is untested for 2D!"); }
14086 TRACE();
14087
14088 MInt cellId;
14089 MInt bndryId;
14090 MInt ghostCellId;
14091 MFloat R;
14092 MFloat massflux = F0;
14093 MFloat inflowArea = F0;
14094 MFloat pressure = F0;
14095 MFloat localVel = F0;
14096 MFloat density = F0;
14097 MFloat referencePoint[3] = {0.0, 0.0, 0.0};
14098 MFloat normal[3] = {0.0, 0.0, 0.0};
14099 MFloat radius = F0;
14100 MFloat velocity = F0;
14101
14102 // --- end of initialization
14103
14104 // compute current massflux, inflow area, reference Point and normal of the inflow area
14105 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
14106 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
14107 bndryId = m_solver->a_bndryId(cellId);
14108 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
14109 for(MInt srfc = 0; srfc < m_bndryCells->a[m_sortedBndryCells->a[id]].m_noSrfcs; srfc++) {
14110 // search for surfaces which belong to the respective boundary condition
14111 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
14112 // compute massflux through the first cell layer
14113 massflux -= (((m_solver->a_pvariable(cellId, PV->U)) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
14114 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0]
14115 + (m_solver->a_pvariable(cellId, PV->V)) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
14116 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1]
14117 + (m_solver->a_pvariable(cellId, PV->W)) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
14118 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2])
14119 * (m_solver->a_pvariable(cellId, PV->RHO)));
14120 inflowArea += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
14121
14122 // compute midpoint of inflow boundary and mean normal
14123 for(MInt i = 0; i < 3; i++) {
14124 referencePoint[i] += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i]
14125 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
14126 normal[i] += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
14127 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
14128 }
14129 }
14130 }
14131 }
14132 }
14133 for(MInt i = 0; i < 3; i++) {
14134 referencePoint[i] /= inflowArea;
14135 normal[i] /= inflowArea;
14136 }
14137
14138 // compute massflux per unit area
14139 massflux /= inflowArea;
14140
14141 // compute static pressure and density iteratively (see e.g. thesis of Ingolf Hoerschler)
14142 pressure = sysEqn().p_Ref();
14143 for(MInt i = 0; i < 20; i++) {
14144 pressure = sysEqn().pressure_IRit(pressure, massflux);
14145 }
14146 pressure = pressure * sysEqn().p_Ref();
14147 density = sysEqn().density_IR_P(pressure);
14148
14149 localVel = massflux / density;
14150
14151 R = sqrt(inflowArea / PI);
14152 radius = F0;
14153 velocity = F0;
14154
14155 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
14156 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
14157 bndryId = m_solver->a_bndryId(cellId);
14158 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
14159 for(MInt srfc = 0; srfc < m_bndryCells->a[m_sortedBndryCells->a[id]].m_noSrfcs; srfc++) {
14160 // search for surfaces which belong to the respective boundary condition
14161 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
14162 ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[srfc]->m_ghostCellId;
14163
14164 // compute radius of the boundary surface and compute velocity according to parabolic profile
14165 radius = POW2(m_solver->a_coordinate(cellId, 0) - referencePoint[0])
14166 + POW2(m_solver->a_coordinate(cellId, 1) - referencePoint[1])
14167 + POW2(m_solver->a_coordinate(cellId, 2) - referencePoint[2]);
14168 velocity = 2.0 * localVel * (1 - radius / POW2(R));
14169
14170 // set ghost cell variables such that p, rho, v_i are attained on the boundary surface; v is assumed to be
14171 // normal to the surface
14172 m_solver->a_pvariable(ghostCellId, PV->RHO) = F2 * density - m_solver->a_pvariable(cellId, PV->RHO);
14173 m_solver->a_pvariable(ghostCellId, PV->P) = F2 * pressure - m_solver->a_pvariable(cellId, PV->P);
14174 m_solver->a_pvariable(ghostCellId, PV->U) =
14175 -F2 * velocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0]
14176 - m_solver->a_pvariable(cellId, PV->U);
14177 m_solver->a_pvariable(ghostCellId, PV->V) =
14178 -F2 * velocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1]
14179 - m_solver->a_pvariable(cellId, PV->V);
14180 m_solver->a_pvariable(ghostCellId, PV->W) =
14181 -F2 * velocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2]
14182 - m_solver->a_pvariable(cellId, PV->W);
14183 }
14184 }
14185 }
14186 }
14187}

◆ bc10910()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc10910 ( MInt  )
inlinevirtual

Definition at line 251 of file fvcartesianbndrycndxd.h.

251{};

◆ bc1091MGC()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1091MGC ( MInt  bcId)

Subsonic laminar tube inflow boundary condition normal to the boundary - multiple ghost cells

Set of variables: Standard PV
prescribes a constant stagnation pressure
density and pressure are computed according to massflux
velocity is computed according to massflux such that a parabolic profile is attained
only valid for circular tubes

special formulation for complex boundaries with multiple ghost cells
works also for surface ghost cells (m_surfaceGhostCell = true)

no 2D version available

minimum number of time steps is prescribed for different testcases
which is required to obtain a massflux different from zero

Author
Claudia Guenther
Date
June 2009, modified Mai 2010

Definition at line 22497 of file fvcartesianbndrycndxd.cpp.

22497 {
22498 TRACE();
22499 IF_CONSTEXPR(nDim == 2) TERMM(1, "3D BC!");
22500
22501 if(m_bndryCndCells[bcId] == m_bndryCndCells[bcId + 1]) {
22502 return;
22503 }
22504
22505 MInt cellId, bndryId;
22506 MInt ghostCellId;
22507 MFloat R;
22508 MFloat massflux = F0;
22509 MFloat inflowArea = F0;
22510 MFloat meanPressure;
22511 MFloat localVelocity;
22512 MFloat meanDensity;
22513 MFloat referencePoint[3] = {0.0, 0.0, 0.0};
22514 MFloat normal[3] = {0.0, 0.0, 0.0};
22515 MFloat radius;
22516 MFloat meanVelocity;
22517 MFloat epsilon = 1e-15;
22518 MInt nghbrId;
22521 MFloatScratchSpace comm_buff_scratch(5, AT_, "comm_buff_scratch");
22522 MFloatScratchSpace comm_buff_result_scratch(5, AT_, "comm_buff_result_scratch");
22523 MFloat* comm_buff = comm_buff_scratch.getPointer();
22524 MFloat* comm_buff_result = comm_buff_result_scratch.getPointer();
22525 MInt noBndryCndCells = m_bndryCndCells[bcId + 1] - m_bndryCndCells[bcId];
22526 MIntScratchSpace edgeCells_scratch(noBndryCndCells, AT_, "edgeCells_scratch");
22527 MFloatScratchSpace edgeDistance_scratch(noBndryCndCells, AT_, "edgeDistance_scratch");
22528 MIntScratchSpace edgeSurface_scratch(noBndryCndCells, AT_, "edgeSurface_scratch");
22529 MInt edgeCellCounter = m_static_bc1091MGC_edgeCellCounter;
22532 MFloat distCur;
22533
22534 // --- end of initialization
22535
22536
22537 if(first2) {
22538 // claudia vorsicht: Alte Testcases aendern!
22539 // SUZI_TC: minTimeSteps = 550
22540 // NOZZLE_TC: minTimeSteps = 260
22541 // TINA_TC: minTimeSteps = 520
22542 // spongeLayerType 49: minTimeSteps = 800
22543 // spongeLayerType 50: minTimeSteps = 750
22544 // special treatment for engine test cases: massflux accepted soonest after minTimeSteps time steps
22545 minTimeSteps = Context::getSolverProperty<MInt>("InflowMinTimeSteps", m_solverId, AT_, &minTimeSteps);
22546
22547 // SUZI_TC: nghbrDir = 0
22548 // ELBOW_TC: nghbrDir = 3
22549 // NOZZLE_TC: nghbrDir = 2
22550 // TINA_TC: nghbrDir = 1
22551 // else: nghbrDir = -1
22552 // special treatment: massflux is averaged over two layers
22553 nghbrDir = Context::getSolverProperty<MInt>("InflowNghbrDir", m_solverId, AT_, &nghbrDir);
22554
22555 first2 = false;
22556 }
22558
22559 // compute current massflux, inflow area, reference Point and normal of the inflow area
22560 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22561 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
22562 bndryId = m_solver->a_bndryId(cellId);
22563 if(m_solver->a_hasProperty(cellId,
22564 SolverCell::IsNotGradient)) { // do not compute massflux of multisolver ghost cells!
22565 continue;
22566 }
22567 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22568 for(MInt srfc = 0; srfc < m_bndryCells->a[m_sortedBndryCells->a[id]].m_noSrfcs; srfc++) {
22569 // search for surfaces which belong to the respective boundary condition
22570 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
22571 // compute massflux through the first cell layer
22572 massflux -= (((m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->U])
22573 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
22574 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0]
22575 + (m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->V])
22576 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
22577 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1]
22578 + (m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->W])
22579 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
22580 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2])
22581 * (m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->RHO]));
22582
22583 if(nghbrDir > -1) {
22584 // compute massflux through the next cell layer
22585 // validity of nghbrId has to be guaranteed by the user! (only for special testcases!)
22586 // only valid if normal is parallel a coordinate axis
22587 nghbrId = m_solver->c_neighborId(cellId, nghbrDir);
22588 massflux -= (((m_solver->a_pvariable(nghbrId, PV->U)) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
22589 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0]
22590 + (m_solver->a_pvariable(nghbrId, PV->V)) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
22591 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1]
22592 + (m_solver->a_pvariable(nghbrId, PV->W)) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area
22593 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2])
22594 * (m_solver->a_pvariable(nghbrId, PV->RHO)));
22595 }
22596 inflowArea += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
22597
22598 // compute midpoint of inflow boundary and mean normal
22599 for(MInt i = 0; i < 3; i++) {
22600 referencePoint[i] += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i]
22601 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
22602 normal[i] += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
22603 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area;
22604 }
22605 }
22606 }
22607 }
22608 }
22609
22610 comm_buff[0] = inflowArea;
22611 comm_buff[1] = referencePoint[0];
22612 comm_buff[2] = referencePoint[1];
22613 comm_buff[3] = referencePoint[2];
22614 comm_buff[4] = massflux;
22615
22616 if(noDomains() > 1) {
22617 MPI_Allreduce(comm_buff, comm_buff_result, 5, MPI_DOUBLE, MPI_SUM, m_comm_bc[m_bc_comm_pointer[bcId]], AT_,
22618 "comm_buff", "comm_buff_result");
22619 }
22620
22621 inflowArea = comm_buff_result[0];
22622 referencePoint[0] = comm_buff_result[1];
22623 referencePoint[1] = comm_buff_result[2];
22624 referencePoint[2] = comm_buff_result[3];
22625 massflux = comm_buff_result[4];
22626
22627 for(MInt i = 0; i < 3; i++) {
22628 referencePoint[i] /= inflowArea;
22629 normal[i] /= inflowArea;
22630 }
22631
22632 // special treatment for nozzle testcase
22634 normal[0] = 0.0;
22635 normal[1] = -1.0;
22636 normal[2] = F0;
22637 referencePoint[0] = 0.0;
22638 referencePoint[2] = 0.0;
22639 }
22640
22641 // compute massflux per unit area
22642 if(nghbrDir > -1) {
22643 massflux /= (2.0 * inflowArea);
22644 } else {
22645 massflux /= (inflowArea);
22646 }
22647
22648 // correct massflux if necessary
22649 if(abs(massflux) < epsilon * inflowArea || globalTimeStep < minTimeSteps) {
22650 massflux = F0;
22651 }
22652
22653 // compute static pressure and density iteratively (see e.g. thesis of Ingolf Hoerschler)
22654 meanPressure = sysEqn().p_Ref();
22655 for(MInt i = 0; i < 20; i++) {
22656 meanPressure = sysEqn().pressure_IRit(meanPressure, massflux);
22657 }
22658 meanPressure = meanPressure * sysEqn().p_Ref();
22659 meanDensity = sysEqn().density_IR_P(meanPressure);
22660 meanVelocity = massflux / meanDensity;
22661
22662 R = sqrt(inflowArea / PI);
22663
22664 // "brute force" computation of boundary distance for TINA engine - non-circular inflow...
22665 if(string2enum(m_solver->m_testCaseName) == TINA_TC && first) {
22666 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22667 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
22668 bndryId = m_solver->a_bndryId(cellId);
22669 if(m_solver->a_hasProperty(cellId,
22670 SolverCell::IsNotGradient)) { // do not compute massflux of multisolver ghost cells!
22671 continue;
22672 }
22673 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22674 if(m_bndryCells->a[bndryId].m_noSrfcs > 1) {
22675 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
22676 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId != m_bndryCndIds[bcId]) {
22677 edgeCells_scratch[edgeCellCounter] = bndryId;
22678 edgeSurface_scratch[edgeCellCounter] = srfc;
22679 edgeCellCounter++;
22680 }
22681 }
22682 }
22683 }
22684 }
22685 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22686 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
22687 bndryId = m_solver->a_bndryId(cellId);
22688 if(m_solver->a_hasProperty(cellId,
22689 SolverCell::IsNotGradient)) { // do not compute massflux of multisolver ghost cells!
22690 continue;
22691 }
22692 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22693 for(MInt srfc = 0; srfc < m_bndryCells->a[m_sortedBndryCells->a[id]].m_noSrfcs; srfc++) {
22694 // search for surfaces which belong to the respective boundary condition
22695 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
22696 edgeDistance_scratch[id - m_bndryCndCells[bcId]] = F2 * R;
22697 for(MInt ec = 0; ec < edgeCellCounter; ec++) {
22698 distCur = F0;
22699 for(MInt d = 0; d < nDim; d++) {
22700 distCur +=
22701 (m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[d]
22702 - m_bndryCells->a[edgeCells_scratch[ec]].m_srfcs[srfc]->m_coordinates[d])
22703 * (m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[d]
22704 - m_bndryCells->a[edgeCells_scratch[ec]].m_srfcs[edgeSurface_scratch[ec]]->m_coordinates[d]);
22705 }
22706 distCur = sqrt(distCur);
22707 if(distCur < edgeDistance_scratch[id - m_bndryCndCells[bcId]]) {
22708 edgeDistance_scratch[id - m_bndryCndCells[bcId]] = distCur;
22709 }
22710 }
22711 }
22712 }
22713 }
22714 }
22715 first = false;
22716 }
22717
22719
22720 MFloat K = 1.0;
22721
22723 MFloat Vdot = F0;
22724
22725 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22726 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
22727 bndryId = m_solver->a_bndryId(cellId);
22728 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22729 for(MInt srfc = 0; srfc < m_bndryCells->a[m_sortedBndryCells->a[id]].m_noSrfcs; srfc++) {
22730 // search for surfaces which belong to the respective boundary condition
22731 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
22732 // compute radius of the boundary surface and compute velocity according to parabolic profile
22733 radius = POW2(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[0] - referencePoint[0])
22734 + POW2(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[1] - referencePoint[1])
22735 + POW2(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[2] - referencePoint[2]);
22736 Vdot += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area * 2.0 * meanVelocity
22737 * (1.0 - radius / POW2(edgeDistance_scratch[id - m_bndryCndCells[bcId]] + sqrt(radius)));
22738 }
22739 }
22740 }
22741 }
22742 if(abs(meanVelocity) > epsilon * inflowArea && abs(Vdot / inflowArea) > epsilon * inflowArea) {
22743 K = meanVelocity / Vdot * inflowArea;
22744 }
22745 }
22746
22747
22748 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22749 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
22750 bndryId = m_solver->a_bndryId(cellId);
22751 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22752 for(MInt srfc = 0; srfc < m_bndryCells->a[m_sortedBndryCells->a[id]].m_noSrfcs; srfc++) {
22753 // search for surfaces which belong to the respective boundary condition
22754 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
22755 ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[srfc]->m_ghostCellId;
22756
22757 // compute radius of the boundary surface and compute velocity according to parabolic profile
22758 radius = POW2(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[0] - referencePoint[0])
22759 + POW2(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[1] - referencePoint[1])
22760 + POW2(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[2] - referencePoint[2]);
22761 localVelocity = 2.0 * meanVelocity * (1.0 - radius / POW2(R));
22763 localVelocity = 2.0 * meanVelocity * K
22764 * (1.0 - radius / POW2(edgeDistance_scratch[id - m_bndryCndCells[bcId]] + sqrt(radius)));
22765 }
22766 if((string2enum(m_solver->m_testCaseName) == NOZZLE_TC) && globalTimeStep >= minTimeSteps) {
22767 localVelocity = -((m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->U])
22768 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0]
22769 + (m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->V])
22770 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1]
22771 + (m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->W])
22772 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2])
22773 * (m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->RHO]) / meanDensity;
22774 }
22775
22776 // set ghost cell variables such that p, rho, v_i are attained on the boundary surface; v is assumed to be
22777 // normal to the surface
22778 m_solver->a_pvariable(ghostCellId, PV->RHO) =
22779 F2 * meanDensity - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->RHO];
22780 m_solver->a_pvariable(ghostCellId, PV->P) =
22781 F2 * meanPressure - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->P];
22782 m_solver->a_pvariable(ghostCellId, PV->U) =
22783 -F2 * localVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0]
22784 - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->U];
22785 m_solver->a_pvariable(ghostCellId, PV->V) =
22786 -F2 * localVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1]
22787 - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->V];
22788 m_solver->a_pvariable(ghostCellId, PV->W) =
22789 -F2 * localVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2]
22790 - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->W];
22791
22792 // if ghost cell is located on the surface, set values directly to the computed p, rho, v
22793 if(m_surfaceGhostCell) {
22794 m_solver->a_pvariable(ghostCellId, PV->RHO) = meanDensity;
22795 m_solver->a_pvariable(ghostCellId, PV->P) = meanPressure;
22796 m_solver->a_pvariable(ghostCellId, PV->U) =
22797 -localVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[0];
22798 m_solver->a_pvariable(ghostCellId, PV->W) =
22799 -localVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[2];
22800 m_solver->a_pvariable(ghostCellId, PV->V) =
22801 -localVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[1];
22802 }
22803 }
22804 }
22805 }
22806 }
22807
22808 if(globalTimeStep % 10 == 0)
22809 cerr << " ReferencePoint, R, normal, Massflux, pressure, density, velocity: " << referencePoint[0] << " "
22810 << referencePoint[1] << " " << referencePoint[2] << ", " << R << ", " << normal[0] << " " << normal[1] << " "
22811 << normal[2] << ", " << massflux << ", " << meanPressure << ", " << meanDensity << ", " << meanVelocity
22812 << endl;
22813}
MInt noDomains() const
Return the total number of domains (total number of ranks in current MPI communicator)
MInt m_static_bc1091MGC_minTimeSteps
MInt m_static_bc1091MGC_edgeCellCounter
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.
This class is a ScratchSpace.
Definition: scratch.h:758
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
Definition: enums.cpp:20
@ NOZZLE_TC
Definition: enums.h:178
@ TINA_TC
Definition: enums.h:178
MInt globalTimeStep
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

◆ bc10970()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc10970 ( MInt  bcId)

Subsonic outflow boundary condition with fixed pressure (cutOff)

Author
Claudia Guenther

Definition at line 15972 of file fvcartesianbndrycndxd.cpp.

15972 {
15973 TRACE();
15974
15975 if(m_sortedCutOffCells[bcId]->size() == 0) return;
15976
15977 const MInt otherDir[4] = {1, 0, 3, 2};
15978
15979 if(m_firstUseBc10970) {
15980 MInt noCutOffBndryIds = Context::propertyLength("cutOffBndryIds", m_solverId);
15981 MInt noCutOffDirections = Context::propertyLength("cutOffDirections", m_solverId);
15982 if(noCutOffDirections != noCutOffBndryIds)
15983 mTerm(1, AT_,
15984 "Wrong number of cut off directions. Must be identical to number of cut off bndryIds! Please check!");
15985 MInt cutOffBndryIdTmp, cutOffDirectionTmp;
15986 for(MInt i = 0; i < noCutOffBndryIds; i++) {
15987 cutOffBndryIdTmp = Context::getSolverProperty<MInt>("cutOffBndryIds", m_solverId, AT_, i);
15988 cutOffDirectionTmp = Context::getSolverProperty<MInt>("cutOffDirections", m_solverId, AT_, i);
15989 if(cutOffBndryIdTmp == m_cutOffBndryCndIds[bcId]) {
15990 m_dirNBc10970 = otherDir[cutOffDirectionTmp];
15991 break;
15992 }
15993 }
15994
15995 m_pModeBc10970 = 0;
15996 m_pModeBc10970 = Context::getSolverProperty<MInt>("BC10970Mode", m_solverId, AT_, &m_pModeBc10970);
15997 m_firstUseBc10970 = false;
15998 }
15999 //---
16000
16001 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16002 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16003 MInt nghbrId = m_solver->c_neighborId(cellId, m_dirNBc10970);
16004
16005 // set the density
16006 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
16007
16008 // set the velocities
16009 for(MInt i = 0; i < nDim; i++)
16010 m_solver->a_pvariable(cellId, PV->VV[i]) = m_solver->a_pvariable(nghbrId, PV->VV[i]);
16011
16012 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
16013 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
16014 m_solver->a_pvariable(cellId, PV->NN[r]) = m_solver->a_pvariable(nghbrId, PV->NN[r]);
16015 }
16016 }
16017
16018 // set the pressure
16019 if(m_pModeBc10970 == 0) {
16020 m_solver->a_pvariable(cellId, PV->P) = F2 * (m_solver->m_PInfinity) - m_solver->a_pvariable(nghbrId, PV->P);
16021 } else if(m_pModeBc10970 == 1) {
16022 m_solver->a_pvariable(cellId, PV->P) = 0.9 * m_solver->m_PInfinity;
16023 } else {
16024 mTerm(1, AT_, "Unknown pressure mode in BC10970");
16025 }
16026 }
16027}
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
Definition: context.cpp:538
MBool m_firstUseBc10970
Only 3D ends ///.
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29

◆ bc10980()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc10980 ( MInt  bcId)

Subsonic inflow boundary condition

Author
Claudia Guenther

Definition at line 16036 of file fvcartesianbndrycndxd.cpp.

16036 {
16037 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function bc10980 is untested for 3D!"); }
16038 TRACE();
16039
16040
16041 if(m_sortedCutOffCells[bcId]->size() == 0) return;
16042
16043 const MInt otherDir[4] = {1, 0, 3, 2};
16044
16045 if(m_firstUseBc10980) {
16046 MInt noCutOffBndryIds = Context::propertyLength("cutOffBndryIds", m_solverId);
16047 MInt noCutOffDirections = Context::propertyLength("cutOffDirections", m_solverId);
16048 if(noCutOffDirections != noCutOffBndryIds)
16049 mTerm(1, AT_,
16050 "Wrong number of cut off directions. Must be identical to number of cut off bndryIds! Please check!");
16051 MInt cutOffBndryIdTmp, cutOffDirectionTmp;
16052 for(MInt i = 0; i < noCutOffBndryIds; i++) {
16053 cutOffBndryIdTmp = Context::getSolverProperty<MInt>("cutOffBndryIds", m_solverId, AT_, i);
16054 cutOffDirectionTmp = Context::getSolverProperty<MInt>("cutOffDirections", m_solverId, AT_, i);
16055 if(cutOffBndryIdTmp == m_cutOffBndryCndIds[bcId]) {
16056 m_dirNBc10980 = otherDir[cutOffDirectionTmp];
16057 break;
16058 }
16059 }
16060
16061 m_firstUseBc10980 = false;
16062 }
16063 //---
16064
16065 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16066 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16067 MInt nghbrId = m_solver->c_neighborId(cellId, m_dirNBc10980);
16068
16069 // set the density
16070 m_solver->a_pvariable(cellId, PV->RHO) = F2 * m_solver->m_rhoInfinity - m_solver->a_pvariable(nghbrId, PV->RHO);
16071
16072 // set the velocities
16073 for(MInt i = 0; i < nDim; i++)
16074 m_solver->a_pvariable(cellId, PV->VV[i]) =
16075 F2 * m_solver->m_VVInfinity[i] - m_solver->a_pvariable(nghbrId, PV->VV[i]);
16076
16077 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
16078 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_SA_DV || SysEqn::m_ransModel == RANS_FS) {
16079 m_solver->a_pvariable(cellId, PV->N) = F2 * m_solver->m_nuTildeInfinity - m_solver->a_pvariable(nghbrId, PV->N);
16080 }
16081 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_KOMEGA || SysEqn::m_ransModel == RANS_SST) {
16082 m_solver->a_pvariable(cellId, PV->K) = F2 * m_solver->m_kInfinity - m_solver->a_pvariable(nghbrId, PV->K);
16083 m_solver->a_pvariable(cellId, PV->OMEGA) =
16084 F2 * m_solver->m_omegaInfinity - m_solver->a_pvariable(nghbrId, PV->OMEGA);
16085 }
16086 }
16087
16088 // set the pressure
16089 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
16090 }
16091}

◆ bc10990()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc10990 ( MInt  )
inlinevirtual

Definition at line 252 of file fvcartesianbndrycndxd.h.

252{};

◆ bc1099MGC()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1099MGC ( MInt  bcId)

Subsonic outflow boundary condition - MGC formulation
Set of variables: Standard PV
static pressure is prescribed with the pressure loss L*m_deltaP (see initialCondition)
density and velocities are assumed not to change in normal direction

multiple ghost cells are handled - MGC formulation is used
surface Ghost cells can be handled

L has to be specified for the respective testcase (approximative length between inflow and outflow) used to compute the pressure loss

no 2D version available

Author
Claudia Guenther
Date
Mai 2009, modified April 2010

Definition at line 22833 of file fvcartesianbndrycndxd.cpp.

22833 {
22834 TRACE();
22835 IF_CONSTEXPR(nDim == 2) TERMM(1, "3D BC!");
22836
22837 MInt cellId, bndryId, ghostCellId;
22838 // TINA_TC: L = 400.0
22839 // SUZI_TC: L = 400.0
22840 // standard: L = 400.0
22841 // NOZZLE_TC: L = 300.0
22842 // Pdiff = L * m_deltaP
22843 // m_Ma = 1.0: Pdiff = 0.1
22844 // neu! vorsicht - alte Testfaelle umstellen!
22845 MFloat& timeOfMaxPdiff = m_static_bc1099MGC_timeOfMaxPdiff;
22847 if(first) {
22848 timeOfMaxPdiff = Context::getSolverProperty<MFloat>("timeOfMaxPdiff", m_solverId, AT_, &timeOfMaxPdiff);
22849 // Convert from freestream-based to stagnation-based non-dimensionalization
22850 timeOfMaxPdiff = timeOfMaxPdiff / m_solver->m_timeRef;
22851 first = false;
22852 }
22853 MFloat Pdiff = m_deltaPL;
22854 MFloat fac = 1.0;
22855 if(m_solver->m_time < timeOfMaxPdiff) fac = m_solver->m_time / timeOfMaxPdiff;
22856 const MFloat initialPressure = sysEqn().p_Ref() - Pdiff;
22857 const MFloat deltaPressure = m_solver->m_PInfinity - sysEqn().p_Ref();
22858
22859
22860 //---
22861
22862 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22863 bndryId = m_sortedBndryCells->a[id];
22864 cellId = m_bndryCells->a[bndryId].m_cellId;
22865
22866 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22867 // set the pressure
22868 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
22869 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId != m_bndryCndIds[bcId]) {
22870 continue;
22871 }
22872 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
22873 m_solver->a_pvariable(ghostCellId, PV->P) =
22874 F2 * (initialPressure + fac * deltaPressure)
22875 - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->P];
22876
22877 // if ghost cell is located on the surface direct application of the surface pressure
22878 if(m_surfaceGhostCell) m_solver->a_pvariable(ghostCellId, PV->P) = (initialPressure + fac * deltaPressure);
22879
22880
22881 // apply the Neumann bc
22882 m_solver->a_pvariable(ghostCellId, PV->RHO) =
22883 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->RHO];
22884 m_solver->a_pvariable(ghostCellId, PV->U) =
22885 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->U];
22886 m_solver->a_pvariable(ghostCellId, PV->V) =
22887 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->V];
22888 m_solver->a_pvariable(ghostCellId, PV->W) =
22889 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->W];
22890 }
22891 }
22892 }
22893}
MFloat m_static_bc1099MGC_timeOfMaxPdiff

◆ bc1101()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1101 ( MInt  bcId)

Subsonic inflow boundary condition for reactants.
Set of variables: Standard CV
u=v=w=IF; rho=rhoIF; dp/dn=0; Yi=Yi81

Definition at line 14197 of file fvcartesianbndrycndxd.cpp.

14197 {
14198 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function bc1101 is untested for 3D!"); }
14199
14200 TRACE();
14201
14202 //----------------------------------------------------------------------------
14203
14204 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
14205 const MInt bndryId = m_sortedBndryCells->a[id];
14206 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
14207 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
14208 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
14209
14210 // density
14211 m_solver->a_variable(ghostCellId, CV->RHO) = F2 * m_solver->m_rhoInfinity - m_solver->a_variable(cellId, CV->RHO);
14212 const MFloat fRho = F1 / m_solver->a_variable(cellId, CV->RHO);
14213
14214 // velocities
14215 m_solver->a_variable(ghostCellId, CV->RHO_VV[0]) =
14216 m_solver->a_variable(ghostCellId, CV->RHO)
14217 * (F2 * m_solver->m_UInfinity - m_solver->a_variable(cellId, CV->RHO_VV[0]) * fRho);
14218
14219 m_solver->a_variable(ghostCellId, CV->RHO_VV[1]) =
14220 m_solver->a_variable(ghostCellId, CV->RHO)
14221 * (F2 * m_solver->m_VInfinity - m_solver->a_variable(cellId, CV->RHO_VV[1]) * fRho);
14222
14223 MFloat rhoU =
14224 POW2(m_solver->a_variable(cellId, CV->RHO_VV[0])) + POW2(m_solver->a_variable(cellId, CV->RHO_VV[1]));
14225 IF_CONSTEXPR(nDim == 3) { rhoU += POW2(m_solver->a_variable(cellId, CV->RHO_VV[2])); }
14226
14227 MFloat rhoUGC = POW2(m_solver->a_variable(ghostCellId, CV->RHO_VV[0]))
14228 + POW2(m_solver->a_variable(ghostCellId, CV->RHO_VV[1]));
14229 IF_CONSTEXPR(nDim == 3) { rhoUGC += POW2(m_solver->a_variable(ghostCellId, CV->RHO_VV[2])); }
14230 // pressure
14231 const MFloat pressureBC =
14232 sysEqn().pressure(m_solver->a_variable(cellId, CV->RHO), rhoU, m_solver->a_variable(cellId, CV->RHO_E));
14233
14234 const MFloat pressureGC = pressureBC;
14235
14236 const MFloat vel = rhoUGC / POW2(m_solver->a_variable(ghostCellId, CV->RHO));
14237
14238 m_solver->a_variable(ghostCellId, CV->RHO_E) =
14239 sysEqn().internalEnergy(pressureGC, m_solver->a_variable(ghostCellId, CV->RHO), vel);
14240
14241 /*
14242 // species
14243 for( MInt i=0; i<noSpecies-1; i++ ) {
14244 m_solver->a_variable( ghostCellId , CV->RHO_Y[i] ) =
14245 m_solver->a_variable( ghostCellId , CV->RHO ) *
14246 ( F2 * m_Yi81[i] -
14247 m_solver->a_variable( cellId , CV->RHO_Y[ i ] ) * fRho );
14248 }
14249 */
14250 }
14251 }
14252}
SysEqn::ConservativeVariables * CV
MFloat & a_variable(const MInt cellId, const MInt varId)
Returns conservative variable v of the cell cellId for variables varId.

◆ bc1102()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1102 ( MInt  bcId)

Subsonic outflow boundary condition for products.
Set of variables: Standard CV
du/dn=dv/dn=dw/dn=0; drho/dn=0; p=pIF; Yi = Yi82

Definition at line 14262 of file fvcartesianbndrycndxd.cpp.

14262 {
14263 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function bc1102 is untested for 3D!"); }
14264
14265 TRACE();
14266
14267 // pressure loss from inflow to outflow
14268 const MFloat deltaP = 0.0;
14269 // 5.0 * m_solver->m_rhoInfinity * m_solver->m_UInfinity * m_solver->m_UInfinity;
14270
14271 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
14272 const MInt bndryId = m_sortedBndryCells->a[id];
14273 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
14274 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
14275 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
14276
14277 // density
14278 m_solver->a_variable(ghostCellId, CV->RHO) = m_solver->a_variable(cellId, CV->RHO);
14279
14280 // momentum fluxes
14281 m_solver->a_variable(ghostCellId, CV->RHO_VV[0]) = m_solver->a_variable(cellId, CV->RHO_VV[0]);
14282 m_solver->a_variable(ghostCellId, CV->RHO_VV[1]) = m_solver->a_variable(cellId, CV->RHO_VV[1]);
14283 IF_CONSTEXPR(nDim == 3) {
14284 m_solver->a_variable(ghostCellId, CV->RHO_VV[2]) = m_solver->a_variable(cellId, CV->RHO_VV[2]);
14285 }
14286
14287 MFloat rhoU =
14288 POW2(m_solver->a_variable(cellId, CV->RHO_VV[0])) + POW2(m_solver->a_variable(cellId, CV->RHO_VV[1]));
14289 IF_CONSTEXPR(nDim == 3) { rhoU += POW2(m_solver->a_variable(cellId, CV->RHO_VV[2])); }
14290 // pressure
14291 const MFloat pressureBC =
14292 sysEqn().pressure(m_solver->a_variable(cellId, CV->RHO), rhoU, m_solver->a_variable(cellId, CV->RHO_E));
14293 const MFloat pressureGC = F2 * (m_solver->m_PInfinity - deltaP) - pressureBC;
14294 const MFloat vel = rhoU / m_solver->a_variable(ghostCellId, CV->RHO);
14295
14296
14297 m_solver->a_variable(ghostCellId, CV->RHO_E) =
14298 sysEqn().internalEnergy(pressureGC, m_solver->a_variable(cellId, CV->RHO), vel);
14299
14300 /*
14301 // species
14302 for( MInt i=0; i<noSpecies-1; i++ ) {
14303 m_solver->a_variable( ghostCellId , CV->RHO_Y[ i ] ) =
14304 m_solver->a_variable( ghostCellId , CV->RHO ) * fRho *
14305 m_solver->a_variable( cellId , CV->RHO_Y[ i ] );
14306 }
14307 */
14308 }
14309 }
14310}

◆ bc11110()

template<MInt nDim, class SysEqn >
FvBndryCndXD< nDim, SysEqn >::bc11110 ( MInt  )

TODO

◆ bc1156()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1156 ( MInt  bcId)

Cold/hot fuel/air coaxial jet (applied directly to the (boundary) cell)
Set of variables: Standard CV + passive scalar
u=v=w=IF; crocco-busemann relation rho=f(rhoIF); dp/dn=0; Z=1*rhoIF;
Seong et. al. Turbulence and heat excited noise sources in single and coaxial jets,2010

3D version

Author
Onur Cetin
Date
August, 2013 (3D)

Definition at line 14324 of file fvcartesianbndrycndxd.cpp.

14324 {
14325 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1156 is untested for 2D!"); }
14326 TRACE();
14327
14328 MInt cellId;
14329 MInt nghbrId;
14330 MInt d = 0;
14331 MFloat radius;
14332 MFloat jet; //, profile_T;//radius2;
14333 // --- end of initialization
14334
14335 switch(m_cutOffBndryCndIds[bcId]) {
14336 case 1156:
14337 d = 1;
14338 break;
14339 case 1166:
14340 d = 3;
14341 break;
14342 case 1176:
14343 d = 5;
14344 break;
14345 default: {
14346 stringstream errorMessage;
14347 errorMessage << "ERROR: Switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
14348 << " not matching any case." << endl;
14349 mTerm(1, AT_, errorMessage.str());
14350 }
14351 }
14352 // loop over all concerning cells
14353 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
14354 cellId = m_sortedCutOffCells[bcId]->a[id];
14355 nghbrId = m_solver->c_neighborId(cellId, d);
14356 // compute the radial position
14357 radius = F0;
14358 for(MInt i = 0; i < nDim; i++) {
14359 if(i != d / 2) radius += POW2(m_solver->a_coordinate(cellId, i));
14360 }
14361 radius = sqrt(radius);
14362
14363 // Jet mean velocity profile
14364 jet = (F1 / 0.90 - F1) * F1B2 * (1 + tanh((m_primaryJetRadius - radius) / (2 * m_momentumThickness)))
14365 + F1B2 * (1 + tanh((m_secondaryJetRadius - radius) / (2 * m_momentumThickness)));
14366
14367 // Set the velocities [Choose 0.05 for momentum thickness ref: Bogey&Bailly]
14369 m_solver->a_pvariable(cellId, PV->VV[1]) = F0;
14370 m_solver->a_pvariable(cellId, PV->VV[2]) = F0;
14371 if(radius <= m_primaryJetRadius) {
14372 // hot air jet
14373 //--------------
14374 // inflow mean density profile (Crocco-Buseman)
14375 m_solver->a_pvariable(cellId, PV->RHO) =
14376 m_solver->m_rhoInfinity * (1 / sysEqn().CroccoBusemann(m_Ma, jet)) / m_solver->m_densityRatio;
14377 // set the pressure of the ghost cell equal to that of the boundary cell
14378 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14379 } else if(radius <= m_secondaryJetRadius && m_primaryJetRadius <= radius) {
14380 // cold air jet
14381 //--------------
14382 // inflow mean density profile (Crocco-Buseman relation)
14383 //-----
14384 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity * (1 / sysEqn().CroccoBusemann(m_Ma, jet));
14385 // set the pressure of the ghost cell equal to that of the boundary cell
14386 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14387 }
14388 // else{
14389 // m_solver->a_pvariable( cellId , PV->P ) = m_solver->a_pvariable( nghbrId , PV->P );
14390 // m_solver->a_pvariable( cellId , PV->RHO ) = m_solver->m_rhoInfinity;
14391 // m_solver->a_pvariable( cellId , PV->VV[0] ) = F0;
14392 // m_solver->a_pvariable( cellId , PV->VV[1] ) = F0;
14393 // m_solver->a_pvariable( cellId , PV->VV[2] ) = F0;
14394 //}
14395 }
14396}

◆ bc1251()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1251 ( MInt  bcId)

TODO

Definition at line 4655 of file fvcartesianbndrycndxd.cpp.

4655 {
4656 TRACE();
4657
4659 Context::getSolverProperty<MFloat>("bc1251ForcingAmplitude", m_solverId, AT_, &m_bc1251ForcingAmplitude);
4661 Context::getSolverProperty<MFloat>("bc1251ForcingWavelength", m_solverId, AT_, &m_bc1251ForcingWavelength);
4663 Context::getSolverProperty<MInt>("bc1251ForcingDirection", m_solverId, AT_, &m_bc1251ForcingDirection);
4664
4665 const MFloat inletSoundSpeed = sysEqn().speedOfSound(m_solver->m_rhoInfinity, m_solver->m_PInfinity);
4667
4668 MInt cellId, nghbrId, d = 0;
4669 const MFloat time = m_solver->m_time;
4670
4671 switch(m_cutOffBndryCndIds[bcId]) {
4672 case 1251:
4673 d = 0;
4674 break;
4675 case 1261:
4676 d = 1;
4677 break;
4678 case 1271:
4679 d = 2;
4680 break;
4681 case 1281:
4682 d = 3;
4683 break;
4684 default: {
4685 stringstream errorMessage;
4686 errorMessage << "ERROR: switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
4687 << " not matching any case." << endl;
4688 mTerm(1, AT_, errorMessage.str());
4689 }
4690 }
4691
4692 const MInt mainVelocityDirection = (d == 0 || d == 1) ? 0 : 1;
4693 const MInt secondaryVelocityDirection = (d == 0 || d == 1) ? 1 : 0;
4694
4695 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
4696 cellId = m_sortedCutOffCells[bcId]->a[id];
4697 nghbrId = m_solver->c_neighborId(cellId, d);
4698
4699 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
4700
4701 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
4702
4703 m_solver->a_pvariable(cellId, PV->VV[mainVelocityDirection]) =
4704 (F1 + m_bc1251ForcingAmplitude * sin(2.0 * PI * m_bc1251ForcingFrequency * time))
4705 * m_solver->m_VVInfinity[mainVelocityDirection];
4706
4707 m_solver->a_pvariable(cellId, PV->VV[secondaryVelocityDirection]) = 0;
4708
4709 IF_CONSTEXPR(isDetChem<SysEqn>) {
4710 for(MInt s = 0; s < m_noSpecies; s++) {
4711 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->m_YInfinity[s];
4712 }
4713 }
4714 }
4715}
MFloat m_bc1251ForcingWavelength

◆ bc1401()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1401 ( MInt  )
inlinevirtual

Definition at line 259 of file fvcartesianbndrycndxd.h.

259{};

◆ bc1601()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1601 ( MInt  bcId)

Random-eddy inflow boundary condition.
Set of variables: Standard CV
Eddies are generated according to Batten et al., AIAA J. 42(3), 485-492 (2004)
and inserted in +x direction

3D version

Author
Rudie Kunnen
Date
Feb. 2010

Definition at line 14410 of file fvcartesianbndrycndxd.cpp.

14410 {
14411 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1601 is untested for 2D!"); }
14412 TRACE();
14413
14414 if(m_sortedCutOffCells[bcId]->size() == 0) {
14415 return;
14416 }
14417
14418 MFloat dummyTime;
14419 MFloat that;
14420 MFloat twopioverlb;
14421
14422 MInt cellId;
14423 MInt nghbrId;
14424 MFloat xhat;
14425 MFloat yhat;
14426 MFloat zhat;
14427 MFloat spongeCorrection;
14428 MFloat fluctChol[3];
14429
14430 dummyTime = m_solver->m_time / m_bc1601->m_tau_b;
14431
14432 m_bc1601->checkRegeneration(dummyTime);
14433
14434 that = 2.0 * PI * dummyTime;
14435 twopioverlb = 2.0 * PI / m_bc1601->m_l_b;
14436
14437 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
14438 cellId = m_sortedCutOffCells[bcId]->a[id];
14439 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
14440 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
14441
14442 nghbrId = m_solver->c_neighborId(cellId, 1); // neighbor in +x dir.
14443
14444 xhat = twopioverlb * m_solver->a_coordinate(cellId, 0);
14445 yhat = twopioverlb * m_solver->a_coordinate(cellId, 1);
14446 zhat = twopioverlb * m_solver->a_coordinate(cellId, 2);
14447
14448 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
14449
14450 // correction factor for the sponge layer
14451 // so that fluctuations are reduced toward the edges in the sponge layer
14452 spongeCorrection = 1.0;
14453 if(m_solver->m_noSpongeFactors > 0) {
14454 spongeCorrection = 1.0 - m_solver->a_spongeFactor(cellId) * m_bc1601->m_invSigmaSponge;
14455 }
14456
14457 m_solver->a_pvariable(cellId, PV->VV[0]) = m_solver->m_UInfinity + fluctChol[0] * spongeCorrection;
14458 m_solver->a_pvariable(cellId, PV->VV[1]) = m_solver->m_VInfinity + fluctChol[1] * spongeCorrection;
14459 m_solver->a_pvariable(cellId, PV->VV[2]) = m_solver->m_WInfinity + fluctChol[2] * spongeCorrection;
14460
14461 // set the density
14462 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
14463
14464 // extrapolate the pressure (dp/dn = 0)
14465 if(m_solver->checkNeighborActive(cellId, 1)) {
14466 nghbrId = m_solver->c_neighborId(cellId, 1);
14467 if(nghbrId < 0) {
14468 cutOffBcMissingNeighbor(cellId, "bc1601");
14469 } else {
14470 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14471 }
14472 } else {
14473 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
14474 }
14475
14476 // species
14477 for(MInt s = 0; s < m_noSpecies; s++) {
14478 m_solver->a_pvariable(cellId, PV->Y[s]) = 1.0;
14479 }
14480 }
14481}
Bc1601Class< nDim > * m_bc1601
void cutOffBcMissingNeighbor(const MInt cellId, const MString bcName)
MFloat & a_spongeFactor(const MInt cellId)
Returns the spongeFactor of the cell cellId.
MBool checkNeighborActive(const MInt cellId, const MInt dir) const
Cecks wether the cell cellId has a valid neighbor in direction dir.

◆ bc16010()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc16010 ( MInt  bcId)

Definition at line 16249 of file fvcartesianbndrycndxd.cpp.

16249 {
16250 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc16010 is untested for 2D!"); }
16251 TRACE();
16252
16253 if(m_sortedCutOffCells[bcId]->size() == 0) {
16254 return;
16255 }
16256
16257 const MInt d = 0; // -x direction
16258 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16259 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16260
16261 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
16262 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
16263
16264 if(m_solver->checkNeighborActive(cellId, d)) {
16265 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
16266 if(nghbrId < 0) {
16267 cutOffBcMissingNeighbor(cellId, "bc16010");
16268 } else {
16269 // set the velocities
16270 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
16271 m_solver->a_pvariable(cellId, PV->V) = m_solver->a_pvariable(nghbrId, PV->V);
16272 m_solver->a_pvariable(cellId, PV->W) = m_solver->a_pvariable(nghbrId, PV->W);
16273 // set the density
16274 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
16275 // set the pressure
16276 m_solver->a_pvariable(cellId, PV->P) = F2 * m_solver->m_PInfinity - m_solver->a_pvariable(nghbrId, PV->P);
16277
16278 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
16279 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
16280 m_solver->a_pvariable(cellId, PV->NN[r]) = m_solver->a_pvariable(nghbrId, PV->NN[r]);
16281 }
16282 }
16283 }
16284 } else {
16285 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_UInfinity;
16286 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_VInfinity;
16287 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_WInfinity;
16288 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
16289 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
16290 }
16291
16292 // species
16293 for(MInt s = 0; s < m_noSpecies; s++) {
16294 m_solver->a_pvariable(cellId, PV->Y[s]) = F0;
16295 }
16296 }
16297}

◆ bc16011()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc16011 ( MInt  bcId)

TODO

Definition at line 16305 of file fvcartesianbndrycndxd.cpp.

16305 {
16306 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc16011 is untested for 2D!"); }
16307 TRACE();
16308
16309 if(m_sortedCutOffCells[bcId]->size() == 0) {
16310 return;
16311 }
16312
16313 const MInt d = 1;
16314 // loop over all concerning cells
16315 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16316 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16317
16318 // set the velocities
16319 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_UInfinity;
16320 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_VInfinity;
16321 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_WInfinity;
16322 // set the density
16323 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
16324
16325 if(m_solver->checkNeighborActive(cellId, d)) {
16326 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
16327 if(nghbrId < 0) {
16328 cutOffBcMissingNeighbor(cellId, "bc16011");
16329 } else {
16330 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
16331 }
16332 } else {
16333 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
16334 }
16335
16336 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
16337 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_SA_DV || SysEqn::m_ransModel == RANS_FS) {
16339 }
16340 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_KOMEGA || SysEqn::m_ransModel == RANS_SST) {
16341 m_solver->a_pvariable(cellId, PV->K) = m_solver->m_kInfinity;
16342 m_solver->a_pvariable(cellId, PV->OMEGA) = m_solver->m_omegaInfinity;
16343 }
16344 }
16345
16346 // set the species
16347 for(MInt s = 0; s < m_noSpecies; s++)
16348 m_solver->a_pvariable(cellId, PV->Y[s]) = 1.0;
16349 }
16350}

◆ bc16012()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc16012 ( MInt  bcId)

Slip-wall Navier-Stokes boundary condition.

Definition at line 16358 of file fvcartesianbndrycndxd.cpp.

16358 {
16359 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc16012 is untested for 2D!"); }
16360 TRACE();
16361
16362 const MInt d = 3;
16363 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16364 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16365 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
16366 if(nghbrId < 0) {
16367 cutOffBcMissingNeighbor(cellId, "bc16012");
16368 } else {
16369 // set the velocities
16370 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
16371 m_solver->a_pvariable(cellId, PV->V) = -m_solver->a_pvariable(nghbrId, PV->V);
16372 m_solver->a_pvariable(cellId, PV->W) = m_solver->a_pvariable(nghbrId, PV->W);
16373 // set the density
16374 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
16375 // set the density
16376 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
16377 // set the species
16378 for(MInt s = 0; s < m_noSpecies; s++)
16379 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
16380 }
16381 }
16382}

◆ bc16013()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc16013 ( MInt  bcId)

TODO

Definition at line 16390 of file fvcartesianbndrycndxd.cpp.

16390 {
16391 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc16013 is untested for 2D!"); }
16392 TRACE();
16393
16394 const MInt d = 2;
16395 // loop over all concerning cells
16396 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16397 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16398 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
16399 if(nghbrId < 0) {
16400 cutOffBcMissingNeighbor(cellId, "bc16013");
16401 } else {
16402 // set the velocities
16403 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
16404 m_solver->a_pvariable(cellId, PV->V) = -m_solver->a_pvariable(nghbrId, PV->V);
16405 m_solver->a_pvariable(cellId, PV->W) = m_solver->a_pvariable(nghbrId, PV->W);
16406 // set the density
16407 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
16408 // set the density
16409 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
16410 // set the species
16411 for(MInt s = 0; s < m_noSpecies; s++)
16412 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
16413 }
16414 }
16415}

◆ bc16014()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc16014 ( MInt  bcId)

TODO

Definition at line 16423 of file fvcartesianbndrycndxd.cpp.

16423 {
16424 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc16014 is untested for 2D!"); }
16425 TRACE();
16426
16427 const MInt d = 5;
16428 // loop over all concerning cells
16429 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16430 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16431 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
16432 if(nghbrId < 0) {
16433 cutOffBcMissingNeighbor(cellId, "bc16014");
16434 } else {
16435 // set the velocities
16436 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
16437 m_solver->a_pvariable(cellId, PV->V) = m_solver->a_pvariable(nghbrId, PV->V);
16438 m_solver->a_pvariable(cellId, PV->W) = -m_solver->a_pvariable(nghbrId, PV->W);
16439 // set the density
16440 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
16441 // set the density
16442 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
16443 // set the species
16444 for(MInt s = 0; s < m_noSpecies; s++)
16445 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
16446 }
16447 }
16448}

◆ bc16015()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc16015 ( MInt  bcId)

TODO

Definition at line 16456 of file fvcartesianbndrycndxd.cpp.

16456 {
16457 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc16015 is untested for 2D!"); }
16458 TRACE();
16459
16460 const MInt d = 4;
16461 // loop over all concerning cells
16462 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16463 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16464 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
16465 if(nghbrId < 0) {
16466 cutOffBcMissingNeighbor(cellId, "bc16015");
16467 } else {
16468 // set the velocities
16469 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
16470 m_solver->a_pvariable(cellId, PV->V) = m_solver->a_pvariable(nghbrId, PV->V);
16471 m_solver->a_pvariable(cellId, PV->W) = -m_solver->a_pvariable(nghbrId, PV->W);
16472 // set the density
16473 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
16474 // set the density
16475 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
16476 // set the species
16477 for(MInt s = 0; s < m_noSpecies; s++)
16478 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
16479 }
16480 }
16481}

◆ bc1602()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1602 ( MInt  bcId)

Random-eddy inflow boundary condition.
Eddies are generated according to Batten et al., AIAA J. 42(3), 485-492 (2004)
and added to the velocity profile

3D version for turbulent slot flame

Author
Stephan Schlimpert
Date
April 2014

Definition at line 14601 of file fvcartesianbndrycndxd.cpp.

14601 {
14602 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1602 is untested for 2D!"); }
14603 TRACE();
14604
14605 MFloat dummyTime;
14606 MFloat that;
14607 MFloat twopioverlb;
14608 MFloat factor1;
14609 MFloat factor2;
14610 MFloat b1;
14611 MFloat b2;
14612 MInt ghost1;
14613 MInt in1;
14614 MFloat xhat;
14615 MFloat yhat;
14616 MFloat zhat;
14617 MFloat fluctChol[3];
14618 MFloat velocity = F0;
14619 MInt d = 3;
14622 MFloat massflux = F0;
14623 MFloat jetInflowArea = F0;
14624
14626 m_log << "computing mass flux " << endl;
14627
14628 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
14629 ghost1 = m_sortedCutOffCells[bcId]->a[id];
14630 if(m_solver->a_isHalo(ghost1)) continue;
14631
14632 MFloat jetArea = POW2(m_solver->c_cellLengthAtCell(ghost1));
14633 factor1 = m_solver->a_coordinate(ghost1, 0);
14634 factor2 = m_solver->a_coordinate(ghost1, 2);
14635
14636 velocity = m_solver->m_Ma
14637 * (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
14638 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
14639 - 1)
14640 * (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
14641 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
14642 - 1);
14643 massflux += m_solver->a_variable(ghost1, PV->RHO) * velocity * jetArea;
14644 jetInflowArea += jetArea;
14645 }
14646 MPI_Allreduce(MPI_IN_PLACE, &massflux, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "massflux");
14647 MPI_Allreduce(MPI_IN_PLACE, &jetInflowArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
14648 "jetInflowArea");
14649
14650
14651 // compute static pressure and density iteratively (see e.g. thesis of Ingolf Hoerschler)
14652 // compute massflux per unit area
14653 massflux /= jetInflowArea;
14657 m_log << "calculated pressure" << m_solver->m_jetPressure << endl;
14658 m_log << "calculated density" << m_solver->m_jetDensity << endl;
14659 m_log << "calculated temperature at inflow " << m_solver->m_jetTemperature << endl;
14660 m_log << "calculated massflux" << massflux << endl;
14661 }
14662 // MFloat FTInfinity = F1/m_solver->m_jetTemperature;
14663
14664 if(m_sortedCutOffCells[bcId]->size() == 0) {
14665 return;
14666 }
14667
14668 dummyTime = m_solver->m_time / m_bc1601->m_tau_b;
14669
14670 m_bc1601->checkRegeneration(dummyTime);
14671
14672 that = 2.0 * PI * dummyTime;
14673 twopioverlb = 2.0 * PI / m_bc1601->m_l_b;
14674
14675 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
14676 ghost1 = m_sortedCutOffCells[bcId]->a[id];
14677 in1 = m_solver->c_neighborId(ghost1, d);
14678
14679 factor1 = m_solver->a_coordinate(ghost1, 0);
14680 factor2 = m_solver->a_coordinate(ghost1, 2);
14681
14682 xhat = twopioverlb * m_solver->a_coordinate(ghost1, 0);
14683 yhat = twopioverlb * m_solver->a_coordinate(ghost1, 1);
14684 zhat = twopioverlb * m_solver->a_coordinate(ghost1, 2);
14685 fluctChol[0] = 0;
14686 fluctChol[1] = 0;
14687 fluctChol[2] = 0;
14688 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
14689
14690 // correction factor for the sponge layer
14691 // so that fluctuations are reduced toward the edges in the sponge layer
14692 /*
14693 spongeCorrection = 1.0;
14694 if (m_solver->m_noSpongeFactors > 0)
14695 spongeCorrection = 1.0 - m_solver->a_spongeFactor(ghost1) * m_bc1601->m_invSigmaSponge;
14696 */
14697
14698 // set variables in the cut-off cell at the desired value
14699 // NOT at the exact interface
14700 /*
14701 velocity = m_solver->m_jetConst[0]*pow(x,20);
14702 velocity +=m_solver->m_jetConst[1]*pow(x,19);
14703 velocity +=m_solver->m_jetConst[2]*pow(x,18);
14704 velocity +=m_solver->m_jetConst[3]*pow(x,17);
14705 velocity +=m_solver->m_jetConst[4]*pow(x,16);
14706 velocity +=m_solver->m_jetConst[5]*pow(x,15);
14707 velocity +=m_solver->m_jetConst[6]*pow(x,14);
14708 velocity +=m_solver->m_jetConst[7]*pow(x,13);
14709 velocity +=m_solver->m_jetConst[8]*pow(x,12);
14710 velocity +=m_solver->m_jetConst[9]*pow(x,11);
14711 velocity +=m_solver->m_jetConst[10]*pow(x,10);
14712 velocity +=m_solver->m_jetConst[11]*pow(x,9);
14713 velocity +=m_solver->m_jetConst[12]*pow(x,8);
14714 velocity +=m_solver->m_jetConst[13]*pow(x,7);
14715 velocity +=m_solver->m_jetConst[14]*pow(x,6);
14716 velocity +=m_solver->m_jetConst[15]*pow(x,5);
14717 velocity +=m_solver->m_jetConst[16]*pow(x,4);
14718 velocity +=m_solver->m_jetConst[17]*pow(x,3);
14719 velocity +=m_solver->m_jetConst[18]*pow(x,2);
14720 velocity +=m_solver->m_jetConst[19]*pow(x,1);
14721 velocity +=m_solver->m_jetConst[20];*/
14722
14723 fluctChol[0] *= (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
14724 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
14725 - 1);
14726 fluctChol[0] *= (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
14727 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
14728 - 1);
14729
14730 fluctChol[2] *= (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
14731 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
14732 - 1);
14733 fluctChol[2] *= (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
14734 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
14735 - 1);
14736
14737 m_solver->a_pvariable(ghost1, PV->U) = F2 * fluctChol[0] - m_solver->a_pvariable(in1, PV->U);
14738 velocity = m_solver->m_Ma;
14739
14740 m_solver->a_pvariable(ghost1, PV->V) = F2 * (velocity + fluctChol[1])
14741 * (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
14742 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
14743 - 1)
14744 * (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
14745 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
14746 - 1)
14747 - m_solver->a_pvariable(in1, PV->V);
14748
14749 m_solver->a_pvariable(ghost1, PV->W) = F2 * fluctChol[2] - m_solver->a_pvariable(in1, PV->W);
14750
14751 // extrapolate the pressure (dp/dn = 0)
14752 // set the pressure
14753 m_solver->a_pvariable(ghost1, PV->P) = m_solver->a_pvariable(in1, PV->P);
14754
14755 // setting density
14756 m_solver->a_pvariable(ghost1, PV->RHO) = F2 * m_solver->m_jetDensity - m_solver->a_pvariable(in1, PV->RHO);
14757
14758 IF_CONSTEXPR(hasPV_C<SysEqn>::value)
14759 if(m_combustion) {
14760 m_solver->a_pvariable(ghost1, PV->C) = F0; //-var[ in1 ][ PV->C ];
14761 }
14762 }
14763}
MPI_Comm mpiComm() const
Return the MPI communicator used by the corresponding solver.
MFloat c_cellLengthAtCell(const MInt cellId) const
Returns the length of the cell for level.
MInt m_restartTimeStep
Definition: solver.h:80
MBool m_restart
Definition: solver.h:97
MFloat m_Ma
the Mach number
Definition: solver.h:71

◆ bc1603()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1603 ( MInt  bcId)

Random-eddy inflow boundary condition.
Eddies are generated according to Batten et al., AIAA J. 42(3), 485-492 (2004)
Mean velocity profile (tangential hyperbolic) is introduced

3D version for turbulent round jet

Author
Onur Cetin
Date
April 2014

Definition at line 14777 of file fvcartesianbndrycndxd.cpp.

14777 {
14778 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1603 is untested for 2D!"); }
14779 TRACE();
14780
14781 if(m_sortedCutOffCells[bcId]->size() == 0) {
14782 return;
14783 }
14784
14785 MFloat that = 0;
14786 MFloat twopioverlb = 0;
14787 MFloat xhat;
14788 MFloat yhat;
14789 MFloat zhat;
14791 const MFloat dummyTime = m_solver->m_time / m_bc1601->m_tau_b;
14792 m_bc1601->checkRegeneration(dummyTime);
14793 that = 2.0 * PI * dummyTime;
14794 twopioverlb = 2.0 * PI / m_bc1601->m_l_b;
14795 }
14796 MFloat fluctChol[3] = {0., 0., 0.};
14797
14798 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
14799 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
14800 const MInt nghbrId = m_solver->c_neighborId(cellId, 1); // neighbor in +x dir.
14801 const MFloat radius = sqrt(POW2(m_solver->a_coordinate(cellId, 1)) + POW2(m_solver->a_coordinate(cellId, 2)));
14802
14803 // if (radius<=m_jetHeight){
14804 if(radius <= F1B2) { // TODO labels:FV
14806 xhat = twopioverlb * m_solver->a_coordinate(cellId, 0);
14807 yhat = twopioverlb * m_solver->a_coordinate(cellId, 1);
14808 zhat = twopioverlb * m_solver->a_coordinate(cellId, 2);
14809 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
14810 }
14811
14812 // TODO labels:FV
14813 m_solver->a_pvariable(cellId, PV->VV[0]) = F1B2 * m_Ma * (1 + tanh((radius) / (0.05))) + fluctChol[0];
14814 m_solver->a_pvariable(cellId, PV->VV[1]) = m_solver->m_VInfinity + fluctChol[1];
14815 m_solver->a_pvariable(cellId, PV->VV[2]) = m_solver->m_WInfinity + fluctChol[2];
14816
14817 MFloat profil;
14818 profil = F1B2 * (1 + tanh((radius) / (0.05)));
14819
14820 /* MFloat profil; */
14821 /* profil = F1B2*m_Ma* (1+tanh((m_jetHeight-radius)/(2*m_momentumThickness))); */
14822 /* // Set velocity profile with or without fluctuations */
14823 /* m_solver->a_pvariable(cellId, PV->VV[0]) = profil*m_Ma + fluctChol[0]; */
14824 /* m_solver->a_pvariable(cellId, PV->VV[1]) = m_solver->m_VInfinity + fluctChol[1]; */
14825 /* m_solver->a_pvariable(cellId, PV->VV[2]) = m_solver->m_WInfinity + fluctChol[2]; */
14826
14827 // set the density Crocco-Buesemann relation
14828 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity * (1 / sysEqn().CroccoBusemann(m_Ma, profil));
14829 // extrapolate the pressure (dp/dn = 0)
14830 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14831 } else {
14832 m_solver->a_pvariable(cellId, PV->VV[0]) = F0;
14833 m_solver->a_pvariable(cellId, PV->VV[1]) = F0;
14834 m_solver->a_pvariable(cellId, PV->VV[2]) = F0;
14835
14836 // set the density without Crocco-Buesemann relation
14837 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
14838 // extrapolate the pressure (dp/dn = 0)
14839 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14840 }
14841 }
14842}

◆ bc1604()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1604 ( MInt  bcId)

Updated version of bc1603 with some fixes/improvements

TODO labels:FV,toenhance unify the two version/fix testcases

Definition at line 14852 of file fvcartesianbndrycndxd.cpp.

14852 {
14853 TRACE();
14854 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1604 is untested for 2D!"); }
14855
14856 if(m_sortedCutOffCells[bcId]->size() == 0) {
14857 return;
14858 }
14859
14860 MFloat that = 0;
14861 MFloat twopioverlb = 0;
14862 MFloat xhat;
14863 MFloat yhat;
14864 MFloat zhat;
14866 const MFloat dummyTime = m_solver->m_time / m_bc1601->m_tau_b;
14867 m_bc1601->checkRegeneration(dummyTime);
14868 that = 2.0 * PI * dummyTime;
14869 twopioverlb = 2.0 * PI / m_bc1601->m_l_b;
14870 }
14871 MFloat fluctChol[3] = {0.0, 0.0, 0.0};
14872
14873 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
14874 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
14875 const MInt nghbrId = m_solver->c_neighborId(cellId, 1); // neighbor in +x dir.
14876 if(nghbrId < 0) {
14877 cutOffBcMissingNeighbor(cellId, "bc1604");
14878 continue;
14879 }
14880
14881 const MFloat radius = sqrt(POW2(m_solver->a_coordinate(cellId, 1)) + POW2(m_solver->a_coordinate(cellId, 2)));
14882
14883 if(radius
14884 <= 1.5 * m_jetHeight) { // Note: was just m_jetHeight but jet profile has still a value of 0.5 at this position
14886 xhat = twopioverlb * m_solver->a_coordinate(cellId, 0);
14887 yhat = twopioverlb * m_solver->a_coordinate(cellId, 1);
14888 zhat = twopioverlb * m_solver->a_coordinate(cellId, 2);
14889 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
14890 }
14891
14892 const MFloat jet = 0.5 * (1.0 + tanh((m_jetHeight - radius) / (2 * m_momentumThickness)));
14893
14894 // Set velocity profile with or without fluctuations
14895 m_solver->a_pvariable(cellId, PV->VV[0]) = jet * m_solver->m_VVInfinity[0] + fluctChol[0];
14896 m_solver->a_pvariable(cellId, PV->VV[1]) = m_solver->m_VVInfinity[1] + fluctChol[1];
14897 m_solver->a_pvariable(cellId, PV->VV[2]) = m_solver->m_VVInfinity[2] + fluctChol[2];
14898
14899 // set the density Crocco-Buesemann relation
14900 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity / sysEqn().CroccoBusemann(m_Ma, jet);
14901 // extrapolate the pressure (dp/dn = 0)
14902 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14903 } else {
14904 m_solver->a_pvariable(cellId, PV->VV[0]) = F0;
14905 m_solver->a_pvariable(cellId, PV->VV[1]) = F0;
14906 m_solver->a_pvariable(cellId, PV->VV[2]) = F0;
14907 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
14908 // extrapolate the pressure (dp/dn = 0)
14909 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14910 }
14911 }
14912}

◆ bc1606()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1606 ( MInt  bcId)

Random-eddy inflow boundary condition for chevron jet.
Eddies are generated according to Batten et al., AIAA J. 42(3), 485-492 (2004)
Mean velocity profile (tangential hyperbolic) is introduced

Author
Vitali Pauz
Date
July 2015

Definition at line 14925 of file fvcartesianbndrycndxd.cpp.

14925 {
14926 TRACE();
14927 IF_CONSTEXPR(nDim == 2) { TERMM(1, "bc1606 not useful in 2D"); }
14928
14929 if(m_sortedCutOffCells[bcId]->size() == 0) {
14930 return;
14931 }
14932
14933 MFloat fluctChol[3];
14934
14935 const MFloat dummyTime = m_solver->m_time / m_bc1601->m_tau_b;
14936 m_bc1601->checkRegeneration(dummyTime);
14937
14938 const MFloat that = 2.0 * PI * dummyTime;
14939 const MFloat twopioverlb = 2.0 * PI / m_bc1601->m_l_b;
14940 const MFloat jetTurbulence = (m_jetInletTurbulence) ? 1.0 : 0.0;
14941 const MFloat inletRadius = m_solver->m_inletRadius;
14942 const MFloat deltaMomentum = m_momentumThickness * inletRadius;
14943
14944 const MFloat densityAmbient = m_solver->m_rhoInfinity;
14945 const MFloat density_i = m_solver->m_nozzleInletRho;
14946
14947 // u(r) / u_i = jet = tanh((R-r)/2delta)
14948 const MFloat u_i = m_solver->m_nozzleInletU;
14949 const MFloat Ma_i = m_solver->m_maNozzleInlet;
14950
14951 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
14952 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
14953 const MInt nghbrId = m_solver->c_neighborId(cellId, 1); // neighbor in +x dir.
14954 if(nghbrId < 0) {
14955 cutOffBcMissingNeighbor(cellId, "bc1606");
14956 continue;
14957 }
14958
14959 const MFloat radius =
14960 sqrt(POW2(m_solver->a_coordinate(cellId, 1) - 0.0) + POW2(m_solver->a_coordinate(cellId, 2) - 0.0));
14961
14962 if(radius <= inletRadius) {
14963 const MFloat xhat = twopioverlb * m_solver->a_coordinate(cellId, 0);
14964 const MFloat yhat = twopioverlb * m_solver->a_coordinate(cellId, 1);
14965 const MFloat zhat = twopioverlb * m_solver->a_coordinate(cellId, 2);
14966
14967 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
14968
14969 // velocity profile, zero at wall
14970 const MFloat jet = tanh((inletRadius - radius) / (2.0 * deltaMomentum));
14971
14972 // Without Crocco-Busemann:
14973 // var[cellId][PV->RHO ]= density_i;
14974
14975 // With Crocco-Busemann:
14976 m_solver->a_pvariable(cellId, PV->RHO) = density_i / sysEqn().CroccoBusemann(Ma_i, jet);
14977 // TODO labels:FV,toenhance scale u/v/w fluctuations near the wall?
14978 m_solver->a_pvariable(cellId, PV->VV[0]) = u_i * jet + fluctChol[0] * jetTurbulence;
14979 m_solver->a_pvariable(cellId, PV->VV[1]) = fluctChol[1] * jetTurbulence;
14980 m_solver->a_pvariable(cellId, PV->VV[2]) = fluctChol[2] * jetTurbulence;
14981
14982 // Extrapolate pressure
14983 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14984 } else {
14985 m_solver->a_pvariable(cellId, PV->VV[0]) = 0.0;
14986 m_solver->a_pvariable(cellId, PV->VV[1]) = 0.0;
14987 m_solver->a_pvariable(cellId, PV->VV[2]) = 0.0;
14988
14989 m_solver->a_pvariable(cellId, PV->RHO) = densityAmbient;
14990
14991 // extrapolate the pressure (dp/dn = 0)
14992 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
14993 }
14994 }
14995}

◆ bc17110()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc17110 ( MInt  bcId)

Linear shear flow, initial condition 466

Definition at line 5713 of file fvcartesianbndrycndxd.cpp.

5713 {
5714 TRACE();
5715
5716 MInt d = 0, cellId, nghbrId;
5717 //---
5718
5719 switch(m_cutOffBndryCndIds[bcId]) {
5720 case 17110:
5721 d = 1;
5722 break;
5723 case 17111:
5724 d = 0;
5725 break;
5726 case 17112:
5727 d = 3;
5728 break;
5729 case 17113:
5730 d = 2;
5731 break;
5732 case 17114:
5733 d = 5;
5734 break;
5735 case 17115:
5736 d = 4;
5737 break;
5738 default: {
5739 stringstream errorMessage;
5740 errorMessage << "ERROR: switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
5741 << " not matching any case." << endl;
5742 mTerm(1, AT_, errorMessage.str());
5743 }
5744 }
5745
5746 MFloat bbox[6] = {F0, F0, F0, F0, F0, F0};
5747 m_solver->m_geometry->getBoundingBox(bbox);
5748 const MFloat deltaY = bbox[1 + nDim] - bbox[1];
5749 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
5750 cellId = m_sortedCutOffCells[bcId]->a[id];
5751 MFloat vel[3] = {F0, F0, F0};
5752 MFloat dy = m_solver->a_coordinate(cellId, 1) / deltaY;
5753 vel[0] = F2 * m_solver->m_UInfinity * dy;
5754 nghbrId = m_solver->c_neighborId(cellId, d);
5755 if((dy > F0 && d == 1) || (dy < F0 && d == 0)) { // inflow
5756 for(MInt i = 0; i < nDim; i++)
5757 m_solver->a_pvariable(cellId, PV->VV[i]) = vel[i];
5758 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
5759 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
5760 } else { // outflow
5761 for(MInt v = 0; v < PV->noVariables; v++)
5762 m_solver->a_pvariable(cellId, v) = m_solver->a_pvariable(nghbrId, v);
5763 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
5764 }
5765 }
5766}
Geometry< nDim > * m_geometry

◆ bc17516()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc17516 ( MInt  bcId)

Characteristic inflow b.c. (top hat velocity profile applied, density, and c are prescribed) forced flame response - wide domain

non reflecting boundaries

Author
Stephan Schlimpert
Date
July 2010

Definition at line 4730 of file fvcartesianbndrycndxd.cpp.

4730 {
4731 TRACE();
4732
4733 MInt forcing = m_solver->m_forcing;
4734 MInt cellId, nghbrId, d = 0; // s=0,dir=-1;
4735 MFloat time = m_solver->m_time;
4738 // MFloat massFlux = F0, density = F0, pressure = F0, velocity = F0, count = 0;
4739 // MFloat maxXCoord = F0, minXCoord = F0, area = F0;
4740 MFloat xPlus, xNegative;
4741 // MFloat integrateFactor = m_solver->m_velocityMagnitudeFactor;
4742 //---
4743 // MFloat vz = F1;
4744 // MFloat yOffsetInject = F0;
4745 // static MInt opposite[6] = {1,0,3,2,5,4};
4746
4747 switch(m_cutOffBndryCndIds[bcId]) {
4748 case 17516:
4749 d = 1; //,vz=F1;//dir=1;s=0;
4750 break;
4751 case 17616:
4752 d = 3; //,vz=F1;//dir=0;s=1;
4753 break;
4754 case 17716:
4755 d = 5; //,vz=F1;//dir=2;s=2;
4756 break;
4757 case 17816:
4758 d = 0; //,vz=-F1;//dir=1;s=0;
4759 break;
4760 default: {
4761 stringstream errorMessage;
4762 errorMessage << "ERROR: switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
4763 << " not matching any case." << endl;
4764 mTerm(1, AT_, errorMessage.str());
4765 }
4766 }
4767
4768 if(!forcing) {
4769 // loop over all concerning cells
4770 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
4771 cellId = m_sortedCutOffCells[bcId]->a[id];
4772 nghbrId = m_solver->c_neighborId(cellId, d);
4773
4774 // compute the pressure gradient with internal cells
4775 // slope = m_solver->a_pvariable( nghbrId2 , PV->P ) - m_solver->a_pvariable( nghbrId ,
4776 // PV->P ) ;
4777
4778 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P); // + slope;
4779
4780 // compute the density from inside of the domain using the pressure
4781 m_solver->a_pvariable(cellId, PV->RHO) =
4782 sysEqn().density_ES(m_solver->a_pvariable(cellId, PV->P), m_solver->m_TInfinity);
4783
4784 /*
4785 // set the velocities
4786 for( MInt i=0; i<nDim; i++ ){
4787 xPlus = m_solver->a_coordinate( cellId , opposite[i]) + radius + yOffsetInject;
4788 xNegative = m_solver->a_coordinate( cellId , opposite[i]) - radius + yOffsetInject;
4789 m_solver->a_pvariable( cellId , PV->VV[i] ) =
4790 vz*m_solver->m_VVInfinity[i]*(F1B2*(F1+tanh(xPlus*m_shearLayerStrength))*(F1-tanh(xNegative*m_shearLayerStrength))-F1);
4791 }
4792 */
4793
4794 // set the velocities
4795 m_solver->a_pvariable(cellId, PV->VV[0]) = 0;
4796
4797 xPlus = m_solver->a_coordinate(cellId, 0) + m_radiusVelFlameTube;
4798 xNegative = m_solver->a_coordinate(cellId, 0) - m_radiusVelFlameTube;
4799
4800 m_solver->a_pvariable(cellId, PV->VV[1]) =
4802 * (F1B2 * (F1 + tanh(xPlus * m_shearLayerStrength)) * (F1 - tanh(xNegative * m_shearLayerStrength)) - F1);
4803 // m_solver->a_pvariable( cellId , PV->VV[1] ) = m_solver->m_VInfinity*(tanh(5.0)-F1B2*tanh(5.0) +
4804 // F1B2*tanh((neg2*xNegative - 0.05)*5.0/0.05))*(tanh(5.0)-F1B2*tanh(5.0) + F1B2*tanh((F2*xPlus -
4805 // 0.05)*5.0/0.05));
4806
4807 // m_solver->a_pvariable( cellId , PV->VV[1] ) =
4808 // F1B4*(1+tanh(xPlus*100.0))*(1-tanh(xNegative*100.0))*m_solver->m_VInfinity;//*integrateFactor;
4809
4810 // set the progress variable
4811 IF_CONSTEXPR(hasPV_C<SysEqn>::value) m_solver->a_pvariable(cellId, PV->C) = F0;
4812 /*
4813 if(!m_solver->a_isHalo( nghbrId ))
4814 if(m_solver->m_massFlux || m_solver->m_plenumWall) {
4815
4816 // mass flux
4817 massFlux += m_solver->a_pvariable( nghbrId , PV->VV[1] ) * m_solver->a_pvariable( nghbrId , PV->RHO
4818 );
4819
4820 // velocity
4821 velocity+= m_solver->a_pvariable( nghbrId , PV->VV[1] );
4822
4823 // pressure
4824 pressure += m_solver->a_pvariable( nghbrId , PV->P );
4825
4826 // density
4827 density += m_solver->a_pvariable( nghbrId , PV->RHO );
4828
4829 count++;
4830
4831 }
4832 */
4833 }
4834 } else {
4835 // loop over all concerning cells
4836 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
4837 cellId = m_sortedCutOffCells[bcId]->a[id];
4838 nghbrId = m_solver->c_neighborId(cellId, d);
4839
4840 // compute the pressure gradient with internal cells
4841 // slope = m_solver->a_pvariable( nghbrId2 , PV->P ) - m_solver->a_pvariable( nghbrId , PV->P
4842 // ) ;
4843
4844 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P); // + slope;
4845
4846 // compute the density from inside of the domain using the pressure
4847 m_solver->a_pvariable(cellId, PV->RHO) =
4848 sysEqn().density_ES(m_solver->a_pvariable(cellId, PV->P), m_solver->m_TInfinity);
4849
4850 // set the velocities
4851 m_solver->a_pvariable(cellId, PV->VV[0]) = 0;
4852
4853 xPlus = m_solver->a_coordinate(cellId, 0) + m_radiusVelFlameTube;
4854 xNegative = m_solver->a_coordinate(cellId, 0) - m_radiusVelFlameTube;
4855
4856 m_solver->a_pvariable(cellId, PV->VV[1]) =
4858 * (F1B2 * (F1 + tanh(xPlus * m_shearLayerStrength)) * (F1 - tanh(xNegative * m_shearLayerStrength)) - F1);
4859 m_solver->a_pvariable(cellId, PV->VV[1]) *= (F1 + ampl * sin(St * time));
4860
4861 // m_solver->a_pvariable( cellId , PV->VV[1] ) = m_solver->m_VInfinity*(tanh(5.0)-F1B2*tanh(5.0) +
4862 // F1B2*tanh((neg2*xNegative - 0.05)*5.0/0.05))*(tanh(5.0)-F1B2*tanh(5.0) + F1B2*tanh((F2*xPlus -
4863 // 0.05)*5.0/0.05)); m_solver->a_pvariable( cellId , PV->VV[1] ) =
4864 // F1B4*(1+tanh(xPlus*100.0))*(1-tanh(xNegative*100.0))*m_solver->m_VInfinity*( F1 + ampl * sin( St * time
4865 // ));//* integrateFactor ;
4866
4867 // set the progress variable
4868 IF_CONSTEXPR(hasPV_C<SysEqn>::value) m_solver->a_pvariable(cellId, PV->C) = F0;
4869 /*
4870 if(!m_solver->a_isHalo( nghbrId ))
4871 if(m_solver->m_massFlux || m_solver->m_plenumWall) {
4872
4873 // mass flux
4874 massFlux += m_solver->a_pvariable( nghbrId , PV->VV[1] ) * m_solver->a_pvariable( nghbrId , PV->RHO
4875 );
4876
4877 // velocity
4878 velocity+= m_solver->a_pvariable( nghbrId , PV->VV[1] );
4879
4880 // pressure
4881 pressure += m_solver->a_pvariable( nghbrId , PV->P );
4882
4883 // density
4884 density += m_solver->a_pvariable( nghbrId , PV->RHO );
4885
4886 count++;
4887
4888 // calculate maximum y coordinate
4889 maxXCoord = mMax(maxXCoord,m_solver->a_coordinate( cellId , 0));
4890
4891 // calculate minimum y coordinate
4892 minXCoord = mMin(minXCoord,m_solver->a_coordinate( cellId , 0));
4893 }
4894 */
4895 }
4896 }
4897 /*
4898 if((m_solver->m_massFlux || m_solver->m_plenumWall) && m_solver->m_RKStep == (m_solver->m_noRKSteps-1)) {
4899 density = density/count;
4900 pressure = pressure/count;
4901 velocity = velocity/count;
4902 massFlux = massFlux/count;
4903 area = abs(maxXCoord) + abs(minXCoord) + m_solver->c_cellLengthAtLevel(m_solver->maxRefinementLevel());
4904 massFlux *= area;
4905
4906 // cerr << area << endl;
4907
4908 FILE* datei;
4909 datei = fopen("massFluxInflow", "a+");
4910 fprintf(datei, " %d", globalTimeStep);
4911 fprintf(datei, " %f", m_solver->m_time);
4912 fprintf(datei, " %-10.10f", massFlux );
4913 fprintf(datei, " %-10.10f", velocity );
4914 fprintf(datei, " %-10.10f", density );
4915 fprintf(datei, " %-10.10f", pressure );
4916 fprintf(datei, "\n");
4917 fclose(datei);
4918 }
4919 */
4920}

◆ bc1753()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1753 ( MInt  bcId)

Subsonic outflow boundary condition (applied directly to the (boundary) cell)
Set of variables: Standard PV + progress variable

nD version

Author
Stephan Schlimpert
Date
Dezember 2010

< outflow b.c - x- direction

< outflow b.c + x- direction

< outflow b.c - y- direction

< outflow b.c + y- direction

< outflow b.c - z- direction

< outflow b.c + z- direction

Definition at line 5007 of file fvcartesianbndrycndxd.cpp.

5007 {
5008 TRACE();
5009
5010 MInt forcing = m_solver->m_forcing;
5011 MInt cellId, nghbrId, d = 0;
5012 MFloat massFlux = F0, density = F0, pressure = F0, velocity = F0, count = 0;
5013 MFloat maxXCoord = F0, minXCoord = F0, area = F0;
5014 MFloat refPressure = m_solver->m_PInfinity;
5015 if(m_solver->m_combustion) {
5016 refPressure = m_solver->m_pressureFlameTube;
5017 }
5018 // --- end of initialization
5019
5020 switch(m_cutOffBndryCndIds[bcId]) {
5021 case 17530:
5022 d = 1;
5023 break;
5024 case 17531:
5025 d = 0;
5026 break;
5027 case 17532:
5028 d = 3;
5029 break;
5030 case 17533:
5031 d = 2;
5032 break;
5033 case 17534:
5034 d = 5;
5035 break;
5036 case 17535:
5037 d = 4;
5038 break;
5039 case 1743:
5040 d = 0;
5041 break;
5042 case 1753:
5043 d = 1;
5044 break;
5045 case 1763:
5046 d = 2;
5047 break;
5048 case 1773:
5049 d = 4;
5050 break;
5051 default: {
5052 stringstream errorMessage;
5053 errorMessage << "ERROR: switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
5054 << " not matching any case." << endl;
5055 mTerm(1, AT_, errorMessage.str());
5056 }
5057 }
5058
5059 if(!forcing) {
5060 // loop over all concerning cells
5061 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
5062 cellId = m_sortedCutOffCells[bcId]->a[id];
5063 nghbrId = m_solver->c_neighborId(cellId, d);
5064
5065 // zero-gradient density
5066 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
5067
5068 // zero-gradient velocity
5069 for(MInt i = 0; i < nDim; i++)
5070 m_solver->a_pvariable(cellId, PV->VV[i]) = m_solver->a_pvariable(nghbrId, PV->VV[i]);
5071
5072 // set the pressure
5073 m_solver->a_pvariable(cellId, PV->P) = F2 * refPressure - m_solver->a_pvariable(nghbrId, PV->P);
5074
5075 // zero-gradient progress variable
5076 for(MInt s = 0; s < m_noSpecies; s++)
5077 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
5078
5079 if(!m_solver->a_isHalo(nghbrId))
5080 if(m_solver->m_combustion) {
5082 // mass flux
5083 massFlux += m_solver->a_pvariable(nghbrId, PV->VV[1]) * m_solver->a_pvariable(nghbrId, PV->RHO);
5084
5085 // velocity
5086 velocity += m_solver->a_pvariable(nghbrId, PV->VV[1]);
5087
5088 // pressure
5089 pressure += m_solver->a_pvariable(nghbrId, PV->P);
5090
5091 // density
5092 density += m_solver->a_pvariable(nghbrId, PV->RHO);
5093
5094 count++;
5095
5096 // calculate maximum y coordinate
5097 maxXCoord = mMax(maxXCoord, m_solver->a_coordinate(cellId, 0));
5098
5099 // calculate minimum y coordinate
5100 minXCoord = mMin(minXCoord, m_solver->a_coordinate(cellId, 0));
5101 }
5102 }
5103 }
5104 } else {
5105 // MFloat factorSurface = 0.5686867;
5106 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
5107 cellId = m_sortedCutOffCells[bcId]->a[id];
5108 nghbrId = m_solver->c_neighborId(cellId, d);
5109
5110 // zero-gradient density
5111 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
5112
5113 // zero-gradient velocity
5114 for(MInt i = 0; i < nDim; i++)
5115 m_solver->a_pvariable(cellId, PV->VV[i]) = m_solver->a_pvariable(nghbrId, PV->VV[i]);
5116
5117 // TOutlet = 1.0 / ( 1.0 + 0.5 * gammaMinusOne *
5118 // POW2(m_Ma*factorSurface*m_solver->m_rhoInfinity/m_solver->a_pvariable(nghbrId, PV->RHO)*( F1 + ampl *
5119 // sin( St * time ))));
5120
5121 // POutlet = sysEqn().pressure_IR(TOutlet);
5122
5123 m_solver->a_pvariable(cellId, PV->P) = F2 * refPressure - m_solver->a_pvariable(nghbrId, PV->P);
5124
5125 // zero-gradient progress variable
5126 for(MInt i = 0; i < m_noSpecies; i++)
5127 m_solver->a_pvariable(cellId, PV->Y[i]) = m_solver->a_pvariable(nghbrId, PV->Y[i]);
5128
5129 if(!m_solver->a_isHalo(nghbrId))
5130 if(m_solver->m_combustion) {
5132 // mass flux
5133 massFlux += m_solver->a_pvariable(nghbrId, PV->VV[1]) * m_solver->a_pvariable(nghbrId, PV->RHO);
5134
5135 // velocity
5136 velocity += m_solver->a_pvariable(nghbrId, PV->VV[1]);
5137
5138 // pressure
5139 pressure += m_solver->a_pvariable(nghbrId, PV->P);
5140
5141 // density
5142 density += m_solver->a_pvariable(nghbrId, PV->RHO);
5143
5144 count++;
5145
5146 // calculate maximum y coordinate
5147 maxXCoord = mMax(maxXCoord, m_solver->a_coordinate(cellId, 0));
5148
5149 // calculate minimum y coordinate
5150 minXCoord = mMin(minXCoord, m_solver->a_coordinate(cellId, 0));
5151 }
5152 }
5153 }
5154 }
5155 if(m_solver->m_combustion) {
5157 if(noDomains() > 1) mTerm(1, AT_, "parallize mass flux computation in bc1753");
5158 density = density / count;
5159 pressure = pressure / count;
5160 velocity = velocity / count;
5161 massFlux = massFlux / count;
5162 area = abs(maxXCoord) + abs(minXCoord) + m_solver->c_cellLengthAtLevel(m_solver->maxRefinementLevel());
5163 massFlux *= area;
5164
5165 // cerr << area << endl;
5166
5167 FILE* datei;
5168 datei = fopen("massFluxOutflow", "a+");
5169 fprintf(datei, " %d", globalTimeStep);
5170 fprintf(datei, " %f", m_solver->m_time);
5171 fprintf(datei, " %-10.10f", massFlux);
5172 fprintf(datei, " %-10.10f", velocity);
5173 fprintf(datei, " %-10.10f", density);
5174 fprintf(datei, " %-10.10f", pressure);
5175 fprintf(datei, "\n");
5176 fclose(datei);
5177 }
5178 }
5179}
MFloat c_cellLengthAtLevel(const MInt level) const
Returns the length of the cell for level.
constexpr T mMin(const T &x, const T &y)
Definition: functions.h:90
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94

◆ bc1755()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1755 ( MInt  bcId)

Subsonic outflow boundary condition (applied directly to the (boundary) cell)
Set of variables: Standard PV + progress variable

nD version

Author
Stephan Schlimpert
Date
19.10.2011

Definition at line 5194 of file fvcartesianbndrycndxd.cpp.

5194 {
5195 TRACE();
5196
5197 MInt cellId = -1, nghbrId = -1, d = 0;
5198 MFloat pressure = m_solver->m_PInfinity;
5199 if(m_solver->m_jet) pressure = m_solver->m_jetPressure;
5200
5201 // --- end of initialization
5202
5203 switch(m_cutOffBndryCndIds[bcId]) {
5204 case 1745:
5205 d = 1;
5206 break;
5207 case 1755:
5208 d = 0;
5209 break;
5210 case 1765:
5211 d = 2;
5212 break;
5213 case 1775:
5214 d = 4;
5215 break;
5216 default: {
5217 stringstream errorMessage;
5218 errorMessage << "ERROR: switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
5219 << " not matching any case." << endl;
5220 mTerm(1, AT_, errorMessage.str());
5221 }
5222 }
5223
5224 // loop over all concerning cells
5225 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
5226 cellId = m_sortedCutOffCells[bcId]->a[id];
5227 nghbrId = m_solver->c_neighborId(cellId, d);
5228
5229 // zero-gradient density
5230 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
5231
5232 // zero-gradient velocity
5233 for(MInt i = 0; i < nDim; i++)
5234 m_solver->a_pvariable(cellId, PV->VV[i]) = m_solver->a_pvariable(nghbrId, PV->VV[i]);
5235
5236 // zero gradient pressure
5237 m_solver->a_pvariable(cellId, PV->P) = F2 * pressure - m_solver->a_pvariable(nghbrId, PV->P);
5238
5239 // zero-gradient progress variable
5240 for(MInt s = 0; s < m_noSpecies; s++) {
5241 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
5242 }
5243 }
5244}

◆ bc1791()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1791 ( MInt  )
inlinevirtual

Definition at line 260 of file fvcartesianbndrycndxd.h.

260{};

◆ bc1792()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1792 ( MInt  bcId)

Subsonic inflow in a rotating frame of reference

Author
Alexej Pogorelov

Definition at line 15005 of file fvcartesianbndrycndxd.cpp.

15005 {
15006 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1792 is untested for 2D!"); }
15007 TRACE();
15008
15009 MFloat radius_1;
15010 MFloat phi_1;
15011 MInt cellId;
15012 MInt d;
15013 MInt nghbrId;
15014
15015 d = 1;
15016
15017 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
15018 cellId = m_sortedCutOffCells[bcId]->a[id];
15019
15020
15021 nghbrId = m_solver->c_neighborId(cellId, d);
15022
15023 radius_1 = sqrt((m_solver->a_coordinate(cellId, 1) - 200.0) * (m_solver->a_coordinate(cellId, 1) - 200.0)
15024 + (m_solver->a_coordinate(cellId, 2) - 200.0) * (m_solver->a_coordinate(cellId, 2) - 200.0));
15025 if((m_solver->a_coordinate(cellId, 1) - 200.0) >= 0 && (m_solver->a_coordinate(cellId, 2) - 200.0) >= 0) {
15026 phi_1 = asin((m_solver->a_coordinate(cellId, 1) - 200.0) / radius_1);
15027 } else if((m_solver->a_coordinate(cellId, 1) - 200.0) >= 0 && (m_solver->a_coordinate(cellId, 2) - 200.0) < 0) {
15028 phi_1 = PI - asin((m_solver->a_coordinate(cellId, 1) - 200.0) / radius_1);
15029 } else if((m_solver->a_coordinate(cellId, 1) - 200.0) < 0 && (m_solver->a_coordinate(cellId, 2) - 200.0) < 0) {
15030 phi_1 = PI - asin((m_solver->a_coordinate(cellId, 1) - 200.0) / radius_1);
15031 } else {
15032 phi_1 = 2 * PI + asin((m_solver->a_coordinate(cellId, 1) - 200.0) / radius_1);
15033 }
15034
15035
15036 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_UInfinity;
15037 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_VInfinity * cos(phi_1) / 29.0 * radius_1;
15038 m_solver->a_pvariable(cellId, PV->W) = -m_solver->m_VInfinity * sin(phi_1) / 29.0 * radius_1;
15039
15040 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
15041 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
15042 }
15043}

◆ bc1801()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1801 ( MInt  )
inlinevirtual

Definition at line 254 of file fvcartesianbndrycndxd.h.

254{};

◆ bc1901()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc1901 ( MInt  )
inlinevirtual

Definition at line 253 of file fvcartesianbndrycndxd.h.

253{};

◆ bc19516()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc19516 ( MInt  bcId)

Inflow b.c. (Hyperbolic tangent velocity with shear layer thickness parameter, 3D round jet)
Velocity profile ref: "Effects of Inflow Conditions and Forcing on Subsonic Jet Flows and Noise AIAA 2005" Bogey and Bailly.

Author
Onur Cetin
Date
February 2013

Definition at line 4934 of file fvcartesianbndrycndxd.cpp.

4934 {
4935 TRACE();
4936 MInt cellId, nghbrId, d = 0; // s=0,dir=-1;
4937 MFloat radius, jet; // rnd, fi, psi, Str;
4938 switch(m_cutOffBndryCndIds[bcId]) {
4939 case 19516:
4940 d = 1; // s=0;dir=1;
4941 break;
4942 case 19616:
4943 d = 3; // s=1;dir=0;
4944 break;
4945 case 19716:
4946 d = 5; // s=2;dir=2;
4947 break;
4948 default: {
4949 stringstream errorMessage;
4950 errorMessage << "ERROR: switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
4951 << " not matching any case." << endl;
4952 mTerm(1, AT_, errorMessage.str());
4953 }
4954 }
4955 // if( !forcing) {
4956 // loop over all concerning cells
4957 // loop over all concerning cells
4958 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
4959 cellId = m_sortedCutOffCells[bcId]->a[id];
4960 nghbrId = m_solver->c_neighborId(cellId, d);
4961
4962 // set the temperature
4963 // m_solver->a_pvariable( cellId , PV->T ) = PV->TInfinity;
4964
4965 // compute the radial position
4966 radius = F0;
4967 for(MInt i = 0; i < nDim; i++)
4968 if(i != d / 2) radius += POW2(m_solver->a_coordinate(cellId, i));
4969 radius = sqrt(radius);
4970
4971 // Jet mean velocity profile
4972 jet = F1B2 * (1 + tanh((m_jetHeight - radius) / (2 * m_momentumThickness)));
4973
4974 // Inflow mean density profile (Crocco-Busemann)
4975 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity * (1 / (sysEqn().CroccoBusemann(m_Ma, jet)));
4976 // m_solver->a_pvariable( cellId , PV->RHO ) = m_solver->m_rhoInfinity;
4977 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
4978 // Choose 0.05 for momentum thickness ref: Bogey&Bailly
4979 if(radius <= m_jetHeight) {
4980 // The following line is the original line from Onur which contains an error that was fixed below
4981 // m_solver->a_pvariable(cellId, PV->VV[0]) =F1B2* m_targetVelocityFactor*
4982 // (1+tanh((m_jetHeight-radius)/(2*m_momentumThickness)));
4983 m_solver->a_pvariable(cellId, PV->VV[0]) =
4984 F1B2 * m_solver->m_VVInfinity[0] * (1 + tanh((m_jetHeight - radius) / (2 * m_momentumThickness)));
4985 m_solver->a_pvariable(cellId, PV->VV[1]) = m_solver->m_VVInfinity[1];
4986 m_solver->a_pvariable(cellId, PV->VV[2]) = m_solver->m_VVInfinity[2];
4987 } else {
4988 m_solver->a_pvariable(cellId, PV->VV[0]) = F0;
4989 m_solver->a_pvariable(cellId, PV->VV[1]) = F0;
4990 m_solver->a_pvariable(cellId, PV->VV[2]) = F0;
4991 }
4992 }
4993}

◆ bc1952()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc1952 ( MInt  bcId)

3D version

Author
Daniel Hartmann
Date
November 11, 2006 (3D)

Definition at line 15053 of file fvcartesianbndrycndxd.cpp.

15053 {
15054 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc1952 is untested for 2D!"); }
15055 TRACE();
15056
15057 MInt cellId;
15058 MInt nghbrId;
15059 MInt d = 0;
15060 //---
15061
15062 switch(m_cutOffBndryCndIds[bcId]) {
15063 case 1952:
15064 d = 0;
15065 break;
15066 case 1972:
15067 d = 4;
15068 break;
15069 default: {
15070 stringstream errorMessage;
15071 errorMessage << "ERROR: Switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
15072 << " not matching any case." << endl;
15073 mTerm(1, AT_, errorMessage.str());
15074 }
15075 }
15076
15077 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
15078 cellId = m_sortedCutOffCells[bcId]->a[id];
15079 nghbrId = m_solver->c_neighborId(cellId, d);
15080
15081 // zero-gradient density
15082 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
15083
15084 // zero-gradient velocity
15085 for(MInt i = 0; i < nDim; i++) {
15086 m_solver->a_pvariable(cellId, PV->VV[i]) = m_solver->a_pvariable(nghbrId, PV->VV[i]);
15087 }
15088
15089 // set the pressure
15090 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
15091
15092 // zero-gradient species
15093 for(MInt s = 0; s < m_noSpecies; s++) {
15094 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
15095 }
15096 }
15097}

◆ bc19520()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc19520 ( MInt  )
inlinevirtual

Definition at line 255 of file fvcartesianbndrycndxd.h.

255{};

◆ bc2001()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc2001 ( MInt  )
inlinevirtual

Definition at line 261 of file fvcartesianbndrycndxd.h.

261{};

◆ bc2002()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc2002 ( MInt  )
inlinevirtual

Definition at line 262 of file fvcartesianbndrycndxd.h.

262{};

◆ bc2003()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc2003 ( MInt  )
inlinevirtual

Definition at line 263 of file fvcartesianbndrycndxd.h.

263{};

◆ bc2700()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc2700 ( MInt  bcId)

Supersonic inflow with imposed acoustic or entropy waves

Author
Thomas Schilden
Date
12.2.2015

Definition at line 15108 of file fvcartesianbndrycndxd.cpp.

15108 {
15109 TRACE();
15110
15111#ifdef _OPENMP
15112#pragma omp parallel for
15113#endif
15114 // set mean flow values
15115 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
15116 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
15117 // density
15118 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
15119 // velocities
15120 for(MInt dim = 0; dim < m_solver->nDim; dim++) {
15121 m_solver->a_pvariable(cellId, PV->VV[dim]) = m_solver->m_VVInfinity[dim];
15122 }
15123 // pressure
15124 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
15125 }
15126
15127 // add the modes
15128 if(m_besselModes) {
15129 // time ist constant during the rk steps, we only need to integrate once
15130 if(!m_solver->m_RKStep) {
15132 }
15133 // add the modes using the precomputed bessel fractions
15134 addBesselModes(bcId);
15135 } else {
15136 addModes(bcId);
15137 }
15138}
void addModes(MInt)
supersonic inflow with imposed onlique shock wave version: cut-off boundary condition author: Thomas ...
void precomputeBesselTrigonometry(MInt)

◆ bc2710()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc2710 ( MInt  bcId)

Simple extrapolation of all variables

Author
: Thomas Schilden
Date
10.1.2014

Definition at line 15455 of file fvcartesianbndrycndxd.cpp.

15455 {
15456 TRACE();
15457
15458 MInt direction = m_cutOffBndryCndIds[bcId] - 2710;
15459
15460 if(direction % 2) {
15461 direction--;
15462 } else {
15463 direction++;
15464 }
15465
15466 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
15467 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
15468 if(m_solver->a_hasProperty(cellId, SolverCell::IsPeriodicWithRot)) {
15469 continue;
15470 }
15471 MLong nghbrId = m_solver->c_neighborId(cellId, direction);
15472
15473 if(nghbrId < 0) {
15474 continue;
15475 }
15476 if(m_solver->c_noChildren(nghbrId) > 0) {
15477 MFloat coCoord = m_solver->a_coordinate(cellId, direction / 2);
15478 MInt childCnt = 0;
15479 // reset cut off cell
15480 for(MInt i = 0; i < PV->noVariables; i++) {
15481 m_solver->a_pvariable(cellId, i) = F0;
15482 }
15483 // use parents neighbours childs, but only the close ones, should be four
15484 for(MInt child = 0; child < IPOW2(nDim); child++) {
15485 MLong childId = m_solver->c_childId(nghbrId, child);
15486 if(childId < 0) {
15487 continue;
15488 }
15489 if(abs(m_solver->a_coordinate(childId, direction / 2) - coCoord) > m_solver->c_cellLengthAtCell(cellId)) {
15490 continue;
15491 }
15492 childCnt++;
15493 for(MInt i = 0; i < PV->noVariables; i++) {
15494 m_solver->a_pvariable(cellId, i) += m_solver->a_pvariable(childId, i);
15495 }
15496 }
15497 // divide by number of cells used
15498 for(MInt i = 0; i < PV->noVariables; i++) {
15499 m_solver->a_pvariable(cellId, i) /= (MFloat)childCnt;
15500 }
15501 } else {
15502 for(MInt i = 0; i < PV->noVariables; i++) {
15503 m_solver->a_pvariable(cellId, i) = m_solver->a_pvariable(nghbrId, i);
15504 }
15505 }
15506 }
15507}
MLong c_childId(const MInt cellId, const MInt pos) const
Returns the grid child id of the grid cell cellId at position pos.
constexpr MLong IPOW2(MInt x)
int64_t MLong
Definition: maiatypes.h:64

◆ bc2720()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc2720 ( MInt  bcId)

Simple extrapolation of all variables, postshock pressure is set

Author
Thomas Schilden
Date
10.1.2014

Definition at line 15518 of file fvcartesianbndrycndxd.cpp.

15518 {
15519 TRACE();
15520
15521 MInt direction = m_cutOffBndryCndIds[bcId] - 2720;
15522
15523 if(direction % 2) {
15524 direction--;
15525 } else {
15526 direction++;
15527 }
15528
15529 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
15530 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
15531 if(m_solver->a_hasProperty(cellId, SolverCell::IsPeriodicWithRot)) {
15532 continue;
15533 }
15534 MLong nghbrId = m_solver->c_neighborId(cellId, direction);
15535
15536 if(nghbrId < 0) {
15537 continue;
15538 }
15539 if(m_solver->c_noChildren(nghbrId) > 0) {
15540 MFloat coCoord = m_solver->a_coordinate(cellId, direction / 2);
15541 MInt childCnt = 0;
15542 // reset cut off cell
15543 for(MInt i = 0; i < PV->noVariables; i++) {
15544 m_solver->a_pvariable(cellId, i) = F0;
15545 }
15546 // use parents neighbours childs, but only the close ones, should be four
15547 for(MInt child = 0; child < IPOW2(nDim); child++) {
15548 MLong childId = m_solver->c_childId(nghbrId, child);
15549 if(childId < 0) {
15550 continue;
15551 }
15552 if(abs(m_solver->a_coordinate(childId, direction / 2) - coCoord) > m_solver->c_cellLengthAtCell(cellId)) {
15553 continue;
15554 }
15555 childCnt++;
15556 for(MInt i = 0; i < PV->noVariables; i++) {
15557 m_solver->a_pvariable(cellId, i) += m_solver->a_pvariable(childId, i);
15558 }
15559 }
15560 // divide by number of cells used
15561 for(MInt i = 0; i < PV->noVariables; i++) {
15562 m_solver->a_pvariable(cellId, i) /= (MFloat)childCnt;
15563 }
15564
15565 m_solver->a_pvariable(cellId, PV->P) = F2 * m_solver->m_postShockPV[PV->P] - m_solver->a_pvariable(cellId, PV->P);
15566 } else {
15567 for(MInt i = 0; i < PV->P; i++) {
15568 m_solver->a_pvariable(cellId, i) = m_solver->a_pvariable(nghbrId, i);
15569 }
15570
15571 m_solver->a_pvariable(cellId, PV->P) =
15572 F2 * m_solver->m_postShockPV[PV->P] - m_solver->a_pvariable(nghbrId, PV->P);
15573
15574 for(MInt i = PV->P + 1; i < PV->noVariables; i++) {
15575 m_solver->a_pvariable(cellId, i) = m_solver->a_pvariable(nghbrId, i);
15576 }
15577 }
15578 }
15579}

◆ bc2770()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc2770 ( MInt  )
inlinevirtual

Definition at line 248 of file fvcartesianbndrycndxd.h.

248{};

◆ bc29050()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc29050 ( MInt  bcId)

Slip-wall Navier-Stokes boundary condition.

Definition at line 17815 of file fvcartesianbndrycndxd.cpp.

17815 {
17816 TRACE();
17817
17818 MInt cellId, d;
17819 MLong nghbrId;
17820 //---end of initialization
17821
17822 MInt Dir[nDim];
17823 for(MInt i = 0; i < nDim; i++) {
17824 Dir[i] = 1;
17825 }
17826 switch(m_cutOffBndryCndIds[bcId]) {
17827 case 29050:
17828 d = 1;
17829 Dir[0] = -1;
17830 break;
17831 case 29051:
17832 d = 0;
17833 Dir[0] = -1;
17834 break;
17835 case 29052:
17836 d = 2;
17837 Dir[1] = -1;
17838 break;
17839 case 29053:
17840 d = 3;
17841 Dir[1] = -1;
17842 break;
17843 case 29054:
17844 IF_CONSTEXPR(nDim == 2) mTerm(1, AT_, "bc29054: symmetry in z-direction not possible for 2D");
17845 d = 4;
17846 Dir[2] = -1;
17847 break;
17848 case 29055:
17849 IF_CONSTEXPR(nDim == 2) mTerm(1, AT_, "bc29054: symmetry in z-direction not possible for 2D");
17850 d = 5;
17851 Dir[2] = -1;
17852 break;
17853 default: {
17854 stringstream errorMessage;
17855 errorMessage << "ERROR: Switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
17856 << " not matching any case." << endl;
17857 mTerm(1, AT_, errorMessage.str());
17858 }
17859 }
17860
17861 // loop over all concerning cells
17862 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17863 cellId = m_sortedCutOffCells[bcId]->a[id];
17864 nghbrId = m_solver->c_neighborId(cellId, d);
17865
17866 // set the velocities
17867 m_solver->a_pvariable(cellId, PV->U) = Dir[0] * m_solver->a_pvariable(nghbrId, PV->U);
17868 m_solver->a_pvariable(cellId, PV->V) = Dir[1] * m_solver->a_pvariable(nghbrId, PV->V);
17869 IF_CONSTEXPR(nDim == 3) { m_solver->a_pvariable(cellId, PV->W) = Dir[2] * m_solver->a_pvariable(nghbrId, PV->W); }
17870 // set the density
17871 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
17872
17873 // set the density
17874 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
17875
17876 // set the species
17877 for(MInt i = 0; i < m_noSpecies; i++) {
17878 m_solver->a_pvariable(cellId, PV->Y[i]) = m_solver->a_pvariable(nghbrId, PV->Y[i]);
17879 }
17880 }
17881}

◆ bc2907()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc2907 ( MInt  bcId)

Coflow bc
Set of variables: Standard CV
u=w=0, v= v_coflow; drho/dn=dp/dn=0;

set adiabtic wall

Definition at line 15590 of file fvcartesianbndrycndxd.cpp.

15590 {
15591 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bc2907 is untested for 2D!"); }
15592 TRACE();
15593
15594 MInt cellId;
15595 MInt bndryId;
15596 MInt ghostCellId;
15597 MFloat TInfinity = m_solver->m_TInfinity;
15599
15600 //---end of initialization
15601
15602 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
15603 bndryId = m_sortedBndryCells->a[id];
15604 cellId = m_bndryCells->a[bndryId].m_cellId;
15605 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15606 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
15607
15608 // set the velocities
15609 if(abs(m_solver->a_coordinate(cellId, 0)) >= m_solver->m_jetCoflowOffset
15610 && // jet radius R = 0.5 + 0.125 distance = 0.625to coflow
15612 && // jet radius R = 0.5 + 0.125 distance = 0.625to coflow
15613 abs(m_solver->a_coordinate(cellId, 2)) <= m_solver->m_jetHalfLength) { // half jet length L = 8.33/2
15614
15615 m_solver->a_pvariable(ghostCellId, PV->V) = F2 * m_solver->m_MaCoflow - m_solver->a_pvariable(cellId, PV->V);
15616 m_solver->a_pvariable(ghostCellId, PV->U) = -m_solver->a_pvariable(cellId, PV->U);
15617 m_solver->a_pvariable(ghostCellId, PV->W) = -m_solver->a_pvariable(cellId, PV->W);
15618
15619 // set the pressure
15620 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
15621 // changed to dirichlet bc
15622 // m_solver->a_pvariable( ghostCellId , PV->RHO ) = F2*CV->m_rhoInfinity -
15623 // m_solver->a_pvariable( cellId , PV->RHO );
15624 // compute the density from inside of the domain using the pressure
15625 m_solver->a_pvariable(ghostCellId, PV->RHO) =
15626 sysEqn().density_ES(m_solver->a_pvariable(cellId, PV->P), TInfinity);
15627
15628 // set the species
15629 for(MInt s = 0; s < m_noSpecies; s++) {
15630 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
15631 }
15632
15633 } else {
15634 m_solver->a_pvariable(ghostCellId, PV->V) = -m_solver->a_pvariable(cellId, PV->V);
15635 m_solver->a_pvariable(ghostCellId, PV->U) = -m_solver->a_pvariable(cellId, PV->U);
15636 m_solver->a_pvariable(ghostCellId, PV->W) = -m_solver->a_pvariable(cellId, PV->W);
15637
15639 // set the density
15640 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
15641
15642 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
15643
15644 // set the species
15645 for(MInt s = 0; s < m_noSpecies; s++) {
15646 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
15647 }
15648 }
15649 }
15650 }
15651}

◆ bc3002()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc3002 ( MInt  bcId)

slip adiabatic wall boundary condition
u_n=0; du_t/dn=0; drho/dn=dp/dn=0
dp/dn=0 is only valid for walls without streamwise curvature!

Definition at line 5510 of file fvcartesianbndrycndxd.cpp.

5510 {
5511 TRACE();
5512
5513 const MInt noSpecies = m_noSpecies;
5514
5515#ifdef _OPENMP
5516#pragma omp parallel for
5517#endif
5518 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5519 const MInt bndryId = m_sortedBndryCells->a[id];
5520 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
5521 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5522 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
5523 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
5524 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
5525
5526 MFloat wallNormalVelocity = F0;
5527
5528 for(MInt i = 0; i < nDim; i++)
5529 wallNormalVelocity +=
5530 m_solver->a_pvariable(cellId, PV->VV[i]) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
5531
5532 for(MInt i = 0; i < nDim; i++)
5533 m_solver->a_pvariable(ghostCellId, PV->VV[i]) =
5534 m_solver->a_pvariable(cellId, PV->VV[i])
5535 - F2 * wallNormalVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
5536
5537 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
5538 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
5539
5540 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
5541 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
5542 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = m_solver->a_pvariable(cellId, PV->NN[r]);
5543 }
5544 }
5545
5546 for(MInt s = 0; s < noSpecies; s++)
5547 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
5548 }
5549 }
5550 }
5551 }
5552}

◆ bc30021()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc30021 ( MInt  bcId)

Definition at line 5563 of file fvcartesianbndrycndxd.cpp.

5563 {
5564 TRACE();
5565
5566 const MInt noSpecies = m_noSpecies;
5567
5568#ifdef _OPENMP
5569#pragma omp parallel for
5570#endif
5571 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5572 const MInt bndryId = m_sortedBndryCells->a[id];
5573 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
5574 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5575 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
5576 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
5577 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
5578
5579 MFloat wallNormalVelocity = F0;
5580
5581 for(MInt i = 0; i < nDim; i++)
5582 wallNormalVelocity +=
5583 m_solver->a_pvariable(cellId, PV->VV[i]) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
5584
5585 for(MInt i = 0; i < nDim; i++)
5586 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = m_solver->a_pvariable(cellId, PV->VV[i]);
5587 // - F2 * wallNormalVelocity * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
5588
5589 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
5590 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
5591
5592 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
5593 for(MInt r = 0; r < m_noRansEquations; ++r) {
5594 m_solver->a_pvariable(ghostCellId, PV->N) = m_solver->a_pvariable(cellId, PV->N);
5595 }
5596 }
5597
5598 for(MInt s = 0; s < noSpecies; s++)
5599 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
5600 }
5601 }
5602 }
5603 }
5604}

◆ bc30022()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc30022 ( MInt  bcId)

Zonal interface LES inflow boundary condition (LES->RANS coupling)

Definition at line 17713 of file fvcartesianbndrycndxd.cpp.

17713 {
17714 TRACE();
17715
17716 IF_CONSTEXPR(isEEGas<SysEqn>)
17717 TERMM(1, "bc7809 not working for AIAFvSysEqnEEGas");
17718
17719 if(m_sortedCutOffCells[bcId]->size() == 0) {
17720 return;
17721 }
17722
17723 const MInt d = 2;
17724 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17725 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
17726 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17727 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17728 if(m_solver->checkNeighborActive(cellId, d)) {
17729 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
17730 if(nghbrId < 0) {
17731 cutOffBcMissingNeighbor(cellId, "bc30022");
17732 } else {
17733 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
17734 m_solver->a_pvariable(cellId, PV->V) = m_horTargetData[id][1];
17735 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_WInfinity;
17736 m_solver->a_pvariable(cellId, PV->RHO) = m_horTargetData[id][2];
17737 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
17738 }
17739 } else {
17740 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_UInfinity;
17741 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_VInfinity;
17742 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_WInfinity;
17743 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
17744 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
17745 }
17746 }
17747}

◆ bc3003()

template<MInt nDim, class SysEqn >
template<MBool MGC>
void FvBndryCndXD< nDim, SysEqn >::bc3003 ( MInt  bcId)

no-slip adiabatic wall boundary condition
u=v=w=0; drho/dn=dp/dn=0;

Definition at line 5257 of file fvcartesianbndrycndxd.cpp.

5257 {
5258 TRACE();
5259 const MInt noSpecies = m_noSpecies;
5260
5261#ifdef _OPENMP
5262#pragma omp parallel for
5263#endif
5264 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5265 const MInt bndryId = m_sortedBndryCells->a[id];
5266 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
5267 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5268 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
5269 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
5270 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
5271
5272 for(MInt i = 0; i < nDim; i++) {
5273 if(MGC) {
5274 if(m_surfaceGhostCell) {
5275 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = 0.0;
5276 } else {
5277 m_solver->a_pvariable(ghostCellId, PV->VV[i]) =
5278 -m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->VV[i]];
5279 }
5280 } else {
5281 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = -m_solver->a_pvariable(cellId, PV->VV[i]);
5282 }
5283 }
5284 if(MGC) {
5285 m_solver->a_pvariable(ghostCellId, PV->RHO) =
5286 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->RHO];
5287 m_solver->a_pvariable(ghostCellId, PV->P) =
5288 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->P];
5289 } else {
5290 // simplified Neumann: assuming the line boundary-ghost is normal to the boundary surface)
5291 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
5292 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
5293 }
5294
5295 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
5296 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_SA_DV || SysEqn::m_ransModel == RANS_FS) {
5297 if(MGC) {
5298 if(m_surfaceGhostCell) {
5299 m_solver->a_pvariable(ghostCellId, PV->N) = 0.0;
5300 } else {
5301 m_solver->a_pvariable(ghostCellId, PV->N) =
5302 -m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->N];
5303 }
5304 } else {
5305 m_solver->a_pvariable(ghostCellId, PV->N) = -m_solver->a_pvariable(cellId, PV->N);
5306 }
5307 }
5308 IF_CONSTEXPR(SysEqn::m_ransModel == RANS_KOMEGA || SysEqn::m_ransModel == RANS_SST) {
5309 // k
5310 m_solver->a_pvariable(ghostCellId, PV->K) = -m_solver->a_pvariable(cellId, PV->K);
5311 // omega
5312 const MFloat rRe = F1 / sysEqn().m_Re0;
5313 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
5314 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
5315 const MFloat omega = m_solver->a_pvariable(cellId, PV->OMEGA);
5316 const MFloat T = sysEqn().temperature_ES(rho, p);
5317 const MFloat mue = sysEqn().sutherlandLaw(T);
5318 const MFloat nu = mue / rho;
5319 const MFloat beta1 = RM_KOMEGA::beta0;
5320 MFloat d = sqrt(POW2(m_solver->a_coordinate(cellId, 0) - m_solver->a_coordinate(ghostCellId, 0))
5321 + POW2(m_solver->a_coordinate(cellId, 1) - m_solver->a_coordinate(ghostCellId, 1)));
5322 IF_CONSTEXPR(nDim == 3) {
5323 d = sqrt(POW2(m_solver->a_coordinate(cellId, 0) - m_solver->a_coordinate(ghostCellId, 0))
5324 + POW2(m_solver->a_coordinate(cellId, 1) - m_solver->a_coordinate(ghostCellId, 1))
5325 + POW2(m_solver->a_coordinate(cellId, 2) - m_solver->a_coordinate(ghostCellId, 2)));
5326 }
5327 const MFloat nu_surface = nu - m_solver->a_slope(cellId, PV->N, 1) * d;
5328 const MFloat omega_surface = pow(rRe, 2.0) * 60 * nu_surface / (beta1 * POW2(d));
5329 m_solver->a_pvariable(ghostCellId, PV->OMEGA) = F2 * omega_surface - omega;
5330 }
5331 }
5332
5333 for(MInt s = 0; s < noSpecies; s++) {
5334 if(MGC) {
5335 m_solver->a_pvariable(ghostCellId, PV->Y[s]) =
5336 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->Y[s]];
5337 } else {
5338 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
5339 }
5340 }
5341 }
5342 }
5343 }
5344 }
5345}
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.
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.

◆ bc3006()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc3006 ( MInt  bcId)

Moving wall Navier-Stokes boundary condition.

Author
Lennart Schneiders

Definition at line 15660 of file fvcartesianbndrycndxd.cpp.

15660 {
15661 TRACE();
15662
15663 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
15664 MInt bndryId = m_sortedBndryCells->a[id];
15665 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
15666
15667 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15668 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
15669 MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
15670 if(ghostCellId < 0 && ghostCellId >= m_solver->a_noCells()) {
15671 mTerm(1, AT_, "Ghost cell: " + to_string(ghostCellId));
15672 }
15673 MInt k = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0];
15674 ASSERT(k > -1 && k < m_solver->m_noEmbeddedBodies + m_solver->m_noPeriodicGhostBodies, "");
15676 mTerm(1, AT_, "Invalid body id: " + to_string(k));
15677 }
15678
15679
15680 MFloat vel[3] = {0.0, 0.0, 0.0};
15681 for(MInt i = 0; i < nDim; i++) {
15682 vel[i] = m_solver->m_bodyVelocity[k * nDim + i];
15683 }
15684
15685 MFloat dx[3]{};
15686 MFloat omega[3]{};
15687 MFloat vrad[3]{};
15688 MFloat dn = 0;
15689 for(MInt i = 0; i < nDim; i++) {
15690 dn += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
15691 * (m_solver->a_coordinate(cellId, i) - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i]);
15692 }
15693 for(MInt i = 0; i < nDim; i++) {
15694 dx[i] = m_solver->a_coordinate(cellId, i) - dn * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
15695 - m_solver->m_bodyCenter[k * nDim + i];
15696 }
15697 for(MInt i = 0; i < 3; i++) {
15698 omega[i] = m_solver->m_bodyAngularVelocity[k * 3 + i];
15699 }
15700 vrad[0] = omega[1] * dx[2] - omega[2] * dx[1];
15701 vrad[1] = omega[2] * dx[0] - omega[0] * dx[2];
15702 IF_CONSTEXPR(nDim == 3) vrad[2] = omega[0] * dx[1] - omega[1] * dx[0];
15703
15704 for(MInt i = 0; i < nDim; i++) {
15705 vel[i] += vrad[i];
15706 }
15707
15708 for(MInt i = 0; i < nDim; i++) {
15709 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = F2 * vel[i] - m_solver->a_pvariable(cellId, PV->VV[i]);
15710 }
15711
15712 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
15713 for(MInt r = 0; r < m_solver->m_noRansEquations; r++) {
15714 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = -m_solver->a_pvariable(cellId, PV->NN[r]);
15715 }
15716 }
15717
15718
15719 for(MInt s = 0; s < m_noSpecies; s++) {
15720 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
15721 }
15722 }
15723 }
15724 }
15725
15726 // gap-Cell correction!
15727 if(m_solver->m_closeGaps && !m_solver->m_gapCells.empty()) {
15728 // update of nearGap-Cells with secondBody-Id!
15730 }
15731}
void setGapGhostCellVariables(MInt bcId)
update ghostCell variables for gap-Cells
std::vector< FvGapCell > m_gapCells
MInt a_noCells() const
Returns the number of cells.

◆ bc3007()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc3007 ( MInt  bcId)

Moving wall Euler boundary condition.

Author
Lennart Schneiders

Definition at line 15768 of file fvcartesianbndrycndxd.cpp.

15768 {
15769#ifdef _OPENMP
15770#pragma omp parallel for
15771#endif
15772 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
15773 const MInt bndryId = m_sortedBndryCells->a[id];
15774 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
15775
15776 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15777 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
15778 MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
15779
15780 MInt k = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0];
15781 ASSERT(k > -1 && k < m_solver->m_noEmbeddedBodies + m_solver->m_noPeriodicGhostBodies, "");
15783 mTerm(1, AT_, "Invalid body id: " + to_string(k));
15784 }
15785
15786 MFloat vel[nDim];
15787 MFloat surfVel[nDim];
15788 for(MInt i = 0; i < nDim; i++) {
15789 surfVel[i] = m_solver->m_bodyVelocity[k * nDim + i];
15790 }
15791 MFloat dx[3] = {F0, F0, F0};
15792 MFloat omega[3] = {F0, F0, F0};
15793 MFloat vrad[3] = {F0, F0, F0};
15794 for(MInt i = 0; i < nDim; i++) {
15795 dx[i] = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i] - m_solver->m_bodyCenter[k * nDim + i];
15796 }
15797 for(MInt i = 0; i < 3; i++) {
15798 omega[i] = m_solver->m_bodyAngularVelocity[k * 3 + i];
15799 }
15800 vrad[0] = omega[1] * dx[2] - omega[2] * dx[1];
15801 vrad[1] = omega[2] * dx[0] - omega[0] * dx[2];
15802 IF_CONSTEXPR(nDim == 3) vrad[2] = omega[0] * dx[1] - omega[1] * dx[0];
15803
15804 for(MInt i = 0; i < nDim; i++) {
15805 surfVel[i] += vrad[i];
15806 }
15807 /*
15808 MFloat imageVel[3] = {F0,F0,F0};
15809 for(MInt s = 0; s < mMin((signed)m_bndryCell[ bndryId ].m_recNghbrIds.size(),m_bndryCells->a[ bndryId
15810 ].m_noSrfcs); s++){ const MInt dummyId = m_bndryCell[ bndryId ].m_recNghbrIds[s]; for( MInt i=0; i<nDim;
15811 i++ ) { m_solver->a_pvariable( dummyId , PV->VV[i] ) = surfVel[i];
15812 }
15813 }
15814 for ( MUint n = 0; n < m_bndryCell[ bndryId ].m_recNghbrIds.size(); n++ ) {
15815 const MInt nghbrId = m_bndryCell[ bndryId ].m_recNghbrIds[n];
15816 if ( nghbrId < 0 || m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_imagePointRecConst.size() !=
15817 m_bndryCell[ bndryId ].m_recNghbrIds.size() ) { cerr << nghbrId << " " << m_bndryCell[ bndryId
15818 ].m_srfcVariables[srfc]->m_imagePointRecConst.size() << " " << m_bndryCell[ bndryId ].m_recNghbrIds.size() <<
15819 endl;
15820 }
15821 ASSERT ( nghbrId > -1 && m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_imagePointRecConst.size() ==
15822 m_bndryCell[ bndryId ].m_recNghbrIds.size(), "" ); for( MInt i=0; i<nDim; i++ ) { imageVel[i] += m_bndryCell[
15823 bndryId ].m_srfcVariables[srfc]->m_imagePointRecConst[n] * m_solver->a_pvariable( nghbrId ,
15824 PV->VV[i]);
15825 }
15826 }
15827
15828 MFloat normal[3] = {F0,F0,F0};
15829 MFloat cnt = F0;
15830 for ( MInt i = 0; i < nDim; i++ ) {
15831 normal[i] = m_solver->a_coordinate( cellId , i ) - m_solver->a_coordinate( ghostCellId , i );
15832 cnt += POW2(normal[i]);
15833 }
15834 cnt = sqrt(cnt);
15835 for ( MInt i = 0; i < nDim; i++ ) {
15836 normal[i] /= cnt;
15837 }
15838
15839
15840 // 1. set the surface velocities
15841 for( MInt i=0; i<nDim; i++ ) {
15842 vel[i] = imageVel[i];//m_solver->a_pvariable( cellId , PV->VV[i] );
15843 for( MInt j=0; j<nDim; j++ ) {
15844 vel[i] +=
15845 normal[i] * //m_bndryCells->a[ bndryId ].m_srfcs[srfc]->m_normalVector[ i ] *
15846 ( surfVel[ j ] - imageVel[i] ) //m_solver->a_pvariable( cellId , PV->VV[j] ) )
15847 * normal[j] ;//m_bndryCells->a[ bndryId ].m_srfcs[srfc]->m_normalVector[ j ] ;
15848 }
15849 }*/
15850
15851 // 1. set the surface velocities
15852 for(MInt i = 0; i < nDim; i++) {
15853 vel[i] = m_solver->a_pvariable(cellId, PV->VV[i]);
15854 for(MInt j = 0; j < nDim; j++) {
15855 vel[i] += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
15856 * (surfVel[j] - m_solver->a_pvariable(cellId, PV->VV[j]))
15857 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[j];
15858 }
15859 }
15860
15861
15862 for(MInt i = 0; i < nDim; i++) {
15863 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = F2 * vel[i] - m_solver->a_pvariable(cellId, PV->VV[i]);
15864 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]] = vel[i];
15865 }
15866 }
15867 }
15868 }
15869}
FvBndryCell< nDim, SysEqn > * m_bndryCell

◆ bc3011()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc3011 ( MInt  bcId)

no-slip isothermal wall boundary condition
u=v=w=0; drho/dn=dp/dn=0;

Definition at line 5463 of file fvcartesianbndrycndxd.cpp.

5463 {
5464 TRACE();
5465
5466#ifdef _OPENMP
5467#pragma omp parallel for
5468#endif
5469 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5470 const MInt bndryId = m_sortedBndryCells->a[id];
5471 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
5472 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5473 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
5474 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
5475 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
5476
5477 for(MInt i = 0; i < nDim; i++) {
5478 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = -m_solver->a_pvariable(cellId, PV->VV[i]);
5479 }
5480 const MFloat pressure = m_solver->a_pvariable(cellId, PV->P);
5481
5482 m_solver->a_pvariable(ghostCellId, PV->P) = pressure;
5483 // 2 * density of the set temperature - density of the cell
5484 m_solver->a_pvariable(ghostCellId, PV->RHO) =
5485 2 * sysEqn().density_ES(pressure, m_Bc3011WallTemperature) - m_solver->a_pvariable(cellId, PV->RHO);
5486
5487 IF_CONSTEXPR(isDetChem<SysEqn>)
5488 m_solver->a_pvariable(ghostCellId, PV->RHO) =
5489 F2 * m_solver->a_avariable(cellId, AV->W_MEAN) * pressure
5491 - m_solver->a_pvariable(cellId, PV->RHO); // to do: needs to be checked
5492
5493 for(MInt s = 0; s < m_noSpecies; s++) {
5494 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
5495 }
5496 }
5497 }
5498 }
5499 }
5500}
SysEqn::AdditionalVariables * AV
MFloat & a_avariable(const MInt cellId, const MInt varId)
Returns additional variable v of the cell cellId for variables varId.

◆ bc3037MGC()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::bc3037MGC ( MInt  )
inlinevirtual

Definition at line 861 of file fvcartesianbndrycndxd.h.

861{};

◆ bc3399()

template<MInt nDim, class SysEqn >
template<MBool MGC>
void FvBndryCndXD< nDim, SysEqn >::bc3399 ( MInt  bcId)

Definition at line 6940 of file fvcartesianbndrycndxd.cpp.

6940 {
6941 TRACE();
6942 const MInt noSpecies = m_noSpecies;
6943
6944#ifdef _OPENMP
6945#pragma omp parallel for
6946#endif
6947 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
6948 const MInt bndryId = m_sortedBndryCells->a[id];
6949 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
6950 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
6951 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
6952 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
6953 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
6954
6955 for(MInt i = 0; i < nDim; i++) {
6956 if(MGC) {
6957 if(m_surfaceGhostCell) {
6958 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = 0.0;
6959 } else {
6960 m_solver->a_pvariable(ghostCellId, PV->VV[i]) =
6961 -m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->VV[i]];
6962 }
6963 } else {
6964 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = -m_solver->a_pvariable(cellId, PV->VV[i]);
6965 }
6966 }
6967 if(MGC) {
6968 m_solver->a_pvariable(ghostCellId, PV->RHO) =
6969 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->RHO];
6970 m_solver->a_pvariable(ghostCellId, PV->P) =
6971 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->P];
6972 } else {
6973 // simplified Neumann: assuming the line boundary-ghost is normal to the boundary surface)
6974 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
6975 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
6976 }
6977
6978 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
6979 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
6980 if(MGC) {
6981 if(m_surfaceGhostCell) {
6982 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = 0.0;
6983 } else {
6984 m_solver->a_pvariable(ghostCellId, PV->NN[r]) =
6985 -m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->NN[r]];
6986 }
6987 } else {
6988 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = m_solver->a_pvariable(cellId, PV->NN[r]);
6989 }
6990 }
6991 }
6992 for(MInt s = 0; s < noSpecies; s++) {
6993 if(MGC) {
6994 m_solver->a_pvariable(ghostCellId, PV->Y[s]) =
6995 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->Y[s]];
6996 } else {
6997 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
6998 }
6999 }
7000 }
7001 }
7002 }
7003 }
7004}

◆ bc3466()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc3466 ( MInt  bcId)

Simple shear flow

Definition at line 15878 of file fvcartesianbndrycndxd.cpp.

15878 {
15879 TRACE();
15880
15881 MFloat vel[3]{};
15882 MFloat bbox[6]{};
15883 m_solver->m_geometry->getBoundingBox(bbox);
15884 const MFloat deltaY = bbox[1 + nDim] - bbox[1];
15885
15886 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
15887 MInt bndryId = m_sortedBndryCells->a[id];
15888 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
15889 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15890 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
15891 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
15892 MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
15893
15894 vel[0] = F2 * m_solver->m_UInfinity * m_bndryCell[bndryId].m_srfcs[0]->m_coordinates[1] / deltaY;
15895 for(MInt i = 0; i < nDim; i++) {
15896 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = F2 * vel[i] - m_solver->a_pvariable(cellId, PV->VV[i]);
15897 }
15898
15899 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
15900 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
15901 }
15902 }
15903 }
15904 }
15905}

◆ bc3600()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc3600 ( MInt  bcId)

Simple and fast fixed adiabatic wall boundary condition for use with the flux-redistribution method

Author
Lennart Schneiders

Definition at line 15915 of file fvcartesianbndrycndxd.cpp.

15915 {
15916 TRACE();
15917#ifdef _OPENMP
15918#pragma omp parallel for
15919#endif
15920 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
15921 MInt bndryId = m_sortedBndryCells->a[id];
15922 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
15923 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15924 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
15925 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
15926 MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
15927 for(MInt i = 0; i < nDim; i++) {
15928 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = -m_solver->a_pvariable(cellId, PV->VV[i]);
15929 }
15930 }
15931 }
15932 }
15933 }
15934}

◆ bc4000()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc4000 ( MInt  bcId)

no-slip adiabatic wall boundary condition with velocity component in periodic direction
u=v, w=factor*u_in; drho/dn=dp/dn=0;

Definition at line 5364 of file fvcartesianbndrycndxd.cpp.

5364 {
5365 TRACE();
5366
5367 const MFloat G = m_wFactor * m_solver->m_UInfinity;
5368
5369 MFloat factor = F1;
5370 if(m_4000timeStepOffset > 0) {
5373 }
5374 }
5375
5376
5377#ifdef _OPENMP
5378#pragma omp parallel for
5379#endif
5380 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5381 const MInt bndryId = m_sortedBndryCells->a[id];
5382 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
5383 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5384 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
5385 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
5386 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
5387
5388 m_solver->a_pvariable(ghostCellId, PV->U) = -m_solver->a_pvariable(cellId, PV->U);
5389 m_solver->a_pvariable(ghostCellId, PV->V) = -m_solver->a_pvariable(cellId, PV->V);
5390 m_solver->a_pvariable(ghostCellId, PV->W) = 2.0 * factor * G - m_solver->a_pvariable(cellId, PV->W);
5391
5392 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
5393 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
5394 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = -m_solver->a_pvariable(cellId, PV->NN[r]);
5395 }
5396 }
5397
5398 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
5399
5400 for(MInt s = 0; s < m_noSpecies; s++) {
5401 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
5402 }
5403 }
5404 }
5405 }
5406 }
5407}

◆ bc4001()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bc4001 ( MInt  bcId)

no-slip adiabatic wall boundary condition
u=v=w=0; drho/dn=dp/dn=0;

Definition at line 5416 of file fvcartesianbndrycndxd.cpp.

5416 {
5417 TRACE();
5418
5419 const MFloat G = m_wFactor * m_solver->m_UInfinity;
5420 const MInt timeStepOffset = m_4000timeStepOffset;
5421
5422#ifdef _OPENMP
5423#pragma omp parallel for
5424#endif
5425 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5426 const MInt bndryId = m_sortedBndryCells->a[id];
5427 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
5428 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5429 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
5430 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
5431 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
5432
5433 m_solver->a_pvariable(ghostCellId, PV->U) = -m_solver->a_pvariable(cellId, PV->U);
5434 m_solver->a_pvariable(ghostCellId, PV->V) = -m_solver->a_pvariable(cellId, PV->V);
5435
5436 MFloat factor = F1;
5437
5439 factor = 1 - cos(PI / (MFloat)timeStepOffset * (globalTimeStep - m_solver->m_restartTimeStep));
5440 }
5441
5442 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
5443 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
5444 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = -m_solver->a_pvariable(cellId, PV->NN[r]);
5445 }
5446 }
5447
5448 m_solver->a_pvariable(ghostCellId, PV->W) = 2.0 * factor * G - m_solver->a_pvariable(cellId, PV->W);
5449 }
5450 }
5451 }
5452 }
5453}

◆ bc7809() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bc7809 ( MInt  bcId)

Definition at line 17637 of file fvcartesianbndrycndxd.cpp.

17637 {
17638 TRACE();
17639
17640 IF_CONSTEXPR(isEEGas<SysEqn>)
17641 TERMM(1, "bc7809 not working for AIAFvSysEqnEEGas");
17642
17643 if(m_sortedCutOffCells[bcId]->size() == 0) {
17644 return;
17645 }
17646
17647 MInt d = 1;
17648
17649 if(!m_solver->m_stgIsActive) {
17650 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17651 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
17652 // set variables
17653 // for(MInt var = 0; var < PV->noVariables; var++) {
17654 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_RANSValues[PV->U][cellId];
17655 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_RANSValues[PV->V][cellId];
17656 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_RANSValues[PV->W][cellId];
17657 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_RANSValues[PV->RHO][cellId];
17658 }
17659 // return;
17660 } else {
17661 if(m_stgLocal[bcId]) {
17663 case MAIA_FINITE_VOLUME: {
17664 m_stgBC[bcId]->bc7909();
17665 break;
17666 }
17667 case MAIA_STRUCTURED: {
17668 m_stgBCStrcd[bcId]->bc7909();
17669 break;
17670 }
17671
17672 default:
17673 mTerm(1, AT_, "Not yet implemented for solver " + m_solver->m_bc7909RANSSolverType);
17674 }
17675 }
17676
17677 if(m_solver->m_noSpecies > 0) {
17678 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17679 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
17680 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
17681 for(MInt i = 0; i < m_noSpecies; i++) {
17682 m_solver->a_pvariable(cellId, PV->Y[i]) = F0;
17683 }
17684 }
17685 }
17686 }
17687 }
17688
17689 // set pressure
17690 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17691 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
17692 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17693 if(m_solver->checkNeighborActive(cellId, d)) {
17694 const MInt nghbrId = m_solver->c_neighborId(cellId, d);
17695 if(nghbrId < 0) {
17696 cutOffBcMissingNeighbor(cellId, "bc7909");
17697 } else {
17698 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
17699 }
17700 } else {
17701 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
17702 }
17703 }
17704}
std::map< MInt, MSTG< nDim, MAIA_STRUCTURED, MAIA_FINITE_VOLUME > * > m_stgBCStrcd
std::map< MInt, MBool > m_stgLocal
std::map< MInt, MSTG< nDim, MAIA_FINITE_VOLUME, MAIA_FINITE_VOLUME > * > m_stgBC
std::vector< MFloat > * m_RANSValues
@ MAIA_FINITE_VOLUME
Definition: enums.h:23
@ MAIA_STRUCTURED
Definition: enums.h:40

◆ bc7809() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bc7809 ( MInt  )
inline

Definition at line 767 of file fvcartesianbndrycndxd.h.

767 {
768 TERMM(-1, "");
769 }

◆ bc7901() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bc7901 ( MInt  bcId)

Definition at line 17360 of file fvcartesianbndrycndxd.cpp.

17360 {
17361 TRACE();
17362
17363 if(m_sortedCutOffCells[bcId]->size() == 0) {
17364 return;
17365 }
17366
17367 MInt cellId, nghbrId, d = m_7901faceNormalDir;
17368 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17369 cellId = m_sortedCutOffCells[bcId]->a[id];
17370
17371 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17372 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17373
17374 if(m_solver->checkNeighborActive(cellId, d)) {
17375 nghbrId = m_solver->c_neighborId(cellId, d);
17376 if(nghbrId < 0) {
17377 cutOffBcMissingNeighbor(cellId, "bc7901");
17378 } else {
17379 // set the velocities
17380 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
17381 m_solver->a_pvariable(cellId, PV->V) = m_solver->a_pvariable(nghbrId, PV->V);
17382 m_solver->a_pvariable(cellId, PV->W) = m_solver->a_pvariable(nghbrId, PV->W);
17383 // set the density
17384 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
17385 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
17386 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
17387 m_solver->a_pvariable(cellId, PV->NN[r]) = m_solver->a_pvariable(nghbrId, PV->NN[r]);
17388 }
17389 }
17390
17391 MFloat pressureTarget = m_solver->m_PInfinity; // m_solver->m_LESValues[PV->P][cellId];
17392
17393 m_solver->a_pvariable(cellId, PV->P) = pressureTarget;
17394 if(m_noSpecies > 0) {
17395 m_solver->a_pvariable(cellId, PV->Y[0]) = m_solver->m_LESValues[PV->Y[0]][cellId];
17396 }
17397 }
17398 } else {
17399 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_UInfinity;
17400 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_VInfinity;
17401 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_WInfinity;
17402 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
17403 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_PInfinity;
17404 }
17405 }
17406}
std::vector< MFloat > * m_LESValues

◆ bc7901() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bc7901 ( MInt  )
inline

Definition at line 742 of file fvcartesianbndrycndxd.h.

742 {
743 TERMM(-1, "");
744 }

◆ bc7902() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bc7902 ( MInt  bcId)

Definition at line 17416 of file fvcartesianbndrycndxd.cpp.

17416 {
17417 TRACE();
17418
17419 if(m_sortedCutOffCells[bcId]->size() == 0) return;
17420
17421 if(globalTimeStep % m_solver->m_zonalTransferInterval == 0 //&& globalTimeStep != m_solver->m_restartTimeStep
17422 && m_solver->m_RKStep == 0) {
17423 for(MInt var = 0; var < PV->noVariables; var++) {
17424 for(MInt i = 0; i < m_7902globalNoWallNormalLocations; i++) {
17425 m_7902LESAverage[var][i] = F0;
17426 }
17427 }
17428
17429 for(MInt var = 0; var < PV->noVariables; var++) {
17430 for(MInt i = 0; i < m_7902globalNoWallNormalLocations; i++) {
17431 for(MInt p = 0; p < (MInt)m_7902periodicLocations[i].size(); p++) {
17433
17434 ASSERT(cellId < (MInt)m_solver->m_LESValues[var].size(),
17435 "Trying to access data [" + to_string(var) + "][" + to_string(cellId) + "] in m_LESValues with length "
17436 + to_string(m_solver->m_LESValues[var].size()) + ", domainId: " + to_string(m_solver->domainId()));
17437
17439 }
17440 }
17441 }
17442
17443 if(noDomains() > 1) {
17444 for(MInt var = 0; var < PV->noVariables; var++) {
17445 MPI_Allreduce(MPI_IN_PLACE, m_7902LESAverage[var], m_7902globalNoWallNormalLocations, MPI_DOUBLE, MPI_SUM,
17446 m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_, "MPI_IN_PLACE", "m_7902LESAverage");
17447 }
17448 }
17449 }
17450
17451 MInt cellId, nghbrId, d = m_7902faceNormalDir;
17452 // Prepare the exchange cells for zonal RANS-LES method
17453 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17454 cellId = m_sortedCutOffCells[bcId]->a[id];
17455
17456 // InitialRange
17458 // Velocities
17459 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_UInfinity;
17460 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_VInfinity;
17461 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_WInfinity;
17462 // Density
17463 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
17464 // Turbulent viscosity
17466
17467 // fully developed LES solution
17468 } else {
17469 for(MInt var = 0; var < PV->noVariables; var++) {
17471 m_solver->a_pvariable(cellId, var) = m_7902LESAverage[var][index];
17472 }
17473 }
17474
17475 // Pressure
17476 if(m_solver->checkNeighborActive(cellId, d)) {
17477 nghbrId = m_solver->c_neighborId(cellId, d);
17478 if(nghbrId < 0) {
17479 cutOffBcMissingNeighbor(cellId, "bc7902");
17480 } else {
17481 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
17482 }
17483 } else {
17484 TERMM(1, "ERROR in bc7902");
17485 }
17486 }
17487}
MInt m_7902globalNoWallNormalLocations
MInt * m_7902globalNoPeriodicLocations
MFloat ** m_7902LESAverage
std::vector< MFloat > * m_7902periodicLocations
virtual MInt domainId() const
Return the domainId (rank)
Definition: solver.h:383
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

◆ bc7902() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bc7902 ( MInt  )
inline

Definition at line 747 of file fvcartesianbndrycndxd.h.

747 {
748 TERMM(-1, "");
749 }

◆ bc7903() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bc7903 ( MInt  bcId)

Definition at line 17550 of file fvcartesianbndrycndxd.cpp.

17550 {
17551 TRACE();
17552
17553 /* if(m_sortedCutOffCells[bcId]->size() == 0) return; */
17554
17555 MInt cellId, nghbrId, d = 0;
17556 // Prepare the exchange cells for zonal RANS-LES method
17557 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17558 cellId = m_sortedCutOffCells[bcId]->a[id];
17559
17560 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17561 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17562
17563 // set boundary values
17564 if(m_solver->checkNeighborActive(cellId, d)) {
17565 nghbrId = m_solver->c_neighborId(cellId, d);
17566 if(nghbrId < 0) {
17567 cutOffBcMissingNeighbor(cellId, "bc7903");
17568 } else {
17569 // set the velocities
17570 m_solver->a_pvariable(cellId, PV->U) = m_solver->a_pvariable(nghbrId, PV->U);
17571 m_solver->a_pvariable(cellId, PV->V) = m_solver->a_pvariable(nghbrId, PV->V);
17572 m_solver->a_pvariable(cellId, PV->W) = m_solver->a_pvariable(nghbrId, PV->W);
17573 // set the density
17574 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->a_pvariable(nghbrId, PV->RHO);
17575
17576 m_solver->a_pvariable(cellId, PV->P) = m_solver->m_RANSValues[PV->P][cellId];
17577
17578 for(MInt s = 0; s < m_noSpecies; s++)
17579 m_solver->a_pvariable(cellId, PV->Y[s]) = m_solver->a_pvariable(nghbrId, PV->Y[s]);
17580 }
17581 } else {
17582 TERMM(1, "ERROR in bc7903");
17583 }
17584 }
17585}

◆ bc7903() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bc7903 ( MInt  )
inline

Definition at line 757 of file fvcartesianbndrycndxd.h.

757 {
758 TERMM(-1, "");
759 }

◆ bc7905() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bc7905 ( MInt  bcId)

Definition at line 17497 of file fvcartesianbndrycndxd.cpp.

17497 {
17498 TRACE();
17499
17500 if(m_sortedCutOffCells[bcId]->size() == 0) return;
17501
17502 MInt cellId, nghbrId, d = m_7902faceNormalDir;
17503 // Prepare the exchange cells for zonal RANS-LES method
17504 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17505 cellId = m_sortedCutOffCells[bcId]->a[id];
17506
17507 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17508 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17509
17510 // InitialRange
17512 // Velocities
17513 m_solver->a_pvariable(cellId, PV->U) = m_solver->m_UInfinity;
17514 m_solver->a_pvariable(cellId, PV->V) = m_solver->m_VInfinity;
17515 m_solver->a_pvariable(cellId, PV->W) = m_solver->m_WInfinity;
17516 // Density
17517 m_solver->a_pvariable(cellId, PV->RHO) = m_solver->m_rhoInfinity;
17518 // Turbulent viscosity
17520
17521 // fully developed LES solution
17522 } else {
17523 for(MInt var = 0; var < PV->noVariables; var++) {
17524 m_solver->a_pvariable(cellId, var) = m_solver->m_LESValues[var][cellId];
17525 }
17526 }
17527
17528 // Pressure
17529 if(m_solver->checkNeighborActive(cellId, d)) {
17530 nghbrId = m_solver->c_neighborId(cellId, d);
17531 if(nghbrId < 0) {
17532 cutOffBcMissingNeighbor(cellId, "bc7905");
17533 } else {
17534 m_solver->a_pvariable(cellId, PV->P) = m_solver->a_pvariable(nghbrId, PV->P);
17535 }
17536 } else {
17537 TERMM(1, "ERROR in bc7905");
17538 }
17539 }
17540}

◆ bc7905() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bc7905 ( MInt  )
inline

Definition at line 752 of file fvcartesianbndrycndxd.h.

752 {
753 TERMM(-1, "");
754 }

◆ bc7909() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bc7909 ( MInt  bcId)

Definition at line 17595 of file fvcartesianbndrycndxd.cpp.

17595 {
17596 TRACE();
17597
17598 IF_CONSTEXPR(isEEGas<SysEqn>)
17599 TERMM(1, "bc7809 not working for AIAFvSysEqnEEGas");
17600
17601 if(m_stgLocal[bcId]) {
17603 case MAIA_FINITE_VOLUME: {
17604 m_stgBC[bcId]->bc7909();
17605 break;
17606 }
17607 case MAIA_STRUCTURED: {
17608 m_stgBCStrcd[bcId]->bc7909();
17609 break;
17610 }
17611 default:
17612 mTerm(1, AT_, "Not yet implemented for solver " + m_solver->m_bc7909RANSSolverType);
17613 }
17614 if(m_solver->m_noSpecies > 0) {
17615 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
17616 MInt bndryId = m_sortedBndryCells->a[id];
17617 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
17618 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
17619 const MInt ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
17620 for(MInt i = 0; i < m_noSpecies; i++) {
17621 m_solver->a_pvariable(ghostCellId, PV->Y[i]) = F0;
17622 }
17623 }
17624 }
17625 }
17626 }
17627}

◆ bc7909() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bc7909 ( MInt  )
inline

Definition at line 762 of file fvcartesianbndrycndxd.h.

762 {
763 TERMM(-1, "");
764 }

◆ bcInit0001()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit0001 ( MInt  bcId)
Author
Daniel Hartmann

Definition at line 4285 of file fvcartesianbndrycndxd.cpp.

4285 {
4286 TRACE();
4287
4288 MInt noDirs = 2 * nDim;
4289 MInt cellId;
4290 MInt bndryId;
4291 MInt nghbrId;
4292 MInt ghostCellId;
4293 MInt temp;
4294 MInt bnd;
4295 MInt id;
4296 MInt linkedCell;
4297 MInt noReconstructIds = 0;
4298 ScratchSpace<MInt> reconstructIds(100, AT_, "reconstructIds");
4299 //---
4300
4301 for(MInt bc = m_bndryCndCells[bcId]; bc < m_bndryCndCells[bcId + 1]; bc++) {
4302 bndryId = m_sortedBndryCells->a[bc];
4303 cellId = m_bndryCells->a[bndryId].m_cellId;
4304 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
4305 if(m_bndryCells->a[bndryId].m_linkedCellId == -1) {
4306 // reset
4307 noReconstructIds = 0;
4308
4309 // add the ghost cell
4310 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
4311 reconstructIds[noReconstructIds] = ghostCellId;
4312 noReconstructIds++;
4313
4314 // add all neighbors
4315 for(MInt c = m_solver->m_identNghbrIds[cellId * noDirs]; c < m_solver->m_identNghbrIds[(cellId + 1) * noDirs];
4316 c++) {
4317 reconstructIds[noReconstructIds] = m_solver->m_storeNghbrIds[c];
4318 noReconstructIds++;
4319 }
4320
4321 // identify boundary neighbors: add their internal neighbors
4322 temp = noReconstructIds;
4323 for(MInt k = 0; k < temp; k++) {
4324 id = reconstructIds[k];
4325 bnd = m_solver->a_bndryId(id);
4326 if(bnd > -1) {
4327 for(MInt c = m_solver->m_identNghbrIds[id * noDirs]; c < m_solver->m_identNghbrIds[(id + 1) * noDirs];
4328 c++) {
4329 nghbrId = m_solver->m_storeNghbrIds[c];
4330 if(m_solver->a_bndryId(nghbrId) == -1) {
4331 reconstructIds[noReconstructIds] = nghbrId;
4332 noReconstructIds++;
4333 }
4334 }
4335 }
4336 }
4337
4338 // replace slave neighbors by their master cells
4339 // if master==cellId add all neighbors of the slave cell
4340 temp = noReconstructIds;
4341 for(MInt k = 0; k < temp; k++) {
4342 id = reconstructIds[k];
4343 bnd = m_solver->a_bndryId(id);
4344 if(bnd > -1) {
4345 linkedCell = m_bndryCells->a[bnd].m_linkedCellId;
4346 if(linkedCell > -1) {
4347 reconstructIds[k] = linkedCell;
4348 if(linkedCell == cellId) {
4349 for(MInt c = m_solver->m_identNghbrIds[id * noDirs]; c < m_solver->m_identNghbrIds[(id + 1) * noDirs];
4350 c++) {
4351 nghbrId = m_solver->m_storeNghbrIds[c];
4352 if(m_solver->a_bndryId(nghbrId) > -1) {
4353 if(m_bndryCells->a[m_solver->a_bndryId(nghbrId)].m_linkedCellId == -1) {
4354 reconstructIds[noReconstructIds] = nghbrId;
4355 noReconstructIds++;
4356 } else {
4357 reconstructIds[noReconstructIds] = m_bndryCells->a[m_solver->a_bndryId(nghbrId)].m_linkedCellId;
4358 noReconstructIds++;
4359 }
4360 } else {
4361 reconstructIds[noReconstructIds] = nghbrId;
4362 noReconstructIds++;
4363 }
4364 }
4365 }
4366 }
4367 }
4368 }
4369
4370 // remove cellId from list
4371 temp = noReconstructIds;
4372 for(MInt k = temp - 1; k > -1; k--) {
4373 if(reconstructIds[k] == cellId) {
4374 noReconstructIds--;
4375 reconstructIds[k] = reconstructIds[noReconstructIds];
4376 }
4377 }
4378
4379 // sort the list
4380 maia::math::quickSort(reconstructIds.begin(), 0, noReconstructIds - 1);
4382 mMin(m_cells.noRecNghbrs(), maia::math::removeDoubleEntries(reconstructIds.begin(), noReconstructIds));
4383
4384 for(MInt k = 0; k < m_solver->a_noReconstructionNeighbors(cellId); k++) {
4385 m_solver->a_reconstructionNeighborId(cellId, k) = reconstructIds[k];
4386 }
4387 }
4388 }
4389 }
4390}
maia::fv::collector::FvCellCollector< nDim > & m_cells
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.
MInt removeDoubleEntries(MInt *a, MInt size)
Definition: maiamath.h:722
void quickSort(MInt *a, MInt start, MInt end)
Definition: maiamath.h:716

◆ bcInit0002()

template<MInt nDim, class SysEqn >
template<MBool MGC>
void FvBndryCndXD< nDim, SysEqn >::bcInit0002 ( MInt  bcId)
   Sets up the reconstruction stencil for the modified Neumann bc
   and stores the necessary data in the ghost cell

   IF MGC
    Adds all ghost cells belonging to all boundary surfaces of both master and small cells to the masters

reconstruction stencil

Author
Daniel Hartmann, Sven Berger

Definition at line 4410 of file fvcartesianbndrycndxd.cpp.

4410 {
4411 TRACE();
4412
4413 static constexpr MInt noDirs = 2 * nDim;
4414 MInt temp = 0;
4415 MInt noReconstructIds = 0;
4416 MIntScratchSpace reconstructIds(MGC ? 100 : noDirs + 1, AT_, "reconstructIds");
4417 //---
4418
4419 // loop over all non-slave boundary cells
4420 for(MInt bc = m_bndryCndCells[bcId]; bc < m_bndryCndCells[bcId + 1]; bc++) {
4421 const MInt bndryId = m_sortedBndryCells->a[bc];
4422 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
4423 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
4424 if(m_solver->a_hasProperty(cellId, SolverCell::IsInvalid)) continue;
4425 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
4426 if((!MGC && m_bndryCells->a[bndryId].m_linkedCellId == -1)
4427 || (MGC && m_bndryCells->a[bndryId].m_linkedCellId > -1)) {
4428 // reset
4429 noReconstructIds = 0;
4430
4431 if(MGC) {
4432 // add the ghost cell
4433 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
4434 reconstructIds[noReconstructIds] = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
4435 noReconstructIds++;
4436 }
4437 } else {
4438 // add the ghost cell
4439 reconstructIds.p[noReconstructIds] = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
4440 noReconstructIds = 1;
4441 }
4442
4443 // add all neighbors
4444 for(MInt c = m_solver->m_identNghbrIds[cellId * noDirs]; c < m_solver->m_identNghbrIds[(cellId + 1) * noDirs];
4445 c++) {
4446 reconstructIds.p[noReconstructIds] = m_solver->m_storeNghbrIds[c];
4447 noReconstructIds++;
4448 }
4449
4450 // replace slave neighbors by their master cells
4451 // if master==cellId add all neighbors of the slave cell
4452 temp = noReconstructIds;
4453 for(MInt k = 0; k < temp; k++) {
4454 const MInt id = reconstructIds.p[k];
4455 if(m_solver->a_bndryId(id) > -1) {
4456 const MInt linkedCell = m_bndryCells->a[m_solver->a_bndryId(id)].m_linkedCellId;
4457 if(linkedCell > -1) {
4458 reconstructIds.p[k] = linkedCell;
4459 if(linkedCell == cellId) {
4460 for(MInt c = m_solver->m_identNghbrIds[id * noDirs]; c < m_solver->m_identNghbrIds[(id + 1) * noDirs];
4461 c++) {
4462 const MInt nghbrId = m_solver->m_storeNghbrIds[c];
4463 if(m_solver->a_bndryId(nghbrId) > -1) {
4464 if(m_bndryCells->a[m_solver->a_bndryId(nghbrId)].m_linkedCellId == -1) {
4465 reconstructIds.p[noReconstructIds] = nghbrId;
4466 noReconstructIds++;
4467 } else {
4468 reconstructIds.p[noReconstructIds] = m_bndryCells->a[m_solver->a_bndryId(nghbrId)].m_linkedCellId;
4469 noReconstructIds++;
4470 }
4471 } else {
4472 reconstructIds.p[noReconstructIds] = nghbrId;
4473 noReconstructIds++;
4474 }
4475 }
4476 if(MGC) {
4477 MInt bnd = m_solver->a_bndryId(id);
4478 // add other ghost-cells to the reconstruction stencil
4479 for(MInt srfcSM = 0; srfcSM < m_bndryCells->a[bnd].m_noSrfcs; srfcSM++) {
4480 reconstructIds[noReconstructIds] = m_bndryCells->a[bnd].m_srfcVariables[srfcSM]->m_ghostCellId;
4481 noReconstructIds++;
4482 }
4483 }
4484 }
4485 }
4486 }
4487 }
4488
4489 // remove cellId from list
4490 temp = noReconstructIds;
4491 for(MInt k = temp - 1; k > -1; k--) {
4492 if(reconstructIds.p[k] == cellId) {
4493 noReconstructIds--;
4494 reconstructIds.p[k] = reconstructIds.p[noReconstructIds];
4495 }
4496 }
4497
4498 // sort the list
4499 maia::math::quickSort(reconstructIds.getPointer(), 0, noReconstructIds - 1);
4501 maia::math::removeDoubleEntries(reconstructIds.getPointer(), noReconstructIds);
4502
4503 for(MInt k = 0; k < m_solver->a_noReconstructionNeighbors(cellId); k++) {
4504 m_solver->a_reconstructionNeighborId(cellId, k) = reconstructIds.p[k];
4505 }
4506 }
4507 }
4508 }
4509
4510 // compute the least-squares constants k_i for the ghost cell (Neumann bc)
4511 if(!MGC) {
4513 }
4514}
void computeNeumannLSConstants(MInt)
Sets up the reconstruction stencil for boundary cells.

◆ bcInit0004()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit0004 ( MInt  bcId)
   Sets up the reconstruction stencil for the modified Neumann bc
   and stores the necessary data in the ghost cell
Author
Daniel Hartmann

Definition at line 4529 of file fvcartesianbndrycndxd.cpp.

4529 {
4530 TRACE();
4531
4532 MInt noDirs = 2 * nDim;
4533 MInt requiredNoCells, tmpCell;
4534 IF_CONSTEXPR(nDim == 2) requiredNoCells = 7;
4535 IF_CONSTEXPR(nDim == 3) requiredNoCells = 9;
4536 MInt cellId, bndryId, nghbrId, ghostCellId, temp, bnd, id, linkedCell;
4537 MInt noReconstructIds;
4538 MIntScratchSpace reconstructIds(100, AT_, "reconstructIds");
4539 stack<MInt> tmpStack;
4540 //---
4541
4542 // loop over all non-slave boundary cells
4543 for(MInt bc = m_bndryCndCells[bcId]; bc < m_bndryCndCells[bcId + 1]; bc++) {
4544 bndryId = m_sortedBndryCells->a[bc];
4545 cellId = m_bndryCells->a[bndryId].m_cellId;
4546 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
4547 if(m_bndryCells->a[bndryId].m_linkedCellId == -1) {
4548 // reset
4549 noReconstructIds = 0;
4550
4551 // add the ghost cell
4552 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
4553 reconstructIds[noReconstructIds] = ghostCellId;
4554 noReconstructIds++;
4555
4556 // add all neighbors
4557 for(MInt c = m_solver->m_identNghbrIds[cellId * noDirs]; c < m_solver->m_identNghbrIds[(cellId + 1) * noDirs];
4558 c++) {
4559 reconstructIds[noReconstructIds] = m_solver->m_storeNghbrIds[c];
4560 noReconstructIds++;
4561 tmpStack.push(m_solver->m_storeNghbrIds[c]);
4562 }
4563
4564 while(noReconstructIds < requiredNoCells) {
4565 // put all cells on s stack
4566 for(MInt n = 0; n < noReconstructIds; n++) {
4567 tmpStack.push(reconstructIds[n]);
4568 }
4569
4570 // add all neighbors of reconstructIds
4571 while(!tmpStack.empty()) {
4572 tmpCell = tmpStack.top();
4573 tmpStack.pop();
4574 for(MInt c = m_solver->m_identNghbrIds[tmpCell * noDirs];
4575 c < m_solver->m_identNghbrIds[(tmpCell + 1) * noDirs];
4576 c++) {
4577 reconstructIds[noReconstructIds] = m_solver->m_storeNghbrIds[c];
4578 noReconstructIds++;
4579 }
4580 }
4581
4582 // replace slave neighbors by their master cells
4583 // a) if master==cellId add all neighbors of the slave cell
4584 temp = noReconstructIds;
4585 for(MInt k = 0; k < temp; k++) {
4586 id = reconstructIds[k];
4587 bnd = m_solver->a_bndryId(id);
4588 if(bnd > -1) {
4589 linkedCell = m_bndryCells->a[bnd].m_linkedCellId;
4590 if(linkedCell > -1) {
4591 reconstructIds[k] = linkedCell;
4592 if(linkedCell == cellId) {
4593 for(MInt c = m_solver->m_identNghbrIds[id * noDirs]; c < m_solver->m_identNghbrIds[(id + 1) * noDirs];
4594 c++) {
4595 nghbrId = m_solver->m_storeNghbrIds[c];
4596 if(m_solver->a_bndryId(nghbrId) > -1) {
4597 if(m_bndryCells->a[m_solver->a_bndryId(nghbrId)].m_linkedCellId == -1) {
4598 reconstructIds[noReconstructIds] = nghbrId;
4599 noReconstructIds++;
4600 } else {
4601 reconstructIds[noReconstructIds] = m_bndryCells->a[m_solver->a_bndryId(nghbrId)].m_linkedCellId;
4602 noReconstructIds++;
4603 }
4604 } else {
4605 reconstructIds[noReconstructIds] = nghbrId;
4606 noReconstructIds++;
4607 }
4608 }
4609 }
4610 }
4611 }
4612 }
4613 // b) remove all the small cells
4614 temp = noReconstructIds;
4615 for(MInt k = 0; k < temp; k++) {
4616 id = reconstructIds[k];
4617 bnd = m_solver->a_bndryId(id);
4618 if(bnd > -1) {
4619 linkedCell = m_bndryCells->a[bnd].m_linkedCellId;
4620 if(linkedCell > -1) reconstructIds[k] = linkedCell;
4621 }
4622 }
4623
4624 // remove cellId from list
4625 temp = noReconstructIds;
4626 for(MInt k = temp - 1; k > -1; k--) {
4627 if(reconstructIds[k] == cellId) {
4628 noReconstructIds--;
4629 reconstructIds[k] = reconstructIds[noReconstructIds];
4630 }
4631 }
4632
4633 // sort the list
4634 maia::math::quickSort(reconstructIds.begin(), 0, noReconstructIds - 1);
4636 maia::math::removeDoubleEntries(reconstructIds.begin(), noReconstructIds);
4637
4638 for(MInt k = 0; k < m_solver->a_noReconstructionNeighbors(cellId); k++)
4639 m_solver->a_reconstructionNeighborId(cellId, k) = reconstructIds[k];
4640 }
4641 }
4642 }
4643 }
4644
4645 // compute the least-squares constants k_i for the ghost cell (Neumann bc)
4647}
iterator begin()
Definition: scratch.h:273

◆ bcInit1050()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit1050 ( MInt  )

Daniel Hartmann, March 06, 2007

Definition at line 14029 of file fvcartesianbndrycndxd.cpp.

14029 {
14030 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function bcInit1050 is untested for 2D!"); }
14031 TRACE();
14032
14033 MInt noCells = m_bndryCells->size();
14034 MFloat eps = 0.0001 / FPOW2(m_solver->maxRefinementLevel());
14035// --- end of initialization
14036
14037// loop over all concerning boundary cells
14038#ifdef _OPENMP
14039#pragma omp parallel for
14040#endif
14041 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
14042 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId == 1051) {
14043 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
14044 MFloat coordinates[nDim];
14045 MFloat coordinatesP[nDim];
14046 for(MInt i = 0; i < nDim; i++) {
14047 coordinates[i] = m_solver->a_coordinate(cellId, i) - m_bndryCells->a[bndryId].m_coordinates[i];
14048 }
14049 for(MInt bndryId2 = 0; bndryId2 < noCells; bndryId2++) {
14050 if(m_bndryCells->a[bndryId2].m_srfcs[0]->m_bndryCndId == 1052) {
14051 MInt periodicCellId = m_bndryCells->a[bndryId2].m_cellId;
14052 for(MInt i = 0; i < nDim; i++) {
14053 coordinatesP[i] = m_solver->a_coordinate(periodicCellId, i) - m_bndryCells->a[bndryId2].m_coordinates[i];
14054 }
14055 if(fabs(coordinates[0] - coordinatesP[0]) < eps && fabs(coordinates[1] - coordinatesP[1]) < eps) {
14056 m_bndryCells->a[bndryId].m_periodicCellId = periodicCellId;
14057 m_bndryCells->a[bndryId2].m_periodicCellId = cellId;
14058 break;
14059 }
14060 }
14061 }
14062 }
14063 }
14064}
constexpr MFloat FPOW2(MInt x)

◆ bcInit1251()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit1251 ( MInt  )

◆ bcInit1601()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit1601 ( MInt  )
Author
Rudie Kunnen

◆ bcInit2700()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit2700 ( MInt  )
Version
: init for cut-off boundary condition
Author
: Thomas Schilden, 12.2.2015

◆ bcInit2770()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit2770 ( MInt  )

a boundary shock region within the cut off cells is created. In this region we impose an oblique shock wave. Therefore we allocate memory to store a solution that is copied to these cells every timestep. There are three possible solutions:

  1. linear blending between up- and downstream values, restartfile = 0
  2. solution from an inner shock region, shockFromInnerSolution = 1, restartFile = 1
  3. solution from the boundary shock region, shockFromInnerSolution = 0, restartFile = 1

◆ bcInit30022()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInit30022 ( MInt  )

◆ bcInit4000()

template<MInt nDim, class SysEqn >
template<MBool MGC>
void FvBndryCndXD< nDim, SysEqn >::bcInit4000 ( MInt  )

Definition at line 5349 of file fvcartesianbndrycndxd.cpp.

5349 {
5350 TRACE();
5351
5352 m_4000timeStepOffset = Context::getSolverProperty<MInt>("bc4000timeStepOffset", m_solverId, AT_);
5353 m_4000timeInterval = Context::getSolverProperty<MInt>("bc4000timeInterval", m_solverId, AT_);
5354 m_wFactor = Context::getSolverProperty<MFloat>("wFactor", m_solverId, AT_);
5355}

◆ bcInit7809() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bcInit7809 ( MInt  bcId)

Definition at line 17142 of file fvcartesianbndrycndxd.cpp.

17142 {
17143 TRACE();
17144
17145 m_log << endl << "::bcInit:" + to_string(m_cutOffBndryCndIds[bcId]) + " ..." << endl;
17146 m_startSTGTimeStep = Context::getSolverProperty<MInt>("startSTGTimeStep", m_solverId, AT_, &m_startSTGTimeStep);
17147
17148 IF_CONSTEXPR(!isEEGas<SysEqn> && !isDetChem<SysEqn>) {
17149 /*
17150 0) Check if stg is active
17151 1) Loop over all boundary cells;
17152 Skip cells if !IsOnCurrentMGLevel;
17153 Check if cell has multiple ghost cells;
17154 Save cells participating in stg and pass them later to STG constructor;
17155 Mark if current rank has cells involved in current stg
17156 2) Create communicator for bc7909 from m_comm_bc[m_bc_comm_pointer[bcId]] communicator
17157 --> ranks which have no STG cells return
17158 3) Determine normal to STG boundary (by now only +x and -x allowed);
17159 Determine y-coordinate of adjacent solid wall (assume wall with constant y in spanwise
17160 direction); Determine normal pointing from the solid wall to the domain;
17161 y-coordinate of adjacent wall is the closest one, from those read in by a property;
17162 4) Create STG object
17163 */
17164
17165 // ======================================================
17166 // 0) Check if stg is active
17167 // ======================================================
17168 if(!m_solver->m_stgIsActive) return; // TERMM(1, "m_stgIsActive=false but CBC 7909, 7910, ... exists!");
17169
17170
17171 // ======================================================
17172 // 1) Loop over all boundary cells;
17173 // Skip cells if !IsOnCurrentMGLevel;
17174 // Check if cell has multiple ghost cells;
17175 // Save cells participating in stg and pass them later to STG constructor
17176 // Mark if current rank has cells involved in current stg
17177 // ======================================================
17178 ScratchSpace<MInt> stgBcCells(m_sortedCutOffCells[bcId]->size(), AT_, "stgBcCells");
17179
17180 MInt noBc7909Cells = 0;
17181 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17182 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
17183 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17184 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
17185 stgBcCells[noBc7909Cells++] = cellId;
17186 m_stgBcCells.push_back(cellId);
17187 }
17188 }
17189
17190 m_stgLocal[bcId] = noBc7909Cells > 0;
17191
17192 // if not involved, exit
17193 if(!(noBc7909Cells > 0)) return;
17194
17195#ifndef NDEBUG
17196 if(!m_stgLocal[bcId]) {
17197 cout << "RANK " << m_solver->domainId() << " has no 7909 cells, although it was entering cbcInit7909 " << endl;
17198 }
17199#endif
17200
17201 // ======================================================
17202 // 2) Create communicator for bc7909 from m_comm_bcCo[m_bcCo_comm_pointer[bcId]] communicator
17203 // ======================================================
17204 m_log << "::bcInit" + to_string(m_cutOffBndryCndIds[bcId]) + ": ... building stg communicator ..." << endl;
17205 const MPI_Comm& comm7909 = m_comm_bcCo[m_bcCo_comm_pointer[bcId]];
17206 MInt comm_size;
17207 MPI_Comm_size(comm7909, &comm_size);
17208 MInt* bc7909CellsperDomain = new MInt[comm_size];
17209 MInt* stgRanks = new MInt[comm_size];
17210 MInt myStgRank = m_solver->domainId();
17211
17212 if(noDomains() > 1) {
17213 MPI_Allgather(&noBc7909Cells, 1, MPI_INT, bc7909CellsperDomain, 1, MPI_INT, comm7909, AT_, "noBc7909Cells ",
17214 "bc7909CellsperDomain");
17215 MPI_Allgather(&myStgRank, 1, MPI_INT, stgRanks, 1, MPI_INT, comm7909, AT_, "myStgRank", "stgRanks");
17216 }
17217
17218 MInt noInvolvedRanks = 0;
17219 MInt* involvedRanks = new MInt[comm_size];
17220 for(MInt i = 0; i < comm_size; i++) {
17221 if(bc7909CellsperDomain[i]) {
17222 involvedRanks[noInvolvedRanks] = i;
17223 ++noInvolvedRanks;
17224 }
17225 }
17226
17227 MPI_Comm commStg;
17228 MPI_Group group, groupStg;
17229 MPI_Comm_group(comm7909, &group, AT_, "group");
17230 MPI_Group_incl(group, noInvolvedRanks, involvedRanks, &groupStg, AT_);
17231
17232 MPI_Comm_create(comm7909, groupStg, &commStg, AT_, "commStg");
17233 m_commStg = commStg;
17234
17235 // ======================================================
17236 // 3) Determine normal to STG boundary
17237 // Determine normal pointing from the solid wall to the domain;
17238 // ======================================================
17239
17240 // JANNIK:change this for cylinder transformation
17241
17242 // static constexpr const MFloat eps = 1e-8;
17243 std::vector<MInt> faces = {0, 0, 0, 0, 0, 0};
17244 for(MInt i = 0; i < noBc7909Cells; ++i) {
17245 const MInt cellId = stgBcCells[i];
17246
17247 for(MInt d = 0; d < 2 * nDim; d++) {
17248 if(!m_solver->a_hasNeighbor(cellId, d, false)) {
17249 ++faces[d];
17250 }
17251 }
17252
17253 // const MFloat* const n = &m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[0];
17254 // if(abs(n[0] - 1.0) < eps)
17255 // ++faces[0];
17256 // else if(abs(n[0] + 1.0) < eps)
17257 // ++faces[1];
17258 // else if(abs(n[1] - 1.0) < eps)
17259 // ++faces[2];
17260 // else if(abs(n[1] + 1.0) < eps)
17261 // ++faces[3];
17262 // else if(abs(n[2] - 1.0) < eps)
17263 // ++faces[4];
17264 // else if(abs(n[2] + 1.0) < eps)
17265 // ++faces[5];
17266 }
17267
17268 const MInt stgFaceNormalDir = std::max_element(faces.begin(), faces.end()) - faces.begin();
17269 // cerr << m_solver->domainId() << " " << stgFaceNormalDir << endl;
17270 // for(MInt d = 0; d < 2*nDim; d++){
17271 // cerr << faces[d] << endl;
17272 // }
17273 // for(MInt i = 0; i < 2 * nDim; i++) {
17274 // if(i != stgFaceNormalDir) {
17275 // if(faces[i] != 0) mTerm(1, AT_, "Something went wrong, STG plane is only allowed in one direction!");
17276 // }
17277 // }
17278
17279 MInt stgDir = stgFaceNormalDir;
17280 if(noDomains() > 1) {
17281 MPI_Allreduce(&stgFaceNormalDir, &stgDir, 1, MPI_INT, MPI_MIN, comm7909, AT_, "dirN", "stgDir");
17282 }
17283 // Sanity check: check if all ranks of STG have normal direction
17284 // if(stgFaceNormalDir != stgDir) {
17285 // mTerm(1, AT_, "Something went wrong, STG plane is only allowed in one direction!");
17286 // } else {
17287 // stgDir = stgFaceNormalDir / 2;
17288 // }
17289
17290 MInt stgWallNormalDir = 3;
17291 MInt noCoords_ = Context::propertyLength("stgWallNormalDir");
17292 for(MInt i = 0; i < noCoords_; i++) {
17293 if(m_cutOffBndryCndIds[bcId] == 7909 + i) {
17294 stgWallNormalDir = Context::getBasicProperty<MFloat>("stgWallNormalDir", AT_, i);
17295 }
17296 }
17297
17298 MInt wallDir = stgWallNormalDir / 2;
17299
17300 // cerr << stgFaceNormalDir << " " << stgDir << " " << stgWallNormalDir << " " << wallDir << endl;
17301
17302 // ======================================================
17303 // 4) Create MSTG object
17304 // ======================================================
17305 m_log << "::bcInit7909: ... creating MSTG object ..." << endl;
17306
17308 case MAIA_FINITE_VOLUME: {
17309 // TODO: don't forget to delete the objects later
17312 m_cutOffBndryCndIds[bcId],
17313 commStg,
17314 &stgBcCells[0],
17315 noBc7909Cells,
17316 stgFaceNormalDir,
17317 stgDir,
17318 stgWallNormalDir,
17319 wallDir,
17320 true);
17321
17322 m_log << "::bcInit" + to_string(m_cutOffBndryCndIds[bcId]) + ": ... creating MSTG object finished..." << endl;
17323
17324 if(m_stgBC.find(bcId) != m_stgBC.end()) {
17326 // if(globalTimeStep > m_solver->m_restartTimeStep+1){
17327 m_stgBC[bcId]->saveStg();
17328 delete m_stgBC[bcId];
17329 m_stgBC.erase(bcId);
17330 stgBC->init(0);
17331 m_stgBC.insert(std::pair<MInt, MSTG<nDim, MAIA_FINITE_VOLUME, MAIA_FINITE_VOLUME>*>(bcId, stgBC));
17332
17333 cerr << "init bc7909 " << m_solver->m_wasAdapted << " " << m_solver->m_wasBalancedZonal << endl;
17334 }
17335 } else {
17336 stgBC->init(0);
17337 m_stgBC.insert(std::pair<MInt, MSTG<nDim, MAIA_FINITE_VOLUME, MAIA_FINITE_VOLUME>*>(bcId, stgBC));
17338 }
17339
17340 break;
17341 }
17342
17343 default:
17344 mTerm(1, AT_, "Not yet implemented for solver " + m_solver->m_bc7909RANSSolverType);
17345 }
17346
17347 m_log << "::bcInit7909: ... FINISHED" << endl;
17348 }
17349}
std::vector< MInt > m_stgBcCells
MInt a_hasNeighbor(const MInt cellId, const MInt dir, const MBool assertNeighborState=true) const
Returns noNeighborIds of the cell CellId for direction dir.
Definition: fvstg.h:609
void init(MInt commStgRoot)
Definition: fvstg.cpp:505
int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm, const MString &name, const MString &varname)
same as MPI_Comm_create, but updates the number of MPI communicators
int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group *newgroup, const MString &name)
same as MPI_Group_incl
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group, const MString &name, const MString &varname)
same as MPI_Comm_group
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

◆ bcInit7809() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bcInit7809 ( MInt  )
inline

Definition at line 736 of file fvcartesianbndrycndxd.h.

736 {
737 TERMM(-1, "");
738 }

◆ bcInit7901() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bcInit7901 ( MInt  bcId)

Definition at line 16487 of file fvcartesianbndrycndxd.cpp.

16487 {
16488 TRACE();
16489
16490 m_log << endl << "::bcInit7901: ..." << endl;
16491
16492 const MFloat eps = 1e-08;
16493
16495 m_7901wallDir = 1;
16497 if(Context::propertyExists("bc7901faceNormalDir")) {
16498 m_7901faceNormalDir = Context::getSolverProperty<MInt>("bc7901faceNormalDir", m_solverId, AT_);
16499 }
16500 if(Context::propertyExists("bc7901wallDir")) {
16501 m_7901wallDir = Context::getSolverProperty<MInt>("bc7901wallDir", m_solverId, AT_);
16502 }
16503 if(Context::propertyExists("bc7901periodicDir")) {
16504 m_7901periodicDir = Context::getSolverProperty<MInt>("bc7901periodicDir", m_solverId, AT_);
16505 }
16506
16508
16509 // Prepare the exchange cells for zonal RANS-LES method
16510 MInt noBc7901Cells = 0;
16511 MInt noBc7901Locations = 0;
16512 MFloat periodicL = 0;
16513 MBool first = true;
16514
16515 // m_7901BcCells.clear();
16517
16518 // ======================================================
16519 // 1) Determine m_7901BcCells
16520 // ======================================================
16521 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16522 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16523 MFloat halfCellLength = m_solver->grid().halfCellLength(cellId);
16524 if(first) {
16525 periodicL = m_solver->a_coordinate(cellId, m_7901periodicDir);
16526 // cerr << m_solver->domainId() << " " << cellId << ": " << periodicL << endl;
16527 first = false;
16528 }
16529
16530 if(abs(m_solver->a_coordinate(cellId, m_7901periodicDir) + halfCellLength - eps - periodicL) < halfCellLength) {
16531 // m_7901BcCells.push_back(cellId);
16533 noBc7901Locations++;
16534 }
16535 noBc7901Cells++;
16536 }
16537
16538 // if not involved, exit
16539 if(noBc7901Cells == 0) return;
16540
16541 /* // ====================================================== */
16542 /* // 2) Create communicator for bc7901 from m_comm_bcCo[m_bcCo_comm_pointer[bcId]] communicator */
16543 /* // ====================================================== */
16544 /* m_log << " + ... building reconstructNut communicator ..." << endl; */
16545
16546 /* const MPI_Comm& comm7901 = m_comm_bcCo[m_bcCo_comm_pointer[bcId]]; */
16547 /* MInt comm_size; */
16548 /* MPI_Comm_size(comm7901, &comm_size); */
16549 /* MInt* rntRanks = new MInt[comm_size]; */
16550 /* MInt myRntRank = m_solver->domainId(); */
16551
16552 /* /\* MPI_Allgather(&noBc7901Cells, 1, MPI_INT, bc7901CellsperDomain, 1, MPI_INT, *\/ */
16553 /* /\* m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_, "noBc7901Cells ", "bc7901CellsperDomain" ); *\/ */
16554 /* MPI_Allgather(&myRntRank, 1, MPI_INT, rntRanks, 1, MPI_INT, */
16555 /* comm7901, AT_, "myRntRank", "rntRanks" ); */
16556
16557 /* MInt rntRoot = rntRanks[0]; */
16558 /* MInt myCommRank = 0; */
16559 /* for(MInt r = 0; r < comm_size; r++){ */
16560 /* if(myRntRank == rntRanks[r]){ */
16561 /* myCommRank = r; */
16562 /* break; */
16563 /* } */
16564 /* } */
16565
16566 /* //cerr << myRntRank << " " << myCommRank << ": " << noBc7901Locations << endl; */
16567
16568 /* // ====================================================== */
16569 /* // 3) Determine global locations in wall-normal direction for spanwise average */
16570 /* // ====================================================== */
16571 /* MInt globalNoBc7901Locations = 0; */
16572
16573 /* MPI_Allreduce(&noBc7901Locations, &globalNoBc7901Locations, 1, */
16574 /* MPI_INT, MPI_SUM, comm7901, */
16575 /* AT_, "noBc7901Locations", "globalNoBc7901Locations"); */
16576
16577 /* ScratchSpace<MFloat> globalBc7901Locations(globalNoBc7901Locations, "globalBc7901Locations", FUN_); */
16578
16579 /* ScratchSpace<MInt> recvbuf( comm_size, "recvbuf", FUN_); */
16580 /* recvbuf.fill(0); */
16581
16582 /* MPI_Gather(&noBc7901Locations, 1, MPI_INT, */
16583 /* &recvbuf[0], 1, MPI_INT, 0, comm7901 , */
16584 /* AT_, "noBc7901Locations", "recvbuf" ); */
16585
16586 /* ScratchSpace<MInt> displs( comm_size, "displspos", FUN_); */
16587 /* if(myRntRank == rntRoot){ */
16588 /* MInt offset = 0; */
16589 /* for (MInt dom = 0; dom < comm_size; dom ++){ */
16590 /* displs[dom] = offset; */
16591 /* offset += recvbuf[dom]; */
16592 /* } */
16593 /* } */
16594
16595 /* MPI_Gatherv(&m_7901wallNormalLocations[0], noBc7901Locations, MPI_DOUBLE, */
16596 /* &globalBc7901Locations[0], &recvbuf[myCommRank], &displs[myCommRank], MPI_DOUBLE, */
16597 /* 0, comm7901, AT_, "m_7901wallNormalLocations", "globalBc7901Locations" ); */
16598
16599 /* MPI_Bcast(&globalBc7901Locations[0], globalNoBc7901Locations, */
16600 /* MPI_DOUBLE, 0, comm7901, AT_, "globalBc7901Locations" ); */
16601
16602 /* m_7901globalWallNormalLocations.clear(); */
16603
16604 /* for(MInt i = 0; i < globalNoBc7901Locations; i++){ */
16605 /* MFloat L = globalBc7901Locations[i]; */
16606 /* if(std::find(m_7901globalWallNormalLocations.begin(), m_7901globalWallNormalLocations.end(), L) ==
16607 * m_7901globalWallNormalLocations.end()) { */
16608 /* m_7901globalWallNormalLocations.push_back(L); */
16609 /* } */
16610 /* } */
16611
16612 /* m_7901globalNoWallNormalLocations = (MInt)m_7901globalWallNormalLocations.size(); */
16613
16614 /* std::sort(m_7901globalWallNormalLocations.begin(), */
16615 /* m_7901globalWallNormalLocations.end()); */
16616
16617 /* /\* if(myRntRank == rntRoot){ *\/ */
16618 /* /\* cerr << "----------------------------" << endl; *\/ */
16619 /* /\* cerr << m_7901globalNoWallNormalLocations << ": " << m_7901globalNoWallNormalLocations << endl; *\/ */
16620 /* /\* for(MInt i = 0; i < m_7901globalNoWallNormalLocations; i++){ *\/ */
16621 /* /\* cerr << m_7901globalWallNormalLocations[i] << endl; *\/ */
16622 /* /\* } *\/ */
16623 /* /\* } *\/ */
16624
16625
16626 /* // ====================================================== */
16627 /* // 4) Determine local cells in periodic locations of global wall-normal locations */
16628 /* // ====================================================== */
16629 /* mAlloc(m_7901periodicLocations, m_7901globalNoWallNormalLocations, */
16630 /* "m_7901periodicLocations", FUN_); */
16631
16632 /* mAlloc(m_7901globalNoPeriodicLocations, m_7901globalNoWallNormalLocations, */
16633 /* "m_7901globalNoPeriodicLocations", 0, FUN_); */
16634
16635 /* for(MInt i = 0; i < m_7901globalNoWallNormalLocations; i++){ */
16636 /* m_7901periodicLocations[i].clear(); */
16637 /* } */
16638
16639 /* mAlloc(m_7901periodicIndex, noBc7901Cells, "m_7901periodicIndex", FUN_); */
16640
16641 /* vector<MInt> noPeriodicLocations (m_7901globalNoWallNormalLocations, F0); */
16642
16643 /* for(MInt i = 0; i < m_7901globalNoWallNormalLocations; i++){ */
16644 /* //MInt count = 0; */
16645 /* for( MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++ ){ */
16646 /* MInt cellId = m_sortedCutOffCells[bcId]->a[id]; */
16647 /* if(abs(m_solver->a_coordinate(cellId,m_7901wallDir)-m_7901globalWallNormalLocations[i]) */
16648 /* < eps){ */
16649 /* m_7901periodicIndex[id] = i; */
16650 /* if(!m_solver->a_isHalo(cellId)){ */
16651 /* m_7901periodicLocations[i].push_back(cellId); */
16652 /* ++noPeriodicLocations[i]; */
16653 /* } */
16654 /* } */
16655 /* } */
16656 /* } */
16657
16658 /* MPI_Allreduce(&noPeriodicLocations[0], &m_7901globalNoPeriodicLocations[0], */
16659 /* m_7901globalNoWallNormalLocations, MPI_INT, MPI_SUM, comm7901, AT_, */
16660 /* "7901noPeriodicLocations", "m_7901globalNoPeriodicLocations"); */
16661
16662 /* // ====================================================== */
16663 /* // 5) Init spanwise average */
16664 /* // ====================================================== */
16665 /* //mAlloc(m_7901LESAverageOld, PV->noVariables, m_7901globalNoWallNormalLocations, "m_7901LESAverageOld",
16666 * F0, FUN_); */
16667 /* mAlloc(m_7901LESAverage, PV->noVariables, m_7901globalNoWallNormalLocations, "m_7901LESAverage", F0,
16668 * FUN_); */
16669
16670
16671 //========================================================================
16672
16673 // MInt noBc7901Cells = m_sortedCutOffCells[bcId]->size();
16674
16675 /* mAlloc(m_7901LESAverage, PV->noVariables, "m_7901LESAverage", FUN_); */
16676
16677 /* for(MInt var = 0; var < PV->noVariables; var++){ */
16678 /* m_7901LESAverage[var].clear(); */
16679 /* } */
16680
16681 /* for(MInt var = 0; var < PV->noVariables; var++){ */
16682 /* for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++){ */
16683 /* MInt cellId = m_sortedCutOffCells[bcId]->a[id]; */
16684 /* m_7901LESAverage[var].push_back(m_solver->m_LESVarAverage[var][cellId]); */
16685 /* } */
16686 /* } */
16687
16688 /* m_7901StartTimeStep = Context::getSolverProperty<MInt>("7901StartTimeStep", m_solver->m_solverId, AT_,
16689 * &m_7901StartTimeStep); */
16690
16691
16692 m_log << "::bcInit7901: ... FINISHED" << endl;
16693}
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Definition: context.cpp:494
std::vector< MFloat > m_7901wallNormalLocations
constexpr GridProxy & grid() const

◆ bcInit7901() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bcInit7901 ( MInt  )
inline

Definition at line 716 of file fvcartesianbndrycndxd.h.

716 {
717 TERMM(-1, "");
718 }

◆ bcInit7902() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bcInit7902 ( MInt  bcId)

Definition at line 16697 of file fvcartesianbndrycndxd.cpp.

16697 {
16698 TRACE();
16699
16700 m_log << endl << "::bcInit7902: ..." << endl;
16701
16702 const MFloat eps = 1e-08;
16703
16705 m_7902wallDir = 1;
16707 if(Context::propertyExists("bc7902faceNormalDir")) {
16708 m_7902faceNormalDir = Context::getSolverProperty<MInt>("bc7902faceNormalDir", m_solverId, AT_);
16709 }
16710 if(Context::propertyExists("bc7902wallDir")) {
16711 m_7902wallDir = Context::getSolverProperty<MInt>("bc7902wallDir", m_solverId, AT_);
16712 }
16713 if(Context::propertyExists("bc7902periodicDir")) {
16714 m_7902periodicDir = Context::getSolverProperty<MInt>("bc7902periodicDir", m_solverId, AT_);
16715 }
16716
16718
16719 // Prepare the exchange cells for zonal RANS-LES method
16720 MInt noBc7902Cells = 0;
16721 MInt noBc7902Locations = 0;
16722 MFloat periodicL = 0;
16723 MBool first = true;
16724
16725 // m_7902BcCells.clear();
16727
16728 // ======================================================
16729 // 1) Determine m_7902BcCells
16730 // ======================================================
16731 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16732 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16733 MFloat halfCellLength = m_solver->grid().halfCellLength(cellId);
16734 if(first) {
16735 periodicL = m_solver->a_coordinate(cellId, m_7902periodicDir);
16736 // cerr << m_solver->domainId() << " " << cellId << ": " << periodicL << endl;
16737 first = false;
16738 }
16739
16740 if(abs(m_solver->a_coordinate(cellId, m_7902periodicDir) + halfCellLength - eps - periodicL) < halfCellLength) {
16741 // m_7902BcCells.push_back(cellId);
16743 noBc7902Locations++;
16744 }
16745 noBc7902Cells++;
16746 }
16747
16748 // if not involved, exit
16749 if(noBc7902Cells == 0) return;
16750
16751 // ======================================================
16752 // 2) Create communicator for bc7902 from m_comm_bcCo[m_bcCo_comm_pointer[bcId]] communicator
16753 // ======================================================
16754 m_log << " + ... building reconstructNut communicator ..." << endl;
16755
16756 const MPI_Comm& comm7902 = m_comm_bcCo[m_bcCo_comm_pointer[bcId]];
16757 MInt comm_size;
16758 MPI_Comm_size(comm7902, &comm_size);
16759 MInt* rntRanks = new MInt[comm_size];
16760 MInt myRntRank = m_solver->domainId();
16761
16762 /* MPI_Allgather(&noBc7902Cells, 1, MPI_INT, bc7902CellsperDomain, 1, MPI_INT, */
16763 /* m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_, "noBc7902Cells ", "bc7902CellsperDomain" ); */
16764 if(comm_size > 0) {
16765 MPI_Allgather(&myRntRank, 1, MPI_INT, rntRanks, 1, MPI_INT, comm7902, AT_, "myRntRank", "rntRanks");
16766 }
16767
16768 MInt rntRoot = rntRanks[0];
16769 MInt myCommRank = 0;
16770 for(MInt r = 0; r < comm_size; r++) {
16771 if(myRntRank == rntRanks[r]) {
16772 myCommRank = r;
16773 break;
16774 }
16775 }
16776
16777 m_rntRoot = rntRanks[0];
16778
16779 // ======================================================
16780 // 3) Determine global locations in wall-normal direction for spanwise average
16781 // ======================================================
16782 MInt globalNoBc7902Locations = 0;
16783
16784 if(comm_size > 0) {
16785 MPI_Allreduce(&noBc7902Locations, &globalNoBc7902Locations, 1, MPI_INT, MPI_SUM, comm7902, AT_, "noBc7902Locations",
16786 "globalNoBc7902Locations");
16787 } else {
16788 globalNoBc7902Locations = noBc7902Locations;
16789 }
16790
16791 ScratchSpace<MFloat> globalBc7902Locations(globalNoBc7902Locations, "globalBc7902Locations", FUN_);
16792
16793 if(comm_size > 0) {
16794 ScratchSpace<MInt> recvbuf(comm_size, "recvbuf", FUN_);
16795 recvbuf.fill(0);
16796
16797 MPI_Gather(&noBc7902Locations, 1, MPI_INT, &recvbuf[0], 1, MPI_INT, 0, comm7902, AT_, "noBc7902Locations",
16798 "recvbuf");
16799
16800
16801 ScratchSpace<MInt> displs(comm_size, "displspos", FUN_);
16802 if(myRntRank == rntRoot) {
16803 MInt offset = 0;
16804 for(MInt dom = 0; dom < comm_size; dom++) {
16805 displs[dom] = offset;
16806 offset += recvbuf[dom];
16807 }
16808 }
16809
16810 MPI_Gatherv(&m_7902wallNormalLocations[0], noBc7902Locations, MPI_DOUBLE, &globalBc7902Locations[0],
16811 &recvbuf[myCommRank], &displs[myCommRank], MPI_DOUBLE, 0, comm7902, AT_, "m_7902wallNormalLocations",
16812 "globalBc7902Locations");
16813
16814 MPI_Bcast(&globalBc7902Locations[0], globalNoBc7902Locations, MPI_DOUBLE, 0, comm7902, AT_,
16815 "globalBc7902Locations");
16816
16818
16819 for(MInt i = 0; i < globalNoBc7902Locations; i++) {
16820 MFloat L = globalBc7902Locations[i];
16824 }
16825 }
16826
16827 } else {
16828 for(MInt i = 0; i < globalNoBc7902Locations; i++) {
16833 }
16834 }
16835 }
16836
16838
16840
16841 // ======================================================
16842 // 4) Determine local cells in periodic locations of global wall-normal locations
16843 // ======================================================
16844 mAlloc(m_7902periodicLocations, m_7902globalNoWallNormalLocations, "m_7902periodicLocations", FUN_);
16845
16846 mAlloc(m_7902globalNoPeriodicLocations, m_7902globalNoWallNormalLocations, "m_7902globalNoPeriodicLocations", 0,
16847 FUN_);
16848
16849 for(MInt i = 0; i < m_7902globalNoWallNormalLocations; i++) {
16850 m_7902periodicLocations[i].clear();
16851 }
16852
16853 mAlloc(m_7902periodicIndex, noBc7902Cells, "m_7902periodicIndex", FUN_);
16854
16855 vector<MInt> noPeriodicLocations(m_7902globalNoWallNormalLocations, F0);
16856
16857 for(MInt i = 0; i < m_7902globalNoWallNormalLocations; i++) {
16858 // MInt count = 0;
16859 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16860 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
16863 if(!m_solver->a_isHalo(cellId)) {
16864 m_7902periodicLocations[i].push_back(cellId);
16865 ++noPeriodicLocations[i];
16866 }
16867 }
16868 }
16869 }
16870
16871 if(comm_size > 0) {
16873 MPI_INT, MPI_SUM, comm7902, AT_, "7902noPeriodicLocations", "m_7902globalNoPeriodicLocations");
16874 }
16875
16876
16877 // ======================================================
16878 // 5) Init spanwise average
16879 // ======================================================
16880 mAlloc(m_7902LESAverage, PV->noVariables, m_7902globalNoWallNormalLocations, "m_7902LESAverage", F0, FUN_);
16881
16882 for(MInt var = 0; var < PV->noVariables; var++) {
16883 for(MInt i = 0; i < m_7902globalNoWallNormalLocations; i++) {
16884 for(MInt p = 0; p < (MInt)m_7902periodicLocations[i].size(); p++) {
16887 }
16888 }
16889 }
16890
16891
16892 for(MInt var = 0; var < PV->noVariables; var++) {
16893 if(comm_size > 0) {
16894 MPI_Allreduce(MPI_IN_PLACE, m_7902LESAverage[var], m_7902globalNoWallNormalLocations, MPI_DOUBLE, MPI_SUM,
16895 m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_, "MPI_IN_PLACE", "m_7902LESAverage");
16896 }
16897 }
16898
16899 m_log << "::bcInit7902: ... FINISHED" << endl;
16900}
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
std::vector< MFloat > m_7902wallNormalLocations
std::vector< MFloat > m_7902globalWallNormalLocations
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
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
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

◆ bcInit7902() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bcInit7902 ( MInt  )
inline

Definition at line 721 of file fvcartesianbndrycndxd.h.

721 {
722 TERMM(-1, "");
723 }

◆ bcInit7905() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bcInit7905 ( MInt  bcId)

Definition at line 16905 of file fvcartesianbndrycndxd.cpp.

16905 {
16906 TRACE();
16907
16908 m_log << endl << "::bcInit7905: ..." << endl;
16909
16911 m_7902wallDir = 1;
16913 if(Context::propertyExists("bc7902faceNormalDir")) {
16914 m_7902faceNormalDir = Context::getSolverProperty<MInt>("bc7902faceNormalDir", m_solverId, AT_);
16915 }
16916 if(Context::propertyExists("bc7902wallDir")) {
16917 m_7902wallDir = Context::getSolverProperty<MInt>("bc7902wallDir", m_solverId, AT_);
16918 }
16919 if(Context::propertyExists("bc7902periodicDir")) {
16920 m_7902periodicDir = Context::getSolverProperty<MInt>("bc7902periodicDir", m_solverId, AT_);
16921 }
16922
16924
16925 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
16926 }
16927
16928 m_log << "::bcInit7902: ... FINISHED" << endl;
16929}

◆ bcInit7905() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t< hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bcInit7905 ( MInt  )
inline

Definition at line 726 of file fvcartesianbndrycndxd.h.

726 {
727 TERMM(-1, "");
728 }

◆ bcInit7909() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::bcInit7909 ( MInt  bcId)

Definition at line 16934 of file fvcartesianbndrycndxd.cpp.

16934 {
16935 TRACE();
16936
16937 m_log << endl << "::bcInit:" + to_string(m_bndryCndIds[bcId]) + " ..." << endl;
16938
16939 m_startSTGTimeStep = Context::getSolverProperty<MInt>("startSTGTimeStep", m_solverId, AT_, &m_startSTGTimeStep);
16940
16941 IF_CONSTEXPR(!isEEGas<SysEqn> && !isDetChem<SysEqn>) {
16942 /*
16943 0) Check if stg is active
16944 1) Loop over all boundary cells;
16945 Skip cells if !IsOnCurrentMGLevel;
16946 Check if cell has multiple ghost cells;
16947 Save cells participating in stg and pass them later to MSTG constructor;
16948 Mark if current rank has cells involved in current stg
16949 2) Create communicator for bc7909 from m_comm_bc[m_bc_comm_pointer[bcId]] communicator
16950 --> ranks which have no STG cells return
16951 3) Determine normal to STG boundary (by now only +x and -x allowed);
16952 Determine y-coordinate of adjacent solid wall (assume wall with constant y in spanwise
16953 direction); Determine normal pointing from the solid wall to the domain;
16954 y-coordinate of adjacent wall is the closest one, from those read in by a property;
16955 4) Create MSTG object
16956 */
16957
16958 // ======================================================
16959 // 0) Check if stg is active
16960 // ======================================================
16961 if(!m_solver->m_stgIsActive) TERMM(1, "m_stgIsActive=false but BC 7909, 7910, ... exists!");
16962
16963 // ======================================================
16964 // 1) Loop over all boundary cells;
16965 // Skip cells if !IsOnCurrentMGLevel;
16966 // Check if cell has multiple ghost cells;
16967 // Save cells participating in stg and pass them later to MSTG constructor
16968 // Mark if current rank has cells involved in current stg
16969 // ======================================================
16970 ScratchSpace<MInt> stgBcCells(m_bndryCndCells[bcId + 1] - m_bndryCndCells[bcId], AT_, "stgBcCells");
16971
16972 MInt noBc7909Cells = 0;
16973 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
16974 const MInt bndryId = m_sortedBndryCells->a[id];
16975 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
16976
16977 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
16978 if(m_bndryCells->a[bndryId].m_noSrfcs > 1) {
16979 mTerm(1, AT_, "Multiple ghost cells by now not supported by STG!");
16980 }
16981 stgBcCells[noBc7909Cells++] = cellId;
16982 m_stgBcCells.push_back(cellId);
16983 }
16984 }
16985
16986 m_stgLocal[bcId] = noBc7909Cells > 0;
16987
16988#ifndef NDEBUG
16989 if(!m_stgLocal[bcId]) {
16990 cout << "RANK " << m_solver->domainId() << " has no 7909 cells, although it was entering bcInit7909 " << endl;
16991 }
16992#endif
16993
16994 // ======================================================
16995 // 2) Create communicator for bc7909 from m_comm_bc[m_bc_comm_pointer[bcId]] communicator
16996 // ======================================================
16997 m_log << "::bcInit" + to_string(m_bndryCndIds[bcId]) + ": ... building stg communicator ..." << endl;
16998 const MPI_Comm& comm7909 = m_comm_bc[m_bc_comm_pointer[bcId]];
16999 MInt comm_size;
17000 MPI_Comm_size(comm7909, &comm_size);
17001 MInt* bc7909CellsperDomain = new MInt[comm_size];
17002 MInt* stgRanks = new MInt[comm_size];
17003 MInt myStgRank = m_solver->domainId();
17004
17005 if(noDomains() > 1) {
17006 MPI_Allgather(&noBc7909Cells, 1, MPI_INT, bc7909CellsperDomain, 1, MPI_INT, comm7909, AT_, "noBc7909Cells ",
17007 "bc7909CellsperDomain");
17008 MPI_Allgather(&myStgRank, 1, MPI_INT, stgRanks, 1, MPI_INT, comm7909, AT_, "myStgRank", "stgRanks");
17009 }
17010
17011 MInt noInvolvedRanks = 0;
17012 MInt* involvedRanks = new MInt[comm_size];
17013 for(MInt i = 0; i < comm_size; i++) {
17014 if(bc7909CellsperDomain[i]) {
17015 involvedRanks[noInvolvedRanks] = i;
17016 ++noInvolvedRanks;
17017 }
17018 }
17019
17020 MPI_Comm commStg;
17021 MPI_Group group, groupStg;
17022 MPI_Comm_group(comm7909, &group, AT_, "group");
17023 MPI_Group_incl(group, noInvolvedRanks, involvedRanks, &groupStg, AT_);
17024
17025 MPI_Comm_create(comm7909, groupStg, &commStg, AT_, "commStg");
17026 m_commStg = commStg;
17027
17028 // if not involved, exit
17029 if(!noBc7909Cells) return;
17030
17031 // ======================================================
17032 // 3) Determine normal to STG boundary
17033 // Determine normal pointing from the solid wall to the domain;
17034 // ======================================================
17035
17036 // JANNIK:change this for cylinder transformation
17037
17038 static constexpr const MFloat eps = 1e-8;
17039 std::vector<MInt> faces = {0, 0, 0, 0, 0, 0};
17040 for(MInt i = 0; i < noBc7909Cells; ++i) {
17041 const MInt cellId = stgBcCells[i];
17042 const MInt bndryId = m_solver->a_bndryId(cellId);
17043 const MFloat* const n = &m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[0];
17044 if(abs(n[0] - 1.0) < eps)
17045 ++faces[0];
17046 else if(abs(n[0] + 1.0) < eps)
17047 ++faces[1];
17048 else if(abs(n[1] - 1.0) < eps)
17049 ++faces[2];
17050 else if(abs(n[1] + 1.0) < eps)
17051 ++faces[3];
17052 else if(abs(n[2] - 1.0) < eps)
17053 ++faces[4];
17054 else if(abs(n[2] + 1.0) < eps)
17055 ++faces[5];
17056 }
17057
17058 const MInt stgFaceNormalDir = std::max_element(faces.begin(), faces.end()) - faces.begin();
17059 for(MInt i = 0; i < 2 * nDim; i++) {
17060 if(i != stgFaceNormalDir) {
17061 if(faces[i] != 0) mTerm(1, AT_, "Something went wrong, STG plane is only allowed in one direction!");
17062 }
17063 }
17064
17065 MInt stgDir = stgFaceNormalDir;
17066 if(noDomains() > 1) {
17067 MPI_Allreduce(&stgFaceNormalDir, &stgDir, 1, MPI_INT, MPI_MIN, comm7909, AT_, "dirN", "stgDir");
17068 }
17069 // Sanity check: check if all ranks of STG have normal direction
17070 if(stgFaceNormalDir != stgDir) {
17071 mTerm(1, AT_, "Something went wrong, STG plane is only allowed in one direction!");
17072 } else {
17073 stgDir = stgFaceNormalDir / 2;
17074 }
17075
17076 MInt stgWallNormalDir = 3;
17077 MInt noCoords_ = Context::propertyLength("stgWallNormalDir");
17078 for(MInt i = 0; i < noCoords_; i++) {
17079 if(m_bndryCndIds[bcId] == 7909 + i) {
17080 stgWallNormalDir = Context::getBasicProperty<MFloat>("stgWallNormalDir", AT_, i);
17081 }
17082 }
17083
17084 MInt wallDir = stgWallNormalDir / 2;
17085
17086 // ======================================================
17087 // 4) Create MSTG object
17088 // ======================================================
17089 m_log << "::bcInit7909: ... creating MSTG object ..." << endl;
17090
17092 case MAIA_FINITE_VOLUME: {
17093 // TODO labels:FV don't forget to delete the objects later
17096 m_bndryCndIds[bcId],
17097 commStg,
17098 &stgBcCells[0],
17099 noBc7909Cells,
17100 stgFaceNormalDir,
17101 stgDir,
17102 stgWallNormalDir,
17103 wallDir,
17104 false);
17105
17106 m_log << "::bcInit" + to_string(m_bndryCndIds[bcId]) + ": ... creating MSTG object finished..." << endl;
17107 stgBC->init(0);
17108 m_stgBC.insert(std::pair<MInt, MSTG<nDim, MAIA_FINITE_VOLUME, MAIA_FINITE_VOLUME>*>(bcId, stgBC));
17109 break;
17110 }
17111 case MAIA_STRUCTURED: {
17112 // TODO labels:FV don't forget to delete the objects later
17114 // stgBC = static_cast<MSTGInterface<nDim>*>(
17116 m_bndryCndIds[bcId],
17117 commStg,
17118 &stgBcCells[0],
17119 noBc7909Cells,
17120 stgFaceNormalDir,
17121 stgDir,
17122 stgWallNormalDir,
17123 wallDir,
17124 false);
17125
17126 m_log << "::bcInit" + to_string(m_bndryCndIds[bcId]) + ": ... creating MSTG object finished..." << endl;
17127 stgBCStrcd->init(0);
17128 m_stgBCStrcd.insert(std::pair<MInt, MSTG<nDim, MAIA_STRUCTURED, MAIA_FINITE_VOLUME>*>(bcId, stgBCStrcd));
17129 break;
17130 }
17131 default:
17132 mTerm(1, AT_, "Not yet implemented for solver " + m_solver->m_bc7909RANSSolverType);
17133 }
17134
17135 m_log << "::bcInit7909: ... FINISHED" << endl;
17136 }
17137}

◆ bcInit7909() [2/2]

template<MInt nDim, class SysEqn >
template<class _ = void, std::enable_if_t<!hasPV_N< SysEqn >::value, _ * > = nullptr, std::enable_if_t< nDim==2, _ * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::bcInit7909 ( MInt  )
inline

Definition at line 731 of file fvcartesianbndrycndxd.h.

731 {
732 TERMM(-1, "");
733 }

◆ bcInitCbc()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcInitCbc ( MInt  )

◆ bcNeumann()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumann ( MInt  bcId)

Definition at line 5611 of file fvcartesianbndrycndxd.cpp.

5611 {
5612 TRACE();
5613
5614#ifdef _OPENMP
5615#pragma omp parallel for
5616#endif
5617 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5618 const MInt bndryId = m_sortedBndryCells->a[id];
5619 const MInt linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
5620 const MInt cellId = (linkedCell > -1) ? linkedCell : m_bndryCells->a[bndryId].m_cellId;
5621 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
5622 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5623 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
5624 // reset the slopes
5625 for(MInt i = 0; i < nDim; i++) {
5626 m_solver->a_slope(cellId, PV->RHO, i) = F0;
5627 m_solver->a_slope(cellId, PV->P, i) = F0;
5628 }
5629
5630 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
5631 const MInt nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
5632 for(MInt i = 0; i < nDim; i++) {
5633 m_solver->a_slope(cellId, PV->RHO, i) +=
5634 m_reconstructionConstants[bndryId][nghbr * nDim + i]
5635 * (m_solver->a_pvariable(nghbrId, PV->RHO) - m_solver->a_pvariable(cellId, PV->RHO));
5636 m_solver->a_slope(cellId, PV->P, i) +=
5637 m_reconstructionConstants[bndryId][nghbr * nDim + i]
5638 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
5639 }
5640 }
5641
5642 // apply the Neumann bc
5643 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
5644 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
5645 for(MInt i = 0; i < nDim; i++) {
5646 const MFloat dx = m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i);
5647 m_solver->a_pvariable(ghostCellId, PV->RHO) += dx * m_solver->a_slope(cellId, PV->RHO, i);
5648 m_solver->a_pvariable(ghostCellId, PV->P) += dx * m_solver->a_slope(cellId, PV->P, i);
5649 }
5650 }
5651 }
5652 }
5653}

◆ bcNeumann3600()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumann3600 ( MInt  bcId)
Author
Lennart Schneiders

Definition at line 15941 of file fvcartesianbndrycndxd.cpp.

15941 {
15942 TRACE();
15943
15944#ifdef _OPENMP
15945#pragma omp parallel for
15946#endif
15947 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
15948 MInt bndryId = m_sortedBndryCells->a[id];
15949 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
15950 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
15951 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
15952 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
15953 MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
15954 m_solver->a_pvariable(ghostCellId, PV->RHO) = m_solver->a_pvariable(cellId, PV->RHO);
15955 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
15956 for(MInt s = 0; s < m_noSpecies; s++) {
15957 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
15958 }
15959 }
15960 }
15961 }
15962 }
15963}

◆ bcNeumannIso()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannIso ( MInt  bcId)

Definition at line 5659 of file fvcartesianbndrycndxd.cpp.

5659 {
5660 TRACE();
5661
5662#ifdef _OPENMP
5663#pragma omp parallel for
5664#endif
5665 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
5666 const MInt bndryId = m_sortedBndryCells->a[id];
5667 const MInt linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
5668 const MInt cellId = (linkedCell > -1) ? linkedCell : m_bndryCells->a[bndryId].m_cellId;
5669 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
5670 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
5671 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
5672 for(MInt i = 0; i < nDim; i++) {
5673 m_solver->a_slope(cellId, PV->P, i) = F0;
5674 }
5675
5676 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
5677 const MInt nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
5678 for(MInt i = 0; i < nDim; i++) {
5679 m_solver->a_slope(cellId, PV->P, i) +=
5680 m_reconstructionConstants[bndryId][nghbr * nDim + i]
5681 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
5682 }
5683 }
5684
5685 // apply the Neumann bc
5686 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
5687 MFloat dp = F0;
5688 for(MInt i = 0; i < nDim; i++) {
5689 dp += (m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i))
5690 * m_solver->a_slope(cellId, PV->P, i);
5691 }
5692 m_solver->a_pvariable(ghostCellId, PV->P) += dp;
5693
5694 // change surface density according to wall temperature and dp
5695 IF_CONSTEXPR(isDetChem<SysEqn>) {
5696 m_solver->a_pvariable(ghostCellId, PV->RHO) +=
5698 }
5699 else {
5700 m_solver->a_pvariable(ghostCellId, PV->RHO) += sysEqn().density_ES(dp, m_Bc3011WallTemperature);
5701 }
5702 }
5703 }
5704 }
5705}

◆ bcNeumannIsothermal()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannIsothermal ( MInt  bcId)
Authors
Daniel Hartmann, Stephan Schlimpert
Date
unknown, August 2011

Definition at line 13187 of file fvcartesianbndrycndxd.cpp.

13187 {
13188 TRACE();
13189
13190 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "Info: untested for 3D."); }
13191
13192 MInt nghbrId = 0;
13193 MInt cellId;
13194 MInt bndryId;
13195 MInt ghostCellId;
13196 MInt linkedCell;
13197 MFloatScratchSpace dx(nDim, AT_, "dx");
13198 MFloat thermalProfileStartFactor = m_solver->m_thermalProfileStartFactor;
13199 const MFloat TInfinity =
13201 //---
13202
13203 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13204 bndryId = m_sortedBndryCells->a[id];
13205 cellId = m_bndryCells->a[bndryId].m_cellId;
13206 linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
13207 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
13208 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13209 if(linkedCell > -1) {
13210 cellId = linkedCell;
13211 }
13212 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
13213 // reset the slopes
13214 for(MInt i = 0; i < nDim; i++) {
13215 m_solver->a_slope(cellId, PV->P, i) = F0;
13216 }
13217
13218 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
13219 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13220 for(MInt i = 0; i < nDim; i++) {
13221 m_solver->a_slope(cellId, PV->P, i) +=
13222 m_reconstructionConstants[bndryId][nghbr * nDim + i]
13223 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
13224 }
13225 }
13226
13227 // compute the offset of mp relative to the cell center
13228 for(MInt i = 0; i < nDim; i++) {
13229 dx.p[i] = m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i);
13230 }
13231
13232 // apply the Neumann bc for the pressure
13233 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13234 for(MInt i = 0; i < nDim; i++) {
13235 m_solver->a_pvariable(ghostCellId, PV->P) += dx.p[i] * m_solver->a_slope(cellId, PV->P, i);
13236 }
13237
13238 // compute the density assuming that on the boundary cell T=T_inf
13239 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13240 sysEqn().density_ES(m_solver->a_pvariable(ghostCellId, PV->P), TInfinity);
13241 }
13242 }
13243 }
13244}

◆ bcNeumannIsothermalBurntProfile()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannIsothermalBurntProfile ( MInt  bcId)
Authors
Stephan Schlimpert
Date
Januar 2012

Definition at line 13253 of file fvcartesianbndrycndxd.cpp.

13253 {
13254 TRACE();
13255
13256 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "Info: untested for 3D."); }
13257
13258 MInt nghbrId = 0;
13259 MInt cellId;
13260 MInt bndryId;
13261 MInt ghostCellId;
13262 MInt linkedCell;
13263 MFloatScratchSpace dx(nDim, AT_, "dx");
13265 MFloat xOffsetTemperatureRise = m_radiusFlameTube + F1B2 * m_solver->m_flameRadiusOffset;
13266 MFloat neg2 = -F2;
13267 MFloat thermalProfileStartFactor = m_solver->m_thermalProfileStartFactor;
13268 //---
13269
13270 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13271 bndryId = m_sortedBndryCells->a[id];
13272 cellId = m_bndryCells->a[bndryId].m_cellId;
13273 linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
13274 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
13275 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13276 if(linkedCell > -1) {
13277 cellId = linkedCell;
13278 }
13279 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
13280 // reset the slopes
13281 for(MInt i = 0; i < nDim; i++) {
13282 m_solver->a_slope(cellId, PV->P, i) = F0;
13283 }
13284
13285 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
13286 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13287 for(MInt i = 0; i < nDim; i++) {
13288 m_solver->a_slope(cellId, PV->P, i) +=
13289 m_reconstructionConstants[bndryId][nghbr * nDim + i]
13290 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
13291 }
13292 }
13293
13294 // compute the offset of mp relative to the cell center
13295 for(MInt i = 0; i < nDim; i++) {
13296 dx.p[i] = m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i);
13297 }
13298
13299 // apply the Neumann bc for the pressure
13300 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13301 for(MInt i = 0; i < nDim; i++) {
13302 m_solver->a_pvariable(ghostCellId, PV->P) += dx.p[i] * m_solver->a_slope(cellId, PV->P, i);
13303 }
13304
13305 MFloat temperatureProfile;
13306 if(m_solver->a_coordinate(cellId, 0) > F0) {
13307 temperatureProfile =
13308 (m_solver->m_temperatureFlameTube * thermalProfileStartFactor
13310 - m_solver->m_temperatureFlameTube * thermalProfileStartFactor)
13311 * (tanh(5.0) - F1B2 * tanh(5.0)
13312 + F1B2
13313 * tanh((F2 * (m_solver->a_coordinate(cellId, 0) - xOffsetTemperatureRise) - deltaX) * 5.0
13314 / deltaX)));
13315 } else {
13316 temperatureProfile =
13317 (m_solver->m_temperatureFlameTube * thermalProfileStartFactor
13319 - m_solver->m_temperatureFlameTube * thermalProfileStartFactor)
13320 * (tanh(5.0) - F1B2 * tanh(5.0)
13321 + F1B2
13322 * tanh((neg2 * (m_solver->a_coordinate(cellId, 0) + xOffsetTemperatureRise) - deltaX)
13323 * 5.0 / deltaX)));
13324 }
13325
13326 // compute the density assuming that on the boundary cell T=T_inf
13327 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13328 sysEqn().density_ES(m_solver->a_pvariable(ghostCellId, PV->P), temperatureProfile);
13329 }
13330 }
13331 }
13332}

◆ bcNeumannIsothermalBurntProfileH()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannIsothermalBurntProfileH ( MInt  bcId)
Authors
Stephan Schlimpert
Date
Januar 2012

Definition at line 13341 of file fvcartesianbndrycndxd.cpp.

13341 {
13342 TRACE();
13343
13344 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "Info: untested for 3D."); }
13345
13346 MInt nghbrId = 0;
13347 MInt cellId;
13348 MInt bndryId;
13349 MInt ghostCellId;
13350 MInt linkedCell;
13351 MFloatScratchSpace dx(nDim, AT_, "dx");
13353 MFloat xOffsetTemperatureRise = m_radiusFlameTube + F1B2 * m_solver->m_flameRadiusOffset;
13354 MFloat thermalProfileStartFactor = m_solver->m_thermalProfileStartFactor;
13356 MFloat tempBurnt =
13358 MFloat neg2 = -F2;
13359 //---
13360
13361 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13362 bndryId = m_sortedBndryCells->a[id];
13363 cellId = m_bndryCells->a[bndryId].m_cellId;
13364 linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
13365 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
13366 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13367 if(linkedCell > -1) {
13368 cellId = linkedCell;
13369 }
13370 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
13371 // reset the slopes
13372 for(MInt i = 0; i < nDim; i++) {
13373 m_solver->a_slope(cellId, PV->P, i) = F0;
13374 }
13375
13376 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
13377 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13378 for(MInt i = 0; i < nDim; i++) {
13379 m_solver->a_slope(cellId, PV->P, i) +=
13380 m_reconstructionConstants[bndryId][nghbr * nDim + i]
13381 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
13382 }
13383 }
13384
13385 // compute the offset of mp relative to the cell center
13386 for(MInt i = 0; i < nDim; i++) {
13387 dx.p[i] = m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i);
13388 }
13389
13390 // apply the Neumann bc for the pressure
13391 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13392 for(MInt i = 0; i < nDim; i++) {
13393 m_solver->a_pvariable(ghostCellId, PV->P) += dx.p[i] * m_solver->a_slope(cellId, PV->P, i);
13394 }
13395
13396 MFloat temperatureProfile;
13397 if(m_solver->a_coordinate(cellId, 0) > F0) {
13398 temperatureProfile =
13399 tempHalfBurnt
13400 + (tempBurnt - tempHalfBurnt)
13401 * (tanh(5.0) - F1B2 * tanh(5.0)
13402 + F1B2
13403 * tanh((F2 * (m_solver->a_coordinate(cellId, 0) - xOffsetTemperatureRise) - deltaX) * 5.0
13404 / deltaX));
13405 } else {
13406 temperatureProfile =
13407 tempHalfBurnt
13408 + (tempBurnt - tempHalfBurnt)
13409 * (tanh(5.0) - F1B2 * tanh(5.0)
13410 + F1B2
13411 * tanh((neg2 * (m_solver->a_coordinate(cellId, 0) + xOffsetTemperatureRise) - deltaX) * 5.0
13412 / deltaX));
13413 }
13414
13415 // compute the density assuming that on the boundary cell T=T_inf
13416 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13417 sysEqn().density_ES(m_solver->a_pvariable(ghostCellId, PV->P), temperatureProfile);
13418 }
13419 }
13420 }
13421}

◆ bcNeumannIsothermalUnburnt()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannIsothermalUnburnt ( MInt  bcId)
Authors
Stephan Schlimpert
Date
November 2011

Definition at line 13577 of file fvcartesianbndrycndxd.cpp.

13577 {
13578 TRACE();
13579
13580 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "Info: untested for 3D."); }
13581
13582 MInt nghbrId = 0;
13583 MInt cellId;
13584 MInt bndryId;
13585 MInt ghostCellId;
13586 MInt linkedCell;
13587 MFloatScratchSpace dx(nDim, AT_, "dx");
13588 const MFloat TInfinityUnburnt = m_solver->m_temperatureFlameTube;
13589 //---
13590
13591 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13592 bndryId = m_sortedBndryCells->a[id];
13593 cellId = m_bndryCells->a[bndryId].m_cellId;
13594 linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
13595 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
13596 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13597 if(linkedCell > -1) {
13598 cellId = linkedCell;
13599 }
13600 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
13601 // reset the slopes
13602 for(MInt i = 0; i < nDim; i++) {
13603 m_solver->a_slope(cellId, PV->P, i) = F0;
13604 }
13605
13606 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
13607 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13608 for(MInt i = 0; i < nDim; i++) {
13609 m_solver->a_slope(cellId, PV->P, i) +=
13610 m_reconstructionConstants[bndryId][nghbr * nDim + i]
13611 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
13612 }
13613 }
13614
13615 // compute the offset of mp relative to the cell center
13616 for(MInt i = 0; i < nDim; i++) {
13617 dx.p[i] = m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i);
13618 }
13619
13620 // apply the Neumann bc for the pressure
13621 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13622 for(MInt i = 0; i < nDim; i++) {
13623 m_solver->a_pvariable(ghostCellId, PV->P) += dx.p[i] * m_solver->a_slope(cellId, PV->P, i);
13624 }
13625
13626 // compute the density assuming that on the boundary cell T=T_inf
13627 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13628 sysEqn().density_ES(m_solver->a_pvariable(ghostCellId, PV->P), TInfinityUnburnt);
13629 }
13630 }
13631 }
13632}

◆ bcNeumannIsothermalUnburntProfile()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannIsothermalUnburntProfile ( MInt  bcId)
Authors
Stephan Schlimpert
Date
Januar 2012

Definition at line 13430 of file fvcartesianbndrycndxd.cpp.

13430 {
13431 TRACE();
13432
13433 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "Info: untested for 3D."); }
13434
13435 MInt nghbrId = 0;
13436 MInt cellId;
13437 MInt bndryId;
13438 MInt ghostCellId;
13439 MInt linkedCell;
13440 MFloatScratchSpace dx(nDim, AT_, "dx");
13442 MFloat yOffsetTemperatureRise = m_solver->m_yOffsetFlameTube - deltaY;
13443 //---
13444
13445 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13446 bndryId = m_sortedBndryCells->a[id];
13447 cellId = m_bndryCells->a[bndryId].m_cellId;
13448 linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
13449 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
13450 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13451 if(linkedCell > -1) {
13452 cellId = linkedCell;
13453 }
13454 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
13455 // reset the slopes
13456 for(MInt i = 0; i < nDim; i++) {
13457 m_solver->a_slope(cellId, PV->P, i) = F0;
13458 }
13459
13460 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
13461 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13462 for(MInt i = 0; i < nDim; i++) {
13463 m_solver->a_slope(cellId, PV->P, i) +=
13464 m_reconstructionConstants[bndryId][nghbr * nDim + i]
13465 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
13466 }
13467 }
13468
13469 // compute the offset of mp relative to the cell center
13470 for(MInt i = 0; i < nDim; i++) {
13471 dx.p[i] = m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i);
13472 }
13473
13474 // apply the Neumann bc for the pressure
13475 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13476 for(MInt i = 0; i < nDim; i++) {
13477 m_solver->a_pvariable(ghostCellId, PV->P) += dx.p[i] * m_solver->a_slope(cellId, PV->P, i);
13478 }
13479
13480 const MFloat temperatureProfile =
13483 * (tanh(5.0) - F1B2 * tanh(5.0)
13484 + F1B2
13485 * tanh((F2 * (m_solver->a_coordinate(cellId, 1) - yOffsetTemperatureRise) - deltaY) * 5.0
13486 / deltaY))));
13487
13488 // compute the density assuming that on the boundary cell T=T_inf
13489 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13490 sysEqn().density_ES(m_solver->a_pvariable(ghostCellId, PV->P), temperatureProfile);
13491 }
13492 }
13493 }
13494}

◆ bcNeumannIsothermalUnburntProfileH()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannIsothermalUnburntProfileH ( MInt  bcId)
Authors
Stephan Schlimpert
Date
Januar 2012

Definition at line 13503 of file fvcartesianbndrycndxd.cpp.

13503 {
13504 TRACE();
13505
13506 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "Info: untested for 3D."); }
13507
13508 MInt nghbrId = 0;
13509 MInt cellId;
13510 MInt bndryId;
13511 MInt ghostCellId;
13512 MInt linkedCell;
13513 MFloatScratchSpace dx(nDim, AT_, "dx");
13515 MFloat yOffsetTemperatureRise = m_solver->m_yOffsetFlameTube - deltaY;
13516 //---
13517
13518 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13519 bndryId = m_sortedBndryCells->a[id];
13520 cellId = m_bndryCells->a[bndryId].m_cellId;
13521 linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
13522 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
13523 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13524 if(linkedCell > -1) {
13525 cellId = linkedCell;
13526 }
13527 if(linkedCell == -1 || m_solver->a_bndryId(linkedCell) == -1) {
13528 // reset the slopes
13529 for(MInt i = 0; i < nDim; i++) {
13530 m_solver->a_slope(cellId, PV->P, i) = F0;
13531 }
13532
13533 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
13534 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13535 for(MInt i = 0; i < nDim; i++) {
13536 m_solver->a_slope(cellId, PV->P, i) +=
13537 m_reconstructionConstants[bndryId][nghbr * nDim + i]
13538 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
13539 }
13540 }
13541
13542 // compute the offset of mp relative to the cell center
13543 for(MInt i = 0; i < nDim; i++) {
13544 dx.p[i] = m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i);
13545 }
13546
13547 // apply the Neumann bc for the pressure
13548 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
13549 for(MInt i = 0; i < nDim; i++) {
13550 m_solver->a_pvariable(ghostCellId, PV->P) += dx.p[i] * m_solver->a_slope(cellId, PV->P, i);
13551 }
13552
13553
13554 const MFloat temperatureProfile =
13557 * (tanh(5.0) - F1B2 * tanh(5.0)
13558 + F1B2
13559 * tanh((F2 * (m_solver->a_coordinate(cellId, 1) - yOffsetTemperatureRise) - deltaY) * 5.0
13560 / deltaY)));
13561
13562 // compute the density assuming that on the boundary cell T=T_inf
13563 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13564 sysEqn().density_ES(m_solver->a_pvariable(ghostCellId, PV->P), temperatureProfile);
13565 }
13566 }
13567 }
13568}

◆ bcNeumannMb()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::bcNeumannMb ( MInt  bcId)
Author
Lennart Schneiders

Definition at line 13638 of file fvcartesianbndrycndxd.cpp.

13638 {
13639 TRACE();
13640
13641 //---
13642
13643 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
13644 const MInt bndryId = m_sortedBndryCells->a[id];
13645 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
13646
13647 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13648 const MBool gapCell = m_solver->a_hasProperty(cellId, SolverCell::IsGapCell);
13649
13650 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
13651 MInt k = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0];
13652 ASSERT(k > -1 && k < m_solver->m_noEmbeddedBodies + m_solver->m_noPeriodicGhostBodies, "");
13654 mTerm(1, AT_, "Invalid body id: " + to_string(k));
13655 }
13656
13657 MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
13658 MFloat normal[nDim];
13659 MFloat delta[3] = {F0, F0, F0};
13660 MFloat dr[3] = {F0, F0, F0};
13661 MFloat dw[3] = {F0, F0, F0};
13662 MFloat dg[3] = {F0, F0, F0};
13663 MFloat du[3] = {F0, F0, F0};
13664 MFloat dv[3] = {F0, F0, F0};
13665 MFloat dn = F0;
13666 for(MInt i = 0; i < nDim; i++) {
13667 normal[i] = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
13668 dr[i] = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i] - m_solver->m_bodyCenter[k * nDim + i];
13669 du[i] = m_solver->m_bodyAcceleration[k * nDim + i];
13670 dv[i] = m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->VV[i]]
13671 - m_solver->m_bodyVelocity[k * nDim + i];
13672 dn += (m_solver->a_coordinate(cellId, i) - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i])
13673 * normal[i];
13674
13675 if(gapCell && m_solver->m_gapInitMethod > 0) {
13676 du[i] = 0;
13677 dv[i] = 0;
13678 }
13679 }
13680
13681 for(MInt i = 0; i < 3; i++) {
13682 dw[i] = m_solver->m_bodyAngularAcceleration[k * 3 + i];
13683 dg[i] = m_solver->m_bodyAngularVelocity[k * 3 + i];
13684 }
13685 // assemble material acceleration
13686 delta[0] = du[0] + dw[1] * dr[2] - dw[2] * dr[1] + dg[1] * dv[2] - dg[2] * dv[1];
13687 delta[1] = du[1] + dw[2] * dr[0] - dw[0] * dr[2] + dg[2] * dv[0] - dg[0] * dv[2];
13688 delta[2] = du[2] + dw[0] * dr[1] - dw[1] * dr[0] + dg[0] * dv[1] - dg[1] * dv[0];
13689
13690
13691 MFloat an = F0;
13692 for(MInt i = 0; i < nDim; i++) {
13693 an += normal[i] * delta[i];
13694 }
13695
13696 MFloat surfTemp =
13697 sysEqn().temperature_ES(m_solver->a_pvariable(cellId, PV->RHO), m_solver->a_pvariable(cellId, PV->P));
13698 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == 3008
13699 || m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == 3010) {
13701 // Timw engine specific
13702 // labels:FV Tina-engine liner-Temperatur hack:
13703 if(m_solver->m_engineSetup && m_solver->m_noGapRegions >= 1 && k == 0) {
13704 if(m_solver->a_coordinate(cellId, 1) > 0) {
13705 surfTemp = 1;
13706 } else if(m_solver->a_coordinate(cellId, 1) > -0.1 && m_solver->a_coordinate(cellId, 1) < 0) {
13707 // linear interpolation between T_infinity and surface temperature
13708 surfTemp = 1 + m_solver->a_coordinate(cellId, 1) / -0.1 * (surfTemp - 1);
13709 }
13710 }
13711 }
13712
13713 const MFloat beta = sysEqn().gamma_Ref() * an / surfTemp;
13714 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_robinFactor = beta;
13715
13716 if(fabs(F1 - beta * dn) < 1e-3) {
13717 cerr << "Warning: small denom Robin BC: " << k << " " << m_solver->m_internalBodyId[k] << " " << beta << " "
13718 << dn << " " << an << " " << surfTemp << " " << srfc << endl;
13719 }
13720 const MFloat fac = (F1 + beta * dn) / (F1 - beta * dn);
13721
13722 m_solver->a_pvariable(ghostCellId, PV->P) = fac * m_solver->a_pvariable(cellId, PV->P);
13723 m_solver->a_pvariable(ghostCellId, PV->RHO) = fac * m_solver->a_pvariable(cellId, PV->RHO);
13724
13725 // JANNIK: should this be here?
13726 for(MInt s = 0; s < m_noSpecies; s++) {
13727 m_solver->a_pvariable(ghostCellId, PV->Y[s]) = m_solver->a_pvariable(cellId, PV->Y[s]);
13728 }
13729
13730 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
13731 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
13732 m_solver->a_pvariable(ghostCellId, PV->NN[r]) = -m_solver->a_pvariable(cellId, PV->NN[r]);
13733 }
13734 }
13735
13736 MFloat pressure = F1B2 * (m_solver->a_pvariable(cellId, PV->P) + m_solver->a_pvariable(ghostCellId, PV->P));
13737 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] = pressure;
13738
13739 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == 3007) {
13740 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] =
13741 m_solver->a_pvariable(cellId, PV->RHO)
13742 * pow(pressure / m_solver->a_pvariable(cellId, PV->P), sysEqn().gamma_Ref());
13743 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13744 F2 * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO]
13745 - m_solver->a_pvariable(cellId, PV->RHO);
13746 } else if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == 3008
13747 || m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == 3010) {
13748 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] = sysEqn().density_ES(pressure, surfTemp);
13749 m_solver->a_pvariable(ghostCellId, PV->RHO) =
13750 F2 * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO]
13751 - m_solver->a_pvariable(cellId, PV->RHO);
13752 } else {
13753 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] =
13754 F1B2 * (m_solver->a_pvariable(cellId, PV->RHO) + m_solver->a_pvariable(ghostCellId, PV->RHO));
13755 }
13756 }
13757 }
13758 }
13759}

◆ calcBesselFractions()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::calcBesselFractions ( const MFloat  xkxmot,
const MFloat  rkr,
const MFloat  dphi,
MFloat trig_P_RHO_U,
MFloat trig_V_W 
)

Definition at line 7635 of file fvcartesianbndrycndxd.cpp.

7636 {
7637 TRACE();
7638 const MFloat phiMax = xkxmot + rkr;
7639 const MFloat phiMin = xkxmot - rkr;
7640 const MFloat PIB2MinusDdhi = PIB2 - dphi;
7641 // numerics
7642 const MFloat DPSI = PI / 180; // resolution in circumferential direction
7643 const MInt MINN = 10; // minimal number of integration steps
7644 const MFloat INTDEC = PIB2; // do i calc (f) or (bessel - f~)
7645 if(phiMin >= PIB2 || phiMax <= PIB2MinusDdhi) {
7646 // rkr*cos(\hat{psi}) is not inside the kxmowt range
7647 trig_V_W = F0;
7648 trig_P_RHO_U = F0;
7649 } else if(phiMin >= PIB2MinusDdhi && phiMax <= PIB2) {
7650 // rkr*cos(\hat{psi}) is completely inside the kxmowt range
7651 trig_V_W = cos(xkxmot + PIB2) * maia::math::besselJ1(rkr);
7652 trig_P_RHO_U = cos(xkxmot) * maia::math::besselJ0(rkr);
7653 } else if(phiMin < PIB2MinusDdhi && phiMax > PIB2) {
7654 // rkr*cos(\hat{psi}) extends both limits of the kxmowt range
7655 const MFloat psihatmax = acos((PIB2 - xkxmot) / rkr);
7656 const MFloat psihatmin = acos((PIB2MinusDdhi - xkxmot) / rkr);
7657 if(psihatmin - psihatmax < INTDEC) {
7658 // from first intersection at psihatmax to second intersection at psihatmin
7659 const MInt noSeg = mMax((MInt)ceil((psihatmin - psihatmax) / DPSI), MINN);
7660 const MFloat dpsi = (psihatmin - psihatmax) / noSeg;
7661 MFloat firstValB1 = F0;
7662 MFloat resultB1 = F0;
7663 MFloat firstValB2 = F0;
7664 MFloat resultB2 = F0;
7665 for(MInt cnt = 1; cnt <= noSeg; cnt++) {
7666 const MFloat secondValB1 = maia::math::lincos(xkxmot + rkr * maia::math::lincos(psihatmax + cnt * dpsi));
7667 const MFloat secondValB2 = maia::math::lincos(psihatmax + cnt * dpsi) * secondValB1;
7668 resultB1 += F1B2 * (firstValB1 + secondValB1) * dpsi;
7669 resultB2 += F1B2 * (firstValB2 + secondValB2) * dpsi;
7670 firstValB1 = secondValB1;
7671 firstValB2 = secondValB2;
7672 }
7673 trig_P_RHO_U = resultB1 / PI;
7674 trig_V_W = resultB2 / PI;
7675 } else {
7676 // from zero to first intersection at psihatmax
7677 const MInt noSeg1 = mMax((MInt)ceil(psihatmax / DPSI), MINN);
7678 const MFloat dpsi1 = psihatmax / noSeg1;
7679 MFloat firstValB1 = maia::math::lincos(phiMax);
7680 MFloat firstValB2 = maia::math::lincos(phiMax);
7681 MFloat resultB1 = F0;
7682 MFloat resultB2 = F0;
7683 for(MInt cnt = 1; cnt <= noSeg1; cnt++) {
7684 const MFloat secondValB1 = maia::math::lincos(xkxmot + rkr * maia::math::lincos(cnt * dpsi1));
7685 const MFloat secondValB2 = maia::math::lincos(cnt * dpsi1) * secondValB1;
7686 resultB1 += F1B2 * (firstValB1 + secondValB1) * dpsi1;
7687 resultB2 += F1B2 * (firstValB2 + secondValB2) * dpsi1;
7688 firstValB1 = secondValB1;
7689 firstValB2 = secondValB2;
7690 }
7691 // from second intersection at psihatmin to PI
7692 const MInt noSeg2 = mMax((MInt)ceil((PI - psihatmin) / DPSI), MINN);
7693 const MFloat dpsi2 = (PI - psihatmin) / noSeg2;
7694 firstValB1 = F0;
7695 firstValB2 = F0;
7696 for(MInt cnt = 1; cnt <= noSeg2; cnt++) {
7697 const MFloat secondValB1 = maia::math::lincos(xkxmot + rkr * maia::math::lincos(psihatmin + cnt * dpsi2));
7698 const MFloat secondValB2 = maia::math::lincos(psihatmin + cnt * dpsi2) * secondValB1;
7699 resultB1 += F1B2 * (firstValB1 + secondValB1) * dpsi2;
7700 resultB2 += F1B2 * (firstValB2 + secondValB2) * dpsi2;
7701 firstValB1 = secondValB1;
7702 firstValB2 = secondValB2;
7703 }
7704 trig_P_RHO_U = cos(xkxmot) * maia::math::besselJ0(rkr) - resultB1 / PI;
7705 trig_V_W = cos(xkxmot + PIB2) * maia::math::besselJ1(rkr) - resultB2 / PI;
7706 }
7707 } else {
7708 // rkr*cos(\hat{psi}) extends at least one limit of the kxmowt range, the other one might be on the limit
7709 const MFloat psihatintersec = acos((((phiMax > PIB2) ? PIB2 : PIB2MinusDdhi) - xkxmot) / rkr);
7710 if(psihatintersec < INTDEC) {
7711 // from zero to intersection
7712 const MInt noSeg = mMax((MInt)ceil(psihatintersec / DPSI), MINN);
7713 const MFloat dpsi = psihatintersec / noSeg;
7714 MFloat firstValB1 = maia::math::lincos(phiMax);
7715 MFloat firstValB2 = maia::math::lincos(phiMax);
7716 MFloat resultB1 = F0;
7717 MFloat resultB2 = F0;
7718 for(MInt cnt = 1; cnt <= noSeg; cnt++) {
7719 const MFloat secondValB1 = maia::math::lincos(xkxmot + rkr * maia::math::lincos(cnt * dpsi));
7720 const MFloat secondValB2 = maia::math::lincos(cnt * dpsi) * secondValB1;
7721 resultB1 += F1B2 * (firstValB1 + secondValB1) * dpsi;
7722 resultB2 += F1B2 * (firstValB2 + secondValB2) * dpsi;
7723 firstValB1 = secondValB1;
7724 firstValB2 = secondValB2;
7725 }
7726 if(phiMax > PIB2) {
7727 trig_P_RHO_U = cos(xkxmot) * maia::math::besselJ0(rkr) - resultB1 / PI;
7728 trig_V_W = cos(xkxmot + PIB2) * maia::math::besselJ1(rkr) - resultB2 / PI;
7729 } else {
7730 trig_P_RHO_U = resultB1 / PI;
7731 trig_V_W = resultB2 / PI;
7732 }
7733 } else {
7734 // from intersection to PI
7735 const MInt noSeg = mMax((MInt)ceil((PI - psihatintersec) / DPSI), MINN);
7736 const MFloat dpsi = (PI - psihatintersec) / noSeg;
7737 MFloat firstValB1 = F0;
7738 MFloat firstValB2 = F0;
7739 MFloat resultB1 = F0;
7740 MFloat resultB2 = F0;
7741 for(MInt cnt = 1; cnt <= noSeg; cnt++) {
7742 const MFloat secondValB1 = maia::math::lincos(xkxmot + rkr * maia::math::lincos(psihatintersec + cnt * dpsi));
7743 const MFloat secondValB2 = maia::math::lincos(psihatintersec + cnt * dpsi) * secondValB1;
7744 resultB1 += F1B2 * (firstValB1 + secondValB1) * dpsi;
7745 resultB2 += F1B2 * (firstValB2 + secondValB2) * dpsi;
7746 firstValB1 = secondValB1;
7747 firstValB2 = secondValB2;
7748 }
7749 if(phiMax > PIB2) {
7750 trig_P_RHO_U = resultB1 / PI;
7751 trig_V_W = resultB2 / PI;
7752 } else {
7753 trig_P_RHO_U = cos(xkxmot) * maia::math::besselJ0(rkr) - resultB1 / PI;
7754 trig_V_W = cos(xkxmot + PIB2) * maia::math::besselJ1(rkr) - resultB2 / PI;
7755 }
7756 }
7757 }
7758}
MFloat besselJ0(MFloat x)
Definition: maiamath.h:343
MFloat besselJ1(MFloat x)
Definition: maiamath.h:380
MFloat lincos(MFloat arg)
Definition: maiamath.h:426

◆ cbc1091()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091 ( MInt  bcId)

Subsonic partially reflecting characteristic inflow condition - cut off
p0,T0 is prescribed, incl. shear and transverse terms

Definition at line 17891 of file fvcartesianbndrycndxd.cpp.

17891 {
17892 TRACE();
17893
17894 if(m_sortedCutOffCells[bcId]->size() == 0) {
17895 return;
17896 }
17897
17898 MInt cbcId = m_cbcBndryCndIds[bcId];
17899
17900 MInt dirN = m_cbcDir[cbcId][0];
17901 MInt dimN = m_cbcDir[cbcId][1];
17902 MInt dimT1 = m_cbcDir[cbcId][2];
17903 MInt dimT2 = m_cbcDir[cbcId][nDim];
17904
17905 MInt last = nDim + 1;
17906
17907 // Allocate memory
17908 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
17909 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
17910 MFloatScratchSpace gradP(nDim, AT_, "gradP");
17911 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
17912 gradY.fill(F0);
17913
17914 MFloatScratchSpace L(PV->noVariables, AT_, "L");
17915 MFloatScratchSpace T(PV->noVariables, AT_, "T");
17916 MFloatScratchSpace V(PV->noVariables, AT_, "V");
17917 MFloatScratchSpace K(PV->noVariables, AT_, "K");
17918
17919 MFloat mach[2] = {F0, F0};
17920 cbcMachCo(bcId, mach);
17921 MFloat meanM = mach[0];
17922 MFloat maxM = mach[1];
17923
17924 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
17925 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
17926 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
17927 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
17928 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
17929
17930 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
17931 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
17932
17933 MFloat T_target = sysEqn().temperature_IR(meanM);
17934 MFloat p_Target = sysEqn().pressure_IR(T_target);
17935 MFloat y_target = F1;
17936
17937 IF_CONSTEXPR(isDetChem<SysEqn>) {
17938 T_target = m_solver->m_detChem.infTemperature;
17939 p_Target = m_solver->m_detChem.infPressure;
17940 }
17941
17942 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
17943 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
17944
17945 if(m_solver->a_isHalo(cellId)) continue;
17946 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
17947 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
17948
17949 MInt bndryId = m_solver->a_bndryId(cellId);
17950 if(bndryId > -1) {
17951 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
17952 }
17953
17954 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
17955 V.fill(F0);
17956 if(m_cbcViscous) {
17957 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
17958 // BC specific
17959 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
17960 IF_CONSTEXPR(nDim == 3) gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0;
17961 // END BC specific
17962 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
17963 &cutOffStencilCellIds[0], &V[0]);
17964 }
17965
17966 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
17967 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
17968 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
17969
17970 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
17971 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
17972 const MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
17973 MFloat temp = sysEqn().temperature_ES(rho, p);
17974
17975 IF_CONSTEXPR(isDetChem<SysEqn>) {
17976 MFloat fMeanMolarWeight = F0;
17977 for(MUint s = 0; s < PV->m_noSpecies; s++) {
17978 fMeanMolarWeight += m_solver->a_pvariable(cellId, PV->Y[s]) * m_solver->m_fMolarMass[s];
17979 }
17980 MFloat meanMolarWeight = F1 / fMeanMolarWeight;
17981 temp = p / rho * meanMolarWeight / m_solver->m_gasConstant;
17982 }
17983
17984 const MFloat a = sysEqn().speedOfSound(rho, p);
17985
17986 if(dirN % 2 == 0) {
17987 L[0] = K[0] * (p - p_Target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
17988 } else {
17989 L[last] = K[last] * (p - p_Target) + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
17990 }
17991
17992 L[1] = K[1] * (temp - T_target) + (a * a * T[0] - T[last]) - V[last];
17993
17994 L[2] = K[2] * ut1 + T[2] + V[2];
17995
17996 IF_CONSTEXPR(nDim == 3) {
17997 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
17998 L[3] = K[3] * ut2 + T[3] + V[3];
17999 }
18000 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
18001 MFloat y = m_solver->a_pvariable(cellId, sysEqn().PV->Y[s]);
18002 L[last + 1 + s] = K[last + 1 + s] * (y - y_target);
18003 }
18004
18005 IF_CONSTEXPR(isDetChem<SysEqn>) {
18006 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
18007 MFloat y = m_solver->a_pvariable(cellId, sysEqn().PV->Y[s]);
18008 L[last + 1 + s] = K[last + 1 + s] * (y - m_solver->m_YInfinity[s]);
18009 }
18010 }
18011
18012 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
18013 }
18014}
void cbcRHS(MInt, MInt, MFloat *, MFloat *, MFloat *)
Calculates the right hand side.
void cbcViscousTerms(MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MInt *, MFloat *)
Calculates the outgoing viscous terms V.
void cbcGradients(MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *)
Calculates the gradients of the cbcCell.
void cbcGradientsViscous(MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MInt *)
Calculates the viscous gradients of the cbcCell.
void cbcTransversalTerms(MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
Calculates the transversal correction terms T.
void cbcOutgoingAmplitudeVariation(MInt, MInt, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
Calculates the outgoing terms wave amplitude variation L.
void cbcDampingInflow(MInt, MInt, MFloat, MFloat *, MString)
Calculates the inflow damping terms.
void cbcMachCo(MInt, MFloat *)
Returns the mean and maximum Mach number of the cut off cells.
void cbcTauQ(MInt, MFloat *, MFloat *, MInt *)
Calculates the stress tensor tau and the heat flux q and the mean velocity on the construction stenci...
struct FvCartesianSolverXD::@9 m_detChem
constexpr bool isDetChem
Checks if the SysEqn is SysEqnDetChem.
uint32_t MUint
Definition: maiatypes.h:63
define array structures

◆ cbc1091a()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091a ( MInt  bcId)

Characteristic boundary condition. Inflow. Prescribed: T, un, ut1, ut2. Partially Refelecting.

Author
Thomas Hoesgen, Soeren Mehnert
Date
May 2020

Definition at line 20457 of file fvcartesianbndrycndxd.cpp.

20457 {
20458 TRACE();
20459
20460 if(m_sortedCutOffCells[bcId]->size() == 0) {
20461 return;
20462 }
20463
20464 MInt cbcId = m_cbcBndryCndIds[bcId];
20465
20466 MInt dirN = m_cbcDir[cbcId][0];
20467 MInt dimN = m_cbcDir[cbcId][1];
20468 MInt dimT1 = m_cbcDir[cbcId][2];
20469 MInt dimT2 = m_cbcDir[cbcId][nDim];
20470
20471 MInt last = nDim + 1;
20472
20473 // Allocate meomry
20474 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
20475 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
20476 MFloatScratchSpace gradP(nDim, AT_, "gradP");
20477 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
20478 gradY.fill(F0);
20479
20480 MFloatScratchSpace L(PV->noVariables, AT_, "L");
20481 MFloatScratchSpace T(PV->noVariables, AT_, "T");
20482 MFloatScratchSpace V(PV->noVariables, AT_, "V");
20483 MFloatScratchSpace K(PV->noVariables, AT_, "K");
20484
20485 MFloat mach[2] = {F0, F0};
20486 cbcMachCo(bcId, mach);
20487 MFloat meanM = mach[0];
20488 MFloat maxM = mach[1];
20489 maxM = F0;
20490
20491 if(m_cbcTurbulence) m_cbcViscous = false;
20492
20493 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
20494 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
20495 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
20496 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
20497 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
20498
20499 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
20500 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
20501
20502 MFloat T_target = sysEqn().temperature_IR(meanM);
20503 IF_CONSTEXPR(isDetChem<SysEqn>) T_target = m_solver->m_detChem.infTemperature;
20504
20505 // BC specific start
20506 MBool solverProfile = false;
20507 solverProfile = Context::getSolverProperty<MBool>("solverProfile", m_solverId, AT_, &solverProfile);
20508 MFloat A = F0;
20509 IF_CONSTEXPR(nDim == 3) { A = sqrt(m_cbcInflowArea[cbcId] / PI); }
20510 else {
20511 A = m_cbcInflowArea[cbcId] * F1B2;
20512 }
20513 MFloat testSum2 = F0;
20514 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
20515 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
20516 if(m_solver->a_isHalo(cellId)) continue;
20517 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
20518 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
20519 MInt bndryId = m_solver->a_bndryId(cellId);
20520
20521 MFloat area;
20522 if(bndryId > -1) {
20523 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
20524 if(srfcId > -1) {
20525 area = m_solver->a_surfaceArea(srfcId);
20526 } else {
20527 mTerm(1, AT_, "something went wrong!");
20528 }
20529 } else {
20530 IF_CONSTEXPR(nDim == 2) area = m_solver->c_cellLengthAtCell(cellId);
20531 IF_CONSTEXPR(nDim == 3) area = POW2(m_solver->c_cellLengthAtCell(cellId));
20532 }
20533
20534 area *= m_dirTangent[cbcId][m_cbcDir[cbcId][2]];
20535
20536 MFloat rsquare;
20537 IF_CONSTEXPR(nDim == 2) {
20538 rsquare = POW2((m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]));
20539 }
20540 else {
20541 rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
20542 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
20543 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
20544 }
20545 testSum2 += area * rsquare;
20546 }
20547
20548 MInt noExchangeData = 1;
20549 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
20550 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
20551 comm_buff[0] = testSum2;
20552
20553 if(noDomains() > 1) {
20554 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 1, MPI_DOUBLE, MPI_MAX, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
20555 AT_, "comm_buff[0]", "comm_buff_result[0]");
20556 }
20557
20558 testSum2 = comm_buff_result[0];
20559
20560 MFloat massflux_test;
20561 IF_CONSTEXPR(nDim == 2) { massflux_test = F3B4 / A * (m_cbcInflowArea[cbcId] - F1 / (A * A) * testSum2); }
20562 else {
20563 massflux_test = F2 * (F1 - testSum2 / (m_cbcInflowArea[cbcId] * A * A));
20564 }
20565 MFloat un_correctionFactor = F1;
20566 if(fabs(massflux_test) > m_solver->m_eps) {
20567 un_correctionFactor = F1 / massflux_test;
20568 }
20569
20570 MFloat massflux_target;
20571 IF_CONSTEXPR(nDim == 2) {
20572 massflux_target = m_solver->m_UInfinity * m_cbcInflowArea[cbcId]
20573 * sysEqn().density_ES(m_solver->m_PInfinity, m_solver->m_TInfinity);
20574 IF_CONSTEXPR(isDetChem<SysEqn>) {
20575 massflux_target = m_solver->m_VInfinity * m_cbcInflowArea[cbcId] * m_solver->m_rhoInfinity;
20576 }
20577 }
20578 // fvmbbndrycnd3d uses m_UInfinity instead!
20579 IF_CONSTEXPR(nDim == 3) {
20580 massflux_target = m_solver->m_VInfinity * m_cbcInflowArea[cbcId]
20581 * sysEqn().density_ES(m_solver->m_PInfinity, m_solver->m_TInfinity);
20582 }
20583 // BC specific end
20584
20585 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
20586 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
20587
20588 if(m_solver->a_isHalo(cellId)) continue;
20589 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
20590 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
20591
20592 MInt bndryId = m_solver->a_bndryId(cellId);
20593
20594 if(bndryId > -1) {
20595 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
20596 }
20597
20598 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
20599 V.fill(F0);
20600 if(m_cbcViscous) {
20601 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
20602 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
20603 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
20604 V.fill(F0);
20605 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
20606 &cutOffStencilCellIds[0], &V[0]);
20607 }
20608
20609 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
20610 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
20611 cbcDampingInflow(cellId, bcId, maxM, &K[0], "velocity");
20612
20613 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20614 MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
20615 MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
20616 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20617 MFloat temp = sysEqn().temperature_ES(rho, p);
20618
20619 IF_CONSTEXPR(isDetChem<SysEqn>) {
20620 MFloat fMeanMolarWeight = F0;
20621 for(MUint s = 0; s < PV->m_noSpecies; s++) {
20622 fMeanMolarWeight += m_solver->a_pvariable(cellId, PV->Y[s]) * m_solver->m_fMolarMass[s];
20623 }
20624 MFloat meanMolarWeight = F1 / fMeanMolarWeight;
20625 temp = p / rho * meanMolarWeight / m_solver->m_gasConstant;
20626 }
20627
20628 MFloat a = sysEqn().speedOfSound(rho, p);
20629 IF_CONSTEXPR(isDetChem<SysEqn>) a = sqrt(m_solver->a_avariable(cellId, m_solver->AV->GAMMA) * p / rho);
20630
20631 // BC specific start
20632 MFloat rsquare;
20633 MFloat un_target;
20634 IF_CONSTEXPR(nDim == 2) {
20635 rsquare = POW2((m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]));
20636 un_target = F3B4 * massflux_target / rho / A * (1 - rsquare / (A * A)) * un_correctionFactor;
20637 }
20638 else {
20639 rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
20640 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
20641 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
20642 un_target = F2 * massflux_target / m_cbcInflowArea[cbcId] * (F1 - rsquare / (A * A)) / rho * un_correctionFactor;
20643 }
20644 if(solverProfile) {
20645 un_target = massflux_target / m_cbcInflowArea[cbcId] / rho;
20646 }
20647 // BC specific end
20648
20649 // detChem specific setting
20650 IF_CONSTEXPR(isDetChem<SysEqn>) un_target = m_solver->m_VInfinity;
20651 MFloat ut1_target = F0;
20652 MFloat y_target = F1;
20653
20654 MFloat L_turbulent[3] = {F0, F0, F0};
20655 if(m_cbcTurbulence) {
20656 cbcTurbulenceInjection(cellId, L_turbulent, id);
20657 }
20658
20659 if(dirN % 2 == 0) {
20660 L[0] = -F1 * K[0] * (un - un_target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
20661 } else {
20662 L[last] = K[last] * (un - un_target) - L_turbulent[0] + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
20663 }
20664
20665 L[1] = K[1] * (temp - T_target) + (a * a * T[0] - T[last]) - V[last];
20666 L[2] = K[2] * (ut1 - ut1_target) - L_turbulent[1] + T[2] + V[2];
20667
20668 IF_CONSTEXPR(nDim == 3) {
20669 MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
20670 MFloat ut2_target = F0;
20671 L[3] = K[3] * (ut2 - ut2_target) - L_turbulent[2] + T[3] + V[3];
20672 }
20673
20674 IF_CONSTEXPR(isDetChem<SysEqn>) {
20675 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20676 MFloat y = m_solver->a_pvariable(cellId, sysEqn().PV->Y[s]);
20677 L[last + 1 + s] = K[last + 1 + s] * (y - m_solver->m_YInfinity[s]);
20678 }
20679 }
20680 else {
20681 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20682 MFloat y = m_solver->a_pvariable(cellId, sysEqn().PV->Y[s]);
20683 L[last + 1 + s] = K[last + 1 + s] * (y - y_target);
20684 }
20685 }
20686 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
20687 }
20688}
void cbcTurbulenceInjection(MInt, MFloat *, MInt)
Turbulence injection (identical to bc1601) adjusted for Taylor's Hypothesis for cbc.
SysEqn::AdditionalVariables * AV

◆ cbc1091b()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091b ( MInt  bcId)

Subsonic fully reflecting characteristic inflow condition - cut off
T0,u,v is prescribed, incl. transverse terms

Definition at line 18023 of file fvcartesianbndrycndxd.cpp.

18023 {
18024 TRACE();
18025
18026 if(m_sortedCutOffCells[bcId]->size() == 0) {
18027 return;
18028 }
18029
18030 MInt cbcId = m_cbcBndryCndIds[bcId];
18031
18032 MInt dirN = m_cbcDir[cbcId][0];
18033 MInt dimN = m_cbcDir[cbcId][1];
18034 MInt dimT1 = m_cbcDir[cbcId][2];
18035
18036 MInt last = nDim + 1;
18037
18038 // Allocate memory
18039 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
18040 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
18041 MFloatScratchSpace gradP(nDim, AT_, "gradP");
18042 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
18043 gradY.fill(F0);
18044
18045 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
18046 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
18047 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
18048 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
18049 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
18050
18051 MFloatScratchSpace L(PV->noVariables, AT_, "L");
18052 MFloatScratchSpace T(PV->noVariables, AT_, "T");
18053 MFloatScratchSpace V(PV->noVariables, AT_, "V");
18054 MFloatScratchSpace K(PV->noVariables, AT_, "K");
18055
18056 MFloat mach[2] = {F0, F0};
18057 cbcMachCo(bcId, mach);
18058 MFloat meanM = mach[0];
18059 MFloat maxM = mach[1];
18060
18061 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
18062
18063 // BC specific
18064 MBool solverProfile = Context::getSolverProperty<MBool>("solverProfile", m_solverId, AT_, &solverProfile);
18065 MFloat A = F0;
18066 IF_CONSTEXPR(nDim == 3) { A = sqrt(m_cbcInflowArea[cbcId] / PI); }
18067 else {
18068 A = m_cbcInflowArea[cbcId] * F1B2;
18069 }
18070 MFloat testSum2 = F0;
18071 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18072 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18073 if(m_solver->a_isHalo(cellId)) continue;
18074 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18075 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18076 MInt bndryId = m_solver->a_bndryId(cellId);
18077
18078 MFloat area;
18079 if(bndryId > -1) {
18080 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
18081 if(srfcId > -1) {
18082 area = m_solver->a_surfaceArea(srfcId);
18083 } else {
18084 mTerm(1, AT_, "something went wrong!");
18085 }
18086 } else {
18087 IF_CONSTEXPR(nDim == 2) area = m_solver->c_cellLengthAtCell(cellId);
18088 IF_CONSTEXPR(nDim == 3) area = POW2(m_solver->c_cellLengthAtCell(cellId));
18089 }
18090
18091 MFloat rsquare;
18092 IF_CONSTEXPR(nDim == 2) {
18093 rsquare = POW2((m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]));
18094 }
18095 else {
18096 rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
18097 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
18098 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
18099 }
18100 testSum2 += area * rsquare;
18101 }
18102 MPI_Allreduce(MPI_IN_PLACE, &testSum2, 3, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
18103 "testSum2", "testSum2Result");
18104
18105
18106 MFloat massflux_test;
18107 IF_CONSTEXPR(nDim == 2) { massflux_test = F3B4 / A * (m_cbcInflowArea[cbcId] - F1 / (A * A) * testSum2); }
18108 else {
18109 massflux_test = F2 * (F1 - testSum2 / (m_cbcInflowArea[cbcId] * A * A));
18110 }
18111 MFloat un_correctionFactor = F1;
18112 if(fabs(massflux_test) > m_solver->m_eps) {
18113 un_correctionFactor = F1 / massflux_test;
18114 }
18115 // END BC specific
18116
18117 // Target values
18118 MFloat massflux_target;
18119 massflux_target = m_solver->m_UInfinity * m_cbcInflowArea[cbcId]
18120 * sysEqn().density_ES(m_solver->m_PInfinity, m_solver->m_TInfinity);
18121 MFloat T_target = sysEqn().temperature_IR(meanM);
18122
18123 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
18124 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
18125
18126 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18127 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18128
18129 if(m_solver->a_isHalo(cellId)) continue;
18130 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18131 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18132
18133 MInt bndryId = m_solver->a_bndryId(cellId);
18134 if(bndryId > -1) {
18135 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
18136 }
18137
18138 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
18139 V.fill(F0);
18140 if(m_cbcViscous) {
18141 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
18142 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
18143 &cutOffStencilCellIds[0], &V[0]);
18144 }
18145
18146 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
18147 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
18148 cbcDampingInflow(cellId, bcId, maxM, &K[0], "velocity");
18149
18150 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
18151 MFloat p = m_solver->a_pvariable(cellId, PV->P);
18152 MFloat a = sysEqn().speedOfSound(rho, p);
18153
18154 MFloat rsquare;
18155 MFloat un_target;
18156 if(nDim == 2) {
18157 rsquare = POW2((m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]));
18158 un_target = F3B4 * massflux_target / rho / A * (1 - rsquare / (A * A)) * un_correctionFactor;
18159 } else {
18160 rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
18161 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
18162 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
18163 un_target = F2 * massflux_target / m_cbcInflowArea[cbcId] * (F1 - rsquare / (A * A)) / rho * un_correctionFactor;
18164 }
18165 if(solverProfile) {
18166 un_target = massflux_target / m_cbcInflowArea[cbcId] / rho;
18167 }
18168
18169 // BC specific
18170 L[2] = F0;
18171 L[3] = F0;
18172 T[2] = F0;
18173 T[3] = F0;
18174 // END BC specific
18175
18176 if(dirN % 2 == 0) {
18177 L[0] = L[last] + (T[last] - rho * a * T[1]);
18178 } else {
18179 L[last] = L[0] + (T[last] + rho * a * T[1]);
18180 }
18181
18182 L[1] = F1B2 * gammaMinusOne * (L[0] + L[last]) + (a * a * T[0] - T[last]);
18183
18184 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
18185
18186 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimN]) = F0;
18187 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT1]) = F0;
18188 m_solver->a_rightHandSide(cellId, CV->RHO_E) = F0;
18189 MFloat sign = F1;
18190 if(dirN % 2 == 0) {
18191 sign = -F1;
18192 }
18193 m_solver->a_pvariable(cellId, PV->VV[dimN]) = un_target * sign;
18194 m_solver->a_pvariable(cellId, PV->VV[dimT1]) = F0;
18195 m_solver->a_pvariable(cellId, PV->P) = T_target;
18196 IF_CONSTEXPR(nDim == 3) {
18197 MInt dimT2 = m_cbcDir[cbcId][nDim];
18198 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT2]) = F0;
18199 m_solver->a_pvariable(cellId, PV->VV[dimT1]) = F0;
18200 }
18201 }
18202}
MFloat & a_rightHandSide(const MInt cellId, MInt const varId)
Returns the right hand side of the cell cellId for the variable varId.

◆ cbc1091b_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091b_after ( MInt  bcId)

Definition at line 18209 of file fvcartesianbndrycndxd.cpp.

18209 {
18210 TRACE();
18211 if(m_sortedCutOffCells[bcId]->size() == 0) {
18212 return;
18213 }
18214
18215 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18216 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18217 if(m_solver->a_isHalo(cellId)) continue;
18218 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18219
18220 const MInt bndryId = m_solver->a_bndryId(cellId);
18221
18222 if(bndryId > -1) {
18223 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) {
18224 continue;
18225 }
18226 }
18227
18228 // recompute the correct energy:
18229 const MFloat rho = m_solver->a_variable(cellId, CV->RHO);
18230 const MFloat u = m_solver->a_pvariable(cellId, PV->VV[0]);
18231 const MFloat v = m_solver->a_pvariable(cellId, PV->VV[1]);
18232 const MFloat T = m_solver->a_pvariable(cellId, PV->P);
18233 const MFloat p = sysEqn().pressure_ES(T, rho);
18234 MFloat velSquared = u * u + v * v;
18235 IF_CONSTEXPR(nDim == 3) {
18236 const MFloat w = m_solver->a_pvariable(cellId, PV->VV[2]);
18237 m_solver->a_variable(cellId, CV->RHO_VV[2]) = rho * w;
18238 velSquared += w * w;
18239 }
18240 m_solver->a_variable(cellId, CV->RHO_E) = sysEqn().internalEnergy(p, rho, velSquared);
18241 m_solver->a_variable(cellId, CV->RHO_VV[0]) = rho * u;
18242 m_solver->a_variable(cellId, CV->RHO_VV[1]) = rho * v;
18243 }
18244}

◆ cbc1091c()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091c ( MInt  bcId)

Subsonic partially reflecting characteristic inflow condition - cut off
p0,T0,v is prescribed, incl. shear and transverse terms

Definition at line 18255 of file fvcartesianbndrycndxd.cpp.

18255 {
18256 TRACE();
18257
18258 if(m_sortedCutOffCells[bcId]->size() == 0) {
18259 return;
18260 }
18261
18262 MInt cbcId = m_cbcBndryCndIds[bcId];
18263
18264 MInt dirN = m_cbcDir[cbcId][0];
18265 MInt dimN = m_cbcDir[cbcId][1];
18266 MInt dimT1 = m_cbcDir[cbcId][2];
18267 MInt dimT2 = m_cbcDir[cbcId][nDim];
18268
18269 MInt last = nDim + 1;
18270
18271 // Allocate memory
18272 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
18273 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
18274 MFloatScratchSpace gradP(nDim, AT_, "gradP");
18275 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
18276 gradY.fill(F0);
18277
18278 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
18279 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
18280 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
18281 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
18282 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
18283
18284 MFloatScratchSpace L(PV->noVariables, AT_, "L");
18285 MFloatScratchSpace T(PV->noVariables, AT_, "T");
18286 MFloatScratchSpace V(PV->noVariables, AT_, "V");
18287 MFloatScratchSpace K(PV->noVariables, AT_, "K");
18288
18289 MFloat mach[2] = {F0, F0};
18290 cbcMachCo(bcId, mach);
18291 MFloat meanM = mach[0];
18292 MFloat maxM = mach[1];
18293
18294 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
18295
18296 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
18297 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
18298
18299 MFloat T_target = sysEqn().temperature_IR(meanM);
18300 MFloat p_Target = sysEqn().pressure_IR(T_target);
18301
18302 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18303 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18304
18305 if(m_solver->a_isHalo(cellId)) continue;
18306 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18307 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18308
18309 MInt bndryId = m_solver->a_bndryId(cellId);
18310 if(bndryId > -1) {
18311 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
18312 }
18313
18314 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
18315 V.fill(F0);
18316 if(m_cbcViscous) {
18317 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
18318 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
18319 IF_CONSTEXPR(nDim == 3) gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0;
18320 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
18321 &cutOffStencilCellIds[0], &V[0]);
18322 }
18323
18324 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
18325 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
18326 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
18327
18328 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
18329 MFloat p = m_solver->a_pvariable(cellId, PV->P);
18330 MFloat a = sysEqn().speedOfSound(rho, p);
18331
18332 if(dirN % 2 == 0) {
18333 L[0] = -L[last] + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
18334 } else {
18335 L[last] = -L[0] + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
18336 }
18337
18338 L[1] = F1B2 * gammaMinusOne * (L[last] - L[0]) + (a * a * T[0] - T[last]) - V[last];
18339
18340 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
18341
18342 m_solver->a_rightHandSide(cellId, CV->RHO) = 0.0;
18343 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT1]) = 0.0;
18344 m_solver->a_rightHandSide(cellId, CV->RHO_E) = 0.0;
18345 IF_CONSTEXPR(nDim == 3) { m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT2]) = 0.0; }
18346 m_solver->a_pvariable(cellId, PV->RHO) = sysEqn().density_ES(p_Target, T_target);
18347 m_solver->a_pvariable(cellId, PV->VV[dimT1]) = 0.0;
18348 IF_CONSTEXPR(nDim == 3) { m_solver->a_pvariable(cellId, PV->VV[dimT2]) = 0.0; }
18349 m_solver->a_pvariable(cellId, PV->P) = p_Target;
18350 }
18351}

◆ cbc1091c_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091c_after ( MInt  bcId)

Definition at line 18358 of file fvcartesianbndrycndxd.cpp.

18358 {
18359 TRACE();
18360
18361 MInt otherDir[2 * nDim];
18362 for(MInt dim = 0; dim < nDim; dim++) {
18363 otherDir[2 * dim] = 2 * dim + 1;
18364 otherDir[2 * dim + 1] = 2 * dim;
18365 }
18366
18372
18373 if(first) {
18374 MInt noCutOffBndryIds = Context::propertyLength("cutOffBndryIds", m_solverId);
18375 MInt noCutOffDirections = Context::propertyLength("cutOffDirections", m_solverId);
18376 if(noCutOffDirections != noCutOffBndryIds) {
18377 mTerm(1, AT_,
18378 "Wrong number of cut off directions. Must be identical to number of cut off bndryIds! Please check!");
18379 }
18380 MInt cutOffBndryIdTmp, cutOffDirectionTmp;
18381 for(MInt i = 0; i < noCutOffBndryIds; i++) {
18382 cutOffBndryIdTmp = Context::getSolverProperty<MInt>("cutOffBndryIds", m_solverId, AT_, i);
18383 cutOffDirectionTmp = Context::getSolverProperty<MInt>("cutOffDirections", m_solverId, AT_, i);
18384 if(cutOffBndryIdTmp == m_cutOffBndryCndIds[bcId]) {
18385 dirN = otherDir[cutOffDirectionTmp];
18386 break;
18387 }
18388 }
18389 dimN = (MInt)dirN / 2;
18390 dimT1 = (dimN + 1) % nDim;
18391 IF_CONSTEXPR(nDim == 3) dimT2 = (dimT1 + 1) % nDim;
18392
18393 first = false;
18394 }
18395
18396 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18397 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18398 if(m_solver->a_isHalo(cellId)) continue;
18399 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18400
18401 MInt bndryId = m_solver->a_bndryId(cellId);
18402
18403 if(bndryId > -1) {
18404 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) {
18405 continue;
18406 }
18407 }
18408
18409 // recompute the correct energy:
18410 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
18411 MFloat u = m_solver->a_variable(cellId, CV->RHO_VV[dimN]) / m_solver->a_variable(cellId, CV->RHO);
18412 MFloat v = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
18413 MFloat p = m_solver->a_pvariable(cellId, PV->P);
18414 const MFloat vel = POW2(u) + POW2(v);
18415 MFloat E = sysEqn().internalEnergy(p, rho, vel);
18416
18417 IF_CONSTEXPR(nDim == 3) {
18418 // compute corrected energy
18419 MFloat w = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
18420 E += F1B2 * (w * w) * rho;
18421 m_solver->a_variable(cellId, CV->RHO_VV[dimT2]) = rho * w;
18422 }
18423
18424 m_solver->a_variable(cellId, CV->RHO_E) = E;
18425 }
18426}
MBool m_static_cbc1091c_after_first

◆ cbc1091d()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091d ( MInt  bcId)

Subsonic partially reflecting characteristic inflow condition - cut off
p0,T0,v is prescribed, incl. shear and transverse terms, profile of un is prescribed

Definition at line 18436 of file fvcartesianbndrycndxd.cpp.

18436 {
18437 TRACE();
18438
18439 if(m_sortedCutOffCells[bcId]->size() == 0) {
18440 return;
18441 }
18442
18443 MInt cbcId = m_cbcBndryCndIds[bcId];
18444 // Determine dirs
18445 MInt dirN = m_cbcDir[cbcId][0];
18446 MInt dimN = m_cbcDir[cbcId][1];
18447 MInt dimT1 = m_cbcDir[cbcId][2];
18448
18449 MInt last = nDim + 1;
18450
18451 // Allocate memory
18452 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
18453 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
18454 MFloatScratchSpace gradP(nDim, AT_, "gradP");
18455 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
18456 gradY.fill(F0);
18457
18458 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
18459 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
18460 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
18461 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
18462 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
18463
18464 MFloatScratchSpace L(PV->noVariables, AT_, "L");
18465 MFloatScratchSpace T(PV->noVariables, AT_, "T");
18466 MFloatScratchSpace V(PV->noVariables, AT_, "V");
18467 MFloatScratchSpace K(PV->noVariables, AT_, "K");
18468
18469 // Get mean/max mach number
18470 MFloat mach[2] = {F0, F0};
18471 cbcMachCo(bcId, mach);
18472 MFloat meanM = mach[0];
18473 MFloat maxM = mach[1];
18474
18475 // BC specific
18476 MBool solverProfile = Context::getSolverProperty<MBool>("solverProfile", m_solverId, AT_, &solverProfile);
18477 MFloat A = F0;
18478 IF_CONSTEXPR(nDim == 3) { A = sqrt(m_cbcInflowArea[cbcId] / PI); }
18479 else {
18480 A = m_cbcInflowArea[cbcId] * F1B2;
18481 }
18482 MFloat testSum2 = F0;
18483 MFloat massflux = F0;
18484 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18485 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18486 if(m_solver->a_isHalo(cellId)) continue;
18487 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18488 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18489 MInt bndryId = m_solver->a_bndryId(cellId);
18490 MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
18491
18492 MFloat area;
18493 if(bndryId > -1) {
18494 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
18495 if(srfcId > -1) {
18496 area = m_solver->a_surfaceArea(srfcId);
18497 } else {
18498 mTerm(1, AT_, "something went wrong!");
18499 }
18500 } else {
18501 IF_CONSTEXPR(nDim == 2) area = m_solver->c_cellLengthAtCell(cellId);
18502 IF_CONSTEXPR(nDim == 3) area = POW2(m_solver->c_cellLengthAtCell(cellId));
18503 }
18504
18505 MFloat rsquare;
18506 IF_CONSTEXPR(nDim == 2) {
18507 rsquare = POW2((m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]));
18508 }
18509 else {
18510 rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
18511 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
18512 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
18513 }
18514 testSum2 += area * rsquare;
18515 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
18516 const MFloat un_N = m_solver->a_pvariable(nghbrN, PV->VV[dimN]);
18517 massflux += un_N * area * rho;
18518 }
18519
18520 MPI_Allreduce(MPI_IN_PLACE, &massflux, 3, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
18521 "massflux", "massfluxResult");
18522 MPI_Allreduce(MPI_IN_PLACE, &testSum2, 3, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
18523 "testSum2", "testSum2Result");
18524
18525 MFloat massflux_test;
18526 IF_CONSTEXPR(nDim == 2) { massflux_test = F3B4 / A * (m_cbcInflowArea[cbcId] - F1 / (A * A) * testSum2); }
18527 else {
18528 massflux_test = F2 * (F1 - testSum2 / (m_cbcInflowArea[cbcId] * A * A));
18529 }
18530 MFloat un_correctionFactor = F1;
18531 if(fabs(massflux_test) > m_solver->m_eps) {
18532 un_correctionFactor = F1 / massflux_test;
18533 }
18534 // END BC specific
18535
18536 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
18537 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
18538
18539 MFloat T_target = sysEqn().temperature_IR(meanM);
18540 MFloat p_Target = sysEqn().pressure_IR(T_target);
18541
18542 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18543 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18544
18545 if(m_solver->a_isHalo(cellId)) continue;
18546 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18547 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18548
18549 MInt bndryId = m_solver->a_bndryId(cellId);
18550 if(bndryId > -1) {
18551 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
18552 }
18553
18554 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
18555 if(m_cbcViscous) {
18556 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
18557 }
18558
18559 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
18560 MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
18561 MFloat p = m_solver->a_pvariable(cellId, PV->P);
18562 MFloat temp = sysEqn().temperature_ES(rho, p);
18563 MFloat a = sysEqn().speedOfSound(rho, p);
18564
18565 MFloat un_target;
18566 IF_CONSTEXPR(nDim == 3) {
18567 MFloat rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
18568 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
18569 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
18570 un_target = F2 * massflux / m_cbcInflowArea[cbcId] * (F1 - rsquare / (A * A)) / un_correctionFactor;
18571 }
18572 else {
18573 MFloat rsquare = POW2((m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]));
18574 if(!solverProfile) {
18575 const MFloat mu = sysEqn().sutherlandLaw(temp);
18576 if(m_cbcViscous)
18577 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimT1] =
18578 -mu * F3B2 * massflux / (rho * A * A * A) * un_correctionFactor;
18579 }
18580 un_target = F3B4 * massflux / A * (1 - rsquare / (A * A)) * un_correctionFactor;
18581 if(solverProfile) {
18582 un_target = m_solver->m_UInfinity;
18583 }
18584 }
18585
18586 V.fill(F0);
18587 if(m_cbcViscous)
18588 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
18589 &cutOffStencilCellIds[0], &V[0]);
18590
18591 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
18592 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
18593 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
18594
18595 if(dirN % 2 == 0) {
18596 L[0] = K[0] * (p - p_Target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
18597 } else {
18598 L[last] = K[last] * (p - p_Target) + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
18599 }
18600
18601 L[1] = K[1] * (temp - T_target) + (a * a * T[0] - T[last]) - V[last];
18602 L[2] = K[2] * ut1 + T[2] + V[2];
18603 IF_CONSTEXPR(nDim == 3) {
18604 MInt dimT2 = m_cbcDir[cbcId][nDim];
18605 MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
18606 L[3] = K[3] * ut2 + T[3] + V[3];
18607 }
18608
18609 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
18610 m_solver->a_pvariable(cellId, PV->VV[dimN]) = un_target;
18611 }
18612}

◆ cbc1091d_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091d_after ( MInt  bcId)

Definition at line 18619 of file fvcartesianbndrycndxd.cpp.

18619 {
18620 TRACE();
18621
18622 MInt otherDir[2 * nDim];
18623 for(MInt dim = 0; dim < nDim; dim++) {
18624 otherDir[2 * dim] = 2 * dim + 1;
18625 otherDir[2 * dim + 1] = 2 * dim;
18626 }
18627
18633
18634 if(first) {
18635 MInt noCutOffBndryIds = Context::propertyLength("cutOffBndryIds", m_solverId);
18636 MInt noCutOffDirections = Context::propertyLength("cutOffDirections", m_solverId);
18637 if(noCutOffDirections != noCutOffBndryIds) {
18638 mTerm(1, AT_,
18639 "Wrong number of cut off directions. Must be identical to number of cut off bndryIds! Please check!");
18640 }
18641 MInt cutOffBndryIdTmp, cutOffDirectionTmp;
18642 for(MInt i = 0; i < noCutOffBndryIds; i++) {
18643 cutOffBndryIdTmp = Context::getSolverProperty<MInt>("cutOffBndryIds", m_solverId, AT_, i);
18644 cutOffDirectionTmp = Context::getSolverProperty<MInt>("cutOffDirections", m_solverId, AT_, i);
18645 if(cutOffBndryIdTmp == m_cutOffBndryCndIds[bcId]) {
18646 dirN = otherDir[cutOffDirectionTmp];
18647 break;
18648 }
18649 }
18650 dimN = (MInt)dirN / 2;
18651 dimT1 = (dimN + 1) % nDim;
18652 IF_CONSTEXPR(nDim == 3) dimT2 = (dimT1 + 1) % nDim;
18653
18654 first = false;
18655 }
18656
18657 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18658 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18659 if(m_solver->a_isHalo(cellId)) continue;
18660 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18661
18662 MInt bndryId = m_solver->a_bndryId(cellId);
18663
18664 if(bndryId > -1) {
18665 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) {
18666 continue;
18667 }
18668 }
18669
18670 // recompute the correct energy:
18671 MFloat rho = m_solver->a_variable(cellId, CV->RHO);
18672 MFloat u = m_solver->a_pvariable(cellId, PV->VV[dimN]);
18673 MFloat u_wrong = m_solver->a_variable(cellId, CV->RHO_VV[dimN]) / m_solver->a_variable(cellId, CV->RHO);
18674 MFloat v = m_solver->a_variable(cellId, CV->RHO_VV[dimT1]) / m_solver->a_variable(cellId, CV->RHO);
18675
18676 MFloat Sum_sq_u = u_wrong * u_wrong + v * v;
18677 MFloat E;
18678 IF_CONSTEXPR(nDim == 2) {
18679 MFloat p = sysEqn().pressure(rho, Sum_sq_u, m_solver->a_variable(cellId, CV->RHO_E));
18680 E = sysEqn().internalEnergy(p, rho, (u * u + v * v));
18681 }
18682 IF_CONSTEXPR(nDim == 3) {
18683 MFloat w = m_solver->a_variable(cellId, CV->RHO_VV[dimT2]) / m_solver->a_variable(cellId, CV->RHO);
18684 MFloat p = sysEqn().pressure(rho, Sum_sq_u, m_solver->a_variable(cellId, CV->RHO_E));
18685 Sum_sq_u += w * w;
18686 E = sysEqn().internalEnergy(p, rho, (u * u + v * v + w * w));
18687 }
18688 m_solver->a_variable(cellId, CV->RHO_VV[dimN]) = rho * u;
18689 m_solver->a_variable(cellId, CV->RHO_E) = E;
18690 }
18691}
MBool m_static_cbc1091d_after_first

◆ cbc1091e()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091e ( MInt  bcId)

Subsonic fully reflecting characteristic inflow condition - cut off
T0,u,v is prescribed, incl. transverse terms

Definition at line 19530 of file fvcartesianbndrycndxd.cpp.

19530 {
19531 TRACE();
19532
19533 if(m_sortedCutOffCells[bcId]->size() == 0) {
19534 return;
19535 }
19536
19537 MInt cbcId = m_cbcBndryCndIds[bcId];
19538
19539 MInt dirN = m_cbcDir[cbcId][0];
19540 MInt dimN = m_cbcDir[cbcId][1];
19541 MInt dimT1 = m_cbcDir[cbcId][2];
19542
19543 MInt last = nDim + 1;
19544
19545 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
19546 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
19547 MFloatScratchSpace gradP(nDim, AT_, "gradP");
19548 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
19549 gradY.fill(F0);
19550
19551 MFloatScratchSpace L(PV->noVariables, AT_, "L");
19552 MFloatScratchSpace T(PV->noVariables, AT_, "T");
19553 MFloatScratchSpace V(PV->noVariables, AT_, "V");
19554 MFloatScratchSpace K(PV->noVariables, AT_, "K");
19555
19556 MFloat mach[2] = {F0, F0};
19557 cbcMachCo(bcId, mach);
19558 MFloat maxM = mach[1];
19559
19560 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
19561
19562 MFloat T_target = sysEqn().temperature_IR(m_solver->m_Ma);
19563
19564 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19565 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19566
19567 if(m_solver->a_isHalo(cellId)) continue;
19568 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19569 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19570
19571 MInt bndryId = m_solver->a_bndryId(cellId);
19572
19573 if(bndryId > -1) {
19574 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
19575 }
19576
19577 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
19578 // labels:FV HACK
19579 gradVV[dimN * nDim + dimT1] = F0;
19580 gradVV[dimT1 * nDim + dimT1] = F0;
19581
19582 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
19583 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
19584
19585 cbcDampingInflow(cellId, bcId, maxM, &K[0], "velocity");
19586
19587 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
19588 MFloat p = m_solver->a_pvariable(cellId, PV->P);
19589 MFloat a = sysEqn().speedOfSound(rho, p);
19590
19591 MFloat un_target = m_solver->m_UInfinity;
19592 MFloat ut1_target = F0;
19593
19594 if(dirN % 2 == 0) {
19595 L[0] = L[last] + (T[last] - rho * a * T[1]);
19596 } else {
19597 L[last] = L[0] + (T[last] + rho * a * T[1]);
19598 }
19599
19600 L[1] = F1B2 * gammaMinusOne * (L[0] + L[last]) + (a * a * T[0] - T[last]);
19601
19602
19603 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
19604
19605 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimN]) = F0;
19606 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT1]) = F0;
19607 m_solver->a_rightHandSide(cellId, CV->RHO_E) = F0;
19608
19609 m_solver->a_pvariable(cellId, PV->VV[dimN]) = un_target;
19610 m_solver->a_pvariable(cellId, PV->VV[dimT1]) = ut1_target;
19611 m_solver->a_pvariable(cellId, PV->P) = T_target;
19612 }
19613}

◆ cbc1091e_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1091e_after ( MInt  bcId)

Definition at line 19618 of file fvcartesianbndrycndxd.cpp.

19618 {
19619 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function cbc1091e_after is untested for 3D!"); }
19620 TRACE();
19621
19622 if(m_sortedCutOffCells[bcId]->size() == 0) return;
19623
19624 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19625 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19626
19627 if(m_solver->a_isHalo(cellId)) continue;
19628 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19629 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19630
19631 MInt bndryId = m_solver->a_bndryId(cellId);
19632
19633 if(bndryId > -1) {
19634 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
19635 }
19636
19637 // recompute the correct energy:
19638 MFloat rho = m_solver->a_variable(cellId, CV->RHO);
19639 MFloat u = m_solver->a_pvariable(cellId, PV->VV[0]);
19640 MFloat v = m_solver->a_pvariable(cellId, PV->VV[1]);
19641 MFloat T = m_solver->a_pvariable(cellId, PV->P);
19642 MFloat p = sysEqn().pressure_ES(T, rho);
19643 MFloat E = sysEqn().internalEnergy(p, rho, (u * u + v * v));
19644
19645 m_solver->a_variable(cellId, CV->RHO_VV[0]) = rho * u;
19646 m_solver->a_variable(cellId, CV->RHO_VV[1]) = rho * v;
19647 m_solver->a_variable(cellId, CV->RHO_E) = E;
19648 }
19649}

◆ cbc1099()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099 ( MInt  bcId)

Characteristic boundary condition. Outflow. Prescribed: p. Partially Refelecting.

Author
Thomas Hoesgen, Soeren Mehnert
Date
May 2020

Definition at line 21038 of file fvcartesianbndrycndxd.cpp.

21038 {
21039 TRACE();
21040
21041 if(m_sortedCutOffCells[bcId]->size() == 0) {
21042 return;
21043 }
21044
21045 MInt cbcId = m_cbcBndryCndIds[bcId];
21046
21047 MInt dirN = m_cbcDir[cbcId][0];
21048 MInt dimN = m_cbcDir[cbcId][1];
21049 MInt dimT1 = m_cbcDir[cbcId][2];
21050 MInt dimT2 = m_cbcDir[cbcId][nDim];
21051
21052 MInt last = nDim + 1;
21053
21054 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
21055 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
21056 MFloatScratchSpace gradP(nDim, AT_, "gradP");
21057 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
21058 gradY.fill(F0);
21059
21060 MFloatScratchSpace L(PV->noVariables, AT_, "L");
21061 MFloatScratchSpace T(PV->noVariables, AT_, "T");
21062 MFloatScratchSpace V(PV->noVariables, AT_, "V");
21063 MFloatScratchSpace K(PV->noVariables, AT_, "K");
21064
21065 MFloat mach[2];
21066 cbcMachCo(bcId, mach);
21067 MFloat meanM = mach[0];
21068 MFloat maxM = mach[1];
21069
21070
21071 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
21072 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
21073 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
21074 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
21075 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
21076
21077 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
21078 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
21079
21080 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21081 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21082
21083 if(m_solver->a_isHalo(cellId)) continue;
21084
21085 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
21086 V.fill(F0);
21087 if(m_cbcViscous) {
21088 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
21089 gradQ[dimN * nDim + dimN] = F0;
21090 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
21091 IF_CONSTEXPR(nDim == 3) gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0;
21092 cbcViscousTerms<(unsigned char)11111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
21093 &cutOffStencilCellIds[0], &V[0]);
21094 }
21095
21096 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
21097 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
21098 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
21099
21100 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21101 MFloat p = m_solver->a_pvariable(cellId, PV->P);
21102 MFloat a = sysEqn().speedOfSound(rho, p);
21103
21104 MFloat beta = meanM;
21105
21106 // BC specific start
21107 MFloat targetPressure = m_solver->m_PInfinity - m_deltaPL;
21108 // BC specific end
21109 // targetPressure = m_solver->m_PInfinity;
21110 MFloat y_target = F0;
21111
21112 if(dirN % 2 == 0) {
21113 L[0] = K[0] * (p - targetPressure) + (F1 - beta) * (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
21114 } else {
21115 L[last] = K[last] * (p - targetPressure) + (F1 - beta) * (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
21116 }
21117 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
21118 MFloat y = m_solver->a_pvariable(cellId, sysEqn().PV->Y[s]);
21119 L[last + 1 + s] = K[last + 1 + s] * (y - y_target);
21120 }
21121
21122 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
21123 }
21124}
void cbcDampingOutflow(MInt, MInt, MFloat, MFloat *)
Calculates the outflow damping terms.

◆ cbc109910()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc109910 ( MInt  bcId)
Author
Jannik Borgelt
Date
May 2023

Definition at line 20803 of file fvcartesianbndrycndxd.cpp.

20803 {
20804 TRACE();
20805
20806 if(m_sortedCutOffCells[bcId]->size() == 0) {
20807 return;
20808 }
20809
20810 MInt cbcId = m_cbcBndryCndIds[bcId];
20811
20812 MInt dirN = m_cbcDir[cbcId][0];
20813 MInt dimN = m_cbcDir[cbcId][1];
20814 MInt dimT1 = m_cbcDir[cbcId][2];
20815 MInt dimT2 = m_cbcDir[cbcId][nDim];
20816
20817 MInt last = nDim + 1;
20818
20819 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
20820 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
20821 MFloatScratchSpace gradP(nDim, AT_, "gradP");
20822 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
20823 gradY.fill(F0);
20824
20825 MFloatScratchSpace L(PV->noVariables, AT_, "L");
20826 MFloatScratchSpace T(PV->noVariables, AT_, "T");
20827 MFloatScratchSpace V(PV->noVariables, AT_, "V");
20828 MFloatScratchSpace K(PV->noVariables, AT_, "K");
20829 L.fill(F0);
20830 T.fill(F0);
20831 V.fill(F0);
20832 K.fill(F0);
20833
20834 std::vector<MFloat> mach(2);
20835 cbcMachCo(bcId, &mach[0]);
20836 MFloat meanM = mach[0];
20837 MFloat maxM = mach[1];
20838
20839 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
20840 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
20841 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
20842 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
20843 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
20844
20845 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
20846 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
20847
20848
20849 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
20850 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
20851
20852 if(m_solver->a_isHalo(cellId)) continue;
20853
20854 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
20855 V.fill(F0);
20856 // if(m_cbcViscous) {
20857 // cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
20858 // gradQ[dimN * nDim + dimN] = F0;
20859 // gradTau[dimN * IPOW2[nDim] + dimT1 * nDim + dimN] = F0;
20860 // IF_CONSTEXPR(nDim == 3) gradTau[dimN * IPOW2[nDim] + dimT2 * nDim + dimN] = F0;
20861 // cbcViscousTerms<(unsigned char)11111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
20862 // &cutOffStencilCellIds[0], &V[0]);
20863 // }
20864
20865 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20866 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20867 MFloat a = sysEqn().speedOfSound(rho, p);
20868
20869 MFloat beta = meanM;
20870
20871 // BC specific start
20872 MFloat targetPressure = m_solver->m_PInfinity;
20873 MFloat targetDensity = m_solver->m_rhoInfinity;
20874
20875 MFloat un_N = 0;
20876
20877 // check neighbor active!
20878 if(m_solver->checkNeighborActive(cellId, dirN) && m_solver->a_hasNeighbor(cellId, dirN)) {
20879 const MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
20880
20881 for(MInt n = 0; n < nDim; n++) {
20882 un_N += m_solver->a_variable(nghbrN, CV->RHO_VV[n]) * m_dirNormal[cbcId][n];
20883 }
20884 }
20885
20886 MFloat y = m_solver->a_coordinate(cellId, 1);
20887 MFloat un_target = m_solver->m_UInfinity;
20888 MInt length = m_unTargetDataCount; //(MInt)un_targetData.size();
20889 for(MInt i = 1; i < length; i++) {
20890 if(m_unTargetData[i].first > y && m_unTargetData[i - 1].first <= y) {
20891 un_target = m_unTargetData[i - 1].second
20892 + (m_unTargetData[i].second - m_unTargetData[i - 1].second)
20893 / (m_unTargetData[i].first - m_unTargetData[i - 1].first) * (y - m_unTargetData[i - 1].first);
20894 }
20895 }
20896
20897 MBool isInflow = false;
20898 if(dirN % 2 == 0) {
20899 if(un_N < F0 /*|| un_target < F0*/) {
20900 isInflow = true;
20901 }
20902 } else {
20903 if(un_N > F0 /*|| un_target > F0*/) {
20904 isInflow = true;
20905 }
20906 }
20907
20908 MFloat un = m_solver->a_pvariable(cellId, PV->VV[0]);
20909
20910 MFloat lambda2 = un;
20911
20912 isInflow = true;
20913
20914 std::ignore = targetDensity;
20915
20916 if(isInflow) {
20917 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
20918 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
20919 if(dirN % 2 == 0) {
20920 L[0] = -F1 * K[0] * (un - un_target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
20921 } else {
20922 L[last] = K[last] * (un - un_target) + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
20923 }
20924 L[1] = lambda2 * (a * a * gradRho[dimN] - gradP[dimN]);
20925 L[2] = lambda2 * (gradVV[dimT1 * nDim + dimN]);
20926 IF_CONSTEXPR(nDim == 3) { L[3] = lambda2 * (gradVV[dimT2 * nDim + dimN]); }
20927 } else {
20928 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
20929 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
20930 if(dirN % 2 == 0) {
20931 L[0] = K[0] * (p - targetPressure) + (F1 - beta) * (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
20932 } else {
20933 L[last] =
20934 K[last] * (p - targetPressure) + (F1 - beta) * (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
20935 }
20936 }
20937
20938 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
20939 }
20940}
std::pair< MFloat, MFloat > * m_unTargetData

◆ cbc109911()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc109911 ( MInt  bcId)
Author
Jannik Borgelt
Date
July 2023

Definition at line 20947 of file fvcartesianbndrycndxd.cpp.

20947 {
20948 TRACE();
20949
20950 if(m_sortedCutOffCells[bcId]->size() == 0) {
20951 return;
20952 }
20953
20954 MInt cbcId = m_cbcBndryCndIds[bcId];
20955
20956 MInt dirN = m_cbcDir[cbcId][0];
20957 // MInt dimN = m_cbcDir[cbcId][1];
20958 // MInt dimT1 = m_cbcDir[cbcId][2];
20959 // MInt dimT2 = m_cbcDir[cbcId][nDim];
20960
20961 MInt last = nDim + 1;
20962
20963 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
20964 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
20965 MFloatScratchSpace gradP(nDim, AT_, "gradP");
20966 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
20967 // gradY.fill(F0);
20968
20969 MFloatScratchSpace L(PV->noVariables, AT_, "L");
20970 MFloatScratchSpace T(PV->noVariables, AT_, "T");
20971 MFloatScratchSpace V(PV->noVariables, AT_, "V");
20972 // MFloatScratchSpace K(PV->noVariables, AT_, "K");
20973 L.fill(F0);
20974 T.fill(F0);
20975 V.fill(F0);
20976 // K.fill(F0);
20977
20978 // MFloat mach[2];
20979 // cbcMachCo(bcId, mach);
20980 // MFloat meanM = mach[0];
20981 // MFloat maxM = mach[1];
20982
20983 // MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
20984 // MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
20985 // MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
20986
20987 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
20988 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
20989 MInt level = m_solver->a_level(cellId);
20990 MInt rDistance = 1 / m_solver->c_cellLengthAtLevel(level);
20991
20992 if(m_solver->a_isHalo(cellId)) continue;
20993
20994 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
20995
20996 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20997 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20998 MFloat u = m_solver->a_pvariable(cellId, PV->VV[0]);
20999 MFloat a = sysEqn().speedOfSound(rho, p);
21000
21001 // BC specific start
21002 MFloat targetPressure = m_solver->m_PInfinity;
21003 // MFloat targetDensity = m_solver->m_rhoInfinity;
21004
21005 MFloat y = m_solver->a_coordinate(cellId, 1);
21006 MFloat un_target = m_solver->m_UInfinity;
21007 MInt length = m_unTargetDataCount; //(MInt)un_targetData.size();
21008 for(MInt i = 1; i < length; i++) {
21009 if(m_unTargetData[i].first > y && m_unTargetData[i - 1].first <= y) {
21010 un_target = m_unTargetData[i - 1].second
21011 + (m_unTargetData[i].second - m_unTargetData[i - 1].second)
21012 / (m_unTargetData[i].first - m_unTargetData[i - 1].first) * (y - m_unTargetData[i - 1].first);
21013 }
21014 }
21015
21016 // MBool switchRelax = false;
21017
21018 // cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
21019 // cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
21020 if(dirN % 2 == 0) {
21021 L[0] = F0; // ToDo
21022 } else {
21023 L[last] = rDistance * ((u - a) * (targetPressure - p) - rho * a * (un_target - u));
21024 }
21025
21026 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
21027 }
21028}

◆ cbc109921()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc109921 ( MInt  bcId)
Author
Jannik Borgelt
Date
September 2023

Definition at line 20695 of file fvcartesianbndrycndxd.cpp.

20695 {
20696 TRACE();
20697
20698 if(m_sortedCutOffCells[bcId]->size() == 0) {
20699 return;
20700 }
20701
20702 MInt cbcId = m_cbcBndryCndIds[bcId];
20703
20704 MInt dirN = m_cbcDir[cbcId][0];
20705 MInt dimN = m_cbcDir[cbcId][1];
20706 // MInt dimT1 = m_cbcDir[cbcId][2];
20707 MInt dimT2 = m_cbcDir[cbcId][nDim];
20708
20709 // MInt last = nDim + 1;
20710
20711 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
20712 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
20713 MFloatScratchSpace gradP(nDim, AT_, "gradP");
20714 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
20715 gradY.fill(F0);
20716
20717 MFloatScratchSpace L(PV->noVariables, AT_, "L");
20718 MFloatScratchSpace T(PV->noVariables, AT_, "T");
20719 MFloatScratchSpace V(PV->noVariables, AT_, "V");
20720 MFloatScratchSpace K(PV->noVariables, AT_, "K");
20721 L.fill(F0);
20722 T.fill(F0);
20723 V.fill(F0);
20724 K.fill(F0);
20725
20726 std::vector<MFloat> mach(2);
20727 cbcMachCo(bcId, &mach[0]);
20728 // MFloat meanM = mach[0];
20729 MFloat maxM = mach[1];
20730
20731 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
20732 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
20733 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
20734 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
20735 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
20736
20737 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
20738 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
20739
20740 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
20741 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
20742
20743 if(m_solver->a_isHalo(cellId)) continue;
20744
20745 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
20746 V.fill(F0);
20747 // if(m_cbcViscous) {
20748 // cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
20749 // gradQ[dimN * nDim + dimN] = F0;
20750 // gradTau[dimN * IPOW2[nDim] + dimT1 * nDim + dimN] = F0;
20751 // IF_CONSTEXPR(nDim == 3) gradTau[dimN * IPOW2[nDim] + dimT2 * nDim + dimN] = F0;
20752 // cbcViscousTerms<(unsigned char)11111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
20753 // &cutOffStencilCellIds[0], &V[0]);
20754 // }
20755
20756 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20757 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20758 MFloat a = sysEqn().speedOfSound(rho, p);
20759
20760 MFloat vn_N = 0;
20761
20762 // check neighbor active!
20763 if(m_solver->checkNeighborActive(cellId, dirN) && m_solver->a_hasNeighbor(cellId, dirN)) {
20764 const MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
20765 for(MInt n = 0; n < nDim; n++) {
20766 vn_N += m_solver->a_variable(nghbrN, CV->RHO_VV[n]) * m_dirNormal[cbcId][n];
20767 }
20768 }
20769
20770 MFloat x = m_solver->a_coordinate(cellId, 0);
20771 MFloat vn_target = m_solver->m_UInfinity;
20772 MInt length = m_vnTargetDataCount;
20773 for(MInt i = 1; i < length; i++) {
20774 if(m_vnTargetData[i].first > x && m_vnTargetData[i - 1].first <= x) {
20775 vn_target = m_vnTargetData[i - 1].second
20776 + (m_vnTargetData[i].second - m_vnTargetData[i - 1].second)
20777 / (m_vnTargetData[i].first - m_vnTargetData[i - 1].first) * (x - m_vnTargetData[i - 1].first);
20778 }
20779 }
20780
20781 MFloat un = m_solver->a_pvariable(cellId, PV->VV[0]);
20782 MFloat vn = m_solver->a_pvariable(cellId, PV->VV[1]);
20783 MFloat lambda1 = (un - a);
20784 MFloat lambda2 = un;
20785
20786 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
20787 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
20788 L[0] = lambda1 * (gradP[dimN] - rho * a * gradVV[dimN * nDim + dimN]);
20789 L[1] = lambda2 * (a * a * gradRho[dimN] - gradP[dimN]);
20790 L[2] = K[2] * (vn - vn_target);
20791 // L[2] = lambda2 * (gradVV[dimT1 * nDim + dimN]);
20792 IF_CONSTEXPR(nDim == 3) { L[3] = lambda2 * (gradVV[dimT2 * nDim + dimN]); }
20793
20794 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
20795 }
20796}
std::pair< MFloat, MFloat > * m_vnTargetData

◆ cbc1099_1091_engine()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099_1091_engine ( MInt  bcId)

Subsonic characteristic inflow/outflow for fvmb with switch by crank-angle

Definition at line 23219 of file fvcartesianbndrycndxd.cpp.

23219 {
23220 TRACE();
23221
23222 if(m_sortedCutOffCells[bcId]->size() == 0) {
23223 return;
23224 }
23225
23226// check cutOfCells:
23227#if !defined NDEBUG
23228 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
23229 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
23230
23231 ASSERT(fabs(m_solver->a_rightHandSide(cellId, CV->RHO)) < m_solver->m_eps, "");
23232 ASSERT(fabs(m_solver->a_rightHandSide(cellId, CV->RHO_VV[0])) < m_solver->m_eps, "");
23233 ASSERT(fabs(m_solver->a_rightHandSide(cellId, CV->RHO_VV[1])) < m_solver->m_eps, "");
23234 ASSERT(fabs(m_solver->a_rightHandSide(cellId, CV->RHO_E)) < m_solver->m_eps, "");
23235 IF_CONSTEXPR(nDim == 3)
23236 ASSERT(fabs(m_solver->a_rightHandSide(cellId, CV->RHO_VV[2])) < m_solver->m_eps, "");
23237 }
23238
23239 // check conservative variables on window and halo-cells:
23240 // uncomment the part below for further debug checks, remaining for documentary purposes
23241 /*
23242 const MInt noChecks = CV->noVariables;
23243 MFloatScratchSpace cellCheck(m_solver->a_noCells(), noChecks, AT_, "cellCheck");
23244 cellCheck.fill(std::numeric_limits<MFloat>::max());
23245
23246 for(MInt cellId = 0; cellId < m_solver->noInternalCells(); cellId++) {
23247 for(MInt v = 0; v < noChecks; v++) {
23248 cellCheck(cellId, v) = m_solver->a_variable(cellId, v);
23249 }
23250 }
23251 m_solver->exchangeData(&cellCheck(0), noChecks);
23252 for(MInt cellId = m_solver->noInternalCells(); cellId < m_solver->c_noCells(); cellId++) {
23253 if(!m_solver->c_isLeafCell(cellId)) continue;
23254 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
23255 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
23256
23257 for(MInt v = 0; v < noChecks; v++) {
23258 if(fabs(cellCheck(cellId, v) - m_solver->a_variable(cellId, v)) > m_solver->m_eps * 10) {
23259 cerr << "Incorrect value at halo-cell: " << m_solver->a_isHalo(cellId) << setprecision(14) << " "
23260 << m_solver->a_variable(cellId, v) << " " << cellCheck(cellId, v) << endl;
23261 }
23262 }
23263 }
23264 */
23265#endif
23266
23267 MInt cbcId = m_cbcBndryCndIds[bcId];
23268
23269 MInt dirN = m_cbcDir[cbcId][0];
23270 MInt dimN = m_cbcDir[cbcId][1];
23271 MInt dimT1 = m_cbcDir[cbcId][2];
23272 MInt dimT2 = m_cbcDir[cbcId][nDim];
23273
23274 MFloat inflowArea = m_cbcInflowArea[cbcId];
23275 inflowArea = inflowArea * m_dirTangent[cbcId][dimT1];
23276
23277 MInt last = nDim + 1;
23278
23279 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
23280 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
23281 MFloatScratchSpace gradP(nDim, AT_, "gradP");
23282 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
23283 gradY.fill(F0);
23284
23285 MFloatScratchSpace L(PV->noVariables, AT_, "L");
23286 MFloatScratchSpace T(PV->noVariables, AT_, "T");
23287 MFloatScratchSpace V(PV->noVariables, AT_, "V");
23288 MFloatScratchSpace K(PV->noVariables, AT_, "K");
23289
23290 MFloat massflux = F0;
23291 MFloat T_mean = F0;
23292 MFloat rho_mean = F0;
23293 MFloat rho_max = F0;
23294 MFloat rho_min = 99;
23295
23296 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
23297 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
23298 MInt bndryId = m_solver->a_bndryId(cellId);
23299
23300 if(m_solver->a_isHalo(cellId)) continue;
23301 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
23302 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
23303
23304 MFloat area = -1;
23305 if(bndryId > -1) {
23306 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
23307 // cell
23308 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
23309 if(srfcId > -1) {
23310 area = m_solver->a_surfaceArea(srfcId);
23311 IF_CONSTEXPR(nDim == 3) ASSERT(area <= POW2(m_solver->c_cellLengthAtCell(cellId)), "");
23312 } else {
23313 for(MInt dir = 0; dir < m_noDirs; dir++) {
23314 srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dir];
23315 if(srfcId > -1) break;
23316 }
23317 if(srfcId == -1) {
23318 mTerm(1, AT_, "something went wrong!");
23319 }
23320 area = m_solver->a_surfaceArea(srfcId);
23321 }
23322 } else {
23323 IF_CONSTEXPR(nDim == 2) area = m_solver->c_cellLengthAtCell(cellId);
23324 IF_CONSTEXPR(nDim == 3) area = POW2(m_solver->c_cellLengthAtCell(cellId));
23325 }
23326
23327 ASSERT(area > 0, "");
23328
23329 // recompute area
23330 area = area * m_dirTangent[cbcId][dimT1];
23331
23332 m_solver->setPrimitiveVariables(cellId);
23333
23334 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
23335 MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
23336
23337 MFloat un_N = 0;
23338 MFloat T_N = 1;
23339
23340 if(m_solver->checkNeighborActive(cellId, dirN) && m_solver->a_hasNeighbor(cellId, dirN)) {
23341 const MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
23342
23343 if(m_dirNormal[cbcId][0] > -2) {
23344 for(MInt n = 0; n < nDim; n++) {
23345 un_N += m_solver->a_variable(nghbrN, CV->RHO_VV[n]) / m_solver->a_variable(nghbrN, CV->RHO)
23346 * m_dirNormal[cbcId][n];
23347 }
23348 } else {
23349 un_N = m_solver->a_variable(nghbrN, CV->RHO_VV[dimN]) / m_solver->a_variable(nghbrN, CV->RHO);
23350 }
23351
23352 if(std::isnan(un_N)) {
23353 cerr << "NAN detected in cutOff-Neighbor! " << endl;
23354 }
23355
23356 T_N = sysEqn().temperature_ES(m_solver->a_variable(nghbrN, CV->RHO), m_solver->a_pvariable(nghbrN, PV->P));
23357 }
23358
23359 if(rho < F0 || std::isnan(rho) || std::isnan(un)) {
23360 cerr << "NAN detected in cutOff-Cell " << m_solver->c_globalId(cellId) << " " << m_solver->a_isHalo(cellId) << " "
23361 << m_solver->a_bndryId(cellId) << " " << rho << " " << bcId << endl;
23362 }
23363
23364 // massflux intentionally without rho
23365 massflux += un_N * area;
23366 T_mean += T_N * area;
23367 rho_mean += rho * area;
23368 rho_min = mMin(rho, rho_min);
23369 rho_max = mMax(rho, rho_max);
23370 }
23371
23372 MInt noExchangeData = 3;
23373 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
23374 comm_buff[0] = massflux;
23375 comm_buff[1] = T_mean;
23376 comm_buff[2] = rho_mean;
23377
23378 if(noDomains() > 1) {
23379 MPI_Allreduce(MPI_IN_PLACE, &comm_buff[0], noExchangeData, MPI_DOUBLE, MPI_SUM,
23380 m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_, "MPI_IN_PLACE", "comm_buff[0]");
23381 MPI_Allreduce(MPI_IN_PLACE, &rho_max, 1, MPI_DOUBLE, MPI_MAX, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
23382 "MPI_IN_PLACE", "rho_max");
23383 MPI_Allreduce(MPI_IN_PLACE, &rho_min, 1, MPI_DOUBLE, MPI_MIN, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
23384 "MPI_IN_PLACE", "rho_min");
23385 }
23386
23387 massflux = comm_buff[0];
23388 T_mean = comm_buff[1];
23389 rho_mean = comm_buff[2];
23390
23391 T_mean /= inflowArea;
23392 rho_mean /= inflowArea;
23393
23394 MFloat mach[2] = {F0, F0};
23395 cbcMachCo(bcId, mach);
23396 MFloat meanM = mach[0];
23397 MFloat maxM = mach[1];
23398
23399
23400 MFloat T_out = sysEqn().temperature_IR(massflux / inflowArea);
23401 MFloat p_out = sysEqn().pressure_IR(T_out);
23402 if(p_out / sysEqn().p_Ref() > 1) p_out = sysEqn().p_Ref();
23403 if(T_out > 1) T_out = 1;
23404 const MFloat p_target = p_out;
23405 MFloat T_target;
23406 if(dirN % 2 == 1) {
23407 T_target = T_out; // intake-side
23408 } else {
23409 T_target = T_mean; // exhaust side
23410 }
23411
23412 if(globalTimeStep % 10 == 0 && m_solver->m_RKStep == 0 && domainId() == m_cbcDomainMin[cbcId]) {
23413 cerr << globalTimeStep << " " << bcId << " " << (dirN % 2)
23414 << " M_mean, M_max, T_target, p_target, rho_mean, massflux, T_mean, rho_min, rho_max" << setprecision(9)
23415 << meanM << ", " << maxM << ", " << T_target << ", " << p_target << ", " << rho_mean << ", " << rho_min << ", "
23416 << rho_max << ", " << massflux << " " << T_mean << endl;
23417 // check engine inflow
23418 /*
23419 if(dirN % 2 == 1 && globalTimeStep % 10 == 0 && m_solver->m_engineSetup) {
23420 // compute isotropic inflowFlux for comparison:
23421 const MInt pistonBodyId = 1;
23422 const MInt pistonNormal = 1; // 0: x, 1: y, 2: z
23423 // const MFloat boreArea = PI / 4 / 2;
23424 // for circle with diameter 1 and 2 inflow ducts (TINA)
23425 const MFloat boreArea = PI / 4;
23426 // for circle with diameter 1 and 1 inflow duct ( HELEN)
23427 // const MFloat boreArea = PI / 4 / 4;
23428 // for quarter circle with diameter 1 and 1 inflow duct ( Inflow-test)
23429 const MFloat volFluxMean = fabs(m_solver->m_bodyVelocity[pistonBodyId * nDim + pistonNormal] * boreArea);
23430 const MFloat flux_iso = volFluxMean / inflowArea;
23431 const MFloat flux = massflux / inflowArea;
23432 const MFloat flux_pos = massflux_pos / area_pos;
23433 const MFloat flux_neg = massflux_neg / area_neg;
23434 const MFloat flux_dif = fabs(flux - flux_iso) / flux * 100;
23435 cerr << "Mean flux " << flux << " positive flux " << flux_pos << " negative flux " << flux_neg
23436 << " isotropic inlow flux " << flux_iso << " dif: " << flux_dif << endl;
23437 }
23438 */
23439 }
23440 ASSERT(!std::isnan(massflux), "ERROR: Mass-flux is nan!");
23441
23442 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
23443 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
23444 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
23445 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
23446 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
23447
23448 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
23449 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
23450
23451 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
23452 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
23453
23454 if(m_solver->a_isHalo(cellId)) continue;
23455 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
23456 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
23457
23458 // get neighbor for eddy calculation
23459 MFloat un_N = 0;
23460 MFloat ut_N[nDim - 1] = {0};
23461
23462 // check neighbor active!
23463 if(m_solver->checkNeighborActive(cellId, dirN) && m_solver->a_hasNeighbor(cellId, dirN)) {
23464 const MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
23465
23466 for(MInt n = 0; n < nDim; n++) {
23467 un_N += m_solver->a_variable(nghbrN, CV->RHO_VV[n]) * m_dirNormal[cbcId][n];
23468 ut_N[0] += m_solver->a_variable(nghbrN, CV->RHO_VV[n]) * m_dirTangent[cbcId][n];
23469 }
23470 IF_CONSTEXPR(nDim == 3) { ut_N[1] = m_solver->a_variable(nghbrN, CV->RHO_VV[dimT2]); }
23471 }
23472
23473 MInt bndryId = m_solver->a_bndryId(cellId);
23474 if(bndryId > -1) {
23475 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
23476 }
23477
23478 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
23479 V.fill(F0);
23480 if(m_cbcViscous) {
23481 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
23482 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
23483 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
23484 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
23485 &cutOffStencilCellIds[0], &V[0]);
23486 }
23487
23488 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
23489
23490 // eddy detection:
23491 MFloat eddy = POW2(ut_N[0]) / POW2(un_N);
23492 IF_CONSTEXPR(nDim == 3) { eddy = (POW2(ut_N[0]) + POW2(ut_N[1])) / POW2(un_N); }
23493
23494 MBool isInflow = true;
23495 if(dirN % 2 == 0) {
23496 if(un_N > F0) {
23497 isInflow = false;
23498 }
23499 } else {
23500 if(un_N < F0) {
23501 isInflow = false;
23502 }
23503 }
23504
23505 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
23506 MFloat ut1 = F0;
23507
23508 for(MInt n = 0; n < nDim; n++) {
23509 ut1 += m_solver->a_pvariable(cellId, PV->VV[n]) * m_dirTangent[cbcId][n];
23510 }
23511
23512 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
23513 MFloat a = sysEqn().speedOfSound(rho, p);
23514 const MFloat Temp = sysEqn().temperature_ES(rho, p);
23515
23516 if(isInflow) {
23517 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
23518 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
23519
23520 if(dirN % 2 == 0) {
23521 L[0] = K[0] * (p - p_target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
23522 } else {
23523 L[last] = K[last] * (p - p_target) + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
23524 }
23525
23526 L[1] = K[1] * (Temp - T_target) + (a * a * T[0] - T[last]) - V[last];
23527 L[2] = K[2] * ut1 + T[2] + V[2];
23528 IF_CONSTEXPR(nDim == 3) {
23529 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
23530 L[3] = K[3] * ut2 + T[3] + V[3];
23531 }
23532
23533 MBool limitVariable = false;
23534 if(m_solver->a_pvariable(cellId, PV->RHO) > 1.0000001) {
23535 m_solver->a_pvariable(cellId, PV->RHO) = 1;
23536 limitVariable = true;
23537 }
23538 if(m_solver->a_pvariable(cellId, PV->P) / sysEqn().p_Ref() > 1.0000001) {
23539 m_solver->a_pvariable(cellId, PV->P) = sysEqn().p_Ref();
23540 limitVariable = true;
23541 }
23542
23543 if(limitVariable) {
23545 }
23546
23547 } else {
23548 MFloat beta = meanM;
23549
23550 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
23551 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
23552
23553 if(eddy > 1) {
23554 // TODO labels:FV update testcase to new version!
23555 if(!m_solver->m_engineSetup) {
23556 K[0] = 0;
23557 } else {
23558 // update: only set K1 to zero for considerable mass-flux through the
23559 // boundary!
23560 if(fabs(massflux) > 0.05) {
23561 K[0] = 0;
23562 } else {
23563 // surpress fluctuations in transversal velocities (sponging)
23564 // const MFloat K3 = eta3 * 10 * a / LN;
23565 L[2] = K[2] * ut1 + T[2] + V[2];
23566 IF_CONSTEXPR(nDim == 3) {
23567 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
23568 L[3] = K[3] * ut2 + T[3] + V[3];
23569 }
23570 }
23571 }
23572 }
23573
23574 if(dirN % 2 == 0) {
23575 L[0] = K[0] * (p - p_target) + (F1 - beta) * (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
23576 } else {
23577 L[last] = K[last] * (p - p_target) + (F1 - beta) * (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
23578 }
23579
23580 // additional amplitude description for low mass-fluxes at outflow!
23581 if(dirN % 2 != 0 && fabs(massflux) < 0.05 && m_solver->m_engineSetup) {
23582 const MFloat K2_outflow = m_cbcRelax[cbcId][1] * rho * a / m_cbcLref[cbcId];
23583 L[1] = K2_outflow * (Temp - T_target) + (a * a * T[0] - T[last]) - V[last];
23584 }
23585 }
23586
23587 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
23588 }
23589}
MInt domainId() const
Return the domain id of this solver on the current MPI communicator.
virtual void setConservativeVariables(MInt cellId)
computes conservative from primitive variables for given cell id
MLong c_globalId(const MInt cellId) const
Returns the global grid id of the grid cell cellId.

◆ cbc1099_1091_engineOld()

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

◆ cbc1099_1091_local()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099_1091_local ( MInt  bcId)

Subsonic partially reflecting characteristic outflow/inflow condition - cut off
TODO: Great differences between 2D- and 3D-versions, should be checked

Definition at line 18820 of file fvcartesianbndrycndxd.cpp.

18820 {
18821 TRACE();
18822
18823 if(m_sortedCutOffCells[bcId]->size() == 0) {
18824 return;
18825 }
18826
18827 MInt cbcId = m_cbcBndryCndIds[bcId];
18828
18829 MInt dirN = m_cbcDir[cbcId][0];
18830 MInt dimN = m_cbcDir[cbcId][1];
18831 MInt dimT1 = m_cbcDir[cbcId][2];
18832 MInt dimT2 = m_cbcDir[cbcId][nDim];
18833
18837
18838 MFloat inflowArea = m_cbcInflowArea[cbcId];
18839 IF_CONSTEXPR(nDim == 3) { R = sqrt(inflowArea / PI); }
18840 IF_CONSTEXPR(nDim == 2) {
18841 targetPressure = sysEqn().p_Ref();
18842 H = inflowArea * F1B2;
18843 }
18844
18845 MInt last = nDim + 1;
18846 // MInt last = 4;
18847 if(last != 4) mTerm(1, AT_, "Last is not four!");
18848
18849 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
18850 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
18851 MFloatScratchSpace gradP(nDim, AT_, "gradP");
18852 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
18853 gradY.fill(F0);
18854
18855 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
18856 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
18857 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
18858 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
18859 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
18860
18861 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
18862 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
18863
18864 MFloatScratchSpace L(PV->noVariables, AT_, "L");
18865 MFloatScratchSpace T(PV->noVariables, AT_, "T");
18866 MFloatScratchSpace V(PV->noVariables, AT_, "V");
18867 MFloatScratchSpace K(PV->noVariables, AT_, "K");
18868
18869 MFloat massflux = F0;
18870 MFloat T_mean = F0;
18871 MFloat massflux_pos = F0;
18872 MFloat massflux_neg = F0;
18873
18874 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18875 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18876 MInt bndryId = m_solver->a_bndryId(cellId);
18877
18878 if(m_solver->a_isHalo(cellId)) continue;
18879 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18880 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18881
18882 MFloat area = -1;
18883 if(bndryId > -1) {
18884 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
18885 if(srfcId > -1) {
18886 area = m_solver->a_surfaceArea(srfcId);
18887 IF_CONSTEXPR(nDim == 3) ASSERT(area <= POW2(m_solver->c_cellLengthAtCell(cellId)), "");
18888 } else {
18889 mTerm(1, AT_, "something went wrong!");
18890 }
18891 } else {
18892 IF_CONSTEXPR(nDim == 2) area = m_solver->c_cellLengthAtCell(cellId);
18893 IF_CONSTEXPR(nDim == 3) area = POW2(m_solver->c_cellLengthAtCell(cellId));
18894 }
18895
18896 ASSERT(area > -1, "");
18897 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
18898 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
18899 const MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
18900 const MFloat Temp = sysEqn().temperature_ES(rho, p);
18901 MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
18902 const MFloat un_N = m_solver->a_pvariable(nghbrN, PV->VV[dimN]);
18903
18904
18905 if(rho < F0 || std::isnan(rho) || std::isnan(un)) {
18906 cerr << "NAN detected in cutOff-Cell " << m_solver->c_globalId(cellId) << " " << m_solver->a_isHalo(cellId) << " "
18907 << m_solver->a_bndryId(cellId) << " " << rho << endl;
18908 }
18909
18910 if(un_N > F0) {
18911 massflux_pos += un_N * area;
18912 } else {
18913 massflux_neg += un_N * area;
18914 }
18915
18916 massflux += un_N * area * rho;
18917 T_mean += Temp * area;
18918 }
18919
18920 MFloat mach[2] = {F0, F0};
18921 cbcMachCo(bcId, mach);
18922 MFloat meanM = mach[0];
18923 MFloat maxM = mach[1];
18924
18925 MInt noExchangeData = 4;
18926 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
18927 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
18928 comm_buff[0] = massflux;
18929 comm_buff[1] = T_mean;
18930 comm_buff[2] = massflux_pos;
18931 comm_buff[3] = massflux_neg;
18932
18933 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 4, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
18934 AT_, "comm_buff[0]", "comm_buff_result[0]");
18935
18936 massflux = comm_buff_result[0];
18937 T_mean = comm_buff_result[1];
18938 massflux_pos = comm_buff_result[2];
18939 massflux_neg = comm_buff_result[3];
18940
18941 T_mean /= inflowArea;
18942
18943 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
18944
18945 MFloat T_target = 1 - gammaMinusOne * F1B2 * (massflux * massflux / inflowArea / inflowArea);
18946 MFloat p_Target = sysEqn().pressure_IR(T_target);
18947
18948 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18949 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18950
18951 if(m_solver->a_isHalo(cellId)) continue;
18952 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18953 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18954
18955 MInt bndryId = m_solver->a_bndryId(cellId);
18956 if(bndryId > -1) {
18957 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
18958 }
18959
18960 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
18961 V.fill(F0);
18962 if(m_cbcViscous) {
18963 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
18964 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
18965 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
18966 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
18967 &cutOffStencilCellIds[0], &V[0]);
18968 }
18969
18970 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
18971
18972 // This is where you differentiate between inflow and outflow
18973 MFloat un_mean = m_solver->a_pvariable(cellId, PV->VV[dimN]);
18974
18975 MBool hasBndryNghbr = false;
18976 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
18977 MInt recNghbr = m_solver->a_reconstructionNeighborId(cellId, nghbr);
18978 if(m_solver->a_bndryId(recNghbr) > -1) hasBndryNghbr = true;
18979 }
18980
18981 MFloat massFluxSum = (abs(massflux_neg) + abs(massflux_pos));
18982 MFloat negMassFluxFactor = F0;
18983 MFloat posMassFluxFactor = F0;
18984 if(massFluxSum > m_solver->m_eps) {
18985 negMassFluxFactor = abs(massflux_neg) / massFluxSum;
18986 posMassFluxFactor = abs(massflux_pos) / massFluxSum;
18987 } else {
18988 if(dirN % 2 == 0) {
18989 negMassFluxFactor = F1;
18990 } else {
18991 posMassFluxFactor = F1;
18992 }
18993 }
18994
18995 MBool isInflow = true;
18996 if(dirN % 2 == 0) {
18997 if(un_mean > F0) {
18998 isInflow = false;
18999 } else {
19000 T_target = negMassFluxFactor * T_target + posMassFluxFactor * T_mean;
19001 }
19002 } else {
19003 if(un_mean < F0) {
19004 isInflow = false;
19005 } else {
19006 T_target = posMassFluxFactor * T_target + posMassFluxFactor * T_mean;
19007 }
19008 }
19009
19010 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
19011 const MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
19012 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
19013 MFloat a = sysEqn().speedOfSound(rho, p);
19014 const MFloat Temp = sysEqn().temperature_ES(rho, p);
19015
19016 if(isInflow) {
19017 targetPressure = p_Target;
19018 MFloat beta = F0;
19019
19020 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
19021 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
19022
19023 MFloat LN = 100;
19024 K[0] = K[0] * m_cbcLref[cbcId] / LN;
19025 K[1] = K[1] * m_cbcLref[cbcId] / LN;
19026 K[2] = K[2] * m_cbcLref[cbcId] / LN * 100;
19027 K[last] = K[last] * m_cbcLref[cbcId] / LN;
19028
19029 MFloat ceta = F1;
19030 if(dirN % 2 == 0)
19031 ceta = -F1;
19032 else
19033 ceta = F1;
19034
19035 // Timw: don't use BndryNghbr-correction!
19036 if((m_solver->a_bndryId(cellId) > -1 || hasBndryNghbr) && false) {
19037 if(dirN % 2 == 0) {
19038 L[0] = K[0] * (p - targetPressure);
19039 } else {
19040 L[last] = K[last] * (p - targetPressure);
19041 }
19042 L[1] = K[1] * (Temp - T_target);
19043 L[2] = K[2] * ut1;
19044 IF_CONSTEXPR(nDim == 3) {
19045 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
19046 L[3] = K[2] * ut2;
19047 }
19048 } else {
19049 if(dirN % 2 == 0) {
19050 L[0] = K[0] * (p - targetPressure) + (beta - 1) * (T[last] + ceta * rho * a * T[1])
19051 + (V[last] + ceta * rho * a * V[1]);
19052 } else {
19053 L[last] = K[last] * (p - targetPressure) + (beta - 1) * (T[last] + ceta * rho * a * T[1])
19054 + (V[last] + ceta * rho * a * V[1]);
19055 }
19056
19057 L[1] = K[1] * (Temp - T_target) - (a * a * T[0] - T[last]) + (a * a * V[0] - V[last]);
19058 L[2] = K[2] * ut1 - T[2] * 0.9;
19059 IF_CONSTEXPR(nDim == 3) {
19060 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
19061 K[3] = K[3] * m_cbcLref[cbcId] / LN * 100;
19062 L[3] = K[3] * ut2 - T[3] * 0.9;
19063 }
19064 }
19065 } else {
19066 targetPressure = sysEqn().p_Ref();
19067 MFloat beta = meanM;
19068
19069 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
19070 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
19071
19072 // for fv-mb: LN = 100.0
19073 MFloat LN = 100;
19074 K[0] = K[0] * m_cbcLref[cbcId] * m_sigmaNonRefl / LN;
19075 K[2] = m_cbcRelax[cbcId][2] * a / LN * 10;
19076
19077 MFloat ceta = F1;
19078 if(dirN % 2 == 0)
19079 ceta = -F1;
19080 else
19081 ceta = F1;
19082
19083 MFloat deltaP = (p - targetPressure);
19084 MFloat tmpP = sysEqn().pressure_ES(T_mean, rho) - targetPressure;
19085 if((m_solver->a_bndryId(cellId) > -1 || hasBndryNghbr)) {
19086 if(tmpP > deltaP) deltaP = tmpP;
19087 if(dirN % 2 == 0) // outflow on pos. coordinate direction -> L1 has to be modeled
19088 L[0] = K[0] * (deltaP);
19089 else
19090 L[last] = K[0] * (deltaP);
19091
19092 } else {
19093 if(tmpP > deltaP) deltaP = tmpP;
19094 if(dirN % 2 == 0) {
19095 L[0] = K[0] * (deltaP) + (beta - 1) * (T[last] + ceta * rho * a * T[1]) + (V[last] + ceta * rho * a * V[0]);
19096 } else {
19097 L[last] =
19098 K[0] * (deltaP) + (beta - 1) * (T[last] + ceta * rho * a * T[1]) + (V[last] + ceta * rho * a * V[1]);
19099 }
19100
19101 IF_CONSTEXPR(nDim == 3) {
19102 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
19103 L[2] += K[2] * ut1;
19104 L[3] += K[2] * ut2;
19105 }
19106 }
19107 }
19108 IF_CONSTEXPR(nDim == 3) {
19109 if((m_solver->a_bndryId(cellId) > -1 || hasBndryNghbr)) {
19110 T[0] = F0;
19111 T[1] = F0;
19112 T[2] = F0;
19113 T[3] = F0;
19114 T[last] = F0;
19115 V[0] = F0;
19116 V[1] = F0;
19117 V[2] = F0;
19118 V[3] = F0;
19119 V[last] = F0;
19120 }
19121 }
19122 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
19123 }
19124}
MFloat m_static_cbc1099_1091_local_R
MFloat m_static_cbc1099_1091_local_H
MFloat m_static_cbc1099_1091_local_targetPressure

◆ cbc1099_1091_local_comb()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099_1091_local_comb ( MInt  bcId)

Subsonic partially reflecting characteristic outflow condition - cut off - turbulent combustion

Definition at line 19133 of file fvcartesianbndrycndxd.cpp.

19133 {
19134 TRACE();
19135
19136 if(m_sortedCutOffCells[bcId]->size() == 0) {
19137 return;
19138 }
19139
19140 MInt cbcId = m_cbcBndryCndIds[bcId];
19141
19142 MInt dirN = m_cbcDir[cbcId][0];
19143 MInt dimN = m_cbcDir[cbcId][1];
19144 MInt dimT1 = m_cbcDir[cbcId][2];
19145 MInt dimT2 = m_cbcDir[cbcId][nDim];
19146
19147 MFloat outFlowArea = m_cbcInflowArea[cbcId];
19148
19149 MInt last = nDim + 1;
19150
19151 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
19152 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
19153 MFloatScratchSpace gradP(nDim, AT_, "gradP");
19154 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
19155 gradY.fill(F0);
19156
19157
19158 MFloatScratchSpace L(PV->noVariables, AT_, "L");
19159 MFloatScratchSpace T(PV->noVariables, AT_, "T");
19160 MFloatScratchSpace V(PV->noVariables, AT_, "V");
19161 MFloatScratchSpace K(PV->noVariables, AT_, "K");
19162
19163 MFloat massflux = F0;
19164 MFloat T_mean = F0;
19165 MFloat rho_mean = F0;
19166
19167 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19168 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19169 MInt bndryId = m_solver->a_bndryId(cellId);
19170
19171 if(m_solver->a_isHalo(cellId)) continue;
19172 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19173 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19174
19175 MFloat area;
19176 if(bndryId > -1) {
19177 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
19178 // cell
19179 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
19180 if(srfcId > -1) {
19181 area = m_solver->a_surfaceArea(srfcId);
19182 } else {
19183 mTerm(1, AT_, "something went wrong!");
19184 }
19185 } else {
19186 IF_CONSTEXPR(nDim == 3) area = POW2(m_solver->c_cellLengthAtCell(cellId));
19187 IF_CONSTEXPR(nDim == 2) area = m_solver->c_cellLengthAtCell(cellId);
19188 }
19189
19190 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
19191 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
19192 const MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
19193 const MFloat Temp = sysEqn().temperature_ES(rho, p);
19194
19195 massflux += un * area * rho;
19196 T_mean += Temp * area;
19197 IF_CONSTEXPR(nDim == 2) rho_mean += rho * area;
19198 }
19199
19200 MFloat mach[2] = {F0, F0};
19201 cbcMachCo(bcId, mach);
19202 MFloat meanM = mach[0];
19203 MFloat maxM = mach[1];
19204
19205 MInt noExchangeData = 2;
19206 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
19207 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
19208 comm_buff[0] = massflux;
19209 comm_buff[1] = T_mean;
19210
19211
19212 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 2, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
19213 AT_, "comm_buff[0]", "comm_buff_result[0]");
19214
19215 IF_CONSTEXPR(nDim == 2) {
19216 MPI_Allreduce(MPI_IN_PLACE, &rho_mean, 1, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
19217 "MPI_IN_PLACE", "rho_mean");
19218 rho_mean /= outFlowArea;
19219
19220 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
19221 MFloat T_target = 1 - gammaMinusOne * F1B2 * (massflux * massflux / outFlowArea / outFlowArea);
19222 MFloat p_Target = sysEqn().pressure_ES(T_target, rho_mean);
19223 MFloat p_test = p_Target;
19224 for(MInt i = 0; i < 20; i++) {
19225 p_test = sysEqn().pressure_IRit(p_test, massflux);
19226 }
19227 m_solver->m_jetPressure = p_Target;
19228 m_solver->m_jetDensity = rho_mean; // gamma*p_Target/T_target;
19229 m_solver->m_jetTemperature = T_target;
19230 }
19231
19232 massflux = comm_buff_result[0];
19233 T_mean = comm_buff_result[1];
19234 T_mean /= outFlowArea;
19235
19236 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
19237 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
19238 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
19239 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
19240 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
19241
19242 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
19243 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
19244
19245 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19246 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19247
19248 if(m_solver->a_isHalo(cellId)) continue;
19249 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19250 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19251
19252 MInt bndryId = m_solver->a_bndryId(cellId);
19253 if(bndryId > -1) {
19254 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
19255 }
19256
19257 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
19258 V.fill(F0);
19259 if(m_cbcViscous) {
19260 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
19261 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
19262 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
19263 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
19264 &cutOffStencilCellIds[0], &V[0]);
19265 }
19266
19267 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
19268
19269 // This is where you differentiate between inflow and outflow
19270 MFloat un_mean = m_solver->a_pvariable(cellId, PV->VV[dimN]);
19271 MFloat T_target_new = 0.0;
19272
19273 MBool isInflow = true;
19274 if(dirN % 2 == 0) {
19275 if(un_mean > F0) {
19276 isInflow = false;
19277 } else {
19278 T_target_new = T_mean;
19279 }
19280 } else {
19281 if(un_mean < F0) {
19282 isInflow = false;
19283 } else {
19284 T_target_new = T_mean;
19285 }
19286 }
19287
19288 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
19289 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
19290 MFloat a = sysEqn().speedOfSound(rho, p);
19291 const MFloat Temp = sysEqn().temperature_ES(rho, p);
19292
19293 const MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
19294
19295 MFloat targetPressure;
19296
19297 if(isInflow) {
19298 targetPressure = 0.0;
19299 MFloat beta = F0;
19300
19301 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
19302 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
19303
19304 IF_CONSTEXPR(nDim == 3) {
19305 K[2] = K[2] * 100;
19306 K[3] = K[3] * 100;
19307 }
19308 K[last] = K[0];
19309
19310 MFloat ceta = F1;
19311 if(dirN % 2 == 0)
19312 ceta = -F1;
19313 else
19314 ceta = F1;
19315
19316 if(dirN % 2 == 0) {
19317 L[0] = K[0] * (p - targetPressure) + (beta - 1) * (T[last] + ceta * rho * a * T[1])
19318 + (V[last] + ceta * rho * a * V[1]);
19319 } else {
19320 L[last] = K[last] * (p - targetPressure) + (beta - 1) * (T[last] + ceta * rho * a * T[1])
19321 + (V[last] + ceta * rho * a * V[1]);
19322 }
19323
19324 L[1] = K[1] * (Temp - T_target_new) - (a * a * T[0] - T[last]) + (a * a * V[0] - V[last]);
19325 L[2] = K[2] * ut1;
19326 IF_CONSTEXPR(nDim == 3) {
19327 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
19328 L[3] = K[3] * ut2;
19329 }
19330 } else {
19331 targetPressure = sysEqn().p_Ref();
19332 MFloat beta = meanM;
19333
19334 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
19335 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
19336
19337 IF_CONSTEXPR(nDim == 3) {
19338 K[2] = K[2] * 100;
19339 K[3] = K[3] * 100;
19340 }
19341 K[0] = K[0] * m_sigmaNonRefl;
19342 K[last] = K[0];
19343
19344 MFloat ceta = F1;
19345 if(dirN % 2 == 0)
19346 ceta = -F1;
19347 else
19348 ceta = F1;
19349
19350 MFloat deltaP = (p - targetPressure);
19351
19352 if(dirN % 2 == 0) {
19353 L[0] = K[0] * (deltaP) + (beta - 1) * (T[last] + ceta * rho * a * T[1]) + (V[last] + ceta * rho * a * V[0]);
19354 } else {
19355 L[last] = K[0] * (deltaP) + (beta - 1) * (T[last] + ceta * rho * a * T[1]) + (V[last] + ceta * rho * a * V[1]);
19356 }
19357 L[2] = K[2] * ut1;
19358 IF_CONSTEXPR(nDim == 3) {
19359 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
19360 L[3] = K[2] * ut2;
19361 }
19362 }
19363 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
19364 }
19365}

◆ cbc1099_1091d() [1/2]

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099_1091d ( MInt  bcId)

Subsonic partially reflecting characteristic inflow/outflow condition - uses methodology of cbc1099 and cbc1091d
no 2D-version available yet!

Author
Claudia Guenther

Definition at line 22905 of file fvcartesianbndrycndxd.cpp.

22905 {
22906 TRACE();
22907
22908 if(m_sortedCutOffCells[bcId]->size() == 0) {
22909 return;
22910 }
22911
22912 MInt cbcId = m_cbcBndryCndIds[bcId];
22913
22914 MInt dirN = m_cbcDir[cbcId][0];
22915 MInt dimN = m_cbcDir[cbcId][1];
22916 MInt dimT1 = m_cbcDir[cbcId][2];
22917 MInt dimT2 = m_cbcDir[cbcId][nDim];
22918
22919 MFloat inflowArea = m_cbcInflowArea[cbcId];
22920 MFloat targetPressure = sysEqn().p_Ref();
22921 MInt last = nDim + 1;
22922
22923 const MFloat R = sqrt(inflowArea / PI);
22924 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
22925 const MFloat ut1_target = F0;
22926
22927 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
22928 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
22929 MFloatScratchSpace gradP(nDim, AT_, "gradP");
22930 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
22931 gradY.fill(F0);
22932
22933 MFloatScratchSpace L(PV->noVariables, AT_, "L");
22934 MFloatScratchSpace T(PV->noVariables, AT_, "T");
22935 MFloatScratchSpace V(PV->noVariables, AT_, "V");
22936 MFloatScratchSpace K(PV->noVariables, AT_, "K");
22937
22938 MFloat massflux = F0;
22939 MFloat testSum2 = F0;
22940 MFloat T_mean = F0;
22941 MFloat massflux_pos = F0;
22942 MFloat massflux_neg = F0;
22943
22944 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
22945 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
22946 MInt bndryId = m_solver->a_bndryId(cellId);
22947
22948 if(m_solver->a_isHalo(cellId)) continue;
22949 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
22950 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
22951
22952 MFloat area;
22953 if(bndryId > -1) {
22954 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
22955 // cell
22956 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
22957 if(srfcId > -1) {
22958 area = m_solver->a_surfaceArea(srfcId);
22959 } else {
22960 mTerm(1, AT_, "something went wrong!");
22961 }
22962 } else {
22963 area = POW2(m_solver->c_cellLengthAtCell(cellId));
22964 }
22965
22966 MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
22967 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
22968 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
22969 const MFloat un_N = m_solver->a_pvariable(nghbrN, PV->VV[dimN]);
22970 const MFloat Temp = sysEqn().temperature_ES(rho, p);
22971
22972 const MFloat rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
22973 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
22974 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
22975
22976 testSum2 += area * rsquare;
22977 massflux += un_N * area;
22978 T_mean += Temp * area;
22979
22980 if(un_N > F0) {
22981 massflux_pos += un_N * area;
22982 } else {
22983 massflux_neg += un_N * area;
22984 }
22985 }
22986
22987 MFloat mach[2] = {F0, F0};
22988 cbcMachCo(bcId, mach);
22989 MFloat meanM = mach[0];
22990 MFloat maxM = mach[1];
22991
22992 MInt noExchangeData = 5;
22993 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
22994 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
22995 comm_buff[0] = massflux;
22996 comm_buff[1] = testSum2;
22997 comm_buff[2] = T_mean;
22998 comm_buff[3] = massflux_pos;
22999 comm_buff[4] = massflux_neg;
23000
23001 if(noDomains() > 1) {
23002 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 5, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
23003 AT_, "comm_buff[0]", "comm_buff_result[0]");
23004 }
23005
23006 massflux = comm_buff_result[0];
23007 testSum2 = comm_buff_result[2];
23008 T_mean = comm_buff_result[3];
23009 massflux_pos = comm_buff_result[4];
23010 massflux_neg = comm_buff_result[5];
23011 T_mean /= inflowArea;
23012 MFloat massflux_test = F2 * (F1 - testSum2 / (inflowArea * R * R));
23013 MFloat un_correctionFactor = F1;
23014 if(fabs(massflux_test) > m_solver->m_eps) un_correctionFactor = F1 / massflux_test;
23015
23016 MFloat T_target = 1 - gammaMinusOne * F1B2 * (massflux * massflux / inflowArea / inflowArea);
23017 MFloat p_Target = sysEqn().pressure_IR(T_target);
23018
23019 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
23020 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
23021 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
23022 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
23023 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
23024
23025 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
23026 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
23027
23028 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
23029 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
23030
23031 if(m_solver->a_isHalo(cellId)) continue;
23032 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
23033 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
23034
23035 MInt bndryId = m_solver->a_bndryId(cellId);
23036 if(bndryId > -1) {
23037 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
23038 }
23039
23040 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
23041 V.fill(F0);
23042 if(m_cbcViscous) {
23043 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
23044 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
23045 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
23046 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
23047 &cutOffStencilCellIds[0], &V[0]);
23048 }
23049
23050 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
23051
23052 const MFloat rsquare = POW2(m_solver->a_coordinate(cellId, 0) - m_cbcReferencePoint[cbcId][0])
23053 + POW2(m_solver->a_coordinate(cellId, 1) - m_cbcReferencePoint[cbcId][1])
23054 + POW2(m_solver->a_coordinate(cellId, 2) - m_cbcReferencePoint[cbcId][2]);
23055
23056 // This is where you differentiate between inflow and outflow
23057 MFloat un_mean = m_solver->a_pvariable(cellId, PV->VV[dimN]);
23058
23059 MBool isInflow = true;
23060 if(dirN % 2 == 0) {
23061 if(un_mean > F0) {
23062 isInflow = false;
23063 } else {
23064 T_target = abs(massflux_neg) / (abs(massflux_neg) + abs(massflux_pos)) * T_target
23065 + abs(massflux_pos) / (abs(massflux_neg) + abs(massflux_pos)) * T_mean;
23066 }
23067 } else {
23068 if(un_mean < F0) {
23069 isInflow = false;
23070 } else {
23071 T_target = abs(massflux_pos) / (abs(massflux_neg) + abs(massflux_pos)) * T_target
23072 + abs(massflux_neg) / (abs(massflux_neg) + abs(massflux_pos)) * T_mean;
23073 }
23074 }
23075
23076 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
23077 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
23078 MFloat a = sysEqn().speedOfSound(rho, p);
23079
23080 const MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
23081 const MFloat Temp = sysEqn().temperature_ES(rho, p);
23082
23083 targetPressure = p_Target;
23084
23085 if(isInflow) {
23086 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
23087 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
23088
23089 MFloat ceta = F1;
23090 if(dirN % 2 == 0)
23091 ceta = -F1;
23092 else
23093 ceta = F1;
23094
23095 if(dirN % 2 == 0) {
23096 L[0] = K[0] * (p - targetPressure) + (T[last] + ceta * rho * a * T[1]) + (V[last] + ceta * rho * a * V[1]);
23097 } else {
23098 L[last] =
23099 K[last] * (p - targetPressure) + (T[last] + ceta * rho * a * T[1]) + (V[last] + ceta * rho * a * V[1]);
23100 }
23101 L[1] = K[1] * (Temp - T_target) + (a * a * T[0] - T[last]) + (a * a * V[0] - V[last]);
23102 L[2] = K[2] * (ut1 - ut1_target) + T[2] + V[2];
23103 IF_CONSTEXPR(nDim == 3) {
23104 const MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
23105 const MFloat ut2_target = F0;
23106 L[3] = K[3] * (ut2 - ut2_target) + T[3] + V[3];
23107 }
23108 } else { // Outflow
23109 MFloat beta = meanM;
23110
23111 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
23112 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
23113
23114 MFloat ceta = F1;
23115 if(dirN % 2 == 0)
23116 ceta = -F1;
23117 else
23118 ceta = F1;
23119
23120 if(dirN % 2 == 0) // outflow on pos. coordinate direction -> L1 has to be modeled
23121 L[0] = K[0] * (p - targetPressure) + (F1 - beta) * (T[last] + ceta * rho * a * T[1])
23122 + (V[last] + ceta * rho * a * V[1]);
23123 else
23124 L[last] = K[last] * (p - targetPressure) + (F1 - beta) * (T[last] + ceta * rho * a * T[1])
23125 + (V[last] + ceta * rho * a * V[1]);
23126 }
23127 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
23128
23129 MFloat un_target = F2 * massflux / inflowArea * (F1 - rsquare / (R * R)) * un_correctionFactor;
23130 m_solver->a_pvariable(cellId, PV->VV[dimN]) = un_target;
23131 }
23132}

◆ cbc1099_1091d() [2/2]

void FvBndryCndXD< 3, FvSysEqnEEGas< 3 > >::cbc1099_1091d ( MInt  )

Definition at line 14 of file fvcartesianbndrycndxd_inst_3d_eegas.cpp.

14 {
15 TERMM(-1, "requires CV->RHO_E");
16}

◆ cbc1099_1091d_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099_1091d_after ( MInt  )

◆ cbc1099a()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099a ( MInt  bcId)

Subsonic fully reflecting characteristic outflow condition - cut off
pstat is set, incl. shear and transverse terms

Definition at line 18700 of file fvcartesianbndrycndxd.cpp.

18700 {
18701 TRACE();
18702
18703 if(m_sortedCutOffCells[bcId]->size() == 0) {
18704 return;
18705 }
18706
18707 MInt cbcId = m_cbcBndryCndIds[bcId];
18708
18709 MInt dirN = m_cbcDir[cbcId][0];
18710 MInt dimN = m_cbcDir[cbcId][1];
18711 MInt dimT1 = m_cbcDir[cbcId][2];
18712 MInt dimT2 = m_cbcDir[cbcId][nDim];
18713
18714 MInt last = nDim + 1;
18715
18716 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
18717 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
18718 MFloatScratchSpace gradP(nDim, AT_, "gradP");
18719 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
18720 gradY.fill(F0);
18721
18722 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
18723 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
18724 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
18725 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
18726 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
18727
18728 MFloatScratchSpace L(PV->noVariables, AT_, "L");
18729 MFloatScratchSpace T(PV->noVariables, AT_, "T");
18730 MFloatScratchSpace V(PV->noVariables, AT_, "V");
18731 MFloatScratchSpace K(PV->noVariables, AT_, "K");
18732
18733 MFloat mach[2];
18734 cbcMachCo(bcId, mach);
18735 MFloat meanM = mach[0];
18736 MFloat maxM = mach[1];
18737
18738 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
18739 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
18740
18741 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18742 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18743
18744 if(m_solver->a_isHalo(cellId)) continue;
18745
18746 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
18747 V.fill(F0);
18748 if(m_cbcViscous) {
18749 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
18750 gradQ[dimN * nDim + dimN] = F0;
18751 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
18752 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
18753 cbcViscousTerms<(unsigned char)11111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
18754 &cutOffStencilCellIds[0], &V[0]);
18755 }
18756
18757 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
18758 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
18759 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
18760
18761 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
18762 MFloat p = m_solver->a_pvariable(cellId, PV->P);
18763 MFloat a = sysEqn().speedOfSound(rho, p);
18764 const MFloat targetPressure = m_solver->m_PInfinity - m_deltaPL;
18765
18766 MFloat beta = meanM;
18767 if(dirN % 2 == 0) {
18768 L[0] = -L[last] + (F1 - beta) * (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
18769 } else {
18770 L[last] = -L[0] + (F1 - beta) * (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
18771 }
18772 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
18773 m_solver->a_rightHandSide(cellId, CV->RHO_E) = 0.0;
18774 m_solver->a_pvariable(cellId, PV->P) = targetPressure;
18775 }
18776}

◆ cbc1099a_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1099a_after ( MInt  bcId)

Definition at line 18783 of file fvcartesianbndrycndxd.cpp.

18783 {
18784 TRACE();
18785
18786 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
18787 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
18788
18789 if(m_solver->a_isHalo(cellId)) continue;
18790 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
18791 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
18792
18793 MInt bndryId = m_solver->a_bndryId(cellId);
18794 if(bndryId > -1) {
18795 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
18796 }
18797
18798 // recompute the correct energy:
18799 MFloat rho = m_solver->a_variable(cellId, CV->RHO);
18800 MFloat u = m_solver->a_variable(cellId, CV->RHO_U) / rho;
18801 MFloat v = m_solver->a_variable(cellId, CV->RHO_V) / rho;
18802 MFloat p = m_solver->a_pvariable(cellId, PV->P);
18803 MFloat E = sysEqn().internalEnergy(p, rho, (u * u + v * v));
18804 IF_CONSTEXPR(nDim == 3) {
18805 MFloat w = m_solver->a_variable(cellId, CV->RHO_W) / rho;
18806 E = sysEqn().internalEnergy(p, rho, (u * u + v * v + w * w));
18807 }
18808
18809 m_solver->a_variable(cellId, CV->RHO_E) = E;
18810 }
18811}

◆ cbc1291()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1291 ( MInt  )

◆ cbc1291a()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1291a ( MInt  )

◆ cbc1291b()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1291b ( MInt  )

◆ cbc1291tm()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1291tm ( MInt  )

◆ cbc1291tma()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1291tma ( MInt  )

◆ cbc1291tmb()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1291tmb ( MInt  )

◆ cbc1291tmc()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1291tmc ( MInt  )

◆ cbc1299()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1299 ( MInt  )

◆ cbc1299a()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1299a ( MInt  )

◆ cbc1299tm()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc1299tm ( MInt  )

◆ cbc2091a()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc2091a ( MInt  bcId)

Subsonic partially reflecting characteristic inflow condition - cut off
T0, u, v is prescribed, incl. transverse terms

Definition at line 21134 of file fvcartesianbndrycndxd.cpp.

21134 {
21135 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function cbc2091a is untested for 3D!"); }
21136 TRACE();
21137
21138 if(m_sortedCutOffCells[bcId]->size() == 0) {
21139 return;
21140 }
21141
21142 MInt cbcId = m_cbcBndryCndIds[bcId];
21143
21144 MInt dirN = m_cbcDir[cbcId][0];
21145 MInt dimN = m_cbcDir[cbcId][1];
21146 MInt dimT1 = m_cbcDir[cbcId][2];
21147 MInt dimT2 = m_cbcDir[cbcId][nDim];
21148
21149 MBool solverProfile = Context::getSolverProperty<MBool>("solverProfile", m_solverId, AT_, &solverProfile);
21150 MFloat time = m_solver->m_time;
21153
21154 MFloat inflowArea = m_cbcInflowArea[cbcId];
21155 // MFloat H = inflowArea * F1B2;
21156
21157 MInt last = nDim + 1;
21158
21159 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
21160 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
21161 MFloatScratchSpace gradP(nDim, AT_, "gradP");
21162 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
21163 gradY.fill(F0);
21164
21165 MFloatScratchSpace L(PV->noVariables, AT_, "L");
21166 MFloatScratchSpace T(PV->noVariables, AT_, "T");
21167 MFloatScratchSpace V(PV->noVariables, AT_, "V");
21168 MFloatScratchSpace K(PV->noVariables, AT_, "K");
21169
21170 MFloat mach[2] = {F0, F0};
21171 cbcMachCo(bcId, mach);
21172 MFloat maxM = mach[1];
21173
21174 MFloat massflux = F0;
21175 MFloat uInt = F0;
21176 MFloat testSum2 = F0;
21177
21178 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21179 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21180 MInt bndryId = m_solver->a_bndryId(cellId);
21181
21182 if(m_solver->a_isHalo(cellId)) continue;
21183 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21184 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21185
21186 MFloat area = F0;
21187 if(bndryId > -1) {
21188 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
21189 // cell
21190 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
21191 if(srfcId > -1)
21192 area = m_solver->a_surfaceArea(srfcId);
21193 else
21194 mTerm(1, AT_, "something went wrong!");
21195 } else {
21196 area = m_solver->c_cellLengthAtCell(cellId);
21197 }
21198
21199 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21200 const MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
21201 const MFloat y = (m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]);
21202 testSum2 += area * y * y;
21203 massflux += un * rho * area;
21204 uInt += un * area;
21205 }
21206
21207 MInt noExchangeData = 2;
21208 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
21209 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
21210 comm_buff[0] = massflux;
21211 comm_buff[1] = testSum2;
21212
21213 if(noDomains() > 1) {
21214 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 3, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
21215 AT_, "comm_buff[0]", "comm_buff_result[0]");
21216 MPI_Allreduce(MPI_IN_PLACE, &uInt, 1, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
21217 "MPI_IN_PLACE", "uInt");
21218 }
21219
21220 massflux = comm_buff_result[0];
21221 testSum2 = comm_buff_result[1];
21222 MFloat massflux_test = uInt / m_solver->m_analyticIntegralVelocity;
21223
21224 MFloat un_correctionFactor = F1;
21225 if(fabs(massflux_test) > m_solver->m_eps) un_correctionFactor = F1 / massflux_test;
21226
21227 const MFloat massflux_target = massflux * un_correctionFactor;
21228
21229 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
21230 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
21231 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
21232 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
21233 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
21234
21235 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
21236 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
21237
21238 MFloat T_target = sysEqn().temperature_ES(m_solver->m_rhoInfinity, m_solver->m_meanPressure);
21239
21240 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21241 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21242
21243 if(m_solver->a_isHalo(cellId)) continue;
21244 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21245 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21246
21247 MInt bndryId = m_solver->a_bndryId(cellId);
21248 if(bndryId > -1) {
21249 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
21250 }
21251
21252 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
21253 V.fill(F0);
21254 if(m_cbcViscous) {
21255 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
21256 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
21257 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
21258 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
21259 &cutOffStencilCellIds[0], &V[0]);
21260 }
21261
21262 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
21263 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
21264 cbcDampingInflow(cellId, bcId, maxM, &K[0], "velocity");
21265
21266 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21267 MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
21268 MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
21269
21270 MFloat p = m_solver->a_pvariable(cellId, PV->P);
21271 MFloat temp = sysEqn().temperature_ES(rho, p);
21272 MFloat a = sysEqn().speedOfSound(rho, p);
21273
21274 MFloat xPlus = (m_solver->a_coordinate(cellId, 0) + m_radiusVelFlameTube);
21275 xPlus *= m_shearLayerStrength;
21276 MFloat xNegative = m_solver->a_coordinate(cellId, 0) - m_radiusVelFlameTube;
21277 xNegative *= m_shearLayerStrength;
21278
21279 MFloat un_target = m_solver->m_VInfinity
21280 * (F1B2 * (F1 + tanh(xPlus)) * (F1 - tanh(xNegative))
21281 - F1); // F3B4 * massflux/H*(1-y*y/(H*H))*un_correctionFactor;
21282
21283 // F3B4 * massflux_target/rho/H*(1-y*y/(H*H))*un_correctionFactor;
21284 if(solverProfile) un_target = massflux_target / inflowArea / rho;
21285
21286 if(m_solver->m_forcing) {
21287 // dundt = un_target;
21288 // dundt *= St*ampl*cos(St*time);
21289 un_target *= (F1 + ampl * sin(St * time));
21290 }
21291
21292 MFloat ut1_target = F0;
21293
21294 if(dirN % 2 == 0) {
21295 L[0] = -F1 * K[0] * (un - un_target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
21296 } else {
21297 L[last] = K[last] * (un - un_target) + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
21298 }
21299
21300 L[1] = K[1] * (temp - T_target) + (a * a * T[0] - T[last]) - V[last];
21301 L[2] = K[2] * (ut1 - ut1_target) + T[2] + V[2];
21302
21303 IF_CONSTEXPR(nDim == 3) {
21304 MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
21305 MFloat ut2_target = F0;
21306 L[3] = K[3] * (ut2 - ut2_target) + T[3] + V[3];
21307 }
21308
21309 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
21310 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
21311 m_solver->a_rightHandSide(cellId, CV->RHO_Y[s]) = F0;
21312 }
21313}

◆ cbc2091b()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc2091b ( MInt  bcId)

Subsonic fully reflecting characteristic inflow condition - cut off
T0,u,v is prescribed, incl. transverse terms

Definition at line 21323 of file fvcartesianbndrycndxd.cpp.

21323 {
21324 TRACE();
21325
21326 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function cbc2091a is untested for 3D!"); }
21327
21328 if(m_sortedCutOffCells[bcId]->size() == 0) {
21329 return;
21330 }
21331
21332 MInt cbcId = m_cbcBndryCndIds[bcId];
21333
21334 MInt dirN = m_cbcDir[cbcId][0];
21335 MInt dimN = m_cbcDir[cbcId][1];
21336 MInt dimT1 = m_cbcDir[cbcId][2];
21337 MInt dimT2 = m_cbcDir[cbcId][nDim];
21338
21339 MBool solverProfile = Context::getSolverProperty<MBool>("solverProfile", m_solverId, AT_, &solverProfile);
21340 MFloat time = m_solver->m_time;
21343
21344 MFloat inflowArea = m_cbcInflowArea[cbcId];
21345 // MFloat H = m_cbcInflowArea[cbcId] * F1B2;
21346
21347 MInt last = nDim + 1;
21348
21349 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
21350 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
21351 MFloatScratchSpace gradP(nDim, AT_, "gradP");
21352 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
21353 gradY.fill(F0);
21354
21355 MFloatScratchSpace L(PV->noVariables, AT_, "L");
21356 MFloatScratchSpace T(PV->noVariables, AT_, "T");
21357 MFloatScratchSpace V(PV->noVariables, AT_, "V");
21358 MFloatScratchSpace K(PV->noVariables, AT_, "K");
21359
21360 MFloat mach[2] = {F0, F0};
21361 cbcMachCo(bcId, mach);
21362 MFloat maxM = mach[1];
21363
21364 MFloat massflux = F0;
21365 MFloat uInt = F0;
21366 MFloat testSum2 = F0;
21367
21368 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21369 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21370 MInt bndryId = m_solver->a_bndryId(cellId);
21371
21372 if(m_solver->a_isHalo(cellId)) continue;
21373 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21374 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21375
21376 MFloat area = F0;
21377 if(bndryId > -1) {
21378 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
21379 // cell
21380 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
21381 if(srfcId > -1)
21382 area = m_solver->a_surfaceArea(srfcId);
21383 else
21384 mTerm(1, AT_, "something went wrong!");
21385 } else {
21386 area = m_solver->c_cellLengthAtCell(cellId);
21387 }
21388
21389 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21390 const MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
21391 const MFloat y = (m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]);
21392 testSum2 += area * y * y;
21393 massflux += un * rho * area;
21394 uInt += un * area;
21395 }
21396
21397 MInt noExchangeData = 2;
21398 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
21399 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
21400 comm_buff[0] = massflux;
21401 comm_buff[1] = testSum2;
21402
21403 if(noDomains() > 1) {
21404 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 3, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
21405 AT_, "comm_buff[0]", "comm_buff_result[0]");
21406 MPI_Allreduce(MPI_IN_PLACE, &uInt, 1, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
21407 "MPI_IN_PLACE", "uInt");
21408 }
21409
21410 massflux = comm_buff_result[0];
21411 testSum2 = comm_buff_result[1];
21412 MFloat massflux_test = uInt / m_solver->m_analyticIntegralVelocity;
21413
21414 MFloat un_correctionFactor = F1;
21415 if(fabs(massflux_test) > m_solver->m_eps) un_correctionFactor = F1 / massflux_test;
21416
21417 const MFloat massflux_target = massflux * un_correctionFactor;
21418 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
21419
21420 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
21421 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
21422 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
21423 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
21424 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
21425
21426 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
21427 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
21428
21429 MFloat T_target = sysEqn().temperature_IR(m_solver->m_Ma);
21430
21431 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21432 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21433
21434 if(m_solver->a_isHalo(cellId)) continue;
21435 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21436 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21437
21438 MInt bndryId = m_solver->a_bndryId(cellId);
21439 if(bndryId > -1) {
21440 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
21441 }
21442
21443 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
21444 V.fill(F0);
21445 if(m_cbcViscous) {
21446 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
21447 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
21448 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
21449 V.fill(F0);
21450 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
21451 &cutOffStencilCellIds[0], &V[0]);
21452 }
21453
21454 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
21455 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
21456 cbcDampingInflow(cellId, bcId, maxM, &K[0], "velocity");
21457
21458 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21459 MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
21460 MFloat p = m_solver->a_pvariable(cellId, PV->P);
21461 MFloat a = sysEqn().speedOfSound(rho, p);
21462
21463 MFloat xPlus = (m_solver->a_coordinate(cellId, 0) + m_radiusVelFlameTube);
21464 xPlus *= m_shearLayerStrength;
21465 MFloat xNegative = m_solver->a_coordinate(cellId, 0) - m_radiusVelFlameTube;
21466 xNegative *= m_shearLayerStrength;
21467
21468 MFloat un_target = m_solver->m_VInfinity
21469 * (F1B2 * (F1 + tanh(xPlus)) * (F1 - tanh(xNegative))
21470 - F1); // F3B4 * massflux/H*(1-y*y/(H*H))*un_correctionFactor;
21471
21472 // F3B4 * massflux_target/rho/H*(1-y*y/(H*H))*un_correctionFactor;
21473 if(solverProfile) un_target = massflux_target / inflowArea / rho;
21474
21475 MFloat ceta = F1;
21476 if(dirN % 2 == 0) // inflow on pos. coordinate direction
21477 ceta = -F1;
21478 else // inflow on neg. coordinate direction
21479 ceta = F1;
21480
21481 MFloat dundt = F0;
21482 if(m_solver->m_forcing) {
21483 dundt = un_target;
21484 dundt *= St * ampl * cos(St * time);
21485 un_target *= (F1 + ampl * sin(St * time));
21486 }
21487 MFloat ut1_target = F0;
21488
21489 if(dirN % 2 == 0) { // inflow on pos. coordinate direction (right) -> un < 0
21490 L[0] = L[last] + (T[last] + ceta * rho * a * T[1]) - ceta * F2 * rho * a * dundt;
21491 } else { // inflow on neg. coordinate direction (left) -> un > 0
21492 L[last] = L[0] + (T[last] + ceta * rho * a * T[1]) - ceta * F2 * rho * a * dundt;
21493 }
21494 L[1] = F1B2 * gammaMinusOne * (L[0] + L[last]) + (a * a * T[0] - T[last]);
21495
21496 MFloat d1 = F1 / (a * a) * (L[1] + F1B2 * (L[last] + L[0]));
21497
21498 MFloat dut1dt1 = m_solver->a_slope(cellId, PV->VV[dimT1], dimT1);
21499 MFloat drhodt1 = m_solver->a_slope(cellId, PV->RHO, dimT1);
21500
21501 MFloat rhs_rho = -d1 - rho * (dut1dt1)-ut1 * drhodt1;
21502
21503 m_solver->a_rightHandSide(cellId, CV->RHO) = -m_solver->a_cellVolume(cellId) * rhs_rho;
21504 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
21505 m_solver->a_rightHandSide(cellId, CV->RHO_Y[s]) -=
21506 m_solver->a_cellVolume(cellId) * rhs_rho * m_solver->a_pvariable(cellId, PV->Y[s]);
21507 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimN]) = F0;
21508 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT1]) = F0;
21509 m_solver->a_rightHandSide(cellId, CV->RHO_E) = F0;
21510
21511 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
21512 m_solver->a_pvariable(cellId, PV->Y[s]) = 0;
21513
21514 m_solver->a_pvariable(cellId, PV->VV[dimN]) = un_target;
21515 m_solver->a_pvariable(cellId, PV->VV[dimT1]) = ut1_target;
21516 m_solver->a_pvariable(cellId, PV->P) = T_target;
21517 }
21518}
MFloat & a_cellVolume(const MInt cellId)
Returns the cell volume of the cell from the fvcellcollector cellId.

◆ cbc2091b_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc2091b_after ( MInt  bcId)

Definition at line 21525 of file fvcartesianbndrycndxd.cpp.

21525 {
21526 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function cbc2091b_after is untested for 3D!"); }
21527 TRACE();
21528
21529 if(m_sortedCutOffCells[bcId]->size() == 0) return;
21530
21531 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21532 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21533
21534 if(m_solver->a_isHalo(cellId)) continue;
21535 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21536 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21537
21538 MInt bndryId = m_solver->a_bndryId(cellId);
21539
21540 if(bndryId > -1) {
21541 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
21542 }
21543
21544 // recompute the correct energy:
21545 MFloat rho = m_solver->a_variable(cellId, CV->RHO);
21546 MFloat u = m_solver->a_pvariable(cellId, PV->VV[0]);
21547 MFloat v = m_solver->a_pvariable(cellId, PV->VV[1]);
21548 MFloat T = m_solver->a_pvariable(cellId, PV->P);
21549 MFloat p = sysEqn().pressure_ES(T, rho);
21550 MFloat E = sysEqn().internalEnergy(p, rho, (u * u + v * v));
21551
21552 m_solver->a_variable(cellId, CV->RHO_VV[0]) = rho * u;
21553 m_solver->a_variable(cellId, CV->RHO_VV[1]) = rho * v;
21554 m_solver->a_variable(cellId, CV->RHO_E) = E;
21555 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
21556 m_solver->a_variable(cellId, CV->RHO_Y[s]) = rho * m_solver->a_pvariable(cellId, PV->Y[s]);
21557 }
21558}

◆ cbc2091d()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc2091d ( MInt  bcId)

Subsonic partially reflecting characteristic inflow condition - cut off
p0,T0,v is prescribed, incl. shear and transverse terms, profile of un is prescribed

Definition at line 21566 of file fvcartesianbndrycndxd.cpp.

21566 {
21567 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function cbc2091a is untested for 3D!"); }
21568 TRACE();
21569
21570 if(m_sortedCutOffCells[bcId]->size() == 0) {
21571 return;
21572 }
21573
21574 MInt cbcId = m_cbcBndryCndIds[bcId];
21575
21576 MInt dirN = m_cbcDir[cbcId][0];
21577 MInt dimN = m_cbcDir[cbcId][1];
21578 MInt dimT1 = m_cbcDir[cbcId][2];
21579 MInt dimT2 = m_cbcDir[cbcId][nDim];
21580
21581 MFloat inflowArea = m_cbcInflowArea[cbcId];
21582 // MFloat H = m_cbcInflowArea[cbcId] * F1B2;
21583
21584 MInt last = nDim + 1;
21585
21586 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
21587 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
21588 MFloatScratchSpace gradP(nDim, AT_, "gradP");
21589 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
21590 gradY.fill(F0);
21591
21592 MFloatScratchSpace L(PV->noVariables, AT_, "L");
21593 MFloatScratchSpace T(PV->noVariables, AT_, "T");
21594 MFloatScratchSpace V(PV->noVariables, AT_, "V");
21595 MFloatScratchSpace K(PV->noVariables, AT_, "K");
21596
21597 MFloat mach[2] = {F0, F0};
21598 cbcMachCo(bcId, mach);
21599 MFloat maxM = mach[1];
21600
21601 MFloat massflux = F0;
21602 MFloat uInt = F0;
21603
21604 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21605 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21606 MInt bndryId = m_solver->a_bndryId(cellId);
21607 MInt nghbrN = m_solver->c_neighborId(cellId, dirN);
21608
21609 if(m_solver->a_isHalo(cellId)) continue;
21610 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21611 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21612
21613 MFloat area = F0;
21614 if(bndryId > -1) {
21615 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
21616 // cell
21617 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
21618 if(srfcId > -1)
21619 area = m_solver->a_surfaceArea(srfcId);
21620 else
21621 mTerm(1, AT_, "something went wrong!");
21622 } else {
21623 area = m_solver->c_cellLengthAtCell(cellId);
21624 }
21625
21626 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21627 const MFloat un_N = m_solver->a_pvariable(nghbrN, PV->VV[dimN]);
21628 massflux += un_N * rho * area;
21629 uInt += un_N * area;
21630 }
21631
21632 MInt noExchangeData = 2;
21633 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
21634 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
21635 comm_buff[0] = massflux;
21636 comm_buff[1] = uInt;
21637
21638 if(noDomains() > 1) {
21639 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 3, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
21640 AT_, "comm_buff[0]", "comm_buff_result[0]");
21641 MPI_Allreduce(MPI_IN_PLACE, &uInt, 1, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
21642 "MPI_IN_PLACE", "uInt");
21643 }
21644
21645 massflux = comm_buff_result[0];
21646 MFloat massflux_test = uInt / m_solver->m_analyticIntegralVelocity;
21647
21648 MFloat un_correctionFactor = F1;
21649 if(fabs(massflux_test) > m_solver->m_eps) un_correctionFactor = F1 / massflux_test;
21650
21651 massflux = massflux * un_correctionFactor;
21652
21653 const MFloat gammaMinusOne = m_solver->m_gamma - 1.0;
21654
21655 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
21656 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
21657 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
21658 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
21659 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
21660
21661 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
21662 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
21663
21664 MFloat T_target = 1 - gammaMinusOne * F1B2 * (massflux * massflux / inflowArea / inflowArea);
21665 MFloat p_Target = sysEqn().pressure_IR(T_target);
21670
21671 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21672 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21673
21674 if(m_solver->a_isHalo(cellId)) continue;
21675 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21676 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21677
21678 MInt bndryId = m_solver->a_bndryId(cellId);
21679 if(bndryId > -1) {
21680 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
21681 }
21682
21683 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
21684 V.fill(F0);
21685 if(m_cbcViscous) {
21686 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
21687 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
21688 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
21689 V.fill(F0);
21690 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
21691 &cutOffStencilCellIds[0], &V[0]);
21692 }
21693
21694 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
21695 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
21696 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
21697
21698 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21699 MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
21700
21701 MFloat p = m_solver->a_pvariable(cellId, PV->P);
21702 MFloat temp = sysEqn().temperature_ES(rho, p);
21703 MFloat a = sysEqn().speedOfSound(rho, p);
21704
21705 MFloat xPlus = (m_solver->a_coordinate(cellId, 0) + m_radiusVelFlameTube);
21706 xPlus *= m_shearLayerStrength;
21707 MFloat xNegative = m_solver->a_coordinate(cellId, 0) - m_radiusVelFlameTube;
21708 xNegative *= m_shearLayerStrength;
21709
21710 MFloat un_target = m_solver->m_VInfinity
21711 * (F1B2 * (F1 + tanh(xPlus)) * (F1 - tanh(xNegative))
21712 - F1); // F3B4 * massflux/H*(1-y*y/(H*H))*un_correctionFactor;
21713
21714 MFloat ut1_target = F0;
21715
21716 if(dirN % 2 == 0) {
21717 L[0] = K[0] * (p - p_Target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
21718 } else {
21719 L[last] = K[last] * (p - p_Target) + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
21720 }
21721
21722 L[1] = K[1] * (temp - T_target) + (a * a * T[0] - T[last]) - V[last];
21723 L[2] = K[2] * (ut1 - ut1_target) + T[2] + V[2];
21724
21725 IF_CONSTEXPR(nDim == 3) {
21726 MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
21727 MFloat ut2_target = F0;
21728 L[3] = K[3] * (ut2 - ut2_target) + T[3] + V[3];
21729 }
21730
21731 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
21732
21733 // temporary fix until species is included in cbcRHS()
21734 MFloat d1 = F1 / (a * a) * (L[1] + F1B2 * (L[last] + L[0]));
21735 MFloat rhs_rho = -d1 + T[0] + V[0];
21736 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
21737 m_solver->a_rightHandSide(cellId, CV->RHO_Y[s]) -=
21738 m_solver->a_cellVolume(cellId) * rhs_rho * m_solver->a_pvariable(cellId, PV->Y[s]);
21739 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
21740 m_solver->a_rightHandSide(cellId, CV->RHO_Y[s]) = F0;
21741 m_solver->a_pvariable(cellId, PV->VV[dimN]) = un_target;
21742 }
21743}

◆ cbc2091d_after()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc2091d_after ( MInt  bcId)

Definition at line 21748 of file fvcartesianbndrycndxd.cpp.

21748 {
21749 TRACE();
21750
21751 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function cbc2091d_after is untested for 3D!"); }
21752
21753 const MInt otherDir[4] = {1, 0, 3, 2};
21754
21759 if(first) {
21760 MInt noCutOffBndryIds = Context::propertyLength("cutOffBndryIds", m_solverId);
21761 MInt noCutOffDirections = Context::propertyLength("cutOffDirections", m_solverId);
21762 if(noCutOffDirections != noCutOffBndryIds)
21763 mTerm(1, AT_,
21764 "Wrong number of cut off directions. Must be identical to number of cut off bndryIds! Please check!");
21765 MInt cutOffBndryIdTmp, cutOffDirectionTmp;
21766 for(MInt i = 0; i < noCutOffBndryIds; i++) {
21767 cutOffBndryIdTmp = Context::getSolverProperty<MInt>("cutOffBndryIds", m_solverId, AT_, i);
21768 cutOffDirectionTmp = Context::getSolverProperty<MInt>("cutOffDirections", m_solverId, AT_, i);
21769 if(cutOffBndryIdTmp == m_cutOffBndryCndIds[bcId]) {
21770 dirN = otherDir[cutOffDirectionTmp];
21771 break;
21772 }
21773 }
21774 dimN = (MInt)dirN / 2;
21775 dimT1 = (dimN + 1) % nDim;
21776
21777 first = false;
21778 }
21779
21780 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21781 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21782 if(m_solver->a_isHalo(cellId)) continue;
21783 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21784 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21785
21786 MInt bndryId = m_solver->a_bndryId(cellId);
21787
21788 if(bndryId > -1) {
21789 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
21790 }
21791
21792 // recompute the correct energy:
21793 MFloat rho = m_solver->a_variable(cellId, CV->RHO);
21794 MFloat u = m_solver->a_pvariable(cellId, PV->VV[dimN]);
21795 MFloat u_wrong = m_solver->a_variable(cellId, CV->RHO_VV[dimN]) / m_solver->a_variable(cellId, CV->RHO);
21796 MFloat v = m_solver->a_variable(cellId, CV->RHO_VV[dimT1]) / m_solver->a_variable(cellId, CV->RHO);
21797 MFloat p = sysEqn().pressure(rho, (u_wrong * u_wrong + v * v), m_solver->a_variable(cellId, CV->RHO_E));
21798 MFloat E = sysEqn().internalEnergy(p, rho, (u * u + v * v));
21799
21800 m_solver->a_variable(cellId, CV->RHO_VV[dimN]) = rho * u;
21801 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
21802 m_solver->a_variable(cellId, CV->RHO_Y[s]) = rho * m_solver->a_pvariable(cellId, PV->Y[s]);
21803 m_solver->a_variable(cellId, CV->RHO_E) = E;
21804 }
21805}

◆ cbc2099_1091_local_comb()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc2099_1091_local_comb ( MInt  bcId)

Subsonic partially reflecting characteristic outflow condition - cut off
turbulent combustion

Definition at line 21814 of file fvcartesianbndrycndxd.cpp.

21814 {
21815 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function cbc2099_1091_local_comb is untested for 3D!"); }
21816 TRACE();
21817
21818 if(m_sortedCutOffCells[bcId]->size() == 0) {
21819 return;
21820 }
21821
21822 MInt cbcId = m_cbcBndryCndIds[bcId];
21823
21824 MInt dirN = m_cbcDir[cbcId][0];
21825 MInt dimN = m_cbcDir[cbcId][1];
21826 MInt dimT1 = m_cbcDir[cbcId][2];
21827 MInt dimT2 = m_cbcDir[cbcId][nDim];
21828
21829 MFloat outFlowArea = m_cbcInflowArea[cbcId];
21830
21831 MInt last = nDim + 1;
21832
21833 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
21834 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
21835 MFloatScratchSpace gradP(nDim, AT_, "gradP");
21836 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
21837 gradY.fill(F0);
21838
21839 MFloatScratchSpace L(PV->noVariables, AT_, "L");
21840 MFloatScratchSpace T(PV->noVariables, AT_, "T");
21841 MFloatScratchSpace V(PV->noVariables, AT_, "V");
21842 MFloatScratchSpace K(PV->noVariables, AT_, "K");
21843
21844 MFloat massflux = F0;
21845 MFloat T_mean = F0;
21846 MFloat rho_mean = F0;
21847
21848 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21849 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21850 MInt bndryId = m_solver->a_bndryId(cellId);
21851
21852 if(m_solver->a_isHalo(cellId)) continue;
21853 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21854 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21855
21856 MFloat area = F0;
21857 if(bndryId > -1) {
21858 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
21859 // cell
21860 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
21861 if(srfcId > -1)
21862 area = m_solver->a_surfaceArea(srfcId);
21863 else
21864 mTerm(1, AT_, "something went wrong!");
21865 } else {
21866 IF_CONSTEXPR(nDim == 2) { area = m_solver->c_cellLengthAtCell(cellId); }
21867 else {
21868 area = POW2(m_solver->c_cellLengthAtCell(cellId));
21869 }
21870 }
21871
21872 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21873 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
21874 const MFloat Temp = sysEqn().temperature_ES(rho, p);
21875 const MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
21876
21877 massflux += un * area * rho;
21878 T_mean += Temp * area;
21879 rho_mean += rho * area;
21880 }
21881
21882 MFloat mach[2] = {F0, F0};
21883 cbcMachCo(bcId, mach);
21884 MFloat maxM = mach[1];
21885
21886 MInt noExchangeData = 2;
21887 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
21888 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
21889 comm_buff[0] = massflux;
21890 comm_buff[2] = T_mean;
21891
21892 if(noDomains() > 1) {
21893 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 2, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
21894 AT_, "comm_buff[0]", "comm_buff_result[0]");
21895 }
21896
21897 massflux = comm_buff_result[0];
21898 T_mean = comm_buff_result[1];
21899 T_mean /= outFlowArea;
21900 rho_mean /= outFlowArea;
21901
21902 MFloat T_target = T_mean;
21903 MFloat p_Target = m_solver->m_PInfinity;
21904
21906 m_solver->m_jetDensity = rho_mean;
21907 m_solver->m_jetTemperature = T_target;
21908
21909 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
21910 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
21911 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
21912 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
21913 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
21914
21915 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
21916 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
21917
21918 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
21919 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
21920
21921 if(m_solver->a_isHalo(cellId)) continue;
21922 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
21923 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
21924
21925 MInt bndryId = m_solver->a_bndryId(cellId);
21926
21927 if(bndryId > -1) {
21928 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
21929 }
21930
21931 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
21932 V.fill(F0);
21933 if(m_cbcViscous) {
21934 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
21935 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
21936 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
21937 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
21938 &cutOffStencilCellIds[0], &V[0]);
21939 }
21940
21941 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
21942
21943 // This is where you differentiate between inflow and outflow
21944 MFloat un_mean = m_solver->a_pvariable(cellId, PV->VV[dimN]);
21945
21946 MBool isInflow = true;
21947 if(dirN % 2 == 0) {
21948 if(un_mean > F0) {
21949 isInflow = false;
21950 } else {
21951 // T_target_new = T_mean;
21952 }
21953 } else {
21954 if(un_mean < F0) {
21955 isInflow = false;
21956 } else {
21957 // T_target_new = T_mean;
21958 }
21959 }
21960
21961 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
21962 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
21963 const MFloat Temp = sysEqn().temperature_ES(rho, p);
21964 const MFloat a = sysEqn().speedOfSound(Temp);
21965
21966
21967 if(isInflow) {
21968 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
21969 cbcDampingInflow(cellId, bcId, maxM, &K[0], "pressure");
21970
21971 MFloat ceta = F1;
21972 if(dirN % 2 == 0)
21973 ceta = -F1;
21974 else
21975 ceta = F1;
21976
21977 K[0] = K[0] / a * m_sigmaNonRefl;
21978 K[last] = K[0];
21979 MFloat beta = F0;
21980
21981 if(dirN % 2 == 0) {
21982 L[0] =
21983 K[0] * (p - p_Target) + (beta - 1) * (T[last] + ceta * rho * a * T[1]) + (V[last] + ceta * rho * a * V[1]);
21984 } else {
21985 L[last] = K[last] * (p - p_Target) + (beta - 1) * (T[last] + ceta * rho * a * T[1])
21986 + (V[last] + ceta * rho * a * V[1]);
21987 }
21988
21989 } else {
21990 cbcOutgoingAmplitudeVariation<0>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
21991 cbcDampingOutflow(cellId, bcId, maxM, &K[0]);
21992
21993 K[0] = K[0] * m_sigmaNonRefl;
21994 K[last] = K[0];
21995
21996 MFloat deltaP = (p - p_Target);
21997
21998 if(dirN % 2 == 0) { // outflow on pos. coordinate direction -> L1 has to be modeled
21999 L[0] = K[0] * deltaP;
22000 } else {
22001 L[last] = K[last] * deltaP;
22002 }
22003 }
22004 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
22005 }
22006}

◆ cbc3091a()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbc3091a ( MInt  bcId)

Subsonic partially reflecting characteristic turbulent inflow condition - cut off
p0,T0,v is prescribed, incl. shear and transverse terms

Definition at line 22231 of file fvcartesianbndrycndxd.cpp.

22231 {
22232 IF_CONSTEXPR(nDim == 2) { TERMM(-1, "INFO: function cbc3091a is untested for 2D!"); }
22233 TRACE();
22234
22235 MFloat dummyTime;
22236 MFloat that, twopioverlb;
22237 MFloat factor1, factor2, b1, b2;
22238 MInt ghost1;
22239 MFloat xhat, yhat, zhat;
22240 MFloat fluctChol[3];
22241 MFloat velocity = F0;
22244 MFloat massfluxTest = F0, jetInflowArea = F0;
22245
22247 m_log << "computing mass flux " << endl;
22248
22249 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
22250 ghost1 = m_sortedCutOffCells[bcId]->a[id];
22251 if(m_solver->a_isHalo(ghost1)) continue;
22252
22253 MFloat jetArea = POW2(m_solver->grid().cellLengthAtCell(ghost1));
22254 factor1 = m_solver->a_coordinate(ghost1, 0);
22255 factor2 = m_solver->a_coordinate(ghost1, 2);
22256
22257 velocity = m_solver->m_Ma
22258 * (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
22259 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
22260 - 1)
22261 * (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
22262 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
22263 - 1);
22264 massfluxTest += m_solver->a_variable(ghost1, PV->RHO) * velocity * jetArea;
22265 jetInflowArea += jetArea;
22266 }
22267
22268 MPI_Allreduce(MPI_IN_PLACE, &massfluxTest, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "massfluxTest");
22269 MPI_Allreduce(MPI_IN_PLACE, &jetInflowArea, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
22270 "jetInflowArea");
22271
22272 // compute static pressure and density iteratively (see e.g. thesis of Ingolf Hoerschler)
22273 // compute massflux per unit area
22274 massfluxTest /= jetInflowArea;
22275
22279 m_log << "calculated pressure" << m_solver->m_jetPressure << endl;
22280 m_log << "calculated density" << m_solver->m_jetDensity << endl;
22281 m_log << "calculated temperature at inflow " << m_solver->m_jetTemperature << endl;
22282 m_log << "calculated massflux" << massfluxTest << endl;
22283 }
22284
22285 if(m_sortedCutOffCells[bcId]->size() == 0) {
22286 return;
22287 }
22288
22289 dummyTime = m_solver->m_time / m_bc1601->m_tau_b;
22290
22291 m_bc1601->checkRegeneration(dummyTime);
22292
22293 that = 2.0 * PI * dummyTime;
22294 twopioverlb = 2.0 * PI / m_bc1601->m_l_b;
22295
22296
22297 MInt cbcId = m_cbcBndryCndIds[bcId];
22298
22299 MInt dirN = m_cbcDir[cbcId][0];
22300 MInt dimN = m_cbcDir[cbcId][1];
22301 MInt dimT1 = m_cbcDir[cbcId][2];
22302 MInt dimT2 = m_cbcDir[cbcId][nDim];
22303
22304 MBool solverProfile = Context::getSolverProperty<MBool>("solverProfile", m_solverId, AT_, &solverProfile);
22305 MFloat inflowArea = m_cbcInflowArea[cbcId];
22306 // MFloat R = sqrt(inflowArea / PI);
22307
22308 MInt last = nDim + 1;
22309
22310 MFloatScratchSpace gradRho(nDim, AT_, "gradRho");
22311 MFloatScratchSpace gradVV(nDim * nDim, AT_, "gradVV");
22312 MFloatScratchSpace gradP(nDim, AT_, "gradP");
22313 MFloatScratchSpace gradY(mMax(1, m_solver->m_noSpecies * nDim), AT_, "gradY");
22314 gradY.fill(F0);
22315
22316 MFloatScratchSpace L(PV->noVariables, AT_, "L");
22317 MFloatScratchSpace T(PV->noVariables, AT_, "T");
22318 MFloatScratchSpace V(PV->noVariables, AT_, "V");
22319 MFloatScratchSpace K(PV->noVariables, AT_, "K");
22320
22321 MFloat mach[2] = {F0, F0};
22322 cbcMachCo(bcId, mach);
22323 MFloat maxM = mach[1];
22324
22325 MFloat massflux = F0;
22326 MFloat testSum2 = F0;
22327
22328 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
22329 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
22330 MInt bndryId = m_solver->a_bndryId(cellId);
22331
22332 if(m_solver->a_isHalo(cellId)) continue;
22333 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
22334 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
22335
22336 MFloat area = F0;
22337 if(bndryId > -1) {
22338 // identify the "boundary surface" between cutoff boundary cell and neighboring layer cell if cell is a boundary
22339 // cell
22340 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
22341 if(srfcId > -1)
22342 area = m_solver->a_surfaceArea(srfcId);
22343 else
22344 mTerm(1, AT_, "something went wrong!");
22345 } else {
22346 area = m_solver->c_cellLengthAtCell(cellId);
22347 }
22348
22349 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
22350 const MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
22351 const MFloat y = (m_solver->a_coordinate(cellId, dimT1) - m_cbcReferencePoint[cbcId][dimT1]);
22352 testSum2 += area * y * y;
22353 massflux += un * rho * area;
22354 }
22355
22356 MInt noExchangeData = 2;
22357 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
22358 MFloatScratchSpace comm_buff_result(noExchangeData, AT_, "comm_buff_result");
22359 comm_buff[0] = massflux;
22360 comm_buff[1] = testSum2;
22361
22362 if(noDomains() > 1) {
22363 MPI_Allreduce(&comm_buff[0], &comm_buff_result[0], 3, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
22364 AT_, "comm_buff[0]", "comm_buff_result[0]");
22365 }
22366
22367 massflux = comm_buff_result[0];
22368 testSum2 = comm_buff_result[1];
22369
22370 const MFloat TInfinity = m_solver->m_TInfinity;
22371 const MFloat PInfinity = m_solver->m_PInfinity;
22372
22373 MFloat ut1_target = F0;
22374 const MFloat massflux_target = m_solver->m_VInfinity * inflowArea * sysEqn().density_ES(PInfinity, TInfinity);
22375 MInt noCutOffBCCells = m_cbcViscous ? m_sortedCutOffCells[bcId]->size() : 1;
22376 MFloatScratchSpace tau(3 * noCutOffBCCells * nDim * nDim, AT_, "tau");
22377 MFloatScratchSpace q(3 * noCutOffBCCells * nDim, AT_, "q");
22378 MFloatScratchSpace gradTau(m_cbcViscous ? (nDim * nDim * nDim) : 1, AT_, "gradTau");
22379 MFloatScratchSpace gradQ(m_cbcViscous ? (nDim * nDim) : 1, AT_, "gradQ");
22380
22381 MIntScratchSpace cutOffStencilCellIds(m_cbcViscous ? m_solver->a_noCells() : 1, AT_, "cutOffStencilCellIds");
22382 if(m_cbcViscous) cbcTauQ(bcId, &tau[0], &q[0], &cutOffStencilCellIds[0]);
22383
22384 MFloat T_target = sysEqn().temperature_IR(m_solver->m_Ma);
22385
22386 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
22387 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
22388
22389 if(m_solver->a_isHalo(cellId)) continue;
22390 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
22391 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
22392
22393 MInt bndryId = m_solver->a_bndryId(cellId);
22394 if(bndryId > -1) {
22395 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
22396 }
22397
22398 cbcGradients(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0]);
22399 V.fill(F0);
22400 if(m_cbcViscous) {
22401 cbcGradientsViscous(cellId, bcId, &tau[0], &q[0], &gradTau[0], &gradQ[0], &cutOffStencilCellIds[0]);
22402 gradTau[dimN * IPOW2(nDim) + dimT1 * nDim + dimN] = F0;
22403 IF_CONSTEXPR(nDim == 3) { gradTau[dimN * IPOW2(nDim) + dimT2 * nDim + dimN] = F0; }
22404 cbcViscousTerms<(unsigned char)01111>(cellId, bcId, &tau[0], &gradTau[0], &gradQ[0], &gradVV[0],
22405 &cutOffStencilCellIds[0], &V[0]);
22406 }
22407
22408 cbcOutgoingAmplitudeVariation<1>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &L[0]);
22409 cbcTransversalTerms<(unsigned char)11111>(cellId, bcId, &gradRho[0], &gradVV[0], &gradP[0], &gradY[0], &T[0]);
22410 cbcDampingInflow(cellId, bcId, maxM, &K[0], "velocity");
22411
22412 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
22413 MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]);
22414 MFloat ut1 = m_solver->a_pvariable(cellId, PV->VV[dimT1]);
22415 MFloat p = m_solver->a_pvariable(cellId, PV->P);
22416 MFloat temp = sysEqn().temperature_ES(rho, p);
22417 MFloat a = sysEqn().speedOfSound(rho, p);
22418
22419 factor1 = m_solver->a_coordinate(cellId, dimT1);
22420 IF_CONSTEXPR(nDim == 3) { factor2 = m_solver->a_coordinate(cellId, dimT2); }
22421
22422 xhat = twopioverlb * m_solver->a_coordinate(cellId, dimN);
22423 yhat = twopioverlb * m_solver->a_coordinate(cellId, dimT1);
22424 IF_CONSTEXPR(nDim == 2) { zhat = F0; }
22425 IF_CONSTEXPR(nDim == 3) { zhat = twopioverlb * m_solver->a_coordinate(cellId, dimT2); }
22426 fluctChol[dimN] = 0;
22427 fluctChol[dimT1] = 0;
22428 fluctChol[dimT2] = 0;
22429
22430 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
22431
22432 fluctChol[dimT1] *= (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
22433 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
22434 - 1);
22435 fluctChol[dimT1] *= (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
22436 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
22437 - 1);
22438 IF_CONSTEXPR(nDim == 3) {
22439 fluctChol[dimT2] *= (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
22440 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
22441 - 1);
22442 fluctChol[dimT2] *= (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
22443 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
22444 - 1);
22445 }
22446
22447 ut1_target = fluctChol[dimT1];
22448 MFloat un_target = (velocity + fluctChol[1])
22449 * (F1B2 * (1 + tanh(b1 * (factor1 + m_solver->m_jetHalfWidth)))
22450 * (1 - tanh(b1 * (factor1 - m_solver->m_jetHalfWidth)))
22451 - 1)
22452 * (F1B2 * (1 + tanh(b2 * (factor2 + m_solver->m_jetHalfLength)))
22453 * (1 - tanh(b2 * (factor2 - m_solver->m_jetHalfLength)))
22454 - 1);
22455 // F2*massflux_target/inflowArea*(F1-rsquare/(R*R))/rho*un_correctionFactor;
22456
22457 if(solverProfile) un_target = massflux_target / inflowArea / rho;
22458
22459 if(dirN % 2 == 0) {
22460 L[0] = -F1 * K[0] * (un - un_target) + (T[last] - rho * a * T[1]) + (V[last] - rho * a * V[1]);
22461 } else {
22462 L[last] = K[last] * (un - un_target) + (T[last] + rho * a * T[1]) + (V[last] + rho * a * V[1]);
22463 }
22464
22465 L[1] = K[1] * (temp - T_target) + (a * a * T[0] - T[last]) - V[last];
22466 L[2] = K[2] * (ut1 - ut1_target) + T[2] + V[2];
22467 IF_CONSTEXPR(nDim == 3) {
22468 MFloat ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
22469 MFloat ut2_target = fluctChol[dimT2];
22470 L[3] = K[3] * (ut2 - ut2_target) + T[3] + V[3];
22471 }
22472
22473 cbcRHS(cellId, bcId, &L[0], &T[0], &V[0]);
22474 for(MInt s = 0; s < m_solver->m_noSpecies; s++)
22475 m_solver->a_rightHandSide(cellId, CV->RHO_Y[s]) = F0;
22476 }
22477}

◆ cbcDampingInflow()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcDampingInflow ( MInt  cellId,
MInt  bcId,
MFloat  maxM,
MFloat K,
MString  prescribedVariable 
)
Date
October 2019

Definition at line 20221 of file fvcartesianbndrycndxd.cpp.

20222 {
20223 TRACE();
20224
20225 MInt cbcId = m_cbcBndryCndIds[bcId];
20226 MInt dirN = m_cbcDir[cbcId][0];
20227 MInt last = CV->noVariables - 1 - m_solver->m_noSpecies;
20228
20229 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20230 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20231 MFloat a = sysEqn().speedOfSound(rho, p);
20232
20233 if(dirN % 2 == 0) {
20234 if(prescribedVariable == "velocity") {
20235 K[0] = m_cbcRelax[cbcId][0] * rho * a * a * (1 - maxM * maxM) / m_cbcLref[cbcId];
20236 } else if(prescribedVariable == "pressure") {
20237 K[0] = m_cbcRelax[cbcId][0] * rho * a * (1 - maxM * maxM) / m_cbcLref[cbcId];
20238 } else {
20239 TERMM(-1, "INFO: no prescribed variable set in cbcDampingInflow");
20240 }
20241 K[last] = m_cbcRelax[cbcId][last] * rho * a * a * (1 - maxM * maxM) / m_cbcLref[cbcId];
20242 } else {
20243 if(prescribedVariable == "velocity") {
20244 K[last] = m_cbcRelax[cbcId][last] * rho * a * a * (1 - maxM * maxM) / m_cbcLref[cbcId];
20245 } else if(prescribedVariable == "pressure") {
20246 K[last] = m_cbcRelax[cbcId][last] * rho * a * (1 - maxM * maxM) / m_cbcLref[cbcId];
20247 } else {
20248 TERMM(-1, "INFO: no prescribed variable set in cbcDampingInflow");
20249 }
20250 K[0] = m_cbcRelax[cbcId][0] * rho * a * a * (1 - maxM * maxM) / m_cbcLref[cbcId];
20251 }
20252
20253 K[1] = m_cbcRelax[cbcId][1] * rho * a / (m_cbcLref[cbcId]);
20254
20255 // needed because of non-dimensionalization (correction for detailed chemistry)
20256 IF_CONSTEXPR(isDetChem<SysEqn>)
20257 K[1] = m_cbcRelax[cbcId][1] * rho * a * m_solver->m_gasConstant
20258 / (m_cbcLref[cbcId] * m_solver->a_avariable(cellId, AV->W_MEAN));
20259
20260 K[2] = m_cbcRelax[cbcId][2] * a / m_cbcLref[cbcId];
20261 IF_CONSTEXPR(nDim == 3) { K[3] = m_cbcRelax[cbcId][3] * a / m_cbcLref[cbcId]; }
20262
20263 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20264 K[last + 1 + s] = m_cbcRelax[cbcId][last + 1 + s] * a / m_cbcLref[cbcId];
20265 }
20266}

◆ cbcDampingOutflow()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcDampingOutflow ( MInt  cellId,
MInt  bcId,
MFloat  maxM,
MFloat K 
)
Date
October 2019

Definition at line 20273 of file fvcartesianbndrycndxd.cpp.

20273 {
20274 TRACE();
20275
20276 MInt cbcId = m_cbcBndryCndIds[bcId];
20277 MInt last = CV->noVariables - 1 - m_solver->m_noSpecies;
20278
20279 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20280 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20281 MFloat a = sysEqn().speedOfSound(rho, p);
20282
20283 K[0] = m_cbcRelax[cbcId][0] * a * (F1 - maxM * maxM) / m_cbcLref[cbcId];
20284 K[last] = K[0];
20285}

◆ cbcGradients()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcGradients ( MInt  cellId,
MInt  bcId,
MFloat gradRho,
MFloat gradVV,
MFloat gradP,
MFloat gradY 
)
Date
October 2019

Definition at line 19916 of file fvcartesianbndrycndxd.cpp.

19917 {
19918 TRACE();
19919
19920 MInt cbcId = m_cbcBndryCndIds[bcId];
19921
19922 MInt dimN = m_cbcDir[cbcId][1];
19923 MInt dimT1 = m_cbcDir[cbcId][2];
19924 MInt dimT2 = m_cbcDir[cbcId][nDim];
19925
19926 gradRho[dimN] = m_solver->a_slope(cellId, PV->RHO, dimN) * m_dirNormal[cbcId][dimN]
19927 + m_solver->a_slope(cellId, PV->RHO, dimT1) * m_dirNormal[cbcId][dimT1];
19928 gradRho[dimT1] = m_solver->a_slope(cellId, PV->RHO, dimN) * m_dirTangent[cbcId][dimN]
19929 + m_solver->a_slope(cellId, PV->RHO, dimT1) * m_dirTangent[cbcId][dimT1];
19930
19931 gradVV[dimN * nDim + dimN] = m_solver->a_slope(cellId, PV->VV[dimN], dimN) * m_dirNormal[cbcId][dimN]
19932 + m_solver->a_slope(cellId, PV->VV[dimN], dimT1) * m_dirNormal[cbcId][dimT1];
19933 gradVV[dimN * nDim + dimT1] = m_solver->a_slope(cellId, PV->VV[dimN], dimN) * m_dirTangent[cbcId][dimN]
19934 + m_solver->a_slope(cellId, PV->VV[dimN], dimT1) * m_dirTangent[cbcId][dimT1];
19935 gradVV[dimT1 * nDim + dimN] = m_solver->a_slope(cellId, PV->VV[dimT1], dimN) * m_dirNormal[cbcId][dimN]
19936 + m_solver->a_slope(cellId, PV->VV[dimT1], dimT1) * m_dirNormal[cbcId][dimT1];
19937 gradVV[dimT1 * nDim + dimT1] = m_solver->a_slope(cellId, PV->VV[dimT1], dimN) * m_dirTangent[cbcId][dimN]
19938 + m_solver->a_slope(cellId, PV->VV[dimT1], dimT1) * m_dirTangent[cbcId][dimT1];
19939
19940 gradP[dimN] = m_solver->a_slope(cellId, PV->P, dimN) * m_dirNormal[cbcId][dimN]
19941 + m_solver->a_slope(cellId, PV->P, dimT1) * m_dirNormal[cbcId][dimT1];
19942 gradP[dimT1] = m_solver->a_slope(cellId, PV->P, dimN) * m_dirTangent[cbcId][dimN]
19943 + m_solver->a_slope(cellId, PV->P, dimT1) * m_dirTangent[cbcId][dimT1];
19944
19945 if(m_solver->m_noSpecies > 0) {
19946 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
19947 gradY[s * nDim + dimN] = m_solver->a_slope(cellId, PV->Y[s], dimN) * m_dirNormal[cbcId][dimN]
19948 + m_solver->a_slope(cellId, PV->Y[s], dimT1) * m_dirNormal[cbcId][dimT1];
19949 gradY[s * nDim + dimT1] = m_solver->a_slope(cellId, PV->Y[s], dimN) * m_dirTangent[cbcId][dimN]
19950 + m_solver->a_slope(cellId, PV->Y[s], dimT1) * m_dirNormal[cbcId][dimT1];
19951 }
19952 }
19953
19954 IF_CONSTEXPR(nDim == 3) {
19955 gradRho[dimN] += m_solver->a_slope(cellId, PV->RHO, dimT2) * m_dirNormal[cbcId][dimT2];
19956 gradRho[dimT1] += m_solver->a_slope(cellId, PV->RHO, dimT2) * m_dirTangent[cbcId][dimT2];
19957 gradRho[dimT2] = m_solver->a_slope(cellId, PV->RHO, dimT2);
19958
19959 gradVV[dimN * nDim + dimN] += m_solver->a_slope(cellId, PV->VV[dimN], dimT2) * m_dirNormal[cbcId][dimT2];
19960 gradVV[dimN * nDim + dimT1] += m_solver->a_slope(cellId, PV->VV[dimN], dimT2) * m_dirTangent[cbcId][dimT2];
19961 gradVV[dimN * nDim + dimT2] = m_solver->a_slope(cellId, PV->VV[dimN], dimT2);
19962 gradVV[dimT1 * nDim + dimN] += m_solver->a_slope(cellId, PV->VV[dimT1], dimT2) * m_dirNormal[cbcId][dimT2];
19963 gradVV[dimT1 * nDim + dimT1] += m_solver->a_slope(cellId, PV->VV[dimT1], dimT2) * m_dirTangent[cbcId][dimT2];
19964 gradVV[dimT1 * nDim + dimT2] = m_solver->a_slope(cellId, PV->VV[dimT1], dimT2);
19965 gradVV[dimT2 * nDim + dimN] = m_solver->a_slope(cellId, PV->VV[dimT2], dimN) * m_dirNormal[cbcId][dimN]
19966 + m_solver->a_slope(cellId, PV->VV[dimT2], dimT1) * m_dirNormal[cbcId][dimT1]
19967 + m_solver->a_slope(cellId, PV->VV[dimT2], dimT2) * m_dirNormal[cbcId][dimT2];
19968 gradVV[dimT2 * nDim + dimT1] = m_solver->a_slope(cellId, PV->VV[dimT2], dimN) * m_dirTangent[cbcId][dimN]
19969 + m_solver->a_slope(cellId, PV->VV[dimT2], dimT1) * m_dirTangent[cbcId][dimT1]
19970 + m_solver->a_slope(cellId, PV->VV[dimT2], dimT2) * m_dirTangent[cbcId][dimT2];
19971 gradVV[dimT2 * nDim + dimT2] = m_solver->a_slope(cellId, PV->VV[dimT2], dimT2);
19972
19973 gradP[dimN] += m_solver->a_slope(cellId, PV->P, dimT2) * m_dirNormal[cbcId][dimT2];
19974 gradP[dimT1] += m_solver->a_slope(cellId, PV->P, dimT2) * m_dirTangent[cbcId][dimT2];
19975 gradP[dimT2] = m_solver->a_slope(cellId, PV->P, dimT2);
19976 if(m_solver->m_noSpecies > 0) {
19977 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
19978 gradY[s * nDim + dimN] += m_solver->a_slope(cellId, PV->Y[s], dimT2) * m_dirNormal[cbcId][dimT2];
19979 gradY[s * nDim + dimT1] += m_solver->a_slope(cellId, PV->Y[s], dimT2) * m_dirTangent[cbcId][dimT2];
19980 gradY[s * nDim + dimT2] = m_solver->a_slope(cellId, PV->Y[s], dimT2);
19981 }
19982 }
19983 }
19984}

◆ cbcGradientsViscous()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcGradientsViscous ( MInt  cellId,
MInt  bcId,
MFloat tau,
MFloat q,
MFloat gradTau,
MFloat gradQ,
MInt cutOffStencilCellIds 
)
Date
October 2019

Definition at line 19875 of file fvcartesianbndrycndxd.cpp.

19876 {
19877 TRACE();
19878
19879 auto index = [&](MInt dim0, MInt dim1, MInt dim2) { return dim0 * (nDim * nDim) + dim1 * nDim + dim2; };
19880
19881 MInt cbcId = m_cbcBndryCndIds[bcId];
19882
19883 MInt dimN = m_cbcDir[cbcId][1];
19884 MInt dimT1 = m_cbcDir[cbcId][2];
19885
19886 MInt coId = cutOffStencilCellIds[cellId];
19887 MInt recData = m_solver->a_reconstructionData(cellId);
19888 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
19889 MInt recNghbr = m_solver->a_reconstructionNeighborId(cellId, nghbr);
19890 MInt coIdN = cutOffStencilCellIds[recNghbr];
19891 for(MInt i = 0; i < nDim; i++) {
19892 MFloat recConst = m_solver->m_reconstructionConstants[nDim * (recData + nghbr) + i];
19893 gradTau[index(dimN, dimN, i)] += recConst * (tau[index(coIdN, dimN, dimN)] - tau[index(coId, dimN, dimN)]);
19894 gradTau[index(dimN, dimT1, i)] += recConst * (tau[index(coIdN, dimN, dimT1)] - tau[index(coId, dimN, dimT1)]);
19895 gradTau[index(dimT1, dimT1, i)] += recConst * (tau[index(coIdN, dimT1, dimT1)] - tau[index(coId, dimT1, dimT1)]);
19896 gradQ[index(0, dimN, i)] += recConst * (q[index(0, coIdN, dimN)] - q[index(0, coId, dimN)]);
19897 gradQ[index(0, dimT1, i)] += recConst * (q[index(0, coIdN, dimT1)] - q[index(0, coId, dimT1)]);
19898 IF_CONSTEXPR(nDim == 3) {
19899 MInt dimT2 = m_cbcDir[cbcId][nDim];
19900 gradTau[index(dimN, dimT2, i)] += recConst * (tau[index(coIdN, dimN, dimT2)] - tau[index(coId, dimN, dimT2)]);
19901 gradTau[index(dimT1, dimT2, i)] +=
19902 recConst * (tau[index(coIdN, dimT1, dimT2)] - tau[index(coId, dimT1, dimT2)]);
19903 gradTau[index(dimT2, dimT2, i)] +=
19904 recConst * (tau[index(coIdN, dimT2, dimT2)] - tau[index(coId, dimT2, dimT2)]);
19905 gradQ[index(0, dimT2, i)] += recConst * (q[index(0, coIdN, dimT2)] - q[index(0, coId, dimT2)]);
19906 }
19907 }
19908 }
19909}
MInt & a_reconstructionData(const MInt cellId)
Returns reconstruction data offset i of the cell cellId.
std::vector< MFloat > m_reconstructionConstants

◆ cbcMachCo()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcMachCo ( MInt  bcId,
MFloat mach 
)
Date
October 2019

Definition at line 19656 of file fvcartesianbndrycndxd.cpp.

19656 {
19657 TRACE();
19658
19659 MInt cbcId = m_cbcBndryCndIds[bcId];
19660 MInt dirN = m_cbcDir[cbcId][0];
19661 MInt dimN = m_cbcDir[cbcId][1];
19662 MInt dimT1 = m_cbcDir[cbcId][2];
19663
19664 MFloat localMach[2] = {F0, F0};
19665
19666 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19667 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19668 MInt bndryId = m_solver->a_bndryId(cellId);
19669
19670 if(m_solver->a_isHalo(cellId)) continue;
19671 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19672 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19673 MFloat area = -1;
19674 if(bndryId > -1) {
19675 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
19676 if(srfcId > -1) {
19677 area = m_solver->a_surfaceArea(srfcId);
19678 IF_CONSTEXPR(nDim == 3) ASSERT(area <= POW2(m_solver->c_cellLengthAtCell(cellId)), "");
19679 } else {
19680 for(MInt dir = 0; dir < m_noDirs; dir++) {
19681 srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dir];
19682 if(srfcId > -1) break;
19683 }
19684 if(srfcId == -1) {
19685 mTerm(1, AT_, "something went wrong!");
19686 }
19687 area = m_solver->a_surfaceArea(srfcId);
19688 }
19689 } else {
19690 IF_CONSTEXPR(nDim == 2) area = m_solver->c_cellLengthAtCell(cellId);
19691 IF_CONSTEXPR(nDim == 3) area = POW2(m_solver->c_cellLengthAtCell(cellId));
19692 }
19693
19694 area *= m_dirTangent[cbcId][dimT1];
19695
19696 const MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
19697 const MFloat p = m_solver->a_pvariable(cellId, PV->P);
19698 const MFloat T = sysEqn().temperature_ES(rho, p);
19699 const MFloat a = sysEqn().speedOfSound(T);
19700
19701 MFloat un = m_solver->a_pvariable(cellId, PV->VV[dimN]) * m_dirNormal[cbcId][dimN]
19702 + m_solver->a_pvariable(cellId, PV->VV[dimT1]) * m_dirNormal[cbcId][dimT1];
19703 IF_CONSTEXPR(nDim == 3) {
19704 MInt dimT2 = m_cbcDir[cbcId][nDim];
19705 un += m_solver->a_pvariable(cellId, PV->VV[dimT2]) * m_dirNormal[cbcId][dimT2];
19706 }
19707
19708 const MFloat M = fabs(un / a);
19709
19710 localMach[0] += fabs(M) * area;
19711 localMach[1] = mMax(localMach[1], M);
19712 }
19713
19714 MFloat globalMach[2] = {F0, F0};
19715
19716 if(m_solver->noDomains() > 1) {
19717 MPI_Allreduce(&localMach[0], &globalMach[0], 1, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
19718 "localMeanMach", "globalMeanMach");
19719 MPI_Allreduce(&localMach[1], &globalMach[1], 1, MPI_DOUBLE, MPI_MAX, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
19720 "localMaxMach", "globalMaxMach");
19721 }
19722
19723 MFloat inflowArea = m_cbcInflowArea[cbcId];
19724 globalMach[0] /= inflowArea;
19725
19726 mach[0] = globalMach[0];
19727 mach[1] = globalMach[1];
19728
19729 return;
19730}
virtual MInt noDomains() const
Definition: solver.h:387

◆ cbcMeanPressureCo()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcMeanPressureCo ( MInt  bcId,
MFloat pressure 
)

Definition at line 20105 of file fvcartesianbndrycndxd.cpp.

20105 {
20106 TRACE();
20107
20108 MInt cbcId = m_cbcBndryCndIds[bcId];
20109 MInt dirN = m_cbcDir[cbcId][0];
20110
20111 MFloat localMeanPressure = F0;
20112
20113 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
20114 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
20115 MInt bndryId = m_solver->a_bndryId(cellId);
20116
20117 if(m_solver->a_isHalo(cellId)) continue;
20118 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
20119 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
20120
20121 MFloat area;
20122 if(bndryId > -1) {
20123 // identify the "boundary surface" between cutoff boundary cell
20124 // and neighboring layer cell if cell is a boundary cell
20125 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
20126 if(srfcId > -1) {
20127 area = m_solver->a_surfaceArea(srfcId);
20128 } else {
20129 mTerm(1, AT_, "something went wrong!");
20130 }
20131 } else {
20132 area = m_solver->c_cellLengthAtCell(cellId);
20133#ifdef DIM3
20134 area = POW2(m_solver->c_cellLengthAtCell(cellId));
20135#endif
20136 }
20137
20138 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20139
20140 localMeanPressure += p * area;
20141 }
20142
20143 MFloat globalMeanPressure = F0;
20144
20145 MPI_Allreduce(&localMeanPressure, &globalMeanPressure, 1, MPI_DOUBLE, MPI_SUM, m_comm_bcCo[m_bcCo_comm_pointer[bcId]],
20146 AT_, "localMeanPressure", "globalMeanPressure");
20147
20148 const MFloat inflowArea = m_cbcInflowArea[cbcId];
20149
20150 globalMeanPressure /= inflowArea;
20151 pressure[0] = globalMeanPressure;
20152 return;
20153}

◆ cbcOutgoingAmplitudeVariation()

template<MInt nDim, class SysEqn >
template<MInt side>
void FvBndryCndXD< nDim, SysEqn >::cbcOutgoingAmplitudeVariation ( MInt  cellId,
MInt  bcId,
MFloat gradRho,
MFloat gradVV,
MFloat gradP,
MFloat gradY,
MFloat L 
)
Date
02.10.2019 side 0 = outflow 1 = inflow

Definition at line 19994 of file fvcartesianbndrycndxd.cpp.

19995 {
19996 TRACE();
19997
19998 MInt cbcId = m_cbcBndryCndIds[bcId];
19999
20000 MInt dimN = m_cbcDir[cbcId][1];
20001 MInt dimT1 = m_cbcDir[cbcId][2];
20002 MInt dimT2 = m_cbcDir[cbcId][nDim];
20003
20004 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20005 MFloat un = F0;
20006 un = m_solver->a_pvariable(cellId, PV->VV[dimN]) * m_dirNormal[cbcId][dimN]
20007 + m_solver->a_pvariable(cellId, PV->VV[dimT1]) * m_dirNormal[cbcId][dimT1];
20008
20009 IF_CONSTEXPR(nDim == 3) { un += m_solver->a_pvariable(cellId, PV->VV[dimT2]) * m_dirNormal[cbcId][dimT2]; }
20010
20011 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20012 MFloat a = sysEqn().speedOfSound(rho, p);
20013
20014 MInt last = CV->noVariables - 1 - m_solver->m_noSpecies;
20015
20016 if(side == 1) {
20017 MFloat lambda1 = (un - a);
20018 MFloat lambda5 = (un + a);
20019 L[0] = lambda1 * (gradP[dimN] - rho * a * gradVV[dimN * nDim + dimN]);
20020 L[last] = lambda5 * (gradP[dimN] + rho * a * gradVV[dimN * nDim + dimN]);
20021 IF_CONSTEXPR(nDim == 3) { L[3] = un * (gradVV[dimT2 * nDim + dimN]); }
20022 } else if(side == 0) {
20023 MFloat lambda1 = (un - a);
20024 MFloat lambda2 = un;
20025 MFloat lambda5 = (un + a);
20026 L[0] = lambda1 * (gradP[dimN] - rho * a * gradVV[dimN * nDim + dimN]);
20027 L[1] = lambda2 * (a * a * gradRho[dimN] - gradP[dimN]);
20028 L[2] = lambda2 * (gradVV[dimT1 * nDim + dimN]);
20029 IF_CONSTEXPR(nDim == 3) { L[3] = lambda2 * (gradVV[dimT2 * nDim + dimN]); }
20030 L[last] = lambda5 * (gradP[dimN] + rho * a * gradVV[dimN * nDim + dimN]);
20031 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20032 L[last + 1 + s] = lambda2 * gradY[s * nDim + dimN];
20033 }
20034 } else {
20035 mTerm(1, AT_, "Wrong template argument");
20036 }
20037}

◆ cbcRHS()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcRHS ( MInt  cellId,
MInt  bcId,
MFloat L,
MFloat T,
MFloat V 
)
Date
October 2019

Definition at line 20291 of file fvcartesianbndrycndxd.cpp.

20291 {
20292 TRACE();
20293
20294 MInt last = CV->noVariables - 1 - m_solver->m_noSpecies;
20295
20296 MInt cbcId = m_cbcBndryCndIds[bcId];
20297
20298 MInt dimN = m_cbcDir[cbcId][1];
20299 MInt dimT1 = m_cbcDir[cbcId][2];
20300
20301 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20302 MFloat un = F0;
20303 MFloat ut1 = F0;
20304
20305 un = m_solver->a_pvariable(cellId, PV->VV[dimN]) * m_dirNormal[cbcId][dimN]
20306 + m_solver->a_pvariable(cellId, PV->VV[dimT1]) * m_dirNormal[cbcId][dimT1];
20307 ut1 = m_solver->a_pvariable(cellId, PV->VV[dimN]) * m_dirTangent[cbcId][dimN]
20308 + m_solver->a_pvariable(cellId, PV->VV[dimT1]) * m_dirTangent[cbcId][dimT1];
20309
20310 MFloat ut2 = F0;
20311 IF_CONSTEXPR(nDim == 3) {
20312 MInt dimT2 = m_cbcDir[cbcId][nDim];
20313 un += m_solver->a_pvariable(cellId, PV->VV[dimT2]) * m_dirNormal[cbcId][dimT2];
20314 ut1 += m_solver->a_pvariable(cellId, PV->VV[dimT2]) * m_dirTangent[cbcId][dimT2];
20315 ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
20316 }
20317
20318 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20319 MFloat a = sysEqn().speedOfSound(rho, p);
20320
20321 MFloat sumOfVVSquared = POW2(un) + POW2(ut1);
20322 IF_CONSTEXPR(nDim == 3) sumOfVVSquared += POW2(ut2);
20323
20324 MFloat d1 = m_dirNormal[cbcId][dimN] * F1 / (a * a) * L[1] + m_dirNormal[cbcId][dimT1] * L[3]
20325 + F1B2 * F1 / (a * a) * (L[last] + L[0]);
20326 MFloat d2 = m_dirNormal[cbcId][dimN] * (F1B2 / (rho * a) * (L[last] - L[0])) - m_dirNormal[cbcId][dimT1] * L[2];
20327 MFloat d3 = m_dirNormal[cbcId][dimN] * L[2] + m_dirNormal[cbcId][dimT1] * (F1B2 / (rho * a) * (L[last] - L[0]));
20328 IF_CONSTEXPR(nDim == 3) {
20329 MInt dimT2 = m_cbcDir[cbcId][nDim];
20330 d1 -= m_dirNormal[cbcId][dimT2] * L[2];
20331 d2 -= m_dirNormal[cbcId][dimT2] * L[3];
20332 d3 += m_dirNormal[cbcId][dimT2] * F1 / (a * a) * L[1];
20333 }
20334 MFloat d5 = F1B2 * (L[last] + L[0]);
20335
20336 std::vector<MFloat> dSpecies;
20337 std::vector<MFloat> rhs_rhoY;
20338 dSpecies.resize(m_solver->m_noSpecies);
20339 rhs_rhoY.resize(m_solver->m_noSpecies);
20340
20341 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20342 dSpecies[s] = L[last + 1 + s];
20343 }
20344
20345 MFloat rhs_rho = -d1 + T[0] + V[0];
20346 MFloat rhs_rhoun = un * (-d1 + T[0] + V[0]) + rho * (-d2 + T[1] + V[1]);
20347 MFloat rhs_rhout1 = ut1 * (-d1 + T[0] + V[0]) + rho * (-d3 + T[2] + V[2]);
20348 MFloat rhs_rhoe = F1B2 * sumOfVVSquared * (-d1 + T[0] + V[0]) + rho * un * (-d2 + T[1] + V[1])
20349 + rho * ut1 * (-d3 + T[2] + V[2]) + sysEqn().cp_Ref() * (-d5 + T[last] + V[last]);
20350
20351 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20352 rhs_rhoY[s] = m_solver->a_pvariable(cellId, PV->Y[s]) * (-d1 + T[0]) + rho * (-dSpecies[s] + T[last + 1 + s]);
20353 }
20354
20355 IF_CONSTEXPR(nDim == 3) {
20356 MInt dimT2 = m_cbcDir[cbcId][nDim];
20357 MFloat d4 = m_dirNormal[cbcId][dimN] * L[3] + m_dirNormal[cbcId][dimT2] * (F1B2 / (rho * a) * (L[last] - L[0]))
20358 - m_dirNormal[cbcId][dimT1] * F1 / (a * a) * L[1];
20359 MFloat rhs_rhout2 = ut2 * (-d1 + T[0] + V[0]) + rho * (-d4 + T[3] + V[3]);
20360 rhs_rhoe += rho * ut2 * (-d4 + T[3] + V[3]);
20361
20362 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT2]) = -m_solver->a_cellVolume(cellId) * rhs_rhout2;
20363 }
20364
20365 m_solver->a_rightHandSide(cellId, CV->RHO) = -m_solver->a_cellVolume(cellId) * rhs_rho;
20366 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimN]) = -m_solver->a_cellVolume(cellId) * rhs_rhoun;
20367 m_solver->a_rightHandSide(cellId, CV->RHO_VV[dimT1]) = -m_solver->a_cellVolume(cellId) * rhs_rhout1;
20368 m_solver->a_rightHandSide(cellId, CV->RHO_E) = -m_solver->a_cellVolume(cellId) * rhs_rhoe;
20369
20370 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20371 m_solver->a_rightHandSide(cellId, CV->RHO_Y[s]) -= m_solver->a_cellVolume(cellId) * rhs_rhoY[s];
20372 }
20373}

◆ cbcTauQ()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcTauQ ( MInt  bcId,
MFloat tau,
MFloat q,
MInt cutOffStencilCellIds 
)
Date
October 2019

Definition at line 19737 of file fvcartesianbndrycndxd.cpp.

19737 {
19738 TRACE();
19739
19740 auto index = [&](MInt dim0, MInt dim1, MInt dim2) { return dim0 * (nDim * nDim) + dim1 * nDim + dim2; };
19741
19742 MInt cbcId = m_cbcBndryCndIds[bcId];
19743
19744 MInt dimN = m_cbcDir[cbcId][1];
19745 MInt dimT1 = m_cbcDir[cbcId][2];
19746
19747 for(MInt i = 0; i < m_solver->maxNoGridCells(); i++) {
19748 cutOffStencilCellIds[i] = -1;
19749 }
19750
19751 MInt cellCounter = 0;
19752 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19753 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19754
19755 if(m_solver->a_isHalo(cellId)) continue;
19756 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
19757 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
19758
19759 MInt bndryId = m_solver->a_bndryId(cellId);
19760 if(bndryId > -1) {
19761 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) continue;
19762 }
19763
19764 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
19765 MFloat p = m_solver->a_pvariable(cellId, PV->P);
19766 MFloat T = sysEqn().temperature_ES(rho, p);
19767
19768 if(cutOffStencilCellIds[cellId] < 0) { // tau and q have not been computed yet
19769 MInt coId = cellCounter++;
19770 cutOffStencilCellIds[cellId] = coId;
19771
19772 MFloat dpdn = m_solver->a_slope(cellId, PV->P, dimN);
19773 MFloat dpdt1 = m_solver->a_slope(cellId, PV->P, dimT1);
19774 MFloat drhodn = m_solver->a_slope(cellId, PV->RHO, dimN);
19775 MFloat drhodt1 = m_solver->a_slope(cellId, PV->RHO, dimT1);
19776 MFloat dundn = m_solver->a_slope(cellId, PV->VV[dimN], dimN);
19777 MFloat dundt1 = m_solver->a_slope(cellId, PV->VV[dimN], dimT1);
19778 MFloat dut1dn = m_solver->a_slope(cellId, PV->VV[dimT1], dimN);
19779 MFloat dut1dt1 = m_solver->a_slope(cellId, PV->VV[dimT1], dimT1);
19780
19781 const MFloat mu = sysEqn().sutherlandLaw(T);
19782 MFloat divT = dundn + dut1dt1;
19783 IF_CONSTEXPR(nDim == 3) {
19784 MInt dimT2 = m_cbcDir[cbcId][nDim];
19785 MFloat dpdt2 = m_solver->a_slope(cellId, PV->P, dimT2);
19786 MFloat drhodt2 = m_solver->a_slope(cellId, PV->RHO, dimT2);
19787 MFloat dundt2 = m_solver->a_slope(cellId, PV->VV[dimN], dimT2);
19788 MFloat dut1dt2 = m_solver->a_slope(cellId, PV->VV[dimT1], dimT2);
19789 MFloat dut2dn = m_solver->a_slope(cellId, PV->VV[dimT2], dimN);
19790 MFloat dut2dt1 = m_solver->a_slope(cellId, PV->VV[dimT2], dimT1);
19791 MFloat dut2dt2 = m_solver->a_slope(cellId, PV->VV[dimT2], dimT2);
19792 divT = divT + dut2dt2;
19793
19794 tau[index(coId, dimN, dimT2)] = mu * (dundt2 + dut2dn);
19795 tau[index(coId, dimT2, dimN)] = tau[index(coId, dimN, dimT2)];
19796 tau[index(coId, dimT1, dimT2)] = mu * (dut1dt2 + dut2dt1);
19797 tau[index(coId, dimT2, dimT2)] = mu * (F2 * dut2dt2 - F2B3 * divT);
19798 tau[index(coId, dimT2, dimT1)] = tau[index(coId, dimT1, dimT2)];
19799
19800 q[index(0, coId, dimT2)] =
19801 mu * m_solver->m_gamma * sysEqn().cp_Ref() / (m_solver->m_Pr * rho) * (dpdt2 - p / rho * drhodt2);
19802 }
19803
19804 tau[index(coId, dimN, dimN)] = mu * (F2 * dundn - F2B3 * divT);
19805 tau[index(coId, dimN, dimT1)] = mu * (dundt1 + dut1dn);
19806 tau[index(coId, dimT1, dimN)] = tau[index(coId, dimN, dimT1)];
19807 tau[index(coId, dimT1, dimT1)] = mu * (F2 * dut1dt1 - F2B3 * divT);
19808
19809 q[index(0, coId, dimN)] =
19810 mu * m_solver->m_gamma * sysEqn().cp_Ref() / (m_solver->m_Pr * rho) * (dpdn - p / rho * drhodn);
19811 q[index(0, coId, dimT1)] =
19812 mu * m_solver->m_gamma * sysEqn().cp_Ref() / (m_solver->m_Pr * rho) * (dpdt1 - p / rho * drhodt1);
19813 }
19814
19815 for(MInt recN = 0; recN < m_solver->a_noReconstructionNeighbors(cellId); recN++) {
19816 MInt recNgbhr = m_solver->a_reconstructionNeighborId(cellId, recN);
19817 if(cutOffStencilCellIds[recNgbhr] < 0) {
19818 MInt coIdN = cellCounter++;
19819 cutOffStencilCellIds[recNgbhr] = coIdN;
19820 // compute shear tensor and heat flux on recNgbhr:
19821 MFloat pG = m_solver->a_pvariable(recNgbhr, PV->P);
19822 MFloat rhoG = m_solver->a_pvariable(recNgbhr, PV->RHO);
19823 MFloat TG = sysEqn().temperature_ES(rhoG, pG);
19824 MFloat muG = sysEqn().sutherlandLaw(TG);
19825 MFloat dpdnG = m_solver->a_slope(recNgbhr, PV->P, dimN);
19826 MFloat dpdt1G = m_solver->a_slope(recNgbhr, PV->P, dimT1);
19827 MFloat drhodnG = m_solver->a_slope(recNgbhr, PV->RHO, dimN);
19828 MFloat drhodt1G = m_solver->a_slope(recNgbhr, PV->RHO, dimT1);
19829 MFloat dundnG = m_solver->a_slope(recNgbhr, PV->VV[dimN], dimN);
19830 MFloat dundt1G = m_solver->a_slope(recNgbhr, PV->VV[dimN], dimT1);
19831 MFloat dut1dnG = m_solver->a_slope(recNgbhr, PV->VV[dimT1], dimN);
19832 MFloat dut1dt1G = m_solver->a_slope(recNgbhr, PV->VV[dimT1], dimT1);
19833
19834 MFloat divTG = dundnG + dut1dt1G;
19835
19836 IF_CONSTEXPR(nDim == 3) {
19837 MInt dimT2 = m_cbcDir[cbcId][nDim];
19838 MFloat dpdt2G = m_solver->a_slope(recNgbhr, PV->P, dimT2);
19839 MFloat drhodt2G = m_solver->a_slope(recNgbhr, PV->RHO, dimT2);
19840 MFloat dundt2G = m_solver->a_slope(recNgbhr, PV->VV[dimN], dimT2);
19841 MFloat dut1dt2G = m_solver->a_slope(recNgbhr, PV->VV[dimT1], dimT2);
19842 MFloat dut2dnG = m_solver->a_slope(recNgbhr, PV->VV[dimT2], dimN);
19843 MFloat dut2dt1G = m_solver->a_slope(recNgbhr, PV->VV[dimT2], dimT1);
19844 MFloat dut2dt2G = m_solver->a_slope(recNgbhr, PV->VV[dimT2], dimT2);
19845 divTG = divTG + dut2dt2G;
19846
19847 tau[index(coIdN, dimN, dimT2)] = muG * (dundt2G + dut2dnG);
19848 tau[index(coIdN, dimT2, dimN)] = tau[index(coIdN, dimN, dimT2)];
19849 tau[index(coIdN, dimT2, dimT2)] = muG * (2 * dut2dt2G - F2B3 * divTG);
19850 tau[index(coIdN, dimT1, dimT2)] = muG * (dut1dt2G + dut2dt1G);
19851 tau[index(coIdN, dimT2, dimT1)] = tau[index(coIdN, dimT1, dimT2)];
19852
19853 q[index(0, coIdN, dimT2)] =
19854 muG * m_solver->m_gamma * sysEqn().cp_Ref() / (m_solver->m_Pr * rhoG) * (dpdt2G - pG / rhoG * drhodt2G);
19855 }
19856
19857 tau[index(coIdN, dimN, dimN)] = muG * (F2 * dundnG - F2B3 * divTG);
19858 tau[index(coIdN, dimN, dimT1)] = muG * (dundt1G + dut1dnG);
19859 tau[index(coIdN, dimT1, dimN)] = tau[index(coIdN, dimN, dimT1)];
19860 tau[index(coIdN, dimT1, dimT1)] = muG * (2 * dut1dt1G - F2B3 * divTG);
19861
19862 q[index(0, coIdN, dimN)] =
19863 muG * m_solver->m_gamma * sysEqn().cp_Ref() / (m_solver->m_Pr * rhoG) * (dpdnG - pG / rhoG * drhodnG);
19864 q[index(0, coIdN, dimT1)] =
19865 muG * m_solver->m_gamma * sysEqn().cp_Ref() / (m_solver->m_Pr * rhoG) * (dpdt1G - pG / rhoG * drhodt1G);
19866 }
19867 }
19868 }
19869}
MInt maxNoGridCells() const

◆ cbcTransversalTerms()

template<MInt nDim, class SysEqn >
template<unsigned char tTerms>
void FvBndryCndXD< nDim, SysEqn >::cbcTransversalTerms ( MInt  cellId,
MInt  bcId,
MFloat gradRho,
MFloat gradVV,
MFloat gradP,
MFloat gradY,
MFloat T 
)
Date
October 2019

Definition at line 20045 of file fvcartesianbndrycndxd.cpp.

20046 {
20047 TRACE();
20048
20049 MInt cbcId = m_cbcBndryCndIds[bcId];
20050
20051 MInt dimN = m_cbcDir[cbcId][1];
20052 MInt dimT1 = m_cbcDir[cbcId][2];
20053 MInt dimT2 = m_cbcDir[cbcId][nDim];
20054
20055 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20056 MFloat ut1 = F0;
20057
20058 ut1 = m_solver->a_pvariable(cellId, PV->VV[dimN]) * m_dirTangent[cbcId][dimN]
20059 + m_solver->a_pvariable(cellId, PV->VV[dimT1]) * m_dirTangent[cbcId][dimT1];
20060
20061 MFloat ut2 = F0;
20062 IF_CONSTEXPR(nDim == 3) {
20063 ut1 += m_solver->a_pvariable(cellId, PV->VV[dimT2]) * m_dirTangent[cbcId][dimT2];
20064 ut2 = m_solver->a_pvariable(cellId, PV->VV[dimT2]);
20065 }
20066
20067 MFloat p = m_solver->a_pvariable(cellId, PV->P);
20068
20069 MInt last = CV->noVariables - 1 - m_solver->m_noSpecies;
20070
20071 if(tTerms & 1) {
20072 T[0] = -rho * gradVV[dimT1 * nDim + dimT1] - ut1 * gradRho[dimT1];
20073 IF_CONSTEXPR(nDim == 3) T[0] += (-rho * gradVV[dimT2 * nDim + dimT2] - ut2 * gradRho[dimT2]);
20074 }
20075
20076 if(tTerms & 2) {
20077 T[1] = -ut1 * gradVV[dimN * nDim + dimT1];
20078 IF_CONSTEXPR(nDim == 3) T[1] += (-ut2 * gradVV[dimN * nDim + dimT2]);
20079 }
20080
20081 if(tTerms & 3) {
20082 T[2] = -ut1 * gradVV[dimT1 * nDim + dimT1] - F1 / rho * gradP[dimT1];
20083 IF_CONSTEXPR(nDim == 3) T[2] += (-ut2 * gradVV[dimT1 * nDim + dimT2]);
20084 }
20085
20086 IF_CONSTEXPR(nDim == 3) {
20087 if(tTerms & 4) {
20088 T[3] = -ut1 * gradVV[dimT2 * nDim + dimT1] - ut2 * gradVV[dimT2 * nDim + dimT2] - F1 / rho * gradP[dimT2];
20089 }
20090 }
20091
20092 if(tTerms & 5) {
20093 T[last] = -ut1 * gradP[dimT1] - p * sysEqn().gamma_Ref() * gradVV[dimT1 * nDim + dimT1];
20094 IF_CONSTEXPR(nDim == 3) T[last] += (-ut2 * gradP[dimT2] - p * sysEqn().gamma_Ref() * gradVV[dimT2 * nDim + dimT2]);
20095 }
20096
20097 for(MInt s = 0; s < m_solver->m_noSpecies; s++) {
20098 T[last + 1 + s] = -ut1 * gradY[s * nDim + dimT1];
20099 IF_CONSTEXPR(nDim == 3) T[last + 1 + s] += -ut2 * gradY[s * nDim + dimT2];
20100 }
20101}

◆ cbcTurbulenceInjection()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cbcTurbulenceInjection ( MInt  cellId,
MFloat L_turbulent,
MInt  sortedCutOffCellId 
)
Author
Soeren Mehnert
Date
June 2020

Definition at line 20381 of file fvcartesianbndrycndxd.cpp.

20381 {
20382 TRACE();
20383
20384 IF_CONSTEXPR(nDim != 3) mTerm(1, AT_, "Only implemented for nDim = 3");
20385
20386 MFloat dummyTime;
20387 MFloat that, twopioverlb;
20388
20389 MFloat xhat, yhat, zhat;
20390 MFloat fluctChol[3];
20391
20392 // calculate fluctuation from time step previous to restart
20393 if(m_solver->m_restart && globalTimeStep == m_solver->m_restartTimeStep + 1) {
20394 dummyTime = (m_solver->m_time - m_solver->m_timeStep) / m_bc1601->m_tau_b;
20395 m_bc1601->checkRegeneration(dummyTime);
20396
20397 that = F2 * PI * dummyTime;
20398 twopioverlb = F2 * PI / m_bc1601->m_l_b;
20399
20400 xhat = twopioverlb * m_solver->a_coordinate(cellId, 0);
20401 yhat = twopioverlb * m_solver->a_coordinate(cellId, 1);
20402 zhat = twopioverlb * m_solver->a_coordinate(cellId, 2);
20403
20404 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
20405
20406 m_oldFluctChol[sortedCutOffCellId][0] = fluctChol[0];
20407 m_oldFluctChol[sortedCutOffCellId][1] = fluctChol[1];
20408 IF_CONSTEXPR(nDim == 3) m_oldFluctChol[sortedCutOffCellId][2] = fluctChol[2];
20409 }
20410
20411 dummyTime = m_solver->m_time / m_bc1601->m_tau_b;
20412 m_bc1601->checkRegeneration(dummyTime);
20413
20414 that = F2 * PI * dummyTime;
20415 twopioverlb = F2 * PI / m_bc1601->m_l_b;
20416
20417 xhat = twopioverlb * m_solver->a_coordinate(cellId, 0);
20418 yhat = twopioverlb * m_solver->a_coordinate(cellId, 1);
20419 zhat = twopioverlb * m_solver->a_coordinate(cellId, 2);
20420
20421 m_bc1601->calculateFlucts(that, xhat, yhat, zhat, fluctChol);
20422
20423 MFloat dFluctCholndn =
20424 (fluctChol[0] - m_oldFluctChol[sortedCutOffCellId][0]) / (m_solver->c_cellLengthAtCell(cellId));
20425 MFloat dFluctCholt1dn =
20426 (fluctChol[1] - m_oldFluctChol[sortedCutOffCellId][1]) / (m_solver->c_cellLengthAtCell(cellId));
20427
20428 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20429 MFloat a = sysEqn().speedOfSound(rho, m_solver->a_pvariable(cellId, PV->P));
20430
20431 L_turbulent[0] = rho * a * m_solver->m_UInfinity * dFluctCholndn;
20432 L_turbulent[1] = rho * a * m_solver->m_UInfinity * dFluctCholt1dn;
20433 IF_CONSTEXPR(nDim == 3) {
20434 MFloat dFluctCholt2dn =
20435 (fluctChol[2] - m_oldFluctChol[sortedCutOffCellId][2]) / (m_solver->c_cellLengthAtCell(cellId));
20436 L_turbulent[2] = rho * a * m_solver->m_UInfinity * dFluctCholt2dn;
20437 }
20438
20439 if(m_solver->m_RKStep == m_solver->m_noRKSteps - 1) {
20440 m_oldFluctChol[sortedCutOffCellId][0] = fluctChol[0];
20441 m_oldFluctChol[sortedCutOffCellId][1] = fluctChol[1];
20442 IF_CONSTEXPR(nDim == 3) m_oldFluctChol[sortedCutOffCellId][2] = fluctChol[2];
20443 }
20444
20445 return;
20446}

◆ cbcViscousTerms()

template<MInt nDim, class SysEqn >
template<unsigned char vTerms>
void FvBndryCndXD< nDim, SysEqn >::cbcViscousTerms ( MInt  cellId,
MInt  bcId,
MFloat tau,
MFloat gradTau,
MFloat gradQ,
MFloat gradVV,
MInt cutOffStencilCellIds,
MFloat V 
)
Date
October 2019

Definition at line 20160 of file fvcartesianbndrycndxd.cpp.

20161 {
20162 TRACE();
20163
20164 auto index = [&](MInt dim0, MInt dim1, MInt dim2) { return dim0 * (nDim * nDim) + dim1 * nDim + dim2; };
20165
20166 // if ( m_solver->m_noSpecies > 0 ) mTerm(1, AT_, "Species not yet supported!");
20167
20168 MInt coId = cutOffStencilCellIds[cellId];
20169
20170 MInt cbcId = m_cbcBndryCndIds[bcId];
20171
20172 MInt dimN = m_cbcDir[cbcId][1];
20173 MInt dimT1 = m_cbcDir[cbcId][2];
20174 MInt dimT2 = m_cbcDir[cbcId][nDim];
20175
20176 MFloat rho = m_solver->a_pvariable(cellId, PV->RHO);
20177 MInt last = CV->noVariables - 1 - m_solver->m_noSpecies;
20178 // MInt last = 4;
20179 if(last != 4) mTerm(1, AT_, "last is not four!");
20180
20181 if(vTerms & 2) {
20182 MFloat Sum_dtaun = gradTau[index(dimN, dimN, dimN)] + gradTau[index(dimN, dimT1, dimT1)];
20183 IF_CONSTEXPR(nDim == 3) { Sum_dtaun += gradTau[index(dimN, dimT2, dimT2)]; }
20184 V[1] = F1 / (sysEqn().m_Re0 * rho) * (Sum_dtaun);
20185 }
20186
20187 if(vTerms & 3) {
20188 MFloat Sum_dtaut = gradTau[index(dimT1, dimT1, dimT1)];
20189 IF_CONSTEXPR(nDim == 3) { Sum_dtaut += gradTau[index(dimT1, dimT2, +dimT2)]; }
20190 V[2] = F1 / (sysEqn().m_Re0 * rho) * (Sum_dtaut);
20191 }
20192
20193 IF_CONSTEXPR(nDim == 3) {
20194 if(vTerms & 4) {
20195 V[3] = F1 / (sysEqn().m_Re0 * rho) * (gradTau[index(dimT1, dimT2, dimT1)] + gradTau[index(dimT2, dimT2, dimT2)]);
20196 }
20197 }
20198
20199 if(vTerms & 5) {
20200 MFloat Sum_d_for_V5 =
20201 tau[index(coId, dimN, dimN)] * gradVV[index(0, dimN, dimN)]
20202 + tau[index(coId, dimN, dimT1)] * (gradVV[index(0, dimT1, dimN)] + gradVV[index(0, dimN, dimT1)])
20203 + tau[index(coId, dimT1, dimT1)] * gradVV[index(0, dimT1, dimT1)] + gradQ[index(0, dimT1, dimT1)];
20204
20205 IF_CONSTEXPR(nDim == 3) {
20206 Sum_d_for_V5 +=
20207 tau[index(coId, dimN, dimT2)] * (gradVV[index(0, dimT2, dimN)] + gradVV[index(0, dimN, dimT2)])
20208 + tau[index(coId, dimT2, dimT2)] * gradVV[index(0, dimT2, dimT2)]
20209 + tau[index(coId, dimT1, dimT2)] * (gradVV[index(0, dimT1, dimT2)] + gradVV[index(0, dimT2, dimT1)])
20210 + gradQ[index(0, dimT2, dimT2)];
20211 }
20212 V[last] = Sum_d_for_V5 / sysEqn().cp_Ref() / sysEqn().m_Re0;
20213 }
20214}

◆ checkBoundaryCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::checkBoundaryCells

Definition at line 7762 of file fvcartesianbndrycndxd.cpp.

7762 {
7763 TRACE();
7764
7765 MInt noCells = m_bndryCells->size();
7766
7767 // check boundary cell volumes
7768 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
7769 if(m_bndryCells->a[bndryId].m_volume <= 0) {
7770 cerr << "Cell " << m_bndryCells->a[bndryId].m_cellId << " at level "
7771 << m_solver->a_level(m_bndryCells->a[bndryId].m_cellId) << " has volume "
7772 << m_bndryCells->a[bndryId].m_volume << endl;
7773 cerr << "Cut points of cell " << m_bndryCells->a[bndryId].m_cellId << ":" << endl;
7774 for(MInt point = 0; point < m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints; point++) {
7775 for(MInt i = 0; i < nDim; i++) {
7776 cerr << point << " x" << i << " " << m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[point][i] << endl;
7777 }
7778 }
7779 }
7780 /*
7781 if( m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints != 2 ) {
7782 cerr << "Cell "
7783 << m_bndryCells->a[ bndryId ].m_cellId
7784 << " at level "
7785 << m_solver->a_level( m_bndryCells->a[ bndryId ].m_cellId )
7786 << " does not have 2 cut points " << endl;
7787 }
7788 //check neighbors
7789 MInt counter = 0;
7790 for( MInt dirId = 0; dirId < 2*nDim; dirId++ ) {
7791 if( m_bndryCells->a[ bndryId ].m_noNghbrIds[ dirId ] > 0 ) {
7792 counter += m_bndryCells->a[ bndryId ].m_noNghbrIds[ dirId ];
7793 }
7794 }
7795 MInt bndryIdNghbr;
7796 if( counter < 2 || counter > 3 ) {
7797 cerr << "At level (direction 0) " << m_solver->a_level( m_bndryCells->a[ bndryId ].m_cellId ) << endl;
7798 cerr << "Number of boundary cell neighbors of " << m_bndryCells->a[ bndryId ].m_cellId << ": " << counter << endl;
7799 cerr << m_solver->a_coordinate( m_bndryCells->a[ bndryId ].m_cellId , 0 ) << " "
7800 << m_solver->a_coordinate( m_bndryCells->a[ bndryId ].m_cellId , 1 ) << " "
7801 << m_solver->c_cellLengthAtCell(m_bndryCells->a[ bndryId ].m_cellId ) << endl;
7802 cerr << "Number of cut points " << m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints << endl;
7803 for( MInt i = 0; i < m_bndryCells->a[ bndryId ].m_srfcs[0]->m_noCutPoints; i++ ) {
7804 cerr << m_bndryCells->a[ bndryId ].m_srfcs[0]->m_cutCoordinates[ i ][ 0 ] << " "
7805 << m_bndryCells->a[ bndryId ].m_srfcs[0]->m_cutCoordinates[ i ][ 1 ] << endl;
7806 }
7807 cerr << "Boundary cell neighbor information:" << endl;
7808 for( MInt dirId = 0; dirId < m_noDirs; dirId++ ) {
7809 if( m_bndryCells->a[ bndryId ].m_noNghbrIds[ dirId ] > 0 ) {
7810 cerr << "+++++" << endl;
7811 cerr << "Neighbor in " << dirId << " direction..." << endl;
7812 bndryIdNghbr = m_bndryCells->a[ bndryId ].m_nghbrIds[ dirId ][ 0 ];
7813 cerr << "...at level (direction 0) " << m_solver->a_level( m_bndryCells->a[ bndryIdNghbr ].m_cellId ) << endl;
7814 cerr << m_solver->a_coordinate( m_bndryCells->a[ bndryIdNghbr ].m_cellId , 0 ) << " "
7815 << m_solver->a_coordinate( m_bndryCells->a[ bndryIdNghbr ].m_cellId , 1 ) << " "
7816 << m_solver->c_cellLengthAtCell( m_bndryCells->a[ bndryIdNghbr ].m_cellId )]) << endl;
7817 cerr << "Number of cut points " << m_bndryCells->a[ bndryIdNghbr ].m_srfcs[0]->m_noCutPoints << endl;
7818 for( MInt i = 0; i < m_bndryCells->a[ bndryIdNghbr ].m_srfcs[0]->m_noCutPoints; i++ ) {
7819 cerr << m_bndryCells->a[ bndryIdNghbr ].m_srfcs[0]->m_cutCoordinates[ i ][ 0 ] << " "
7820 << m_bndryCells->a[ bndryIdNghbr ].m_srfcs[0]->m_cutCoordinates[ i ][ 1 ] << endl;
7821 }
7822 cerr << endl;
7823 }
7824 cerr << "+++++" << endl;
7825 }
7826 cerr << "-------------------------------" << endl;
7827 }
7828 */
7829 }
7830 // cout << "*** all boundary cells checked ***" << endl;
7831}

◆ checkCutPointsValidity()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::checkCutPointsValidity
Author
Daniel Hartmann, Claudia Guenther, Andreas Lintermann
Date
15.04.2016

This was part of the function computeCutPoints() before. Had to be moved out of this function to apply a different handlin for parallel geometries.

Definition at line 11890 of file fvcartesianbndrycndxd.cpp.

11890 {
11891 TRACE();
11892
11893 const MInt noCells = m_bndryCells->size();
11894 // boundary cells with not enough cut points should be removed -> important: check, if corresponding cell should also
11895 // be removed! mark boundary cells with less than 3/2 cut points
11896 for(MInt bndryId = noCells - 1; bndryId > -1; bndryId--) {
11897 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
11898 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints < nDim) {
11899#ifndef NDEBUG
11900 m_log << "cell " << cellId << " on level " << m_solver->a_level(cellId) << " with globalId "
11901 << m_solver->c_globalId(cellId) << " has less than " << nDim << " cut points! deleting bndryCell! " << endl;
11902#endif
11903
11904 m_solver->a_isInterface(cellId) = false;
11905 m_solver->a_hasProperty(cellId, SolverCell::IsMovingBnd) = false;
11906 m_solver->a_bndryId(cellId) = -1;
11907 m_solver->a_bndryId(m_bndryCells->a[bndryId].m_cellId) = -1;
11908 deleteBndryCell(bndryId);
11909
11910 // If the deleted bounday cell was not the last cell in m_bndryCells the last cell was moved
11911 // to the position of the deleted cell and its corresponding bndryId needs to be updated!
11912 if(bndryId < m_bndryCells->size()) {
11913 m_solver->a_bndryId(m_bndryCells->a[bndryId].m_cellId) = bndryId;
11914 }
11915
11916 // if cell is not located fully in the fluid domain, mark it as inactive
11917 // do not really delete the cell, as this leas to inconsistencies with the other domains resulting from cell
11918 // reordering!
11919 if(!checkInside(cellId)) {
11920#ifndef NDEBUG
11921 if(m_solver->c_noChildren(cellId) == 0) {
11922 cerr << domainId() << ": cell deactivated"
11923 << ", cellId " << cellId << ", globalId " << m_solver->c_globalId(cellId) << ", level "
11924 << m_solver->a_level(cellId) << endl;
11925 }
11926#endif
11927 m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = false;
11928 m_solver->a_hasProperty(cellId, SolverCell::IsInvalid) = true;
11929
11930 MInt parentId = m_solver->c_parentId(cellId);
11931 MInt itCnt = 0;
11932 while(parentId > -1) {
11933 m_solver->a_hasProperty(parentId, SolverCell::IsOnCurrentMGLevel) = false;
11934 m_solver->a_hasProperty(parentId, SolverCell::IsInvalid) = true;
11935 // cerr << domainId() <<": parent " << parentId << " " << m_solver->c_globalId( parentId ) << endl;
11936 // if ( m_solver->c_parentId( parentId ) == -1 ) cerr << domainId() <<": parent " << parentId << endl;
11937 parentId = m_solver->c_parentId(parentId);
11938 itCnt++;
11939 if(itCnt > m_solver->maxLevel() - m_solver->minLevel()) {
11940 mTerm(1, AT_, "Invalid parent relations.");
11941 }
11942 }
11943 }
11944 }
11945 }
11946}
void deleteBndryCell(MInt)
Deletes a boundary cell (without collector fragmentation)
MBool checkInside(MInt)
checks if all corners of a cell are located in the computational domain
MBool a_isInterface(const MInt cellId) const
Returns isInterface of the cell cellId.
MLong c_parentId(const MInt cellId) const
Returns the grid parent id of the cell cellId.
MInt minLevel() const
Read-only accessors for grid data.

◆ checkCutPointsValidityParGeom()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::checkCutPointsValidityParGeom
Author
Andreas Lintermann
Date
15.04.2016
Todo:
labels:FV,totest this function is not yet working

This function in principal does the same as checkCutPointsValidity(), however, makes use of parallel geometry information.

Definition at line 11960 of file fvcartesianbndrycndxd.cpp.

11960 {
11961 TRACE();
11962
11963 // 1. basic init
11964 const MInt noCells = m_bndryCells->size();
11965 const MInt* traverseOrder = traverseCorners2D;
11966 IF_CONSTEXPR(nDim == 3) traverseOrder = traverseCorners3D;
11967
11968 MInt noCorners = IPOW2(nDim);
11969 MInt noShares = noCorners - 1;
11970
11971 MIntScratchSpace sharedCorners(noCorners, noShares, AT_, "sharedCorners");
11972 for(MInt c = 0; c < noCorners; c++) {
11973 for(MInt s = 0; s < noShares; s++) {
11974 IF_CONSTEXPR(nDim == 2) { sharedCorners(c, s) = sharedCornerNeighs2D[c][s]; }
11975 else {
11976 sharedCorners(c, s) = sharedCornerNeighs3D[c][s];
11977 }
11978 }
11979 }
11980
11981
11982 // 2. prepare: how many of the cells that we need to consider are totally outside?
11983 vector<MInt> missing;
11984
11985 // 2.1 find first only those that are easily detectable, i.e., cells that have a neighbor which is not an
11986 // interface cell. That is, run over all neighbors and check for the property IsInterface.
11987 // If a cell has only interface neighbors, it is added to the missing list that is processed in 2.2.
11988 for(MInt bndryId = noCells - 1; bndryId > -1; bndryId--) {
11989 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints < nDim) {
11990 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
11991 MBool found = false;
11992 MInt insidePt = -1;
11993
11994 // search a corner point that is inside for sure
11995 for(MInt corner = 0; corner < IPOW2(nDim); corner++) {
11996 for(MInt s = 0; s < noShares; s++) {
11997 MInt dir = sharedCorners(corner, s);
11998 if(m_solver->a_hasNeighbor(cellId, dir)
11999 && !m_solver->a_hasProperty(m_solver->c_neighborId(cellId, dir), SolverCell::IsInterface)) {
12000 found = true;
12001 insidePt = corner;
12002 break;
12003 }
12004 }
12005 if(found) break;
12006 }
12007
12008 // we found a corner of the current cell that is definitively inside
12009 if(found) {
12010 // perform a check if there is a way to an outside cell, then this cell
12011 // is not completely located inside
12012 cout << insidePt << " " << traverseOrder << endl;
12013 } else {
12014 }
12015 /*
12016
12017
12018 //run over all neighbors
12019 for(MInt n = 0; n < noNeigh; n++)
12020 {
12021 //great we found one
12022 if(m_solver->a_hasNeighbor(cellId, n) && !m_solver->a_hasProperty( m_solver->c_neighborId(cellId,n) ,
12023 SolverCell::IsInterface) )
12024 {
12025 found = true;
12026 bndCellIsOutside.insert(pair<MInt,MBool>(cellId,true));
12027 break;
12028 }
12029
12030 if(found)
12031 break;
12032 }
12033
12034 //the cell is either isolated or all neighbors are interface cells
12035 if(!found)
12036 missing.push_back(cellId);
12037
12038 */
12039 }
12040 }
12041
12042
12043 // 2.2 run over the cells that have
12044 if(!missing.empty()) {
12045 }
12046
12047 for(MInt bndryId = noCells - 1; bndryId > -1; bndryId--) {
12048 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
12049
12050 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints < nDim) {
12051#ifndef NDEBUG
12052 m_log << "cell " << cellId << " on level " << m_solver->a_level(cellId) << " with globalId "
12053 << m_solver->c_globalId(cellId) << " has less than " << nDim << " cut points! deleting bndryCell! " << endl;
12054#endif
12055
12056 m_solver->a_isInterface(cellId) = false;
12057 m_solver->a_bndryId(cellId) = -1;
12058 m_solver->a_bndryId(m_bndryCells->a[bndryId].m_cellId) = -1;
12059 deleteBndryCell(bndryId);
12060
12061 // If the deleted bounday cell was not the last cell in m_bndryCells the last cell was moved
12062 // to the position of the deleted cell and its corresponding bndryId needs to be updated!
12063 if(bndryId < m_bndryCells->size()) {
12064 m_solver->a_bndryId(m_bndryCells->a[bndryId].m_cellId) = bndryId;
12065 }
12066
12067 // if cell is not located fully in the fluid domain, mark it as inactive
12068 // do not really delete the cell, as this leas to inconsistencies with the other domains resulting from cell
12069 // reordering!
12070 if(!checkInside(cellId)) {
12071#ifndef NDEBUG
12072 if(m_solver->c_noChildren(cellId) == 0)
12073 cerr << domainId() << ": cell deactivated"
12074 << ", cellId " << cellId << ", globalId " << m_solver->c_globalId(cellId) << ", level "
12075 << m_solver->a_level(cellId) << endl;
12076#endif
12077
12078 m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel) = false;
12079 m_solver->a_hasProperty(cellId, SolverCell::IsInvalid) = true;
12080
12081 MInt parentId = m_solver->c_parentId(cellId);
12082 while(parentId > -1) {
12083 m_solver->a_hasProperty(parentId, SolverCell::IsOnCurrentMGLevel) = false;
12084 m_solver->a_hasProperty(parentId, SolverCell::IsInvalid) = true;
12085
12086 parentId = m_solver->c_parentId(parentId);
12087 }
12088 }
12089 }
12090 }
12091}

◆ checkInside()

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::checkInside ( MInt  cellId)

returns true if all eight corners of the cell are located in the fluid region important to decide if a former cut cell can be deleted if it has only "invalid" cut points (e.g. two on the same edge) or if it has to be kept as regular, non-boundary cell

Author
Claudia Guenther, June 2009

Definition at line 9985 of file fvcartesianbndrycndxd.cpp.

9985 {
9986 TRACE();
9987
9988 static constexpr MInt cornerIndices[8][3] = {{-1, -1, -1}, {1, -1, -1}, {-1, 1, -1}, {1, 1, -1},
9989 {-1, -1, 1}, {1, -1, 1}, {-1, 1, 1}, {1, 1, 1}};
9990 MFloat corner[3] = {0, 0, 0};
9991 MBool inside = true;
9992 MFloat cellHalfLength = F1B2 * m_solver->c_cellLengthAtCell(cellId);
9993
9994 for(MInt i = 0; i < m_noCorners; i++) {
9995 for(MInt dim = 0; dim < nDim; dim++) {
9996 corner[dim] = m_solver->c_coordinate(cellId, dim) + cornerIndices[i][dim] * cellHalfLength;
9997 }
9998 IF_CONSTEXPR(nDim == 2) {
9999 if((MBool)m_solver->m_geometry->pointIsInside(corner)) {
10000 inside = false; // pointIsInside == true if Point is outside fluid domain
10001 }
10002 }
10003 else {
10004 if((MBool)m_solver->m_geometry->pointIsInside2(corner)) {
10005 inside = false; // pointIsInside == true if Point is outside fluid domain
10006 }
10007 }
10008 }
10009
10010 return inside;
10011}
MFloat c_coordinate(const MInt cellId, const MInt dir) const
Returns the coordinate of the cell from the grid().tree() cellId for dimension dir.

◆ checkOutside() [1/2]

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::checkOutside ( const MFloat coords,
const MInt  level 
)

Definition at line 10041 of file fvcartesianbndrycndxd.cpp.

10041 {
10042 TRACE();
10043 static constexpr MInt cornerIndices[8][3] = {{-1, -1, -1}, {1, -1, -1}, {-1, 1, -1}, {1, 1, -1},
10044 {-1, -1, 1}, {1, -1, 1}, {-1, 1, 1}, {1, 1, 1}};
10045 MFloat corner[3] = {0, 0, 0};
10046 MBool outside = true;
10047 MFloat cellHalfLength = F1B2 * m_solver->c_cellLengthAtLevel(level);
10048
10049 for(MInt i = 0; i < m_noCorners; i++) {
10050 for(MInt dim = 0; dim < nDim; dim++) {
10051 corner[dim] = coords[dim] + cornerIndices[i][dim] * cellHalfLength;
10052 }
10053 IF_CONSTEXPR(nDim == 2) {
10054 if(!m_solver->m_geometry->pointIsInside(corner)) {
10055 outside = false; // pointIsInside == true if Point is outside fluid domain
10056 }
10057 }
10058 else {
10059 if(!m_solver->m_geometry->pointIsInside2(corner)) {
10060 outside = false; // pointIsInside == true if Point is outside fluid domain
10061 }
10062 }
10063 }
10064 return outside;
10065}

◆ checkOutside() [2/2]

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::checkOutside ( MInt  cellId)

Definition at line 10014 of file fvcartesianbndrycndxd.cpp.

10014 {
10015 TRACE();
10016 static constexpr MInt cornerIndices[8][3] = {{-1, -1, -1}, {1, -1, -1}, {-1, 1, -1}, {1, 1, -1},
10017 {-1, -1, 1}, {1, -1, 1}, {-1, 1, 1}, {1, 1, 1}};
10018 MFloat corner[3] = {0, 0, 0};
10019 MBool outside = true;
10020 MFloat cellHalfLength = F1B2 * m_solver->c_cellLengthAtCell(cellId);
10021
10022 for(MInt i = 0; i < m_noCorners; i++) {
10023 for(MInt dim = 0; dim < nDim; dim++) {
10024 corner[dim] = m_solver->c_coordinate(cellId, dim) + cornerIndices[i][dim] * cellHalfLength;
10025 }
10026 IF_CONSTEXPR(nDim == 2) {
10027 if(!m_solver->m_geometry->pointIsInside(corner)) {
10028 outside = false; // pointIsInside == true if Point is outside fluid domain
10029 }
10030 }
10031 else {
10032 if(!m_solver->m_geometry->pointIsInside2(corner)) {
10033 outside = false; // pointIsInside == true if Point is outside fluid domain
10034 }
10035 }
10036 }
10037 return outside;
10038}

◆ cmptGhostCells()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::cmptGhostCells ( )
inlinevirtual

Definition at line 213 of file fvcartesianbndrycndxd.h.

213{};

◆ computeCutoffBoundaryGeometry()

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::computeCutoffBoundaryGeometry ( const MInt  bcId,
const MInt  dirN,
MFloat referencePoint 
)
Author
Claudia Guenther, December 2013

Definition at line 12324 of file fvcartesianbndrycndxd.cpp.

12325 {
12326 MFloat inflowArea = F0;
12327 for(MInt i = F0; i < nDim; i++) {
12328 referencePoint[i] = F0;
12329 }
12330
12331 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
12332 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
12333
12334 if(m_solver->a_isHalo(cellId)) continue;
12335 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
12336 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
12337
12338 const MInt bndryId = m_solver->a_bndryId(cellId);
12339
12340 MFloat area = F0;
12341 if(bndryId > -1) {
12342 // identify the "boundary surface" between cutoff boundary cell
12343 // and neighboring layer cell if cell is a boundary cell
12344 MInt srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dirN];
12345 if(srfcId > -1) {
12346 area = m_solver->a_surfaceArea(srfcId);
12347 } else {
12348 for(MInt dir = 0; dir < m_noDirs; dir++) {
12349 srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[dir];
12350 if(srfcId > -1) break;
12351 }
12352 if(srfcId == -1) {
12353 cerr << "[" << domainId() << "]: did not find associated surface in dir " << dirN << " for cell " << cellId
12354 << endl;
12355 writeStlFileOfCell(cellId, "cell.stl");
12356 mTerm(1, AT_, "something went wrong!");
12357 }
12358 area = m_solver->a_surfaceArea(srfcId);
12359 }
12360 } else {
12361 IF_CONSTEXPR(nDim == 2) { area = m_solver->c_cellLengthAtCell(cellId); }
12362 else {
12363 area = POW2(m_solver->c_cellLengthAtCell(cellId));
12364 }
12365 }
12366 inflowArea += area;
12367 // compute midpoint of inflow boundary and mean normal
12368 for(MInt i = 0; i < nDim; i++) {
12369 referencePoint[i] += m_solver->a_coordinate(cellId, i) * area;
12370 }
12371 }
12372
12373 MInt minDom = domainId();
12374
12375 if(noDomains() > 1) {
12376 const MInt noExchangeData = 1 + nDim;
12377 MFloatScratchSpace comm_buff(noExchangeData, AT_, "comm_buff");
12378 comm_buff[0] = inflowArea;
12379 for(MInt i = 0; i < nDim; i++) {
12380 comm_buff[i + 1] = referencePoint[i];
12381 }
12382
12383 MPI_Allreduce(MPI_IN_PLACE, &comm_buff[0], noExchangeData, MPI_DOUBLE, MPI_SUM,
12384 m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_, "MPI_IN_PLACE", "comm_buff[0]");
12385 MPI_Allreduce(MPI_IN_PLACE, &minDom, 1, MPI_INT, MPI_MIN, m_comm_bcCo[m_bcCo_comm_pointer[bcId]], AT_,
12386 "MPI_IN_PLACE", "minDom");
12387
12388 inflowArea = comm_buff[0];
12389 for(MInt i = 0; i < nDim; i++) {
12390 referencePoint[i] = comm_buff[i + 1];
12391 }
12392 }
12393
12394 for(MInt i = 0; i < nDim; i++) {
12395 referencePoint[i] /= inflowArea;
12396 }
12397
12398 stringstream referencePointOutputStream;
12399 referencePointOutputStream << referencePoint[0] << " " << referencePoint[1] << " ";
12400 IF_CONSTEXPR(nDim == 3) referencePointOutputStream << referencePoint[2] << " ";
12401
12402 if(domainId() == minDom) {
12403 cerr << " [" << domainId() << "]: bndryId: " << bcId << " refPoint: " << referencePointOutputStream.str()
12404 << ", area: " << inflowArea << endl;
12405 }
12406
12407 return inflowArea;
12408}
virtual void writeStlFileOfCell(MInt, const MChar *)

◆ computeCutPoints()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeCutPoints ( )
  • m_srfcs->m_bndryCndId (the one with the smallest Id of all intersecting elements)
  • m_srfcs->m_noCutPoints
  • m_srfcs->m_cutCoordinates
Author
Daniel Hartmann, 22.12.2006, Claudia Guenther 08/2013, Sohel Herff 2016

◆ computeGhostCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeGhostCells

Definition at line 625 of file fvcartesianbndrycndxd.cpp.

625 {
626 TRACE();
629 //---
630
631 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
632 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
633 // append a cell to the cell-collectors only!
634 m_cells.append();
636 const MInt ghostCellId = m_solver->a_noCells() - 1;
637 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = ghostCellId;
638
639#ifdef mirroredGhostCell
640 // calculate the global coordinates of the ghost point as a mirror image of
641 // the center of gravity of the concerning boundary cell to the body surface
642 // compute the connection vector between the center of the gravity of the
643 // boundary cell and the center of the body surface
644 for(MInt i = 0; i < nDim; i++) {
645 connectionVctr[i] = m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i)
646 - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i];
647 }
648
649 // to compute the distance, project the connection vector into the normal
650 // vector by using a scalar product
651 distance = F0;
652 for(MInt i = 0; i < nDim; i++) {
653 distance += connectionVctr[i] * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
654 }
655 distance = fabs(distance);
656
657 // the ghost coordinates are found if the double distance is added to the
658 // center of gravity of the boundary cell in negative direction of the
659 // normal vector of the body surface
660 for(MInt i = 0; i < nDim; i++) {
661 m_solver->a_coordinate(ghostCellId, i) =
662 m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i)
663 - 2.0 * distance * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
664 }
665#else
666 // compute the ghost cell coordinates (new version)
667 for(MInt i = 0; i < nDim; i++) {
668 m_solver->a_coordinate(ghostCellId, i) = F2 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i]
669 - m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i);
670 }
671#endif
672
673 if(!m_cellMerging) {
674 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
675 const MFloat cellHalfLength = F1B2 * m_solver->c_cellLengthAtCell(cellId);
676 MFloat dn = F0;
677 for(MInt i = 0; i < nDim; i++) {
678 dn += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
679 * (m_solver->a_coordinate(cellId, i) - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i]);
680 }
681 for(MInt i = 0; i < nDim; i++) {
682 // m_solver->a_coordinate( ghostCellId , i ) = m_solver->a_coordinate( cellId , i ) - ( dn + cellHalfLength
683 // ) * m_bndryCells->a[ bndryId ].m_srfcs[srfc]->m_normalVector[ i ]; use mirrored coords if dn > dx/2:
684 m_solver->a_coordinate(ghostCellId, i) =
685 m_solver->a_coordinate(cellId, i)
686 - mMax(F2 * dn, dn + cellHalfLength) * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
687 }
688 }
689
690 m_solver->a_noReconstructionNeighbors(ghostCellId) = 0;
691 m_solver->a_level(ghostCellId) = m_solver->a_level(m_bndryCells->a[bndryId].m_cellId);
692
693 // grid-cell properties:
694 /* m_solver->c_globalId(ghostCellId) = -1;
695
696 // set all possible child ids of the newly created cell to -1
697 for( MInt ccId = 0; ccId < IPOW2(nDim); ccId++)
698 m_solver->c_childId( ghostCellId , ccId ) = -1;
699
700 m_solver->c_parentId(ghostCellId) = -1;
701 */
702 // set pointer to cellId
703 m_solver->m_associatedInternalCells.push_back(m_bndryCells->a[bndryId].m_cellId);
704
705 // mark a ghost cell in m_bndryCellIds and the cell collector
706 m_solver->a_bndryId(ghostCellId) = -2;
707 m_solver->a_isBndryGhostCell(ghostCellId) = true;
708
709 ASSERT(m_solver->a_level(ghostCellId) == m_solver->a_level(m_solver->getAssociatedInternalCell(ghostCellId)), "");
710 }
711 }
712}
std::vector< MInt > m_associatedInternalCells
MBool a_isBndryGhostCell(const MInt cellId) const
Returns isBndryGhostCell of the cell cellId.
const MInt & getAssociatedInternalCell(const MInt &cellId) const
Returns the Id of the split cell, if cellId is a split child.
MFloat distance(const MFloat *a, const MFloat *b)
Definition: maiamath.h:249

◆ computeGhostCellsMGC()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeGhostCellsMGC

Works with multiple ghost cells for complex geometries. Ghost cells are located in normal direction to the surface from the surface centroids. Method also provides the image point locations. If necessary, the ghost and image points can be written in two separate .vtk files

Author
Claudia Guenther, April 2010

Definition at line 729 of file fvcartesianbndrycndxd.cpp.

729 {
730 TRACE();
731
732 MFloat dist = F0;
733 ofstream ofl;
734 ofstream ofl2;
735 if(m_outputIGPoints) {
736 const MChar* filename = "imagePoints_";
737 stringstream filename2;
738 filename2 << filename << domainId() << ".vtk";
739 ofl.open((filename2.str()).c_str(), ofstream::trunc);
740 const MChar* filename3 = "ghostPoints";
741 stringstream filename4;
742 filename4 << filename3 << domainId() << ".vtk";
743 ofl2.open((filename4.str()).c_str(), ofstream::trunc);
744 }
745
746 MInt noImagePoints = 0;
747 //---
748
751
752 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
753 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
754 // append a cell to the fv-cell-collectors
755 m_cells.append();
757
758 // initialize m_bndryCellIds
759 m_solver->a_bndryId(m_solver->a_noCells() - 1) = -2;
760
761 const MInt ghostCellId = m_solver->a_noCells() - 1;
762
763 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId = ghostCellId;
764
765
766 if(m_solver->a_hasProperty(m_bndryCells->a[bndryId].m_cellId, SolverCell::IsOnCurrentMGLevel)) {
767 // if(m_solver->a_hasProperty(m_bndryCells->a[ bndryId ].m_cellId, SolverCell::IsActive))
768 MInt gridcellId = m_bndryCells->a[bndryId].m_cellId;
769 if(m_solver->a_hasProperty(gridcellId, SolverCell::IsSplitClone)) {
770 gridcellId = m_solver->m_splitChildToSplitCell.find(gridcellId)->second;
771 }
772 if(m_solver->c_noChildren(gridcellId) == 0) noImagePoints++;
773 }
774
775 // compute geometric data of the ghost cell
776
777 // compute ImagePoint coordinates
778 dist = F0;
779 for(MInt i = 0; i < nDim; i++) {
780 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[i] =
781 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i];
782 m_solver->a_coordinate(ghostCellId, i) = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i];
783
784 dist += m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i]
785 * (m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i)
786 - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i]);
787 }
788 dist = fabs(dist);
789 if(m_surfaceGhostCell != 0) {
790 for(MInt i = 0; i < nDim; i++) {
791 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[i] +=
792 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] * dist;
793 }
794 } else {
795 for(MInt i = 0; i < nDim; i++) {
796 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[i] +=
797 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] * dist;
798 m_solver->a_coordinate(ghostCellId, i) -= m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] * dist;
799 }
800 }
801
802 // init Ghost cell properties
803 m_solver->a_noReconstructionNeighbors(ghostCellId) = 0;
804 m_solver->a_level(ghostCellId) = m_solver->a_level(m_bndryCells->a[bndryId].m_cellId);
805
806 // set pointer to cellId
807 m_solver->m_associatedInternalCells.push_back(m_bndryCells->a[bndryId].m_cellId);
808 m_solver->a_isBndryGhostCell(ghostCellId) = true;
809 }
810 }
811
812 // if required write out image and ghost points to a .vtk data file
813 if(m_outputIGPoints) {
814 if(ofl && ofl2) {
815 ofl.setf(ios::fixed);
816 ofl.precision(7);
817 ofl2.setf(ios::fixed);
818 ofl2.precision(7);
819
820 ofl << "# vtk DataFile Version 3.0" << endl
821 << "MAIAD imagePoints file" << endl
822 << "ASCII" << endl
823 << "DATASET POLYDATA" << endl
824 << "POINTS " << noImagePoints << " float" << endl;
825
826 ofl2 << "# vtk DataFile Version 3.0" << endl
827 << "MAIAD ghostPoints file" << endl
828 << "ASCII" << endl
829 << "DATASET POLYDATA" << endl
830 << "POINTS " << noImagePoints << " float" << endl;
831
832 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
833 if(!m_solver->a_hasProperty(m_bndryCells->a[bndryId].m_cellId, SolverCell::IsOnCurrentMGLevel)) continue;
834 // if(!m_solver->a_hasProperty(m_bndryCells->a[ bndryId ].m_cellId, SolverCell::IsActive))
835 // continue;
836 if(m_solver->c_noChildren(m_bndryCells->a[bndryId].m_cellId) > 0) continue;
837 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
838 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
839 for(MInt i = 0; i < 3; i++) {
840 ofl << m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[i] << " ";
841 ofl2 << m_solver->a_coordinate(ghostCellId, i) << " ";
842 }
843 ofl << endl;
844 ofl2 << endl;
845 }
846 }
847
848 ofl << "VERTICES " << noImagePoints << " " << noImagePoints * 2 << endl;
849 ofl2 << "VERTICES " << noImagePoints << " " << noImagePoints * 2 << endl;
850 for(MInt i = 0; i < noImagePoints; i++) {
851 ofl << "1 " << i << endl;
852 ofl2 << "1 " << i << endl;
853 }
854 }
855
856 ofl.close();
857 ofl2.close();
858 }
859}
char MChar
Definition: maiatypes.h:56
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
Definition: pointbox.h:54

◆ computeImagePointRecConst()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeImagePointRecConst ( MInt  updateOnlyBndryCndId = -1)
Author
Lennart Schneiders

Definition at line 9293 of file fvcartesianbndrycndxd.cpp.

9293 {
9294 TRACE();
9295
9296 const MInt minRecDim = nDim + 1;
9297 // const MInt medRecDim = m_secondOrderRec ? 2*nDim + 1 : minRecDim;
9298 const MInt maxRecDim = m_secondOrderRec ? (IPOW2(nDim) + 2) : minRecDim;
9299 const MInt noBndryCells = m_bndryCells->size();
9300 const MInt maxNoSrfcs = 14;
9302 mTerm(1, AT_, "Increase maxNoSrfcs. " + to_string(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces));
9303 }
9304 const MInt maxNoNghbrs = 200;
9305 const MInt noLayersStencil = m_noFluxRedistributionLayers;
9306 const MFloat condNumThreshold = 1e7;
9308 if(noDomains() > 1 && noLayersStencil > mMin(m_noFluxRedistributionLayers, m_solver->noHaloLayers())) {
9309 cerr << "Warning: noLayersStencil smaller than flux redistribution layers!" << endl;
9310 }
9311
9312 MIntScratchSpace layerId(maxNoNghbrs, AT_, "layerId");
9314 MFloatScratchSpace deltaXSurf(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, nDim, AT_, "deltaXSurf");
9315 MFloatScratchSpace imagePoint(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, nDim, AT_, "imagePoint");
9316 MFloatScratchSpace surfCoords(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, nDim, AT_, "surfCoords");
9317 MFloatScratchSpace deltaXSurfProj(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, nDim, AT_, "deltaXSurfProj");
9319 MFloatScratchSpace backup(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, maxRecDim, AT_, "backup");
9320 MFloatScratchSpace mat(maxNoNghbrs, maxRecDim, AT_, "mat_imagePoint");
9321 MFloatScratchSpace matInv(maxRecDim, maxNoNghbrs, AT_, "matInv");
9322 MFloatScratchSpace weights(maxNoNghbrs, AT_, "weights");
9323
9324 MFloat maxCondNum0 = F0;
9325 MFloat maxCondNum1 = F0;
9326 MFloat avgCondNum0 = F0;
9327 MFloat avgCondNum1 = F0;
9328 MFloat condCnt0 = F0;
9329 MFloat condCnt1 = F0;
9330
9331 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
9332 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
9333 const MInt noSrfcs = m_bndryCells->a[bndryId].m_noSrfcs;
9334 MInt gridcellId = cellId;
9335 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitClone)) {
9336 gridcellId = m_solver->m_splitChildToSplitCell.find(cellId)->second;
9337 }
9338
9339 // if( m_solver->a_isPeriodic( cellId ) ) continue;
9340 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
9341 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
9342 if(!m_solver->a_hasProperty(cellId, SolverCell::IsSplitChild) && m_solver->c_noChildren(gridcellId) > 0) continue;
9343 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
9344 if(m_bndryCell[bndryId].m_recNghbrIds.size() == 0) continue;
9345 MBool skip = false;
9346 if(updateOnlyBndryCndId > -1) {
9347 skip = true;
9348 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9349 if(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId == updateOnlyBndryCndId) skip = false;
9350 }
9351 }
9352 if(skip) continue;
9353
9354 const MFloat normalizationFactor =
9355 FPOW2(m_solver->a_level(cellId))
9356 / m_solver->c_cellLengthAtLevel(0); // scaling factor to reduce the condition number of the resulting eq. sys.
9357
9358 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9359 // const MInt ghostCellId = m_bndryCells->a[ bndryId ].m_srfcVariables[srfc]->m_ghostCellId;
9360 // ASSERT( ghostCellId > -1, "" );
9361 deltaNSurf[srfc] = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
9362 for(MInt i = 0; i < nDim; i++) {
9363 // normal(srfc,i) = m_bndryCell[ bndryId ].m_srfcs[srfc]->m_normalVector[ i ];
9364 normal(srfc, i) = m_bndryCell[bndryId].m_srfcs[srfc]->m_normalVectorCentroid[i];
9365 }
9366 /*deltaNSurf[srfc] = F0;
9367 for ( MInt i = 0; i < nDim; i++ ) {
9368 normal(srfc,i) = m_bndryCell[ bndryId ].m_srfcs[srfc]->m_normalVector[ i ];
9369 deltaNSurf[srfc] += normal(srfc,i) * ( m_solver->a_coordinate( cellId , i ) - m_bndryCell[ bndryId
9370 ].m_srfcs[srfc]->m_coordinates[ i ] );
9371 }
9372 */
9373 }
9374
9375 MFloatScratchSpace dummyCoordinates(noSrfcs, nDim, AT_, "dummyCoordinates");
9376 MIntScratchSpace dummyLevel(noSrfcs, AT_, "dummyLevel");
9377 MFloatScratchSpace dummyCellVolume(noSrfcs, AT_, "dummyLevel");
9378 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9379 for(MInt i = 0; i < nDim; i++) {
9380 // deltaXSurf(srfc,i) = m_bndryCell[ bndryId ].m_srfcs[srfc]->m_coordinates[ i ] - m_solver->a_coordinate(
9381 // cellId , i );
9382 deltaXSurfProj(srfc, i) = -deltaNSurf[srfc] * normal(srfc, i);
9383 deltaXSurf(srfc, i) = deltaXSurfProj(srfc, i);
9384 // imagePoint(srfc,i) = m_solver->a_coordinate( cellId , i ) + ( F1B2 *
9385 // m_solver->c_cellLengthAtLevel(m_solver->a_level( cellId )) - deltaNSurf[srfc] ) * normal(srfc,i);
9386 // imagePoint(srfc,i) = m_solver->a_coordinate( cellId , i ) + mMax( F0, ( F1B2 *
9387 // m_solver->c_cellLengthAtLevel(m_solver->a_level( cellId )) - deltaNSurf[srfc] ) ) * normal(srfc,i); if
9388 // dn>dx/2 use cell coordinates, otherwise fixed wall distance of dx/2, i.e., the image point is never closer to
9389 // the surface than the corresponding cell:
9390 imagePoint(srfc, i) =
9391 m_solver->a_coordinate(cellId, i)
9392 + mMax(F0, (mMax(deltaNSurf[srfc], F1B2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId)))
9393 - deltaNSurf[srfc]))
9394 * normal(srfc, i);
9395 surfCoords(srfc, i) = m_solver->a_coordinate(cellId, i) - deltaNSurf[srfc] * normal(srfc, i);
9396 }
9397
9398 const MInt dummyId = m_bndryCell[bndryId].m_recNghbrIds[srfc]; // dummyIds(srfc);
9399 dummyLevel[srfc] = m_solver->a_level(cellId);
9400 dummyCellVolume(srfc) = m_solver->grid().gridCellVolume(m_solver->a_level(cellId));
9401 m_solver->a_bndryId(dummyId) = -1;
9402 for(MInt i = 0; i < nDim; i++) {
9403 dummyCoordinates(srfc, i) = m_solver->a_coordinate(cellId, i) + deltaXSurfProj(srfc, i);
9404 }
9405 }
9406
9407 const MInt recSize = m_bndryCell[bndryId].m_recNghbrIds.size();
9408 const MInt noNghbrIds = recSize;
9409 for(MInt k = 0; k < noNghbrIds; k++) {
9410 layerId(k) = (MInt)m_bndryCell[bndryId].m_cellVarsRecConst[k];
9411 if(k <= noSrfcs && layerId(k) != 0) {
9412 mTerm(1, AT_, "FvBndryCndXD<nDim, SysEqn>::computeImagePointRecConst: Inconsistency 0.");
9413 }
9414 if(k > noSrfcs && (layerId(k) < 1 || layerId(k) > noLayersStencil)) {
9415 mTerm(1, AT_, "FvBndryCndXD::computeImagePointRecConst: Inconsistency 0b.");
9416 }
9417 }
9418 m_bndryCell[bndryId].m_cellVarsRecConst.resize(0);
9419
9420 mat.fill(F0);
9421 weights.fill(F0);
9422
9423 // image point reconstruction constants
9424 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9425 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.resize(recSize);
9426 ASSERT(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size()
9427 == m_bndryCell[bndryId].m_recNghbrIds.size(),
9428 "");
9429 for(MInt k = 0; k < noNghbrIds; k++) {
9430 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[k];
9431 const MFloat* const nghbrCoord =
9432 (k < noSrfcs) ? &dummyCoordinates(k, 0) : &(m_solver->a_coordinate(nghbrId, 0));
9433 const MInt nghbrLevel = (k < noSrfcs) ? dummyLevel[k] : m_solver->a_level(nghbrId);
9434 const MFloat nghbrCellVolume = (k < noSrfcs) ? dummyCellVolume(k) : m_solver->a_cellVolume(nghbrId);
9435 mat(k, 0) = F1;
9436 MFloat dx = F0;
9437 for(MInt i = 0; i < nDim; i++) {
9438 mat(k, 1 + i) = (nghbrCoord[i] - imagePoint(srfc, i)) * normalizationFactor;
9439 dx += POW2(nghbrCoord[i] - imagePoint(srfc, i));
9440 }
9441 weights(k) = maia::math::RBF(dx, POW2(m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId))))
9442 * maia::math::deltaFun(nghbrCellVolume / m_solver->grid().gridCellVolume(nghbrLevel), 1e-6, 0.1);
9443 // weights(k) = maia::math::RBF( dx, POW2( m_solver->c_cellLengthAtLevel( m_solver->a_level( cellId ) ) ) );
9444 // //no additional weights (may be useful for fixed boundaries)
9445
9446 if(layerId(k) > 1) {
9447 weights(k) = F0; // stencil is required also on the first halo layer from which only one additional layer is
9448 }
9449 // accessible, otherwise three halo layers are required for unique results
9450 }
9451
9452 const MInt recDim = minRecDim;
9453 maia::math::invert(mat, weights, matInv, noNghbrIds, recDim);
9454 const MFloat condNum = maia::math::frobeniusMatrixNormSquared(mat, noNghbrIds, recDim);
9455 maxCondNum0 = mMax(maxCondNum0, condNum);
9456 avgCondNum0 += condNum;
9457 condCnt0 += F1;
9458 if(condNum < F0 || condNum > condNumThreshold) {
9459 cerr << "() Warning: Image-point SVD failed (" << condNum << ") cell " << cellId << " ("
9460 << m_solver->c_globalId(cellId) << ") "
9461 << ", " << recSize << "x" << nDim + 1 << " vfrac "
9462 << m_bndryCells->a[bndryId].m_volume / m_solver->grid().gridCellVolume(m_solver->a_level(cellId))
9463 << " at timestep " << globalTimeStep << endl;
9464 for(MInt k = 0; k < recSize; k++) {
9465 cerr << m_bndryCell[bndryId].m_recNghbrIds[k] << " ";
9466 }
9467 cerr << endl;
9468 for(MInt k = 0; k < recSize; k++) {
9469 cerr << weights(k) << " ";
9470 }
9471 cerr << endl;
9472 for(MInt k = 0; k < recSize; k++) {
9473 const MFloat nghbrCellVolume =
9474 (k < noSrfcs) ? dummyCellVolume(k) : m_solver->a_cellVolume(m_bndryCell[bndryId].m_recNghbrIds[k]);
9475 cerr << nghbrCellVolume << " ";
9476 }
9477 cerr << endl;
9478 // for ( MInt k = 0; k < recSize; k++ ) { cerr << layerId(k) << " "; } cerr << endl;
9479 // for ( MInt k = 0; k < recSize; k++ ) { cerr << m_solver->a_level( m_bndryCell[ bndryId ].m_recNghbrIds[k] )
9480 // << " "; } cerr << endl; for ( MInt k = 0; k < recSize; k++ ) { cerr << m_solver->a_hasProperty( m_bndryCell[
9481 // bndryId ].m_recNghbrIds[k] , SolverCell::IsOnCurrentMGLevel) << " "; } cerr << endl;
9482 }
9483 for(MInt k = 0; k < noNghbrIds; k++) {
9484 for(MInt i = 0; i < nDim; i++) {
9485 matInv(1 + i, k) *= normalizationFactor;
9486 }
9487 }
9488 for(MInt k = 0; k < noNghbrIds; k++) {
9489 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[k] = matInv(0, k);
9490 }
9491
9492 MFloat phiSum = m_bndryCells->a[bndryId].m_gapDistance;
9493
9494 const MFloat dx0 = F1B2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId));
9495 const MFloat dx1 = F2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId));
9496 const MFloat gapInd =
9497 F1 - mMax(F0, mMin(F1, (phiSum - dx0) / (dx1 - dx0))); // narrow gap indicator, reduce interpolation
9498 // order to increase stability
9499 if(gapInd > 1e-12) {
9500 for(MInt k = 0; k < noNghbrIds; k++) {
9501 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[k] *= (F1 - gapInd);
9502 }
9503 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[noSrfcs] += gapInd;
9504 }
9505 /*
9506 MBool reduceOrder = ( noSrfcs > 1 ) || ( phiSum < F2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId))) ;
9507 if ( reduceOrder ) { //|| m_bndryCell[ bndryId ].m_srfcs[srfc]->m_bndryCndId / 1000 != 3 ) {
9508 for ( MInt k = 0; k < noNghbrIds; k++ ) {
9509 m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_imagePointRecConst[k] = F0;
9510 }
9511 m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_imagePointRecConst[noSrfcs] = F1;
9512 } */
9513 }
9514 }
9515 if(firstRun || globalTimeStep % 100 == 0) {
9516 m_log << "Image point average (maximum) condition number: " << avgCondNum0 / condCnt0 << " (" << maxCondNum0
9517 << "), normal stress: " << avgCondNum1 / condCnt1 << " (" << maxCondNum1 << ")." << endl;
9518 }
9519
9520#ifndef NDEBUG
9521 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
9522 const MInt noSrfcs = m_bndryCells->a[bndryId].m_noSrfcs;
9523 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9524 if(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size()
9525 != m_bndryCell[bndryId].m_recNghbrIds.size()) {
9526 cerr << domainId() << ": " << bndryId << " " << srfc << " " << m_bndryCell[bndryId].m_recNghbrIds.size() << " "
9527 << m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size() << endl;
9528 mTerm(1, AT_, "FvBndryCndXD::computeImagePointRecConst: Inconsistency 1.");
9529 }
9530 }
9531 }
9532#endif
9533
9534 firstRun = false;
9535}
MBool m_static_computeImagePointRecConst_firstRun
MInt noHaloLayers() const
MFloat RBF(const MFloat R, const MFloat R0)
radial base function
Definition: maiamath.h:873
void invert(MFloat *A, const MInt m, const MInt n)
Definition: maiamath.cpp:171
MFloat frobeniusMatrixNormSquared(MFloatScratchSpace &m, MInt dim1, MInt dim2)
Definition: maiamath.h:328
MFloat deltaFun(const MFloat r, const MFloat r0, const MFloat r1)
Definition: maiamath.h:885

◆ computeMirrorCoordinates() [1/2]

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeMirrorCoordinates ( MInt  bndryId,
MFloat x 
)

Definition at line 908 of file fvcartesianbndrycndxd.cpp.

908 {
909 // TRACE();
910
911 MFloat distance = 0;
912 //---
913
914 for(MInt i = 0; i < nDim; i++) {
915 x[i] = m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i)
916 - m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[i];
917 }
918
919 for(MInt i = 0; i < nDim; i++) {
920 distance += x[i] * m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i];
921 }
922 distance = fabs(distance);
923 for(MInt i = 0; i < nDim; i++) {
924 x[i] = m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i)
925 - F2 * distance * m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i];
926 }
927}

◆ computeMirrorCoordinates() [2/2]

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeMirrorCoordinates ( MInt  bndryId,
MFloat x,
MInt  srfcId 
)

Definition at line 933 of file fvcartesianbndrycndxd.cpp.

933 {
934 // TRACE();
935
936 MFloat distance = 0;
937 //---
938
939 for(MInt i = 0; i < nDim; i++) {
940 x[i] = m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i)
941 - m_bndryCells->a[bndryId].m_srfcs[srfcId]->m_coordinates[i];
942 }
943
944 for(MInt i = 0; i < nDim; i++) {
945 distance += x[i] * m_bndryCells->a[bndryId].m_srfcs[srfcId]->m_normalVector[i];
946 }
947 distance = fabs(distance);
948 for(MInt i = 0; i < nDim; i++) {
949 x[i] = m_solver->a_coordinate(m_bndryCells->a[bndryId].m_cellId, i)
950 - F2 * distance * m_bndryCells->a[bndryId].m_srfcs[srfcId]->m_normalVector[i];
951 }
952}

◆ computeNeumannLSConstants()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeNeumannLSConstants ( MInt  bcId)

Information is stored on the reconstructionData of the respective boundary cell

Author
Daniel Hartmann

Definition at line 12867 of file fvcartesianbndrycndxd.cpp.

12867 {
12868 TRACE();
12869
12870 const MInt noSmallCells = m_smallBndryCells->size();
12871 MInt bndryId;
12872 MInt nghbrId;
12873 MInt cellId;
12874 MInt noNghbrIds;
12875 MInt id;
12876 MInt noUnknowns = nDim;
12877 MFloatScratchSpace x_scratch(nDim, AT_, "x_scratch");
12878 MFloat* x = x_scratch.getPointer();
12879 MBool bcCell = false;
12880 //---
12881
12882 // cell-center reconstruction
12883 for(MInt bc = m_bndryCndCells[bcId]; bc < m_bndryCndCells[bcId + 1]; bc++) {
12884 bndryId = m_sortedBndryCells->a[bc];
12885 cellId = m_bndryCells->a[bndryId].m_cellId;
12886 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
12887 continue;
12888 }
12889 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) {
12890 continue;
12891 }
12892 if(m_bndryCells->a[bndryId].m_linkedCellId > -1) {
12893 continue;
12894 }
12895 if(m_solver->c_noChildren(cellId) > 0) {
12896 continue;
12897 }
12898
12899 noNghbrIds = m_solver->a_noReconstructionNeighbors(cellId);
12900
12901 // loop over least-squares cell cluster
12902 for(MInt cell = 0; cell < noNghbrIds; cell++) {
12903 id = m_solver->a_reconstructionNeighborId(cellId, cell);
12904 if(!m_solver->a_isBndryGhostCell(id)) {
12905 for(MInt i = 0; i < nDim; i++) {
12906 x[i] = m_solver->a_coordinate(id, i);
12907 }
12908 } else {
12910 }
12911
12912 for(MInt i = 0; i < nDim; i++) {
12913 m_solver->m_A[cell][i] = x[i] - m_solver->a_coordinate(cellId, i);
12914 }
12915 // additional terms for a higher-order reconstruction
12917 for(MInt i = 0; i < nDim; i++) {
12918 m_solver->m_A[cell][nDim + i] = POW2(x[i] - m_solver->a_coordinate(cellId, i));
12919 }
12920 m_solver->m_A[cell][2 * nDim + 1] =
12921 (x[0] - m_solver->a_coordinate(cellId, 0)) * (x[1] - m_solver->a_coordinate(cellId, 1));
12922 m_solver->m_A[cell][2 * nDim + 2] =
12923 (x[0] - m_solver->a_coordinate(cellId, 0)) * (x[2] - m_solver->a_coordinate(cellId, 2));
12924 m_solver->m_A[cell][2 * nDim + 3] =
12925 (x[1] - m_solver->a_coordinate(cellId, 1)) * (x[2] - m_solver->a_coordinate(cellId, 2));
12926 }
12927 }
12928
12929 // compute ATA
12930 for(MInt i = 0; i < noUnknowns; i++) {
12931 for(MInt j = 0; j < noUnknowns; j++) {
12932 m_solver->m_ATA[i][j] = F0;
12933 for(MInt k = 0; k < noNghbrIds; k++) {
12934 m_solver->m_ATA[i][j] += m_solver->m_A[k][i] * m_solver->m_A[k][j];
12935 }
12936 }
12937 }
12938
12939 // invert ATA
12940 const MFloat epsilon = POW3(m_solver->c_cellLengthAtLevel(m_solver->maxRefinementLevel()) / (1000.0));
12941 maia::math::inverse(m_solver->m_ATA, m_solver->m_ATAi, noUnknowns, epsilon);
12942
12943 // compute (ATA)^(-1) * AT
12944 for(MInt i = 0; i < noUnknowns; i++) {
12945 for(MInt j = 0; j < noNghbrIds; j++) {
12946 m_solver->m_ATA[i][j] = F0;
12947 for(MInt k = 0; k < noUnknowns; k++) {
12948 m_solver->m_ATA[i][j] += m_solver->m_ATAi[i][k] * m_solver->m_A[j][k];
12949 }
12950 }
12951 }
12952
12953 // loop over least-squares cell cluster
12954 for(MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
12955 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
12956
12957 // compute the constants
12958 if(!m_solver->a_isBndryGhostCell(nghbrId)) {
12959 for(MInt i = 0; i < nDim; i++) {
12960 m_reconstructionConstants[bndryId][nDim * nghbr + i] = m_solver->m_ATA[i][nghbr];
12961 }
12962 } else {
12963 for(MInt i = 0; i < nDim; i++) {
12964 m_reconstructionConstants[bndryId][nDim * nghbr + i] = F0;
12965 }
12966 }
12967 }
12968 }
12969
12970 // loop over all slave cells with internal master
12971 for(MInt sid = 0; sid < noSmallCells; sid++) {
12972 bcCell = false;
12973 bndryId = m_smallBndryCells->a[sid];
12974 cellId = m_bndryCells->a[bndryId].m_linkedCellId;
12975 // check, if cell is indeed a boundary cell with bc bcId:
12976 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
12977 // only compute reconstruction constants for the cells with the respective boundary condition
12978 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
12979 bcCell = true;
12980 break;
12981 }
12982 }
12983 if(!bcCell) {
12984 continue;
12985 }
12986 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
12987 continue;
12988 }
12989 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) {
12990 continue;
12991 }
12992 if(m_solver->a_bndryId(cellId) > -1) {
12993 continue;
12994 }
12995
12996 // take all neighbors of the master cell
12997 noNghbrIds = m_solver->a_noReconstructionNeighbors(cellId);
12998
12999 // loop over least-squares cell cluster
13000 for(MInt cell = 0; cell < noNghbrIds; cell++) {
13001 id = m_solver->a_reconstructionNeighborId(cellId, cell);
13002 if(!m_solver->a_isBndryGhostCell(id)) {
13003 for(MInt i = 0; i < nDim; i++) {
13004 x[i] = m_solver->a_coordinate(id, i);
13005 }
13006 } else {
13008 }
13009
13010 for(MInt i = 0; i < nDim; i++) {
13011 m_solver->m_A[cell][i] = x[i] - m_solver->a_coordinate(cellId, i);
13012 }
13013 // additional terms for a higher-order reconstruction
13015 for(MInt i = 0; i < nDim; i++) {
13016 m_solver->m_A[cell][nDim + i] = POW2(x[i] - m_solver->a_coordinate(cellId, i));
13017 }
13018 m_solver->m_A[cell][2 * nDim + 1] =
13019 (x[0] - m_solver->a_coordinate(cellId, 0)) * (x[1] - m_solver->a_coordinate(cellId, 1));
13020 m_solver->m_A[cell][2 * nDim + 2] =
13021 (x[0] - m_solver->a_coordinate(cellId, 0)) * (x[2] - m_solver->a_coordinate(cellId, 2));
13022 m_solver->m_A[cell][2 * nDim + 3] =
13023 (x[1] - m_solver->a_coordinate(cellId, 1)) * (x[2] - m_solver->a_coordinate(cellId, 2));
13024 }
13025 }
13026
13027 // compute ATA
13028 for(MInt i = 0; i < noUnknowns; i++) {
13029 for(MInt j = 0; j < noUnknowns; j++) {
13030 m_solver->m_ATA[i][j] = F0;
13031 for(MInt k = 0; k < noNghbrIds; k++) {
13032 m_solver->m_ATA[i][j] += m_solver->m_A[k][i] * m_solver->m_A[k][j];
13033 }
13034 }
13035 }
13036
13037 // invert ATA
13038 const MFloat epsilon = POW3(m_solver->c_cellLengthAtLevel(m_solver->maxRefinementLevel()) / (1000.0));
13039 maia::math::inverse(m_solver->m_ATA, m_solver->m_ATAi, noUnknowns, epsilon);
13040
13041 // compute (ATA)^(-1) * AT
13042 for(MInt i = 0; i < noUnknowns; i++) {
13043 for(MInt j = 0; j < noNghbrIds; j++) {
13044 m_solver->m_ATA[i][j] = F0;
13045 for(MInt k = 0; k < noUnknowns; k++) {
13046 m_solver->m_ATA[i][j] += m_solver->m_ATAi[i][k] * m_solver->m_A[j][k];
13047 }
13048 }
13049 }
13050
13051 // loop over least-squares cell cluster
13052 for(MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
13053 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13054
13055 // compute the constants
13056 if(!m_solver->a_isBndryGhostCell(nghbrId)) {
13057 for(MInt i = 0; i < nDim; i++) {
13058 m_reconstructionConstants[bndryId][nDim * nghbr + i] = m_solver->m_ATA[i][nghbr];
13059 }
13060 } else {
13061 for(MInt i = 0; i < nDim; i++) {
13062 m_reconstructionConstants[bndryId][nDim * nghbr + i] = F0;
13063 }
13064 }
13065 }
13066 }
13067}
void computeMirrorCoordinates(MInt, MFloat *, MInt)
MInt size()
Definition: list.h:20
constexpr Real POW3(const Real x)
Definition: functions.h:123
MInt inverse(MFloat **a, MFloat **ainv, MInt n, const MFloat epsilon)
Definition: maiamath.h:587

◆ computePlaneVectors()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computePlaneVectors

plane vectors are computed for all cut surfaces of a boundary cell

Author
Daniel Hartmann, modified by Claudia Guenther, Mai 2009

Definition at line 12599 of file fvcartesianbndrycndxd.cpp.

12599 {
12600 TRACE();
12601
12602
12603 const MInt noCells = m_bndryCells->size();
12604 for(MInt id = 0; id < noCells; id++) {
12605 for(MInt srfc = 0; srfc < m_bndryCells->a[id].m_noSrfcs; srfc++) {
12606 const MInt cellId = m_bndryCells->a[id].m_cellId;
12608 if(m_solver->c_noChildren(cellId) > 0 || (!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))) {
12609 continue;
12610 }
12611 }
12612 MFloat testVector0[nDim]{};
12613 MInt component[nDim - 1]{};
12614
12615
12616 if(fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[0])
12617 < fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[1])) {
12618 IF_CONSTEXPR(nDim == 3) {
12619 if(fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[0])
12620 < fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[2])) {
12621 component[0] = 0;
12622 if(fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[1])
12623 < fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[2])) {
12624 component[1] = 1;
12625 } else {
12626 component[1] = 2;
12627 }
12628 } else {
12629 component[0] = 2;
12630 component[1] = 0;
12631 }
12632 }
12633 else IF_CONSTEXPR(nDim == 2) {
12634 component[0] = 0;
12635 }
12636 } else
12637 IF_CONSTEXPR(nDim == 3) {
12638 if(fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[1])
12639 < fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[2])) {
12640 component[0] = 1;
12641 if(fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[0])
12642 < fabs(m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[2])) {
12643 component[1] = 0;
12644 } else {
12645 component[1] = 2;
12646 }
12647 } else {
12648 component[0] = 2;
12649 component[1] = 1;
12650 }
12651 }
12652 else IF_CONSTEXPR(nDim == 2) {
12653 component[0] = 1;
12654 }
12655
12656 testVector0[component[0]] = F1;
12657
12658 // (i) first vector
12659 // scalar product of test vector and normal vector
12660 MFloat sp[nDim - 1]{};
12661 for(MInt i = 0; i < nDim; i++) {
12662 sp[0] += testVector0[i] * m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[i];
12663 }
12664 // 1st orthogonal vector
12665 for(MInt i = 0; i < nDim; i++) {
12666 m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[i] =
12667 testVector0[i] - sp[0] * m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[i];
12668 }
12669 // normalize (use sp[0])
12670 sp[0] = F0;
12671 for(MInt i = 0; i < nDim; i++) {
12672 sp[0] += POW2(m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[i]);
12673 }
12674 sp[0] = F1 / sqrt(sp[0]);
12675 for(MInt i = 0; i < nDim; i++) {
12676 m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[i] *= sp[0];
12677 }
12678 IF_CONSTEXPR(nDim == 3) {
12679 // (ii) second vector
12680 MFloat testVector1[nDim]{};
12681 testVector1[component[1]] = F1;
12682 // scalar product of test vector and normal vector
12683 sp[0] = F0;
12684 for(MInt i = 0; i < nDim; i++) {
12685 sp[0] += testVector1[i] * m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[i];
12686 }
12687 // scalar product of test vector and first plane vector
12688 sp[1] = F0;
12689 for(MInt i = 0; i < nDim; i++) {
12690 sp[1] += testVector1[i] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[i];
12691 }
12692 // 1st orthogonal vector
12693 for(MInt i = 0; i < nDim; i++) {
12694 m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[i] =
12695 testVector1[i] - sp[0] * m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[i]
12696 - sp[1] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[i];
12697 }
12698 // normalize (use sp[])
12699 sp[0] = F0;
12700 for(MInt i = 0; i < nDim; i++) {
12701 sp[0] += POW2(m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[i]);
12702 }
12703 sp[0] = F1 / sqrt(sp[0]);
12704 for(MInt i = 0; i < nDim; i++) {
12705 m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[i] *= sp[0];
12706 }
12707 }
12708
12709 MFloat normalVector[nDim];
12711 // compute the normal vector - already given by surface normal
12712 for(MInt i = 0; i < nDim; i++) {
12713 normalVector[i] = m_bndryCells->a[id].m_srfcs[srfc]->m_normalVector[i];
12714 }
12715 } else {
12716 const MInt ghostCellId = m_bndryCells->a[id].m_srfcVariables[srfc]->m_ghostCellId;
12717
12718 // compute the normal vector - unit vector in direction cellCenter->ghostCellCenter
12719 MFloat coordinates[nDim];
12720
12721 for(MInt i = 0; i < nDim; i++) {
12722 coordinates[i] = m_solver->a_coordinate(cellId, i) - m_solver->a_coordinate(ghostCellId, i);
12723 }
12724 MFloat FtotalDistance = F0;
12725 for(MInt i = 0; i < nDim; i++) {
12726 FtotalDistance += POW2(coordinates[i]);
12727 }
12728 FtotalDistance = F1 / sqrt(FtotalDistance);
12729 for(MInt i = 0; i < nDim; i++) {
12730 normalVector[i] = coordinates[i] * FtotalDistance;
12731 }
12732 }
12733
12734 // compute the Jacobian
12735 MFloat JacobianQuotient;
12736
12737 IF_CONSTEXPR(nDim == 2) {
12738 JacobianQuotient = normalVector[0] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[1]
12739 - normalVector[1] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[0];
12740 }
12741 else IF_CONSTEXPR(nDim == 3) {
12742 JacobianQuotient = normalVector[0] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[1]
12743 * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[2]
12744 + normalVector[1] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[2]
12745 * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[0]
12746 + normalVector[2] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[0]
12747 * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[1]
12748 - normalVector[0] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[2]
12749 * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[1]
12750 - normalVector[1] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[0]
12751 * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[2]
12752 - normalVector[2] * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector0[1]
12753 * m_bndryCells->a[id].m_srfcs[srfc]->m_planeVector1[0];
12754 }
12755 m_bndryCells->a[id].m_srfcs[srfc]->m_FJacobian = F1 / JacobianQuotient;
12756 }
12757 }
12758}

◆ computePoly3()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computePoly3 ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computePoly4()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computePoly4 ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computePoly5()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computePoly5 ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computePoly6()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computePoly6 ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computePolygon()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computePolygon ( MFloat x,
const MInt  N,
MFloat centroid,
MFloat area 
)

◆ computePyra()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computePyra ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computeReconstructionConstants_interpolation()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeReconstructionConstants_interpolation ( )

◆ computeReverseMap()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::computeReverseMap
Author
Daniel Hartmann
Date
May 2008

Definition at line 606 of file fvcartesianbndrycndxd.cpp.

606 {
607 TRACE();
608
609 // initialize all cells as internal cells
610 for(MInt id = 0; id < m_solver->a_noCells(); id++) {
611 m_solver->a_bndryId(id) = -1;
612 }
613
614 // correct the entries of boundary cells
615 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
616 m_solver->a_bndryId(m_bndryCells->a[bndryId].m_cellId) = bndryId;
617 }
618}

◆ computeTetra()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computeTetra ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computeTrapez()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computeTrapez ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computeTri() [1/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computeTri ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ computeTri() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::computeTri ( MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ copyRHSIntoGhostCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::copyRHSIntoGhostCells

Definition at line 5771 of file fvcartesianbndrycndxd.cpp.

5771 {
5772 TRACE();
5773
5774 MInt noCells = m_bndryCells->size();
5775
5776 for(MInt id = 0; id < noCells; id++) {
5777 for(MInt srfc = 0; srfc < m_bndryCells->a[id].m_noSrfcs; srfc++) {
5778 MInt ghostCellId = m_bndryCells->a[id].m_srfcVariables[srfc]->m_ghostCellId;
5779 MInt cellId = m_bndryCells->a[id].m_cellId;
5780 for(MInt i = 0; i < FV->noVariables; i++) {
5781 m_solver->a_rightHandSide(ghostCellId, i) = m_solver->a_rightHandSide(cellId, i);
5782 }
5783 }
5784 }
5785}
SysEqn::FluxVariables * FV

◆ correctBoundarySurfaceVariablesMGC()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::correctBoundarySurfaceVariablesMGC

values are set to ghost cell and image value, respectively (in comment: values are set to the arithmetic mean of ghost cell and image value)

version is able to work with multiple ghost cells. Used if ghost cells are located normal to boundary surface from surface centroid and ghost cells are not positioned directly on the surface.

Author
Claudia Guenther, Mai 2010

Definition at line 1171 of file fvcartesianbndrycndxd.cpp.

1171 {
1172 TRACE();
1173
1174 const MInt noBndrySurfaces = m_noBoundarySurfaces;
1175 const MInt noVars = CV->noVariables;
1176 const MInt surfaceVarMemory = m_solver->m_surfaceVarMemory;
1177 MFloat* surfaceVar = (MFloat*)(&(m_solver->a_surfaceVariable(0, 0, 0)));
1178 MInt nghbr0, nghbr1, bndryId, ghostSurf;
1179 //---
1180
1181#ifdef _OPENMP
1182#pragma omp parallel for
1183#endif
1184 for(MInt bs = 0; bs < noBndrySurfaces; bs++) {
1187 if(m_solver->a_isBndryGhostCell(nghbr0)) {
1189 ghostSurf = 0;
1190 for(MInt srfcId = 0; srfcId < m_bndryCells->a[bndryId].m_noSrfcs; srfcId++) {
1191 if(m_bndryCells->a[bndryId].m_srfcVariables[srfcId]->m_ghostCellId == nghbr0) {
1192 ghostSurf = srfcId;
1193 break;
1194 }
1195 }
1196 // set left an right value to ghost cell value and image value, respectively
1197 // for( MInt var = 0; var < noVars; var++ ) {
1198 // surfaceVar[ m_boundarySurfaces[bs]*surfaceVarMemory + var ] =
1199 // m_solver->a_pvariable( nghbr0 , var );
1200 // surfaceVar[ m_boundarySurfaces[bs]*surfaceVarMemory + noVars + var ] =
1201 // m_bndryCells->a[bndryId].m_srfcVariables[ghostSurf]->m_imageVariables[var];
1202 // }
1203 // set both left and right value to mean of ghost cell value and image value
1204 for(MInt var = 0; var < noVars; var++) {
1205 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + var] =
1206 F1B2
1207 * (m_solver->a_pvariable(nghbr0, var)
1208 + m_bndryCells->a[bndryId].m_srfcVariables[ghostSurf]->m_imageVariables[var]);
1209 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + noVars + var] =
1210 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + var];
1211 }
1212 } else if(m_solver->a_isBndryGhostCell(nghbr1)) {
1214 ghostSurf = 0;
1215 for(MInt srfcId = 0; srfcId < m_bndryCells->a[bndryId].m_noSrfcs; srfcId++) {
1216 if(m_bndryCells->a[bndryId].m_srfcVariables[srfcId]->m_ghostCellId == nghbr1) {
1217 ghostSurf = srfcId;
1218 break;
1219 }
1220 }
1221 // set right an left value to ghost cell value and image value, respectively
1222 // for( MInt var = 0; var < noVars; var++ ) {
1223 // surfaceVar[ m_boundarySurfaces[bs]*surfaceVarMemory + var ] =
1224 // m_solver->a_pvariable( nghbr1 , var );
1225 // surfaceVar[ m_boundarySurfaces[bs]*surfaceVarMemory + noVars + var ] =
1226 // m_bndryCells->a[bndryId].m_srfcVariables[ghostSurf]->m_imageVariables[var];
1227 // }
1228 // set both left and right value to mean of ghost cell value and image value
1229 for(MInt var = 0; var < noVars; var++) {
1230 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + var] =
1231 F1B2
1232 * (m_solver->a_pvariable(nghbr1, var)
1233 + m_bndryCells->a[bndryId].m_srfcVariables[ghostSurf]->m_imageVariables[var]);
1234 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + noVars + var] =
1235 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + var];
1236 }
1237 } else
1238 cerr << "[ " << domainId() << " ]"
1239 << " Error in FvBndryCndXD::correctBoundarySurfaceVariablesMGC; This case should not occur! "
1240 << " surface " << m_boundarySurfaces[bs] << " has no ghost cell neighbor! "
1241 << "neighbors: " << nghbr0 << " " << nghbr1 << endl;
1242 }
1243}
MFloat & a_surfaceVariable(const MInt srfcId, const MInt dir, const MInt varId)
Returns the variable varId of surface srfcId in direction dir.

◆ correctBoundarySurfaceVariablesMGCSurface()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::correctBoundarySurfaceVariablesMGCSurface

values are set equal to the ghost cell value

version is able to work with multiple ghost cells. Used if ghost cells are located normal to boundary surface from surface centroid and ghost cells are positioned directly on the surface.

Author
Claudia Guenther, Mai 2010

Definition at line 1258 of file fvcartesianbndrycndxd.cpp.

1258 {
1259 TRACE();
1260
1261 const MInt noBndrySurfaces = m_noBoundarySurfaces;
1262 const MInt noVars = CV->noVariables;
1263 const MInt surfaceVarMemory = m_solver->m_surfaceVarMemory;
1264 MFloat* surfaceVar = (MFloat*)(&(m_solver->a_surfaceVariable(0, 0, 0)));
1265 MInt nghbr0, nghbr1;
1266 //---
1267
1268#ifdef _OPENMP
1269#pragma omp parallel for
1270#endif
1271 for(MInt bs = 0; bs < noBndrySurfaces; bs++) {
1274 if(m_solver->a_isBndryGhostCell(nghbr0)) {
1275 for(MInt var = 0; var < noVars; var++) {
1276 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + var] = m_solver->a_pvariable(nghbr0, var);
1277 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + noVars + var] = m_solver->a_pvariable(nghbr0, var);
1278 }
1279 } else if(m_solver->a_isBndryGhostCell(nghbr1)) {
1280 for(MInt var = 0; var < noVars; var++) {
1281 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + var] = m_solver->a_pvariable(nghbr1, var);
1282 surfaceVar[m_boundarySurfaces[bs] * surfaceVarMemory + noVars + var] = m_solver->a_pvariable(nghbr1, var);
1283 }
1284 } else
1285 cerr << "[ " << domainId() << " ]"
1286 << " Error in FvBndryCndXD::correctBoundarySurfaceVariablesMGCSurface; This case should not occur! "
1287 << " surface " << m_boundarySurfaces[bs] << " has no ghost cell neighbor! "
1288 << "neighbors: " << nghbr0 << " " << nghbr1 << endl;
1289 }
1290}

◆ correctCell()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::correctCell ( MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ correctCellCoordinates()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::correctCellCoordinates

Definition at line 517 of file fvcartesianbndrycndxd.cpp.

517 {
518 TRACE();
519
520 MInt noCells = m_bndryCells->size();
521 //---
522
523 for(MInt id = 0; id < noCells; id++) {
524 for(MInt i = 0; i < nDim; i++) {
525 m_solver->a_coordinate(m_bndryCells->a[id].m_cellId, i) += m_bndryCells->a[id].m_coordinates[i];
526 }
527 }
528 ASSERT(!m_cellCoordinatesCorrected, "Irregular sequence of cell-coordinate correction!");
530}

◆ correctCoarseBndryCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::correctCoarseBndryCells

corrects the volume and the center of gravity of the boundary cells using fine cell information creates body surfaces using fine cell information does not work correctly with multipleGhostCell formulation (claudia)!

it is required that small and master cells are not yet merged!!! NOTE: not doing anything in the new multi-level as multi-solver approach!

Author
Daniel Hartmann, March 10, 2006

Definition at line 8908 of file fvcartesianbndrycndxd.cpp.

8908 {
8909 TRACE();
8910
8911 MInt cellId;
8912 MInt noChildren;
8913 MInt childCellId;
8914 MInt noCells = m_bndryCells->size();
8915 MFloat bndryCellVolumes;
8916 MFloat childVolume;
8917 MFloat volume;
8918 MFloatScratchSpace bndryXyz_scratch(nDim, AT_, "bndryXyz_scratch");
8919 MFloat* bndryXyz = bndryXyz_scratch.getPointer();
8920 MFloatScratchSpace cellXyz_scratch(nDim, AT_, "cellXyz_scratch");
8921 MFloat* cellXyz = cellXyz_scratch.getPointer();
8922 MFloatScratchSpace srfcXyz_scratch(nDim, AT_, "srfcXyz_scratch");
8923 MFloat* srfcXyz = srfcXyz_scratch.getPointer();
8924 MFloat srfcArea;
8925
8926 // ------------- end of initialization --------------
8927
8928 // loop over all levels
8929 for(MInt level = m_solver->maxRefinementLevel() - 1; level > 0; level--) {
8930 // loop over all boundary cells
8931 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
8932 // choose only those boundary cells at the current level
8933 cellId = m_bndryCells->a[bndryId].m_cellId;
8934 if(m_solver->a_level(cellId) == level) {
8935 noChildren = m_solver->c_noChildren(cellId);
8936
8937 if(noChildren > 0) {
8938 // reset temp. variables
8939 volume = 0;
8940 bndryCellVolumes = 0;
8941 srfcArea = 0;
8942 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8943 bndryXyz[spaceId] = 0;
8944 cellXyz[spaceId] = 0;
8945 srfcXyz[spaceId] = 0;
8946 }
8947
8948 // -------- average children cell coordinates and volumes ---------
8949 for(MInt childId = 0; childId < IPOW2(nDim); childId++) {
8950 if(m_solver->c_childId(cellId, childId) == -1) continue;
8951
8952 childCellId = m_solver->c_childId(cellId, childId);
8953
8954 if(m_solver->a_bndryId(childCellId) > -1) {
8955 volume += m_bndryCells->a[m_solver->a_bndryId(childCellId)].m_volume;
8956 bndryCellVolumes += m_bndryCells->a[m_solver->a_bndryId(childCellId)].m_volume;
8957
8958 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8959 bndryXyz[spaceId] += m_solver->a_coordinate(childCellId, spaceId)
8960 * m_bndryCells->a[m_solver->a_bndryId(childCellId)].m_volume;
8961 }
8962
8963 // average body surface of children
8964 srfcArea += m_bndryCells->a[m_solver->a_bndryId(childCellId)].m_srfcs[0]->m_area;
8965 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8966 srfcXyz[spaceId] += m_bndryCells->a[m_solver->a_bndryId(childCellId)].m_srfcs[0]->m_coordinates[spaceId]
8967 * m_bndryCells->a[m_solver->a_bndryId(childCellId)].m_srfcs[0]->m_area;
8968 }
8969
8970 } else {
8971 childVolume = m_solver->c_cellLengthAtCell(childCellId);
8972 for(MInt spaceId = 1; spaceId < nDim; spaceId++) {
8973 childVolume *= m_solver->c_cellLengthAtCell(childCellId);
8974 }
8975 volume += childVolume;
8976 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8977 cellXyz[spaceId] += m_solver->a_coordinate(childCellId, spaceId) * childVolume;
8978 }
8979 }
8980 }
8981
8982 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8983 cellXyz[spaceId] += bndryXyz[spaceId];
8984 cellXyz[spaceId] = cellXyz[spaceId] / volume;
8985 bndryXyz[spaceId] = bndryXyz[spaceId] / bndryCellVolumes;
8986 srfcXyz[spaceId] = srfcXyz[spaceId] / srfcArea;
8987 }
8988
8989 // ----------------------------------------------------------------
8990
8991 // correct the coordinate shift of the boundary cell
8992 // set the coordinates of the boundary cell
8993 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8994 m_bndryCells->a[bndryId].m_coordinates[spaceId] +=
8995 cellXyz[spaceId] - m_solver->a_coordinate(cellId, spaceId);
8996 m_solver->a_coordinate(cellId, spaceId) = cellXyz[spaceId];
8997 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[spaceId] = srfcXyz[spaceId];
8998 }
8999
9000 // update coarse cell volume
9001 m_bndryCells->a[bndryId].m_volume = volume;
9002 }
9003 }
9004 }
9005 }
9006}

◆ correctFace()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::correctFace ( MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ correctGhostCellSlopesViscous()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::correctGhostCellSlopesViscous

Definition at line 2145 of file fvcartesianbndrycndxd.cpp.

2145 {
2146 TRACE();
2147
2148 const MInt noBndryCells = m_bndryCells->size();
2149 const MInt noPVars = PV->noVariables;
2150
2151#ifdef _OPENMP
2152#pragma omp parallel for
2153#endif
2154 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
2155 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
2156 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
2157 continue;
2158 }
2159 if(m_solver->a_isHalo(cellId)) {
2160 continue;
2161 }
2162 if(m_bndryCell[bndryId].m_recNghbrIds.size() == 0) {
2163 continue;
2164 }
2165 if(m_solver->a_hasProperty(cellId, SolverCell::IsCutOff)) {
2166 continue;
2167 }
2168
2169 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
2170 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
2171 MFloat normal[3] = {F0, F0, F0};
2172 for(MInt i = 0; i < nDim; i++) {
2173 normal[i] = m_bndryCell[bndryId].m_srfcs[srfc]->m_normalVectorCentroid[i];
2174 }
2175 MFloat dng = F0;
2176 for(MInt i = 0; i < nDim; i++) {
2177 dng += (m_solver->a_coordinate(cellId, i) - m_solver->a_coordinate(ghostCellId, i)) * normal[i];
2178 }
2179 dng -= m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
2180
2181 for(MInt v = 0; v < noPVars; v++) {
2182 switch(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v]) {
2183 case BC_DIRICHLET:
2184 // case BC_ISOTHERMAL:
2185 case BC_UNSET:
2186 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v] =
2187 (m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v] - m_solver->a_pvariable(ghostCellId, v))
2188 / dng;
2189 // m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_normalDeriv[v] = ( m_solver->a_pvariable( cellId , v) -
2190 // m_solver->a_pvariable( ghostCellId , v) ) / dng;
2191 for(MInt i = 0; i < nDim; i++) {
2192 m_solver->a_slope(ghostCellId, v, i) =
2193 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v] * normal[i];
2194 // m_solver->a_slope( ghostCellId , v, i) = m_solver->a_slope( cellId , v, i); //use this if local density
2195 // peaks/drops occur
2196 }
2197 break;
2198
2199 case BC_NEUMANN:
2200 case BC_ISOTHERMAL:
2201 for(MInt i = 0; i < nDim; i++) {
2202 m_solver->a_slope(ghostCellId, v, i) =
2203 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v] * normal[i];
2204 }
2205 break;
2206
2207 case BC_ROBIN:
2208 for(MInt i = 0; i < nDim; i++) {
2209 m_solver->a_slope(ghostCellId, v, i) =
2210 normal[i]
2211 * (m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v]
2212 - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_robinFactor
2213 * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v]);
2214 }
2215 break;
2216
2217 default: {
2218 stringstream errorMessage;
2219 errorMessage << "ERROR: Invalid BC type with value = "
2220 << m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] << ", variable number" << v
2221 << ", at bc = " << m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId;
2222 mTerm(1, AT_, errorMessage.str());
2223 }
2224 }
2225
2226 for(MInt i = 0; i < nDim; i++) {
2227 m_solver->a_slope(ghostCellId, v, i) =
2228 2.0 * m_solver->a_slope(ghostCellId, v, i) - m_solver->a_slope(cellId, v, i);
2229 }
2230 }
2231 }
2232 }
2233}
@ BC_ROBIN
Definition: enums.h:334
@ BC_UNSET
Definition: enums.h:334
@ BC_NEUMANN
Definition: enums.h:334
@ BC_ISOTHERMAL
Definition: enums.h:334
@ BC_DIRICHLET
Definition: enums.h:334

◆ correctInflowBoundary() [1/4]

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

◆ correctInflowBoundary() [2/4]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::correctInflowBoundary ( MInt  ,
MBool  = false 
)
inline

Definition at line 568 of file fvcartesianbndrycndxd.h.

568{}

◆ correctInflowBoundary() [3/4]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::correctInflowBoundary ( MInt  ,
MFloat *&  ,
MFloat *&   
)

◆ correctInflowBoundary() [4/4]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::correctInflowBoundary ( MInt  ,
MFloat *&  ,
MFloat *&  ,
MBool  = false 
)
inline

Definition at line 570 of file fvcartesianbndrycndxd.h.

570{}

◆ correctMasterSlaveSurfaces()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::correctMasterSlaveSurfaces
Author
: Daniel Hartmann, December 27, 2006

Definition at line 12816 of file fvcartesianbndrycndxd.cpp.

12816 {
12817 TRACE();
12818
12819 MInt cellId;
12820 MInt bndryId;
12821 MInt masterCellId;
12822 MInt noSurfaces = m_solver->a_noSurfaces();
12823 MInt otherId[2] = {1, 0};
12824 //--- end of initialization
12825
12826
12827 for(MInt srfcId = 0; srfcId < noSurfaces; srfcId++) {
12828 for(MInt nghbrId = 0; nghbrId < 2; nghbrId++) {
12829 cellId = m_solver->a_surfaceNghbrCellId(srfcId, nghbrId);
12830 if(m_solver->a_bndryId(cellId) < 0) {
12831 continue;
12832 }
12833
12834 bndryId = m_solver->a_bndryId(cellId);
12835 // check whether the cell is a slave cell
12836 if(m_bndryCells->a[bndryId].m_linkedCellId == -1) {
12837 continue;
12838 }
12839
12840 masterCellId = m_bndryCells->a[bndryId].m_linkedCellId;
12841
12842 // check whether the other neighbor of the surface is the
12843 // master cell
12844 if(m_solver->a_surfaceNghbrCellId(srfcId, otherId[nghbrId]) == masterCellId) {
12845 // THIS CASE SHOULD NOT APPEAR
12846 cerr << " srfc: " << srfcId << " cellId: " << cellId << " master: " << masterCellId
12847 << " other neighbor: " << m_solver->a_surfaceNghbrCellId(srfcId, otherId[nghbrId]) << endl;
12848 mTerm(1, AT_, "correctMasterSlaveSurfaces ERROR, exiting...");
12849
12850 } else {
12851 // shift the Id to the master cell
12852 m_solver->a_surfaceNghbrCellId(srfcId, nghbrId) = masterCellId;
12853 }
12854 }
12855 }
12856}

◆ correctNormal()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::correctNormal ( MFloat )

◆ createBndryCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::createBndryCells

Definition at line 12416 of file fvcartesianbndrycndxd.cpp.

12416 {
12417 TRACE();
12418
12419 MInt noCells = m_solver->a_noCells();
12420 MInt noDirs = 2 * nDim;
12421 //--- end of initialization
12422
12424
12425 for(MInt cellId = 0; cellId < noCells; cellId++) {
12426 if(m_solver->a_isInterface(cellId)) {
12427 if(isCutOffInterface(cellId)) {
12428 continue;
12429 }
12430 MInt bndryId = m_bndryCells->size();
12432 m_bndryCells->a[bndryId].m_cellId = cellId;
12433 m_bndryCells->a[bndryId].m_linkedCellId = -1;
12434 for(MInt face = 0; face < noDirs; face++) {
12435 m_bndryCells->a[bndryId].m_associatedSrfc[face] = -1;
12436 }
12437 for(MInt i = 0; i < nDim; i++) {
12438 m_bndryCells->a[bndryId].m_coordinates[i] = F0;
12439 }
12440 }
12441 }
12442}
MInt resetSize(MInt inputSize)
Definition: collector.h:45
void append()
Definition: collector.h:153
MInt isCutOffInterface(MInt cellId)

◆ createBndryCndHandler()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::createBndryCndHandler
Authors
Daniel Hartmann, Stephan Schlimpert
Date
, 22.12.2006, Januar 2011

< outflow b.c - x- direction

< outflow b.c + x- direction

< outflow b.c - y- direction

< outflow b.c + y- direction

< outflow b.c - z- direction

< outflow b.c + z- direction

< outflow b.c - x+ direction

< outflow b.c - x- direction

< outflow b.c - y+ direction

< outflow b.c - y- direction

< outflow b.c - x+ direction

< outflow b.c - x- direction

< outflow b.c - y+ direction

< outflow b.c - y- direction

Definition at line 2460 of file fvcartesianbndrycndxd.cpp.

2460 {
2461 TRACE();
2463 mAlloc(bndryCndHandlerVariables, m_maxNoBndryCndIds, "bndryCndHandlerVariables", AT_);
2464
2466 mAlloc(bndryCndHandlerSpongeVariables, mMax(1, m_noSpongeBndryCndIds), "bndryCndHandlerSpongeVariables", AT_);
2467
2469 mAlloc(bndryCndHandlerCutOffVariables, m_maxNoBndryCndIds, "bndryCndHandlerCutOffVariables", AT_);
2470
2472 mAlloc(bndryCndHandlerCutOffInit, m_maxNoBndryCndIds, "bndryCndHandlerCutOffInit", &FvBndryCndXD::bc0, AT_);
2473
2474 // mDeallocate( nonReflectingBoundaryCondition );
2475 // mAlloc( nonReflectingBoundaryCondition, m_maxNoBndryCndIds, "nonReflectingBoundaryCondition", AT_ );
2476
2478 mAlloc(nonReflectingCutOffBoundaryCondition, m_maxNoBndryCndIds, "nonReflectingCutOffBoundaryCondition", AT_);
2479
2482 "nonReflectingBoundaryConditionAfterTreatmentCutOff", AT_);
2483
2485 mAlloc(bndryCndHandlerCutOffSlopesInviscid, m_maxNoBndryCndIds, "bndryCndHandlerCutOffSlopesInviscid", AT_);
2486
2488 mAlloc(bndryCndHandlerSlopesInviscid, m_maxNoBndryCndIds, "bndryCndHandlerSlopesInviscid", AT_);
2489
2491 mAlloc(bndryViscousSlopes, m_maxNoBndryCndIds, "bndryViscousSlopes", AT_);
2492
2494 mAlloc(bndryCutOffViscousSlopes, m_maxNoBndryCndIds, "bndryCutOffViscousSlopes", AT_);
2495
2497 mAlloc(bndryCndHandlerInit, m_maxNoBndryCndIds, "bndryCndHandlerInit", AT_);
2498
2500 mAlloc(bndryCndHandlerNeumann, m_maxNoBndryCndIds, "bndryCndHandlerNeumann", AT_);
2501
2502 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++) {
2508
2509 switch(m_cutOffBndryCndIds[bcId]) {
2510 case 0: // do nothing
2514 break;
2515
2516 case 10910: // parabolic inflow - y-direction
2520 break;
2521
2522 case 109100:
2528 break;
2529
2530 case 109101: // subsonic characteristic inflow -> partially reflecting, T0, u, v is prescribed, incl. transverse
2531 // terms
2537 break;
2538
2539 case 309101: // subsonic characteristic turbulent inflow -> partially reflecting, T0, u, v is prescribed, incl.
2540 // transverse terms
2546 break;
2547
2548 case 209101: // subsonic characteristic inflow -> partially reflecting, T0, u, v is prescribed, incl. transverse
2549 // terms
2555 break;
2556
2557 case 209102: // subsonic characteristic inflow ->fully reflecting, T0, u, v is prescribed, incl. transverse terms
2558 // + forcing
2565 break;
2566
2567 case 109103: // subsonic characteristic inflow ->fully reflecting, p0,T0,v is prescribed, incl. shear and
2568 // transverse terms
2575 break;
2576
2577 case 109104: // subsonic characteristic inflow -> partially reflecting, p0,T0,v is prescribed, incl. shear and
2578 // transverse terms, profile of u1 is prescribed
2579 case 1091040:
2580 case 1091041:
2587 break;
2588
2589 case 209104: // subsonic characteristic inflow -> partially reflecting, p0,T0,v is prescribed, incl. shear and
2590 // transverse terms, profile of u1 is prescribed
2597 break;
2598
2599 case 109105: // subsonic characteristic inflow ->fully reflecting, p, u, v is prescribed, incl. transverse terms
2606 break;
2607
2608 case 109199: // subsonic characteristic inflow/outflow switch -> uses 109104 and 109900 methods
2615 break;
2616 case 109198: // subsonic characteristic inflow/outflow switch -> uses 109104 and 109900 methods
2622 break;
2623
2624 case 209198: // subsonic characteristic inflow/outflow switch -> uses 109104 and 109900 methods
2630 break;
2631
2632 case 309198: // subsonic characteristic inflow/outflow switch -> uses 109104 and 109900 methods
2638 break;
2639
2640 // subsonic characteristic inflow/outflow switch by crank-angle
2641 case 209199: // combined inflow with 309199
2642 case 309199:
2643 case 409199: // single outflow
2644 case 509199: // single inflow
2648 if(!m_solver->m_engineSetup) {
2651 } else {
2652 IF_CONSTEXPR(nDim == 3) {
2654 }
2655 else {
2658 }
2659 }
2660 break;
2661
2662 case 109900:
2668 break;
2669 case 109910:
2675 break;
2676 case 109911:
2682 break;
2683
2684 case 109901: // subsonic characteristic outflow -> fully reflecting, p is prescribed, incl. shear and transverse
2685 // terms
2692 break;
2693
2694 case 10990: // simple outflow, fixed pressure
2698 break;
2699
2700 case 10970: // simple outflow, fixed pressure
2704 break;
2705
2706 case 10980: // simple inflow, x-direction, fixed pressure
2710 break;
2711
2712 case 11110: // inflow/outflow from RANS
2715 bndryCutOffViscousSlopes[bcId] = &FvBndryCndXD::sbc00co; // TODO labels:FV
2716 break;
2717
2718 // characteristic inflow b.c. - x/y/z direction - top hat velocity profile - progress variable
2719 // for forced response
2720 case 17516:
2721 case 17616:
2722 case 17716:
2723 case 17816:
2725 break;
2726
2727 case 1251:
2728 case 1261:
2729 case 1271:
2730 case 1281:
2732 break;
2733
2734 // Round Jet inflow b.c. - x/y/z direction - parabolic velocity profile
2735 case 19516:
2736 case 19616:
2737 case 19716:
2739 break;
2740
2741 // simple outflow b.c. - x/y/z direction - progress variable
2742 case 17530:
2743 case 17531:
2744 case 17532:
2745 case 17533:
2746 case 17534:
2747 case 17535:
2748 case 1743:
2749 case 1753:
2750 case 1763:
2751 case 1773:
2753 break;
2754
2755 // simple outflow b.c. pressure infinity - x/y/z direction - progress variable
2756 case 1745:
2757 case 1755:
2758 case 1765:
2759 case 1775:
2763 break;
2764
2765 // linear shear flow (initial condition 466)
2766 case 17110:
2767 case 17111:
2768 case 17112:
2769 case 17113:
2770 case 17114:
2771 case 17115:
2773 break;
2774
2775 // simple outflow b.c. - pos. x/y/z direction - passive scalar
2776 case 1952:
2778 break;
2779
2780 // non-reflecting outflow b.c. - species
2781 case 19520:
2782 case 19720:
2784 break;
2785
2786 // simple inflow b.c. - x/y/z direction - passive scalar
2787 case 1156:
2788 case 1166:
2789 case 1176:
2791 break;
2792
2793 // supersonic inflow with acoustic and entropy waves
2794 case 2700:
2797 break;
2798 // supersonic inflow with acoustic and entropy waves, single modes
2799 case 2800:
2802 break;
2803
2804 case 2770:
2807 break;
2808
2809 // extrapolation of all variables and slopes
2810 case 2710:
2811 case 2711:
2812 case 2712:
2813 case 2713:
2814 case 2714:
2815 case 2715:
2817 // bndryCndHandlerCutOffSlopesInviscid[bcId] =
2818 // &FvBndryCndXD::bc2710s;
2820 break;
2821
2822 // extrapolation of all variables and slopes
2823 case 2720:
2824 case 2721:
2825 case 2722:
2826 case 2723:
2827 case 2724:
2828 case 2725:
2830 // bndryCndHandlerCutOffSlopesInviscid[bcId] =
2831 // &FvBndryCndXD::bc2710s;
2833 break;
2834
2835 // Euler cut-off boundary condition
2836 case 29053:
2837 case 29052:
2838 case 29050:
2839 case 29051:
2841 /*
2842 bndryCndHandlerCutOffSlopesInviscid[bcId] =
2843 &FvBndryCndXD::sbc00co;
2844 bndryCutOffViscousSlopes[bcId] =
2845 &FvBndryCndXD::sbc00co;*/
2846 break;
2847
2848 // random-eddy inflow cut-off boundary condition
2849 case 1601:
2854 break;
2855 // random-eddy inflow cut-off boundary condition with a velocity profile (turbulent slot flame)
2856 case 1602:
2861 break;
2862 // random-eddy inflow cut-off boundary condition with mean velocity profile for 3D round jet
2863 case 1603:
2868 break;
2869 // random-eddy inflow cut-off BC with mean velocity profile for 3D round jet (1603 updated)
2870 case 1604:
2875 break;
2876 // random-eddy inflow cut-off boundary condition with mean velocity profile for 3D chevron jet
2877 case 1606:
2882 break;
2883
2884 case 1791:
2888 break;
2889
2890
2891 case 1792:
2895 break;
2896
2897 // outflow cut-off
2898 case 16010:
2902 break;
2903 case 16011:
2907 break;
2908
2909 // Euler cut-off boundary condition
2910 case 16012:
2914 break;
2915 case 16013:
2919 break;
2920 case 16014:
2924 break;
2925 case 16015:
2929 break;
2930
2931 //---Zonal BC---
2932 case 7901:
2933 IF_CONSTEXPR(hasPV_N<SysEqn>::value) {
2936 }
2937 break;
2938 case 7902:
2939 IF_CONSTEXPR(hasPV_N<SysEqn>::value) {
2942 }
2943 else mTerm(1, AT_, "BC7902 only works with a SysEqn that has PV->N");
2946 break;
2947 case 7905:
2948 IF_CONSTEXPR(hasPV_N<SysEqn>::value) {
2951 }
2952 else mTerm(1, AT_, "BC7905 only works with a SysEqn that has PV->N");
2955 break;
2956 case 7903:
2957 IF_CONSTEXPR(!hasPV_N<SysEqn>::value)
2959 else mTerm(1, AT_, "BC7908 only works for LES");
2960 break;
2961 case 7909:
2962 IF_CONSTEXPR(!hasPV_N<SysEqn>::value) {
2965 }
2966 else mTerm(1, AT_, "BC7908 only works for LES");
2969 break;
2970 case 30022:
2975 break;
2976
2977 default: {
2978 stringstream errorMessage;
2979 errorMessage << "ERROR: Switch variable 'm_cutOffBndryCndIds[ bcId ]' with value " << m_cutOffBndryCndIds[bcId]
2980 << " not matching any case." << endl;
2981 mTerm(1, AT_, errorMessage.str());
2982 }
2983 }
2984 }
2985 // set the pointer to the corresponding bc functions
2986 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
2987 switch(m_bndryCndIds[bcId]) {
2988 case 0:
2990 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
2993 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
2994 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
2995 break;
2996
2997 case 1:
2999 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3002 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3003 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3004 break;
3005
3006 // Symmetry boundary condition about x-axis
3007 case 100100:
3009 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3014 break;
3015
3016 // simple inflow b.c. - x direction
3017 case 1001:
3019 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3022 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3023 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3024 break;
3025 case 1009:
3027 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3030 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3031 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3032 break;
3033 // simple inflow b.c. - y direction
3034 case 1011:
3036 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3039 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3040 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<1>;
3041 break;
3042
3043 // simple inflow b.c. - y direction
3044 case 2011:
3046 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3049 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3050 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<1>;
3051 break;
3052 // combined jet inflow/wall boundary condition
3053 case 1401:
3055 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3058 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3059 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3060 break;
3061 // simple inflow b.c. - x direction - species
3062 case 1801:
3064 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3067 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3068 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2901<0>;
3069 break;
3070 // simple inflow b.c. - y direction - passive scalar
3071 case 1901:
3073 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3076 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3077 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2901<0>;
3078 break;
3079 // simple inflow b.c. - y direction - passive scalar
3080 case 1911:
3082 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3085 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3086 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2901<1>;
3087 break;
3088 // simple inflow b.c. - z direction - passive scalar
3089 case 1921:
3090 IF_CONSTEXPR(nDim == 3) {
3092 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3095 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3096 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2901<2>;
3097 }
3098 else {
3099 TERM(-1);
3100 }
3101 break;
3102 // simple outflow b.c.
3103 case 1002:
3105 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3108 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3109 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3110 break;
3111
3112 case 1012:
3114 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3117 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3118 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<1>;
3119 break;
3120 case 1021:
3121 IF_CONSTEXPR(nDim == 3) {
3123 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3126 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3127 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<2>;
3128 }
3129 else {
3130 TERM(-1);
3131 }
3132 break;
3133
3134 case 1022:
3136 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3139 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3140 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<2>;
3141 break;
3142
3143 case 1003:
3145 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3148 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3149 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3150 break;
3151
3152 case 1004:
3154 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3157 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3158 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3159 break;
3160
3161 case 1005:
3163 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3166 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3167 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3168 break;
3169
3170 // laminar tube inflow b.c. - normal direction
3171 case 1091:
3172 case 1092:
3175 } else {
3177 }
3178 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3180 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<true>;
3181 } else {
3182 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3183 }
3185 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3186 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3187 break;
3188
3189 // simple outflow b.c. normal direction
3190 case 1098:
3192 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3193 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3195 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3196 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3197 break;
3198 case 1099:
3200 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3202 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<true>;
3203 } else {
3204 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3205 }
3207 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3208 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3209 break;
3210 case 2001:
3212 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3215 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3216 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3217 break;
3218
3219 case 2002:
3221 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3224 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3225 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3226 break;
3227
3228 case 2003:
3229 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3230 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3233 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3234 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3235 break;
3236
3237
3238 // solid wall Euler b.c.
3239 case 3002:
3241 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<true>;
3242 } else {
3243 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3244 }
3245
3246 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3248 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3249
3251 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<true>;
3252 } else {
3253 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3254 }
3255
3256 if(m_bndryCndIds[bcId] == 3002) {
3258 }
3259 break;
3260 case 30021:
3262 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<true>;
3263 } else {
3264 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3265 }
3266
3267 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3269 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3270
3272 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<true>;
3273 } else {
3274 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3275 }
3276
3277 if(m_bndryCndIds[bcId] == 30021) {
3279 }
3280 break;
3281 case 3399: // spalding wall model adiabatic no slip b.c. using precomputed mue_wm
3283 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<true>;
3285 bndryCndHandlerVariables[bcId] = &FvBndryCndXD::bc3399<true>;
3286 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<true>;
3287 } else {
3288 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3290 bndryCndHandlerVariables[bcId] = &FvBndryCndXD::bc3399<false>;
3291 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3292 }
3293 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3294 break;
3295
3296
3297 // solid wall b.c.
3298 case 3003:
3299 case 3009:
3300 case 4003: // not used for force calculation etc.
3301 case 3037:
3302 case 3905:
3303 case 30040:
3304 case 30050:
3305 case 4000:
3306 case 4001:
3308 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<true>;
3309 } else {
3310 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3311 }
3312 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3315 } else {
3317 }
3319 if(m_bndryCndIds[bcId] == 3003 || m_bndryCndIds[bcId] == 3009) {
3320 bndryCndHandlerVariables[bcId] = &FvBndryCndXD::bc3003<true>;
3321 } else if(m_bndryCndIds[bcId] == 3037) {
3323 }
3324 } else {
3325 if(m_bndryCndIds[bcId] == 4000) {
3327 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit4000<true>;
3328 } else if(m_bndryCndIds[bcId] == 4001) {
3330 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit4000<true>;
3331 } else {
3332 bndryCndHandlerVariables[bcId] = &FvBndryCndXD::bc3003<false>;
3333 }
3334 }
3335 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3337 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<true>;
3338 } else {
3339 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3340 }
3341 break;
3342
3343 case 3004:
3344 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3345 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3348 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3349 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3350 break;
3351
3352 case 3005:
3354 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3357 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3358 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3359 break;
3360
3361
3362 // isothermal solid wall b.c.
3363 case 3011:
3364 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3367 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3369 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<true>;
3370 } else {
3371 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2000<false>;
3372 }
3373 break;
3374
3375
3376 case 3006: // moving wall b.c. adiabatic
3377 case 3010: // moving wall b.c. isothermal
3381 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3383 break;
3384
3385 // moving wall b.c. without boundary slopes
3386 case 3060:
3392 break;
3393
3394 // moving wall euler b.c.
3395 case 3007:
3399 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000; // bc0;
3401 break;
3402
3403 // moving wall euler b.c. isothermal without slopes and Neumann-Type
3404 case 3008:
3410 break;
3411
3412 // simple and fast solid fixed adiabatic wall b.c. for non-merging small cell treatment
3413
3414 case 3600:
3416 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3419 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3421 break;
3422
3423 // simple shear flow (initialCondition 466)
3424 case 3466:
3426 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3429 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3431 break;
3432
3433
3434 // no-slip wall b.c. (x direction) - passive scalar
3435 case 2907:
3436 bndryCndHandlerInit[bcId] = &FvBndryCndXD::bcInit0002<false>;
3437 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3440 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3441 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3442 break;
3443
3444 // combustion
3445 // (do not compute species ghost cell gradients according to sbc2000)
3446 case 1101:
3447 case 1102:
3448 if(m_bndryCndIds[bcId] == 1101) {
3450 } else if(m_bndryCndIds[bcId] == 1102) {
3452 }
3453 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3456 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3457 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<0>;
3458 break;
3459
3460 case 1111:
3461 case 1112:
3462 if(m_bndryCndIds[bcId] == 1111) {
3464 } else if(m_bndryCndIds[bcId] == 1112) {
3466 }
3467 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3470 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3471 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<1>;
3472 break;
3473
3474 case 1121:
3475 case 1122:
3476 if(m_bndryCndIds[bcId] == 1121) {
3478 } else if(m_bndryCndIds[bcId] == 1122) {
3480 }
3481 // nonReflectingBoundaryCondition[bcId] = &FvBndryCndXD::bc0;
3484 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3485 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc2001<2>;
3486 break;
3487
3488 case 7909:
3489 case 7910:
3490 case 7911:
3491 case 7912:
3492 case 7913:
3493 // stg
3494 IF_CONSTEXPR(!hasPV_N<SysEqn>::value) {
3497 }
3498 else mTerm(1, AT_, to_string(m_cutOffBndryCndIds[bcId]) + " only works for LES");
3500 bndryCndHandlerSlopesInviscid[bcId] = &FvBndryCndXD::sbc1000;
3501 bndryViscousSlopes[bcId] = &FvBndryCndXD::sbc1000;
3502 break;
3503
3504 case 4100:
3505 mTerm(1, AT_,
3506 "This boundary condition id was only used for the ghost fluid solver, which has been removed in Nov. "
3507 "2012. There is an alternative b.c. id that uses the same methods (minus the GF stuff): 4000");
3508 break;
3509
3510 case 4101:
3511 mTerm(1, AT_,
3512 "This boundary condition id was only used for the ghost fluid solver, which has been removed in Nov. "
3513 "2012. There is an alternative b.c. id that uses the same methods (minus the GF stuff): 4001");
3514 break;
3515
3516 default: {
3517 std::stringstream errorMsg;
3518 errorMsg << "FvBndryCndXD::initBndryCells error" << std::endl
3519 << "#" << bcId << " Unknown Boundary Condition Id: " << m_bndryCndIds[bcId] << std::endl;
3520 mTerm(1, AT_, errorMsg.str());
3521 }
3522 }
3523 }
3524}
BndryCndHandler * bndryCndHandlerVariables
void cbc1099_1091_local_comb(MInt)
BndryCndHandler * bndryCndHandlerSlopesInviscid
virtual void bc19520(MInt)
BndryCndHandler * bndryCndHandlerCutOffInit
void sbc1000co(const MInt)
Cut off condition for the slopes.
void sbc00co(const MInt)
Cut off condition for the slopes.
void cbc1091e_after(MInt)
Subsonic fully reflecting characteristic inflow condition - cut off - sets T0,u,v to prescribed value...
MInt m_noSpongeBndryCndIds
number of sponge boundary condition IDs
void cbc1099a_after(MInt)
Subsonic fully reflecting characteristic outflow condition - cut off - sets pstat to prescribed value...
void sbc2720co(MInt)
Cut off condition for the slopes copys the slopes, and sets pressure slope to sero NOTIMPLEMENTED ver...
void cbc1099_1091d_after(MInt)
void bcNeumannMb(MInt)
Moving boundary Neumann condition.
void cbc109911(MInt)
Characteristic boundary condition. Outflow. Prescribed: p. Partially Refelecting.
virtual void bc2001(MInt)
virtual void bc1801(MInt)
void bcInit2700(MInt)
init for the acoustic and entropy waves
virtual void sbc2710co(MInt)
virtual void bc1901(MInt)
void bcInit0004(MInt)
Sets up the reconstruction stencil for boundary cells (quadratic least-squares reconstruction)
void cbc2099_1091_local_comb(MInt)
virtual void bc2770(MInt)
virtual void bc1003(MInt)
BndryCndHandler * bndryCndHandlerInit
void cbc1099_1091_engineOld(MInt)
virtual void bc3037MGC(MInt)
virtual void bc2003(MInt)
BndryCndHandler * bndryCndHandlerCutOffVariables
virtual void bc10990(MInt)
void bc11110(MInt)
BndryCndHandler * bndryViscousSlopes
virtual void bc1401(MInt)
void cbc1091c_after(MInt)
Subsonic fully reflecting characteristic inflow condition - cut off - sets T0,u,v to prescribed value...
virtual void bc2002(MInt)
BndryCndHandler * bndryCndHandlerCutOffSlopesInviscid
void cbc1091d_after(MInt)
Subsonic fully reflecting characteristic inflow condition - cut off - sets un to prescribed value aft...
virtual void bc1001coflowY(MInt)
void bcInit30022(MInt)
void bcInit1601(MInt)
Initialize bc1601.
BndryCndHandler * bndryCndHandlerSpongeVariables
void sbc1002(MInt)
Symmetry boundary condition about x-axis (slopes)
void cbc2091b_after(MInt)
Subsonic fully reflecting characteristic inflow condition - cut off - sets T0,u,v to prescribed value...
virtual void bc1791(MInt)
void bcInit2770(MInt)
supersonic inflow with imposed onlique shock wave and linear waves version: cut-off boundary conditio...
void cbc2091d_after(MInt)
Subsonic fully reflecting characteristic inflow condition - cut off - sets un to prescribed value aft...
void bcInitCbc(MInt)
virtual void bc10910(MInt)
void cbc109910(MInt)
Characteristic boundary condition. Outflow. Prescribed: p. Partially Refelecting.
virtual void bc1005(MInt)
virtual void bc1004(MInt)
void bc1952(MInt)
Subsonic outflow boundary condition (applied directly to the (boundary) cell). Set of variables: Stan...
void bcNeumann3600(MInt)
Simple and fast fixed adiabatic wall boundary condition for use with the flux-redistribution method.
BndryCndHandler * bndryCutOffViscousSlopes
void bcInit0001(MInt)
Sets up the reconstruction stencil for boundary cells.
Checks if the primitive variable N exists.

◆ createBoundaryAtCutoff()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::createBoundaryAtCutoff ( )

◆ createCutFace() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==2, _ * > >
void FvBndryCndXD< nDim, SysEqn >::createCutFace

computes the geometry of each the cut cells (3D version) multiply cut cells can not be handeled! computes the following boundary cell member variables:

  • m_noSrfcs
  • m_volume
  • m_coordinates
  • m_srfcs[srfc]->m_area
  • m_srfcs[srfc]->m_coordinates
  • m_srfcs[srfc]->m_volume
  • m_srfcs[srfc]->m_normalVector
  • m_externalFaces for each cut surface (currently only 1):
  • m_srfcs[srfc]->m_bodyId
  • m_srfcs[srfc]->m_cutEdge
  • m_srfcs[srfc]->m_cutCoordinates of the respective surface in addition, surfaces for the body surfaces and the cut cartesian faces of each cell are suplied (will be corrected in checkForSrfcs)
    Author
    Claudia Guenther, 10/2013
  • m_noSrfcs = 1 (otherwise quit)
  • m_volume
  • m_coordinates
  • m_srfcs[srfc]->m_area
  • m_srfcs[srfc]->m_coordinates
  • m_srfcs[srfc]->m_volume
  • m_srfcs[srfc]->m_normalVector
  • m_externalFaces for each cut surface (i.e. the cut surface):
  • m_srfcs[srfc]->m_bodyId
  • m_srfcs[srfc]->m_cutEdge
  • m_srfcs[srfc]->m_cutCoordinates of the respective surface in addition, surfaces for the body surfaces and the cut cartesian faces of each cell are suplied (will be corrected in checkForSrfcs)
    Author
    Daniel Hartmann, 23.12.2006, changed by Claudia Guenther, 10/2013, changed by Sohel Herff 2016

Definition at line 23691 of file fvcartesianbndrycndxd.cpp.

23691 {
23692 TRACE();
23693
23694 const MInt otherDir[2] = {1, 0};
23695 const MInt faceOrder[4] = {2, 1, 3, 0};
23696 const MFloat signCode[2][4] = {{-F1, F1, F1, -F1}, {-F1, -F1, F1, F1}};
23697
23698 //----------------------------------------------------------------------------
23699 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
23700 MInt cellId = m_bndryCells->a[bndryId].m_cellId;
23701
23702 for(MInt f = 0; f < m_noDirs; f++) {
23703 m_bndryCells->a[bndryId].m_externalFaces[f] = false;
23704 }
23705
23706 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints != 2) {
23707 cerr << "** FvBndryCnd2D ERROR" << endl;
23708 cerr << "boundary cell " << bndryId << endl;
23709 cerr << m_solver->a_coordinate(cellId, 0) << " " << m_solver->a_coordinate(cellId, 1) << endl;
23710 cerr << m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints
23711 << " -> number of cut points is not equal two - multiple body surfaces not implemented!" << endl;
23712 continue;
23713 }
23714
23715 const MFloat cellLength = m_solver->c_cellLengthAtCell(cellId);
23716 const MFloat cellHalfLength = F1B2 * cellLength;
23717
23718 if(!m_solver->c_isLeafCell(cellId) || (!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel))) {
23719 m_bndryCells->a[bndryId].m_volume = m_solver->grid().gridCellVolume(m_solver->a_level(cellId));
23720 for(MInt i = 0; i < nDim; i++) {
23721 m_bndryCells->a[bndryId].m_coordinates[i] = F0;
23722 }
23723 m_bndryCells->a[bndryId].m_noSrfcs = 0;
23724 continue;
23725 }
23726
23727 MInt noCutPoints = m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints;
23728
23729 MInt cutPointIds[4] = {-1, -1, -1, -1};
23730 MInt edgeCutPointCounter[4] = {0, 0, 0, 0};
23731 for(MInt cp = 0; cp < noCutPoints; cp++) {
23732 MInt edge = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[cp];
23733 ASSERT(edgeCutPointCounter[edge] == 0, "");
23734 cutPointIds[edge] = cp;
23735 edgeCutPointCounter[edge]++;
23736 }
23737
23738 // store relevant cut and corner point information in math. pos. sense of rotation (only convex cells are allowed)
23739 MFloat coords[16];
23740 MInt pointBodyId[8]; // -1: corner point; > -1: cut point with body Id
23741 MInt pointEdgeId[8];
23742 MInt noNodes = 0;
23743 for(MInt n = 0; n < 4; n++) {
23744 MFloat cornerPoint[2] = {F0, F0};
23745 for(MInt d = 0; d < nDim; d++)
23746 cornerPoint[d] = m_solver->a_coordinate(cellId, d) + signCode[d][n] * cellHalfLength;
23747 if(!m_solver->m_geometry->pointIsInside(cornerPoint)) {
23748 for(MInt d = 0; d < nDim; d++)
23749 coords[noNodes * 2 + d] = cornerPoint[d];
23750 pointBodyId[noNodes] = -1; // corner point
23751 pointEdgeId[noNodes] =
23752 faceOrder[n]; // holds the edge which starts in the respective point (math. pos. sense of rotation)
23753 noNodes++;
23754 }
23755 MInt cpId = cutPointIds[faceOrder[n]];
23756 if(cpId > -1) {
23757 for(MInt d = 0; d < nDim; d++)
23758 coords[noNodes * 2 + d] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cpId][d];
23759 pointBodyId[noNodes] = m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[cpId]; // point is a cut point
23760 pointEdgeId[noNodes] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[cpId]; // cut edge
23761 noNodes++;
23762 }
23763 }
23764 // after this, the original cut point storage can be deleted -> will be stored cut-surface-wise in correct order
23765 // from now on!
23766
23767 // compute cell "volume" and centroid
23768 MFloat volume = F0;
23769 MFloat centroid[2]{};
23770 computePolygon(coords, noNodes, centroid, &volume);
23771
23772 // set up data structure of line segments for easier processing
23773 MInt lineSegments[8][2]; // stores the point Ids of the points defining the different segments
23774 MInt lineTypes[8]; // -2: uncut cartesian face, -1: cut cartesian face, >=0: body segment
23775 MInt edgeLinePointer[4] = {
23776 -1, -1, -1, -1}; // stores segment Id for each (cut or uncut) Cartesian edge which is part of the polygonal
23777 // cell description, -1 if edge is nonFluidSide and thus not part of the polygon
23778 MInt bodyLinePointer[4] = {
23779 -1, -1, -1,
23780 -1}; // stores segment Id for each body surface = non-Cartesian edges in the polygonal cell description
23781 MInt bodyLineCounter = 0; // number of body surfaces
23782 for(MInt segment = 0; segment < noNodes; segment++) {
23783 MInt firstPoint = segment;
23784 MInt secondPoint = (segment + 1) % noNodes;
23785 lineSegments[segment][0] = firstPoint;
23786 lineSegments[segment][1] = secondPoint;
23787 if(pointBodyId[firstPoint] == -1 && pointBodyId[secondPoint] == -1) {
23788 // line segment is uncut cartesian segment
23789 edgeLinePointer[pointEdgeId[firstPoint]] = segment;
23790 lineTypes[segment] = -2; // uncut cartesian face
23791 } else if(pointBodyId[firstPoint] == -1 || pointBodyId[secondPoint] == -1) {
23792 // line segment is cut cartesian segment
23793 edgeLinePointer[pointEdgeId[firstPoint]] = segment;
23794 lineTypes[segment] = -1; // cut cartesian face
23795 } else {
23796 // line segment is body segment with pointBodyId
23797 bodyLinePointer[bodyLineCounter] = segment;
23798 lineTypes[segment] = bodyLineCounter++;
23799 }
23800 if(bodyLineCounter > 1) {
23801 cerr << to_string(m_solver->c_cellLengthAtCell(cellId)) << endl;
23802 cerr << to_string(m_solver->c_cellLengthAtCell(cellId)) << endl;
23803 // cerr << to_string(m_solver->a_surfaceCoordinate( cellId , 1) << endl;
23804 }
23805 }
23806
23807 MFloat cutFaceAreas[4];
23808 MFloat surfCoords[2];
23809 for(MInt dir = 0; dir < m_noDirs; dir++) {
23810 MInt edge = dir;
23811 MInt sideId = dir % 2;
23812 MInt spaceId = dir / 2;
23813 MInt tDir = otherDir[spaceId];
23814 for(MInt j = 0; j < nDim; j++) {
23815 surfCoords[j] = m_solver->a_coordinate(cellId, j);
23816 }
23817 surfCoords[spaceId] += signCode[0][sideId] * cellHalfLength;
23818
23819 MInt segmentId = edgeLinePointer[edge];
23820 if(segmentId == -1) {
23821 // non fluid side
23822 m_bndryCells->a[bndryId].m_externalFaces[dir] = true;
23823 cutFaceAreas[dir] = F0;
23824 } else {
23825 MInt lineType = lineTypes[segmentId];
23826 if(lineType == -2) {
23827 // uncut Cartesian face
23828 cutFaceAreas[dir] = cellLength;
23829 } else {
23830 // cut Cartesian face - compute segment area
23831 MInt point1 = lineSegments[segmentId][0];
23832 MInt point2 = lineSegments[segmentId][1];
23833 MFloat pointDiff = coords[point2 * 2 + tDir] - coords[point1 * 2 + tDir];
23834 cutFaceAreas[dir] = fabs(pointDiff);
23835 surfCoords[tDir] = coords[point1 * 2 + tDir] + F1B2 * pointDiff;
23836 }
23837 }
23838
23839 MBool createSrfc = true;
23840 MInt nghbrId = -1;
23841 if(m_solver->a_hasNeighbor(cellId, dir) > 0) {
23842 nghbrId = m_solver->c_neighborId(cellId, dir);
23843 } else {
23844 if(m_solver->c_parentId(cellId) > -1) {
23845 if(m_solver->a_hasNeighbor(m_solver->c_parentId(cellId), dir) > 0)
23846 nghbrId = m_solver->c_neighborId(m_solver->c_parentId(cellId), dir);
23847 else
23848 createSrfc = false;
23849 } else
23850 createSrfc = false;
23851 }
23852 if(createSrfc)
23853 if(m_solver->c_noChildren(nghbrId) > 0) createSrfc = false;
23854 if(createSrfc) {
23855 MInt srfcId = m_solver->a_noSurfaces();
23856 m_surfaces.append();
23857 m_solver->a_surfaceOrientation(srfcId) = spaceId;
23858 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
23859 m_solver->a_surfaceNghbrCellId(srfcId, otherDir[sideId]) = cellId;
23860 m_solver->a_surfaceArea(srfcId) = cutFaceAreas[dir];
23861 for(MInt i = 0; i < nDim; i++) {
23862 m_solver->a_surfaceCoordinate(srfcId, i) = surfCoords[i];
23863 }
23864 m_bndryCells->a[bndryId].m_associatedSrfc[dir] = srfcId;
23865 }
23866 }
23867
23868 ASSERT(bodyLineCounter == 1, ""); // in a later version, multiply cut cells can be enabled!
23869 m_bndryCells->a[bndryId].m_noSrfcs = 1;
23870
23871 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
23872 MInt segmentId = bodyLinePointer[srfc];
23873 ASSERT(segmentId > -1, "");
23874 MInt point1 = lineSegments[segmentId][0];
23875 MInt point2 = lineSegments[segmentId][1];
23876
23877 // compute area and normal of body surface
23878 MFloat area = F0;
23879 MFloat normal[2];
23880 MFloat surfaceCoordinates[2];
23881 // compute body surfaces
23882 MFloat deltaX = coords[point2 * 2] - coords[point1 * 2];
23883 MFloat deltaY = coords[point2 * 2 + 1] - coords[point1 * 2 + 1];
23884 area = sqrt(deltaX * deltaX + deltaY * deltaY);
23885 normal[0] = -deltaY / mMax(m_solver->m_eps, area);
23886 normal[1] = deltaX / mMax(m_solver->m_eps, area);
23887 surfaceCoordinates[0] = coords[point1 * 2 + 0] + F1B2 * deltaX;
23888 surfaceCoordinates[1] = coords[point1 * 2 + 1] + F1B2 * deltaY;
23889
23890 // store cut point information
23891 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_noCutPoints = 2;
23892 for(MInt i = 0; i < nDim; i++) {
23893 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_cutCoordinates[0][i] = coords[point1 * 2 + i];
23894 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_cutCoordinates[1][i] = coords[point2 * 2 + i];
23895 }
23896 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_cutEdge[0] = pointEdgeId[point1];
23897 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_cutEdge[1] = pointEdgeId[point2];
23898 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[0] = pointBodyId[point1];
23899 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bodyId[1] = pointBodyId[point2];
23900
23901 // store body surface information
23902 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area = area;
23903 for(MInt i = 0; i < nDim; i++) {
23904 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i] = normal[i];
23905 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_coordinates[i] = surfaceCoordinates[i];
23906 }
23907 }
23908
23909 m_bndryCells->a[bndryId].m_volume = volume;
23910 for(MInt i = 0; i < nDim; i++) {
23911 m_bndryCells->a[bndryId].m_coordinates[i] = centroid[i] - m_solver->a_coordinate(cellId, i);
23912 }
23913
23914 // for debug purpose: check cell areas:
23915 MFloat areaCheck[2] = {F0, F0};
23916 const MFloat checkEps = 1e-12;
23917 for(MInt i = 0; i < nDim; i++) {
23918 areaCheck[i] += (cutFaceAreas[2 * i] - cutFaceAreas[2 * i + 1]);
23919 }
23920 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
23921 for(MInt i = 0; i < nDim; i++) {
23922 areaCheck[i] +=
23923 m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_normalVector[i];
23924 }
23925 }
23926 MBool checkPassed = ((fabs(areaCheck[0]) < checkEps) && (fabs(areaCheck[1]) < checkEps));
23927 if(!checkPassed) {
23928 cerr << "** FvBndryCnd2D WARNING" << endl;
23929 cerr << "boundary cell " << bndryId << endl;
23930 cerr << m_solver->a_coordinate(cellId, 0) << " " << m_solver->a_coordinate(cellId, 1) << endl;
23931 cerr << " -> boundary cell check not passed! " << endl;
23932 cerr << " area check: " << areaCheck[0] << " " << areaCheck[1] << endl;
23933 continue;
23934 }
23935 }
23936}
void computePolygon(MFloat *x, const MInt N, MFloat *centroid, MFloat *area)
MBool c_isLeafCell(const MInt cellId) const

◆ createCutFace() [2/2]

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

◆ createCutFaceMGC() [1/2]

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==3, _ * > >
void FvBndryCndXD< nDim, SysEqn >::createCutFaceMGC

recomputes the cut cells based on the cut points on the cell edges - MGC version

computes the following boundary cell member variables: 2 cut points are assumed for each cell face multiple boundary cut faces are allowed

  • m_noSrfcs
  • m_srfcs[srfc]->m_area
  • m_srfcs[srfc]->m_coordinates
  • m_srfcs[srfc]->m_volume
  • m_srfcs[srfc]->m_normalVector
  • m_externalFaces

cell structure is determined by using a modified marching cubes approach (see e.g. Evgeni V. Chernyaev, Marching Cubes 33 and further publications) uses fvlookuptable.h

extended version of createCutFaceMG() method which is able to handle split cells and ambiguous cell configurations correctly.

Author
Claudia Guenther, Feb 2009

Definition at line 24899 of file fvcartesianbndrycndxd.cpp.

24899 {
24900 TRACE();
24901
24902 static constexpr MInt cornerIndices[8][3] = {{-1, -1, -1}, {1, -1, -1}, {-1, 1, -1}, {1, 1, -1},
24903 {-1, -1, 1}, {1, -1, 1}, {-1, 1, 1}, {1, 1, 1}};
24904 // the following variables describe the different corner/edge/face numbering in MAIA and MarchingCubes table
24905 static constexpr MInt cornersMCtoSOLVER[8] = {2, 0, 1, 3, 6, 4, 5, 7};
24906 static constexpr MInt cornersSOLVERtoMC[8] = {1, 2, 0, 3, 5, 6, 4, 7};
24907 static constexpr MInt edgesMCtoSOLVER[12] = {0, 2, 1, 3, 4, 6, 5, 7, 10, 8, 9, 11};
24908 static constexpr MInt facesMCtoSOLVER[6] = {0, 2, 1, 3, 4, 5};
24909 static constexpr MInt neighborCorner[6] = {1, -1, 2, -2, 4, -4};
24910 static constexpr MInt cornerFaceMapping[24] = {0, 2, 4, 1, 2, 4, 0, 3, 4, 1, 3, 4,
24911 0, 2, 5, 1, 2, 5, 0, 3, 5, 1, 3, 5};
24912 static constexpr MInt faceCornerMapping[24] = {0, 2, 4, 6, 1, 3, 5, 7, 0, 1, 4, 5,
24913 2, 3, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7};
24914
24915 unsigned char outcode_MC = 0;
24916 MInt noCells = m_bndryCells->size();
24917 MInt cellId;
24918 MFloat gridCellVolume;
24919 MFloat corner[8][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
24920 MInt currentCase;
24921 MInt presentCases[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
24922 MInt* presentSubCases[15];
24923 const MInt maxNoSubCases = 48;
24924 MIntScratchSpace presentSubCases_scratch(15 * maxNoSubCases, AT_, "presentSubCases_scratch");
24925 for(MInt i = 0; i < 15; i++)
24926 presentSubCases[i] = &presentSubCases_scratch.p[maxNoSubCases * i];
24927 for(MInt i = 0; i < 15; i++) {
24928 for(MInt j = 0; j < maxNoSubCases; j++) {
24929 presentSubCases[i][j] = 0;
24930 }
24931 }
24932 MBool currentOutcode = false;
24933 MInt nghbrId;
24934 MInt sideId;
24935 MInt otherSideId;
24936 MInt srfcId;
24937 MInt spaceId;
24938 MFloat* faceCentroid[6];
24939 MFloatScratchSpace faceCentroid_scratch(nDim * 6, AT_, "faceCentroid_scratch");
24940 for(MInt i = 0; i < 6; i++)
24941 faceCentroid[i] = &faceCentroid_scratch.p[i * nDim];
24942 MFloat* faceCentroid_0[6];
24943 MFloatScratchSpace faceCentroid_0_scratch(nDim * 6, AT_, "faceCentroid_0_scratch");
24944 for(MInt i = 0; i < 6; i++)
24945 faceCentroid_0[i] = &faceCentroid_0_scratch.p[i * nDim];
24946 MFloat* faceCentroid_00[6];
24947 MFloatScratchSpace faceCentroid_00_scratch(nDim * 6, AT_, "faceCentroid_00_scratch");
24948 for(MInt i = 0; i < 6; i++)
24949 faceCentroid_00[i] = &faceCentroid_00_scratch.p[i * nDim];
24950 MFloat* normal[6];
24951 MFloatScratchSpace normal_scratch(nDim * 6, AT_, "normal_scratch");
24952 for(MInt i = 0; i < 6; i++)
24953 normal[i] = &normal_scratch.p[i * nDim];
24954 const MInt maxNoPyramids = 13;
24955 MFloat* pyraCentroid[maxNoPyramids];
24956 MFloatScratchSpace pyraCentroid_scratch(nDim * maxNoPyramids, AT_, "pyraCentroid_scratch");
24957 for(MInt i = 0; i < maxNoPyramids; i++)
24958 pyraCentroid[i] = &pyraCentroid_scratch.p[i * nDim];
24959 MFloatScratchSpace faceVolume_scratch(F2 * m_noDirs, AT_, "faceVolume_scratch");
24960 MFloat* faceVolume = faceVolume_scratch.getPointer();
24961 MFloatScratchSpace pyraVolume_scratch(maxNoPyramids, AT_, "pyraVolume_scratch");
24962 MFloat* pyraVolume = pyraVolume_scratch.getPointer();
24963 MFloatScratchSpace faceVolume_0_scratch(F2 * m_noDirs, AT_, "faceVolume_0_scratch");
24964 MFloat* faceVolume_0 = faceVolume_0_scratch.getPointer();
24965 MFloatScratchSpace faceVolume_00_scratch(F2 * m_noDirs, AT_, "faceVolume_00_scratch");
24966 MFloat* faceVolume_00 = faceVolume_00_scratch.getPointer();
24967 MFloat cellVolume_0;
24968 MFloatScratchSpace cellCentroid_0_scratch(nDim, AT_, "cellCentroid_0_scratch");
24969 MFloat* cellCentroid_0 = cellCentroid_0_scratch.getPointer();
24970 MFloatScratchSpace cellCentroid_00_scratch(nDim, AT_, "cellCentroid_00_scratch");
24971 MInt currentSubCase;
24972 MInt subCaseDummy;
24973 MFloat* p_0;
24974 MFloat* p_1;
24975 MFloat* p_2;
24976 MFloat* p_3;
24977 MFloat* p_4;
24978 MFloat* p_5;
24979 MFloat* p_0s;
24980 MFloat* p_1s;
24981 MFloat* p_2s;
24982 MFloat* p_3s;
24983 MFloat* p_0ss;
24984 MFloat* p_1ss;
24985 MFloat* p_2ss;
24986 MFloat* p_3ss;
24987 MFloat* p_1sss;
24988 MFloat* p_2sss;
24989 MFloat* p_3sss;
24990
24991 MInt splitCorner1 = -1;
24992 MInt splitCorner2 = -1;
24993 MInt splitCorner12 = -1;
24994 MInt splitCorner22 = -1;
24995 MInt cutDummy;
24996 MInt face1;
24997 MInt face2;
24998 MInt face3;
24999 MInt face4;
25000 MInt face5;
25001 MInt face6;
25002 MInt* facepointers[6] = {&face1, &face2, &face3, &face4, &face5, &face6};
25003 MInt cutPoints[12] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
25004 MFloatScratchSpace normalVec_c_scratch(nDim, AT_, "normalVec_c_scratch");
25005 MFloat* normalVec_c = normalVec_c_scratch.getPointer();
25006 MFloat area_c;
25007 MFloatScratchSpace coordinates_c_scratch(nDim, AT_, "coordinates_c_scratch");
25008 MFloat* coordinates_c = coordinates_c_scratch.getPointer();
25009 MFloat volume_C;
25010 MFloatScratchSpace coordinatesCell_scratch(nDim, AT_, "coordinatesCell_scratch");
25011 MFloat* coordinates_Cell = coordinatesCell_scratch.getPointer();
25012 MFloat M[3] = {0, 0, 0};
25013 MFloat dummy_1[3] = {0, 0, 0};
25014 MBool nfs_cur[6] = {false, false, false, false, false, false};
25015 MBool nfs_cur_0[6] = {false, false, false, false, false, false};
25016 MBool nfs_cur_00[6] = {false, false, false, false, false, false};
25017 MBool faceCut[6] = {false, false, false, false, false, false};
25018 MBool faceCut_0[6] = {false, false, false, false, false, false};
25019 MBool faceCut_00[6] = {false, false, false, false, false, false};
25020 MInt noFaces;
25021 MFloat absA;
25022 MFloatScratchSpace faceDiff_scratch(2 * nDim, AT_, "faceDiff_scratch");
25023 MFloat* faceDiff = faceDiff_scratch.getPointer();
25024 // MInt maxNoNodes = 1000; // might be necessary to increase for extremely detailed .stl geometries! See error
25025 // output below
25026 static constexpr MInt opposite[6] = {1, 0, 3, 2, 5, 4};
25027 MInt bndryId2 = -1, bndryId3 = -1;
25028 MInt cellId2 = -1, cellId3 = -1;
25029 MIntScratchSpace splitFace_scratch(noCells, AT_, "splitFace_scratch");
25030 MIntScratchSpace splitCell_scratch(noCells, AT_, "splitCell_scratch");
25031 MIntScratchSpace disambiguation_scratch(noCells, AT_, "disambiguation_scratch");
25032 MIntScratchSpace ambIds_scratch(noCells, AT_, "ambIds_scratch");
25033 MIntScratchSpace ambiguousCells_scratch(noCells, AT_, "ambiguousCells_scratch");
25034 MIntScratchSpace subCases_scratch(noCells, AT_, "subCases_scratch");
25035 MIntScratchSpace mcCases_scratch(noCells, AT_, "mcCases_scratch");
25036 MInt* splitFace = splitFace_scratch.getPointer();
25037 MInt* splitCell = splitCell_scratch.getPointer();
25038 MInt* disambiguation = disambiguation_scratch.getPointer();
25039 MInt* ambIds = ambIds_scratch.getPointer();
25040 MInt* ambiguousCells = ambiguousCells_scratch.getPointer();
25041 MInt* subCases = subCases_scratch.getPointer();
25042 MInt* mcCases = mcCases_scratch.getPointer();
25043 for(MInt i = 0; i < m_bndryCells->size(); i++) {
25044 ambiguousCells[i] = -1;
25045 disambiguation[i] = -1;
25046 ambIds[i] = -1;
25047 splitCell[i] = 0;
25048 splitFace[i] = 0;
25049 }
25050 MInt noSplitCells = 0;
25051 MInt noSplitFaces = 0;
25052 MInt noAmbiguousCells = 0;
25053 MInt bdAmbId;
25054 MInt faceTMP;
25055 MInt nghbrCellId;
25056 MInt nghbrBndryId;
25057 stack<MInt> ambStack;
25058 MFloatScratchSpace splitFaceVolume_scratch(2, AT_, "splitFaceVolume_scratch");
25059 MFloat* splitFaceVolume = splitFaceVolume_scratch.getPointer();
25060 MFloat* splitFaceCentroid[2];
25061 MFloatScratchSpace splitFaceCentroid_scratch(nDim * 2, AT_, "splitFaceCentroid_scratch");
25062 for(MInt i = 0; i < 2; i++)
25063 splitFaceCentroid[i] = &splitFaceCentroid_scratch.p[i * nDim];
25064 MFloat* splitFaceNormal[2];
25065 MFloatScratchSpace splitFaceNormal_scratch(nDim * 2, AT_, "splitFaceNormal_scratch");
25066 for(MInt i = 0; i < 2; i++)
25067 splitFaceNormal[i] = &splitFaceNormal_scratch.p[i * nDim];
25068 MFloatScratchSpace splitFaceVolume2_scratch(2, AT_, "splitFaceVolume2_scratch");
25069 MFloat* splitFaceVolume2 = splitFaceVolume2_scratch.getPointer();
25070 MFloat* splitFaceCentroid2[2];
25071 MFloatScratchSpace splitFaceCentroid2_scratch(nDim * 2, AT_, "splitFaceCentroid2_scratch");
25072 for(MInt i = 0; i < 2; i++)
25073 splitFaceCentroid2[i] = &splitFaceCentroid2_scratch.p[i * nDim];
25074 MFloat* splitFaceNormal2[2];
25075 MFloatScratchSpace splitFaceNormal2_scratch(nDim * 2, AT_, "splitFaceNormal2_scratch");
25076 for(MInt i = 0; i < 2; i++)
25077 splitFaceNormal2[i] = &splitFaceNormal2_scratch.p[i * nDim];
25078 MInt splitFaceId = -1;
25079 MInt splitFaceId2 = -1;
25080 MInt splitSurfaceIndexCounter = 2;
25081 MInt mcCorner;
25082 MBool keepNghbrs = true;
25083 MInt disamb_tmp = 0;
25084 MInt disambPointer[16][21];
25085 const MInt* disambPointer_dummy = nullptr;
25086 MIntScratchSpace levelSetCornerSigns(8, AT_, "levelSetCornerSigns");
25087 //--- end of initialization
25088
25089 // preprocessing of each cell
25090 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
25091 cellId = m_bndryCells->a[bndryId].m_cellId;
25092 m_bndryCells->a[bndryId].m_noSrfcs = 0;
25093 outcode_MC = 0;
25094
25095 for(MInt f = 0; f < m_noDirs; f++) {
25096 m_bndryCells->a[bndryId].m_externalFaces[f] = false;
25097 }
25098
25099 if(m_solver->c_noChildren(cellId) > 0) {
25100 continue;
25101 }
25102 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
25103 m_bndryCells->a[bndryId].m_volume = F0;
25104 continue;
25105 }
25106
25107 // 1. Determine Case/Subcase of each bndry cell
25108 // get In/Outcode of the corners of the voxel
25109 // 0 -> Corner is outside Fluid Domain
25110 // 1 -> Corner is inside Fluid Domain or on Boundary
25111 for(MInt i = 0; i < 8; i++) {
25112 for(MInt dim = 0; dim < nDim; dim++) {
25113 corner[i][dim] =
25114 m_solver->a_coordinate(cellId, dim) + cornerIndices[i][dim] * F1B2 * m_solver->c_cellLengthAtCell(cellId);
25115 }
25116 currentOutcode = !((MBool)m_solver->m_geometry->pointIsInside2(corner[i]));
25117 if(currentOutcode) outcode_MC = outcode_MC | (1 << cornersSOLVERtoMC[i]);
25118 }
25119
25120 // Determine Case and check if case is implemented
25121 currentCase = (MInt)cases[outcode_MC][0];
25122 mcCases[bndryId] = currentCase;
25123 currentSubCase = (MInt)cases[outcode_MC][1];
25124 subCases[bndryId] = currentSubCase;
25125 if(!caseStatesSTL[currentCase][0]) {
25126 cerr << "Error in createCutFaceMGC: Case not implemented: " << currentCase << endl;
25127 continue;
25128 }
25129
25130 // 2.1 Determine ambiguous cells
25131 disambiguation[bndryId] = -1;
25132 if(!caseStatesSTL[mcCases[bndryId]][1]) { // ambiguous case
25133 ambIds[bndryId] = noAmbiguousCells;
25134 ambiguousCells[noAmbiguousCells++] = bndryId;
25135 }
25136 }
25137
25138
25139 // 2.2 Prepare corner cell mapping array
25140 MIntScratchSpace cornerCellMapping_scratch(8 * noAmbiguousCells, AT_, "cornerCellMapping_scratch");
25141 MInt* cornerCellMapping = cornerCellMapping_scratch.getPointer();
25142 for(MInt i = 0; i < noAmbiguousCells; i++) {
25143 bdAmbId = ambiguousCells[i];
25144 cellId = m_bndryCells->a[bdAmbId].m_cellId;
25145 outcode_MC = 0;
25146
25147 // redetermine outcode
25148 for(MInt j = 0; j < 8; j++) {
25149 for(MInt dim = 0; dim < nDim; dim++) {
25150 corner[j][dim] = m_solver->a_coordinate(cellId, dim)
25151 + cornerIndices[j][dim] * F1B2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId));
25152 }
25153 currentOutcode = !((MBool)m_solver->m_geometry->pointIsInside2(corner[j]));
25154 if(currentOutcode) outcode_MC = outcode_MC | (1 << cornersSOLVERtoMC[j]);
25155 }
25156 for(MInt j = 0; j < 8; j++) {
25157 mcCorner = cornersSOLVERtoMC[j];
25158 if(!(outcode_MC & 1 << mcCorner))
25159 cornerCellMapping[i * 8 + j] = -1;
25160 else
25161 cornerCellMapping[i * 8 + j] = cellId;
25162 }
25163 }
25164
25165 // 3. Determine case of ambiguous cells by states of surface midpoints - new!
25166 for(MInt ambId = 0; ambId < noAmbiguousCells; ambId++) {
25167 bdAmbId = ambiguousCells[ambId];
25168 disambiguation[bdAmbId] = 0;
25169 cellId = m_bndryCells->a[bdAmbId].m_cellId;
25170 currentCase = mcCases[bdAmbId];
25171 currentSubCase = subCases[bdAmbId];
25172
25173 MInt faceMax = 0;
25174 switch(currentCase) {
25175 case 3:
25176 faceMax = 1;
25177 break;
25178 case 4:
25179 m_bndryCells->a[bdAmbId].m_noSrfcs = 2;
25180 continue;
25181 case 6:
25182 faceMax = 1;
25183 break;
25184 case 7:
25185 faceMax = 3;
25186 break;
25187 case 10:
25188 faceMax = 2;
25189 break;
25190 case 12:
25191 faceMax = 2;
25192 break;
25193 default: {
25194 stringstream errorMessage;
25195 errorMessage << " Error in FvBndryCnd3D::createCutFaceMGC: cell in ambigous cells does not have an "
25196 "ambiguous case... cellId: "
25197 << cellId << " case: " << currentCase << " bndryId: " << bdAmbId << endl;
25198 writeStlFileOfCell(cellId, "errorcell.stl");
25199 mTerm(1, AT_, errorMessage.str());
25200 }
25201 }
25202
25203 for(MInt i = 0; i < faceMax; i++) {
25204 // compute ambigous face centroid and check if it is fluid or solid. If fluid, choose connected, else choose
25205 // separated.
25206 switch(currentCase) {
25207 case 3:
25208 faceTMP = facesMCtoSOLVER[tiling3_1STL[currentSubCase][2 + i]];
25209 break;
25210
25211 case 6:
25212 faceTMP = facesMCtoSOLVER[tiling6_1STL[currentSubCase][2 + i]];
25213 break;
25214 case 7:
25215 faceTMP = facesMCtoSOLVER[tiling7_1STL[currentSubCase][3 + i]];
25216 break;
25217
25218 case 10:
25219 faceTMP = facesMCtoSOLVER[tiling10_1STL[currentSubCase][2 + i]];
25220 break;
25221
25222 case 12:
25223 faceTMP = facesMCtoSOLVER[tiling12_1STL[currentSubCase][2 + i]];
25224 break;
25225 default: {
25226 stringstream errorMessage;
25227 errorMessage << "ERROR: Switch variable 'currentCase' with value " << currentCase << " not matching any case."
25228 << endl;
25229 mTerm(1, AT_, errorMessage.str());
25230 }
25231 }
25232 nghbrCellId = m_solver->c_neighborId(cellId, faceTMP);
25233 if(nghbrCellId < 0 || !m_solver->a_hasNeighbor(cellId, faceTMP)) {
25234 stringstream errorMessage;
25235 errorMessage << " Error in FvBndryCnd3D::createCutFaceMGC: no neighbor in ambiguous direction... exiting."
25236 << endl;
25237 errorMessage << " cellId: " << cellId << ", ambiguous face: " << faceTMP << endl;
25238 writeStlFileOfCell(cellId, "errorcell.stl");
25239 mTerm(1, AT_, errorMessage.str());
25240 }
25241 // compute ambiguous face centroid
25242 for(MInt dim = 0; dim < nDim; dim++) {
25243 corner[0][dim] = (m_solver->a_coordinate(cellId, dim) + m_solver->a_coordinate(nghbrCellId, dim)) * F1B2;
25244 }
25245 currentOutcode = (MBool)m_solver->m_geometry->pointIsInside2(corner[0]);
25246
25247 // returns true if point is not located in fluid domain, false if it is located in the fluid domain
25248 if(currentOutcode) {
25249 disambiguation[bdAmbId] += IPOW2(faceMax - i - 1);
25250 }
25251 }
25252 }
25253
25254 // 3.2 Determine split cell and split surface cells & count them
25255 for(MInt ambId = 0; ambId < noAmbiguousCells; ambId++) {
25256 bdAmbId = ambiguousCells[ambId];
25257 cellId = m_bndryCells->a[bdAmbId].m_cellId;
25258 currentCase = mcCases[bdAmbId];
25259 currentSubCase = subCases[bdAmbId];
25260
25261 switch(currentCase) {
25262 case 3:
25263 if(currentSubCase < 12 && disambiguation[bdAmbId] == 1) {
25264 splitCell[bdAmbId] = true;
25265 noSplitCells++;
25266 } else if(currentSubCase >= 12 && disambiguation[bdAmbId] == 1) {
25267 splitFace[bdAmbId] = true;
25268 noSplitFaces++;
25269 }
25270 break;
25271 case 4:
25272 if(currentSubCase < 4) {
25273 splitCell[bdAmbId] = true;
25274 noSplitCells++;
25275 }
25276 break;
25277 case 6:
25278 if(currentSubCase < 24 && disambiguation[bdAmbId] == 1) {
25279 splitCell[bdAmbId] = true;
25280 noSplitCells++;
25281 } else if(currentSubCase >= 24 && disambiguation[bdAmbId] == 1) {
25282 splitFace[bdAmbId] = true;
25283 noSplitFaces++;
25284 }
25285 break;
25286 case 7:
25287 if(currentSubCase < 8) {
25288 switch(disambiguation[bdAmbId]) {
25289 case 0:
25290 // connected cell, no special cell
25291 break;
25292 case 1:
25293 case 2:
25294 case 4:
25295 splitFace[bdAmbId] = true;
25296 noSplitFaces++;
25297 break;
25298 case 3:
25299 case 5:
25300 case 6:
25301 splitCell[bdAmbId] = true;
25302 noSplitCells++;
25303 break;
25304 case 7:
25305 splitCell[bdAmbId] = true;
25306 noSplitCells++;
25307 noSplitCells++;
25308 break;
25309 default: {
25310 stringstream errorMessage;
25311 errorMessage << "ERROR: Switch variable 'disambiguation[bdAmbId]' with value " << disambiguation[bdAmbId]
25312 << " not matching any case." << endl;
25313 mTerm(1, AT_, errorMessage.str());
25314 }
25315 }
25316 } else {
25317 switch(disambiguation[bdAmbId]) {
25318 case 0:
25319 // connected cell, no special cell
25320 break;
25321 case 1:
25322 case 2:
25323 case 4:
25324 splitFace[bdAmbId] = true;
25325 noSplitFaces++;
25326 break;
25327 case 3:
25328 case 5:
25329 case 6:
25330 // Here: Check how to manage split faces for cells with 2 split faces!
25331 splitFace[bdAmbId] = true;
25332 noSplitFaces++;
25333 noSplitFaces++;
25334 break;
25335 case 7:
25336 splitCell[bdAmbId] = true;
25337 noSplitCells++;
25338 break;
25339 default: {
25340 stringstream errorMessage;
25341 errorMessage << "ERROR: Switch variable 'disambiguation[bdAmbId]' with value " << disambiguation[bdAmbId]
25342 << " not matching any case." << endl;
25343 mTerm(1, AT_, errorMessage.str());
25344 }
25345 }
25346 }
25347 break;
25348 case 10:
25349 if(disambiguation[bdAmbId] == 3) {
25350 splitCell[bdAmbId] = true;
25351 noSplitCells++;
25352 }
25353 if(disambiguation[bdAmbId] == 2 || disambiguation[bdAmbId] == 1) {
25354 stringstream errorMessage;
25355 errorMessage << " found case 10 cell with disambiguation " << disambiguation[bdAmbId] << " and cellId "
25356 << cellId << ". This means cell is a case 10.2 cell which is not implemented. Exiting..."
25357 << endl;
25358 mTerm(1, AT_, errorMessage.str());
25359 }
25360 break;
25361 case 12:
25362 if(disambiguation[bdAmbId] == 3) {
25363 splitCell[bdAmbId] = true;
25364 noSplitCells++;
25365 }
25366 if(disambiguation[bdAmbId] == 2 || disambiguation[bdAmbId] == 1) {
25367 stringstream errorMessage;
25368 errorMessage << " found case 12 cell with disambiguation " << disambiguation[bdAmbId] << " and cellId "
25369 << cellId << ". This means cell is a case 12.2 cell which is not implemented. Exiting..."
25370 << endl;
25371 mTerm(1, AT_, errorMessage.str());
25372 }
25373 break;
25374 default: {
25375 stringstream errorMessage;
25376 errorMessage << "ERROR: Switch variable 'currentCase' with value " << currentCase << " not matching any case."
25377 << endl;
25378 mTerm(1, AT_, errorMessage.str());
25379 }
25380 }
25381 }
25382
25383 // 3.3 Allocate space for split face information
25384 // index is (- m_associatedSurfaces[bndryId][face])*6 + ident for the first split surface
25385 // index is (- m_associatedSurfaces[bndryId][face])*6 + 3 + ident for the second split surface
25386 // ident = 1: srfcId in m_srfcs
25387 // ident = 2: corner left cell (in -dir)
25388 // ident = 3: corner right cell (in +dir)
25389 // indices 0 to 11 may not be used! First index to be stored in m_associatedSurfaces is -2!
25390 // split Cells: positive if cell is a split cell, link to split parent
25391 // split Cells: negative if cell is a split parent, -link to split child
25392 // split Cells: 0 if no split cell and no split parent. Check later, if cell 0 is either split cell or split parent ->
25393 // doof
25394 const MInt maxNoSplitChildrenPerCell = 3;
25395 mAlloc(m_splitSurfaces, (2 + noSplitFaces) * 2 * maxNoSplitChildrenPerCell, "m_splitSurfaces", -1, AT_);
25396 mAlloc(m_splitParents, noCells + noSplitCells, "m_splitPartents", -1, AT_);
25397 mAlloc(m_splitChildren, (noCells + noSplitCells) * maxNoSplitChildrenPerCell, "m_splitChildren", -1, AT_);
25398
25399 // 4. Compute cut cell information
25400 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
25401 noFaces = 0;
25402 cellId = m_bndryCells->a[bndryId].m_cellId;
25403 gridCellVolume = m_solver->grid().gridCellVolume(m_solver->a_level(cellId));
25404 outcode_MC = 0;
25405 volume_C = 0;
25406 coordinates_Cell[0] = 0;
25407 coordinates_Cell[1] = 0;
25408 coordinates_Cell[2] = 0;
25409
25410
25411 // store all cut points in a separate array
25412 for(MInt cutPoint = 0; cutPoint < m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints; cutPoint++) {
25413 cutPoints[m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[cutPoint]] = cutPoint;
25414 }
25415
25416 for(MInt i = 0; i < nDim; i++) {
25417 faceVolume[2 * i] = POW2(m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId)));
25418 faceVolume[2 * i + 1] = faceVolume[2 * i];
25419 for(MInt j = 0; j < 3; j++) {
25420 faceCentroid[2 * i][j] = m_solver->a_coordinate(cellId, j);
25421 faceCentroid[2 * i + 1][j] = m_solver->a_coordinate(cellId, j);
25422 }
25423 faceCentroid[2 * i][i] -= F1B2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId));
25424 faceCentroid[2 * i + 1][i] += F1B2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId));
25425 }
25426
25427 // if cell is no leaf cell do not compute it but set variables to dummy values.
25428 if(!m_solver->c_isLeafCell(cellId)) {
25429 m_bndryCells->a[bndryId].m_volume = gridCellVolume;
25430 for(MInt dim = 0; dim < 3; dim++) {
25431 m_bndryCells->a[bndryId].m_coordinates[dim] = m_solver->a_coordinate(cellId, dim);
25432 }
25433 m_bndryCells->a[bndryId].m_noSrfcs = 0;
25434 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = faceVolume[0];
25435 for(MInt dim = 0; dim < 3; dim++) {
25436 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = faceCentroid[0][dim];
25437 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = F1 / sqrt(F3);
25438 }
25439 for(MInt i = 0; i < nDim; i++) {
25440 m_bndryCells->a[bndryId].m_coordinates[i] -= m_solver->a_coordinate(cellId, i);
25441 }
25442 continue;
25443 }
25444
25445 // 1. Compute Voxel corners
25446 for(MInt i = 0; i < 8; i++) {
25447 for(MInt dim = 0; dim < nDim; dim++) {
25448 corner[i][dim] = m_solver->a_coordinate(cellId, dim)
25449 + cornerIndices[i][dim] * F1B2 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId));
25450 }
25451 }
25452 for(MInt i = 0; i < 6; i++) {
25453 faceCut[i] = false;
25454 faceCut_0[i] = false;
25455 }
25456
25457
25458 // 2. Determine Case and check if case is implemented and if case is unambiguous
25459 currentCase = mcCases[bndryId];
25460 presentCases[currentCase]++;
25461 currentSubCase = subCases[bndryId];
25462 presentSubCases[currentCase][currentSubCase]++;
25463
25464 if(!(m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints == caseCutPoints[currentCase])) {
25465 cerr << "FvBndryCnd3D::createCutFaceMGC - Error: number of cut points not correct!" << endl;
25466 cerr << "Case: " << currentCase << " cutPointsTheory: " << caseCutPoints[currentCase]
25467 << " actual Cut Points: " << m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints << endl;
25468 cerr << "Cell level: " << m_solver->a_level(cellId) << endl;
25469 stringstream fileName;
25470 fileName << cellId << ".stl";
25471 writeStlFileOfCell(cellId, (fileName.str()).c_str());
25472 cerr << "Wrote stl-file of cell. FileName: " << (fileName.str()) << endl;
25473 }
25474 if(!caseStatesSTL[currentCase][0]) {
25475 cerr << "FvBndryCnd3D::createCutFaceMGC - Error: Case not implemented: " << currentCase << endl;
25476 cerr << "Cell level: " << m_solver->a_level(cellId) << endl;
25477 stringstream fileName;
25478 fileName << cellId << ".stl";
25479 writeStlFileOfCell(cellId, (fileName.str()).c_str());
25480 cerr << "Wrote stl-file of cell. FileName: " << (fileName.str()) << endl;
25481 continue;
25482 }
25483
25484
25485 // compute cell depending on its case and disambiguation
25486 if(!caseStatesSTL[currentCase][1]) {
25487 switch(currentCase) {
25488 case 3: {
25489 for(MInt i = 0; i < 6; i++) {
25490 faceVolume_0[i] = faceVolume[i];
25491 for(MInt j = 0; j < 3; j++) {
25492 faceCentroid_0[i][j] = faceCentroid[i][j];
25493 }
25494 }
25495 cellVolume_0 = gridCellVolume;
25496 for(MInt i = 0; i < 3; i++) {
25497 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
25498 }
25499
25500
25501 if((currentSubCase < 12 && disambiguation[bndryId] == 0)
25502 || (currentSubCase >= 12 && disambiguation[bndryId] == 1)) { // case 3.2, 1 surface
25503
25504 // compute cell without correction (no split surface, convex cell), correct later if subCase >= 12 (split
25505 // surface, concave cell)
25506 m_bndryCells->a[bndryId].m_noSrfcs = 1;
25507
25508 for(MInt face = 0; face < 6; face++) {
25509 nfs_cur[face] = nfs3_2[currentSubCase][face];
25510 }
25511 noFaces = 5;
25512 p_0 = corner[cornersMCtoSOLVER[tiling3_2STL[currentSubCase][0]]];
25513 p_0s = corner[cornersMCtoSOLVER[tiling3_2STL[currentSubCase][1]]];
25514
25515 cutDummy = edgesMCtoSOLVER[tiling3_2STL[currentSubCase][2]];
25516 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25517 cutDummy = edgesMCtoSOLVER[tiling3_2STL[currentSubCase][3]];
25518 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25519 cutDummy = edgesMCtoSOLVER[tiling3_2STL[currentSubCase][4]];
25520 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25521 cutDummy = edgesMCtoSOLVER[tiling3_2STL[currentSubCase][5]];
25522 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25523 cutDummy = edgesMCtoSOLVER[tiling3_2STL[currentSubCase][6]];
25524 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25525 cutDummy = edgesMCtoSOLVER[tiling3_2STL[currentSubCase][7]];
25526 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25527 face1 = facesMCtoSOLVER[tiling3_2STL[currentSubCase][8]];
25528 face2 = facesMCtoSOLVER[tiling3_2STL[currentSubCase][9]];
25529 face3 = facesMCtoSOLVER[tiling3_2STL[currentSubCase][10]];
25530 face4 = facesMCtoSOLVER[tiling3_2STL[currentSubCase][11]];
25531 face5 = facesMCtoSOLVER[tiling3_2STL[currentSubCase][12]];
25532
25533 computeTri(p_0, p_1, p_2, &faceVolume[face1], faceCentroid[face1], normal[face1]);
25534 computeTri(p_0, p_2, p_3, &faceVolume[face2], faceCentroid[face2], normal[face2]);
25535 computeTri(p_0s, p_2s, p_3s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
25536 computeTri(p_0s, p_1s, p_2s, &faceVolume[face4], faceCentroid[face4], normal[face4]);
25537 computePoly6(p_0, p_1, p_3s, p_0s, p_1s, p_3, &faceVolume[face5], faceCentroid[face5], normal[face5]);
25538
25539 computePoly6(p_1, p_2, p_3, p_1s, p_2s, p_3s, &area_c, coordinates_c, normalVec_c);
25540
25541 maia::math::vecAvg<3>(M, p_0, p_0s, p_1, p_1s, p_2, p_2s, p_3, p_3s);
25542
25543 for(MInt i = 0; i < 5; i++) {
25544 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
25545 &pyraVolume[i], pyraCentroid[i]);
25546 }
25547 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[5], pyraCentroid[5]);
25548
25549 for(MInt i = 0; i < 6; i++) {
25550 volume_C += pyraVolume[i];
25551 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
25552 }
25553 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
25554
25555 if(currentSubCase >= 12) { // correct cell
25556
25557 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
25558 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
25559 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
25560 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
25561 p_1ss = corner[cornersMCtoSOLVER[tiling3_2STL[currentSubCase][13]]];
25562 p_2ss = corner[cornersMCtoSOLVER[tiling3_2STL[currentSubCase][14]]];
25563 splitCorner1 = cornersMCtoSOLVER[tiling3_2STL[currentSubCase][13]];
25564 splitCorner2 = cornersMCtoSOLVER[tiling3_2STL[currentSubCase][14]];
25565 computeTri(p_1s, p_1ss, p_3, &splitFaceVolume[0], splitFaceCentroid[0], splitFaceNormal[0]);
25566 computeTri(p_1, p_2ss, p_3s, &splitFaceVolume[1], splitFaceCentroid[1], splitFaceNormal[1]);
25567 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
25568
25569 correctNormal(normalVec_c);
25570 splitFaceId = face5;
25571 }
25572
25573 m_bndryCells->a[bndryId].m_volume = volume_C;
25574 // create 1 Cut face
25575 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
25576 for(MInt dim = 0; dim < 3; dim++) {
25577 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
25578 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
25579 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
25580 }
25581
25582 faceCut[face1] = true;
25583 faceCut[face2] = true;
25584 faceCut[face3] = true;
25585 faceCut[face4] = true;
25586 faceCut[face5] = true;
25587
25588 absA = F0;
25589 for(MInt i = 0; i < nDim; i++) {
25590 if(!nfs_cur[2 * i + 1]) faceVolume[2 * i + 1] = 0;
25591 if(!nfs_cur[2 * i]) faceVolume[2 * i] = 0;
25592 faceDiff[i] = faceVolume[2 * i + 1] - faceVolume[2 * i];
25593 absA += POW2(faceDiff[i]);
25594 }
25595
25596 if(currentSubCase < 12) {
25597 for(MInt i = 0; i < nDim; i++) {
25598 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i] = faceDiff[i] / sqrt(absA);
25599 }
25600 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = sqrt(absA);
25601 }
25602
25603 } else { // case 3.1 - two surfaces or split cell
25604
25605 if(currentSubCase < 12) {
25606 // split cell: add another boundary cell and a new cell:
25607 cellId2 = createSplitCell_MGC(cellId, 1);
25608 bndryId2 = m_solver->a_bndryId(cellId2);
25609 m_splitParents[bndryId2] = bndryId;
25610 m_splitChildren[bndryId * 3 + 0] = bndryId2;
25611 if(bndryId == 0)
25612 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! " << endl;
25613 m_bndryCells->a[bndryId].m_noSrfcs = 1;
25614 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
25615 } else {
25616 m_bndryCells->a[bndryId].m_noSrfcs = 2;
25617 }
25618
25619 for(MInt face = 0; face < 6; face++) {
25620 nfs_cur[face] = nfs3_1[currentSubCase][face];
25621 }
25622
25623 // 1st Pyramid + 1st cutFace
25624 subCaseDummy = tiling3_1STL[currentSubCase][0];
25625 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
25626 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
25627 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25628 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
25629 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25630 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
25631 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25632 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
25633 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
25634 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
25635
25636 faceCut[face1] = true;
25637 faceCut[face2] = true;
25638 faceCut[face3] = true;
25639
25640 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
25641 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
25642 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
25643
25644 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
25645
25646 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
25647
25648 if(currentSubCase >= 12) {
25649 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
25650 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
25651 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
25652
25653 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
25654
25655 correctNormal(normalVec_c);
25656 } else {
25657 for(MInt face = 0; face < 6; face++) {
25658 nfs_cur[face] = nfs1[subCaseDummy][face];
25659 }
25660 }
25661
25662 // create 1st Cut face and 1st cell
25663 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
25664 for(MInt dim = 0; dim < 3; dim++) {
25665 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
25666 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
25667 }
25668 m_bndryCells->a[bndryId].m_volume = volume_C;
25669 for(MInt dim = 0; dim < 3; dim++) {
25670 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
25671 }
25672
25673 if(currentSubCase >= 12) {
25674 faceVolume_0[face1] = faceVolume[face1];
25675 faceVolume_0[face2] = faceVolume[face2];
25676 faceVolume_0[face3] = faceVolume[face3];
25677 cellVolume_0 = volume_C;
25678 for(MInt i = 0; i < 3; i++) {
25679 cellCentroid_0[i] = coordinates_Cell[i];
25680 faceCentroid_0[face1][i] = faceCentroid[face1][i];
25681 faceCentroid_0[face2][i] = faceCentroid[face2][i];
25682 faceCentroid_0[face3][i] = faceCentroid[face3][i];
25683 }
25684 }
25685
25686 // 2nd Pyramid + 2nd cutFace
25687 subCaseDummy = tiling3_1STL[currentSubCase][1];
25688 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
25689 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
25690 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25691 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
25692 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25693 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
25694 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25695 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
25696 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
25697 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
25698
25699 if(currentSubCase < 12) {
25700 for(MInt face = 0; face < 6; face++) {
25701 nfs_cur_0[face] = nfs1[subCaseDummy][face];
25702 }
25703
25704 faceCut_0[face1] = true;
25705 faceCut_0[face2] = true;
25706 faceCut_0[face3] = true;
25707
25708 computeTri(p_0, p_1, p_3, &faceVolume_0[face1], faceCentroid_0[face1]);
25709 computeTri(p_0, p_3, p_2, &faceVolume_0[face2], faceCentroid_0[face2]);
25710 computeTri(p_0, p_2, p_1, &faceVolume_0[face3], faceCentroid_0[face3]);
25711
25712 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
25713
25714 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
25715
25716 // create 2nd Cut face & cell
25717 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
25718 for(MInt dim = 0; dim < 3; dim++) {
25719 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
25720 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
25721 }
25722
25723 m_bndryCells->a[bndryId2].m_volume = volume_C;
25724 for(MInt dim = 0; dim < 3; dim++) {
25725 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
25726 }
25727
25728 // fill ambiguous corners array
25729 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]] = cellId2;
25730
25731 } else {
25732 faceCut[face1] = true;
25733 faceCut[face2] = true;
25734 faceCut[face3] = true;
25735
25736 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
25737 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
25738 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
25739
25740 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
25741
25742 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
25743
25744 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
25745 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
25746 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
25747
25748 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
25749
25750 correctNormal(normalVec_c);
25751
25752 // create 2nd Cut face
25753 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
25754 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
25755 for(MInt dim = 0; dim < 3; dim++) {
25756 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
25757 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
25758 }
25759
25760 m_bndryCells->a[bndryId].m_volume = volume_C;
25761 for(MInt dim = 0; dim < 3; dim++) {
25762 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
25763 }
25764 }
25765 }
25766 break;
25767 }
25768 case 4: {
25769 for(MInt i = 0; i < 6; i++) {
25770 faceVolume_0[i] = faceVolume[i];
25771 for(MInt j = 0; j < 3; j++) {
25772 faceCentroid_0[i][j] = faceCentroid[i][j];
25773 }
25774 }
25775 cellVolume_0 = gridCellVolume;
25776 for(MInt i = 0; i < 3; i++) {
25777 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
25778 }
25779
25780 // cerr << "Case 4.1 detected. Starting Cutface computation..." << endl;
25781 if(currentSubCase < 4) {
25782 // split cell: add another boundary cell and a new cell:
25783 cellId2 = createSplitCell_MGC(cellId, 1);
25784 bndryId2 = m_solver->a_bndryId(cellId2);
25785 m_splitParents[bndryId2] = bndryId;
25786 m_splitChildren[bndryId * 3 + 0] = bndryId2;
25787 if(bndryId == 0)
25788 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! " << endl;
25789
25790 // compute first cell:
25791 m_bndryCells->a[bndryId].m_noSrfcs = 1;
25792
25793 // first cell is a pyramid - case 1:
25794 subCaseDummy = tiling4_1STL[currentSubCase][0];
25795 for(MInt face = 0; face < 6; face++) {
25796 nfs_cur[face] = nfs1[subCaseDummy][face];
25797 }
25798 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
25799 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
25800 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25801 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
25802 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25803 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
25804 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25805 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
25806 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
25807 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
25808
25809 faceCut[face1] = true;
25810 faceCut[face2] = true;
25811 faceCut[face3] = true;
25812
25813 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
25814 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
25815 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
25816
25817 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
25818
25819 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
25820
25821 m_bndryCells->a[bndryId].m_volume = volume_C;
25822 for(MInt dim = 0; dim < 3; dim++) {
25823 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
25824 }
25825
25826 // create 1st Cut face
25827 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
25828 for(MInt dim = 0; dim < 3; dim++) {
25829 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
25830 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
25831 }
25832
25833 // compute 2nd cell:
25834
25835 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
25836
25837 subCaseDummy = tiling4_1STL[currentSubCase][1];
25838 for(MInt face = 0; face < 6; face++) {
25839 nfs_cur_0[face] = nfs1[subCaseDummy][face];
25840 }
25841 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
25842 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
25843 p_1 = m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25844 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
25845 p_2 = m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25846 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
25847 p_3 = m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25848 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
25849 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
25850 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
25851
25852 faceCut_0[face1] = true;
25853 faceCut_0[face2] = true;
25854 faceCut_0[face3] = true;
25855
25856 computeTri(p_0, p_1, p_3, &faceVolume_0[face1], faceCentroid_0[face1]);
25857 computeTri(p_0, p_3, p_2, &faceVolume_0[face2], faceCentroid_0[face2]);
25858 computeTri(p_0, p_2, p_1, &faceVolume_0[face3], faceCentroid_0[face3]);
25859
25860 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
25861
25862 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
25863
25864 m_bndryCells->a[bndryId2].m_volume = volume_C;
25865 for(MInt dim = 0; dim < 3; dim++) {
25866 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
25867 }
25868
25869 // create 2nd Cut face
25870 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
25871 for(MInt dim = 0; dim < 3; dim++) {
25872 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
25873 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
25874 }
25875
25876 // fill ambiguous corners array
25877 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]] = cellId2;
25878
25879 } else {
25880 m_bndryCells->a[bndryId].m_noSrfcs = 2;
25881 for(MInt face = 0; face < 6; face++) {
25882 nfs_cur[face] = nfs4_1[currentSubCase][face];
25883 }
25884 // 1st Pyramid + 1st cutFace
25885 subCaseDummy = tiling4_1STL[currentSubCase][0];
25886 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
25887 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
25888 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25889 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
25890 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25891 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
25892 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25893 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
25894 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
25895 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
25896
25897 faceCut[face1] = true;
25898 faceCut[face2] = true;
25899 faceCut[face3] = true;
25900
25901 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
25902 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
25903 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
25904
25905 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
25906
25907 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
25908
25909 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
25910 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
25911 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
25912
25913 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
25914
25915 correctNormal(normalVec_c);
25916
25917 // create 1st Cut face
25918 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
25919 for(MInt dim = 0; dim < 3; dim++) {
25920 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
25921 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
25922 }
25923
25924 faceVolume_0[face1] = faceVolume[face1];
25925 faceVolume_0[face2] = faceVolume[face2];
25926 faceVolume_0[face3] = faceVolume[face3];
25927 cellVolume_0 = volume_C;
25928 for(MInt i = 0; i < 3; i++) {
25929 cellCentroid_0[i] = coordinates_Cell[i];
25930 faceCentroid_0[face1][i] = faceCentroid[face1][i];
25931 faceCentroid_0[face2][i] = faceCentroid[face2][i];
25932 faceCentroid_0[face3][i] = faceCentroid[face3][i];
25933 }
25934
25935 // 2nd Pyramid + 2nd cutFace
25936 subCaseDummy = tiling4_1STL[currentSubCase][1];
25937 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
25938 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
25939 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25940 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
25941 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25942 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
25943 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
25944 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
25945 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
25946 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
25947
25948 faceCut[face1] = true;
25949 faceCut[face2] = true;
25950 faceCut[face3] = true;
25951
25952 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
25953 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
25954 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
25955
25956 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
25957
25958 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
25959
25960 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
25961 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
25962 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
25963
25964 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
25965
25966 correctNormal(normalVec_c);
25967
25968 // create 2nd Cut face
25969 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
25970 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
25971 for(MInt dim = 0; dim < 3; dim++) {
25972 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
25973 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
25974 }
25975
25976 m_bndryCells->a[bndryId].m_volume = volume_C;
25977 for(MInt dim = 0; dim < 3; dim++) {
25978 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
25979 }
25980 }
25981 break;
25982 }
25983 case 6: {
25984 for(MInt i = 0; i < 6; i++) {
25985 faceVolume_0[i] = faceVolume[i];
25986 for(MInt j = 0; j < 3; j++) {
25987 faceCentroid_0[i][j] = faceCentroid[i][j];
25988 }
25989 }
25990 cellVolume_0 = gridCellVolume;
25991 for(MInt i = 0; i < 3; i++) {
25992 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
25993 }
25994 if((currentSubCase < 24 && disambiguation[bndryId] == 1)
25995 || (currentSubCase >= 24 && disambiguation[bndryId] == 0)) {
25996 // case 6.1 - 2 surfaces or split cell
25997
25998 if(currentSubCase < 24) {
25999 // split cell: add another boundary cell and a new cell:
26000 cellId2 = createSplitCell_MGC(cellId, 1);
26001 bndryId2 = m_solver->a_bndryId(cellId2);
26002 m_splitParents[bndryId2] = bndryId;
26003 m_splitChildren[bndryId * 3 + 0] = bndryId2;
26004 if(bndryId == 0)
26005 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! " << endl;
26006 m_bndryCells->a[bndryId].m_noSrfcs = 1;
26007 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
26008 } else {
26009 m_bndryCells->a[bndryId].m_noSrfcs = 2;
26010 }
26011
26012 for(MInt face = 0; face < 6; face++) {
26013 nfs_cur[face] = nfs6_1[currentSubCase][face];
26014 }
26015
26016 // 1st prism & 1st cutFace
26017 subCaseDummy = tiling6_1STL[currentSubCase][0];
26018 p_0 = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][0]]];
26019 p_0s = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][1]]];
26020 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][2]];
26021 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26022 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][3]];
26023 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26024 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][4]];
26025 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26026 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][5]];
26027 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26028 face1 = facesMCtoSOLVER[tiling2STL[subCaseDummy][6]];
26029 face2 = facesMCtoSOLVER[tiling2STL[subCaseDummy][7]];
26030 face3 = facesMCtoSOLVER[tiling2STL[subCaseDummy][8]];
26031 face4 = facesMCtoSOLVER[tiling2STL[subCaseDummy][9]];
26032
26033 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2], normal[face2]);
26034 computeTri(p_0s, p_3s, p_2s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
26035 computeTrapez(p_0, p_0s, p_3s, p_3, &faceVolume[face1], faceCentroid[face1], normal[face1]);
26036 computeTrapez(p_2, p_2s, p_0s, p_0, &faceVolume[face4], faceCentroid[face4], normal[face4]);
26037
26038 computePoly4(p_3, p_3s, p_2s, p_2, &area_c, coordinates_c, normalVec_c);
26039
26040 maia::math::vecAvg<3>(M, p_0, p_0s, p_2, p_2s, p_3, p_3s);
26041
26042 for(MInt i = 0; i < 4; i++) {
26043 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
26044 &pyraVolume[i], pyraCentroid[i]);
26045 }
26046 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[4], pyraCentroid[4]);
26047 for(MInt i = 0; i < 5; i++) {
26048 volume_C += pyraVolume[i];
26049 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26050 }
26051 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26052
26053 if(currentSubCase >= 24) {
26054 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26055 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
26056 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
26057 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
26058
26059 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
26060
26061 correctNormal(normalVec_c);
26062 } else {
26063 for(MInt face = 0; face < 6; face++) {
26064 nfs_cur[face] = nfs2[subCaseDummy][face];
26065 }
26066 }
26067
26068 faceCut[face1] = true;
26069 faceCut[face2] = true;
26070 faceCut[face3] = true;
26071 faceCut[face4] = true;
26072
26073 // create 1st Cut face & 1st cut cell
26074 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
26075 for(MInt dim = 0; dim < 3; dim++) {
26076 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26077 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26078 }
26079 m_bndryCells->a[bndryId].m_volume = volume_C;
26080 for(MInt dim = 0; dim < 3; dim++) {
26081 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26082 }
26083
26084 if(currentSubCase >= 24) {
26085 faceVolume_0[face1] = faceVolume[face1];
26086 faceVolume_0[face2] = faceVolume[face2];
26087 faceVolume_0[face3] = faceVolume[face3];
26088 faceVolume_0[face4] = faceVolume[face4];
26089 cellVolume_0 = volume_C;
26090 volume_C = 0;
26091 for(MInt i = 0; i < 3; i++) {
26092 cellCentroid_0[i] = coordinates_Cell[i];
26093 faceCentroid_0[face1][i] = faceCentroid[face1][i];
26094 faceCentroid_0[face2][i] = faceCentroid[face2][i];
26095 faceCentroid_0[face3][i] = faceCentroid[face3][i];
26096 faceCentroid_0[face4][i] = faceCentroid[face4][i];
26097 coordinates_Cell[i] = 0;
26098 }
26099 }
26100
26101 // 2nd Pyramid + 2nd cutFace
26102 subCaseDummy = tiling6_1STL[currentSubCase][1];
26103 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
26104 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
26105 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26106 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
26107 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26108 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
26109 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26110 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
26111 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
26112 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
26113
26114 if(currentSubCase < 24) {
26115 for(MInt face = 0; face < 6; face++) {
26116 nfs_cur_0[face] = nfs1[subCaseDummy][face];
26117 }
26118
26119 faceCut_0[face1] = true;
26120 faceCut_0[face2] = true;
26121 faceCut_0[face3] = true;
26122
26123 computeTri(p_0, p_1, p_3, &faceVolume_0[face1], faceCentroid_0[face1]);
26124 computeTri(p_0, p_3, p_2, &faceVolume_0[face2], faceCentroid_0[face2]);
26125 computeTri(p_0, p_2, p_1, &faceVolume_0[face3], faceCentroid_0[face3]);
26126
26127 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
26128
26129 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
26130
26131 // create 2nd Cut face & cell
26132 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
26133 for(MInt dim = 0; dim < 3; dim++) {
26134 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26135 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26136 }
26137
26138 m_bndryCells->a[bndryId2].m_volume = volume_C;
26139 for(MInt dim = 0; dim < 3; dim++) {
26140 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
26141 }
26142
26143 // fill ambiguous corners array
26144 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]] = cellId2;
26145 } else {
26146 faceCut[face1] = true;
26147 faceCut[face2] = true;
26148 faceCut[face3] = true;
26149
26150 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
26151 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
26152 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
26153
26154 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
26155
26156 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
26157
26158 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26159 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
26160 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
26161
26162 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
26163
26164 correctNormal(normalVec_c);
26165
26166 // create 2nd Cut face
26167 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
26168 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
26169 for(MInt dim = 0; dim < 3; dim++) {
26170 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
26171 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
26172 }
26173
26174 m_bndryCells->a[bndryId].m_volume = volume_C;
26175 for(MInt dim = 0; dim < 3; dim++) {
26176 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26177 }
26178 }
26179
26180 } else {
26181 // case 6.2 - 1 surface (computed as 3 connected surfaces)
26182
26183 // compute cell without correction (no split surface, convex cell), correct later if subCase >=24 (split
26184 // surface, concave cell)
26185 m_bndryCells->a[bndryId].m_noSrfcs = 3;
26186
26187 for(MInt face = 0; face < 6; face++) {
26188 nfs_cur[face] = nfs6_1[currentSubCase][face];
26189 }
26190 p_0 = corner[cornersMCtoSOLVER[tiling6_2STL[currentSubCase][0]]];
26191 p_1 = corner[cornersMCtoSOLVER[tiling6_2STL[currentSubCase][1]]];
26192 p_2 = corner[cornersMCtoSOLVER[tiling6_2STL[currentSubCase][2]]];
26193 p_4 = corner[cornersMCtoSOLVER[tiling6_2STL[currentSubCase][3]]];
26194 p_5 = corner[cornersMCtoSOLVER[tiling6_2STL[currentSubCase][4]]];
26195
26196 cutDummy = edgesMCtoSOLVER[tiling6_2STL[currentSubCase][5]];
26197 p_0s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26198 cutDummy = edgesMCtoSOLVER[tiling6_2STL[currentSubCase][6]];
26199 p_0ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26200 cutDummy = edgesMCtoSOLVER[tiling6_2STL[currentSubCase][7]];
26201 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26202 cutDummy = edgesMCtoSOLVER[tiling6_2STL[currentSubCase][8]];
26203 p_1ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26204 cutDummy = edgesMCtoSOLVER[tiling6_2STL[currentSubCase][9]];
26205 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26206 cutDummy = edgesMCtoSOLVER[tiling6_2STL[currentSubCase][10]];
26207 p_2ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26208 cutDummy = edgesMCtoSOLVER[tiling6_2STL[currentSubCase][11]];
26209 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26210 face1 = facesMCtoSOLVER[tiling6_2STL[currentSubCase][12]];
26211 face2 = facesMCtoSOLVER[tiling6_2STL[currentSubCase][13]];
26212 face3 = facesMCtoSOLVER[tiling6_2STL[currentSubCase][14]];
26213 face4 = facesMCtoSOLVER[tiling6_2STL[currentSubCase][15]];
26214 face5 = facesMCtoSOLVER[tiling6_2STL[currentSubCase][16]];
26215 face6 = facesMCtoSOLVER[tiling6_2STL[currentSubCase][17]];
26216
26217 computePoly6(p_1, p_1s, p_2s, p_2, p_2ss, p_1ss, &faceVolume[face1], faceCentroid[face1], normal[face1]);
26218 computeTrapez(p_0, p_1, p_1s, p_0s, &faceVolume[face2], faceCentroid[face2], normal[face2]);
26219 computeTrapez(p_0, p_1, p_1ss, p_0ss, &faceVolume[face3], faceCentroid[face3], normal[face3]);
26220 computeTri(p_2, p_3, p_2ss, &faceVolume[face4], faceCentroid[face4], normal[face4]);
26221 computeTri(p_2s, p_2, p_3, &faceVolume[face5], faceCentroid[face5], normal[face5]);
26222 computeTri(p_0, p_0s, p_0ss, &faceVolume[face6], faceCentroid[face6], normal[face6]);
26223
26224 maia::math::vecAvg<3>(M, p_0s, p_0ss, p_1s, p_1ss, p_2s, p_2ss, p_3, p_0, p_1, p_2);
26225
26226 for(MInt i = 0; i < 6; i++) {
26227 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
26228 &pyraVolume[i], pyraCentroid[i]);
26229 }
26230 // 1st cut surface
26231 computePoly4(p_0s, p_3, p_2s, p_1s, &area_c, coordinates_c, normalVec_c);
26232 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[6], pyraCentroid[6]);
26233 if(currentSubCase >= 24) correctNormal(normalVec_c);
26234 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
26235 for(MInt dim = 0; dim < 3; dim++) {
26236 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26237 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26238 }
26239 // 2nd cut surface
26240 computePoly4(p_0ss, p_1ss, p_2ss, p_3, &area_c, coordinates_c, normalVec_c);
26241 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[7], pyraCentroid[7]);
26242 if(currentSubCase >= 24) correctNormal(normalVec_c);
26243 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
26244 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
26245 for(MInt dim = 0; dim < 3; dim++) {
26246 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
26247 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
26248 }
26249 // 3rd cut surface
26250 computePoly3(p_0s, p_0ss, p_3, &area_c, coordinates_c, normalVec_c);
26251 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[8], pyraCentroid[8]);
26252 if(currentSubCase >= 24) correctNormal(normalVec_c);
26253 m_bndryCells->a[bndryId].m_srfcs[2]->m_area = area_c;
26254 m_bndryCells->a[bndryId].m_srfcs[2]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
26255 for(MInt dim = 0; dim < 3; dim++) {
26256 m_bndryCells->a[bndryId].m_srfcs[2]->m_coordinates[dim] = coordinates_c[dim];
26257 m_bndryCells->a[bndryId].m_srfcs[2]->m_normalVector[dim] = normalVec_c[dim];
26258 }
26259
26260 for(MInt i = 0; i < 9; i++) {
26261 volume_C += pyraVolume[i];
26262 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26263 }
26264 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26265
26266 if(currentSubCase >= 24) { // cell with split surface
26267
26268 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
26269 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
26270 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
26271 correctFace(&faceVolume[face5], faceCentroid[face5], &faceVolume_0[face5], faceCentroid_0[face5]);
26272 correctFace(&faceVolume[face6], faceCentroid[face6], &faceVolume_0[face6], faceCentroid_0[face6]);
26273 splitCorner1 = cornersMCtoSOLVER[tiling6_2STL[currentSubCase][3]];
26274 splitCorner2 = cornersMCtoSOLVER[tiling6_2STL[currentSubCase][4]];
26275 computeTri(p_4, p_2s, p_1s, &splitFaceVolume[0], splitFaceCentroid[0], splitFaceNormal[0]);
26276 computeTri(p_5, p_1ss, p_2ss, &splitFaceVolume[1], splitFaceCentroid[1], splitFaceNormal[1]);
26277
26278 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
26279
26280 splitFaceId = face1;
26281 }
26282
26283 m_bndryCells->a[bndryId].m_volume = volume_C;
26284 for(MInt dim = 0; dim < 3; dim++) {
26285 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26286 }
26287
26288 faceCut[face1] = true;
26289 faceCut[face2] = true;
26290 faceCut[face3] = true;
26291 faceCut[face4] = true;
26292 faceCut[face5] = true;
26293 faceCut[face6] = true;
26294 }
26295
26296 break;
26297 }
26298 case 7: {
26299 disamb_tmp = disambiguation[bndryId];
26300 if(currentSubCase >= 8) disamb_tmp = 7 - disamb_tmp;
26301
26302 switch(disamb_tmp) {
26303 case 0: {
26304 // compute case 7.4.1
26305
26306 for(MInt i = 0; i < 6; i++) {
26307 faceVolume_0[i] = faceVolume[i];
26308 for(MInt j = 0; j < 3; j++) {
26309 faceCentroid_0[i][j] = faceCentroid[i][j];
26310 }
26311 }
26312 cellVolume_0 = gridCellVolume;
26313 for(MInt i = 0; i < 3; i++) {
26314 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
26315 }
26316
26317 if(currentSubCase >= 8) {
26318 // split cell: add another boundary cell and a new cell:
26319 cellId2 = createSplitCell_MGC(cellId, 1);
26320 bndryId2 = m_solver->a_bndryId(cellId2);
26321 m_splitParents[bndryId2] = bndryId;
26322 m_splitChildren[bndryId * 3 + 0] = bndryId2;
26323 if(bndryId == 0)
26324 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! "
26325 << endl;
26326 m_bndryCells->a[bndryId].m_noSrfcs = 1;
26327 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
26328 } else {
26329 m_bndryCells->a[bndryId].m_noSrfcs = 2;
26330 }
26331
26332 for(MInt face = 0; face < 6; face++) {
26333 nfs_cur[face] = nfs7_1[currentSubCase][face];
26334 }
26335
26336 // 1st Pyramid + 1st cutFace
26337 subCaseDummy = tiling7_4_1STL[currentSubCase][0];
26338 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
26339 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
26340 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26341 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
26342 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26343 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
26344 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26345 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
26346 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
26347 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
26348
26349 faceCut[face1] = true;
26350 faceCut[face2] = true;
26351 faceCut[face3] = true;
26352
26353 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
26354 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
26355 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
26356
26357 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
26358
26359 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
26360
26361 if(currentSubCase < 8) {
26362 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26363 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
26364 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
26365
26366 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
26367
26368 correctNormal(normalVec_c);
26369 } else {
26370 for(MInt face = 0; face < 6; face++) {
26371 nfs_cur[face] = nfs1[subCaseDummy][face];
26372 }
26373 }
26374
26375 // create 1st Cut face and 1st cell
26376 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
26377 for(MInt dim = 0; dim < 3; dim++) {
26378 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26379 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26380 }
26381 m_bndryCells->a[bndryId].m_volume = volume_C;
26382 for(MInt dim = 0; dim < 3; dim++) {
26383 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26384 }
26385
26386 if(currentSubCase < 8) {
26387 faceVolume_0[face1] = faceVolume[face1];
26388 faceVolume_0[face2] = faceVolume[face2];
26389 faceVolume_0[face3] = faceVolume[face3];
26390 cellVolume_0 = volume_C;
26391 volume_C = 0;
26392 for(MInt i = 0; i < 3; i++) {
26393 cellCentroid_0[i] = coordinates_Cell[i];
26394 faceCentroid_0[face1][i] = faceCentroid[face1][i];
26395 faceCentroid_0[face2][i] = faceCentroid[face2][i];
26396 faceCentroid_0[face3][i] = faceCentroid[face3][i];
26397 coordinates_Cell[i] = 0;
26398 }
26399 } else {
26400 volume_C = 0;
26401 for(MInt i = 0; i < 3; i++) {
26402 coordinates_Cell[i] = 0;
26403 }
26404 }
26405
26406 // create 2nd part of cell
26407 subCaseDummy = tiling7_4_1STL[currentSubCase][1];
26408 noFaces = 6;
26409 p_0 = corner[cornersMCtoSOLVER[tiling9STL[subCaseDummy][0]]];
26410 p_1 = corner[cornersMCtoSOLVER[tiling9STL[subCaseDummy][1]]];
26411 p_2 = corner[cornersMCtoSOLVER[tiling9STL[subCaseDummy][2]]];
26412 p_3 = corner[cornersMCtoSOLVER[tiling9STL[subCaseDummy][3]]];
26413
26414 cutDummy = edgesMCtoSOLVER[tiling9STL[subCaseDummy][4]];
26415 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26416 cutDummy = edgesMCtoSOLVER[tiling9STL[subCaseDummy][5]];
26417 p_1ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26418 cutDummy = edgesMCtoSOLVER[tiling9STL[subCaseDummy][6]];
26419 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26420 cutDummy = edgesMCtoSOLVER[tiling9STL[subCaseDummy][7]];
26421 p_2ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26422 cutDummy = edgesMCtoSOLVER[tiling9STL[subCaseDummy][8]];
26423 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26424 cutDummy = edgesMCtoSOLVER[tiling9STL[subCaseDummy][9]];
26425 p_3ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26426 face1 = facesMCtoSOLVER[tiling9STL[subCaseDummy][10]];
26427 face2 = facesMCtoSOLVER[tiling9STL[subCaseDummy][11]];
26428 face3 = facesMCtoSOLVER[tiling9STL[subCaseDummy][12]];
26429 face4 = facesMCtoSOLVER[tiling9STL[subCaseDummy][13]];
26430 face5 = facesMCtoSOLVER[tiling9STL[subCaseDummy][14]];
26431 face6 = facesMCtoSOLVER[tiling9STL[subCaseDummy][15]];
26432
26433 if(currentSubCase >= 8) {
26434 for(MInt face = 0; face < 6; face++) {
26435 nfs_cur_0[face] = nfs9[subCaseDummy][face];
26436 faceCut_0[face] = true;
26437 }
26438
26439 computePoly5(p_0, p_3, p_3ss, p_2s, p_2, &faceVolume_0[face1], faceCentroid_0[face1], normal[face1]);
26440 computePoly5(p_0, p_1, p_1ss, p_3s, p_3, &faceVolume_0[face3], faceCentroid_0[face3], normal[face3]);
26441 computePoly5(p_0, p_2, p_2ss, p_1s, p_1, &faceVolume_0[face5], faceCentroid_0[face5], normal[face5]);
26442 computeTri(p_1, p_1s, p_1ss, &faceVolume_0[face2], faceCentroid_0[face2], normal[face2]);
26443 computeTri(p_2, p_2s, p_2ss, &faceVolume_0[face4], faceCentroid_0[face4], normal[face4]);
26444 computeTri(p_3, p_3s, p_3ss, &faceVolume_0[face6], faceCentroid_0[face6], normal[face6]);
26445
26446 computePoly6(p_1ss, p_1s, p_2ss, p_2s, p_3ss, p_3s, &area_c, coordinates_c, normalVec_c);
26447
26448 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_3, p_1s, p_2s, p_3s, p_1ss, p_2ss, p_3ss);
26449
26450 for(MInt i = 0; i < 6; i++) {
26451 computePyra(&faceVolume_0[*facepointers[i]], faceCentroid_0[*facepointers[i]],
26452 normal[*facepointers[i]], M, &pyraVolume[i], pyraCentroid[i]);
26453 }
26454 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[6], pyraCentroid[6]);
26455 for(MInt i = 0; i < 7; i++) {
26456 volume_C += pyraVolume[i];
26457 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26458 }
26459 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26460
26461 // create 2nd Cut face & cell
26462 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
26463 for(MInt dim = 0; dim < 3; dim++) {
26464 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26465 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26466 }
26467
26468 m_bndryCells->a[bndryId2].m_volume = volume_C;
26469 for(MInt dim = 0; dim < 3; dim++) {
26470 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
26471 }
26472
26473 // fill ambiguous corners array
26474 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling9STL[subCaseDummy][0]]] = cellId2;
26475 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling9STL[subCaseDummy][1]]] = cellId2;
26476 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling9STL[subCaseDummy][2]]] = cellId2;
26477 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling9STL[subCaseDummy][3]]] = cellId2;
26478
26479 } else {
26480 for(MInt face = 0; face < 6; face++) {
26481 faceCut[face] = true;
26482 }
26483
26484 computePoly5(p_0, p_3, p_3ss, p_2s, p_2, &faceVolume[face1], faceCentroid[face1], normal[face1]);
26485 computePoly5(p_0, p_1, p_1ss, p_3s, p_3, &faceVolume[face3], faceCentroid[face3], normal[face3]);
26486 computePoly5(p_0, p_2, p_2ss, p_1s, p_1, &faceVolume[face5], faceCentroid[face5], normal[face5]);
26487 computeTri(p_1, p_1s, p_1ss, &faceVolume[face2], faceCentroid[face2], normal[face2]);
26488 computeTri(p_2, p_2s, p_2ss, &faceVolume[face4], faceCentroid[face4], normal[face4]);
26489 computeTri(p_3, p_3s, p_3ss, &faceVolume[face6], faceCentroid[face6], normal[face6]);
26490
26491 computePoly6(p_1ss, p_1s, p_2ss, p_2s, p_3ss, p_3s, &area_c, coordinates_c, normalVec_c);
26492
26493 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_3, p_1s, p_2s, p_3s, p_1ss, p_2ss, p_3ss);
26494
26495 for(MInt i = 0; i < 6; i++) {
26496 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]],
26497 M, &pyraVolume[i], pyraCentroid[i]);
26498 }
26499 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[6], pyraCentroid[6]);
26500 for(MInt i = 0; i < 7; i++) {
26501 volume_C += pyraVolume[i];
26502 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26503 }
26504 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26505
26506 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26507 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
26508 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
26509 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
26510 correctFace(&faceVolume[face5], faceCentroid[face5], &faceVolume_0[face5], faceCentroid_0[face5]);
26511 correctFace(&faceVolume[face6], faceCentroid[face6], &faceVolume_0[face6], faceCentroid_0[face6]);
26512
26513 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
26514
26515 correctNormal(normalVec_c);
26516
26517 // create 2nd Cut face
26518 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
26519 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
26520 for(MInt dim = 0; dim < 3; dim++) {
26521 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
26522 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
26523 }
26524
26525 m_bndryCells->a[bndryId].m_volume = volume_C;
26526 for(MInt dim = 0; dim < 3; dim++) {
26527 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26528 }
26529 }
26530
26531 break;
26532 }
26533 case 1:
26534 case 2:
26535 case 4: {
26536 for(MInt i = 0; i < 6; i++) {
26537 faceVolume_0[i] = faceVolume[i];
26538 faceVolume_00[i] = faceVolume[i];
26539 for(MInt j = 0; j < 3; j++) {
26540 faceCentroid_0[i][j] = faceCentroid[i][j];
26541 }
26542 }
26543 cellVolume_0 = gridCellVolume;
26544 for(MInt i = 0; i < 3; i++) {
26545 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
26546 }
26547
26548 for(MInt face = 0; face < 6; face++) {
26549 nfs_cur[face] = nfs7_1[currentSubCase][face];
26550 }
26551
26552 if(disamb_tmp == 1) disambPointer_dummy = &tiling7_3_1STL[0][0];
26553 if(disamb_tmp == 2) disambPointer_dummy = &tiling7_3_2STL[0][0];
26554 if(disamb_tmp == 4) disambPointer_dummy = &tiling7_3_4STL[0][0];
26555
26556 for(MInt i = 0; i < 16; i++)
26557 for(MInt j = 0; j < 21; j++)
26558 disambPointer[i][j] = disambPointer_dummy[i * 21 + j];
26559
26560 p_0 = corner[cornersMCtoSOLVER[disambPointer[currentSubCase][0]]];
26561 p_1 = corner[cornersMCtoSOLVER[disambPointer[currentSubCase][1]]];
26562 p_2 = corner[cornersMCtoSOLVER[disambPointer[currentSubCase][2]]];
26563 p_3 = corner[cornersMCtoSOLVER[disambPointer[currentSubCase][3]]];
26564 p_4 = corner[cornersMCtoSOLVER[disambPointer[currentSubCase][4]]];
26565 p_5 = corner[cornersMCtoSOLVER[disambPointer[currentSubCase][5]]];
26566 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][6]];
26567 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26568 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][7]];
26569 p_1ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26570 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][8]];
26571 p_1sss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26572 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][9]];
26573 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26574 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][10]];
26575 p_2ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26576 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][11]];
26577 p_2sss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26578 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][12]];
26579 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26580 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][13]];
26581 p_3ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26582 cutDummy = edgesMCtoSOLVER[disambPointer[currentSubCase][14]];
26583 p_3sss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26584
26585 face1 = facesMCtoSOLVER[disambPointer[currentSubCase][15]];
26586 face2 = facesMCtoSOLVER[disambPointer[currentSubCase][16]];
26587 face3 = facesMCtoSOLVER[disambPointer[currentSubCase][17]];
26588 face4 = facesMCtoSOLVER[disambPointer[currentSubCase][18]];
26589 face5 = facesMCtoSOLVER[disambPointer[currentSubCase][19]];
26590 face6 = facesMCtoSOLVER[disambPointer[currentSubCase][20]];
26591 if(currentSubCase < 8) {
26592 // case 7.3 - 2 surfaces
26593 m_bndryCells->a[bndryId].m_noSrfcs = 2;
26594
26595 // case 7.3 - 1 surface (computed as 2 connected surfaces)
26596 computePoly6(p_1, p_1sss, p_3sss, p_3, p_3s, p_1ss, &faceVolume[face2], faceCentroid[face2],
26597 normal[face2]);
26598 computePoly6(p_1, p_1s, p_2ss, p_2, p_2sss, p_1sss, &faceVolume[face3], faceCentroid[face3],
26599 normal[face3]);
26600 computeTri(p_1, p_1ss, p_1s, &faceVolume[face4], faceCentroid[face4], normal[face4]);
26601 computeTri(p_2, p_2ss, p_2s, &faceVolume[face5], faceCentroid[face5], normal[face5]);
26602 computeTri(p_3, p_3ss, p_3s, &faceVolume[face6], faceCentroid[face6], normal[face6]);
26603 splitCorner1 = cornersMCtoSOLVER[disambPointer[currentSubCase][3]];
26604 splitCorner2 = cornersMCtoSOLVER[disambPointer[currentSubCase][2]];
26605 computeTri(p_3, p_3sss, p_3ss, &splitFaceVolume[0], splitFaceCentroid[0], splitFaceNormal[0]);
26606 computeTri(p_2, p_2s, p_2sss, &splitFaceVolume[1], splitFaceCentroid[1], splitFaceNormal[1]);
26607
26608 splitFaceId = face1;
26609 maia::math::vecAvg<3>(M, p_1s, p_1ss, p_1sss, p_2s, p_2ss, p_2sss, p_3s, p_3ss, p_3sss);
26610
26611 faceVolume[face1] = F0;
26612
26613 for(MInt i = 0; i < 6; i++) {
26614 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]],
26615 M, &pyraVolume[i], pyraCentroid[i]);
26616 }
26617 computePyra(&splitFaceVolume[0], splitFaceCentroid[0], splitFaceNormal[0], M, &pyraVolume[6],
26618 pyraCentroid[6]);
26619 computePyra(&splitFaceVolume[1], splitFaceCentroid[1], splitFaceNormal[1], M, &pyraVolume[7],
26620 pyraCentroid[7]);
26621
26622 // 1st cut surface
26623 computePoly5(p_1sss, p_2sss, p_2s, p_3ss, p_3sss, &area_c, coordinates_c, normalVec_c);
26624 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[8], pyraCentroid[8]);
26625 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
26626 for(MInt dim = 0; dim < 3; dim++) {
26627 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26628 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26629 }
26630 // 2nd cut surface
26631 computePoly6(p_1s, p_1ss, p_3s, p_3ss, p_2s, p_2ss, &area_c, coordinates_c, normalVec_c);
26632 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[9], pyraCentroid[9]);
26633 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
26634 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
26635 for(MInt dim = 0; dim < 3; dim++) {
26636 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
26637 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
26638 }
26639
26640 for(MInt i = 0; i < 10; i++) {
26641 volume_C += pyraVolume[i];
26642 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26643 }
26644 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26645
26646 m_bndryCells->a[bndryId].m_volume = volume_C;
26647 for(MInt dim = 0; dim < 3; dim++) {
26648 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26649 }
26650
26651 faceCut[face1] = true;
26652 faceCut[face2] = true;
26653 faceCut[face3] = true;
26654 faceCut[face4] = true;
26655 faceCut[face5] = true;
26656 faceCut[face6] = true;
26657
26658 } else {
26659 // case 7.3 - 3 surfaces
26660 m_bndryCells->a[bndryId].m_noSrfcs = 3;
26661
26662 // case 7.3 - 1 surface (computed as 2 connected surfaces)
26663 computeTri(p_3, p_3sss, p_3ss, &faceVolume[face1], faceCentroid[face1], normal[face1]);
26664 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26665 faceVolume_0[face1] = faceVolume[face1];
26666 computeTri(p_2, p_2s, p_2sss, &faceVolume[face1], faceCentroid[face1], normal[face1]);
26667 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26668
26669 computeTri(p_4, p_1ss, p_3s, &splitFaceVolume[0], splitFaceCentroid[0], splitFaceNormal[0]);
26670 computeTri(p_0, p_3sss, p_1sss, &splitFaceVolume[1], splitFaceCentroid[1], splitFaceNormal[1]);
26671 splitCorner1 = cornersMCtoSOLVER[disambPointer[currentSubCase][4]];
26672 splitCorner2 = cornersMCtoSOLVER[disambPointer[currentSubCase][0]];
26673
26674 computeTri(p_5, p_2ss, p_1s, &splitFaceVolume2[0], splitFaceCentroid2[0], splitFaceNormal2[0]);
26675 computeTri(p_0, p_1sss, p_2sss, &splitFaceVolume2[1], splitFaceCentroid2[1], splitFaceNormal2[1]);
26676 splitCorner12 = cornersMCtoSOLVER[disambPointer[currentSubCase][5]];
26677 splitCorner22 = cornersMCtoSOLVER[disambPointer[currentSubCase][0]];
26678
26679 computeTri(p_1, p_1ss, p_1s, &faceVolume[face4], faceCentroid[face4], normal[face4]);
26680 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
26681 computeTri(p_2, p_2ss, p_2s, &faceVolume[face5], faceCentroid[face5], normal[face5]);
26682 correctFace(&faceVolume[face5], faceCentroid[face5], &faceVolume_0[face5], faceCentroid_0[face5]);
26683 computeTri(p_3, p_3ss, p_3s, &faceVolume[face6], faceCentroid[face6], normal[face6]);
26684 correctFace(&faceVolume[face6], faceCentroid[face6], &faceVolume_0[face6], faceCentroid_0[face6]);
26685
26686 splitFaceId = face2;
26687 splitFaceId2 = face3;
26688 maia::math::vecAvg<3>(M, p_1s, p_1ss, p_1sss, p_2s, p_2ss, p_2sss, p_3s, p_3ss, p_3sss);
26689
26690 faceVolume[face2] = F0;
26691 faceVolume[face3] = F0;
26692
26693 for(MInt i = 0; i < 6; i++) {
26694 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]],
26695 M, &pyraVolume[i], pyraCentroid[i]);
26696 }
26697 computePyra(&splitFaceVolume[0], splitFaceCentroid[0], splitFaceNormal[0], M, &pyraVolume[6],
26698 pyraCentroid[6]);
26699 computePyra(&splitFaceVolume[1], splitFaceCentroid[1], splitFaceNormal[1], M, &pyraVolume[7],
26700 pyraCentroid[7]);
26701 computePyra(&splitFaceVolume2[0], splitFaceCentroid2[0], splitFaceNormal2[0], M, &pyraVolume[8],
26702 pyraCentroid[8]);
26703 computePyra(&splitFaceVolume2[1], splitFaceCentroid2[1], splitFaceNormal2[1], M, &pyraVolume[9],
26704 pyraCentroid[9]);
26705 // 1st cut surface
26706 computePoly5(p_1ss, p_1sss, p_3sss, p_3ss, p_3s, &area_c, coordinates_c, normalVec_c);
26707 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[10], pyraCentroid[10]);
26708 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
26709 for(MInt dim = 0; dim < 3; dim++) {
26710 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26711 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26712 }
26713 // 2nd cut surface
26714 computePoly5(p_1sss, p_1s, p_2ss, p_2s, p_2sss, &area_c, coordinates_c, normalVec_c);
26715 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[11], pyraCentroid[11]);
26716 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
26717 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
26718 for(MInt dim = 0; dim < 3; dim++) {
26719 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
26720 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
26721 }
26722 // 3rd cut surface
26723 computePoly3(p_1s, p_1sss, p_1ss, &area_c, coordinates_c, normalVec_c);
26724 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[12], pyraCentroid[12]);
26725 m_bndryCells->a[bndryId].m_srfcs[2]->m_area = area_c;
26726 m_bndryCells->a[bndryId].m_srfcs[2]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
26727 for(MInt dim = 0; dim < 3; dim++) {
26728 m_bndryCells->a[bndryId].m_srfcs[2]->m_coordinates[dim] = coordinates_c[dim];
26729 m_bndryCells->a[bndryId].m_srfcs[2]->m_normalVector[dim] = normalVec_c[dim];
26730 }
26731
26732 for(MInt i = 0; i < 13; i++) {
26733 volume_C += pyraVolume[i];
26734 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26735 }
26736 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26737
26738 m_bndryCells->a[bndryId].m_volume = volume_C;
26739 for(MInt dim = 0; dim < 3; dim++) {
26740 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26741 }
26742
26743 faceCut[face1] = true;
26744 faceCut[face2] = true;
26745 faceCut[face3] = true;
26746 faceCut[face4] = true;
26747 faceCut[face5] = true;
26748 faceCut[face6] = true;
26749 }
26750 break;
26751 }
26752 case 3:
26753 case 5:
26754 case 6: {
26755 // compute case 7.2
26756
26757 if(disamb_tmp == 3) disambPointer_dummy = &tiling7_2_3STL[0][0];
26758 if(disamb_tmp == 5) disambPointer_dummy = &tiling7_2_5STL[0][0];
26759 if(disamb_tmp == 6) disambPointer_dummy = &tiling7_2_6STL[0][0];
26760
26761 for(MInt i = 0; i < 16; i++)
26762 for(MInt j = 0; j < 2; j++)
26763 disambPointer[i][j] = disambPointer_dummy[i * 2 + j];
26764
26765 for(MInt i = 0; i < 6; i++) {
26766 faceVolume_0[i] = faceVolume[i];
26767 for(MInt j = 0; j < 3; j++) {
26768 faceCentroid_0[i][j] = faceCentroid[i][j];
26769 }
26770 }
26771 cellVolume_0 = gridCellVolume;
26772 for(MInt i = 0; i < 3; i++) {
26773 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
26774 }
26775
26776 if(currentSubCase < 8) {
26777 // split cell: add another boundary cell and a new cell:
26778 cellId2 = createSplitCell_MGC(cellId, 1);
26779 bndryId2 = m_solver->a_bndryId(cellId2);
26780 m_splitParents[bndryId2] = bndryId;
26781 m_splitChildren[bndryId * 3 + 0] = bndryId2;
26782 if(bndryId == 0)
26783 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! "
26784 << endl;
26785 m_bndryCells->a[bndryId].m_noSrfcs = 1;
26786 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
26787 } else {
26788 m_bndryCells->a[bndryId].m_noSrfcs = 2;
26789 }
26790
26791 for(MInt face = 0; face < 6; face++) {
26792 nfs_cur[face] = nfs7_1[currentSubCase][face];
26793 }
26794
26795 // 1st Pyramid + 1st cutFace
26796 subCaseDummy = disambPointer[currentSubCase][0];
26797 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
26798 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
26799 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26800 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
26801 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26802 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
26803 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26804 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
26805 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
26806 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
26807
26808 faceCut[face1] = true;
26809 faceCut[face2] = true;
26810 faceCut[face3] = true;
26811
26812 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
26813 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
26814 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
26815
26816 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
26817
26818 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
26819
26820 if(currentSubCase >= 8) {
26821 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26822 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
26823 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
26824
26825 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
26826
26827 correctNormal(normalVec_c);
26828 } else {
26829 for(MInt face = 0; face < 6; face++) {
26830 nfs_cur[face] = nfs1[subCaseDummy][face];
26831 }
26832 }
26833
26834 // create 1st Cut face and 1st cell
26835 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
26836 for(MInt dim = 0; dim < 3; dim++) {
26837 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26838 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26839 }
26840 m_bndryCells->a[bndryId].m_volume = volume_C;
26841 for(MInt dim = 0; dim < 3; dim++) {
26842 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
26843 }
26844
26845 if(currentSubCase >= 8) {
26846 faceVolume_0[face1] = faceVolume[face1];
26847 faceVolume_0[face2] = faceVolume[face2];
26848 faceVolume_0[face3] = faceVolume[face3];
26849 cellVolume_0 = volume_C;
26850 volume_C = 0;
26851 for(MInt i = 0; i < 3; i++) {
26852 cellCentroid_0[i] = coordinates_Cell[i];
26853 faceCentroid_0[face1][i] = faceCentroid[face1][i];
26854 faceCentroid_0[face2][i] = faceCentroid[face2][i];
26855 faceCentroid_0[face3][i] = faceCentroid[face3][i];
26856 coordinates_Cell[i] = 0;
26857 }
26858 } else {
26859 volume_C = 0;
26860 for(MInt i = 0; i < 3; i++) {
26861 coordinates_Cell[i] = 0;
26862 }
26863 }
26864
26865 // create 2nd part of cell
26866 subCaseDummy = disambPointer[currentSubCase][1];
26867
26868 // 3.2 case
26869 noFaces = 5;
26870
26871 p_0 = corner[cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][0]]];
26872 p_0s = corner[cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][1]]];
26873
26874 cutDummy = edgesMCtoSOLVER[tiling3_2STL[subCaseDummy][2]];
26875 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26876 cutDummy = edgesMCtoSOLVER[tiling3_2STL[subCaseDummy][3]];
26877 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26878 cutDummy = edgesMCtoSOLVER[tiling3_2STL[subCaseDummy][4]];
26879 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26880 cutDummy = edgesMCtoSOLVER[tiling3_2STL[subCaseDummy][5]];
26881 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26882 cutDummy = edgesMCtoSOLVER[tiling3_2STL[subCaseDummy][6]];
26883 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26884 cutDummy = edgesMCtoSOLVER[tiling3_2STL[subCaseDummy][7]];
26885 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
26886 face1 = facesMCtoSOLVER[tiling3_2STL[subCaseDummy][8]];
26887 face2 = facesMCtoSOLVER[tiling3_2STL[subCaseDummy][9]];
26888 face3 = facesMCtoSOLVER[tiling3_2STL[subCaseDummy][10]];
26889 face4 = facesMCtoSOLVER[tiling3_2STL[subCaseDummy][11]];
26890 face5 = facesMCtoSOLVER[tiling3_2STL[subCaseDummy][12]];
26891
26892 if(currentSubCase < 8) {
26893 for(MInt face = 0; face < 6; face++) {
26894 nfs_cur_0[face] = nfs3_2[subCaseDummy][face];
26895 }
26896 faceCut_0[face1] = true;
26897 faceCut_0[face2] = true;
26898 faceCut_0[face3] = true;
26899 faceCut_0[face4] = true;
26900 faceCut_0[face5] = true;
26901
26902 computeTri(p_0, p_1, p_2, &faceVolume_0[face1], faceCentroid_0[face1], normal[face1]);
26903 computeTri(p_0, p_2, p_3, &faceVolume_0[face2], faceCentroid_0[face2], normal[face2]);
26904 computeTri(p_0s, p_2s, p_3s, &faceVolume_0[face3], faceCentroid_0[face3], normal[face3]);
26905 computeTri(p_0s, p_1s, p_2s, &faceVolume_0[face4], faceCentroid_0[face4], normal[face4]);
26906 computePoly6(p_0, p_1, p_3s, p_0s, p_1s, p_3, &faceVolume_0[face5], faceCentroid_0[face5],
26907 normal[face5]);
26908
26909 computePoly6(p_1, p_2, p_3, p_1s, p_2s, p_3s, &area_c, coordinates_c, normalVec_c);
26910
26911 maia::math::vecAvg<3>(M, p_0, p_0s, p_1, p_1s, p_2, p_2s, p_3, p_3s);
26912
26913 for(MInt i = 0; i < 5; i++) {
26914 computePyra(&faceVolume_0[*facepointers[i]], faceCentroid_0[*facepointers[i]],
26915 normal[*facepointers[i]], M, &pyraVolume[i], pyraCentroid[i]);
26916 }
26917 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[5], pyraCentroid[5]);
26918
26919 for(MInt i = 0; i < 6; i++) {
26920 volume_C += pyraVolume[i];
26921 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26922 }
26923 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26924
26925 absA = F0;
26926 for(MInt i = 0; i < nDim; i++) {
26927 if(!nfs_cur_0[2 * i + 1]) faceVolume_0[2 * i + 1] = 0;
26928 if(!nfs_cur_0[2 * i]) faceVolume_0[2 * i] = 0;
26929 faceDiff[i] = faceVolume_0[2 * i + 1] - faceVolume_0[2 * i];
26930 absA += POW2(faceDiff[i]);
26931 }
26932
26933 for(MInt i = 0; i < nDim; i++) {
26934 normalVec_c[i] = faceDiff[i] / sqrt(absA);
26935 }
26936 area_c = sqrt(absA);
26937
26938 // create 2nd Cut face & cell
26939 // create 1 Cut face
26940 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
26941 for(MInt dim = 0; dim < 3; dim++) {
26942 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
26943 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
26944 }
26945
26946 m_bndryCells->a[bndryId2].m_volume = volume_C;
26947 for(MInt dim = 0; dim < 3; dim++) {
26948 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
26949 }
26950
26951 // fill ambiguous corners array
26952 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][0]]] = cellId2;
26953 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][1]]] = cellId2;
26954 } else {
26955 faceCut[face1] = true;
26956 faceCut[face2] = true;
26957 faceCut[face3] = true;
26958 faceCut[face4] = true;
26959 faceCut[face5] = true;
26960
26961 computeTri(p_0, p_1, p_2, &faceVolume[face1], faceCentroid[face1], normal[face1]);
26962 computeTri(p_0, p_2, p_3, &faceVolume[face2], faceCentroid[face2], normal[face2]);
26963 computeTri(p_0s, p_2s, p_3s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
26964 computeTri(p_0s, p_1s, p_2s, &faceVolume[face4], faceCentroid[face4], normal[face4]);
26965 computePoly6(p_0, p_1, p_3s, p_0s, p_1s, p_3, &faceVolume[face5], faceCentroid[face5], normal[face5]);
26966
26967 computePoly6(p_1, p_2, p_3, p_1s, p_2s, p_3s, &area_c, coordinates_c, normalVec_c);
26968
26969 maia::math::vecAvg<3>(M, p_0, p_0s, p_1, p_1s, p_2, p_2s, p_3, p_3s);
26970
26971 for(MInt i = 0; i < 5; i++) {
26972 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]],
26973 M, &pyraVolume[i], pyraCentroid[i]);
26974 }
26975 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[5], pyraCentroid[5]);
26976
26977 for(MInt i = 0; i < 6; i++) {
26978 volume_C += pyraVolume[i];
26979 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
26980 }
26981 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
26982
26983 // correct cell
26984 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
26985 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
26986 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
26987 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
26988 p_1ss = corner[cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][13]]];
26989 p_2ss = corner[cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][14]]];
26990 splitCorner1 = cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][13]];
26991 splitCorner2 = cornersMCtoSOLVER[tiling3_2STL[subCaseDummy][14]];
26992 computeTri(p_1s, p_1ss, p_3, &splitFaceVolume[0], splitFaceCentroid[0], splitFaceNormal[0]);
26993 computeTri(p_1, p_2ss, p_3s, &splitFaceVolume[1], splitFaceCentroid[1], splitFaceNormal[1]);
26994 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
26995
26996 correctNormal(normalVec_c);
26997 splitFaceId = face5;
26998
26999 // create 2nd Cut face
27000 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
27001 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
27002 for(MInt dim = 0; dim < 3; dim++) {
27003 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
27004 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
27005 }
27006
27007 m_bndryCells->a[bndryId].m_volume = volume_C;
27008 for(MInt dim = 0; dim < 3; dim++) {
27009 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27010 }
27011 }
27012 break;
27013 }
27014 case 7: {
27015 if(currentSubCase < 8) {
27016 // split cell2: add 2 other boundary cells and 2 new cells:
27017 cellId2 = createSplitCell_MGC(cellId, 1);
27018 bndryId2 = m_solver->a_bndryId(cellId2);
27019 cellId3 = createSplitCell_MGC(cellId, 2);
27020 bndryId3 = m_solver->a_bndryId(cellId3);
27021 m_splitParents[bndryId2] = bndryId;
27022 m_splitParents[bndryId3] = bndryId;
27023 m_splitChildren[bndryId * 3 + 0] = bndryId2;
27024 m_splitChildren[bndryId * 3 + 1] = bndryId3;
27025 if(bndryId == 0)
27026 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! "
27027 << endl;
27028 m_bndryCells->a[bndryId].m_noSrfcs = 1;
27029 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
27030 m_bndryCells->a[bndryId3].m_noSrfcs = 1;
27031 } else {
27032 m_bndryCells->a[bndryId].m_noSrfcs = 3;
27033 }
27034
27035 for(MInt face = 0; face < 6; face++) {
27036 nfs_cur[face] = nfs7_1[currentSubCase][face];
27037 }
27038
27039 // 1st Pyramid + 1st cutFace
27040 subCaseDummy = tiling7_1STL[currentSubCase][0];
27041 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
27042 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
27043 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27044 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
27045 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27046 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
27047 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27048 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
27049 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
27050 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
27051
27052 faceCut[face1] = true;
27053 faceCut[face2] = true;
27054 faceCut[face3] = true;
27055
27056 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
27057 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
27058 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
27059
27060 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
27061
27062 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
27063
27064 if(currentSubCase >= 8) {
27065 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
27066 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
27067 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
27068
27069 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
27070
27071 correctNormal(normalVec_c);
27072 } else {
27073 for(MInt face = 0; face < 6; face++) {
27074 nfs_cur[face] = nfs1[subCaseDummy][face];
27075 }
27076 }
27077
27078 // create 1st Cut face and 1st cell
27079 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
27080 for(MInt dim = 0; dim < 3; dim++) {
27081 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27082 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27083 }
27084 m_bndryCells->a[bndryId].m_volume = volume_C;
27085 for(MInt dim = 0; dim < 3; dim++) {
27086 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27087 }
27088
27089 if(currentSubCase >= 8) {
27090 faceVolume_0[face1] = faceVolume[face1];
27091 faceVolume_0[face2] = faceVolume[face2];
27092 faceVolume_0[face3] = faceVolume[face3];
27093 cellVolume_0 = volume_C;
27094 for(MInt i = 0; i < 3; i++) {
27095 cellCentroid_0[i] = coordinates_Cell[i];
27096 faceCentroid_0[face1][i] = faceCentroid[face1][i];
27097 faceCentroid_0[face2][i] = faceCentroid[face2][i];
27098 faceCentroid_0[face3][i] = faceCentroid[face3][i];
27099 }
27100 }
27101
27102 // 2nd Pyramid + 2nd cutFace
27103 subCaseDummy = tiling7_1STL[currentSubCase][1];
27104 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
27105 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
27106 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27107 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
27108 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27109 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
27110 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27111 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
27112 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
27113 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
27114
27115 if(currentSubCase < 8) {
27116 for(MInt face = 0; face < 6; face++) {
27117 nfs_cur_0[face] = nfs1[subCaseDummy][face];
27118 }
27119
27120 faceCut_0[face1] = true;
27121 faceCut_0[face2] = true;
27122 faceCut_0[face3] = true;
27123
27124 computeTri(p_0, p_1, p_3, &faceVolume_0[face1], faceCentroid_0[face1]);
27125 computeTri(p_0, p_3, p_2, &faceVolume_0[face2], faceCentroid_0[face2]);
27126 computeTri(p_0, p_2, p_1, &faceVolume_0[face3], faceCentroid_0[face3]);
27127
27128 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
27129
27130 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
27131
27132 // create 2nd Cut face & cell
27133 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
27134 for(MInt dim = 0; dim < 3; dim++) {
27135 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27136 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27137 }
27138
27139 m_bndryCells->a[bndryId2].m_volume = volume_C;
27140 for(MInt dim = 0; dim < 3; dim++) {
27141 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
27142 }
27143 // fill ambiguous corners array
27144 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]] = cellId2;
27145 } else {
27146 faceCut[face1] = true;
27147 faceCut[face2] = true;
27148 faceCut[face3] = true;
27149
27150 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
27151 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
27152 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
27153
27154 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
27155
27156 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
27157
27158 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
27159 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
27160 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
27161
27162 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
27163
27164 correctNormal(normalVec_c);
27165
27166 // create 2nd Cut face
27167 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
27168 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
27169 for(MInt dim = 0; dim < 3; dim++) {
27170 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
27171 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
27172 }
27173
27174 m_bndryCells->a[bndryId].m_volume = volume_C;
27175 for(MInt dim = 0; dim < 3; dim++) {
27176 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27177 }
27178 }
27179
27180 if(currentSubCase >= 8) {
27181 faceVolume_0[face1] = faceVolume[face1];
27182 faceVolume_0[face2] = faceVolume[face2];
27183 faceVolume_0[face3] = faceVolume[face3];
27184 cellVolume_0 = volume_C;
27185 for(MInt i = 0; i < 3; i++) {
27186 cellCentroid_0[i] = coordinates_Cell[i];
27187 faceCentroid_0[face1][i] = faceCentroid[face1][i];
27188 faceCentroid_0[face2][i] = faceCentroid[face2][i];
27189 faceCentroid_0[face3][i] = faceCentroid[face3][i];
27190 }
27191 }
27192
27193 // 3rd Pyramid + 3rd cutFace
27194 subCaseDummy = tiling7_1STL[currentSubCase][2];
27195 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
27196 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
27197 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27198 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
27199 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27200 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
27201 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27202 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
27203 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
27204 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
27205
27206 if(currentSubCase < 8) {
27207 for(MInt face = 0; face < 6; face++) {
27208 nfs_cur_00[face] = nfs1[subCaseDummy][face];
27209 }
27210
27211 faceCut_00[face1] = true;
27212 faceCut_00[face2] = true;
27213 faceCut_00[face3] = true;
27214
27215 computeTri(p_0, p_1, p_3, &faceVolume_00[face1], faceCentroid_00[face1]);
27216 computeTri(p_0, p_3, p_2, &faceVolume_00[face2], faceCentroid_00[face2]);
27217 computeTri(p_0, p_2, p_1, &faceVolume_00[face3], faceCentroid_00[face3]);
27218
27219 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
27220
27221 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
27222
27223 // create 3rd Cut face & cell
27224 m_bndryCells->a[bndryId3].m_srfcs[0]->m_area = area_c;
27225 for(MInt dim = 0; dim < 3; dim++) {
27226 m_bndryCells->a[bndryId3].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27227 m_bndryCells->a[bndryId3].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27228 }
27229
27230 m_bndryCells->a[bndryId3].m_volume = volume_C;
27231 for(MInt dim = 0; dim < 3; dim++) {
27232 m_bndryCells->a[bndryId3].m_coordinates[dim] = coordinates_Cell[dim];
27233 }
27234
27235 // fill ambiguous corners array
27236 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]] = cellId3;
27237
27238 } else {
27239 faceCut[face1] = true;
27240 faceCut[face2] = true;
27241 faceCut[face3] = true;
27242
27243 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
27244 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
27245 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
27246
27247 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
27248
27249 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
27250
27251 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
27252 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
27253 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
27254
27255 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
27256
27257 correctNormal(normalVec_c);
27258
27259 // create 2nd Cut face
27260 m_bndryCells->a[bndryId].m_srfcs[2]->m_area = area_c;
27261 m_bndryCells->a[bndryId].m_srfcs[2]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
27262 for(MInt dim = 0; dim < 3; dim++) {
27263 m_bndryCells->a[bndryId].m_srfcs[2]->m_coordinates[dim] = coordinates_c[dim];
27264 m_bndryCells->a[bndryId].m_srfcs[2]->m_normalVector[dim] = normalVec_c[dim];
27265 }
27266
27267 m_bndryCells->a[bndryId].m_volume = volume_C;
27268 for(MInt dim = 0; dim < 3; dim++) {
27269 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27270 }
27271 }
27272 break;
27273 }
27274 default: {
27275 stringstream errorMessage;
27276 errorMessage << "ERROR: Switch variable 'disamb_tmp' with value " << disamb_tmp
27277 << " not matching any case." << endl;
27278 mTerm(1, AT_, errorMessage.str());
27279 }
27280 }
27281 break;
27282 }
27283 case 10: {
27284 for(MInt i = 0; i < 6; i++) {
27285 faceVolume_0[i] = faceVolume[i];
27286 for(MInt j = 0; j < 3; j++) {
27287 faceCentroid_0[i][j] = faceCentroid[i][j];
27288 }
27289 }
27290 cellVolume_0 = gridCellVolume;
27291 for(MInt i = 0; i < 3; i++) {
27292 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
27293 }
27294
27295 if(disambiguation[bndryId] == 3) { // case 10.2, split cell
27296
27297 cellId2 = createSplitCell_MGC(cellId, 1);
27298 bndryId2 = m_solver->a_bndryId(cellId2);
27299 m_splitParents[bndryId2] = bndryId;
27300 m_splitChildren[bndryId * 3 + 0] = bndryId2;
27301 if(bndryId == 0)
27302 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! " << endl;
27303 m_bndryCells->a[bndryId].m_noSrfcs = 1;
27304 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
27305
27306 // 1st prism & 1st cutFace
27307 subCaseDummy = tiling10_2STL[currentSubCase][0];
27308 for(MInt face = 0; face < 6; face++) {
27309 nfs_cur[face] = nfs2[subCaseDummy][face];
27310 }
27311 p_0 = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][0]]];
27312 p_0s = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][1]]];
27313 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][2]];
27314 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27315 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][3]];
27316 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27317 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][4]];
27318 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27319 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][5]];
27320 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27321 face1 = facesMCtoSOLVER[tiling2STL[subCaseDummy][6]];
27322 face2 = facesMCtoSOLVER[tiling2STL[subCaseDummy][7]];
27323 face3 = facesMCtoSOLVER[tiling2STL[subCaseDummy][8]];
27324 face4 = facesMCtoSOLVER[tiling2STL[subCaseDummy][9]];
27325
27326 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2], normal[face2]);
27327 computeTri(p_0s, p_3s, p_2s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
27328 computeTrapez(p_0, p_0s, p_3s, p_3, &faceVolume[face1], faceCentroid[face1], normal[face1]);
27329 computeTrapez(p_2, p_2s, p_0s, p_0, &faceVolume[face4], faceCentroid[face4], normal[face4]);
27330
27331 computePoly4(p_3, p_3s, p_2s, p_2, &area_c, coordinates_c, normalVec_c);
27332
27333 maia::math::vecAvg<3>(M, p_0, p_0s, p_2, p_2s, p_3, p_3s);
27334
27335 for(MInt i = 0; i < 4; i++) {
27336 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
27337 &pyraVolume[i], pyraCentroid[i]);
27338 }
27339 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[4], pyraCentroid[4]);
27340 for(MInt i = 0; i < 5; i++) {
27341 volume_C += pyraVolume[i];
27342 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
27343 }
27344 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
27345
27346 faceCut[face1] = true;
27347 faceCut[face2] = true;
27348 faceCut[face3] = true;
27349 faceCut[face4] = true;
27350
27351 // create 1st Cut face and 1st cell
27352 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
27353 for(MInt dim = 0; dim < 3; dim++) {
27354 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27355 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27356 }
27357
27358 m_bndryCells->a[bndryId].m_volume = volume_C;
27359 volume_C = 0;
27360 for(MInt dim = 0; dim < 3; dim++) {
27361 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27362 coordinates_Cell[dim] = F0;
27363 }
27364
27365 // 2nd Prism + 2nd cutFace = 2nd cell
27366 subCaseDummy = tiling10_2STL[currentSubCase][1];
27367 for(MInt face = 0; face < 6; face++) {
27368 nfs_cur_0[face] = nfs2[subCaseDummy][face];
27369 }
27370 p_0 = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][0]]];
27371 p_0s = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][1]]];
27372 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][2]];
27373 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27374 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][3]];
27375 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27376 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][4]];
27377 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27378 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][5]];
27379 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27380 face1 = facesMCtoSOLVER[tiling2STL[subCaseDummy][6]];
27381 face2 = facesMCtoSOLVER[tiling2STL[subCaseDummy][7]];
27382 face3 = facesMCtoSOLVER[tiling2STL[subCaseDummy][8]];
27383 face4 = facesMCtoSOLVER[tiling2STL[subCaseDummy][9]];
27384
27385 computeTri(p_0, p_3, p_2, &faceVolume_0[face2], faceCentroid_0[face2], normal[face2]);
27386 computeTri(p_0s, p_3s, p_2s, &faceVolume_0[face3], faceCentroid_0[face3], normal[face3]);
27387 computeTrapez(p_0, p_0s, p_3s, p_3, &faceVolume_0[face1], faceCentroid_0[face1], normal[face1]);
27388 computeTrapez(p_2, p_2s, p_0s, p_0, &faceVolume_0[face4], faceCentroid_0[face4], normal[face4]);
27389
27390 computePoly4(p_3, p_3s, p_2s, p_2, &area_c, coordinates_c, normalVec_c);
27391
27392 maia::math::vecAvg<3>(M, p_0, p_0s, p_2, p_2s, p_3, p_3s);
27393
27394 for(MInt i = 0; i < 4; i++) {
27395 computePyra(&faceVolume_0[*facepointers[i]], faceCentroid_0[*facepointers[i]], normal[*facepointers[i]],
27396 M, &pyraVolume[i], pyraCentroid[i]);
27397 }
27398 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[4], pyraCentroid[4]);
27399 for(MInt i = 0; i < 5; i++) {
27400 volume_C += pyraVolume[i];
27401 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
27402 }
27403 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
27404
27405 faceCut_0[face1] = true;
27406 faceCut_0[face2] = true;
27407 faceCut_0[face3] = true;
27408 faceCut_0[face4] = true;
27409
27410 // create 2nd Cut face
27411 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
27412 for(MInt dim = 0; dim < 3; dim++) {
27413 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27414 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27415 }
27416
27417 m_bndryCells->a[bndryId2].m_volume = volume_C;
27418 for(MInt dim = 0; dim < 3; dim++) {
27419 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
27420 }
27421
27422 // fill ambiguous corner array
27423 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling2STL[subCaseDummy][0]]] = cellId2;
27424 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling2STL[subCaseDummy][1]]] = cellId2;
27425
27426 } else if(disambiguation[bndryId] == 0) {
27427 // case 10_1 - 2 surfaces, connected cell
27428
27429 m_bndryCells->a[bndryId].m_noSrfcs = 2;
27430 for(MInt face = 0; face < 6; face++) {
27431 nfs_cur[face] = nfs10[currentSubCase][face];
27432 }
27433
27434 // 1st prism & 1st cutFace
27435 subCaseDummy = tiling10_1STL[currentSubCase][0];
27436 p_0 = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][0]]];
27437 p_0s = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][1]]];
27438 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][2]];
27439 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27440 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][3]];
27441 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27442 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][4]];
27443 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27444 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][5]];
27445 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27446 face1 = facesMCtoSOLVER[tiling2STL[subCaseDummy][6]];
27447 face2 = facesMCtoSOLVER[tiling2STL[subCaseDummy][7]];
27448 face3 = facesMCtoSOLVER[tiling2STL[subCaseDummy][8]];
27449 face4 = facesMCtoSOLVER[tiling2STL[subCaseDummy][9]];
27450
27451 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2], normal[face2]);
27452 computeTri(p_0s, p_3s, p_2s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
27453 computeTrapez(p_0, p_0s, p_3s, p_3, &faceVolume[face1], faceCentroid[face1], normal[face1]);
27454 computeTrapez(p_2, p_2s, p_0s, p_0, &faceVolume[face4], faceCentroid[face4], normal[face4]);
27455
27456 computePoly4(p_3, p_3s, p_2s, p_2, &area_c, coordinates_c, normalVec_c);
27457
27458 maia::math::vecAvg<3>(M, p_0, p_0s, p_2, p_2s, p_3, p_3s);
27459
27460 for(MInt i = 0; i < 4; i++) {
27461 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
27462 &pyraVolume[i], pyraCentroid[i]);
27463 }
27464 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[4], pyraCentroid[4]);
27465 for(MInt i = 0; i < 5; i++) {
27466 volume_C += pyraVolume[i];
27467 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
27468 }
27469 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
27470
27471 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
27472 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
27473 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
27474 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
27475
27476 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
27477
27478 correctNormal(normalVec_c);
27479
27480 faceCut[face1] = true;
27481 faceCut[face2] = true;
27482 faceCut[face3] = true;
27483 faceCut[face4] = true;
27484
27485 // create 1st Cut face
27486 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
27487 for(MInt dim = 0; dim < 3; dim++) {
27488 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27489 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27490 }
27491
27492 faceVolume_0[face1] = faceVolume[face1];
27493 faceVolume_0[face2] = faceVolume[face2];
27494 faceVolume_0[face3] = faceVolume[face3];
27495 faceVolume_0[face4] = faceVolume[face4];
27496 cellVolume_0 = volume_C;
27497 volume_C = 0;
27498 for(MInt i = 0; i < 3; i++) {
27499 cellCentroid_0[i] = coordinates_Cell[i];
27500 faceCentroid_0[face1][i] = faceCentroid[face1][i];
27501 faceCentroid_0[face2][i] = faceCentroid[face2][i];
27502 faceCentroid_0[face3][i] = faceCentroid[face3][i];
27503 faceCentroid_0[face4][i] = faceCentroid[face4][i];
27504 coordinates_Cell[i] = 0;
27505 }
27506
27507 // 2nd Prism + 2nd cutFace
27508 subCaseDummy = tiling10_1STL[currentSubCase][1];
27509 p_0 = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][0]]];
27510 p_0s = corner[cornersMCtoSOLVER[tiling2STL[subCaseDummy][1]]];
27511 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][2]];
27512 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27513 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][3]];
27514 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27515 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][4]];
27516 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27517 cutDummy = edgesMCtoSOLVER[tiling2STL[subCaseDummy][5]];
27518 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27519 face1 = facesMCtoSOLVER[tiling2STL[subCaseDummy][6]];
27520 face2 = facesMCtoSOLVER[tiling2STL[subCaseDummy][7]];
27521 face3 = facesMCtoSOLVER[tiling2STL[subCaseDummy][8]];
27522 face4 = facesMCtoSOLVER[tiling2STL[subCaseDummy][9]];
27523
27524 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2], normal[face2]);
27525 computeTri(p_0s, p_3s, p_2s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
27526 computeTrapez(p_0, p_0s, p_3s, p_3, &faceVolume[face1], faceCentroid[face1], normal[face1]);
27527 computeTrapez(p_2, p_2s, p_0s, p_0, &faceVolume[face4], faceCentroid[face4], normal[face4]);
27528
27529 computePoly4(p_3, p_3s, p_2s, p_2, &area_c, coordinates_c, normalVec_c);
27530
27531 maia::math::vecAvg<3>(M, p_0, p_0s, p_2, p_2s, p_3, p_3s);
27532
27533 for(MInt i = 0; i < 4; i++) {
27534 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
27535 &pyraVolume[i], pyraCentroid[i]);
27536 }
27537 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[4], pyraCentroid[4]);
27538 for(MInt i = 0; i < 5; i++) {
27539 volume_C += pyraVolume[i];
27540 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
27541 }
27542 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
27543
27544 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
27545 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
27546 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
27547 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
27548
27549 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
27550
27551 correctNormal(normalVec_c);
27552
27553 faceCut[face1] = true;
27554 faceCut[face2] = true;
27555 faceCut[face3] = true;
27556 faceCut[face4] = true;
27557
27558 // create 2nd Cut face
27559 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
27560 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
27561 for(MInt dim = 0; dim < 3; dim++) {
27562 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
27563 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
27564 }
27565
27566 m_bndryCells->a[bndryId].m_volume = volume_C;
27567 for(MInt dim = 0; dim < 3; dim++) {
27568 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27569 }
27570 }
27571 break;
27572 }
27573 case 12: {
27574 for(MInt i = 0; i < 6; i++) {
27575 faceVolume_0[i] = faceVolume[i];
27576 for(MInt j = 0; j < 3; j++) {
27577 faceCentroid_0[i][j] = faceCentroid[i][j];
27578 }
27579 }
27580 cellVolume_0 = gridCellVolume;
27581 for(MInt i = 0; i < 3; i++) {
27582 cellCentroid_0[i] = m_solver->a_coordinate(cellId, i);
27583 }
27584
27585 if(disambiguation[bndryId] == 3) { // case 12.1 disconnected, split cell
27586
27587 cellId2 = createSplitCell_MGC(cellId, 1);
27588 bndryId2 = m_solver->a_bndryId(cellId2);
27589 m_splitParents[bndryId2] = bndryId;
27590 m_splitChildren[bndryId * 3 + 0] = bndryId2;
27591 if(bndryId == 0)
27592 cerr << " problem in FvBndryCnd3D::createCutFaceMGC, assuming cell 0 is no split cell failed! " << endl;
27593 m_bndryCells->a[bndryId].m_noSrfcs = 1;
27594 m_bndryCells->a[bndryId2].m_noSrfcs = 1;
27595
27596 // 1st case 5 cell & 1st cutFace
27597 subCaseDummy = tiling12_1STL[23 - currentSubCase][0];
27598 for(MInt face = 0; face < 6; face++) {
27599 nfs_cur[face] = nfs5[subCaseDummy][face];
27600 }
27601 p_0 = corner[cornersMCtoSOLVER[tiling5STL[subCaseDummy][0]]];
27602 p_1 = corner[cornersMCtoSOLVER[tiling5STL[subCaseDummy][1]]];
27603 p_2 = corner[cornersMCtoSOLVER[tiling5STL[subCaseDummy][2]]];
27604 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][3]];
27605 p_0s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27606 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][4]];
27607 p_0ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27608 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][5]];
27609 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27610 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][6]];
27611 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27612 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][7]];
27613 p_2ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27614 face1 = facesMCtoSOLVER[tiling5STL[subCaseDummy][8]];
27615 face2 = facesMCtoSOLVER[tiling5STL[subCaseDummy][9]];
27616 face3 = facesMCtoSOLVER[tiling5STL[subCaseDummy][10]];
27617 face4 = facesMCtoSOLVER[tiling5STL[subCaseDummy][11]];
27618 face5 = facesMCtoSOLVER[tiling5STL[subCaseDummy][12]];
27619
27620 computePoly5(p_0, p_0ss, p_2ss, p_2, p_1, &faceVolume[face1], faceCentroid[face1], normal[face1]);
27621 computeTri(p_0ss, p_0, p_0s, &faceVolume[face2], faceCentroid[face2], normal[face2]);
27622 computeTrapez(p_0, p_1, p_1s, p_0s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
27623 computeTrapez(p_1, p_1s, p_2s, p_2, &faceVolume[face4], faceCentroid[face4], normal[face4]);
27624 computeTri(p_2s, p_2, p_2ss, &faceVolume[face5], faceCentroid[face5], normal[face5]);
27625
27626 computePoly5(p_0s, p_1s, p_2s, p_2ss, p_0ss, &area_c, coordinates_c, normalVec_c);
27627
27628 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_0s, p_1s, p_2s, p_0ss, p_2ss);
27629
27630 for(MInt i = 0; i < 5; i++) {
27631 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
27632 &pyraVolume[i], pyraCentroid[i]);
27633 }
27634 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[5], pyraCentroid[5]);
27635 for(MInt i = 0; i < 6; i++) {
27636 volume_C += pyraVolume[i];
27637 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
27638 }
27639 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
27640
27641 faceCut[face1] = true;
27642 faceCut[face2] = true;
27643 faceCut[face3] = true;
27644 faceCut[face4] = true;
27645 faceCut[face5] = true;
27646
27647 // create 1st Cut face
27648 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
27649 for(MInt dim = 0; dim < 3; dim++) {
27650 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27651 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27652 }
27653
27654 m_bndryCells->a[bndryId].m_volume = volume_C;
27655 volume_C = 0;
27656 for(MInt dim = 0; dim < 3; dim++) {
27657 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27658 coordinates_Cell[dim] = m_solver->a_coordinate(cellId, dim);
27659 }
27660
27661 // 2nd Pyramid + 2nd cutFace = 2nd cell
27662 subCaseDummy = tiling12_1STL[23 - currentSubCase][1];
27663 for(MInt face = 0; face < 6; face++) {
27664 nfs_cur_0[face] = nfs1[subCaseDummy][face];
27665 }
27666 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
27667 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
27668 p_1 = m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27669 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
27670 p_2 = m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27671 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
27672 p_3 = m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27673 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
27674 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
27675 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
27676
27677 faceCut_0[face1] = true;
27678 faceCut_0[face2] = true;
27679 faceCut_0[face3] = true;
27680
27681 computeTri(p_0, p_1, p_3, &faceVolume_0[face1], faceCentroid_0[face1]);
27682 computeTri(p_0, p_3, p_2, &faceVolume_0[face2], faceCentroid_0[face2]);
27683 computeTri(p_0, p_2, p_1, &faceVolume_0[face3], faceCentroid_0[face3]);
27684
27685 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
27686
27687 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
27688
27689 m_bndryCells->a[bndryId2].m_volume = volume_C;
27690 for(MInt dim = 0; dim < 3; dim++) {
27691 m_bndryCells->a[bndryId2].m_coordinates[dim] = coordinates_Cell[dim];
27692 }
27693
27694 // create 2nd Cut face
27695 m_bndryCells->a[bndryId2].m_srfcs[0]->m_area = area_c;
27696 for(MInt dim = 0; dim < 3; dim++) {
27697 m_bndryCells->a[bndryId2].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27698 m_bndryCells->a[bndryId2].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27699 }
27700
27701 // fill ambiguous corner array
27702 cornerCellMapping[ambIds[bndryId] * 8 + cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]] = cellId2;
27703
27704 } else if(disambiguation[bndryId] == 0) {
27705 // case 12_1 - 2 surfaces, connected cell
27706
27707 m_bndryCells->a[bndryId].m_noSrfcs = 2;
27708 for(MInt face = 0; face < 6; face++) {
27709 nfs_cur[face] = nfs12_1[currentSubCase][face];
27710 }
27711
27712 // 1st case 5 cell & 1st cutFace
27713 subCaseDummy = tiling12_1STL[currentSubCase][0];
27714
27715 p_0 = corner[cornersMCtoSOLVER[tiling5STL[subCaseDummy][0]]];
27716 p_1 = corner[cornersMCtoSOLVER[tiling5STL[subCaseDummy][1]]];
27717 p_2 = corner[cornersMCtoSOLVER[tiling5STL[subCaseDummy][2]]];
27718 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][3]];
27719 p_0s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27720 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][4]];
27721 p_0ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27722 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][5]];
27723 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27724 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][6]];
27725 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27726 cutDummy = edgesMCtoSOLVER[tiling5STL[subCaseDummy][7]];
27727 p_2ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27728 face1 = facesMCtoSOLVER[tiling5STL[subCaseDummy][8]];
27729 face2 = facesMCtoSOLVER[tiling5STL[subCaseDummy][9]];
27730 face3 = facesMCtoSOLVER[tiling5STL[subCaseDummy][10]];
27731 face4 = facesMCtoSOLVER[tiling5STL[subCaseDummy][11]];
27732 face5 = facesMCtoSOLVER[tiling5STL[subCaseDummy][12]];
27733
27734 computePoly5(p_0, p_0ss, p_2ss, p_2, p_1, &faceVolume[face1], faceCentroid[face1], normal[face1]);
27735 computeTri(p_0ss, p_0, p_0s, &faceVolume[face2], faceCentroid[face2], normal[face2]);
27736 computeTrapez(p_0, p_1, p_1s, p_0s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
27737 computeTrapez(p_1, p_1s, p_2s, p_2, &faceVolume[face4], faceCentroid[face4], normal[face4]);
27738 computeTri(p_2s, p_2, p_2ss, &faceVolume[face5], faceCentroid[face5], normal[face5]);
27739
27740 computePoly5(p_0s, p_1s, p_2s, p_2ss, p_0ss, &area_c, coordinates_c, normalVec_c);
27741
27742 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_0s, p_1s, p_2s, p_0ss, p_2ss);
27743
27744 for(MInt i = 0; i < 5; i++) {
27745 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
27746 &pyraVolume[i], pyraCentroid[i]);
27747 }
27748 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[5], pyraCentroid[5]);
27749 for(MInt i = 0; i < 6; i++) {
27750 volume_C += pyraVolume[i];
27751 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
27752 }
27753 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
27754
27755 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
27756 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
27757 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
27758 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
27759 correctFace(&faceVolume[face5], faceCentroid[face5], &faceVolume_0[face5], faceCentroid_0[face5]);
27760
27761 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
27762
27763 correctNormal(normalVec_c);
27764
27765 faceCut[face1] = true;
27766 faceCut[face2] = true;
27767 faceCut[face3] = true;
27768 faceCut[face4] = true;
27769 faceCut[face5] = true;
27770
27771 // create 1st Cut face
27772 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
27773 for(MInt dim = 0; dim < 3; dim++) {
27774 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
27775 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
27776 }
27777
27778 faceVolume_0[face1] = faceVolume[face1];
27779 faceVolume_0[face2] = faceVolume[face2];
27780 faceVolume_0[face3] = faceVolume[face3];
27781 faceVolume_0[face4] = faceVolume[face4];
27782 faceVolume_0[face5] = faceVolume[face5];
27783 cellVolume_0 = volume_C;
27784 volume_C = 0;
27785 for(MInt i = 0; i < 3; i++) {
27786 cellCentroid_0[i] = coordinates_Cell[i];
27787 faceCentroid_0[face1][i] = faceCentroid[face1][i];
27788 faceCentroid_0[face2][i] = faceCentroid[face2][i];
27789 faceCentroid_0[face3][i] = faceCentroid[face3][i];
27790 faceCentroid_0[face4][i] = faceCentroid[face4][i];
27791 faceCentroid_0[face5][i] = faceCentroid[face5][i];
27792 coordinates_Cell[i] = 0;
27793 }
27794
27795 // 2nd Pyramid + 2nd cutFace
27796 subCaseDummy = tiling12_1STL[currentSubCase][1];
27797 p_0 = corner[cornersMCtoSOLVER[tiling1STL[subCaseDummy][0]]];
27798 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][1]];
27799 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27800 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][2]];
27801 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27802 cutDummy = edgesMCtoSOLVER[tiling1STL[subCaseDummy][3]];
27803 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
27804 face1 = facesMCtoSOLVER[tiling1STL[subCaseDummy][4]];
27805 face2 = facesMCtoSOLVER[tiling1STL[subCaseDummy][5]];
27806 face3 = facesMCtoSOLVER[tiling1STL[subCaseDummy][6]];
27807
27808 faceCut[face1] = true;
27809 faceCut[face2] = true;
27810 faceCut[face3] = true;
27811
27812 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
27813 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
27814 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
27815
27816 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
27817
27818 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
27819
27820 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
27821 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
27822 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
27823
27824 correctCell(&volume_C, coordinates_Cell, &cellVolume_0, cellCentroid_0);
27825
27826 correctNormal(normalVec_c);
27827
27828 // create 2nd Cut face
27829 m_bndryCells->a[bndryId].m_srfcs[1]->m_area = area_c;
27830 m_bndryCells->a[bndryId].m_srfcs[1]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
27831 for(MInt dim = 0; dim < 3; dim++) {
27832 m_bndryCells->a[bndryId].m_srfcs[1]->m_coordinates[dim] = coordinates_c[dim];
27833 m_bndryCells->a[bndryId].m_srfcs[1]->m_normalVector[dim] = normalVec_c[dim];
27834 }
27835
27836 m_bndryCells->a[bndryId].m_volume = volume_C;
27837 for(MInt dim = 0; dim < 3; dim++) {
27838 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
27839 }
27840 }
27841 break;
27842 }
27843 default: {
27844 mTerm(1, AT_, "Unknown case probably in disamb_tmp");
27845 }
27846 }
27847
27848 for(MInt i = 0; i < nDim; i++) {
27849 m_bndryCells->a[bndryId].m_coordinates[i] -= m_solver->a_coordinate(cellId, i);
27850 }
27851 if(splitCell[bndryId]) {
27852 for(MInt i = 0; i < nDim; i++) {
27853 m_bndryCells->a[bndryId2].m_coordinates[i] -= m_solver->a_coordinate(cellId2, i);
27854 }
27855 }
27856 if(currentCase == 7 && disamb_tmp == 7) {
27857 for(MInt i = 0; i < nDim; i++) {
27858 m_bndryCells->a[bndryId3].m_coordinates[i] -= m_solver->a_coordinate(cellId3, i);
27859 }
27860 }
27861
27862 // face data is assembled
27863 // create a surface for the cut face if a boundary cell neighbor exists
27864 if(!splitFace[bndryId]) { // cell can be split cell. here, the first cell is connected
27865 for(MInt face = 0; face < 6; face++) {
27866 m_bndryCells->a[bndryId].m_associatedSrfc[face] = -1;
27867 if(!faceCut[face]) continue;
27868 sideId = face % 2;
27869 spaceId = face / 2;
27870 if(nfs_cur[face]) {
27871 if(m_solver->a_hasNeighbor(cellId, face) > 0)
27872 nghbrId = m_solver->c_neighborId(cellId, face);
27873 else {
27874 if(m_solver->c_parentId(cellId) > -1) {
27875 if(m_solver->a_hasNeighbor(m_solver->c_parentId(cellId), face) > 0)
27876 nghbrId = m_solver->c_neighborId(m_solver->c_parentId(cellId), face);
27877 else
27878 continue;
27879 } else
27880 continue;
27881 }
27882 if(m_solver->c_noChildren(nghbrId) > 0) continue;
27883 otherSideId = (sideId + 1) % 2;
27884 srfcId = m_solver->a_noSurfaces();
27885 m_surfaces.append();
27886 m_solver->a_surfaceOrientation(srfcId) = spaceId;
27887 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
27888 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId;
27889 for(MInt dim = 0; dim < nDim; dim++) {
27890 m_solver->a_surfaceCoordinate(srfcId, dim) = faceCentroid[face][dim];
27891 }
27892 m_solver->a_surfaceArea(srfcId) = faceVolume[face];
27893 m_bndryCells->a[bndryId].m_associatedSrfc[face] = srfcId;
27894 } else {
27895 stringstream errorMessage;
27896 errorMessage << "Error in FvBndryCnd3D::createCutFaceMGC - 1. Problem with face " << face << endl;
27897 errorMessage << "bndryId: " << bndryId << endl;
27898 errorMessage << "cellId: " << cellId << endl;
27899 errorMessage << "bndryCnd: " << m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
27900 errorMessage << "case, subcase: " << currentCase << ", " << currentSubCase << endl;
27901 errorMessage << "disamb: " << disambiguation[bndryId] << endl;
27902 errorMessage << "face Volumes: " << faceVolume[0] << ", " << faceVolume[1] << ", " << faceVolume[2] << ", "
27903 << faceVolume[3] << ", " << faceVolume[4] << ", " << faceVolume[5] << endl;
27904 errorMessage << "faceCentroids: ";
27905 for(MInt i = 0; i < 6; i++) {
27906 errorMessage << faceCentroid[i][0] << ", " << faceCentroid[i][1] << ", " << faceCentroid[i][2] << "; "
27907 << endl;
27908 }
27909 errorMessage << "area_c = " << area_c << endl;
27910 errorMessage << "normalVec_c = " << normalVec_c[0] << ", " << normalVec_c[1] << ", " << normalVec_c[2]
27911 << endl;
27912 errorMessage << "coordinates_c = " << coordinates_c[0] << ", " << coordinates_c[1] << ", "
27913 << coordinates_c[2] << endl;
27914 errorMessage << "coordinates_Cell = " << coordinates_Cell[0] << ", " << coordinates_Cell[1] << ", "
27915 << coordinates_Cell[2] << endl;
27916 errorMessage << "volume_C = " << volume_C << endl;
27917 mTerm(1, AT_, errorMessage.str());
27918 }
27919 }
27920 }
27921 if(splitFace[bndryId]) { // cell is not a split cell. here, both split surfaces are created and connected
27922 for(MInt face = 0; face < 6; face++) {
27923 m_bndryCells->a[bndryId].m_associatedSrfc[face] = -1;
27924 if(!faceCut[face]) continue;
27925 sideId = face % 2;
27926 spaceId = face / 2;
27927 if(nfs_cur[face]) {
27928 if(m_solver->a_hasNeighbor(cellId, face) > 0)
27929 nghbrId = m_solver->c_neighborId(cellId, face);
27930 else {
27931 if(m_solver->c_parentId(cellId) > -1) {
27932 if(m_solver->a_hasNeighbor(m_solver->c_parentId(cellId), face) > 0)
27933 nghbrId = m_solver->c_neighborId(m_solver->c_parentId(cellId), face);
27934 else
27935 continue;
27936 } else
27937 continue;
27938 }
27939 if(m_solver->c_noChildren(nghbrId) > 0) continue;
27940 otherSideId = (sideId + 1) % 2;
27941 if(face == splitFaceId) {
27942 // first surface
27943 srfcId = m_solver->a_noSurfaces();
27944 m_surfaces.append();
27945 m_solver->a_surfaceOrientation(srfcId) = spaceId;
27946 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
27947 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId;
27948 for(MInt dim = 0; dim < nDim; dim++) {
27949 m_solver->a_surfaceCoordinate(srfcId, dim) = splitFaceCentroid[0][dim];
27950 }
27951 m_solver->a_surfaceArea(srfcId) = splitFaceVolume[0];
27952 m_splitSurfaces[splitSurfaceIndexCounter * 6] = srfcId;
27953 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 1] = splitCorner1;
27954 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 2] = splitCorner1 + neighborCorner[face];
27955 // second surface
27956 srfcId = m_solver->a_noSurfaces();
27957 m_surfaces.append();
27958 m_solver->a_surfaceOrientation(srfcId) = spaceId;
27959 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
27960 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId;
27961 for(MInt dim = 0; dim < nDim; dim++) {
27962 m_solver->a_surfaceCoordinate(srfcId, dim) = splitFaceCentroid[1][dim];
27963 }
27964 m_solver->a_surfaceArea(srfcId) = splitFaceVolume[1];
27965 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 3] = srfcId;
27966 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 3 + 1] = splitCorner2;
27967 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 3 + 2] = splitCorner2 + neighborCorner[face];
27968 // set associated Srfc Pointer
27969 m_bndryCells->a[bndryId].m_associatedSrfc[face] = -splitSurfaceIndexCounter;
27970 splitSurfaceIndexCounter++;
27971 } else {
27972 srfcId = m_solver->a_noSurfaces();
27973 m_surfaces.append();
27974 m_solver->a_surfaceOrientation(srfcId) = spaceId;
27975 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
27976 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId;
27977 for(MInt dim = 0; dim < nDim; dim++) {
27978 m_solver->a_surfaceCoordinate(srfcId, dim) = faceCentroid[face][dim];
27979 }
27980 m_solver->a_surfaceArea(srfcId) = faceVolume[face];
27981 m_bndryCells->a[bndryId].m_associatedSrfc[face] = srfcId;
27982 }
27983 } else {
27984 stringstream errorMessage;
27985 errorMessage << "Error in FvBndryCnd3D::createCutFaceMGC - 2. Problem with face " << face << endl;
27986 errorMessage << "bndryId: " << bndryId << endl;
27987 errorMessage << "cellId: " << cellId << endl;
27988 errorMessage << "bndryCnd: " << m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
27989 errorMessage << "case, subcase: " << currentCase << ", " << currentSubCase << endl;
27990 errorMessage << "disamb: " << disambiguation[bndryId] << endl;
27991 errorMessage << "face Volumes: " << faceVolume[0] << ", " << faceVolume[1] << ", " << faceVolume[2] << ", "
27992 << faceVolume[3] << ", " << faceVolume[4] << ", " << faceVolume[5] << endl;
27993 errorMessage << "faceCentroids: ";
27994 for(MInt i = 0; i < 6; i++) {
27995 errorMessage << faceCentroid[i][0] << ", " << faceCentroid[i][1] << ", " << faceCentroid[i][2] << "; "
27996 << endl;
27997 }
27998 errorMessage << "area_c = " << area_c << endl;
27999 errorMessage << "normalVec_c = " << normalVec_c[0] << ", " << normalVec_c[1] << ", " << normalVec_c[2]
28000 << endl;
28001 errorMessage << "coordinates_c = " << coordinates_c[0] << ", " << coordinates_c[1] << ", "
28002 << coordinates_c[2] << endl;
28003 errorMessage << "coordinates_Cell = " << coordinates_Cell[0] << ", " << coordinates_Cell[1] << ", "
28004 << coordinates_Cell[2] << endl;
28005 errorMessage << "volume_C = " << volume_C << endl;
28006 mTerm(1, AT_, errorMessage.str());
28007 }
28008 }
28009 }
28010 if(currentCase == 7 && currentSubCase >= 8
28011 && (disamb_tmp == 1 || disamb_tmp == 2
28012 || disamb_tmp == 4)) { // cell is not a split cell but a 7.3 cell. here, the additional split surfaces are
28013 // created and connected
28014 for(MInt face = 0; face < 6; face++) {
28015 if(face != splitFaceId2) continue;
28016 if(!faceCut[face]) continue;
28017 sideId = face % 2;
28018 spaceId = face / 2;
28019 if(nfs_cur[face]) {
28020 if(m_solver->a_hasNeighbor(cellId, face) > 0)
28021 nghbrId = m_solver->c_neighborId(cellId, face);
28022 else {
28023 if(m_solver->c_parentId(cellId) > -1) {
28024 if(m_solver->a_hasNeighbor(m_solver->c_parentId(cellId), face) > 0)
28025 nghbrId = m_solver->c_neighborId(m_solver->c_parentId(cellId), face);
28026 else
28027 continue;
28028 } else
28029 continue;
28030 }
28031 if(m_solver->c_noChildren(nghbrId) > 0) continue;
28032 otherSideId = (sideId + 1) % 2;
28033 // first surface
28034 srfcId = m_solver->a_noSurfaces();
28035 m_surfaces.append();
28036 m_solver->a_surfaceOrientation(srfcId) = spaceId;
28037 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
28038 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId;
28039 for(MInt dim = 0; dim < nDim; dim++) {
28040 m_solver->a_surfaceCoordinate(srfcId, dim) = splitFaceCentroid2[0][dim];
28041 }
28042 m_solver->a_surfaceArea(srfcId) = splitFaceVolume2[0];
28043 m_splitSurfaces[splitSurfaceIndexCounter * 6] = srfcId;
28044 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 1] = splitCorner12;
28045 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 2] = splitCorner12 + neighborCorner[face];
28046 // second surface
28047 srfcId = m_solver->a_noSurfaces();
28048 m_surfaces.append();
28049 m_solver->a_surfaceOrientation(srfcId) = spaceId;
28050 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
28051 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId;
28052 for(MInt dim = 0; dim < nDim; dim++) {
28053 m_solver->a_surfaceCoordinate(srfcId, dim) = splitFaceCentroid2[1][dim];
28054 }
28055 m_solver->a_surfaceArea(srfcId) = splitFaceVolume2[1];
28056 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 3] = srfcId;
28057 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 3 + 1] = splitCorner22;
28058 m_splitSurfaces[splitSurfaceIndexCounter * 6 + 3 + 2] = splitCorner22 + neighborCorner[face];
28059 // set associated Srfc Pointer
28060 m_bndryCells->a[bndryId].m_associatedSrfc[face] = -splitSurfaceIndexCounter;
28061 splitSurfaceIndexCounter++;
28062 } else {
28063 stringstream errorMessage;
28064 errorMessage << "Error in FvBndryCnd3D::createCutFaceMGC - 3. Problem with face " << face << endl;
28065 errorMessage << "bndryId: " << bndryId << endl;
28066 errorMessage << "cellId: " << cellId << endl;
28067 errorMessage << "bndryCnd: " << m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
28068 errorMessage << "case, subcase: " << currentCase << ", " << currentSubCase << endl;
28069 errorMessage << "disamb: " << disambiguation[bndryId] << endl;
28070 errorMessage << "face Volumes: " << faceVolume[0] << ", " << faceVolume[1] << ", " << faceVolume[2] << ", "
28071 << faceVolume[3] << ", " << faceVolume[4] << ", " << faceVolume[5] << endl;
28072 errorMessage << "faceCentroids: ";
28073 for(MInt i = 0; i < 6; i++) {
28074 errorMessage << faceCentroid[i][0] << ", " << faceCentroid[i][1] << ", " << faceCentroid[i][2] << "; "
28075 << endl;
28076 }
28077 errorMessage << "area_c = " << area_c << endl;
28078 errorMessage << "normalVec_c = " << normalVec_c[0] << ", " << normalVec_c[1] << ", " << normalVec_c[2]
28079 << endl;
28080 errorMessage << "coordinates_c = " << coordinates_c[0] << ", " << coordinates_c[1] << ", "
28081 << coordinates_c[2] << endl;
28082 errorMessage << "coordinates_Cell = " << coordinates_Cell[0] << ", " << coordinates_Cell[1] << ", "
28083 << coordinates_Cell[2] << endl;
28084 errorMessage << "volume_C = " << volume_C << endl;
28085 mTerm(1, AT_, errorMessage.str());
28086 }
28087 }
28088 }
28089 if(splitCell[bndryId]) { // first cell has been connected in standard routine above
28090 for(MInt face = 0; face < 6; face++) {
28091 m_bndryCells->a[bndryId2].m_associatedSrfc[face] = -1;
28092 if(!faceCut_0[face]) continue;
28093 sideId = face % 2;
28094 spaceId = face / 2;
28095 if(nfs_cur_0[face]) {
28096 // Timw: consider cellId2 as a SplitChild
28097 MInt splitChildId = cellId2;
28098 if(m_solver->a_hasProperty(cellId2, SolverCell::IsSplitClone))
28099 cellId2 = m_solver->m_splitChildToSplitCell.find(cellId2)->second;
28100 if(m_solver->a_hasNeighbor(cellId2, face) > 0)
28101 nghbrId = m_solver->c_neighborId(cellId2, face);
28102 else {
28103 if(m_solver->c_parentId(cellId2) > -1) {
28104 if(m_solver->a_hasNeighbor(m_solver->c_parentId(cellId2), face) > 0)
28105 nghbrId = m_solver->c_neighborId(m_solver->c_parentId(cellId2), face);
28106 else
28107 continue;
28108 } else
28109 continue;
28110 }
28111 cellId2 = splitChildId;
28112 if(m_solver->c_noChildren(nghbrId) > 0) continue;
28113 otherSideId = (sideId + 1) % 2;
28114 srfcId = m_solver->a_noSurfaces();
28115 m_surfaces.append();
28116 m_solver->a_surfaceOrientation(srfcId) = spaceId;
28117 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
28118 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId2;
28119 for(MInt dim = 0; dim < nDim; dim++) {
28120 m_solver->a_surfaceCoordinate(srfcId, dim) = faceCentroid_0[face][dim];
28121 }
28122 m_solver->a_surfaceArea(srfcId) = faceVolume_0[face];
28123 m_bndryCells->a[bndryId2].m_associatedSrfc[face] = srfcId;
28124 } else {
28125 stringstream errorMessage;
28126 errorMessage << "Error in FvBndryCnd3D::createCutFaceMGC - 4. Problem with face " << face << endl;
28127 errorMessage << "bndryId: " << bndryId2 << endl;
28128 errorMessage << "cellId: " << cellId2 << endl;
28129 errorMessage << "split cell! Twin: " << bndryId << endl;
28130 errorMessage << "bndryCnd: " << m_bndryCells->a[bndryId2].m_srfcs[0]->m_bndryCndId;
28131 errorMessage << "case, subcase: " << currentCase << ", " << currentSubCase << endl;
28132 errorMessage << "disamb: " << disambiguation[bndryId] << endl;
28133 errorMessage << "face Volumes: " << faceVolume_0[0] << ", " << faceVolume_0[1] << ", " << faceVolume_0[2]
28134 << ", " << faceVolume_0[3] << ", " << faceVolume_0[4] << ", " << faceVolume_0[5] << endl;
28135 errorMessage << "faceCentroids: ";
28136 for(MInt i = 0; i < 6; i++) {
28137 errorMessage << faceCentroid_0[i][0] << ", " << faceCentroid_0[i][1] << ", " << faceCentroid_0[i][2]
28138 << "; " << endl;
28139 }
28140 errorMessage << "area_c = " << area_c << endl;
28141 errorMessage << "normalVec_c = " << normalVec_c[0] << ", " << normalVec_c[1] << ", " << normalVec_c[2]
28142 << endl;
28143 errorMessage << "coordinates_c = " << coordinates_c[0] << ", " << coordinates_c[1] << ", "
28144 << coordinates_c[2] << endl;
28145 errorMessage << "coordinates_Cell = " << coordinates_Cell[0] << ", " << coordinates_Cell[1] << ", "
28146 << coordinates_Cell[2] << endl;
28147 errorMessage << "volume_C = " << volume_C << endl;
28148 mTerm(1, AT_, errorMessage.str());
28149 }
28150 }
28151 }
28152 // split3 cell:
28153 if(currentCase == 7 && disamb_tmp == 7) {
28154 for(MInt face = 0; face < 6; face++) {
28155 m_bndryCells->a[bndryId3].m_associatedSrfc[face] = -1;
28156 if(!faceCut_00[face]) continue;
28157 sideId = face % 2;
28158 spaceId = face / 2;
28159 if(nfs_cur_00[face]) {
28160 // Timw: consider cellId3 as a SplitChild
28161 MInt splitChildId = cellId3;
28162 if(m_solver->a_hasProperty(cellId3, SolverCell::IsSplitClone))
28163 cellId3 = m_solver->m_splitChildToSplitCell.find(cellId3)->second;
28164 if(m_solver->a_hasNeighbor(cellId3, face) > 0)
28165 nghbrId = m_solver->c_neighborId(cellId3, face);
28166 else {
28167 if(m_solver->c_parentId(cellId3) > -1) {
28168 if(m_solver->a_hasNeighbor(m_solver->c_parentId(cellId3), face) > 0)
28169 nghbrId = m_solver->c_neighborId(m_solver->c_parentId(cellId3), face);
28170 else
28171 continue;
28172 } else
28173 continue;
28174 }
28175 cellId3 = splitChildId;
28176 if(m_solver->c_noChildren(nghbrId) > 0) continue;
28177 otherSideId = (sideId + 1) % 2;
28178 srfcId = m_solver->a_noSurfaces();
28179 m_surfaces.append();
28180 m_solver->a_surfaceOrientation(srfcId) = spaceId;
28181 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
28182 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId3;
28183 for(MInt dim = 0; dim < nDim; dim++) {
28184 m_solver->a_surfaceCoordinate(srfcId, dim) = faceCentroid_00[face][dim];
28185 }
28186 m_solver->a_surfaceArea(srfcId) = faceVolume_00[face];
28187 m_bndryCells->a[bndryId3].m_associatedSrfc[face] = srfcId;
28188 } else {
28189 stringstream errorMessage;
28190 errorMessage << "Error in FvBndryCnd3D::createCutFaceMGC - 5. Problem with face " << face << endl;
28191 errorMessage << "bndryId: " << bndryId3 << endl;
28192 errorMessage << "cellId: " << cellId3 << endl;
28193 errorMessage << "split cell! Twin (triple): " << bndryId << endl;
28194 errorMessage << "bndryCnd: " << m_bndryCells->a[bndryId3].m_srfcs[0]->m_bndryCndId;
28195 errorMessage << "case, subcase: " << currentCase << ", " << currentSubCase << endl;
28196 errorMessage << "disamb: " << disambiguation[bndryId] << endl;
28197 errorMessage << "face Volumes: " << faceVolume_00[0] << ", " << faceVolume_00[1] << ", " << faceVolume_00[2]
28198 << ", " << faceVolume_00[3] << ", " << faceVolume_00[4] << ", " << faceVolume_00[5] << endl;
28199 errorMessage << "faceCentroids: ";
28200 for(MInt i = 0; i < 6; i++) {
28201 errorMessage << faceCentroid_00[i][0] << ", " << faceCentroid_00[i][1] << ", " << faceCentroid_00[i][2]
28202 << "; " << endl;
28203 }
28204 errorMessage << "area_c = " << area_c << endl;
28205 errorMessage << "normalVec_c = " << normalVec_c[0] << ", " << normalVec_c[1] << ", " << normalVec_c[2]
28206 << endl;
28207 errorMessage << "coordinates_c = " << coordinates_c[0] << ", " << coordinates_c[1] << ", "
28208 << coordinates_c[2] << endl;
28209 errorMessage << "coordinates_Cell = " << coordinates_Cell[0] << ", " << coordinates_Cell[1] << ", "
28210 << coordinates_Cell[2] << endl;
28211 mTerm(1, AT_, errorMessage.str());
28212 }
28213 }
28214 }
28215
28216 for(MInt face = 0; face < 6; face++) {
28217 if(!nfs_cur[face]) {
28218 m_bndryCells->a[bndryId].m_externalFaces[face] = true;
28219 }
28220 }
28221 if(splitCell[bndryId]) {
28222 for(MInt face = 0; face < 6; face++) {
28223 if(!nfs_cur_0[face]) {
28224 m_bndryCells->a[bndryId2].m_externalFaces[face] = true;
28225 }
28226 }
28227 }
28228 if(currentCase == 7 && disamb_tmp == 7) {
28229 for(MInt face = 0; face < 6; face++) {
28230 if(!nfs_cur_00[face]) {
28231 m_bndryCells->a[bndryId3].m_externalFaces[face] = true;
28232 }
28233 }
28234 }
28235 } else {
28236 m_bndryCells->a[bndryId].m_noSrfcs = 1;
28237 stringstream fileName;
28238 switch(currentCase) {
28239 case 0:
28240 cerr << "FvBndryCnd3D::createCutFaceMGC - Error: Cell is not a boundary cell!" << endl;
28241 cerr << "CellId: " << cellId << " BndryId: " << bndryId << endl;
28242 cerr << "Cell level: " << m_solver->a_level(cellId) << endl;
28243 fileName << cellId << ".stl";
28244 writeStlFileOfCell(cellId, (fileName.str()).c_str());
28245 cerr << "Wrote stl-file of cell. FileName: " << (fileName.str()) << endl;
28246 break;
28247 case 1: {
28248 // cerr << "Case 1 detected. Starting Cutface computation..." << endl;
28249 for(MInt face = 0; face < 6; face++) {
28250 nfs_cur[face] = nfs1[currentSubCase][face];
28251 }
28252 p_0 = corner[cornersMCtoSOLVER[tiling1STL[currentSubCase][0]]];
28253 noFaces = 3;
28254 if(currentSubCase < 8) { // 1 Point is inside, 5 Points are outside
28255 } else { // 1 Point is outside, 5 Points are inside
28256 for(MInt i = 0; i < 6; i++) {
28257 faceVolume_0[i] = faceVolume[i];
28258 for(MInt j = 0; j < 3; j++) {
28259 faceCentroid_0[i][j] = faceCentroid[i][j];
28260 }
28261 }
28262 }
28263 cutDummy = edgesMCtoSOLVER[tiling1STL[currentSubCase][1]];
28264 p_1 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28265 cutDummy = edgesMCtoSOLVER[tiling1STL[currentSubCase][2]];
28266 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28267 cutDummy = edgesMCtoSOLVER[tiling1STL[currentSubCase][3]];
28268 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28269 face1 = facesMCtoSOLVER[tiling1STL[currentSubCase][4]];
28270 face2 = facesMCtoSOLVER[tiling1STL[currentSubCase][5]];
28271 face3 = facesMCtoSOLVER[tiling1STL[currentSubCase][6]];
28272
28273 computeTri(p_0, p_1, p_3, &faceVolume[face1], faceCentroid[face1]);
28274 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2]);
28275 computeTri(p_0, p_2, p_1, &faceVolume[face3], faceCentroid[face3]);
28276
28277 computePoly3(p_1, p_2, p_3, &area_c, coordinates_c, normalVec_c);
28278
28279 computeTetra(p_0, p_1, p_2, p_3, &volume_C, coordinates_Cell);
28280
28281 if(currentSubCase >= 8) {
28282 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
28283 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
28284 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
28285
28286 correctCell(&volume_C, coordinates_Cell, &gridCellVolume, &m_solver->a_coordinate(cellId, 0));
28287
28288 correctNormal(normalVec_c);
28289 }
28290
28291 m_bndryCells->a[bndryId].m_volume = volume_C;
28292 // create 1 Cut face
28293 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
28294 for(MInt dim = 0; dim < 3; dim++) {
28295 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
28296 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
28297 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
28298 }
28299 } break;
28300 case 2: {
28301 // cerr << "Case 2 detected. Starting Cutface computation..." << endl;
28302 for(MInt face = 0; face < 6; face++) {
28303 nfs_cur[face] = nfs2[currentSubCase][face];
28304 }
28305 noFaces = 4;
28306 p_0 = corner[cornersMCtoSOLVER[tiling2STL[currentSubCase][0]]];
28307 p_0s = corner[cornersMCtoSOLVER[tiling2STL[currentSubCase][1]]];
28308 if(currentSubCase < 12) { // 2 Points are inside, 4 Points are outside
28309 } else { // 2 Points are outside, 4 Points are inside
28310 for(MInt i = 0; i < 6; i++) {
28311 faceVolume_0[i] = faceVolume[i];
28312 for(MInt j = 0; j < 3; j++) {
28313 faceCentroid_0[i][j] = faceCentroid[i][j];
28314 }
28315 }
28316 }
28317
28318 cutDummy = edgesMCtoSOLVER[tiling2STL[currentSubCase][2]];
28319 p_3 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28320 cutDummy = edgesMCtoSOLVER[tiling2STL[currentSubCase][3]];
28321 p_2 = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28322 cutDummy = edgesMCtoSOLVER[tiling2STL[currentSubCase][4]];
28323 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28324 cutDummy = edgesMCtoSOLVER[tiling2STL[currentSubCase][5]];
28325 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28326 face1 = facesMCtoSOLVER[tiling2STL[currentSubCase][6]];
28327 face2 = facesMCtoSOLVER[tiling2STL[currentSubCase][7]];
28328 face3 = facesMCtoSOLVER[tiling2STL[currentSubCase][8]];
28329 face4 = facesMCtoSOLVER[tiling2STL[currentSubCase][9]];
28330
28331 computeTri(p_0, p_3, p_2, &faceVolume[face2], faceCentroid[face2], normal[face2]);
28332 computeTri(p_0s, p_3s, p_2s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
28333 computeTrapez(p_0, p_0s, p_3s, p_3, &faceVolume[face1], faceCentroid[face1], normal[face1]);
28334 computeTrapez(p_2, p_2s, p_0s, p_0, &faceVolume[face4], faceCentroid[face4], normal[face4]);
28335
28336 computePoly4(p_3, p_3s, p_2s, p_2, &area_c, coordinates_c, normalVec_c);
28337
28338 maia::math::vecAvg<3>(M, p_0, p_0s, p_2, p_2s, p_3, p_3s);
28339
28340 for(MInt i = 0; i < 4; i++) {
28341 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
28342 &pyraVolume[i], pyraCentroid[i]);
28343 }
28344 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[4], pyraCentroid[4]);
28345 for(MInt i = 0; i < 5; i++) {
28346 volume_C += pyraVolume[i];
28347 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
28348 }
28349 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
28350
28351 if(currentSubCase >= 12) {
28352 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
28353 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
28354 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
28355 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
28356
28357 correctCell(&volume_C, coordinates_Cell, &gridCellVolume, &m_solver->a_coordinate(cellId, 0));
28358
28359 correctNormal(normalVec_c);
28360 }
28361
28362 m_bndryCells->a[bndryId].m_volume = volume_C;
28363 // create 1 Cut face
28364 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
28365 for(MInt dim = 0; dim < 3; dim++) {
28366 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
28367 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
28368 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
28369 }
28370 } break;
28371 case 5: {
28372 // cerr << "Case 5 detected. Starting Cutface computation..." << endl;
28373 for(MInt face = 0; face < 6; face++) {
28374 nfs_cur[face] = nfs5[currentSubCase][face];
28375 }
28376 noFaces = 5;
28377 p_0 = corner[cornersMCtoSOLVER[tiling5STL[currentSubCase][0]]];
28378 p_1 = corner[cornersMCtoSOLVER[tiling5STL[currentSubCase][1]]];
28379 p_2 = corner[cornersMCtoSOLVER[tiling5STL[currentSubCase][2]]];
28380 if(currentSubCase < 24) { // 3 Points are inside, 5 Points are outside
28381 } else { // 3 Points are outside, 5 Points are inside
28382 for(MInt i = 0; i < 6; i++) {
28383 faceVolume_0[i] = faceVolume[i];
28384 for(MInt j = 0; j < 3; j++) {
28385 faceCentroid_0[i][j] = faceCentroid[i][j];
28386 }
28387 }
28388 }
28389
28390 cutDummy = edgesMCtoSOLVER[tiling5STL[currentSubCase][3]];
28391 p_0s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28392 cutDummy = edgesMCtoSOLVER[tiling5STL[currentSubCase][4]];
28393 p_0ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28394 cutDummy = edgesMCtoSOLVER[tiling5STL[currentSubCase][5]];
28395 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28396 cutDummy = edgesMCtoSOLVER[tiling5STL[currentSubCase][6]];
28397 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28398 cutDummy = edgesMCtoSOLVER[tiling5STL[currentSubCase][7]];
28399 p_2ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28400 face1 = facesMCtoSOLVER[tiling5STL[currentSubCase][8]];
28401 face2 = facesMCtoSOLVER[tiling5STL[currentSubCase][9]];
28402 face3 = facesMCtoSOLVER[tiling5STL[currentSubCase][10]];
28403 face4 = facesMCtoSOLVER[tiling5STL[currentSubCase][11]];
28404 face5 = facesMCtoSOLVER[tiling5STL[currentSubCase][12]];
28405
28406 computePoly5(p_0, p_0ss, p_2ss, p_2, p_1, &faceVolume[face1], faceCentroid[face1], normal[face1]);
28407 computeTri(p_0ss, p_0, p_0s, &faceVolume[face2], faceCentroid[face2], normal[face2]);
28408 computeTrapez(p_0, p_1, p_1s, p_0s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
28409 computeTrapez(p_1, p_1s, p_2s, p_2, &faceVolume[face4], faceCentroid[face4], normal[face4]);
28410 computeTri(p_2s, p_2, p_2ss, &faceVolume[face5], faceCentroid[face5], normal[face5]);
28411
28412 computePoly5(p_0s, p_1s, p_2s, p_2ss, p_0ss, &area_c, coordinates_c, normalVec_c);
28413
28414 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_0s, p_1s, p_2s, p_0ss, p_2ss);
28415
28416 for(MInt i = 0; i < 5; i++) {
28417 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
28418 &pyraVolume[i], pyraCentroid[i]);
28419 }
28420 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[5], pyraCentroid[5]);
28421 for(MInt i = 0; i < 6; i++) {
28422 volume_C += pyraVolume[i];
28423 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
28424 }
28425 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
28426
28427 if(currentSubCase >= 24) {
28428 correctFace(&faceVolume[face1], faceCentroid[face1], &faceVolume_0[face1], faceCentroid_0[face1]);
28429 correctFace(&faceVolume[face2], faceCentroid[face2], &faceVolume_0[face2], faceCentroid_0[face2]);
28430 correctFace(&faceVolume[face3], faceCentroid[face3], &faceVolume_0[face3], faceCentroid_0[face3]);
28431 correctFace(&faceVolume[face4], faceCentroid[face4], &faceVolume_0[face4], faceCentroid_0[face4]);
28432 correctFace(&faceVolume[face5], faceCentroid[face5], &faceVolume_0[face5], faceCentroid_0[face5]);
28433
28434 correctCell(&volume_C, coordinates_Cell, &gridCellVolume, &m_solver->a_coordinate(cellId, 0));
28435
28436 correctNormal(normalVec_c);
28437 }
28438
28439 m_bndryCells->a[bndryId].m_volume = volume_C;
28440 // create 1 Cut face
28441 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
28442 for(MInt dim = 0; dim < 3; dim++) {
28443 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
28444 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
28445 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
28446 }
28447 } break;
28448 case 8: {
28449 // cerr << "Case 8 detected. Starting Cutface computation..." << endl;
28450 for(MInt face = 0; face < 6; face++) {
28451 nfs_cur[face] = nfs8[currentSubCase][face];
28452 }
28453 noFaces = 4;
28454 p_0 = corner[cornersMCtoSOLVER[tiling8STL[currentSubCase][0]]];
28455 p_1 = corner[cornersMCtoSOLVER[tiling8STL[currentSubCase][1]]];
28456 p_2 = corner[cornersMCtoSOLVER[tiling8STL[currentSubCase][2]]];
28457 p_3 = corner[cornersMCtoSOLVER[tiling8STL[currentSubCase][3]]];
28458
28459 cutDummy = edgesMCtoSOLVER[tiling8STL[currentSubCase][4]];
28460 p_0s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28461 cutDummy = edgesMCtoSOLVER[tiling8STL[currentSubCase][5]];
28462 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28463 cutDummy = edgesMCtoSOLVER[tiling8STL[currentSubCase][6]];
28464 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28465 cutDummy = edgesMCtoSOLVER[tiling8STL[currentSubCase][7]];
28466 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28467 face5 = facesMCtoSOLVER[tiling8STL[currentSubCase][8]];
28468 face1 = facesMCtoSOLVER[tiling8STL[currentSubCase][9]];
28469 face2 = facesMCtoSOLVER[tiling8STL[currentSubCase][10]];
28470 face3 = facesMCtoSOLVER[tiling8STL[currentSubCase][11]];
28471 face4 = facesMCtoSOLVER[tiling8STL[currentSubCase][12]];
28472
28473 computeTrapez(p_0, p_1, p_1s, p_0s, &faceVolume[face1], faceCentroid[face1], normal[face1]);
28474 computeTrapez(p_1, p_2, p_2s, p_1s, &faceVolume[face2], faceCentroid[face2], normal[face2]);
28475 computeTrapez(p_2, p_3, p_3s, p_2s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
28476 computeTrapez(p_3, p_0, p_0s, p_3s, &faceVolume[face4], faceCentroid[face4], normal[face4]);
28477
28478 computeTrapez(p_0, p_3, p_2, p_1, &faceVolume[face5], faceCentroid[face5], normal[face5]);
28479
28480 computePoly4(p_0s, p_1s, p_2s, p_3s, &area_c, coordinates_c, normalVec_c);
28481
28482 maia::math::vecAvg<3>(M, p_0, p_0s, p_1, p_1s, p_2, p_2s, p_3, p_3s);
28483
28484 for(MInt i = 0; i < 5; i++) {
28485 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
28486 &pyraVolume[i], pyraCentroid[i]);
28487 }
28488 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[5], pyraCentroid[5]);
28489 for(MInt i = 0; i < 6; i++) {
28490 volume_C += pyraVolume[i];
28491 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
28492 }
28493 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
28494
28495 m_bndryCells->a[bndryId].m_volume = volume_C;
28496 // create 1 Cut face
28497 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
28498 for(MInt dim = 0; dim < 3; dim++) {
28499 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
28500 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
28501 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
28502 }
28503 } break;
28504 case 9: {
28505 // cerr << "Case 9 detected. Starting Cutface computation..." << endl;
28506 for(MInt face = 0; face < 6; face++) {
28507 nfs_cur[face] = nfs9[currentSubCase][face];
28508 }
28509 noFaces = 6;
28510 p_0 = corner[cornersMCtoSOLVER[tiling9STL[currentSubCase][0]]];
28511 p_1 = corner[cornersMCtoSOLVER[tiling9STL[currentSubCase][1]]];
28512 p_2 = corner[cornersMCtoSOLVER[tiling9STL[currentSubCase][2]]];
28513 p_3 = corner[cornersMCtoSOLVER[tiling9STL[currentSubCase][3]]];
28514
28515 cutDummy = edgesMCtoSOLVER[tiling9STL[currentSubCase][4]];
28516 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28517 cutDummy = edgesMCtoSOLVER[tiling9STL[currentSubCase][5]];
28518 p_1ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28519 cutDummy = edgesMCtoSOLVER[tiling9STL[currentSubCase][6]];
28520 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28521 cutDummy = edgesMCtoSOLVER[tiling9STL[currentSubCase][7]];
28522 p_2ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28523 cutDummy = edgesMCtoSOLVER[tiling9STL[currentSubCase][8]];
28524 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28525 cutDummy = edgesMCtoSOLVER[tiling9STL[currentSubCase][9]];
28526 p_3ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28527 face1 = facesMCtoSOLVER[tiling9STL[currentSubCase][10]];
28528 face2 = facesMCtoSOLVER[tiling9STL[currentSubCase][11]];
28529 face3 = facesMCtoSOLVER[tiling9STL[currentSubCase][12]];
28530 face4 = facesMCtoSOLVER[tiling9STL[currentSubCase][13]];
28531 face5 = facesMCtoSOLVER[tiling9STL[currentSubCase][14]];
28532 face6 = facesMCtoSOLVER[tiling9STL[currentSubCase][15]];
28533
28534 computePoly5(p_0, p_3, p_3ss, p_2s, p_2, &faceVolume[face1], faceCentroid[face1], normal[face1]);
28535 computePoly5(p_0, p_1, p_1ss, p_3s, p_3, &faceVolume[face3], faceCentroid[face3], normal[face3]);
28536 computePoly5(p_0, p_2, p_2ss, p_1s, p_1, &faceVolume[face5], faceCentroid[face5], normal[face5]);
28537 computeTri(p_1, p_1s, p_1ss, &faceVolume[face2], faceCentroid[face2], normal[face2]);
28538 computeTri(p_2, p_2s, p_2ss, &faceVolume[face4], faceCentroid[face4], normal[face4]);
28539 computeTri(p_3, p_3s, p_3ss, &faceVolume[face6], faceCentroid[face6], normal[face6]);
28540
28541 computePoly6(p_1ss, p_1s, p_2ss, p_2s, p_3ss, p_3s, &area_c, coordinates_c, normalVec_c);
28542
28543 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_3, p_1s, p_2s, p_3s, p_1ss, p_2ss, p_3ss);
28544
28545 for(MInt i = 0; i < 6; i++) {
28546 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
28547 &pyraVolume[i], pyraCentroid[i]);
28548 }
28549 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[6], pyraCentroid[6]);
28550 for(MInt i = 0; i < 7; i++) {
28551 volume_C += pyraVolume[i];
28552 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
28553 }
28554 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
28555
28556 m_bndryCells->a[bndryId].m_volume = volume_C;
28557 // create 1 Cut face
28558 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
28559 for(MInt dim = 0; dim < 3; dim++) {
28560 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
28561 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
28562 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
28563 }
28564 }
28565
28566 break;
28567 case 11: {
28568 // cerr << "Case 11 detected. Starting Cutface computation..." << endl;
28569 for(MInt face = 0; face < 6; face++) {
28570 nfs_cur[face] = nfs11[currentSubCase][face];
28571 }
28572 noFaces = 6;
28573 p_0 = corner[cornersMCtoSOLVER[tiling11STL[currentSubCase][0]]];
28574 p_1 = corner[cornersMCtoSOLVER[tiling11STL[currentSubCase][1]]];
28575 p_2 = corner[cornersMCtoSOLVER[tiling11STL[currentSubCase][2]]];
28576 p_3 = corner[cornersMCtoSOLVER[tiling11STL[currentSubCase][3]]];
28577
28578 cutDummy = edgesMCtoSOLVER[tiling11STL[currentSubCase][4]];
28579 p_0s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28580 cutDummy = edgesMCtoSOLVER[tiling11STL[currentSubCase][5]];
28581 p_0ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28582 cutDummy = edgesMCtoSOLVER[tiling11STL[currentSubCase][6]];
28583 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28584 cutDummy = edgesMCtoSOLVER[tiling11STL[currentSubCase][7]];
28585 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28586 cutDummy = edgesMCtoSOLVER[tiling11STL[currentSubCase][8]];
28587 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28588 cutDummy = edgesMCtoSOLVER[tiling11STL[currentSubCase][9]];
28589 p_3ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28590 face1 = facesMCtoSOLVER[tiling11STL[currentSubCase][10]];
28591 face2 = facesMCtoSOLVER[tiling11STL[currentSubCase][11]];
28592 face3 = facesMCtoSOLVER[tiling11STL[currentSubCase][12]];
28593 face4 = facesMCtoSOLVER[tiling11STL[currentSubCase][13]];
28594 face5 = facesMCtoSOLVER[tiling11STL[currentSubCase][14]];
28595 face6 = facesMCtoSOLVER[tiling11STL[currentSubCase][15]];
28596
28597 computeTri(p_0, p_0s, p_0ss, &faceVolume[face1], faceCentroid[face1], normal[face1]);
28598 computePoly5(p_3s, p_3, p_2, p_1, p_1s, &faceVolume[face2], faceCentroid[face2], normal[face2]);
28599 computeTrapez(p_2, p_3, p_3ss, p_2s, &faceVolume[face3], faceCentroid[face3], normal[face3]);
28600 computeTrapez(p_1, p_0, p_0ss, p_1s, &faceVolume[face4], faceCentroid[face4], normal[face4]);
28601 computePoly5(p_1, p_2, p_2s, p_0s, p_0, &faceVolume[face5], faceCentroid[face5], normal[face5]);
28602 computeTri(p_3, p_3s, p_3ss, &faceVolume[face6], faceCentroid[face6], normal[face6]);
28603
28604 computePoly6(p_0ss, p_0s, p_2s, p_3ss, p_3s, p_1s, &area_c, coordinates_c, normalVec_c);
28605
28606 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_3, p_0s, p_1s, p_2s, p_3s, p_0ss, p_3ss);
28607
28608 for(MInt i = 0; i < 6; i++) {
28609 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
28610 &pyraVolume[i], pyraCentroid[i]);
28611 }
28612 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[6], pyraCentroid[6]);
28613 for(MInt i = 0; i < 7; i++) {
28614 volume_C += pyraVolume[i];
28615 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
28616 }
28617 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
28618
28619 m_bndryCells->a[bndryId].m_volume = volume_C;
28620 // create 1 Cut face
28621 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
28622 for(MInt dim = 0; dim < 3; dim++) {
28623 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
28624 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
28625 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
28626 }
28627 break;
28628 }
28629 case 14: {
28630 // cerr << "Case 14 detected. Starting Cutface computation..." << endl;
28631 for(MInt face = 0; face < 6; face++) {
28632 nfs_cur[face] = nfs14[currentSubCase][face];
28633 }
28634 noFaces = 6;
28635 p_0 = corner[cornersMCtoSOLVER[tiling14STL[currentSubCase][0]]];
28636 p_1 = corner[cornersMCtoSOLVER[tiling14STL[currentSubCase][1]]];
28637 p_2 = corner[cornersMCtoSOLVER[tiling14STL[currentSubCase][2]]];
28638 p_3 = corner[cornersMCtoSOLVER[tiling14STL[currentSubCase][3]]];
28639
28640 cutDummy = edgesMCtoSOLVER[tiling14STL[currentSubCase][4]];
28641 p_0s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28642 cutDummy = edgesMCtoSOLVER[tiling14STL[currentSubCase][5]];
28643 p_0ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28644 cutDummy = edgesMCtoSOLVER[tiling14STL[currentSubCase][6]];
28645 p_1s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28646 cutDummy = edgesMCtoSOLVER[tiling14STL[currentSubCase][7]];
28647 p_2s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28648 cutDummy = edgesMCtoSOLVER[tiling14STL[currentSubCase][8]];
28649 p_3s = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28650 cutDummy = edgesMCtoSOLVER[tiling14STL[currentSubCase][9]];
28651 p_3ss = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[cutPoints[cutDummy]];
28652 face1 = facesMCtoSOLVER[tiling14STL[currentSubCase][10]];
28653 face2 = facesMCtoSOLVER[tiling14STL[currentSubCase][11]];
28654 face3 = facesMCtoSOLVER[tiling14STL[currentSubCase][12]];
28655 face4 = facesMCtoSOLVER[tiling14STL[currentSubCase][13]];
28656 face5 = facesMCtoSOLVER[tiling14STL[currentSubCase][14]];
28657 face6 = facesMCtoSOLVER[tiling14STL[currentSubCase][15]];
28658
28659 computeTri(p_0, p_0s, p_0ss, &faceVolume[face1], faceCentroid[face1], normal[face1]);
28660 computePoly5(p_2, p_3, p_3ss, p_1s, p_1, &faceVolume[face2], faceCentroid[face2], normal[face2]);
28661 computeTrapez(p_2s, p_3s, p_3, p_2, &faceVolume[face3], faceCentroid[face3], normal[face3]);
28662 computeTrapez(p_1s, p_0s, p_0, p_1, &faceVolume[face4], faceCentroid[face4], normal[face4]);
28663 computePoly5(p_2, p_1, p_0, p_0ss, p_2s, &faceVolume[face5], faceCentroid[face5], normal[face5]);
28664 computeTri(p_3, p_3s, p_3ss, &faceVolume[face6], faceCentroid[face6], normal[face6]);
28665
28666 computePoly6(p_0ss, p_0s, p_1s, p_3ss, p_3s, p_2s, &area_c, coordinates_c, normalVec_c);
28667
28668 maia::math::vecAvg<3>(M, p_0, p_1, p_2, p_3, p_0s, p_1s, p_2s, p_3s, p_0ss, p_3ss);
28669
28670 for(MInt i = 0; i < 6; i++) {
28671 computePyra(&faceVolume[*facepointers[i]], faceCentroid[*facepointers[i]], normal[*facepointers[i]], M,
28672 &pyraVolume[i], pyraCentroid[i]);
28673 }
28674 computePyra(&area_c, coordinates_c, normalVec_c, M, &pyraVolume[6], pyraCentroid[6]);
28675 for(MInt i = 0; i < 7; i++) {
28676 volume_C += pyraVolume[i];
28677 maia::math::vecAdd<3>(coordinates_Cell, vecScalarMul(pyraVolume[i], pyraCentroid[i], dummy_1));
28678 }
28679 vecScalarMul(F1 / volume_C, coordinates_Cell, coordinates_Cell);
28680
28681 m_bndryCells->a[bndryId].m_volume = volume_C;
28682 // create 1 Cut face
28683 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = area_c;
28684 for(MInt dim = 0; dim < 3; dim++) {
28685 m_bndryCells->a[bndryId].m_srfcs[0]->m_coordinates[dim] = coordinates_c[dim];
28686 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[dim] = normalVec_c[dim];
28687 m_bndryCells->a[bndryId].m_coordinates[dim] = coordinates_Cell[dim];
28688 }
28689
28690 break;
28691 }
28692 default: {
28693 stringstream errorMessage;
28694 errorMessage << "FvBndryCnd3D::createCutFaceMGC - Error: Inconsistent type implementation." << endl;
28695 mTerm(1, AT_, errorMessage.str());
28696 }
28697 }
28698
28699 absA = F0;
28700 for(MInt i = 0; i < nDim; i++) {
28701 // make sure faceVolume of non fluid sides is zero
28702 if(!nfs_cur[2 * i + 1]) faceVolume[2 * i + 1] = 0;
28703 if(!nfs_cur[2 * i]) faceVolume[2 * i] = 0;
28704 // correct coordinates - bndrycell coordinates are stored relative to cell coordinates
28705 m_bndryCells->a[bndryId].m_coordinates[i] -= m_solver->a_coordinate(cellId, i);
28706 // implicitly recompute the correct area and normal of the cut surface
28707 faceDiff[i] = faceVolume[2 * i + 1] - faceVolume[2 * i];
28708 absA += POW2(faceDiff[i]);
28709 }
28710 // This is only unique if the cut surface is planar. Otherwise, this is nevertheless a reasonnable choice.
28711 for(MInt i = 0; i < nDim; i++) {
28712 m_bndryCells->a[bndryId].m_srfcs[0]->m_normalVector[i] = faceDiff[i] / sqrt(absA);
28713 }
28714 m_bndryCells->a[bndryId].m_srfcs[0]->m_area = sqrt(absA);
28715
28716 // face data is assembled
28717 // create a surface for the cut face if a boundary cell neighbor exists
28718 for(MInt face = 0; face < 6; face++) {
28719 m_bndryCells->a[bndryId].m_associatedSrfc[face] = -1;
28720 for(MInt i = 0; i < noFaces; i++) {
28721 if(!(*facepointers[i] == face)) continue;
28722 sideId = face % 2;
28723 spaceId = face / 2;
28724 if(nfs_cur[face]) {
28725 if(m_solver->a_hasNeighbor(cellId, face) > 0) {
28726 nghbrId = m_solver->c_neighborId(cellId, face);
28727 } else {
28728 if(m_solver->c_parentId(cellId) > -1) {
28729 if(m_solver->a_hasNeighbor(m_solver->c_parentId(cellId), face) > 0)
28730 nghbrId = m_solver->c_neighborId(m_solver->c_parentId(cellId), face);
28731 else
28732 continue;
28733 } else
28734 continue;
28735 }
28736 if(m_solver->c_noChildren(nghbrId) > 0) continue;
28737 otherSideId = (sideId + 1) % 2;
28738 srfcId = m_solver->a_noSurfaces();
28739 m_surfaces.append();
28740 m_solver->a_surfaceOrientation(srfcId) = spaceId;
28741 m_solver->a_surfaceNghbrCellId(srfcId, sideId) = nghbrId;
28742 m_solver->a_surfaceNghbrCellId(srfcId, otherSideId) = cellId;
28743 for(MInt dim = 0; dim < nDim; dim++) {
28744 m_solver->a_surfaceCoordinate(srfcId, dim) = faceCentroid[face][dim];
28745 }
28746 m_solver->a_surfaceArea(srfcId) = faceVolume[face];
28747 m_bndryCells->a[bndryId].m_associatedSrfc[face] = srfcId;
28748 break;
28749 } else {
28750 stringstream errorMessage;
28751 errorMessage << " Error in FvBndryCnd3D::createCutFaceMGC - 6. Problem with face " << face << endl;
28752 errorMessage << "bndryId: " << bndryId << endl;
28753 errorMessage << "cellId: " << cellId << endl;
28754 errorMessage << "bndryCnd: " << m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
28755 errorMessage << "case, subcase: " << currentCase << ", " << currentSubCase << endl;
28756 errorMessage << "face Volumes: " << faceVolume[0] << ", " << faceVolume[1] << ", " << faceVolume[2] << ", "
28757 << faceVolume[3] << ", " << faceVolume[4] << ", " << faceVolume[5] << endl;
28758 errorMessage << "faceCentroids: ";
28759 for(MInt j = 0; j < 6; j++) {
28760 errorMessage << faceCentroid[j][0] << ", " << faceCentroid[j][1] << ", " << faceCentroid[j][2] << "; "
28761 << endl;
28762 }
28763 errorMessage << "area_c = " << area_c << endl;
28764 errorMessage << "normalVec_c = " << normalVec_c[0] << ", " << normalVec_c[1] << ", " << normalVec_c[2]
28765 << endl;
28766 errorMessage << "coordinates_c = " << coordinates_c[0] << ", " << coordinates_c[1] << ", "
28767 << coordinates_c[2] << endl;
28768 errorMessage << "coordinates_Cell = " << coordinates_Cell[0] << ", " << coordinates_Cell[1] << ", "
28769 << coordinates_Cell[2] << endl;
28770 errorMessage << "volume_C = " << volume_C << endl;
28771 mTerm(1, AT_, errorMessage.str());
28772 }
28773 }
28774 }
28775 // set nonFluidSideIds
28776 for(MInt face = 0; face < 6; face++) {
28777 if(!nfs_cur[face]) {
28778 m_bndryCells->a[bndryId].m_externalFaces[face] = true;
28779 }
28780 }
28781 }
28782 }
28783
28784 // initialize bndryNghbrs array
28785 if(keepNghbrs) {
28786 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
28787 cellId = m_bndryCells->a[bndryId].m_cellId;
28788 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitClone)) {
28789 cellId = m_solver->m_splitChildToSplitCell.find(cellId)->second;
28791 }
28792 for(MInt dirId = 0; dirId < m_noDirs; dirId++) {
28793 m_bndryNghbrs[bndryId * m_noDirs * 2 + dirId * 2] = -1;
28794 if(m_solver->a_hasNeighbor(cellId, dirId) > 0)
28795 m_bndryNghbrs[bndryId * m_noDirs * 2 + dirId * 2] = m_solver->c_neighborId(cellId, dirId);
28796 m_bndryNghbrs[bndryId * m_noDirs * 2 + dirId * 2 + 1] = -1;
28797 }
28798 }
28799 }
28800
28801 // 5. Compute neighbor information for ambiguous cells
28802
28803 if(!keepNghbrs) {
28804 for(MInt ambId = 0; ambId < noAmbiguousCells; ambId++) {
28805 MInt bndryId = ambiguousCells[ambId];
28806 cellId = m_bndryCells->a[bndryId].m_cellId;
28807
28808 // a) Check cells which are splitCells without split surface
28809 if(splitCell[bndryId] && !splitFace[bndryId]) {
28810 // first update connections split relative cell
28811 for(MInt child = 0; child < 3; child++) {
28812 bndryId2 = m_splitChildren[bndryId * 3 + child];
28813 if(bndryId2 == -1) break;
28814 cellId2 = m_bndryCells->a[bndryId2].m_cellId;
28815 // cellId2 = splitRelatives[ambId];
28816 // bndryId2 = m_solver->a_bndryId(cellId2);
28817 for(MInt corn = 0; corn < 8; corn++) {
28818 if(cornerCellMapping[ambId * 8 + corn] == cellId2) { // this corner belongs to split relative cell!
28819 for(MInt f = 0; f < 3; f++) {
28820 faceTMP = cornerFaceMapping[corn * 3 + f];
28821 nghbrCellId = m_solver->c_neighborId(cellId2, faceTMP);
28822 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
28823 if(nghbrBndryId < 0) mTerm(1, AT_, "strange split cell neighbor");
28824 if(!splitCell[nghbrBndryId] && !splitFace[nghbrBndryId]) {
28825 // neighbor is not ambigous or not split/split surface -> forward and backward connections
28826 // forward connection is already alright, establish backward connection:
28827 // m_solver->c_neighborId(nghbrCellId, opposite[faceTMP]) = cellId2;
28828 srfcId = m_bndryCells->a[nghbrBndryId].m_associatedSrfc[opposite[faceTMP]];
28829 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == nghbrCellId) {
28830 m_solver->a_surfaceNghbrCellId(srfcId, 1) = cellId2;
28831 } else {
28832 m_solver->a_surfaceNghbrCellId(srfcId, 0) = cellId2;
28833 }
28834 } else { // establish forward connection. backward connection will be established by neighboring cell
28835 if(splitCell[nghbrBndryId]) {
28836 // connect to correct split relative of neighbor cell, both neighbor and surface neighbors
28837 // m_solver->c_neighborId(cellId2, faceTMP) = cornerCellMapping[ambIds[nghbrBndryId] * 8 + corn +
28838 // neighborCorner[faceTMP]];
28839 srfcId = m_bndryCells->a[bndryId2].m_associatedSrfc[faceTMP];
28840 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == cellId2) {
28841 m_solver->a_surfaceNghbrCellId(srfcId, 1) = m_solver->c_neighborId(cellId2, faceTMP);
28842 } else {
28843 m_solver->a_surfaceNghbrCellId(srfcId, 0) = m_solver->c_neighborId(cellId2, faceTMP);
28844 }
28845 } else if(splitFace[nghbrBndryId]) {
28846 // nothing has to be done (neighbor is already correct, surface neighbors too)
28847 }
28848 }
28849 }
28850 } else {
28851 // non fluid corner, do nothing
28852 }
28853 }
28854 // correct neighbors on non-fluid sides
28855 // for(MInt f = 0; f < m_noDirs; f++ ){
28856 // if( m_bndryCells->a[bndryId2].m_externalFaces[f]){
28857 // m_solver->c_neighborId(cellId2, f) = -1;
28858 // }
28859 // }
28860 }
28861
28862 // second update connections cell
28863 for(MInt corn = 0; corn < 8; corn++) {
28864 if(cornerCellMapping[ambId * 8 + corn] == cellId) { // this corner belongs to split relative cell!
28865 for(MInt f = 0; f < 3; f++) {
28866 faceTMP = cornerFaceMapping[corn * 3 + f];
28867 nghbrCellId = m_solver->c_neighborId(cellId, faceTMP);
28868 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
28869 if(!splitCell[nghbrBndryId] && !splitFace[nghbrBndryId]) {
28870 // neighbor is not ambigous or not split/split surface -> forward and backward connections
28871 // forward connection is already alright, establish backward connection:
28872 // should already be ok as nghbr cell and srfc are connected to base cell
28873 } else { // establish forward connection. backward connection will be established by neighboring cell
28874 if(splitCell[nghbrBndryId]) {
28875 // connect to correct split relative of neighbor cell, both neighbor and surface neighbors
28876 // m_solver->c_neighborId(cellId, faceTMP) = cornerCellMapping[ambIds[nghbrBndryId] * 8
28877 //+ corn + neighborCorner[faceTMP]];
28878 srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[faceTMP];
28879 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == cellId) {
28880 m_solver->a_surfaceNghbrCellId(srfcId, 1) = m_solver->c_neighborId(cellId, faceTMP);
28881 } else {
28882 m_solver->a_surfaceNghbrCellId(srfcId, 0) = m_solver->c_neighborId(cellId, faceTMP);
28883 }
28884 } else if(splitFace[nghbrBndryId]) {
28885 // nothing has to be done (neighbor is already correct, surface neighbors too)
28886 }
28887 }
28888 }
28889 } else {
28890 // non fluid corner, do nothing
28891 }
28892 }
28893 // // correct neighbors on non-fluid sides
28894 // for(MInt f = 0; f < m_noDirs; f++ ){
28895 // if( m_bndryCells->a[bndryId].m_externalFaces[f]){
28896 // m_solver->c_neighborId(cellId, f) = -1;
28897 // }
28898 // }
28899 }
28900
28901
28902 // b) Check cells which are no splitCells but with split surface
28903 if(!splitCell[bndryId] && splitFace[bndryId]) {
28904 for(MInt face = 0; face < 6; face++) {
28905 srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[face];
28906 // srfcId < -1: split surface, srfcId = -1: non fluid side or non cut surface -> do nothing. srfcId >= 0:
28907 // normal cut surface, check neighbor
28908 if(srfcId < -1) {
28909 // split surface
28910 nghbrCellId = m_solver->c_neighborId(cellId, face);
28911 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
28912 // connect first surface
28913 splitCorner1 = m_splitSurfaces[-srfcId * 6 + 1];
28914 splitCorner2 = m_splitSurfaces[-srfcId * 6 + 2];
28915 if(splitCell[nghbrBndryId]) {
28916 if(m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6], 0) == cellId)
28918 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
28919 else
28921 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
28922 } else if(splitFace[nghbrBndryId]) {
28923 // nothing has to be done (neighbor is already correct, surface neighbors too)
28924 } else {
28925 // should not happen
28926 stringstream errorMessage;
28927 errorMessage << " Error in FvBndryCnd3D::createCutFaceMGC::this should not happen! ";
28928 mTerm(1, AT_, errorMessage.str());
28929 }
28930
28931 // connect second surface
28932 splitCorner1 = m_splitSurfaces[-srfcId * 6 + 3 + 1];
28933 splitCorner2 = m_splitSurfaces[-srfcId * 6 + 3 + 2];
28934 if(splitCell[nghbrBndryId]) {
28935 if(m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6 + 3], 0) == cellId)
28936 m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6 + 3], 1) =
28937 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
28938 else
28939 m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6 + 3], 0) =
28940 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
28941 } else if(splitFace[nghbrBndryId]) {
28942 // nothing has to be done (neighbor is already correct, surface neighbors too)
28943 } else {
28944 // should not happen
28945 }
28946 } else if(srfcId >= 0) {
28947 // regular surface, check neighboring cells!
28948 nghbrCellId = m_solver->c_neighborId(cellId, face);
28949 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
28950 if(splitCell[nghbrBndryId]) {
28951 for(MInt i = 0; i < 4; i++) {
28952 if(cornerCellMapping[ambIds[nghbrBndryId] * 8 + faceCornerMapping[face * 6 + i]] == -1) {
28953 // non fluid corner, do nothing!
28954 } else {
28955 // set face neighbor and srfc neighbors
28956 // m_solver->c_neighborId(cellId, face) = cornerCellMapping[ambIds[nghbrBndryId]*8 +
28957 // faceCornerMapping[ face * 6 + i]];
28958 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == cellId)
28959 m_solver->a_surfaceNghbrCellId(srfcId, 1) = m_solver->c_neighborId(cellId, face);
28960 else
28961 m_solver->a_surfaceNghbrCellId(srfcId, 0) = m_solver->c_neighborId(cellId, face);
28962 break;
28963 }
28964 }
28965 } else if(splitFace[nghbrBndryId]) {
28966 // nothing has to be done (neighbor is already correct, surface neighbors too)
28967 } else {
28968 // everything alright, nothing has to be done.
28969 }
28970 }
28971 }
28972 }
28973 }
28974
28975
28976 } else {
28977 for(MInt ambId = 0; ambId < noAmbiguousCells; ambId++) {
28978 MInt bndryId = ambiguousCells[ambId];
28979 cellId = m_bndryCells->a[bndryId].m_cellId;
28980
28981 // a) Check cells which are splitCells without split surface
28982 if(splitCell[bndryId] && !splitFace[bndryId]) {
28983 // first update connections split relative cell
28984 for(MInt child = 0; child < 3; child++) {
28985 bndryId2 = m_splitChildren[bndryId * 3 + child];
28986 if(bndryId2 == -1) break;
28987 cellId2 = m_bndryCells->a[bndryId2].m_cellId;
28988 MInt splitCellId = cellId2;
28989 for(MInt corn = 0; corn < 8; corn++) {
28990 if(cornerCellMapping[ambId * 8 + corn] == cellId2) { // this corner belongs to split relative cell!
28991 for(MInt f = 0; f < 3; f++) {
28992 faceTMP = cornerFaceMapping[corn * 3 + f];
28993 if(m_solver->a_hasProperty(cellId2, SolverCell::IsSplitClone)) {
28994 cellId2 = m_solver->m_splitChildToSplitCell.find(cellId2)->second;
28995 }
28996 nghbrCellId = m_solver->c_neighborId(cellId2, faceTMP);
28997 if(!m_solver->a_hasNeighbor(cellId2, faceTMP) || nghbrCellId < 0) continue;
28998 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
28999 if(!splitCell[nghbrBndryId] && !splitFace[nghbrBndryId]) {
29000 // neighbor is not ambigous or not split/split surface -> forward and backward connections
29001 // forward connection is already alright (in m_nghbrIds), update m_bndryNghbrs, establish backward
29002 // connection:
29003 m_bndryNghbrs[nghbrBndryId * m_noDirs * 2 + opposite[faceTMP] * 2] = splitCellId;
29004 m_bndryNghbrs[bndryId2 * m_noDirs * 2 + faceTMP * 2] = nghbrCellId;
29005 srfcId = m_bndryCells->a[nghbrBndryId].m_associatedSrfc[opposite[faceTMP]];
29006 if(srfcId > -1) {
29007 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == nghbrCellId) {
29008 m_solver->a_surfaceNghbrCellId(srfcId, 1) = splitCellId;
29009 } else {
29010 m_solver->a_surfaceNghbrCellId(srfcId, 0) = splitCellId;
29011 }
29012 } else
29013 cerr << "no surf found " << m_solver->a_isHalo(splitCellId) << " "
29014 << m_solver->a_isHalo(nghbrCellId) << endl;
29015 } else { // establish forward connection. backward connection will be established by neighboring cell
29016 if(splitCell[nghbrBndryId]) {
29017 // connect to correct split relative of neighbor cell, both neighbor and surface neighbors
29018 m_bndryNghbrs[bndryId2 * m_noDirs * 2 + faceTMP * 2] =
29019 cornerCellMapping[ambIds[nghbrBndryId] * 8 + corn + neighborCorner[faceTMP]];
29020 srfcId = m_bndryCells->a[bndryId2].m_associatedSrfc[faceTMP];
29021 if(srfcId > -1) {
29022 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == splitCellId) {
29023 m_solver->a_surfaceNghbrCellId(srfcId, 1) =
29024 m_bndryNghbrs[bndryId2 * m_noDirs * 2 + faceTMP * 2];
29025 } else {
29026 m_solver->a_surfaceNghbrCellId(srfcId, 0) =
29027 m_bndryNghbrs[bndryId2 * m_noDirs * 2 + faceTMP * 2];
29028 }
29029 }
29030 } else if(splitFace[nghbrBndryId]) {
29031 // nothing has to be done (neighbor is already correct, surface neighbors too) -> update
29032 // m_bndryNghbrs, backward connection will be established by neighboring cell
29033 m_bndryNghbrs[bndryId2 * m_noDirs * 2 + faceTMP * 2] = nghbrCellId;
29034 }
29035 }
29036 }
29037 } else {
29038 // non fluid corner, do nothing
29039 }
29040 }
29041 // correct neighbors on non-fluid sides
29042 for(MInt f = 0; f < m_noDirs; f++) {
29043 if(m_bndryCells->a[bndryId2].m_externalFaces[f]) m_bndryNghbrs[bndryId2 * m_noDirs * 2 + f * 2] = -1;
29044 }
29045 }
29046
29047 // second update connections cell
29048 for(MInt corn = 0; corn < 8; corn++) {
29049 if(cornerCellMapping[ambId * 8 + corn] == cellId) { // this corner belongs to split cell!
29050 for(MInt f = 0; f < 3; f++) {
29051 faceTMP = cornerFaceMapping[corn * 3 + f];
29052 nghbrCellId = m_solver->c_neighborId(cellId, faceTMP);
29053 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
29054 if(!splitCell[nghbrBndryId] && !splitFace[nghbrBndryId]) {
29055 // neighbor is not ambigous or not split/split surface -> forward and backward connections
29056 // forward connection is already alright, establish backward connection:
29057 // should already be ok as nghbr cell and srfc are connected to base cell
29058 // update m_bndryNghbrs
29059 m_bndryNghbrs[bndryId * m_noDirs * 2 + faceTMP * 2] = nghbrCellId;
29060 m_bndryNghbrs[nghbrBndryId * m_noDirs * 2 + opposite[faceTMP] * 2] = cellId;
29061 } else { // establish forward connection. backward connection will be established by neighboring cell
29062 if(splitCell[nghbrBndryId]) {
29063 // connect to correct split relative of neighbor cell, both neighbor and surface neighbors
29064 m_bndryNghbrs[bndryId * m_noDirs * 2 + faceTMP * 2] =
29065 cornerCellMapping[ambIds[nghbrBndryId] * 8 + corn + neighborCorner[faceTMP]];
29066 srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[faceTMP];
29067 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == cellId) {
29068 m_solver->a_surfaceNghbrCellId(srfcId, 1) = m_bndryNghbrs[bndryId * m_noDirs * 2 + faceTMP * 2];
29069 } else {
29070 m_solver->a_surfaceNghbrCellId(srfcId, 0) = m_bndryNghbrs[bndryId * m_noDirs * 2 + faceTMP * 2];
29071 }
29072 } else if(splitFace[nghbrBndryId]) {
29073 m_bndryNghbrs[bndryId * m_noDirs * 2 + faceTMP * 2] = nghbrCellId;
29074 // nothing has to be done (neighbor is already correct, surface neighbors too)
29075 }
29076 }
29077 }
29078 } else {
29079 // non fluid corner, do nothing
29080 }
29081 }
29082 // correct neighbors on non-fluid sides
29083 for(MInt f = 0; f < m_noDirs; f++) {
29084 if(m_bndryCells->a[bndryId].m_externalFaces[f]) m_bndryNghbrs[bndryId * m_noDirs * 2 + f * 2] = -1;
29085 }
29086 }
29087
29088
29089 // b) Check cells which are no splitCells but with split surface
29090 if(!splitCell[bndryId] && splitFace[bndryId]) {
29091 for(MInt face = 0; face < 6; face++) {
29092 srfcId = m_bndryCells->a[bndryId].m_associatedSrfc[face];
29093 // srfcId < -1: split surface, srfcId = -1: non fluid side or non cut surface -> do nothing. srfcId >= 0:
29094 // normal cut surface, check neighbor
29095 if(srfcId < -1) {
29096 // split surface
29097 nghbrCellId = m_solver->c_neighborId(cellId, face);
29098 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
29099 // connect first surface
29100 splitCorner1 = m_splitSurfaces[-srfcId * 6 + 1];
29101 splitCorner2 = m_splitSurfaces[-srfcId * 6 + 2];
29102 if(splitCell[nghbrBndryId]) {
29103 m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2] =
29104 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
29105 if(m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6], 0) == cellId)
29107 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
29108 else
29110 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
29111 } else if(splitFace[nghbrBndryId]) {
29112 // nothing has to be done (neighbor is already correct, surface neighbors too)
29113 m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2] = nghbrCellId;
29114 } else {
29115 // should not happen
29116 stringstream errorMessage;
29117 errorMessage << " Error in FvBndryCnd3D::createCutFaceMGC::this should not happen! ";
29118 mTerm(1, AT_, errorMessage.str());
29119 }
29120
29121 // connect second surface
29122 splitCorner1 = m_splitSurfaces[-srfcId * 6 + 3 + 1];
29123 splitCorner2 = m_splitSurfaces[-srfcId * 6 + 3 + 2];
29124 if(splitCell[nghbrBndryId]) {
29125 // add second split neighbor as neighbor
29126 m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2 + 1] =
29127 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
29128 if(m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6 + 3], 0) == cellId)
29129 m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6 + 3], 1) =
29130 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
29131 else
29132 m_solver->a_surfaceNghbrCellId(m_splitSurfaces[-srfcId * 6 + 3], 0) =
29133 cornerCellMapping[ambIds[nghbrBndryId] * 8 + splitCorner2];
29134 } else if(splitFace[nghbrBndryId]) {
29135 // nothing has to be done (neighbor is already correct, surface neighbors too)
29136 m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2 + 1] = nghbrCellId;
29137 } else {
29138 // should not happen
29139 stringstream errorMessage;
29140 errorMessage << " Error in FvBndryCnd3D::createCutFaceMGC::this should not happen! ";
29141 mTerm(1, AT_, errorMessage.str());
29142 }
29143 } else if(srfcId >= 0) {
29144 // regular surface, check neighboring cells!
29145 nghbrCellId = m_solver->c_neighborId(cellId, face);
29146 nghbrBndryId = m_solver->a_bndryId(nghbrCellId);
29147 if(splitCell[nghbrBndryId]) {
29148 for(MInt i = 0; i < 4; i++) {
29149 if(cornerCellMapping[ambIds[nghbrBndryId] * 8 + faceCornerMapping[face * 6 + i]] == -1) {
29150 // non fluid corner, do nothing!
29151 } else {
29152 // set face neighbor and srfc neighbors
29153 m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2] =
29154 cornerCellMapping[ambIds[nghbrBndryId] * 8 + faceCornerMapping[face * 6 + i]];
29155 if(m_solver->a_surfaceNghbrCellId(srfcId, 0) == cellId)
29156 m_solver->a_surfaceNghbrCellId(srfcId, 1) = m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2];
29157 else
29158 m_solver->a_surfaceNghbrCellId(srfcId, 0) = m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2];
29159 break;
29160 }
29161 }
29162 } else {
29163 // everything alright, nothing has to be done.
29164 m_bndryNghbrs[bndryId * m_noDirs * 2 + face * 2] = nghbrCellId;
29165 }
29166 }
29167 }
29168 }
29169 }
29170
29171 // correct nonFluidSide neighbors
29172 if(keepNghbrs) {
29173 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
29174 cellId = m_bndryCells->a[bndryId].m_cellId;
29175 for(MInt f = 0; f < m_noDirs; f++) {
29176 if(m_bndryCells->a[bndryId].m_externalFaces[f]) {
29177 m_bndryNghbrs[bndryId * m_noDirs * 2 + f * 2] = -1;
29178 m_bndryNghbrs[bndryId * m_noDirs * 2 + f * 2 + 1] = -1;
29179 }
29180 }
29181 }
29182 }
29183 }
29184
29185#ifndef NDEBUG
29186 for(MInt i = 0; i < 15; i++) {
29187 cerr << "Occurences case " << i << " : " << presentCases[i] << " times" << endl;
29188 }
29189 cerr << "---------------------------------------------------------------" << endl << endl << endl;
29190 cerr << "Number Surfaces: " << m_solver->a_noSurfaces() << endl;
29191#endif
29192}
void computeTetra(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
MFloat * vecScalarMul(MFloat, MFloat *, MFloat *)
void computeTri(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
void computePoly5(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
void correctNormal(MFloat *)
void correctCell(MFloat *, MFloat *, MFloat *, MFloat *)
void correctFace(MFloat *, MFloat *, MFloat *, MFloat *)
void computePoly4(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
void computePoly6(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
MInt createSplitCell_MGC(MInt, MInt)
produces an exact copy of a fvcell and the respective boundary cell
void computeTrapez(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
void computePyra(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
void computePoly3(MFloat *, MFloat *, MFloat *, MFloat *, MFloat *, MFloat *)
void assertValidGridCellId(const MInt cellId) const
Cecks wether the cell cellId is an actual grid-cell.
T * getPointer() const
Deprecated: use begin() instead!
Definition: scratch.h:316
pointer p
Deprecated: use [] instead!
Definition: scratch.h:315

◆ createCutFaceMGC() [2/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==2, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::createCutFaceMGC ( )
inline

Definition at line 591 of file fvcartesianbndrycndxd.h.

591 {
592 TERMM(1, "MGC in 2D not implemented yet!");
593 }

◆ createSortedBndryCellList()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::createSortedBndryCellList

Definition at line 474 of file fvcartesianbndrycndxd.cpp.

474 {
475 TRACE();
476
477 MInt bc;
478 MInt size;
479 MInt noBndryCells = m_bndryCells->size();
480 MBool append = false;
481 //---
482
483 m_bndryCndCells[m_noBndryCndIds] = noBndryCells;
485 size = 0;
486 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
487 m_bndryCndCells[bcId] = size;
488 bc = m_bndryCndIds[bcId];
489 for(MInt id = 0; id < noBndryCells; id++) {
490 append = false;
491 for(MInt srfc = 0; srfc < m_bndryCells->a[id].m_noSrfcs; srfc++) {
492 if(m_bndryCells->a[id].m_srfcs[srfc]->m_bndryCndId == bc) {
493 append = true;
494 break;
495 }
496 }
497 if(append) {
499 m_sortedBndryCells->a[size] = id;
500 size++;
501 }
502 // //Debug
503 // MInt cellId = m_bndryCells->a[ m_sortedBndryCells->a[ bcId ] ].m_cellId;
504 // std::cout << "createSortedBndryCellList CellTemp: " << m_solver->a_pvariable(cellId,PV->P) <<
505 // std::endl;
506 }
507 }
509}
void append()
Definition: list.h:66
MInt setSize(MInt inputSize)
Definition: list.h:31

◆ createSplitCell_MGC()

template<MInt nDim, class SysEqn >
template<class _ , std::enable_if_t< nDim==3, _ * > >
MInt FvBndryCndXD< nDim, SysEqn >::createSplitCell_MGC ( MInt  cellId,
MInt  noSplitChilds 
)

FVCell must be a boundary cell.

Function is needed to handle split cells (cells that are cut into two separate parts by the geometry) -> each cell that is split gets an associated cell clone

Author
Claudia Guenther, Feb 2010 Update Tim Wegmann July 2018

Definition at line 29206 of file fvcartesianbndrycndxd.cpp.

29206 {
29207 TRACE();
29208
29209 MInt bndryId2, cellId2, bndryId;
29210 //-----------------------------------------
29211 MInt splitId = m_solver->m_splitCells.size();
29212 if(noSplitChilds > 1) {
29213 splitId = splitId - 1;
29214 m_solver->m_splitChilds[splitId].resize(noSplitChilds);
29215 } else {
29216 m_solver->m_splitCells.push_back(cellId);
29218 m_solver->m_splitChilds[splitId].resize(noSplitChilds);
29219 }
29220
29221 bndryId = m_solver->a_bndryId(cellId);
29222 bndryId2 = m_bndryCells->size();
29223 cellId2 = m_solver->a_noCells();
29224
29226 m_cells.append();
29228 ASSERT(cellId2 == m_solver->a_noCells() - 1, "Error in the cell-count, for splitchilds!");
29229
29230 m_solver->m_splitChilds[splitId][noSplitChilds - 1] = cellId2;
29231 m_solver->m_splitChildToSplitCell.insert(pair<MInt, MInt>(cellId2, cellId));
29232
29233 m_bndryCells->a[bndryId2].m_cellId = cellId2;
29234 m_solver->a_bndryId(cellId2) = bndryId2;
29235 m_solver->a_bndryId(cellId2) = bndryId2;
29236
29237 for(MInt face = 0; face < 6; face++) {
29238 m_bndryCells->a[bndryId2].m_associatedSrfc[face] = -1;
29239 m_bndryCells->a[bndryId2].m_externalFaces[face] = false;
29240 }
29241
29242 m_bndryCells->a[bndryId2].m_srfcs[0]->m_bndryCndId = m_bndryCells->a[bndryId].m_srfcs[0]->m_bndryCndId;
29243 m_bndryCells->a[bndryId2].m_srfcs[0]->m_noCutPoints = m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints;
29244
29245 for(MInt i = 0; i < m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints; i++) {
29246 m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutEdge[i] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[i];
29247 m_bndryCells->a[bndryId2].m_srfcs[0]->m_bodyId[i] = m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[i];
29248 for(MInt j = 0; j < nDim; j++)
29249 m_bndryCells->a[bndryId2].m_srfcs[0]->m_cutCoordinates[i][j] =
29250 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[i][j];
29251 }
29252
29253 for(MInt i = 0; i < nDim; i++) {
29254 m_solver->a_coordinate(cellId2, i) = m_solver->a_coordinate(cellId, i);
29255 }
29256 m_solver->a_isInterface(cellId2) = m_solver->a_isInterface(cellId);
29257
29258 m_solver->a_level(cellId2) = m_solver->a_level(cellId);
29259
29260 m_solver->a_copyPropertiesSolver(cellId, cellId2);
29261
29262 m_solver->a_hasProperty(cellId2, SolverCell::IsSplitCell) = false;
29263 m_solver->a_hasProperty(cellId2, SolverCell::IsSplitChild) = false;
29264 m_solver->a_hasProperty(cellId2, SolverCell::IsSplitClone) = true;
29265
29266 m_solver->a_hasProperty(cellId, SolverCell::IsSplitCell) = false;
29267 m_solver->a_hasProperty(cellId, SolverCell::IsSplitChild) = false;
29268 m_solver->a_hasProperty(cellId, SolverCell::IsSplitClone) = false;
29269
29270
29271 return cellId2;
29272}
std::vector< std::vector< MInt > > m_splitChilds
void a_copyPropertiesSolver(const MInt fromCellId, const MInt toCellId)
Returns property p of the cell cellId.
std::vector< MInt > m_splitCells

◆ createSpongeAtSpongeBndryCnds()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::createSpongeAtSpongeBndryCnds
Author
Stephan Schlimpert
Date
Januar 2011, Oktober, 2011

the sponge cells are automatically defined between the boundary edges (=sponge edges) d = direction for determing songe cells (1..5) s1,s3 = directions for determing edges of sponge boundaries (or maximum sponge coordinates within domain) s2 = direction for setting maximum sponge coordinate with the sponge Factor -> spongeCoord sponge cells "S" determined e.g. for NEGATIVE_XWALL (o = normal cells)

 |                 .                |
 |                 .                |
 |                 .                |
 |oooooooooooooooooooooooooooooooooo|
 |oooooooooooooooooooooooooooooooooo|
 |oooooSSSSSSSSSSSSSSSSSSSSSSSoooooo|
 |____ SSSSSSSSSSSSSSSSSSSSSSS _____|
      |SSSSSSSSSSSSSSSSSSSSSSS|
      |SSSSSSSSSSSSSSSSSSSSSSS|
      |SSSSSSSSSSSSSSSSSSSSSSS|                ^
      |SSSSSSSSSSSSSSSSSSSSSSS|                |

d=0,s1=0 |_______________________|

last change: 3D + parallel version

Todo:
labels:FV radial version, sponge region at outer edges (inner edges possible), general parallel version without normal restriction

Definition at line 3561 of file fvcartesianbndrycndxd.cpp.

3561 {
3562 TRACE();
3563
3564 MBool spongeCellsFound = false;
3565 MBool append = false;
3566 MInt bcSpId, spongeCellId;
3567 MInt noBndryCells = m_bndryCells->size();
3568 MInt s1 = -1, s2 = -1, s3 = -1; // for sponge coordinate area directions
3569 MFloat spongeCoordMin2 = F0, spongeCoordMax2 = F0, spongeCoordMin = F0, spongeCoordMax = F0, spongeCoordFace = F0;
3570 MInt cellId, currentSpongeCellId, oldSortedSpongeBndryCellsSize;
3571 MFloat maxSpongeFactor = 0.0, minSpongeFactor = 100.0, maxSpongeFactorOverlap = 0.0, minSpongeFactorOverlap = 100.0;
3572 MFloat cellFaceCoordinate = -11111.0;
3574 MInt count = 0; // number of sponge cells laying in three sponge zones
3575 MInt cntHalo = 0;
3576 MInt cntHaloInside = 0;
3577 MFloatScratchSpace distance(m_solver->a_noCells(), AT_, "distance");
3578 //---
3579
3582 for(MInt bcId = 0; bcId < m_noSpongeBndryCndIds; bcId++)
3583 m_spongeBndryCells[bcId] = 0;
3584
3585 // reseting sponge information
3586 for(MInt c = 0; c < m_solver->a_noCells(); c++) {
3587 m_solver->a_hasProperty(c, SolverCell::IsInSpongeLayer) = false;
3588 m_solver->a_spongeFactor(c) = F0;
3589 }
3590
3591 std::vector<MFloat> minSpongeCoords(2 * m_noSpongeBndryCndIds);
3592 std::vector<MFloat> maxSpongeCoords(2 * m_noSpongeBndryCndIds);
3593
3594 // find sponge cells at boundary (see "at cut off" below)
3595 for(MInt bcId = 0; bcId < m_noSpongeBndryCndIds; bcId++) {
3596 bcSpId = m_spongeBndryCndIds[bcId];
3597 spongeCellsFound = false;
3598 spongeCoordMin = 10000;
3599 spongeCoordMax = -10000;
3600 spongeCoordMin2 = 10000;
3601 spongeCoordMax2 = -10000;
3602 spongeCoordFace = -99999999.0;
3603 m_spongeCoord[bcId] = -99999999.0;
3604 cellFaceCoordinate = -11111.0;
3605 m_log << "*************************************************************" << endl;
3606 m_log << "Information for sponge boundary Id: " << bcSpId << endl;
3607 m_log << "*************************************************************" << endl;
3608
3609 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
3610 append = false;
3611 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
3612 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == bcSpId) {
3613 append = true;
3614 break; // append spongeCellId and go to next boundary cell
3615 }
3616 }
3617 if(append) {
3618 spongeCellId = m_bndryCells->a[bndryId].m_cellId;
3621 spongeCellsFound = true;
3622 m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer) = true;
3623 }
3624 }
3625 if(spongeCellsFound) {
3626 m_log << "Collecting " << m_sortedSpongeBndryCells->size() - m_spongeBndryCells[bcId]
3627 << " sponge cells at the boundary ... ";
3629 m_log << " ok" << endl;
3630 }
3631
3632 if(!spongeCellsFound) {
3633 // find sponge cells at cut off
3634 for(MInt bcCut = 0; bcCut < m_noCutOffBndryCndIds; bcCut++) {
3635 if(bcSpId != m_cutOffBndryCndIds[bcCut]) continue;
3636 spongeCellsFound = true; // not used here but for information that sponge cells are found here
3637 m_log << "Collecting ";
3638 for(MInt id = 0; id < m_sortedCutOffCells[bcCut]->size(); id++) {
3639 spongeCellId = m_sortedCutOffCells[bcCut]->a[id];
3642 m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer) = true;
3643 }
3646 << " sponge cells at the cut-off boundary ... ";
3647 m_log << " ok" << endl;
3648 break;
3649 }
3650 }
3651
3652 if(!spongeCellsFound || ((m_sortedSpongeBndryCells->size() - m_spongeBndryCells[bcId]) == 0)) {
3653 m_log << "sponge cells not yet found on domain " << domainId() << endl;
3654 m_spongeBndryCells[bcId + 1] = m_spongeBndryCells[bcId];
3655 }
3656 // reset the sponge factor to a positive value
3657 m_spongeFactor[bcId] = abs(m_spongeFactor[bcId]);
3658
3659 MInt vz = -1;
3660 switch(m_spongeDirections[bcId]) {
3661 case 1:
3662 m_log << "POSITIVE_XWALL" << endl;
3663 s1 = 1;
3664 s2 = 0;
3665 s3 = 2;
3666 vz = 0;
3667 m_spongeFactor[bcId] = -m_spongeFactor[bcId];
3668 break;
3669 case 0:
3670 m_log << "NEGATIVE_XWALL" << endl;
3671 s1 = 1;
3672 s2 = 0;
3673 s3 = 2;
3674 vz = 1;
3675 break;
3676 case 3:
3677 m_log << "POSITIVE_YWALL" << endl;
3678 s1 = 0;
3679 s2 = 1;
3680 s3 = 2;
3681 vz = 0;
3682 m_spongeFactor[bcId] = -m_spongeFactor[bcId];
3683 break;
3684 case 2:
3685 m_log << "NEGATIVE_YWALL" << endl;
3686 s1 = 0;
3687 s2 = 1;
3688 s3 = 2;
3689 vz = 1;
3690 break;
3691 case 5:
3692 m_log << "POSITIVE_ZWALL" << endl;
3693 s1 = 0;
3694 s2 = 2;
3695 s3 = 1;
3696 vz = 0;
3697 m_spongeFactor[bcId] = -m_spongeFactor[bcId];
3698 break;
3699 case 4:
3700 m_log << "NEGATIVE_ZWALL" << endl;
3701 s1 = 0;
3702 s2 = 2;
3703 s3 = 1;
3704 vz = 1;
3705 break;
3706 default: {
3707 mTerm(1, AT_, "wrong sponge direction selected");
3708 }
3709 }
3710 TERMM_IF_COND(vz != 0 && vz != 1, "ERROR: invalid coordinate orientation of sponge vz = " + std::to_string(vz));
3711
3712 IF_CONSTEXPR(nDim == 3) {
3713 // find min sponge edge - only for information
3714 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3716 cellFaceCoordinate = m_solver->a_coordinate(cellId, s3) - F1B2 * m_solver->c_cellLengthAtCell(cellId);
3717 spongeCoordMin2 = mMin(spongeCoordMin2, cellFaceCoordinate);
3718 }
3719
3720 // find max sponge edge - only for information
3721 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3723 cellFaceCoordinate = m_solver->a_coordinate(cellId, s3) + F1B2 * m_solver->c_cellLengthAtCell(cellId);
3724 spongeCoordMax2 = mMax(spongeCoordMax2, cellFaceCoordinate);
3725 }
3726
3727 // find min sponge edge - only for information
3728 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3730 cellFaceCoordinate = m_solver->a_coordinate(cellId, s1) - F1B2 * m_solver->c_cellLengthAtCell(cellId);
3731 spongeCoordMin = mMin(spongeCoordMin, cellFaceCoordinate);
3732 }
3733
3734 // find max sponge edge - only for information and define max sponge area in spongeCoordDirection
3735 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3737 halfCellWidth = F1B2 * m_solver->c_cellLengthAtCell(cellId);
3738 cellFaceCoordinate = m_solver->a_coordinate(cellId, s1) + halfCellWidth;
3739 if(spongeCoordMax < cellFaceCoordinate) {
3740 spongeCoordMax = cellFaceCoordinate;
3741 if(m_spongeFactor[bcId] > 0) {
3742 m_spongeCoord[bcId] =
3743 m_solver->a_coordinate(cellId, s2) + m_spongeLayerThickness * m_spongeFactor[bcId] - halfCellWidth;
3744 spongeCoordFace = m_solver->a_coordinate(cellId, s2) - halfCellWidth;
3745 } else {
3746 m_spongeCoord[bcId] =
3747 m_solver->a_coordinate(cellId, s2) + m_spongeLayerThickness * m_spongeFactor[bcId] + halfCellWidth;
3748 spongeCoordFace = m_solver->a_coordinate(cellId, s2) + halfCellWidth;
3749 }
3750 }
3751 }
3752
3753 if(noDomains() == 1) {
3754 if(approx(spongeCoordMin2, 10000.0, MFloatEps) || approx(spongeCoordMax2, -10000.0, MFloatEps)
3755 || approx(spongeCoordMin, 10000.0, MFloatEps) || approx(spongeCoordMax, -10000.0, MFloatEps)
3756 || approx(m_spongeCoord[bcId], -111111.0, MFloatEps)) {
3757 cerr << "Warning: sponge boundary Id " << bcSpId << " info ( rank " << domainId() << " ): " << endl;
3758 cerr << "Warning: boundary cell edge couldn't be found" << endl;
3759 cerr << "sponge edge coordinate[" << s3 << "] = " << spongeCoordMin2 << endl;
3760 cerr << "sponge edge coordinate[" << s3 << "] = " << spongeCoordMax2 << endl;
3761 cerr << "sponge edge coordinate[" << s1 << "] = " << spongeCoordMin << endl;
3762 cerr << "sponge edge coordinate[" << s1 << "] = " << spongeCoordMax << endl;
3763 cerr << "sponge cells defined up to coordinate[" << s2 << "] = " << m_spongeCoord[bcId] << endl;
3764 mTerm(1, AT_, "Warning: boundary cell edge couldn't be found");
3765 }
3766 }
3767 }
3768 else { // 2D code
3769 // find min sponge edge - only for information
3770 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3772 cellFaceCoordinate = m_solver->a_coordinate(cellId, s1) - F1B2 * m_solver->c_cellLengthAtCell(cellId);
3773 spongeCoordMin = mMin(spongeCoordMin, cellFaceCoordinate);
3774 }
3775
3776 // find max sponge edge - only for information and define max sponge area in spongeCoordDirection
3777 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3779 halfCellWidth = F1B2 * m_solver->c_cellLengthAtCell(cellId);
3780 cellFaceCoordinate = m_solver->a_coordinate(cellId, s1) + halfCellWidth;
3781 if(spongeCoordMax < cellFaceCoordinate) {
3782 spongeCoordMax = cellFaceCoordinate;
3783 if(m_spongeFactor[bcId] > 0) {
3784 m_spongeCoord[bcId] =
3785 m_solver->a_coordinate(cellId, s2) + m_spongeLayerThickness * m_spongeFactor[bcId] - halfCellWidth;
3786 spongeCoordFace = m_solver->a_coordinate(cellId, s2) - halfCellWidth;
3787 } else {
3788 m_spongeCoord[bcId] =
3789 m_solver->a_coordinate(cellId, s2) + m_spongeLayerThickness * m_spongeFactor[bcId] + halfCellWidth;
3790 spongeCoordFace = m_solver->a_coordinate(cellId, s2) + halfCellWidth;
3791 }
3792 }
3793 }
3794 if(noDomains() == 1) {
3795 if(approx(spongeCoordMin, 10000.0, MFloatEps) || approx(spongeCoordMax, -10000.0, MFloatEps)
3796 || approx(m_spongeCoord[bcId], -111111.0, MFloatEps)) {
3797 mTerm(1, AT_, " boundary cell edge couldn't be found");
3798 }
3799 }
3800 }
3801
3802
3803 // MPI exchange of sponge coordinates + sponge boundary Id + algorithm going over all cells
3804 MPI_Allreduce(MPI_IN_PLACE, &spongeCoordMin, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_, "MPI_IN_PLACE",
3805 "spongeCoordMin");
3806 MPI_Allreduce(MPI_IN_PLACE, &spongeCoordMax, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
3807 "spongeCoordMax");
3808 IF_CONSTEXPR(nDim == 3) {
3809 MPI_Allreduce(MPI_IN_PLACE, &spongeCoordMin2, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_, "MPI_IN_PLACE",
3810 "spongeCoordMin2");
3811 MPI_Allreduce(MPI_IN_PLACE, &spongeCoordMax2, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
3812 "spongeCoordMax2");
3813 }
3814 MPI_Allreduce(MPI_IN_PLACE, &m_spongeCoord[bcId], 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
3815 "m_spongeCoord[ bcId ]");
3816 MPI_Allreduce(MPI_IN_PLACE, &spongeCoordFace, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
3817 "spongeCoordFace");
3818
3819 IF_CONSTEXPR(nDim == 3) {
3820 m_log << "sponge edge coordinate[" << s3 << "] = " << spongeCoordMin2 << endl;
3821 m_log << "sponge edge coordinate[" << s3 << "] = " << spongeCoordMax2 << endl;
3822 }
3823 m_log << "sponge edge coordinate[" << s1 << "] = " << spongeCoordMin << endl;
3824 m_log << "sponge edge coordinate[" << s1 << "] = " << spongeCoordMax << endl;
3825 m_log << "sponge face coordinate[" << s2 << "] = " << spongeCoordFace << endl;
3826 m_log << "sponge cells defined up to coordinate[" << s2 << "] = " << m_spongeCoord[bcId] << endl;
3827
3828 minSpongeCoords[2 * bcId] = spongeCoordMin;
3829 minSpongeCoords[2 * bcId + 1] = spongeCoordMin2;
3830 maxSpongeCoords[2 * bcId] = spongeCoordMax;
3831 maxSpongeCoords[2 * bcId + 1] = spongeCoordMax2;
3832
3833 // Check for a previous sponge boundary in the same direction and prevent overwriting its
3834 // values Note: this does not work properly for more than 2 sponge boundaries in one direction
3835 const MInt dir = m_spongeDirections[bcId];
3836 MBool isAdditionalSpongeInDir = false;
3837 MInt firstSpongeBcIdInDir = -1;
3838 MInt firstSpongeIdInDir = -1;
3839 for(MInt i = 0; i < bcId; i++) {
3840 if(m_spongeDirections[i] == dir) {
3841 isAdditionalSpongeInDir = true;
3842 firstSpongeBcIdInDir = m_spongeBndryCndIds[i];
3843 firstSpongeIdInDir = i;
3844 break;
3845 }
3846 }
3847 if(isAdditionalSpongeInDir) {
3848 m_log << "additional sponge in direction " << dir << ", skipping cells with BC " << firstSpongeBcIdInDir
3849 << " intersection" << std::endl;
3850 }
3851
3852 // determine sponge cells
3853 m_log << "Creating ";
3854 oldSortedSpongeBndryCellsSize = m_spongeBndryCells[bcId + 1];
3855
3856 for(MInt id = 0; id < m_solver->a_noCells(); id++) {
3857 // continue for sponge cells at boundary, already in list
3858 if(m_solver->a_hasProperty(id, SolverCell::IsInSpongeLayer)) continue;
3859 if(m_solver->c_noChildren(id) > 0) continue;
3860
3861 if(vz == 0 && m_solver->a_coordinate(id, s2) < m_spongeCoord[bcId]) continue;
3862 if(vz == 1 && m_solver->a_coordinate(id, s2) > m_spongeCoord[bcId]) continue;
3863
3864 if(m_solver->a_coordinate(id, s1) > spongeCoordMax) continue;
3865 if(m_solver->a_coordinate(id, s1) < spongeCoordMin) continue;
3866 IF_CONSTEXPR(nDim == 3) {
3867 if(m_solver->a_coordinate(id, s3) > spongeCoordMax2) continue;
3868 if(m_solver->a_coordinate(id, s3) < spongeCoordMin2) continue;
3869 }
3870
3871 // Check for a bcId intersection if this an additional sponge in this direction
3872 if(isAdditionalSpongeInDir) {
3873 std::set<MInt> bcIds;
3874 MFloat line[2 * nDim];
3875 const MFloat halfLength = 0.5 * m_solver->c_cellLengthAtCell(id);
3876
3877 MBool skip = false;
3878
3879 // TODO labels:FV speedup by checking bounding box of additional sponge in direction
3880 MBool insideBox = true;
3881 {
3882 const MFloat pos1 = m_solver->a_coordinate(id, s1);
3883 const MFloat pos2 = m_solver->a_coordinate(id, s3);
3884 const MInt offset = 2 * firstSpongeIdInDir;
3885 if(pos1 + halfLength < minSpongeCoords[offset] || pos1 - halfLength > maxSpongeCoords[offset]) {
3886 insideBox = false;
3887 } else if(pos2 + halfLength < minSpongeCoords[offset + 1]
3888 || pos2 - halfLength > maxSpongeCoords[offset + 1]) {
3889 insideBox = false;
3890 }
3891 }
3892
3893 // Loop over all cell corner coordinates in the boundary plane
3894 if(insideBox) {
3895 const MFloat outDir = (vz == 0) ? 1.0 : -1.0;
3896 for(MInt i = 0; i < 2 && !skip; i++) {
3897 for(MInt j = 0; j < (nDim - 1) && !skip; j++) {
3898 std::copy_n(&m_solver->a_coordinate(id, 0), nDim, &line[0]);
3899 std::copy_n(&m_solver->a_coordinate(id, 0), nDim, &line[nDim]);
3900 // Second point lies outside the geometry
3901 line[s2] = line[s2] + outDir * 2 * m_solver->c_cellLengthAtLevel(0);
3902
3903 line[s1] -= pow(-1.0, i) * halfLength;
3904 line[s1 + nDim] = line[s1];
3905
3906 IF_CONSTEXPR(nDim == 3) {
3907 line[s3] -= pow(-1.0, j) * halfLength;
3908 line[s3 + nDim] = line[s3];
3909 }
3910
3911 // Get boundary condition ids cut by the line from the cell corner through the
3912 // boundary plane and check if the first sponge-bc id is present and skip if so
3913 m_solver->m_geometry->getLineIntersectingElementsBcIds(line, bcIds);
3914 if(bcIds.size() > 0 && (bcIds.count(firstSpongeBcIdInDir) > 0)) {
3915 skip = true;
3916 }
3917 }
3918 }
3919 }
3920 if(skip) continue;
3921 }
3922
3925 }
3927 // reseting property 14, will be set later and needed for spongefactor calculation
3928 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3929 currentSpongeCellId = m_sortedSpongeBndryCells->a[id];
3930 m_solver->a_hasProperty(currentSpongeCellId, SolverCell::IsInSpongeLayer) = false;
3931 }
3932
3933 if(noDomains() == 0) {
3934 if(oldSortedSpongeBndryCellsSize == m_sortedSpongeBndryCells->size()) {
3935 m_log << "Warning: Only first row of sponge boundary ID " << m_spongeBndryCndIds[bcId]
3936 << " was identified as sponge cells" << endl;
3937 m_log << " Possible reason could be that the spongeFactor has to be multiplied by -1" << endl;
3938 m_log << " Possible reason could be wrong sponge coordinates communicated" << endl;
3939 cerr << "Warning: Only first row of sponge boundary ID " << m_spongeBndryCndIds[bcId]
3940 << " was identified as sponge cells" << endl;
3941 cerr << " Possible reason could be that the spongeFactor has to be multiplied by -1" << endl;
3942 cerr << " Possible reason could be wrong sponge coordinates communicated" << endl;
3943 }
3944 }
3945 m_log << m_sortedSpongeBndryCells->size() - oldSortedSpongeBndryCellsSize << " additional sponge cells ... ";
3946 m_log << " ok" << endl;
3948 m_log << "total number of sponge cells " << m_spongeBndryCells[bcId + 1] - m_spongeBndryCells[bcId] << endl;
3949 m_log << "*************************************************" << endl << endl;
3950 MInt startBcId = 0;
3951 MInt endBcId = bcId;
3952
3953 // setting sponge information for all other sponge boundary ids, which were already identified to identifiy
3954 // overlapping sponge cells and sponge boundary ids
3955 for(MInt id = m_spongeBndryCells[startBcId]; id < m_spongeBndryCells[endBcId]; id++) {
3956 spongeCellId = m_sortedSpongeBndryCells->a[id];
3957 m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer) = true;
3958 }
3959
3960 switch(m_spongeLayerLayout) {
3961 case 0: {
3962 const MFloat spongeThicknessEpsilon = m_spongeLayerThickness / 10000000.0;
3963 MFloat spongeEpsilon = m_solver->c_cellLengthAtLevel(m_solver->maxRefinementLevel()) / 1000.0;
3964 MFloat beta = m_spongeBeta;
3965 MFloat constant;
3966 MFloat spongeFactorBcId = m_spongeLayerThickness * abs(m_spongeFactor[bcId]);
3967 MFloat spongeDistanceFactor = F1 / (mMax(spongeEpsilon, spongeFactorBcId));
3968 MFloat spongeDistance = F0;
3969
3970 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
3971 bcSpId = m_spongeBndryCndIds[bcId];
3972 spongeCellId = m_sortedSpongeBndryCells->a[id];
3973 if(m_solver->a_isHalo(spongeCellId)) cntHalo++;
3974 // compute the max sigma sponge value if already identified in one sponge area
3975 if(m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer)) {
3976 // compute the distance to the spongeCoordinate
3977 spongeDistance = abs(m_solver->a_coordinate(spongeCellId, s2) - m_spongeCoord[bcId]) * spongeDistanceFactor;
3978 distance.p[spongeCellId] = mMax(distance.p[spongeCellId], spongeDistance);
3979 // compute the dissipation function...
3980 // if(bcSpId==17616)
3981 // constant = tanh(distance.p[spongeCellId]*5.0);
3982 // else
3983 constant = pow(distance.p[spongeCellId], beta);
3984 constant *= m_sigmaSpongeBndryId[bcId];
3985
3986 // if distance to small than sponge cell keeps the spongeFactor that it already owns
3987 if(distance.p[spongeCellId] > spongeThicknessEpsilon) {
3988 if(m_solver->a_spongeBndryId(spongeCellId, 1) == -1) {
3989 // second sponge Id of the sponge cell which lays in two sponge areas
3990 m_solver->a_spongeBndryId(spongeCellId, 1) = bcSpId;
3991 // compute the max sponge Factor for sponge cells which are laying in two sponge areas
3992 m_solver->a_spongeFactor(spongeCellId) = mMax(constant, m_solver->a_spongeFactor(spongeCellId));
3993 } else if(nDim == 3 && m_solver->a_spongeBndryId(spongeCellId, 2) == -1) {
3994 // third sponge Id of the sponge cell which lays in third sponge areas (only possible for 3 dimensional
3995 // cases)
3996 m_solver->a_spongeBndryId(spongeCellId, 2) = bcSpId;
3997 m_solver->a_spongeFactor(spongeCellId) = mMax(constant, m_solver->a_spongeFactor(spongeCellId));
3998 if(!m_solver->a_isHalo(spongeCellId)) count++;
3999 IF_CONSTEXPR(nDim == 2) {
4000 cerr << "ERROR: three sponge boundary Ids: " << m_solver->a_spongeBndryId(spongeCellId, 0) << ", "
4001 << m_solver->a_spongeBndryId(spongeCellId, 1) << ", ";
4002 cerr << m_solver->a_spongeBndryId(spongeCellId, 2)
4003 << "founded for one cell -> not possible for 2 dimensional case" << endl;
4004 stringstream errorMessage;
4005 errorMessage << " three sponge boundary Ids: " << m_solver->a_spongeBndryId(spongeCellId, 0) << ", "
4006 << m_solver->a_spongeBndryId(spongeCellId, 1) << ", "
4007 << m_solver->a_spongeBndryId(spongeCellId, 2)
4008 << "founded for one cell -> not possible for 2 dimensional case";
4009 mTerm(1, AT_, errorMessage.str());
4010 }
4011 } else {
4012 stringstream errorMessage;
4013 IF_CONSTEXPR(nDim == 3) {
4014 errorMessage << "four sponge boundary Ids: " << m_solver->a_spongeBndryId(spongeCellId, 0) << ", "
4015 << m_solver->a_spongeBndryId(spongeCellId, 1) << ", "
4016 << m_solver->a_spongeBndryId(spongeCellId, 2) << ", " << bcSpId
4017 << "founded for one cell -> not possible for 3 dimensional case";
4018 }
4019 else {
4020 errorMessage << "three sponge boundary Ids: " << m_solver->a_spongeBndryId(spongeCellId, 0) << ", "
4021 << m_solver->a_spongeBndryId(spongeCellId, 1) << ", " << bcSpId
4022 << "founded for one cell -> not possible for 2 dimensional case";
4023 }
4024 mTerm(1, AT_, errorMessage.str());
4025 }
4026 if(m_solver->m_spongeTimeDependent[bcId] > 0)
4027 m_solver->a_spongeFactorStart(spongeCellId) = m_solver->a_spongeFactor(spongeCellId);
4028
4029 maxSpongeFactorOverlap = mMax(maxSpongeFactorOverlap, m_solver->a_spongeFactor(spongeCellId));
4030 minSpongeFactorOverlap = mMin(minSpongeFactorOverlap, m_solver->a_spongeFactor(spongeCellId));
4031 // if(!(m_solver->a_spongeFactor(spongeCellId))<=0 && !(m_solver->a_spongeFactor(spongeCellId)) >=0)
4032 // cerr << m_solver->a_spongeFactor(spongeCellId)<< endl;
4033 }
4034 } else { // cells which are not already identified as sponge cells
4035
4036 m_solver->a_spongeFactor(spongeCellId) = F0;
4037 // compute the distance to the spongeCoordinate
4038 distance.p[spongeCellId] =
4039 abs(m_solver->a_coordinate(spongeCellId, s2) - m_spongeCoord[bcId]) * spongeDistanceFactor;
4040 // compute the dissipation function...
4041 // if(bcSpId==17616)
4042 // constant = tanh(distance.p[spongeCellId]*5.0);
4043 // else
4044 constant = pow(distance.p[spongeCellId], beta);
4045 constant *= m_sigmaSpongeBndryId[bcId];
4046
4047 if(distance.p[spongeCellId] > spongeThicknessEpsilon) {
4050 if(m_solver->a_isHalo(spongeCellId)) cntHaloInside++;
4051
4052 m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer) = true;
4053 m_solver->a_spongeFactor(spongeCellId) = constant;
4054 if(m_solver->m_spongeTimeDependent[bcId] > 0) m_solver->a_spongeFactorStart(spongeCellId) = constant;
4055
4056 m_solver->a_spongeBndryId(spongeCellId, 0) = bcSpId;
4057 m_solver->a_spongeBndryId(spongeCellId, 1) =
4058 -1; // second possible sponge Id if the cell is laying in two sponge areas
4059 // for 3 dimensional case
4060 IF_CONSTEXPR(nDim == 3) {
4061 m_solver->a_spongeBndryId(spongeCellId, 2) =
4062 -1; // third possible sponge Id if the cell is laying in two sponge areas
4063 }
4064 // if(!(m_solver->a_spongeFactor( spongeCellId ))<=0 && !(m_solver->a_spongeFactor( spongeCellId )) >=0)
4065 // {
4066 // cerr << m_solver->a_spongeFactor( spongeCellId ) << endl;
4067 // mTerm(1,AT_);
4068 // }
4069 maxSpongeFactor = mMax(maxSpongeFactor, m_solver->a_spongeFactor(spongeCellId));
4070 minSpongeFactor = mMin(minSpongeFactor, m_solver->a_spongeFactor(spongeCellId));
4071 }
4072 }
4073 }
4074 break;
4075 }
4076 // tanh function for sponge forcing
4077 case 10: {
4078 const MFloat spongeThicknessEpsilon = m_spongeLayerThickness / 10000000.0;
4079 MFloat spongeEpsilon = m_solver->c_cellLengthAtLevel(m_solver->maxRefinementLevel()) / 1000.0;
4080 MFloat constant;
4081 MFloat spongeFactorBcId = m_spongeLayerThickness * abs(m_spongeFactor[bcId]);
4082 MFloat spongeDistanceFactor = F1 / (mMax(spongeEpsilon, spongeFactorBcId));
4083 MFloat spongeDistance = F0;
4084 /*
4085 if(m_spongeBndryCndIds[bcId]==17616 && m_solver->m_spongeTimeDependent[bcId]>0){
4086 MString errorMessage="check code for bcId 17616 and sponge time dependent because tanh function for
4087 spongeFactor calc is used"; mTerm(AT_,1,errorMessage);
4088 }
4089 */
4090 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
4091 bcSpId = m_spongeBndryCndIds[bcId];
4092 spongeCellId = m_sortedSpongeBndryCells->a[id];
4093 if(m_solver->a_isHalo(spongeCellId)) cntHalo++;
4094 // compute the max sigma sponge value if already identified in one sponge area
4095 if(m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer)) {
4096 // compute the distance to the spongeCoordinate
4097 spongeDistance = abs(m_solver->a_coordinate(spongeCellId, s2) - m_spongeCoord[bcId]) * spongeDistanceFactor;
4098 distance.p[spongeCellId] = mMax(distance.p[spongeCellId], spongeDistance);
4099 // compute the dissipation function...
4100 constant = F1 - F1B2 * tanh(5.0) + F1B2 * tanh((F2 * (distance.p[spongeCellId]) - F1) * 5.0);
4101 constant *= m_sigmaSpongeBndryId[bcId];
4102 // if distance to small than sponge cell keeps the spongeFactor that it already owns
4103 if(distance.p[spongeCellId] > spongeThicknessEpsilon) {
4104 if(m_solver->a_spongeBndryId(spongeCellId, 1) == -1) {
4105 // second sponge Id of the sponge cell which lays in two sponge areas
4106 m_solver->a_spongeBndryId(spongeCellId, 1) = bcSpId;
4107 // compute the max sponge Factor for sponge cells which are laying in two sponge areas
4108 m_solver->a_spongeFactor(spongeCellId) = mMax(constant, m_solver->a_spongeFactor(spongeCellId));
4109 } else if(nDim == 3 && m_solver->a_spongeBndryId(spongeCellId, 2) == -1) {
4110 // third sponge Id of the sponge cell which lays in third sponge areas (only possible for 3 dimensional
4111 // cases)
4112 m_solver->a_spongeBndryId(spongeCellId, 2) = bcSpId;
4113 m_solver->a_spongeFactor(spongeCellId) = mMax(constant, m_solver->a_spongeFactor(spongeCellId));
4114 if(!m_solver->a_isHalo(spongeCellId)) count++;
4115 IF_CONSTEXPR(nDim == 2) {
4116 cerr << "ERROR: three sponge boundary Ids: " << m_solver->a_spongeBndryId(spongeCellId, 0) << ", "
4117 << m_solver->a_spongeBndryId(spongeCellId, 1) << ", ";
4118 cerr << m_solver->a_spongeBndryId(spongeCellId, 2)
4119 << "founded for one cell -> not possible for 2 dimensional case" << endl;
4120 mTerm(1, AT_);
4121 }
4122 } else {
4123 cerr << "ERROR: four sponge boundary Ids: " << m_solver->a_spongeBndryId(spongeCellId, 0) << ", "
4124 << m_solver->a_spongeBndryId(spongeCellId, 1) << ", ";
4125 cerr << m_solver->a_spongeBndryId(spongeCellId, 2) << ", " << bcSpId
4126 << "founded for one cell -> not possible for 3 dimensional case" << endl;
4127 mTerm(1, AT_);
4128 }
4129
4130 if(m_solver->m_spongeTimeDependent[bcId] > 0)
4131 m_solver->a_spongeFactorStart(spongeCellId) = m_solver->a_spongeFactor(spongeCellId);
4132
4133 maxSpongeFactorOverlap = mMax(maxSpongeFactorOverlap, m_solver->a_spongeFactor(spongeCellId));
4134 minSpongeFactorOverlap = mMin(minSpongeFactorOverlap, m_solver->a_spongeFactor(spongeCellId));
4135 // if(!(m_solver->a_spongeFactor( spongeCellId))<=0 && !(m_solver->a_spongeFactor( spongeCellId)) >=0)
4136 // cerr << m_solver->a_spongeFactor(spongeCellId) << endl;
4137 }
4138 } else { // cells which are not already identified as sponge cells
4139
4140 m_solver->a_spongeFactor(spongeCellId) = F0;
4141 // compute the distance to the spongeCoordinate
4142 distance.p[spongeCellId] =
4143 abs(m_solver->a_coordinate(spongeCellId, s2) - m_spongeCoord[bcId]) * spongeDistanceFactor;
4144 // compute the dissipation function...
4145 constant =
4146 F1 - F1B2 * tanh(5.0) + F1B2 * tanh((F2 * (distance.p[spongeCellId]) - F1) * 5.0); // stephans tanh
4147 // constant = POW2(distance.p[spongeCellId]); // standard x^2
4148 // constant = F1B2 - F1B2*cos(PI*distance.p[spongeCellId]);
4149
4150 constant *= m_sigmaSpongeBndryId[bcId];
4151
4152 if(distance.p[spongeCellId] > spongeThicknessEpsilon) {
4155 if(m_solver->a_isHalo(spongeCellId)) cntHaloInside++;
4156
4157 m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer) = true;
4158 m_solver->a_spongeFactor(spongeCellId) = constant;
4159 if(m_solver->m_spongeTimeDependent[bcId] > 0) m_solver->a_spongeFactorStart(spongeCellId) = constant;
4160
4161 m_solver->a_spongeBndryId(spongeCellId, 0) = bcSpId;
4162 m_solver->a_spongeBndryId(spongeCellId, 1) =
4163 -1; // second possible sponge Id if the cell is laying in two sponge areas
4164 // for 3 dimensional case
4165 IF_CONSTEXPR(nDim == 3) {
4166 m_solver->a_spongeBndryId(spongeCellId, 2) =
4167 -1; // third possible sponge Id if the cell is laying in two sponge areas
4168 }
4169 // if(!(m_solver->a_spongeFactor( spongeCellId ))<=0 && !(m_solver->a_spongeFactor( spongeCellId )) >=0)
4170 // {
4171 // cerr << m_solver->a_spongeFactor( spongeCellId ) << endl;
4172 // mTerm(1,AT_);
4173 // }
4174 maxSpongeFactor = mMax(maxSpongeFactor, m_solver->a_spongeFactor(spongeCellId));
4175 minSpongeFactor = mMin(minSpongeFactor, m_solver->a_spongeFactor(spongeCellId));
4176 }
4177 }
4178 }
4179 break;
4180 }
4181 default: {
4182 stringstream errorMessage;
4183 errorMessage << "ERROR: spongeLayerLayout " << m_spongeLayerLayout << " does not exist!" << endl;
4184 mTerm(1, AT_, errorMessage.str());
4185 }
4186 }
4187 // reseting sponge information of all boundary Ids to identifiy overlapping sponge cells at more than one boundary
4188 for(MInt id = m_spongeBndryCells[startBcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
4189 spongeCellId = m_sortedSpongeBndryCells->a[id];
4190 m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer) = false;
4191 }
4192 }
4193 MInt noHaloSpongeCells = cntHalo;
4194 MInt noSpongeCells = m_spongeBndryCells[m_noSpongeBndryCndIds] - cntHalo;
4195 MInt noInternalSpongeCells = m_solver->m_noCellsInsideSpongeLayer - cntHaloInside;
4196 MInt noOverlappingSpongeCells3d = count;
4197
4198 MPI_Allreduce(MPI_IN_PLACE, &noHaloSpongeCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
4199 "noHaloSpongeCells");
4200 MPI_Allreduce(MPI_IN_PLACE, &noSpongeCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "noSpongeCells");
4201 MPI_Allreduce(MPI_IN_PLACE, &noInternalSpongeCells, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
4202 "noInternalSpongeCells");
4203
4204 IF_CONSTEXPR(nDim == 3)
4205 MPI_Allreduce(MPI_IN_PLACE, &noOverlappingSpongeCells3d, 1, MPI_INT, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE",
4206 "noOverlappingSpongeCells3d");
4207 MPI_Allreduce(MPI_IN_PLACE, &maxSpongeFactor, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
4208 "maxSpongeFactor");
4209 MPI_Allreduce(MPI_IN_PLACE, &minSpongeFactor, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_, "MPI_IN_PLACE",
4210 "minSpongeFactor");
4211 MPI_Allreduce(MPI_IN_PLACE, &maxSpongeFactorOverlap, 1, MPI_DOUBLE, MPI_MAX, mpiComm(), AT_, "MPI_IN_PLACE",
4212 "maxSpongeFactorOverlap");
4213 MPI_Allreduce(MPI_IN_PLACE, &minSpongeFactorOverlap, 1, MPI_DOUBLE, MPI_MIN, mpiComm(), AT_, "MPI_IN_PLACE",
4214 "minSpongeFactorOverlap");
4215
4216 m_log << "*********************" << endl;
4217 m_log << "Sponge cell summary" << endl;
4218 m_log << "*********************" << endl;
4219 m_log << noSpongeCells << " sponge cells + " << endl;
4220 m_log << noHaloSpongeCells << " sponge halo cells created" << endl;
4221 m_log << "with " << noInternalSpongeCells << " internal sponge cells and " << endl;
4222 m_log << "with " << noSpongeCells - noInternalSpongeCells - noOverlappingSpongeCells3d
4223 << " sponge cells laying in 2 sponge areas and " << endl;
4224 m_log << "with " << noOverlappingSpongeCells3d << " sponge cells laying in 3 sponge areas " << endl;
4225 m_log << "max sponge factor: " << maxSpongeFactor << endl;
4226 m_log << "min sponge factor: " << minSpongeFactor << endl;
4227 m_log << "max sponge factor overlap: " << maxSpongeFactorOverlap << endl;
4228 m_log << "min sponge factor overlap: " << minSpongeFactorOverlap << endl;
4229 m_log << endl;
4230 if((!(maxSpongeFactor >= F0) && !(maxSpongeFactor <= F0)) || (!(minSpongeFactor >= F0) && !(minSpongeFactor <= F0))) {
4231 mTerm(1, AT_, "error: maximum sponge factor is nan");
4232 }
4233 if(maxSpongeFactor < 0 || minSpongeFactor < 0) {
4234 mTerm(1, AT_, "sponge Factor is negative");
4235 }
4236 if(m_spongeTimeDep) {
4237 m_log << "***********************************" << endl;
4238 m_log << "Time dependent sponge cell summary" << endl;
4239 m_log << "***********************************" << endl;
4240 for(MInt bcId = 0; bcId < m_noSpongeBndryCndIds; bcId++) {
4241 bcSpId = m_spongeBndryCndIds[bcId];
4242 if(m_spongeTimeDependent[bcId] < 1) continue;
4243 if(m_spongeTimeDependent[bcId] == 1) {
4244 m_log << "time dependent sponge decreasing function at sponge boundary " << bcSpId << endl;
4245 m_log << "sponge decreasing start at iteration: " << m_spongeStartIteration[bcId] << endl;
4246 m_log << "sponge decreasing end at iteration: " << m_spongeEndIteration[bcId] << endl;
4247 m_log << "sponge start value: " << m_sigmaSpongeBndryId[bcId] << endl;
4248 m_log << "sponge end value will be zero" << endl << endl;
4249 } else if(m_spongeTimeDependent[bcId] == 2) {
4250 m_log << "time dependent sponge increasing function at sponge boundary " << bcSpId << endl;
4251 m_log << "sponge increasing start at iteration: " << m_spongeStartIteration[bcId] << endl;
4252 m_log << "sponge increasing end at iteration: " << m_spongeEndIteration[bcId] << endl << endl;
4253 } else if(m_spongeTimeDependent[bcId] == 3) {
4254 m_log << "time dependent sponge decreasing function at sponge boundary " << bcSpId << endl;
4255 m_log << "sponge decreasing start at iteration: " << m_spongeStartIteration[bcId] << endl;
4256 m_log << "sponge decreasing end at iteration: " << m_spongeEndIteration[bcId] << endl;
4257 m_log << "sponge start value: " << m_sigmaSpongeBndryId[bcId] << endl;
4258 m_log << "sponge end value: " << m_sigmaEndSpongeBndryId[bcId] << endl << endl;
4259 }
4260 }
4261 }
4262
4263 // setting property 14 for all sponge cells
4264 for(MInt bcId = 0; bcId < m_noSpongeBndryCndIds; bcId++) {
4265 for(MInt id = m_spongeBndryCells[bcId]; id < m_spongeBndryCells[bcId + 1]; id++) {
4266 spongeCellId = m_sortedSpongeBndryCells->a[id];
4267 m_solver->a_hasProperty(spongeCellId, SolverCell::IsInSpongeLayer) = true;
4268 }
4269 }
4270
4271 // this following line should be removed if we switch to a use of function pointers to the specific sponge bounary
4272 // condition
4274}
MFloat * m_sigmaSpongeBndryId
MInt * m_spongeBndryCndIds
holds the sponge boundary IDs
MFloat * m_spongeEndIteration
MFloat * m_spongeStartIteration
MFloat * m_sigmaEndSpongeBndryId
MInt & a_spongeBndryId(const MInt cellId, const MInt dir)
Returns the spongeBndryId of the cell cellId for direction dir.
MFloat & a_spongeFactorStart(const MInt cellId)
Returns the spongeFactorStart of the cell cellId.
MBool approx(const T &, const U &, const T)
Definition: functions.h:272

◆ cutOffBcMissingNeighbor()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::cutOffBcMissingNeighbor ( const MInt  cellId,
const MString  bcName 
)

Helper method to treat cut-off cells without a neighbor in a certain direction. This situation should only appear in multisolver cases and if the cell is a halo. That is, the cut-off halo-cell is only created due to additional halos in the multisolver grid and it should not be relevant to the computation. Thus the primitive variables are set to NaN such that any influence of these cells can be detected.

Definition at line 17756 of file fvcartesianbndrycndxd.cpp.

17756 {
17757#ifndef NDEBUG
17758 ASSERT(m_solver->a_isHalo(cellId) && g_multiSolverGrid,
17759 "Error in " + bcName + ": missing neighbor for (halo) cut-off cell only allowed in multisolver case (halo = "
17760 + to_string(m_solver->a_isHalo(cellId)) + "; multisolver = " + to_string(g_multiSolverGrid) + ")");
17761#else
17762 std::ignore = bcName;
17763#endif
17764 const MFloat nanValue = std::numeric_limits<MFloat>::quiet_NaN();
17765 std::fill_n(&m_solver->a_pvariable(cellId, 0), PV->noVariables, nanValue);
17766}
MBool g_multiSolverGrid

◆ deleteBndryCell()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::deleteBndryCell ( MInt  id)
Author
Daniel Hartmann

Definition at line 12766 of file fvcartesianbndrycndxd.cpp.

12766 {
12767 TRACE();
12768
12769 MInt size = m_bndryCells->size();
12770 if(size == 0) {
12771 mTerm(1, AT_, "collector is empty.");
12772 }
12773 void* from;
12774 void* to;
12775 MLong dataSize;
12776 char* rawMemory = m_bndryCells->getRawPointer();
12778 to = (void*)(rawMemory + dataSize * (MLong)id);
12779 from = (void*)(rawMemory + dataSize * (size - 1));
12780
12781 // 3. if the cell to delete is already the last cell we are finished here...
12782 if(size - 1 == id) {
12783 // 3.a tidy up your old place
12784 m_bndryCells->a[size - 1].allocateElements(from, (void*)m_bndryCells->getRawPointer(), size - 1);
12785 // 3.b Decrease current collector size by one (Note: was previously done before tidying up)
12786 m_bndryCells->setSize(size - 1);
12787 return;
12788 }
12789
12790 // 4. Move last cell to freed space
12791 // a. copy members of last cell to free space
12792 m_bndryCells->a[id] = m_bndryCells->a[size - 1];
12793
12794 // b. Move raw memory to free space
12795 memcpy(to, from, dataSize);
12796
12797 // c. call moveElements (which shifts pointers
12798 // to the new destination
12799 m_bndryCells->a[id].moveElements(to);
12800
12801 // d. tidy up your old place
12802 m_bndryCells->a[size - 1].allocateElements(from, (void*)m_bndryCells->getRawPointer(), size - 1);
12803
12804 // 8. Decrease current collector size by one
12805 m_bndryCells->setSize(size - 1);
12806}
char * getRawPointer()
Definition: collector.h:164
MInt setSize(MInt inputSize)
Definition: collector.h:40
static MInt staticElementSize()

◆ detectSmallBndryCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::detectSmallBndryCells

Master setting for lower levels commented out!!!

Cell arrays used for temporary data storage: slope[0][0] : flags whether the boundary cell is a small cell slope[0][1] : flags whether treatment for the boundary cell is finished slope[1][0] : stores the internal neighbor slope[1][1] : stores a potential master cell

Author
: Daniel Hartmann, April 27, 2006

Definition at line 7851 of file fvcartesianbndrycndxd.cpp.

7851 {
7852 TRACE();
7853
7854 MInt noCells = m_bndryCells->size();
7855 MInt counter;
7856 MInt countChained;
7857 MInt formerMasterBnd;
7858 MInt cellId;
7859 MInt nghbrId;
7860 MInt count1;
7861 MInt count2;
7862 MInt primaryDirection = 0;
7863 MFloat maxComponent;
7864 MBool wall = false;
7865 //---
7866
7867 // reset collector of small cells
7869
7870 m_log << "Small cell treatment " << endl;
7871 m_log << "using " << m_volumeLimitWall << " " << m_volumeLimitOther << endl;
7872
7873 counter = 0;
7874 // set small cell flag
7875 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
7876 m_solver->a_slope(bndryId, 0, 0) = (MFloat) false;
7877 m_solver->a_slope(bndryId, 0, 1) = (MFloat) false;
7878 cellId = m_bndryCell[bndryId].m_cellId;
7879 wall = false;
7880 for(MInt srfcId = 0; srfcId < m_bndryCells->a[m_solver->a_bndryId(cellId)].m_noSrfcs; srfcId++) {
7881 if(m_bndryCell[bndryId].m_srfcs[srfcId]->m_bndryCndId / 1000 == 3) {
7882 wall = true;
7883 break;
7884 }
7885 }
7886 if(wall) {
7887 if(m_bndryCell[bndryId].m_volume / m_solver->grid().gridCellVolume(m_solver->a_level(cellId))
7889 m_solver->a_slope(bndryId, 0, 0) = (MFloat) true;
7890 m_bndryCell[bndryId].m_linkedCellId = cellId;
7891 counter++;
7892 }
7893 } else {
7894 if(m_bndryCell[bndryId].m_volume / m_solver->grid().gridCellVolume(m_solver->a_level(cellId))
7896 m_solver->a_slope(bndryId, 0, 0) = (MFloat) true;
7897 m_bndryCell[bndryId].m_linkedCellId = cellId;
7898 counter++;
7899 }
7900 }
7901 }
7902
7903 // check for potential master cells
7904 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
7905 m_solver->a_slope(bndryId, 1, 0) = (MFloat)(-1);
7906 m_solver->a_slope(bndryId, 1, 1) = (MFloat)(-1);
7907 if((MInt)m_solver->a_slope(bndryId, 0, 0)) {
7908 // set primary direction
7909 maxComponent = F0;
7910 for(MInt i = 0; i < nDim; i++) {
7911 if(fabs(m_bndryCell[bndryId].m_srfcs[0]->m_normalVector[i]) > maxComponent) {
7912 maxComponent = fabs(m_bndryCell[bndryId].m_srfcs[0]->m_normalVector[i]);
7913 if(m_bndryCell[bndryId].m_srfcs[0]->m_normalVector[i] < F0) {
7914 primaryDirection = 2 * i;
7915 } else {
7916 primaryDirection = 2 * i + 1;
7917 }
7918 }
7919 }
7920 //
7921 cellId = m_bndryCell[bndryId].m_cellId;
7922 if(m_solver->a_hasNeighbor(cellId, primaryDirection) > 0) {
7923 nghbrId = m_solver->c_neighborId(cellId, primaryDirection);
7924 if(m_solver->a_bndryId(nghbrId) > -1) {
7925 m_solver->a_slope(bndryId, 1, 1) = (MFloat)nghbrId;
7926 } else {
7927 m_solver->a_slope(bndryId, 1, 0) = (MFloat)nghbrId;
7928 }
7929 }
7930 }
7931 }
7932
7933 m_log << "Small cell treatment..." << endl;
7934 m_log << counter << " small cells to link" << endl;
7935
7936 count1 = 0;
7937 count2 = 0;
7938 countChained = 0;
7939
7940 // 1. connect small cells to internal master cells
7941 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
7942 if(!(MInt)m_solver->a_slope(bndryId, 0, 0)) continue;
7943 if((MInt)m_solver->a_slope(bndryId, 1, 0) == -1) continue;
7944 m_bndryCell[bndryId].m_linkedCellId = (MInt)m_solver->a_slope(bndryId, 1, 0);
7945 m_solver->a_slope(bndryId, 0, 1) = (MFloat) true;
7946 counter--;
7947 count1++;
7948 }
7949
7950 // 2. connect all small cells with at least one possible master cell
7951 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
7952 if(!(MInt)m_solver->a_slope(bndryId, 0, 0)) continue;
7953 if((MInt)m_solver->a_slope(bndryId, 0, 1)) continue;
7954 if((MInt)m_solver->a_slope(bndryId, 1, 1) == -1) continue;
7955 m_bndryCell[bndryId].m_linkedCellId = (MInt)m_solver->a_slope(bndryId, 1, 1);
7956 m_solver->a_slope(bndryId, 0, 1) = (MFloat) true;
7957 counter--;
7958 count2++;
7959 }
7960
7961 // 3. connect small cells the master of which is also a small cell to the master's master
7962 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
7963 if(!(MInt)m_solver->a_slope(bndryId, 0, 0)) continue;
7964 if(!(MInt)m_solver->a_slope(bndryId, 0, 1)) continue;
7965 if(m_solver->a_bndryId(m_bndryCell[bndryId].m_linkedCellId) == -1) continue;
7966 if(!(MInt)m_solver->a_slope(m_solver->a_bndryId(m_bndryCell[bndryId].m_linkedCellId), 0, 0)) continue;
7967 formerMasterBnd = m_solver->a_bndryId(m_bndryCell[bndryId].m_linkedCellId);
7968 m_bndryCell[bndryId].m_linkedCellId = m_bndryCell[formerMasterBnd].m_linkedCellId;
7969 countChained++;
7970 }
7971
7972 m_log << "Master cell statistics: " << endl;
7973 m_log << "__________________________________" << endl << endl;
7974 m_log << " * links to internal cells " << count1 << endl;
7975 m_log << " * links to boundary cells " << count2 << endl;
7976 m_log << " * chained links " << countChained << endl;
7977 m_log << "__________________________________" << endl;
7978
7979 // create small cells
7980 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
7981 if((MInt)m_solver->a_slope(bndryId, 0, 0) && (MInt)m_solver->a_slope(bndryId, 0, 1)) {
7983 m_smallBndryCells->a[m_smallBndryCells->size() - 1] = bndryId;
7984 }
7985 }
7986
7987 // fill the lists smallCellIds and masterCellIds
7988 noCells = m_smallBndryCells->size();
7989 for(MInt s = 0; s < noCells; s++) {
7991 m_solver->m_masterCellIds[s] = m_bndryCell[m_smallBndryCells->a[s]].m_linkedCellId;
7992 }
7993}

◆ detectSmallBndryCellsMGC()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::detectSmallBndryCellsMGC ( )

Is able to handle multiple cut surfaces and complex geometries. Some special settings for test cases included; If a cell hast several cut surfaces, master cell related to wall boundary condition is prefered if not specified otherwise.

Cell arrays used for temporary data storage: slope[0][0] : flags whether the boundary cell is a small cell slope[0][1] : flags whether treatment for the boundary cell is finished slope[1][0] : stores the internal neighbor slope[1][1] : stores a potential master cell slope[2][0] : stores the ID of a small cell cluster with no simple master

Author
: Claudia Guenther, November 2011

◆ domainId()

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::domainId ( ) const
inlineprotected

Definition at line 488 of file fvcartesianbndrycndxd.h.

488{ return m_solver->domainId(); }

◆ exchangeComputedCutPoints()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::exchangeComputedCutPoints

Definition at line 12099 of file fvcartesianbndrycndxd.cpp.

12099 {
12100 TRACE();
12101 MBool bndryRfnJump = false;
12102 bndryRfnJump = Context::getSolverProperty<MBool>("bndryRfnJump", m_solverId, AT_, &bndryRfnJump);
12103
12104 if(bndryRfnJump == 0) {
12105 return;
12106 }
12107 m_log << "processing MInts " << endl;
12108 MIntScratchSpace idSendRecBuffers(m_solver->a_noCells() * 12, AT_, "idSendRecBuffers");
12109 idSendRecBuffers.fill(0);
12110
12111 MInt cnt = 0;
12112 for(MInt cellId = 0; cellId < m_solver->a_noCells(); cellId++) {
12113 if(m_solver->a_bndryId(cellId) < 0) {
12114 continue;
12115 }
12116 MInt bndryId = m_solver->a_bndryId(cellId);
12117 idSendRecBuffers[cellId * 12 + 0] = m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints;
12118 idSendRecBuffers[cellId * 12 + 1] = m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[0];
12119 idSendRecBuffers[cellId * 12 + 2] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[0];
12120 idSendRecBuffers[cellId * 12 + 3] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[1];
12121 idSendRecBuffers[cellId * 12 + 4] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[2];
12122 idSendRecBuffers[cellId * 12 + 5] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[3];
12123 idSendRecBuffers[cellId * 12 + 6] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[4];
12124 idSendRecBuffers[cellId * 12 + 7] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[5];
12125 idSendRecBuffers[cellId * 12 + 8] = m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 0];
12126 idSendRecBuffers[cellId * 12 + 9] = m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 1];
12127 idSendRecBuffers[cellId * 12 + 10] = m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 2];
12128 idSendRecBuffers[cellId * 12 + 11] = m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 3];
12129
12130 if(idSendRecBuffers[cellId * 12 + 0] > 0 && m_solver->a_isWindow(cellId)) {
12131 cnt++;
12132 }
12133 }
12134 m_log << "... " << cnt << " window boundary cells to exchange to all domains ... (Ids) " << endl;
12135
12136 m_solver->exchangeData(&idSendRecBuffers[0], 12);
12137
12138 for(MInt i = 0; i < m_solver->noNeighborDomains(); i++) {
12139 for(MInt j = 0; j < m_solver->noHaloCells(i); j++) {
12140 MInt thishaloCellId = m_solver->haloCellId(i, j);
12141 MInt bndryId = m_solver->a_bndryId(thishaloCellId);
12142 if(m_solver->a_bndryId(thishaloCellId) < 0) {
12143 continue;
12144 }
12145 m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints = idSendRecBuffers[thishaloCellId * 12 + 0];
12146 m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[0] = idSendRecBuffers[thishaloCellId * 12 + 1];
12147 m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[1] = idSendRecBuffers[thishaloCellId * 12 + 1];
12148 m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[2] = idSendRecBuffers[thishaloCellId * 12 + 1];
12149 m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[3] = idSendRecBuffers[thishaloCellId * 12 + 1];
12150 m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[4] = idSendRecBuffers[thishaloCellId * 12 + 1];
12151 m_bndryCells->a[bndryId].m_srfcs[0]->m_bodyId[5] = idSendRecBuffers[thishaloCellId * 12 + 1];
12152 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[0] = idSendRecBuffers[thishaloCellId * 12 + 2];
12153 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[1] = idSendRecBuffers[thishaloCellId * 12 + 3];
12154 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[2] = idSendRecBuffers[thishaloCellId * 12 + 4];
12155 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[3] = idSendRecBuffers[thishaloCellId * 12 + 5];
12156 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[4] = idSendRecBuffers[thishaloCellId * 12 + 6];
12157 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[5] = idSendRecBuffers[thishaloCellId * 12 + 7];
12158 m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 0] =
12159 idSendRecBuffers[thishaloCellId * 12 + 8];
12160 m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 1] =
12161 idSendRecBuffers[thishaloCellId * 12 + 9];
12162 m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 2] =
12163 idSendRecBuffers[thishaloCellId * 12 + 10];
12164 m_solver->m_bndryRfnJumpInformation[m_bndryCells->a[bndryId].m_cellId * 4 + 3] =
12165 idSendRecBuffers[thishaloCellId * 12 + 11];
12166 }
12167 }
12168 m_log << " finished. " << endl;
12169
12170 m_log << "processing MFloats " << endl;
12171 MFloatScratchSpace floatSendRecBuffers(m_solver->a_noCells() * 18, AT_, "floatSendRecBuffers");
12172 floatSendRecBuffers.fill(0);
12173
12174 cnt = 0;
12175 for(MInt cellId = 0; cellId < m_solver->a_noCells(); cellId++) {
12176 if(m_solver->a_bndryId(cellId) < 0) {
12177 continue;
12178 }
12179 MInt bndryId = m_solver->a_bndryId(cellId);
12180
12181 floatSendRecBuffers[cellId * 18 + 0] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[0][0];
12182 floatSendRecBuffers[cellId * 18 + 1] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[0][1];
12183 floatSendRecBuffers[cellId * 18 + 2] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[0][2];
12184 floatSendRecBuffers[cellId * 18 + 3] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[1][0];
12185 floatSendRecBuffers[cellId * 18 + 4] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[1][1];
12186 floatSendRecBuffers[cellId * 18 + 5] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[1][2];
12187 floatSendRecBuffers[cellId * 18 + 6] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[2][0];
12188 floatSendRecBuffers[cellId * 18 + 7] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[2][1];
12189 floatSendRecBuffers[cellId * 18 + 8] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[2][2];
12190 floatSendRecBuffers[cellId * 18 + 9] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[3][0];
12191 floatSendRecBuffers[cellId * 18 + 10] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[3][1];
12192 floatSendRecBuffers[cellId * 18 + 11] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[3][2];
12193 floatSendRecBuffers[cellId * 18 + 12] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[4][0];
12194 floatSendRecBuffers[cellId * 18 + 13] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[4][1];
12195 floatSendRecBuffers[cellId * 18 + 14] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[4][2];
12196 floatSendRecBuffers[cellId * 18 + 15] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[5][0];
12197 floatSendRecBuffers[cellId * 18 + 16] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[5][1];
12198 floatSendRecBuffers[cellId * 18 + 17] = m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[5][2];
12199 if((floatSendRecBuffers[cellId * 18 + 0] > 0 || floatSendRecBuffers[cellId * 18 + 1] > 0
12200 || floatSendRecBuffers[cellId * 18 + 2] > 0 || floatSendRecBuffers[cellId * 18 + 3] > 0
12201 || floatSendRecBuffers[cellId * 18 + 4] > 0 || floatSendRecBuffers[cellId * 18 + 5] > 0
12202 || floatSendRecBuffers[cellId * 18 + 6] > 0 || floatSendRecBuffers[cellId * 18 + 7] > 0
12203 || floatSendRecBuffers[cellId * 18 + 8] > 0 || floatSendRecBuffers[cellId * 18 + 9] > 0
12204 || floatSendRecBuffers[cellId * 18 + 10] > 0 || floatSendRecBuffers[cellId * 18 + 11] > 0
12205 || floatSendRecBuffers[cellId * 18 + 12] > 0 || floatSendRecBuffers[cellId * 18 + 13] > 0
12206 || floatSendRecBuffers[cellId * 18 + 14] > 0 || floatSendRecBuffers[cellId * 18 + 15] > 0
12207 || floatSendRecBuffers[cellId * 18 + 16] > 0 || floatSendRecBuffers[cellId * 18 + 17] > 0
12208 || floatSendRecBuffers[cellId * 18 + 0] < 0 || floatSendRecBuffers[cellId * 18 + 1] < 0
12209 || floatSendRecBuffers[cellId * 18 + 2] < 0 || floatSendRecBuffers[cellId * 18 + 3] < 0
12210 || floatSendRecBuffers[cellId * 18 + 4] < 0 || floatSendRecBuffers[cellId * 18 + 5] < 0
12211 || floatSendRecBuffers[cellId * 18 + 6] < 0 || floatSendRecBuffers[cellId * 18 + 7] < 0
12212 || floatSendRecBuffers[cellId * 18 + 8] < 0 || floatSendRecBuffers[cellId * 18 + 9] < 0
12213 || floatSendRecBuffers[cellId * 18 + 10] < 0 || floatSendRecBuffers[cellId * 18 + 11] < 0
12214 || floatSendRecBuffers[cellId * 18 + 12] < 0 || floatSendRecBuffers[cellId * 18 + 13] < 0
12215 || floatSendRecBuffers[cellId * 18 + 14] < 0 || floatSendRecBuffers[cellId * 18 + 15] < 0
12216 || floatSendRecBuffers[cellId * 18 + 16] < 0 || floatSendRecBuffers[cellId * 18 + 17] < 0)
12217 && m_solver->a_isWindow(cellId)) {
12218 cnt++;
12219 }
12220 }
12221 m_log << "... " << cnt << " window boundary cells to exchange to all domains ... (Floats) " << endl;
12222
12223
12224 m_solver->exchangeData(&floatSendRecBuffers[0], 18);
12225 for(MInt i = 0; i < m_solver->noNeighborDomains(); i++) {
12226 for(MInt j = 0; j < m_solver->noHaloCells(i); j++) {
12227 MInt thishaloCellId = m_solver->haloCellId(i, j);
12228 MInt bndryId = m_solver->a_bndryId(thishaloCellId);
12229 if(m_solver->a_bndryId(thishaloCellId) < 0) {
12230 continue;
12231 }
12232
12233 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[0][0] = floatSendRecBuffers[thishaloCellId * 18 + 0];
12234 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[0][1] = floatSendRecBuffers[thishaloCellId * 18 + 1];
12235 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[0][2] = floatSendRecBuffers[thishaloCellId * 18 + 2];
12236 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[1][0] = floatSendRecBuffers[thishaloCellId * 18 + 3];
12237 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[1][1] = floatSendRecBuffers[thishaloCellId * 18 + 4];
12238 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[1][2] = floatSendRecBuffers[thishaloCellId * 18 + 5];
12239 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[2][0] = floatSendRecBuffers[thishaloCellId * 18 + 6];
12240 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[2][1] = floatSendRecBuffers[thishaloCellId * 18 + 7];
12241 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[2][2] = floatSendRecBuffers[thishaloCellId * 18 + 8];
12242 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[3][0] = floatSendRecBuffers[thishaloCellId * 18 + 9];
12243 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[3][1] = floatSendRecBuffers[thishaloCellId * 18 + 10];
12244 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[3][2] = floatSendRecBuffers[thishaloCellId * 18 + 11];
12245 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[4][0] = floatSendRecBuffers[thishaloCellId * 18 + 12];
12246 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[4][1] = floatSendRecBuffers[thishaloCellId * 18 + 13];
12247 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[4][2] = floatSendRecBuffers[thishaloCellId * 18 + 14];
12248 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[5][0] = floatSendRecBuffers[thishaloCellId * 18 + 15];
12249 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[5][1] = floatSendRecBuffers[thishaloCellId * 18 + 16];
12250 m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[5][2] = floatSendRecBuffers[thishaloCellId * 18 + 17];
12251 }
12252 }
12253 m_log << " finished. " << endl;
12254}
MBool a_isWindow(const MInt cellId) const
Returns IsWindow of the cell cellId.
MInt noHaloCells(const MInt domainId) const
MInt noNeighborDomains() const
MInt haloCellId(const MInt domainId, const MInt cellId) const
void exchangeData(T *data, const MInt dataBlockSize=1)
Exchange memory in 'data' assuming a solver size of 'dataBlockSize' per cell.

◆ exchangeCutOffBoundaryCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::exchangeCutOffBoundaryCells
Author
Stephan Schlimpert
Date
April 2014

Definition at line 1873 of file fvcartesianbndrycndxd.cpp.

1873 {
1874 TRACE();
1875 // exchange cells for all cut off boundary condition and add them to the corresponding lists
1876 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++) {
1877 MInt bcIdNr = m_cutOffBndryCndIds[bcId];
1878 MInt noInternalCutOffCells = m_sortedCutOffCells[bcId]->size();
1879 m_log << "processing bcIdNr " << bcIdNr << " with " << noInternalCutOffCells << " internal cut off cells...";
1880 MIntScratchSpace intSendRecBuffers(m_solver->a_noCells(), AT_, "intSendRecBuffers");
1881 intSendRecBuffers.fill(0);
1882 // gather b_properties[SolverCell::IsCutOff] only for current cut off bc
1883 MInt cnt = 0;
1884 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
1885 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
1886 intSendRecBuffers[cellId] = m_solver->a_hasProperty(cellId, SolverCell::IsCutOff);
1887 if(intSendRecBuffers[cellId] > 0 && m_solver->a_isWindow(cellId)) cnt++;
1888 }
1889 m_log << "... " << cnt << " window cut off cells to exchange to all domains ... ";
1890 // exchange b_properties only on window cells and receive corresponding data on halo cells
1891 m_solver->exchangeData(intSendRecBuffers.getPointer(), 1);
1892 // scatter data to cell collector and append halo cell to the cut off boundary collector
1893 for(MInt i = 0; i < m_solver->noNeighborDomains(); i++) {
1894 for(MInt j = 0; j < m_solver->noHaloCells(i); j++) {
1895 MInt thishaloCellId = m_solver->haloCellId(i, j);
1896 if(!m_solver->a_hasProperty(thishaloCellId, SolverCell::IsOnCurrentMGLevel)) continue;
1897 if(m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff)) continue;
1898 m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff) = intSendRecBuffers[thishaloCellId];
1899 if(m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff)) {
1900 m_sortedCutOffCells[bcId]->a[m_sortedCutOffCells[bcId]->size()] = thishaloCellId;
1901 m_sortedCutOffCells[bcId]->append();
1902 }
1903 }
1904 }
1905 // Note: Azimuthal window and halo cells might not be on same grid level. Therefore, intSendRecBuffers are modified
1906 // for parent data
1907 if(m_solver->grid().azimuthalPeriodicity()) {
1908 MInt axDir = m_solver->grid().raw().m_azimuthalAxialDir;
1909 // Modify parent data
1910 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
1911 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
1912 if(m_solver->a_hasProperty(cellId, SolverCell::IsCutOff)) {
1913 if(m_solver->c_parentId(cellId) > -1) {
1914 intSendRecBuffers[m_solver->c_parentId(cellId)] = true;
1915 }
1916 }
1917 }
1918 m_solver->exchangeDataAzimuthal(intSendRecBuffers.getPointer(), 1);
1919 for(MInt i = 0; i < m_solver->grid().noAzimuthalNeighborDomains(); i++) {
1920 for(MInt j = 0; j < m_solver->grid().noAzimuthalHaloCells(i); j++) {
1921 MInt thishaloCellId = m_solver->grid().azimuthalHaloCell(i, j);
1922 if(!m_solver->a_hasProperty(thishaloCellId, SolverCell::IsOnCurrentMGLevel)) continue;
1923 if(m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff)) continue;
1924 if(intSendRecBuffers[thishaloCellId] > 0) {
1925 if(!m_solver->a_hasNeighbor(thishaloCellId, axDir)) {
1926 if(m_solver->c_parentId(thishaloCellId) < 0
1927 || (m_solver->c_parentId(thishaloCellId) > -1
1928 && !m_solver->a_hasNeighbor(m_solver->c_parentId(thishaloCellId), axDir))) {
1929 m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff) = intSendRecBuffers[thishaloCellId];
1930 }
1931 } else if(!m_solver->a_hasNeighbor(thishaloCellId, axDir + 1)) {
1932 if(m_solver->c_parentId(thishaloCellId) < 0
1933 || (m_solver->c_parentId(thishaloCellId) > -1
1934 && !m_solver->a_hasNeighbor(m_solver->c_parentId(thishaloCellId), axDir + 1))) {
1935 m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff) = intSendRecBuffers[thishaloCellId];
1936 }
1937 }
1938 }
1939 if(m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff)) {
1940 m_sortedCutOffCells[bcId]->a[m_sortedCutOffCells[bcId]->size()] = thishaloCellId;
1941 m_sortedCutOffCells[bcId]->append();
1942 }
1943 }
1944 }
1945 for(MUint i = 0; i < m_solver->m_azimuthalRemappedNeighborDomains.size(); i++) {
1946 for(MUint j = 0; j < m_solver->m_azimuthalRemappedHaloCells[i].size(); j++) {
1947 MInt thishaloCellId = m_solver->m_azimuthalRemappedHaloCells[i][j];
1948 if(!m_solver->a_hasProperty(thishaloCellId, SolverCell::IsOnCurrentMGLevel)) continue;
1949 if(m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff)) continue;
1950 if(intSendRecBuffers[thishaloCellId]
1951 && (!m_solver->a_hasNeighbor(thishaloCellId, axDir)
1952 || !m_solver->a_hasNeighbor(thishaloCellId, axDir + 1))) {
1953 m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff) = intSendRecBuffers[thishaloCellId];
1954 }
1955 if(m_solver->a_hasProperty(thishaloCellId, SolverCell::IsCutOff)) {
1956 m_sortedCutOffCells[bcId]->a[m_sortedCutOffCells[bcId]->size()] = thishaloCellId;
1957 m_sortedCutOffCells[bcId]->append();
1958 }
1959 }
1960 }
1961 }
1962 m_log << " finished. " << endl
1963 << " number received cut off cells = " << m_sortedCutOffCells[bcId]->size() - noInternalCutOffCells
1964 << " for current bcId = " << bcIdNr << endl;
1965 }
1966}
void exchangeDataAzimuthal(T *data, const MInt dataBlockSize=1)
std::vector< std::vector< MInt > > m_azimuthalRemappedHaloCells
std::vector< MInt > m_azimuthalRemappedNeighborDomains

◆ generateBndryCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::generateBndryCells ( )
virtual
Author
Daniel Hartmann, 22.12.2006, modified by Claudia Guenther, January 2010

◆ getFeatureEdges()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::getFeatureEdges ( MInt ,
MFloat **&  ,
MInt  ,
MInt *&  ,
MFloat *&  ,
MFloat *&   
)

◆ getIntersectionPoints()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::getIntersectionPoints ( MFloat **&  ,
MFloat **&  ,
MInt  ,
MInt  ,
MFloat **&  ,
MInt  
)

◆ getSortedElements()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::getSortedElements ( const std::vector< MInt > &  ,
MInt ,
MInt *&  ,
MInt ,
MInt *&  ,
MInt   
)

◆ initBesselModes()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initBesselModes ( MInt  )

◆ initBndryCnds()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initBndryCnds

Definition at line 2247 of file fvcartesianbndrycndxd.cpp.

2247 {
2248 TRACE();
2249
2250 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
2251 (this->*bndryCndHandlerInit[bcId])(bcId);
2252 }
2253
2255
2256 if(m_solver->m_wmLES) {
2258 }
2259}
void setBCTypes(MInt updateOnlyBndryCndId=-1)

◆ initBndryCommunications()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initBndryCommunications
Author
?, Andreas Lintermann
Date
?, 07.05.2019

Function is called from creatBndCells().

Definition at line 5799 of file fvcartesianbndrycndxd.cpp.

5799 {
5800 TRACE();
5801
5802 // find out global number and kind of boundary conditions...
5803 MIntScratchSpace comm_allBndryIds_scratch(m_maxNoBndryCndIds, AT_, "comm_allBndryIds_scratch");
5804 MIntScratchSpace comm_allBndryIds_result_scratch(noDomains() * m_maxNoBndryCndIds, AT_,
5805 "comm_allBndryIds_result_scratch");
5806 MInt* comm_allBndryIds = comm_allBndryIds_scratch.getPointer();
5807 MInt* comm_allBndryIds_result = comm_allBndryIds_result_scratch.getPointer();
5808 for(MInt i = 0; i < noDomains() * m_maxNoBndryCndIds; i++) {
5809 comm_allBndryIds_result[i] = -1;
5810 }
5811
5812 MPI_Group world_group;
5813 MPI_Comm_group(mpiComm(), &world_group, AT_, "world_group");
5814
5815 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
5816 comm_allBndryIds[bcId] = m_bndryCndIds[bcId];
5817 }
5818 for(MInt bcId = m_noBndryCndIds; bcId < m_maxNoBndryCndIds; bcId++) {
5819 comm_allBndryIds[bcId] = -1;
5820 }
5821
5822 MPI_Allgather(comm_allBndryIds, m_maxNoBndryCndIds, MPI_INT, comm_allBndryIds_result, m_maxNoBndryCndIds, MPI_INT,
5823 mpiComm(), AT_, "comm_allBndryIds", "comm_allBndryIds_result");
5824
5825 MIntScratchSpace sortedBndryCndIds_scratch(m_maxNoBndryCndIds, AT_, "sortedBndryCndIds_scratch");
5826 MInt* sortedBndryCndIds = sortedBndryCndIds_scratch.getPointer();
5827 MInt realNoBndryCndIds = 0;
5828 for(MInt i = 0; i < m_maxNoBndryCndIds * noDomains(); i++) {
5829 if(comm_allBndryIds_result[i] > -1) sortedBndryCndIds[realNoBndryCndIds++] = comm_allBndryIds_result[i];
5830 }
5831 maia::math::quickSort(sortedBndryCndIds, 0, realNoBndryCndIds - 1);
5832 realNoBndryCndIds = maia::math::removeDoubleEntries(sortedBndryCndIds, realNoBndryCndIds);
5833
5834 MIntScratchSpace procs_bcId_scratch(realNoBndryCndIds * noDomains(), AT_, "procs_bcId_scratch");
5835 MInt* procs_bcId = procs_bcId_scratch.getPointer();
5836 MIntScratchSpace noProcs_scratch(realNoBndryCndIds, AT_, "noProcs_scratch");
5837 MInt* noProcs = noProcs_scratch.getPointer();
5838
5839 // this is just a workaround, needs fixing! allocation should be placed in the constructor or so!
5840 // needs to be done by every rank, also those that become inactive! -> moved to resetBndryCommunication()
5841 // if(m_comm_bc_init > 0)
5842 // {
5843 // for( MInt i = 0; i < m_comm_bc_init; i++ )
5844 // {
5845 // if(m_comm_bc[ i ] != MPI_COMM_NULL && m_comm_bc[i] != MPI_COMM_WORLD)
5846 // MPI_Comm_free(&m_comm_bc[ i ], AT_, "m_comm_bc[i]");
5847 // }
5848 //}
5850 if(realNoBndryCndIds > 0) {
5851 mAlloc(m_comm_bc, realNoBndryCndIds, "m_comm_bc", AT_);
5852 }
5853
5855 mAlloc(m_bc_comm_pointer, m_maxNoBndryCndIds, "m_bc_comm_pointer", -1, AT_);
5856
5857 for(MInt i = 0; i < realNoBndryCndIds; i++) {
5858 noProcs[i] = 0;
5859 for(MInt p = 0; p < noDomains(); p++) {
5860 for(MInt j = 0; j < m_maxNoBndryCndIds; j++) {
5861 if(comm_allBndryIds_result[p * m_maxNoBndryCndIds + j] == sortedBndryCndIds[i]) {
5862 procs_bcId[noProcs[i]++] = p;
5863 }
5864 }
5865 }
5866 MPI_Group bc_group;
5867 MPI_Group_incl(world_group, noProcs[i], procs_bcId, &bc_group, AT_);
5868
5869 MPI_Comm_create(mpiComm(), bc_group, &m_comm_bc[i], AT_, "m_comm_bc[i]");
5870
5871 MPI_Group_free(&bc_group, AT_);
5872 }
5873
5874 // set the current numnber of communicators (for next call)
5875 m_comm_bc_init = realNoBndryCndIds;
5876
5877 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
5878 for(MInt i = 0; i < realNoBndryCndIds; i++) {
5879 if(m_bndryCndIds[bcId] == sortedBndryCndIds[i]) {
5880 m_bc_comm_pointer[bcId] = i;
5881 }
5882 }
5883 }
5884
5885
5886 IF_CONSTEXPR(nDim == 3) {
5887 if(m_solver->m_vtuGeometryOutput.empty()) {
5888 m_log << "VTU geometry output for boundaryIds: ";
5889 for(MInt i = 0; i < realNoBndryCndIds; i++) {
5890 if((sortedBndryCndIds[i] >= 3000 && sortedBndryCndIds[i] < 4000)
5892 m_solver->m_vtuGeometryOutput.insert(sortedBndryCndIds[i]);
5893 m_log << sortedBndryCndIds[i] << " ";
5894 }
5895 }
5896 m_log << endl;
5897 }
5898 }
5899
5900
5901 // find out global number and kind of cutOff boundary conditions...
5902 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++) {
5903 if(m_sortedCutOffCells[bcId]->size() > 0) {
5904 comm_allBndryIds[bcId] = m_cutOffBndryCndIds[bcId];
5905 } else {
5906 comm_allBndryIds[bcId] = -1;
5907 }
5908 }
5909 for(MInt bcId = m_noCutOffBndryCndIds; bcId < m_maxNoBndryCndIds; bcId++) {
5910 comm_allBndryIds[bcId] = -1;
5911 }
5912 for(MInt i = 0; i < noDomains() * m_maxNoBndryCndIds; i++) {
5913 comm_allBndryIds_result[i] = -1;
5914 }
5915
5916 MPI_Allgather(comm_allBndryIds, m_maxNoBndryCndIds, MPI_INT, comm_allBndryIds_result, m_maxNoBndryCndIds, MPI_INT,
5917 mpiComm(), AT_, "comm_allBndryIds", "comm_allBndryIds_result");
5918
5919 realNoBndryCndIds = 0;
5920 for(MInt i = 0; i < m_maxNoBndryCndIds * noDomains(); i++) {
5921 if(comm_allBndryIds_result[i] > -1) sortedBndryCndIds[realNoBndryCndIds++] = comm_allBndryIds_result[i];
5922 }
5923 maia::math::quickSort(sortedBndryCndIds, 0, realNoBndryCndIds - 1);
5924 realNoBndryCndIds = maia::math::removeDoubleEntries(sortedBndryCndIds, realNoBndryCndIds);
5925
5926 if(realNoBndryCndIds == 0) {
5927 return;
5928 }
5929
5930 MIntScratchSpace procs_bcIdCo_scratch(realNoBndryCndIds * noDomains(), AT_, "procs_bcIdCo_scratch");
5931 procs_bcId = procs_bcIdCo_scratch.getPointer();
5932 MIntScratchSpace noProcsCo_scratch(realNoBndryCndIds, AT_, "noProcsCo_scratch");
5933 noProcs = noProcsCo_scratch.getPointer();
5934
5935
5936 // this is just a workaround, needs fixing! allocation should be placed in the constructor or so!
5937 // needs to be done by every rank, also those that become inactive! -> moved to resetBndryCommunication()
5938 // if(m_comm_bcCo_init > 0)
5939 // {
5940 // for( MInt i = 0; i < m_comm_bcCo_init; i++ )
5941 // {
5942 // if(m_comm_bcCo[ i ] != MPI_COMM_NULL && m_comm_bcCo[i] != MPI_COMM_WORLD)
5943 // MPI_Comm_free(&m_comm_bcCo[ i ], AT_, "m_comm_bcCo[]i");
5944 // }
5945 //}
5947 if(realNoBndryCndIds > 0) {
5948 mAlloc(m_comm_bcCo, realNoBndryCndIds, "m_comm_bcCo", AT_);
5949 }
5950
5952 mAlloc(m_bcCo_comm_pointer, m_maxNoBndryCndIds, "m_bcCo_comm_pointer", -1, AT_);
5953
5954 for(MInt i = 0; i < realNoBndryCndIds; i++) {
5955 noProcs[i] = 0;
5956 for(MInt p = 0; p < noDomains(); p++) {
5957 for(MInt j = 0; j < m_maxNoBndryCndIds; j++) {
5958 if(comm_allBndryIds_result[p * m_maxNoBndryCndIds + j] == sortedBndryCndIds[i]) {
5959 procs_bcId[noProcs[i]++] = p;
5960 }
5961 }
5962 }
5963 MPI_Group bc_group;
5964 MPI_Group_incl(world_group, noProcs[i], procs_bcId, &bc_group, AT_);
5965
5966 MPI_Comm_create(mpiComm(), bc_group, &m_comm_bcCo[i], AT_, "m_comm_bcCo[i]");
5967
5968 MPI_Group_free(&bc_group, AT_);
5969 }
5970
5971 // set the number communicators for next call
5972 m_comm_bcCo_init = realNoBndryCndIds;
5973
5974 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++) {
5975 if(m_sortedCutOffCells[bcId]->size() == 0) continue;
5976
5977 for(MInt i = 0; i < realNoBndryCndIds; i++) {
5978 if(m_cutOffBndryCndIds[bcId] == sortedBndryCndIds[i]) {
5979 m_bcCo_comm_pointer[bcId] = i;
5980 }
5981 }
5982 }
5983
5984 MPI_Group_free(&world_group, AT_);
5985}
std::set< MInt > m_vtuGeometryOutput
@ VTP
Definition: enums.h:18
int MPI_Group_free(MPI_Group *group, const MString &name)
same as MPI_Group_free

◆ initCutOffBndryCnds()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initCutOffBndryCnds

Definition at line 1639 of file fvcartesianbndrycndxd.cpp.

1639 {
1640 TRACE();
1641
1642 // calls functions to initialize boundary conditions
1643 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++) {
1644 (this->*(bndryCndHandlerCutOffInit[bcId]))(bcId);
1645 }
1646}

◆ initModes()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initModes ( MInt  )

◆ initSmallCellCorrection()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initSmallCellCorrection ( MInt  updateOnlyBndryCndId = -1)
Author
Lennart Schneiders

Definition at line 9549 of file fvcartesianbndrycndxd.cpp.

9549 {
9550 TRACE();
9551
9553 return;
9554 }
9555
9556 const MInt minRecDim = nDim + 1;
9557 const MInt medRecDim = 2 * nDim + 1;
9558 const MInt maxRecDim = m_secondOrderRec ? (IPOW2(nDim) + 2) : minRecDim;
9559 const MInt noBndryCells = m_bndryCells->size();
9560 const MInt maxNoSrfcs = 14;
9561 const MInt volFactor = nDim == 3 ? 4 : 2;
9563 mTerm(1, AT_, "Increase maxNoSrfcs. " + to_string(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces));
9564 }
9565 const MInt maxNoNghbrs = 200;
9566 const MInt noLayersStencil = m_noFluxRedistributionLayers;
9567 const MFloat condNumThreshold = 1e7;
9569 if(noLayersStencil > mMin(m_noFluxRedistributionLayers, m_solver->noHaloLayers())) {
9570 cerr << "Warning: noLayersStencil smaller than flux redistribution layers!" << endl;
9571 }
9572 if(firstRun) m_log << "Initializing small cell treatment." << endl;
9573
9575 MFloatScratchSpace deltaXSurf(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, nDim, AT_, "deltaXSurf");
9576 MFloatScratchSpace deltaXSurfProj(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, nDim, AT_, "deltaXSurfProj");
9578 MFloatScratchSpace backup(FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces, maxRecDim, AT_, "backup");
9579 MFloatScratchSpace mat(maxNoNghbrs, maxRecDim, AT_, "mat_smallCells");
9580 MFloatScratchSpace matInv(maxRecDim, maxNoNghbrs, AT_, "matInv");
9581 MFloatScratchSpace weights(maxNoNghbrs, AT_, "weights");
9582
9583 MFloat maxCondNum0 = F0;
9584 MFloat maxCondNum1 = F0;
9585 MFloat avgCondNum0 = F0;
9586 MFloat avgCondNum1 = F0;
9587 MFloat condCnt0 = F0;
9588 MFloat condCnt1 = F0;
9589
9590 m_smallCutCells.clear();
9591 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
9592 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
9593 const MInt noSrfcs = m_bndryCells->a[bndryId].m_noSrfcs;
9594 MInt gridcellId = cellId;
9595 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitClone)) {
9596 gridcellId = m_solver->m_splitChildToSplitCell.find(cellId)->second;
9597 }
9598
9599 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
9600 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
9601 if(!m_solver->a_hasProperty(cellId, SolverCell::IsSplitChild) && m_solver->c_noChildren(gridcellId) > 0) continue;
9602 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
9603 if(m_solver->a_isPeriodic(cellId)) continue;
9604 if(m_solver->a_isHalo(cellId)) continue;
9605
9606 // commented version also applies smallCellCorrection for cutCells on lower levels, however
9607 // they only need to be stabilised if their volume falls below the threshold of the fines cells!
9608 // maxLevelChange
9609 const MFloat vfrac =
9611 ? m_solver->a_cellVolume(cellId) / m_solver->grid().gridCellVolume(m_solver->a_level(cellId))
9612 : m_solver->a_cellVolume(cellId) / m_solver->grid().gridCellVolume(m_solver->maxLevel());
9613 MBool atWall = false;
9614 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
9615 if(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId / 1000 == 3) atWall = true;
9616 }
9617 MFloat volumeLimit = atWall ? m_volumeLimitWall : m_volumeLimitOther;
9618
9620 volumeLimit = volumeLimit * volFactor * (m_solver->maxLevel() - m_solver->a_level(cellId));
9621 }
9622
9623 if(vfrac < volumeLimit) {
9624 m_smallCutCells.push_back(bndryId);
9625 } else {
9626 // continue;
9627 }
9628
9629 MBool skip = false;
9630 if(updateOnlyBndryCndId > -1) {
9631 skip = true;
9632 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9633 if(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId == updateOnlyBndryCndId) skip = false;
9634 }
9635 }
9636 if(skip && vfrac < volumeLimit
9637 && m_bndryCell[bndryId].m_cellVarsRecConst.size()
9638 != IPOW2(noSrfcs) * m_bndryCell[bndryId].m_recNghbrIds.size()) {
9639 cerr << domainId() << ": strange skip " << cellId << " " << m_solver->c_globalId(cellId) << endl;
9640 }
9641 if(skip) continue;
9642
9643 const MFloat normalizationFactor =
9644 FPOW2(m_solver->a_level(cellId))
9645 / m_solver->c_cellLengthAtLevel(0); // scaling factor to reduce the condition number of the resulting eq. sys.
9646 const MInt recSize = m_bndryCell[bndryId].m_recNghbrIds.size();
9647 ASSERT(recSize > 0, "");
9648
9649 MFloatScratchSpace dummyCoordinates(noSrfcs, nDim, AT_, "dummyCoordinates");
9650 MIntScratchSpace dummyLevel(noSrfcs, AT_, "dummyLevel");
9651 MFloatScratchSpace dummyCellVolume(noSrfcs, AT_, "dummyCellVolume");
9652
9653 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9654 deltaNSurf[srfc] = F0;
9655 for(MInt i = 0; i < nDim; i++) {
9656 normal(srfc, i) = m_bndryCell[bndryId].m_srfcs[srfc]->m_normalVector[i];
9657 deltaNSurf[srfc] +=
9658 normal(srfc, i)
9659 * (m_solver->a_coordinate(cellId, i) - m_bndryCell[bndryId].m_srfcs[srfc]->m_coordinates[i]);
9660 }
9661 for(MInt i = 0; i < nDim; i++) {
9662 deltaXSurf(srfc, i) = m_bndryCell[bndryId].m_srfcs[srfc]->m_coordinates[i]
9663 - m_solver->a_coordinate(cellId, i); // Futile, see lines below!
9664 deltaXSurfProj(srfc, i) = -mMax(1e-12, deltaNSurf[srfc]) * normal(srfc, i);
9665 deltaXSurf(srfc, i) = deltaXSurfProj(srfc, i);
9666 }
9667
9668 const MInt dummyId = m_bndryCell[bndryId].m_recNghbrIds[srfc]; // dummyIds(srfc);
9669 dummyLevel[srfc] = m_solver->a_level(cellId);
9670 dummyCellVolume(srfc) = m_solver->grid().gridCellVolume(m_solver->a_level(cellId));
9671 m_solver->a_bndryId(dummyId) = -1;
9672 for(MInt i = 0; i < nDim; i++) {
9673 dummyCoordinates(srfc, i) = m_solver->a_coordinate(cellId, i) + deltaXSurfProj(srfc, i);
9674 }
9675 }
9676
9677 mat.fill(F0);
9678 weights.fill(F0);
9679
9680 MFloat counter = F0;
9681 for(MInt k = 0; k < recSize; k++) {
9682 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[k];
9683 const MInt nghbrLevel = (k < noSrfcs) ? dummyLevel[k] : m_solver->a_level(nghbrId);
9684 const MFloat nghbrCellVolume = (k < noSrfcs) ? dummyCellVolume(k) : m_solver->a_cellVolume(nghbrId);
9685 counter += (m_solver->a_bndryId(nghbrId) > -1)
9686 ? maia::math::deltaFun(nghbrCellVolume / m_solver->grid().gridCellVolume(nghbrLevel), 1e-8, F1)
9687 : F1;
9688 }
9689 const MInt recDim = mMax(
9690 minRecDim, (counter > (MFloat)maxRecDim) ? maxRecDim : ((counter > (MFloat)medRecDim) ? medRecDim : minRecDim));
9691 // const MInt recDim = maxRecDim;
9692 const MInt recDim2 = minRecDim;
9693 ASSERT(minRecDim, "");
9694 ASSERT(medRecDim, "");
9695
9696 for(MInt k = 0; k < recSize; k++) {
9697 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[k]; // nghbrList(k);
9698 const MFloat* const nghbrCoord = (k < noSrfcs) ? &dummyCoordinates(k, 0) : &(m_solver->a_coordinate(nghbrId, 0));
9699 const MInt nghbrLevel = (k < noSrfcs) ? dummyLevel[k] : m_solver->a_level(nghbrId);
9700 const MFloat nghbrCellVolume = (k < noSrfcs) ? dummyCellVolume(k) : m_solver->a_cellVolume(nghbrId);
9701 MFloat deltaX[3];
9702 MFloat dx = F0;
9703 for(MInt i = 0; i < nDim; i++) {
9704 deltaX[i] = (nghbrCoord[i] - m_solver->a_coordinate(cellId, i)) * normalizationFactor;
9705 dx += POW2(nghbrCoord[i] - m_solver->a_coordinate(cellId, i));
9706 }
9707
9708 MFloat nfac = F1;
9709 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9710 MFloat dn = F0;
9711 for(MInt i = 0; i < nDim; i++) {
9712 dn += (nghbrCoord[i] - m_bndryCell[bndryId].m_srfcs[srfc]->m_coordinates[i]) * normal(srfc, i);
9713 }
9714 MFloat deltan = 0.1 * m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId));
9715 nfac *= mMin(F1, mMax(F0, (dn + deltan) / deltan));
9716 // nfac *= mMin( F1, mMax( F0, (dn+deltan)/(F2*deltan) ) );
9717 }
9718 if(noSrfcs > 1) nfac = F1;
9719 // nfac=F1;
9720
9721 weights(k) = maia::math::RBF(dx, POW2(m_solver->c_cellLengthAtLevel(m_solver->a_level(cellId))))
9722 * maia::math::deltaFun(nghbrCellVolume / m_solver->grid().gridCellVolume(nghbrLevel), 1e-8, 1.0);
9723
9724 if(k > noSrfcs) weights(k) *= nfac; // do not remove (stability)!
9725
9726 MInt cnt = 0;
9727 mat(k, cnt) = F1;
9728 cnt++;
9729 for(MInt i = 0; i < nDim; i++) {
9730 mat(k, cnt) = deltaX[i];
9731 cnt++;
9732 }
9733 for(MInt i = 0; i < nDim; i++) {
9734 if(cnt >= recDim) continue;
9735 mat(k, cnt) = F1B2 * POW2(deltaX[i]);
9736 cnt++;
9737 }
9738 for(MInt i = 0; i < nDim; i++) {
9739 for(MInt j = i + 1; j < nDim; j++) {
9740 if(cnt >= recDim) continue;
9741 mat(k, cnt) = deltaX[i] * deltaX[j];
9742 cnt++;
9743 }
9744 }
9745 }
9746
9747
9748 maia::math::invert(mat, weights, matInv, recSize, recDim);
9749 const MFloat condNum = maia::math::frobeniusMatrixNormSquared(mat, recSize, recDim);
9750
9751 maxCondNum0 = mMax(maxCondNum0, condNum);
9752 avgCondNum0 += condNum;
9753 condCnt0 += F1;
9754 if(condNum < F0 || condNum > condNumThreshold) {
9755 cerr << "(1) Warning: SVD failed (" << condNum << ") cell " << cellId << " (" << m_solver->c_globalId(cellId)
9756 << ") "
9757 << ", " << recSize << "x" << recDim << " vfrac " << setprecision(14)
9758 << m_bndryCells->a[bndryId].m_volume / m_solver->grid().gridCellVolume(m_solver->a_level(cellId))
9759 << setprecision(6) << ", p13: " << m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)
9760 << ", p15: " << m_solver->a_isHalo(cellId) << " at timestep " << globalTimeStep
9761 << ", coords: " << m_solver->a_coordinate(cellId, 0) << " " << m_solver->a_coordinate(cellId, 10) << " "
9762 << m_solver->a_coordinate(cellId, mMin(nDim - 1, 2)) << endl;
9763 // for ( MInt k = 0; k < recSize; k++ ) cerr << nghbrList(k) << " "; cerr << endl;
9764 // for ( MInt k = 0; k < recSize; k++ ) cerr << weights(k) << " "; cerr << endl;
9765
9766 const MFloat rank = maia::math::invertR(mat, weights, matInv, recSize, minRecDim);
9767 if(rank >= min(recSize, minRecDim)) {
9768 cerr << "Succeeded using reduced-order reconstruction." << endl;
9769 } else {
9770 cerr << "Failed also with reduced-order reconstruction, using fallback solution." << endl;
9771 }
9772 }
9773
9774 for(MInt k = 0; k < recSize; k++) {
9775 MInt cnt = 1;
9776 for(MInt i = 0; i < nDim; i++) {
9777 matInv(cnt, k) *= normalizationFactor;
9778 cnt++;
9779 }
9780 for(cnt = nDim + 1; cnt < recDim; cnt++) {
9781 matInv(cnt, k) *= POW2(normalizationFactor);
9782 }
9783 }
9784
9785 // for single boundary surface there is a Dirichlet and a Neumann stencil for the different
9786 // boundary conditions for multiple boundary surfaces, there can be combinations of
9787 // Neumann-Dirichlet or Dirichlet-Neumann boundary conditions, e.g., when a solid wall and an
9788 // outflow boundary intersect the cell, therefore IPOW2(noSrfcs) combinations
9789 m_bndryCell[bndryId].m_cellVarsRecConst.resize(recSize * IPOW2(noSrfcs));
9790 for(MInt p = 0; p < recSize; p++) {
9791 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * p] = matInv(0, p);
9792 }
9793
9794 // first and second derivatives at the cell centroid
9795 MInt noDerivs = maxRecDim - 1;
9796 m_bndryCell[bndryId].m_cellDerivRecConst.resize(noDerivs * recSize);
9797 std::fill_n(m_bndryCell[bndryId].m_cellDerivRecConst.begin(), noDerivs * recSize, F0);
9798 for(MInt k = 1; k < recDim; k++) {
9799 MInt id = k - 1;
9800 for(MInt p = 0; p < recSize; p++) {
9801 m_bndryCell[bndryId].m_cellDerivRecConst[noDerivs * p + id] = matInv(k, p);
9802 }
9803 }
9804
9805 if(condNum < F0 || condNum > condNumThreshold) {
9806 MFloat sumcnt = F0;
9807 for(MInt k = 0; k < recSize; k++) {
9808 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[k]; // nghbrList(k);
9809 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k] = F0;
9810 if(nghbrId == cellId) continue;
9811 MFloat dx = F0;
9812 for(MInt i = 0; i < nDim; i++) {
9813 dx += POW2(m_solver->a_coordinate(nghbrId, i) - m_solver->a_coordinate(cellId, i));
9814 }
9815 MFloat volume = m_solver->a_cellVolume(nghbrId);
9816 MFloat fac =
9817 maia::math::deltaFun(volume / m_solver->grid().gridCellVolume(m_solver->a_level(nghbrId)), 1e-8, 1.0);
9818 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k] = fac / mMax(1e-14, sqrt(dx));
9819 sumcnt += m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k];
9820 }
9821 for(MInt k = 0; k < recSize; k++) {
9822 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k] /= sumcnt;
9823 }
9824 }
9825
9826
9827 // backup Dirichlet stencil above
9828 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9829 for(MInt k = 0; k < recDim; k++) {
9830 backup(srfc, k) = mat(srfc, k);
9831 }
9832
9833 // !!!!!!!!!!!!!!!!!!!!!!!
9834 // !!!!!!!!!!!!!!!!!!!!!!!
9835 if(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->RHO] == BC_ISOTHERMAL) {
9836 weights(srfc) = F0; // !!!!!!!!!!!!!!!!!!!!!!! (extrapolation)
9837 }
9838 // !!!!!!!!!!!!!!!!!!!!!!!
9839 // !!!!!!!!!!!!!!!!!!!!!!!
9840 }
9841 for(MInt s = 1; s < IPOW2(noSrfcs); s++) { // zero'th bitset corresponds to full Dirichlet stencil determined above
9842 bitset<maxNoSrfcs> NeumannCode(s);
9843 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9844 if(NeumannCode.test(srfc)) {
9845 MFloat deltaX[3];
9846 MInt cnt = 1;
9847 const MFloat beta = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_robinFactor;
9848 if(std::isnan(beta)) cerr << "nan" << endl;
9849 // mat(srfc,0) = F0 ;
9850 mat(srfc, 0) = beta;
9851 for(MInt i = 0; i < nDim; i++) {
9852 deltaX[i] = deltaXSurfProj(srfc, i) * normalizationFactor;
9853 // mat( srfc , cnt ) = normal(srfc,i);
9854 mat(srfc, cnt) = normal(srfc, i) + beta * deltaX[i]; // Old line
9855 // mat(srfc, cnt) = normal(srfc, i) * normalizationFactor + beta * deltaX[i]; //TODO:Verify
9856 cnt++;
9857 }
9858 for(MInt i = 0; i < nDim; i++) {
9859 if(cnt >= recDim2) continue;
9860 // mat( srfc , cnt ) = normal(srfc,i) * deltaX[ i ];
9861 mat(srfc, cnt) = normal(srfc, i) * deltaX[i] + beta * F1B2 * POW2(deltaX[i]); // Old line
9862 // mat(srfc, cnt) = normal(srfc, i) * normalizationFactor * deltaX[i] + beta * F1B2 * POW2(deltaX[i]);
9863 cnt++;
9864 }
9865 for(MInt i = 0; i < nDim; i++) {
9866 for(MInt j = i + 1; j < nDim; j++) {
9867 if(cnt >= recDim2) continue;
9868 // mat( srfc , cnt ) = normal(srfc,i) * deltaX[ j ] + normal(srfc,j) * deltaX[ i ];
9869 // TODO: check
9870 // mat(srfc, cnt) = normal(srfc, i) * normalizationFactor * deltaX[j] + normal(srfc, j) *
9871 // normalizationFactor * deltaX[i] + beta * deltaX[i] * deltaX[j];
9872 mat(srfc, cnt) = normal(srfc, i) * deltaX[j] + normal(srfc, j) * deltaX[i] + beta * deltaX[i] * deltaX[j];
9873 cnt++;
9874 }
9875 }
9876 } else {
9877 for(MInt k = 0; k < recDim; k++) {
9878 mat(srfc, k) = backup(srfc, k);
9879 }
9880 }
9881 }
9882
9883 ASSERT(recDim2 <= recDim, "");
9884 maia::math::invert(mat, weights, matInv, recSize, recDim2);
9885 const MFloat condNum2 = maia::math::frobeniusMatrixNormSquared(mat, recSize, recDim2);
9886 maxCondNum1 = mMax(maxCondNum1, condNum2);
9887 avgCondNum1 += condNum;
9888 condCnt1 += F1;
9889 if(condNum2 < F0 || condNum2 > condNumThreshold) {
9890 cerr << "(2) Warning: SVD failed (" << condNum2 << ") cell " << cellId << " (" << m_solver->c_globalId(cellId)
9891 << ") "
9892 << ", " << recSize << "x" << recDim2 << " vfrac "
9893 << m_bndryCells->a[bndryId].m_volume / m_solver->grid().gridCellVolume(m_solver->a_level(cellId)) << endl;
9894 }
9895
9896 for(MInt k = 0; k < recSize; k++) {
9897 MInt cnt = 1;
9898 for(MInt i = 0; i < nDim; i++) {
9899 matInv(cnt, k) *= normalizationFactor;
9900 cnt++;
9901 }
9902 for(cnt = nDim + 1; cnt < recDim2; cnt++) {
9903 matInv(cnt, k) *= POW2(normalizationFactor);
9904 }
9905 }
9906 for(MInt p = 0; p < recSize; p++) {
9907 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * p + s] = matInv(0, p);
9908 }
9909
9910 // fallback solution: inverse distance weighting
9911 if(condNum2 < F0 || condNum2 > condNumThreshold) {
9912 MFloat sumcnt = F0;
9913 for(MInt k = 0; k < recSize; k++) {
9914 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[k]; // nghbrList(k);
9915 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k + s] = F0;
9916 if(nghbrId == cellId) continue;
9917 if(k < noSrfcs) continue;
9918 MFloat dx = F0;
9919 for(MInt i = 0; i < nDim; i++) {
9920 dx += POW2(m_solver->a_coordinate(nghbrId, i) - m_solver->a_coordinate(cellId, i));
9921 }
9922 MFloat volume = m_solver->a_cellVolume(nghbrId);
9923 MFloat fac =
9924 maia::math::deltaFun(volume / m_solver->grid().gridCellVolume(m_solver->a_level(nghbrId)), 1e-8, 1.0);
9925 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k + s] = fac / mMax(1e-14, sqrt(dx));
9926 sumcnt += m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k + s];
9927 }
9928 for(MInt k = 0; k < recSize; k++) {
9929 m_bndryCell[bndryId].m_cellVarsRecConst[IPOW2(noSrfcs) * k + s] /= sumcnt;
9930 }
9931 }
9932 }
9933 }
9934 if(firstRun || globalTimeStep % 100 == 0) {
9935 m_log << "Small cell treatment average (maximum) condition numbers == Dirichlet stencil: " << avgCondNum0 / condCnt0
9936 << " (" << maxCondNum0 << "), Neumann stencil: " << avgCondNum1 / condCnt1 << " (" << maxCondNum1 << ")."
9937 << endl;
9938 }
9939
9940 MLong smallCells = m_smallCutCells.size();
9941 MPI_Allreduce(MPI_IN_PLACE, &smallCells, 1, MPI_LONG, MPI_SUM, mpiComm(), AT_, "MPI_IN_PLACE", "smallCells");
9942
9943 if(firstRun || globalTimeStep % 100 == 0) {
9944 m_log << "Number of small cut cells for flux redistribution: " << m_smallCutCells.size() << "; global "
9945 << smallCells << endl;
9946 }
9947#ifndef NDEBUG
9948 /*
9949 for( MInt bndryId = 0; bndryId < noBndryCells; bndryId++ ) {
9950 const MInt noSrfcs = m_bndryCells->a[bndryId].m_noSrfcs;
9951 for(MInt srfc = 0; srfc < noSrfcs; srfc++){
9952 if ( m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_imagePointRecConst.size() !=
9953 m_bndryCell[ bndryId ].m_recNghbrIds.size() ) { cerr << domainId() << ": " << bndryId << " " <<
9954 srfc << " " << m_bndryCell[ bndryId ].m_recNghbrIds.size()
9955 << " " << m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_imagePointRecConst.size()
9956 << endl; mTerm(1,AT_, "FvBndryCndXD::bcInitSmallCellCorrection: Inconsistency 1.");
9957 }
9958 }
9959 }*/
9960 for(MUint smallc = 0; smallc < m_smallCutCells.size(); smallc++) {
9961 const MInt bndryId = m_smallCutCells[smallc];
9962 const MInt noSrfcs = m_bndryCells->a[bndryId].m_noSrfcs;
9963 if(m_bndryCell[bndryId].m_cellVarsRecConst.size() != IPOW2(noSrfcs) * m_bndryCell[bndryId].m_recNghbrIds.size()) {
9964 cerr << m_bndryCell[bndryId].m_cellVarsRecConst.size() << " "
9965 << IPOW2(noSrfcs) * m_bndryCell[bndryId].m_recNghbrIds.size() << " "
9966 << m_solver->a_isHalo(m_bndryCells->a[bndryId].m_cellId) << endl;
9967 mTerm(1, AT_, "FvBndryCndXD::initSmallCellCorrection: Inconsistency 1.");
9968 }
9969 }
9970#endif
9971
9972 firstRun = false;
9973}
MBool m_static_initSmallCellCorrection_firstRun
std::vector< MInt > m_smallCutCells
MBool a_isPeriodic(const MInt cellId) const
Returns IsPeriodic of the cell cellId.
MInt invertR(T &A, T &weights, T &AInv, const MInt m, const MInt n)
Definition: maiamath.cpp:280

◆ initSmallCellRHSCorrection()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initSmallCellRHSCorrection ( MInt  updateOnlyBndryCndId = -1)

◆ initWMBndryCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initWMBndryCells ( )

◆ initWMSurfaces()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::initWMSurfaces

Definition at line 7007 of file fvcartesianbndrycndxd.cpp.

7007 {
7008 TRACE();
7009
7010 m_solver->m_wmSurfaces.clear();
7011
7012 if(PV->noVariables > 5) mTerm(1, AT_, "WMLES not implemented for noPVars > 5");
7013
7014 const MFloat utau = sqrt(m_solver->m_UInfinity / m_solver->m_wmDistance / sysEqn().m_Re0);
7015
7016 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
7017 MInt bc = m_bndryCndIds[bcId];
7018 switch(bc) {
7019 case 3399:
7020 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
7021 const MInt bndryId = m_sortedBndryCells->a[id];
7022 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
7023 if(m_solver->a_hasProperty(cellId, SolverCell::IsHalo)) continue;
7024 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
7025
7026 m_bndryCells->a[bndryId].m_isWMCell = true;
7027
7028 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
7029 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_wmSrfcId = (MInt)m_solver->m_wmSurfaces.size();
7031 m_solver->m_wmSurfaces.back().init(bndryId, srfc, utau);
7032 m_solver->m_wmSurfaces.back().m_wmUII = m_solver->m_UInfinity;
7033 if(std::isnan(m_solver->m_wmSurfaces.back().m_wmUTAU)) {
7034 MLong gId = m_solver->c_globalId(cellId);
7035 cerr << "utau is nan at globalId = " << gId << " bndryId = " << bndryId << " surfaceId = " << srfc
7036 << endl;
7037 m_log << "utau is nan at globalId = " << gId << " bndryId = " << bndryId << " surfaceId = " << srfc
7038 << endl;
7039 }
7040 }
7041 }
7042 break;
7043 default:
7044 break;
7045 }
7046 }
7047}
std::vector< FvWMSurface< nDim > > m_wmSurfaces

◆ isCutOffInterface()

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::isCutOffInterface ( MInt  cellId)

Definition at line 2016 of file fvcartesianbndrycndxd.cpp.

2016 {
2017 if(!m_solver->m_cutOffInterface.size()) return 0;
2018
2019 // a. Create target for check
2020 const MFloat cellHalfLength = m_solver->c_cellLengthAtCell(cellId) / F2;
2021 MFloat target[6];
2022 std::vector<MInt> nodeList;
2023
2024 for(MInt j = 0; j < nDim; j++) {
2025 target[j] = m_solver->a_coordinate(cellId, j) - cellHalfLength;
2026 target[j + nDim] = m_solver->a_coordinate(cellId, j) + cellHalfLength;
2027 }
2028
2029 // b. Do the intersection test
2030 if(m_gridCutTest == "SAT")
2031 m_solver->m_geometry->getIntersectionElements(target, nodeList, cellHalfLength, &m_solver->a_coordinate(cellId, 0));
2032 else
2033 m_solver->m_geometry->getIntersectionElements(target, nodeList);
2034
2035 const MInt noNodes = nodeList.size();
2036 if(noNodes == 0) return 0;
2037
2038 // c. check for the lowest bcId
2039 MInt bndCndId = m_solver->m_geometry->elements[nodeList[0]].m_bndCndId;
2040 for(MInt n = 1; n < noNodes; n++) {
2041 bndCndId = mMin(m_solver->m_geometry->elements[nodeList[n]].m_bndCndId, bndCndId);
2042 }
2043 if(m_solver->m_cutOffInterface.find(bndCndId) == m_solver->m_cutOffInterface.end())
2044 return 0;
2045 else
2046 return bndCndId;
2047}
std::set< MInt > m_cutOffInterface

◆ markCutOff()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::markCutOff ( MIntScratchSpace cutOffCells)

Definition at line 1975 of file fvcartesianbndrycndxd.cpp.

1975 {
1976 TRACE();
1977
1978 MInt noCutOffDirections = Context::propertyLength("cutOffDirections", m_solverId);
1979
1980 // add cells to cutOffDirection noundary conditions
1981 for(MInt dir = 0; dir < noCutOffDirections; dir++) {
1982 MInt direction = Context::getSolverProperty<MInt>("cutOffDirections", m_solverId, AT_, dir);
1983 // search cells in cut off direction
1984 for(MInt cellId = 0; cellId < m_solver->noInternalCells(); cellId++) {
1985 if(m_solver->c_noChildren(cellId) > 0) continue;
1986 if(m_solver->a_hasNeighbor(cellId, direction) != 0) continue;
1987 if(m_solver->a_isInterface(cellId)) continue;
1988 if(m_solver->a_hasProperty(cellId, SolverCell::IsInactive)) continue;
1989
1990 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
1991
1992 if(m_solver->c_parentId(cellId) > -1) {
1993 const MInt parent = m_solver->c_parentId(cellId);
1994 if(m_solver->a_hasNeighbor(parent, direction) != 0) continue;
1995 if(m_solver->a_isInterface(parent)) continue;
1996 }
1997 cutOffCells(cellId) = 1;
1998 MInt parentId = m_solver->c_parentId(cellId);
1999 while(parentId > -1 && parentId < m_solver->a_noCells()) {
2000 cutOffCells(parentId) = 1;
2001 parentId = m_solver->c_parentId(parentId);
2002 }
2003 }
2004 }
2005
2006 m_solver->exchangeData(&cutOffCells(0), 1);
2007}
MInt noInternalCells() const override
Return the number of internal cells within this solver.

◆ mergeCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::mergeCells

merges master and small cells

Master cell coordinates, volume, and the coordinates, area and orientation of its body surface are updated Small cell coordinates are updated; volume and body surface remain unchanged

Cell arrays used for temporary data storage: slope[0][i] : original coordinates slope[1][0] : volumes

Author
: Daniel Hartmann, April 20, 2006

Definition at line 8632 of file fvcartesianbndrycndxd.cpp.

8632 {
8633 TRACE();
8634
8635 MInt smallCell;
8636 MInt smallCellId;
8637 MInt master;
8638 MInt masterId;
8639 MInt noCells = m_solver->a_noCells();
8640 MInt noSmallCells = m_smallBndryCells->size();
8641 MFloat area;
8642 MFloat factor;
8643 MFloat totalVolume;
8644 MFloat coordinates;
8645 MFloat avrgCoordinates;
8646 MFloatScratchSpace oldNormalVector_scratch(nDim, AT_, "oldNormalVector_scratch");
8647 MFloat* oldNormalVector = oldNormalVector_scratch.getPointer();
8648 //---
8649
8650 // store all original coordinates, reset volumes
8651 for(MInt id = 0; id < noCells; id++) {
8652 m_solver->a_slope(id, 1, 0) = m_solver->grid().gridCellVolume(m_solver->a_level(id));
8653 for(MInt i = 0; i < nDim; i++) {
8654 m_solver->a_slope(id, 0, i) = m_solver->a_coordinate(id, i);
8655 }
8656 }
8657
8658 for(MInt smallId = 0; smallId < noSmallCells; smallId++) {
8659 smallCell = m_smallBndryCells->a[smallId];
8660 smallCellId = m_bndryCell[smallCell].m_cellId;
8661 masterId = m_bndryCell[smallCell].m_linkedCellId;
8662 master = m_solver->a_bndryId(masterId);
8663
8664 if(master > -1) {
8665 // first case: master cell is a boundary cell
8666 // ------------------------------------------
8667
8668 totalVolume = m_bndryCell[master].m_volume + m_bndryCell[smallCell].m_volume;
8669
8670 for(MInt v = 0; v < CV->noVariables; v++) {
8671 m_solver->a_variable(masterId, v) = (m_solver->a_variable(masterId, v) * m_bndryCell[master].m_volume
8672 + m_solver->a_variable(smallCellId, v) * m_bndryCell[smallCell].m_volume)
8673 / totalVolume;
8674 m_solver->a_variable(smallCellId, v) = m_solver->a_variable(masterId, v);
8675 }
8676 for(MInt v = 0; v < PV->noVariables; v++) {
8677 m_solver->a_pvariable(masterId, v) = (m_solver->a_pvariable(masterId, v) * m_bndryCell[master].m_volume
8678 + m_solver->a_pvariable(smallCellId, v) * m_bndryCell[smallCell].m_volume)
8679 / totalVolume;
8680 m_solver->a_pvariable(smallCellId, v) = m_solver->a_pvariable(masterId, v);
8681 }
8682
8683
8684 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8685 // update coordinates of the...
8686 coordinates = (m_solver->a_coordinate(masterId, spaceId) * m_bndryCell[master].m_volume
8687 + m_solver->a_coordinate(smallCellId, spaceId) * m_bndryCell[smallCell].m_volume)
8688 / totalVolume;
8689 // ...master cell
8690 m_bndryCell[master].m_coordinates[spaceId] += (coordinates - m_solver->a_coordinate(masterId, spaceId));
8691 m_solver->a_coordinate(masterId, spaceId) = coordinates;
8692
8693 // update surface coordinates
8694 // --------------------------
8695 // the new surface coordinates are the area-average of the small cell and
8696 // master cell body surfaces
8697 avrgCoordinates =
8698 (m_bndryCell[master].m_srfcs[0]->m_coordinates[spaceId] * m_bndryCell[master].m_srfcs[0]->m_area
8699 + m_bndryCell[smallCell].m_srfcs[0]->m_coordinates[spaceId] * m_bndryCell[smallCell].m_srfcs[0]->m_area)
8700 / (m_bndryCell[master].m_srfcs[0]->m_area + m_bndryCell[smallCell].m_srfcs[0]->m_area);
8701
8702 m_bndryCell[master].m_srfcs[0]->m_coordinates[spaceId] = avrgCoordinates;
8703
8704 // update surface orientation
8705 // --------------------------
8706 oldNormalVector[spaceId] = m_bndryCell[master].m_srfcs[0]->m_normalVector[spaceId];
8707 m_bndryCell[master].m_srfcs[0]->m_normalVector[spaceId] =
8708 m_bndryCell[master].m_srfcs[0]->m_normalVector[spaceId] * m_bndryCell[master].m_srfcs[0]->m_area
8709 + m_bndryCell[smallCell].m_srfcs[0]->m_normalVector[spaceId] * m_bndryCell[smallCell].m_srfcs[0]->m_area;
8710 }
8711 factor = 0;
8712 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8713 factor += POW2(m_bndryCell[master].m_srfcs[0]->m_normalVector[spaceId]);
8714 }
8715 factor = sqrt(factor);
8716 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8717 m_bndryCell[master].m_srfcs[0]->m_normalVector[spaceId] =
8718 m_bndryCell[master].m_srfcs[0]->m_normalVector[spaceId] / factor;
8719 }
8720
8721 // update surface area
8722 area = 0;
8723 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8724 area += m_bndryCell[master].m_srfcs[0]->m_normalVector[spaceId]
8725 * (oldNormalVector[spaceId] * m_bndryCell[master].m_srfcs[0]->m_area
8726 + m_bndryCell[smallCell].m_srfcs[0]->m_normalVector[spaceId]
8727 * m_bndryCell[smallCell].m_srfcs[0]->m_area);
8728 }
8729
8730 m_bndryCell[master].m_srfcs[0]->m_area = area;
8731
8732 // update cell volume = master cell volume + small cell volume
8733 m_bndryCell[master].m_volume = totalVolume;
8734
8735 } else {
8736 // second case: master is an internal cell
8737 // ---------------------------------------
8738 totalVolume = m_solver->a_slope(masterId, 1, 0) + m_bndryCell[smallCell].m_volume;
8739
8740 for(MInt v = 0; v < CV->noVariables; v++) {
8741 m_solver->a_variable(masterId, v) = (m_solver->a_variable(masterId, v) * m_solver->a_slope(masterId, 1, 0)
8742 + m_solver->a_variable(smallCellId, v) * m_bndryCell[smallCell].m_volume)
8743 / totalVolume;
8744 m_solver->a_variable(smallCellId, v) = m_solver->a_variable(masterId, v);
8745 }
8746 for(MInt v = 0; v < PV->noVariables; v++) {
8747 m_solver->a_pvariable(masterId, v) = (m_solver->a_pvariable(masterId, v) * m_solver->a_slope(masterId, 1, 0)
8748 + m_solver->a_pvariable(smallCellId, v) * m_bndryCell[smallCell].m_volume)
8749 / totalVolume;
8750 m_solver->a_pvariable(smallCellId, v) = m_solver->a_pvariable(masterId, v);
8751 }
8752
8753
8754 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8755 // update coordinates of the...
8756 coordinates = (m_solver->a_coordinate(masterId, spaceId) * m_solver->a_slope(masterId, 1, 0)
8757 + m_solver->a_coordinate(smallCellId, spaceId) * m_bndryCell[smallCell].m_volume)
8758 / totalVolume;
8759 // ...master cell
8760 m_solver->a_coordinate(masterId, spaceId) = coordinates;
8761 }
8762 m_solver->a_slope(masterId, 1, 0) = totalVolume;
8763 }
8764 }
8765
8766 // small cells are moved to the final position of their master cell
8767 // small cells with an internal master receive its original position
8768 for(MInt smallId = 0; smallId < noSmallCells; smallId++) {
8769 smallCell = m_smallBndryCells->a[smallId];
8770 smallCellId = m_bndryCell[smallCell].m_cellId;
8771 masterId = m_bndryCell[smallCell].m_linkedCellId;
8772 master = m_solver->a_bndryId(masterId);
8773
8774 for(MInt i = 0; i < nDim; i++) {
8775 m_bndryCell[smallCell].m_coordinates[i] +=
8776 (m_solver->a_coordinate(masterId, i) - m_solver->a_coordinate(smallCellId, i));
8777 m_solver->a_coordinate(smallCellId, i) = m_solver->a_coordinate(masterId, i);
8778 }
8779
8780 if(master == -1) {
8781 for(MInt i = 0; i < nDim; i++) {
8782 m_bndryCell[smallCell].m_masterCoordinates[i] = m_solver->a_slope(masterId, 0, i);
8783 }
8784 }
8785 }
8786}

◆ mergeCellsMGC()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::mergeCellsMGC

Master cell coordinates, volume, and the coordinates, area and orientation of its body surface are updated Small cell coordinates are updated; volume and body surface remain unchanged

Cell arrays used for temporary data storage: slope[0][i] : original coordinates slope[1][0] : volumes

Contrary to original formulation the bondary surfaces of master and small cells are kept unchanged

Author
: Claudia Guenther, April 2009

Definition at line 8807 of file fvcartesianbndrycndxd.cpp.

8807 {
8808 TRACE();
8809
8810 MInt smallCell;
8811 MInt smallCellId;
8812 MInt master;
8813 MInt masterId;
8814 MInt noCells = m_solver->a_noCells();
8815 MInt noSmallCells = m_smallBndryCells->size();
8816 MFloat totalVolume;
8817 MFloat coordinates;
8818 //---
8819
8820 // store all original coordinates, reset volumes
8821 for(MInt id = 0; id < noCells; id++) {
8822 m_solver->a_slope(id, 1, 0) = m_solver->grid().gridCellVolume(m_solver->a_level(id));
8823 for(MInt i = 0; i < nDim; i++) {
8824 m_solver->a_slope(id, 0, i) = m_solver->a_coordinate(id, i);
8825 }
8826 }
8827
8828 for(MInt smallId = 0; smallId < noSmallCells; smallId++) {
8829 smallCell = m_smallBndryCells->a[smallId];
8830 smallCellId = m_bndryCell[smallCell].m_cellId;
8831 masterId = m_bndryCell[smallCell].m_linkedCellId;
8832 master = m_solver->a_bndryId(masterId);
8833
8834 if(master > -1) {
8835 // first case: master cell is a boundary cell
8836 // ------------------------------------------
8837
8838 totalVolume = m_bndryCell[master].m_volume + m_bndryCell[smallCell].m_volume;
8839
8840 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8841 // update coordinates of the...
8842 coordinates = (m_solver->a_coordinate(masterId, spaceId) * m_bndryCell[master].m_volume
8843 + m_solver->a_coordinate(smallCellId, spaceId) * m_bndryCell[smallCell].m_volume)
8844 / totalVolume;
8845 // ...master cell
8846 m_bndryCell[master].m_coordinates[spaceId] += (coordinates - m_solver->a_coordinate(masterId, spaceId));
8847 m_solver->a_coordinate(masterId, spaceId) = coordinates;
8848 }
8849
8850 // update cell volume = master cell volume + small cell volume
8851 m_bndryCell[master].m_volume = totalVolume;
8852
8853 } else {
8854 // second case: master is an internal cell
8855 // ---------------------------------------
8856 totalVolume = m_solver->a_slope(masterId, 1, 0) + m_bndryCell[smallCell].m_volume;
8857
8858 for(MInt spaceId = 0; spaceId < nDim; spaceId++) {
8859 // update coordinates of the...
8860 coordinates = (m_solver->a_coordinate(masterId, spaceId) * m_solver->a_slope(masterId, 1, 0)
8861 + m_solver->a_coordinate(smallCellId, spaceId) * m_bndryCell[smallCell].m_volume)
8862 / totalVolume;
8863 // ...master cell
8864 m_solver->a_coordinate(masterId, spaceId) = coordinates;
8865 }
8866
8867 // if master has multiple small cells, volume must be updated!
8868 m_solver->a_slope(masterId, 1, 0) = totalVolume;
8869 }
8870 }
8871
8872 // small cells are moved to the final position of their master cell
8873 // small cells with an internal master receive its original position
8874 // in the masterCoordinates variable
8875 for(MInt smallId = 0; smallId < noSmallCells; smallId++) {
8876 smallCell = m_smallBndryCells->a[smallId];
8877 smallCellId = m_bndryCell[smallCell].m_cellId;
8878 masterId = m_bndryCell[smallCell].m_linkedCellId;
8879 master = m_solver->a_bndryId(masterId);
8880
8881 for(MInt i = 0; i < nDim; i++) {
8882 m_bndryCell[smallCell].m_coordinates[i] +=
8883 (m_solver->a_coordinate(masterId, i) - m_solver->a_coordinate(smallCellId, i));
8884 m_solver->a_coordinate(smallCellId, i) = m_solver->a_coordinate(masterId, i);
8885 }
8886
8887 if(master == -1) {
8888 for(MInt i = 0; i < nDim; i++) {
8889 m_bndryCell[smallCell].m_masterCoordinates[i] = m_solver->a_slope(masterId, 0, i);
8890 }
8891 }
8892 }
8893}

◆ mpiComm()

template<MInt nDim, class SysEqn >
MPI_Comm FvBndryCndXD< nDim, SysEqn >::mpiComm ( ) const
inlineprotected

Definition at line 485 of file fvcartesianbndrycndxd.h.

485{ return m_solver->mpiComm(); }
MPI_Comm mpiComm() const
Return the MPI communicator used by this solver.
Definition: solver.h:380

◆ noDomains()

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::noDomains ( ) const
inlineprotected

Definition at line 491 of file fvcartesianbndrycndxd.h.

491{ return m_solver->noDomains(); }

◆ plotAllCutPoints()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::plotAllCutPoints
Author
Claudia Guenther, December 2008

Definition at line 12262 of file fvcartesianbndrycndxd.cpp.

12262 {
12263 TRACE();
12264
12265 const MChar* fileName = "AllCutPoints_";
12266 stringstream fileName2;
12267 fileName2 << fileName << domainId() << ".vtk";
12268 ofstream ofl;
12269 ofl.open((fileName2.str()).c_str(), ofstream::trunc);
12270
12271 MInt noCutPoints = 0;
12272 const MInt noCells = m_bndryCells->size();
12273
12274 //-------------------------------------
12275
12276 // count the total number of cut points
12277 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
12278 noCutPoints += m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints;
12279 }
12280
12281 if(ofl) {
12282 ofl.setf(ios::fixed);
12283 ofl.precision(20);
12284
12285 ofl << "# vtk DataFile Version 3.0" << endl
12286 << "MAIAD intersectionPoints file" << endl
12287 << "ASCII" << endl
12288 << "DATASET POLYDATA" << endl
12289 << "POINTS " << noCutPoints << " float" << endl;
12290
12291 // write each cut point in the data file
12292 for(MInt bndryId = 0; bndryId < noCells; bndryId++) {
12293 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints > 0) {
12294 for(MInt edge = 0; edge < m_noEdges; edge++) {
12295 for(MInt n = 0; n < m_bndryCells->a[bndryId].m_srfcs[0]->m_noCutPoints; n++) {
12296 if(m_bndryCells->a[bndryId].m_srfcs[0]->m_cutEdge[n] == edge) {
12297 for(MInt i = 0; i < nDim; i++) {
12298 ofl << m_bndryCells->a[bndryId].m_srfcs[0]->m_cutCoordinates[n][i] << " ";
12299 }
12300 IF_CONSTEXPR(nDim == 2) ofl << F0 << " ";
12301 ofl << endl;
12302 }
12303 }
12304 }
12305 }
12306 }
12307
12308 ofl << "VERTICES " << noCutPoints << " " << noCutPoints * 2 << endl;
12309 for(MInt i = 0; i < noCutPoints; i++) {
12310 ofl << "1 " << i << endl;
12311 }
12312 }
12313
12314 ofl.close();
12315}

◆ plotEdges()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::plotEdges ( MInt ,
MFloat **&   
)

◆ plotIntersectionPoints()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::plotIntersectionPoints ( MInt ,
MFloat ***&   
)

◆ plotSurface()

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

◆ plotTriangle()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::plotTriangle ( std::ofstream &  ,
MFloat ,
MFloat ,
MFloat ,
MFloat  
)

◆ precomputeBesselTrigonometry()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::precomputeBesselTrigonometry ( MInt  bcId)

Definition at line 7549 of file fvcartesianbndrycndxd.cpp.

7549 {
7550 TRACE();
7551 const MFloat time = m_solver->m_time;
7552 const MBool isFiltered = m_cutOffBndryCndIds[bcId] == 2800 ? true : false;
7553 const MInt noCutOffCells = m_sortedCutOffCells[bcId]->size();
7554
7555 for(MInt mode = 0; mode < m_modes; mode++) {
7556 const MFloat modeOmega = m_modeOmega[mode];
7557 const MFloat modeEtaMin = m_modeEtaMin[mode];
7558 const MFloat dphi = m_nmbrOfModes[mode] * PI;
7559
7560 for(MInt id = 0; id < noCutOffCells; id++) {
7561 const MInt cellId = m_sortedCutOffCells[bcId]->a[id];
7562
7563 // polar coords
7564 const MFloat dy = m_solver->a_coordinate(cellId, 1);
7565 const MFloat dz = m_solver->a_coordinate(cellId, 2);
7566 const MFloat r = sqrt(POW2(dy) + POW2(dz));
7567
7568 // argument
7569 const MFloat xkxmot = m_modeK[mode][0] * m_solver->a_coordinate(cellId, 0) - modeOmega * time;
7570 const MFloat rkr = r * m_modeK[mode][1];
7571
7572 const MInt offset = mode * noCutOffCells + 2 * id;
7573
7574 if(isFiltered) {
7575 calcBesselFractions(xkxmot - modeEtaMin, rkr, dphi, m_besselTrig[offset], m_besselTrig[offset + 1]);
7576 } else {
7577 m_besselTrig[offset] = cos(xkxmot) * maia::math::besselJ0(rkr);
7578 m_besselTrig[offset + 1] = cos(xkxmot + PIB2) * maia::math::besselJ1(rkr);
7579 }
7580 }
7581 }
7582}
void calcBesselFractions(const MFloat, const MFloat, const MFloat, MFloat &, MFloat &)

◆ recorrectCellCoordinates()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::recorrectCellCoordinates

Definition at line 538 of file fvcartesianbndrycndxd.cpp.

538 {
539 TRACE();
540
541 MInt smallCell = 0;
542 MInt masterId;
543 MInt noCells = m_bndryCells->size();
544 MInt noSmallCells = m_smallBndryCells->size();
545 //---
546
547 for(MInt id = 0; id < noCells; id++) {
548 for(MInt i = 0; i < nDim; i++) {
549 m_solver->a_coordinate(m_bndryCells->a[id].m_cellId, i) -= m_bndryCells->a[id].m_coordinates[i];
550 }
551 }
552 // recorrect all coordinates of internal master cells
553 for(MInt smallId = 0; smallId < noSmallCells; smallId++) {
554 smallCell = m_smallBndryCells->a[smallId];
555 masterId = m_bndryCells->a[smallCell].m_linkedCellId;
556 if(m_solver->a_bndryId(masterId) == -1) {
557 for(MInt i = 0; i < nDim; i++) {
558 m_solver->a_coordinate(masterId, i) = m_bndryCells->a[smallCell].m_masterCoordinates[i];
559 }
560 }
561 }
562 ASSERT(m_cellCoordinatesCorrected, "Irregular sequence of cell-coordinate correction!");
564}

◆ rerecorrectCellCoordinates()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::rerecorrectCellCoordinates

Definition at line 568 of file fvcartesianbndrycndxd.cpp.

568 {
569 TRACE();
570
571 const MInt noCells = m_bndryCells->size();
572 const MInt noSmallCells = m_smallBndryCells->size();
573 //---
574
575 for(MInt id = 0; id < noCells; id++) {
576 for(MInt i = 0; i < nDim; i++) {
577 m_solver->a_coordinate(m_bndryCells->a[id].m_cellId, i) += m_bndryCells->a[id].m_coordinates[i];
578 }
579 }
580 // rerecorrect all coordinates of internal master cells
581 for(MInt smallId = 0; smallId < noSmallCells; smallId++) {
582 const MInt smallCell = m_smallBndryCells->a[smallId];
583 const MInt smallCellId = m_bndryCells->a[smallCell].m_cellId;
584 const MInt masterId = m_bndryCells->a[smallCell].m_linkedCellId;
585 if(m_solver->a_bndryId(masterId) == -1) {
586 for(MInt i = 0; i < nDim; i++) {
587 m_solver->a_coordinate(masterId, i) = m_solver->a_coordinate(smallCellId, i);
588 }
589 }
590 }
591 ASSERT(!m_cellCoordinatesCorrected, "Irregular sequence of cell-coordinate correction!");
593}

◆ resetBndryCommunication()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::resetBndryCommunication

Definition at line 23642 of file fvcartesianbndrycndxd.cpp.

23642 {
23643 TRACE();
23644 if(m_comm_bc_init > 0) {
23645 for(MInt i = 0; i < m_comm_bc_init; i++) {
23646 if(m_comm_bc[i] != MPI_COMM_NULL && m_comm_bc[i] != MPI_COMM_WORLD) {
23647 MPI_Comm_free(&m_comm_bc[i], AT_, "m_comm_bc[i]");
23648 }
23649 }
23650 }
23651
23652 if(m_comm_bcCo_init > 0) {
23653 for(MInt i = 0; i < m_comm_bcCo_init; i++) {
23654 if(m_comm_bcCo[i] != MPI_COMM_NULL && m_comm_bcCo[i] != MPI_COMM_WORLD) {
23655 MPI_Comm_free(&m_comm_bcCo[i], AT_, "m_comm_bcCo[]i");
23656 }
23657 }
23658 }
23659}
int MPI_Comm_free(MPI_Comm *comm, const MString &name, const MString &varname)
same as MPI_Comm_free, but updates the number of MPI communicators

◆ resetCutOff()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::resetCutOff
Author
Tim Wegmann

Definition at line 23597 of file fvcartesianbndrycndxd.cpp.

23597 {
23598 TRACE();
23599
23600 for(auto it = m_sortedCutOffCells.begin(); it != m_sortedCutOffCells.end(); it++) {
23601 delete *it;
23602 }
23603
23604 m_sortedCutOffCells.clear();
23606}

◆ resetCutOffFirst()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::resetCutOffFirst
Author
Tim Wegmann NOTE: not ideal implementation, but working...

Definition at line 23614 of file fvcartesianbndrycndxd.cpp.

23614 {
23615 TRACE();
23616
23634 IF_CONSTEXPR(nDim == 3) {
23637 }
23638}
MBool m_static_cbc1099_1091d_after_first
MBool m_static_cbc2099_1091_local_comb_first
MBool m_static_cbc1099_1091_local_first
MBool m_static_cbc1099_1091_engine_first
MBool m_static_cbc1099_1091_local_comb_first

◆ saveBc7901()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::saveBc7901 ( )
inline

Definition at line 215 of file fvcartesianbndrycndxd.h.

215{};

◆ sbc00co()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::sbc00co ( const  MInt)

Definition at line 19371 of file fvcartesianbndrycndxd.cpp.

19371 {
19372 TRACE();
19373
19374 const MInt noVars = PV->noVariables;
19375
19376 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19377 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19378
19379 // set the cut off slopes to zero
19380 for(MInt varId = 0; varId < noVars; varId++) {
19381 for(MInt i = 0; i < nDim; i++) {
19382 m_solver->a_slope(cellId, varId, i) = F0;
19383 }
19384 }
19385 }
19386}

◆ sbc1000co()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::sbc1000co ( const  MInt)

Definition at line 19434 of file fvcartesianbndrycndxd.cpp.

19434 {
19435 TRACE();
19436
19437 const MInt noVars = PV->noVariables;
19438 const MInt otherDir[6] = {1, 0, 3, 2, 5, 4};
19439
19441 const MInt fixedMaxNoBndryCndIds = s_sbc1000co_fixedMaxNoBndryCndIds;
19442 MInt(&directions)[fixedMaxNoBndryCndIds] = m_static_sbc1000co_directions;
19443 if(first) { // TODO labels:FV move this to some initialization routine
19444 if(fixedMaxNoBndryCndIds < m_maxNoBndryCndIds) {
19445 mTerm(1, AT_, "fixedMaxNoBndryCndIds is too small. increase...");
19446 }
19447
19448 MInt noCutOffBndryIds = Context::propertyLength("cutOffBndryIds", m_solverId);
19449 MInt noCutOffDirections = Context::propertyLength("cutOffDirections", m_solverId);
19450 if(noCutOffDirections != noCutOffBndryIds) {
19451 mTerm(1, AT_,
19452 "Wrong number of cut off directions. Must be identical to number of cut off bndryIds! Please check!");
19453 }
19454 MInt cutOffBndryIdTmp, cutOffDirectionTmp;
19455 for(MInt bc = 0; bc < m_noCutOffBndryCndIds; bc++) {
19456 for(MInt i = 0; i < noCutOffBndryIds; i++) {
19457 cutOffBndryIdTmp = Context::getSolverProperty<MInt>("cutOffBndryIds", m_solverId, AT_, i);
19458 cutOffDirectionTmp = Context::getSolverProperty<MInt>("cutOffDirections", m_solverId, AT_, i);
19459 if(cutOffBndryIdTmp == m_cutOffBndryCndIds[bc]) {
19460 directions[bc] = otherDir[cutOffDirectionTmp];
19461 break;
19462 }
19463 }
19464 }
19465
19466 first = false;
19467 }
19468 //---end of initialization
19469
19470 const MInt direction = directions[bcId];
19471
19472 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
19473 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
19474 MLong nghbrId = m_solver->c_neighborId(cellId, direction);
19475
19476 // continue if the neighbor does not exist -> happens on the second layer of halo cells
19477 if(nghbrId < 0) {
19478 TERMM_IF_NOT_COND(m_solver->a_isHalo(cellId), "Error: cell has no neighbor and is not a halo cell.");
19479 continue;
19480 }
19481
19482 if(m_solver->a_hasProperty(nghbrId, SolverCell::IsInactive)) continue;
19483
19484 if(m_solver->a_hasProperty(nghbrId, SolverCell::IsOnCurrentMGLevel)) {
19485 // copy the slopes from the boundary cell to the ghost cell
19486 for(MInt varId = 0; varId < noVars; varId++) {
19487 for(MInt i = 0; i < nDim; i++) {
19488 m_solver->a_slope(cellId, varId, i) = m_solver->a_slope(nghbrId, varId, i);
19489 }
19490 }
19491 }
19492 }
19493}
MInt m_static_sbc1000co_directions[s_sbc1000co_fixedMaxNoBndryCndIds]
static constexpr MInt s_sbc1000co_fixedMaxNoBndryCndIds

◆ sbc1002()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::sbc1002 ( MInt  bcId)
Author
Claudia Guenther
Date
01/2014

Definition at line 19500 of file fvcartesianbndrycndxd.cpp.

19500 {
19501 TRACE();
19502
19503 MInt cellId;
19504 MInt ghostCellId = 0;
19505 const MInt noVars = PV->noVariables;
19506 //---end of initialization
19507
19508 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
19509 cellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_cellId;
19510 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
19511 ghostCellId = m_bndryCells->a[m_sortedBndryCells->a[id]].m_srfcVariables[0]->m_ghostCellId;
19512
19513 // copy the slopes from the boundary cell to the ghost cell
19514 for(MInt varId = 0; varId < noVars; varId++) {
19515 m_solver->a_slope(ghostCellId, varId, 0) = m_solver->a_slope(cellId, varId, 0);
19516 m_solver->a_slope(ghostCellId, varId, 1) = -m_solver->a_slope(cellId, varId, 1);
19517 }
19518 }
19519 }
19520}

◆ sbc2000()

template<MInt nDim, class SysEqn >
template<MBool MGC>
void FvBndryCndXD< nDim, SysEqn >::sbc2000 ( MInt  bcId)

Solid wall Navier-Stokes boundary condition - adiabatic wall
Computes ghost cell slopes for the viscous flux computation
See 3D-paper
Uses precomputed plane vectors and Jacobian

Author
Daniel Hartmann, Sven Berger

Definition at line 6659 of file fvcartesianbndrycndxd.cpp.

6659 {
6660 TRACE();
6661
6662 const MInt noPVars = PV->noVariables;
6663
6664#ifdef _OPENMP
6665#pragma omp parallel for
6666#endif
6667 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
6668 const MInt bndryId = m_sortedBndryCells->a[id];
6669 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
6670
6671 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
6672 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
6673 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId == m_bndryCndIds[bcId]) {
6674 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
6675
6676 MFloat preFactor = NAN;
6677 IF_CONSTEXPR(nDim == 3) {
6678 if(MGC) {
6679 // compute the distance between ghost and boundary cell (MGC formulation -> image Point)
6680 preFactor = 1.0
6681 / sqrt(POW2(m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[0]
6682 - m_solver->a_coordinate(ghostCellId, 0))
6683 + POW2(m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[1]
6684 - m_solver->a_coordinate(ghostCellId, 1))
6685 + POW2(m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[2]
6686 - m_solver->a_coordinate(ghostCellId, 2)))
6687 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_FJacobian;
6688 } else {
6689 // compute the distance between ghost and boundary cell and multiply with inverse Jacobian
6690 preFactor = 1.0
6691 / sqrt(POW2(m_solver->a_coordinate(cellId, 0) - m_solver->a_coordinate(ghostCellId, 0))
6692 + POW2(m_solver->a_coordinate(cellId, 1) - m_solver->a_coordinate(ghostCellId, 1))
6693 + POW2(m_solver->a_coordinate(cellId, 2) - m_solver->a_coordinate(ghostCellId, 2)))
6694 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_FJacobian;
6695 }
6696 }
6697 else {
6698 if(MGC) {
6699 // compute the distance between ghost and boundary cell (MGC formulation -> image Point)
6700 preFactor = 1.0
6701 / sqrt(POW2(m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[0]
6702 - m_solver->a_coordinate(ghostCellId, 0))
6703 + POW2(m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[1]
6704 - m_solver->a_coordinate(ghostCellId, 1)))
6705 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_FJacobian;
6706
6707 } else {
6708 // compute the distance between ghost and boundary cell and multiply with inverse Jacobian
6709 preFactor = 1.0
6710 / sqrt(POW2(m_solver->a_coordinate(cellId, 0) - m_solver->a_coordinate(ghostCellId, 0))
6711 + POW2(m_solver->a_coordinate(cellId, 1) - m_solver->a_coordinate(ghostCellId, 1)))
6712 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_FJacobian;
6713 }
6714 }
6715
6716 MFloat const1;
6717 MFloat const2;
6718 MFloat const3;
6719
6720 IF_CONSTEXPR(nDim == 3) {
6721 // compute the surface slopes
6722 const1 = (m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector0[1]
6723 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector1[2]
6724 - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector1[1]
6725 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector0[2])
6726 * preFactor;
6727
6728 const2 = (m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector0[2]
6729 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector1[0]
6730 - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector1[2]
6731 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector0[0])
6732 * preFactor;
6733
6734 const3 = (m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector0[0]
6735 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector1[1]
6736 - m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector1[0]
6737 * m_bndryCells->a[bndryId].m_srfcs[srfc]->m_planeVector0[1])
6738 * preFactor;
6739 }
6740 else {
6741 const1 = preFactor * m_bndryCells->a[bndryId].m_srfcs[0]->m_planeVector0[1];
6742 const2 = -preFactor * m_bndryCells->a[bndryId].m_srfcs[0]->m_planeVector0[0];
6743 const3 = 0;
6744 }
6745
6746 // compute the slopes on the ghost cell
6747 for(MInt i = 0; i < nDim; i++) {
6748 MFloat factor = NAN;
6749 if(MGC) {
6750 factor = (m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[PV->VV[i]]
6751 - m_solver->a_pvariable(ghostCellId, PV->VV[i]));
6752 } else {
6753 factor = (m_solver->a_pvariable(cellId, PV->VV[i]) - m_solver->a_pvariable(ghostCellId, PV->VV[i]));
6754 }
6755 m_solver->a_slope(ghostCellId, PV->VV[i], 0) =
6756 2.0 * factor * const1 - m_solver->a_slope(cellId, PV->VV[i], 0);
6757 m_solver->a_slope(ghostCellId, PV->VV[i], 1) =
6758 2.0 * factor * const2 - m_solver->a_slope(cellId, PV->VV[i], 1);
6759 IF_CONSTEXPR(nDim == 3) {
6760 m_solver->a_slope(ghostCellId, PV->VV[i], 2) =
6761 2.0 * factor * const3 - m_solver->a_slope(cellId, PV->VV[i], 2);
6762 }
6763 }
6764
6765
6766 for(MInt varId = nDim; varId < noPVars; varId++) {
6767 for(MInt i = 0; i < nDim; i++) {
6768 m_solver->a_slope(ghostCellId, varId, i) = -m_solver->a_slope(cellId, varId, i);
6769 }
6770 }
6771 }
6772 }
6773 }
6774 }
6775}

◆ sbc2001()

template<MInt nDim, class SysEqn >
template<MInt dir>
void FvBndryCndXD< nDim, SysEqn >::sbc2001 ( MInt  bcId)
Author
Daniel Hartmann, Sven Berger

Definition at line 6786 of file fvcartesianbndrycndxd.cpp.

6786 {
6787 TRACE();
6788 static_assert(dir <= nDim, "ERROR: Invalid direction!");
6789
6790 const MInt noPVars = PV->noVariables;
6791
6792#ifdef _OPENMP
6793#pragma omp parallel for
6794#endif
6795 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
6796 const MInt bndryId = m_sortedBndryCells->a[id];
6797 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
6798 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
6799 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
6800
6801 for(MInt v = 0; v < noPVars; v++) {
6802 if(dir == 0) {
6803 m_solver->a_slope(ghostCellId, v, 0) =
6804 (m_solver->a_pvariable(cellId, v) - m_solver->a_pvariable(ghostCellId, v))
6805 / (m_solver->a_coordinate(cellId, 0) - m_solver->a_coordinate(ghostCellId, 0));
6806 } else {
6807 m_solver->a_slope(ghostCellId, v, 0) = m_solver->a_slope(cellId, v, 0);
6808 }
6809
6810 if(dir == 1) {
6811 m_solver->a_slope(ghostCellId, v, 1) =
6812 (m_solver->a_pvariable(cellId, v) - m_solver->a_pvariable(ghostCellId, v))
6813 / (m_solver->a_coordinate(cellId, 1) - m_solver->a_coordinate(ghostCellId, 1));
6814 } else {
6815 m_solver->a_slope(ghostCellId, v, 1) = m_solver->a_slope(cellId, v, 1);
6816 }
6817
6818 IF_CONSTEXPR(nDim == 3) {
6819 if(dir == 2) {
6820 m_solver->a_slope(ghostCellId, v, 2) =
6821 (m_solver->a_pvariable(cellId, v) - m_solver->a_pvariable(ghostCellId, v))
6822 / (m_solver->a_coordinate(cellId, 2) - m_solver->a_coordinate(ghostCellId, 2));
6823 } else {
6824 m_solver->a_slope(ghostCellId, v, 2) = m_solver->a_slope(cellId, v, 2);
6825 }
6826 }
6827 }
6828
6829 // compute the slopes on the ghost cell
6830 for(MInt v = 0; v < noPVars; v++) {
6831 for(MInt i = 0; i < nDim; i++) {
6832 m_solver->a_slope(ghostCellId, v, i) =
6833 2.0 * m_solver->a_slope(ghostCellId, v, i) - m_solver->a_slope(cellId, v, i);
6834 }
6835 }
6836 }
6837 }
6838}

◆ sbc2710co()

template<MInt nDim, class SysEqn >
virtual void FvBndryCndXD< nDim, SysEqn >::sbc2710co ( MInt  )
inlinevirtual

Definition at line 249 of file fvcartesianbndrycndxd.h.

249{};

◆ sbc2720co()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::sbc2720co ( MInt  bcId)

Definition at line 22015 of file fvcartesianbndrycndxd.cpp.

22015 {
22016 TRACE();
22017 MInt direction = m_cutOffBndryCndIds[bcId] - 2720;
22018
22019 if(direction % 2) {
22020 direction--;
22021 } else {
22022 direction++;
22023 }
22024
22025 const MInt noPVars = PV->noVariables;
22026
22027 for(MInt id = 0; id < m_sortedCutOffCells[bcId]->size(); id++) {
22028 MInt cellId = m_sortedCutOffCells[bcId]->a[id];
22029 MLong nghbrId = m_solver->c_neighborId(cellId, direction);
22030
22031 if(nghbrId < 0) {
22032 continue;
22033 }
22034 if(m_solver->c_noChildren(nghbrId) > 0) {
22035 MFloat coCoord = m_solver->a_coordinate(cellId, direction / 2);
22036 MInt childCnt = 0;
22037 // reset cut off cell
22038 for(MInt varId = 0; varId < noPVars; varId++) {
22039 for(MInt i = 0; i < nDim; i++) {
22040 m_solver->a_slope(cellId, varId, i) = F0;
22041 }
22042 }
22043 for(MInt child = 0; child < IPOW2(nDim); child++) {
22044 MInt childId = m_solver->c_childId(nghbrId, child);
22045 if(childId < 0) {
22046 continue;
22047 }
22048 if(abs(m_solver->a_coordinate(childId, direction / 2) - coCoord) > m_solver->c_cellLengthAtCell(cellId)) {
22049 continue;
22050 }
22051 childCnt++;
22052 for(MInt varId = 0; varId < noPVars; varId++) {
22053 for(MInt i = 0; i < nDim; i++) {
22054 m_solver->a_slope(cellId, varId, i) += m_solver->a_slope(childId, varId, i);
22055 }
22056 }
22057 }
22058 for(MInt varId = 0; varId < noPVars; varId++) {
22059 for(MInt i = 0; i < nDim; i++) {
22060 m_solver->a_slope(cellId, varId, i) /= childCnt;
22061 }
22062 }
22063 } else {
22064 // copy the slopes
22065 for(MInt varId = 0; varId < noPVars; varId++) {
22066 for(MInt i = 0; i < nDim; i++) {
22067 m_solver->a_slope(cellId, varId, i) = m_solver->a_slope(nghbrId, varId, i);
22068 }
22069 }
22070 }
22071 }
22072}

◆ sbc2801x() [1/2]

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::sbc2801x ( MInt  bcId)
Author
Daniel Hartmann, 12.01.2007

Definition at line 22081 of file fvcartesianbndrycndxd.cpp.

22081 {
22082 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function sbc2801x is untested for 3D!"); }
22083 TRACE();
22084
22085 MInt bndryId, cellId, ghostCellId;
22086 MFloat Frho, FrhoGhost, rhoU2;
22087 const MInt noPVars = PV->noVariables;
22088 ScratchSpace<MFloat> PVbndry(noPVars, AT_, "PVbndry");
22089 ScratchSpace<MFloat> PVghost(noPVars, AT_, "PVghost");
22090 //---
22091
22092 Frho = FrhoGhost = rhoU2 = 0.0;
22093
22094 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22095 bndryId = m_sortedBndryCells->a[id];
22096 cellId = m_bndryCells->a[bndryId].m_cellId;
22097 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22098 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
22099
22100 for(MInt i = 0; i < nDim; i++) {
22101 PVbndry[i] = m_solver->a_variable(cellId, CV->RHO_VV[i]) * Frho;
22102 PVghost[i] = m_solver->a_variable(ghostCellId, CV->RHO_VV[i]) * FrhoGhost;
22103 }
22104
22105 // density
22106 PVbndry[PV->RHO] = m_solver->a_variable(cellId, CV->RHO);
22107 PVghost[PV->RHO] = m_solver->a_variable(ghostCellId, CV->RHO);
22108
22109 // pressure
22110 rhoU2 = F0;
22111 for(MInt i = 0; i < nDim; i++) {
22112 rhoU2 += POW2(m_solver->a_variable(cellId, CV->RHO_VV[i]));
22113 }
22114
22115 PVbndry[PV->P] = sysEqn().pressure(Frho, rhoU2, m_solver->a_variable(cellId, CV->RHO_E));
22116 rhoU2 = F0;
22117 for(MInt i = 0; i < nDim; i++) {
22118 rhoU2 += POW2(m_solver->a_variable(ghostCellId, CV->RHO_VV[i]));
22119 }
22120 PVbndry[PV->P] = sysEqn().pressure(FrhoGhost, rhoU2, m_solver->a_variable(ghostCellId, CV->RHO_E));
22121
22122 // species
22123 for(MInt k = 0; k < m_noSpecies; k++) {
22124 PVbndry[PV->Y[k]] = m_solver->a_variable(cellId, CV->RHO_Y[k]) * Frho;
22125 PVghost[PV->Y[k]] = m_solver->a_variable(ghostCellId, CV->RHO_Y[k]) * FrhoGhost;
22126 }
22127
22128 for(MInt var = 0; var < noPVars; var++) {
22129 m_solver->a_slope(ghostCellId, var, 0) =
22130 (PVbndry[var] - PVghost[var])
22131 / (m_solver->a_coordinate(cellId, 0) - m_solver->a_coordinate(ghostCellId, 0));
22132 m_solver->a_slope(ghostCellId, var, 1) = m_solver->a_slope(cellId, var, 1);
22133 }
22134
22135 // compute the slopes on the ghost cell
22136 for(MInt varId = 0; varId < noPVars; varId++) {
22137 for(MInt i = 0; i < nDim; i++) {
22138 m_solver->a_slope(ghostCellId, varId, i) =
22139 F2 * m_solver->a_slope(ghostCellId, varId, i) - m_solver->a_slope(cellId, varId, i);
22140 }
22141 }
22142 }
22143 }
22144}

◆ sbc2801x() [2/2]

void FvBndryCndXD< 3, FvSysEqnEEGas< 3 > >::sbc2801x ( MInt  )

Definition at line 19 of file fvcartesianbndrycndxd_inst_3d_eegas.cpp.

19 {
20 TERMM(-1, "requires CV->RHO_E");
21}

◆ sbc2801y()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::sbc2801y ( MInt  bcId)
Author
Daniel Hartmann, 12.01.2007

Definition at line 22152 of file fvcartesianbndrycndxd.cpp.

22152 {
22153 IF_CONSTEXPR(!hasE<SysEqn>) {
22154 mTerm(1, AT_, "Not compatible with SysEqn without RHO_E!");
22155 return;
22156 }
22157 IF_CONSTEXPR(nDim == 3) { TERMM(-1, "INFO: function sbc2801x is untested for 3D!"); }
22158 TRACE();
22159
22160 MInt bndryId, cellId, ghostCellId;
22161 MFloat Frho, FrhoGhost, rhoU2;
22162 const MInt noPVars = PV->noVariables;
22163 ScratchSpace<MFloat> PVbndry(noPVars, AT_, "PVbndry");
22164 ScratchSpace<MFloat> PVghost(noPVars, AT_, "PVghost");
22165 //---
22166
22167 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
22168 bndryId = m_sortedBndryCells->a[id];
22169 cellId = m_bndryCells->a[bndryId].m_cellId;
22170 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
22171 ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
22172
22173 // determine the primitive variables on the boundary and on the ghost cell
22174 Frho = F1 / m_solver->a_variable(cellId, CV->RHO);
22175 FrhoGhost = F1 / m_solver->a_variable(ghostCellId, CV->RHO);
22176 // velocitites
22177 for(MInt i = 0; i < nDim; i++) {
22178 PVbndry[i] = m_solver->a_variable(cellId, CV->RHO_VV[i]) * Frho;
22179 PVghost[i] = m_solver->a_variable(ghostCellId, CV->RHO_VV[i]) * FrhoGhost;
22180 }
22181
22182 // density
22183 PVbndry[PV->RHO] = m_solver->a_variable(cellId, CV->RHO);
22184 PVghost[PV->RHO] = m_solver->a_variable(ghostCellId, CV->RHO);
22185
22186 // pressure
22187 rhoU2 = F0;
22188 for(MInt i = 0; i < nDim; i++) {
22189 rhoU2 += POW2(m_solver->a_variable(cellId, CV->RHO_VV[i]));
22190 }
22191 rhoU2 *= Frho;
22192 PVbndry[PV->P] = sysEqn().pressure(1.0, rhoU2, m_solver->a_variable(cellId, CV->RHO_E));
22193 rhoU2 = F0;
22194 for(MInt i = 0; i < nDim; i++) {
22195 rhoU2 += POW2(m_solver->a_variable(ghostCellId, CV->RHO_VV[i]));
22196 }
22197 rhoU2 *= FrhoGhost;
22198 PVghost[PV->P] = sysEqn().pressure(1.0, rhoU2, m_solver->a_variable(ghostCellId, CV->RHO_E));
22199
22200 // species
22201 for(MInt k = 0; k < m_noSpecies; k++) {
22202 PVbndry[PV->Y[k]] = m_solver->a_variable(cellId, CV->RHO_Y[k]) * Frho;
22203 PVghost[PV->Y[k]] = m_solver->a_variable(ghostCellId, CV->RHO_Y[k]) * FrhoGhost;
22204 }
22205
22206 for(MInt var = 0; var < noPVars; var++) {
22207 m_solver->a_slope(ghostCellId, var, 0) = m_solver->a_slope(cellId, var, 0);
22208 m_solver->a_slope(ghostCellId, var, 1) =
22209 (PVbndry[var] - PVghost[var])
22210 / (m_solver->a_coordinate(cellId, 1) - m_solver->a_coordinate(ghostCellId, 1));
22211 }
22212
22213 // compute the slopes on the ghost cell
22214 for(MInt varId = 0; varId < noPVars; varId++) {
22215 for(MInt i = 0; i < nDim; i++) {
22216 m_solver->a_slope(ghostCellId, varId, i) =
22217 F2 * m_solver->a_slope(ghostCellId, varId, i) - m_solver->a_slope(cellId, varId, i);
22218 }
22219 }
22220 }
22221 }
22222}

◆ sbc2901()

template<MInt nDim, class SysEqn >
template<MInt dir>
void FvBndryCndXD< nDim, SysEqn >::sbc2901 ( MInt  bcId)

Solid wall Navier-Stokes boundary condition
Computes ghost cell slopes for the viscous flux computation
Set of variables: primitive (u,v,rho,p,Z)

Author
Daniel Hartmann, Sven Berger

Definition at line 6848 of file fvcartesianbndrycndxd.cpp.

6848 {
6849 TRACE();
6850 static_assert(dir <= nDim, "ERROR: Invalid direction!");
6851
6852
6853 const MInt noPVars = PV->noVariables;
6854 ScratchSpace<MFloat> PVbndry(noPVars, AT_, "PVbndry");
6855 ScratchSpace<MFloat> PVghost(noPVars, AT_, "PVghost");
6856
6857 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
6858 const MInt bndryId = m_sortedBndryCells->a[id];
6859 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
6860 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
6861 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[0]->m_ghostCellId;
6862
6863 // determine the primitive variables on the boundary and on the ghost cell
6864 const MFloat Frho = 1.0 / m_solver->a_variable(cellId, CV->RHO);
6865 const MFloat FrhoGhost = 1.0 / m_solver->a_variable(ghostCellId, CV->RHO);
6866 // velocitites
6867 for(MInt i = 0; i < nDim; i++) {
6868 PVbndry[i] = m_solver->a_variable(cellId, CV->RHO_VV[i]) * Frho;
6869 PVghost[i] = m_solver->a_variable(ghostCellId, CV->RHO_VV[i]) * FrhoGhost;
6870 }
6871
6872 // density
6873 PVbndry[PV->RHO] = m_solver->a_variable(cellId, CV->RHO);
6874 PVghost[PV->RHO] = m_solver->a_variable(ghostCellId, CV->RHO);
6875
6876 // pressure
6877 MFloat rhoU2 = 0.0;
6878 for(MInt i = 0; i < nDim; i++) {
6879 rhoU2 += POW2(m_solver->a_variable(cellId, CV->RHO_VV[i]));
6880 }
6881 PVbndry[PV->P] =
6882 sysEqn().pressure(m_solver->a_variable(cellId, CV->RHO), rhoU2, m_solver->a_variable(cellId, CV->RHO_E));
6883
6884 rhoU2 = F0;
6885 for(MInt i = 0; i < nDim; i++) {
6886 rhoU2 += POW2(m_solver->a_variable(ghostCellId, CV->RHO_VV[i]));
6887 }
6888 PVghost[PV->P] = sysEqn().pressure(m_solver->a_variable(ghostCellId, CV->RHO), rhoU2,
6889 m_solver->a_variable(ghostCellId, CV->RHO_E));
6890
6891 // passive scalar
6892 for(MInt s = 0; s < m_noSpecies; s++) {
6893 PVbndry[PV->Y[s]] = m_solver->a_variable(cellId, CV->RHO_Y[s]) * Frho;
6894 PVghost[PV->Y[s]] = m_solver->a_variable(ghostCellId, CV->RHO_Y[s]) * FrhoGhost;
6895 }
6896
6897 for(MInt var = 0; var < noPVars; var++) {
6898 if(dir == 0) {
6899 m_solver->a_slope(ghostCellId, var, 0) =
6900 (PVbndry[var] - PVghost[var])
6901 / (m_solver->a_coordinate(cellId, 0) - m_solver->a_coordinate(ghostCellId, 0));
6902 } else {
6903 m_solver->a_slope(ghostCellId, var, 0) = m_solver->a_slope(cellId, var, 0);
6904 }
6905
6906 if(dir == 1) {
6907 m_solver->a_slope(ghostCellId, var, 1) =
6908 (PVbndry[var] - PVghost[var])
6909 / (m_solver->a_coordinate(cellId, 1) - m_solver->a_coordinate(ghostCellId, 1));
6910 } else {
6911 m_solver->a_slope(ghostCellId, var, 1) = m_solver->a_slope(cellId, var, 1);
6912 }
6913
6914 IF_CONSTEXPR(nDim == 3) {
6915 if(dir == 2) {
6916 m_solver->a_slope(ghostCellId, var, 2) =
6917 (PVbndry[var] - PVghost[var])
6918 / (m_solver->a_coordinate(cellId, 2) - m_solver->a_coordinate(ghostCellId, 2));
6919 } else {
6920 m_solver->a_slope(ghostCellId, var, 2) = m_solver->a_slope(cellId, var, 2);
6921 }
6922 }
6923 }
6924
6925 // compute the slopes on the ghost cell
6926 for(MInt varId = 0; varId < noPVars; varId++) {
6927 for(MInt i = 0; i < nDim; i++) {
6928 m_solver->a_slope(ghostCellId, varId, i) =
6929 2.0 * m_solver->a_slope(ghostCellId, varId, i) - m_solver->a_slope(cellId, varId, i);
6930 }
6931 }
6932 }
6933 }
6934}

◆ setBCTypes()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::setBCTypes ( MInt  updateOnlyBndryCndId = -1)

Definition at line 2266 of file fvcartesianbndrycndxd.cpp.

2266 {
2267 TRACE();
2268 const MInt noPVars = PV->noVariables;
2269 set<MInt> unhandledBCs;
2270
2271 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
2272 if((updateOnlyBndryCndId > -1) && (m_bndryCndIds[bcId] != updateOnlyBndryCndId)) {
2273 continue;
2274 }
2275
2276 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
2277 MInt bndryId = m_sortedBndryCells->a[id];
2278
2279 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
2280 ASSERT(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId > -1, "");
2281 if(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_bndryCndId != m_bndryCndIds[bcId]) {
2282 continue;
2283 }
2284
2285 // initialization: Dirichlet type and zero normal derivatives, individual specifications below
2286 for(MInt v = 0; v < noPVars; v++) {
2287 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] = BC_DIRICHLET;
2288 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v] = F0;
2289 }
2290 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_robinFactor = F0;
2291
2292 // set species variable to BC_NEUMANN
2293 for(MInt s = 0; s < m_noSpecies; s++) {
2294 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->Y[s]] = BC_NEUMANN;
2295 }
2296
2297 switch(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId) {
2298 //---
2299 // supersonic inflow conditions
2300 //---
2301 case 0:
2302 case 1091:
2303 case 1092:
2304 case 1101:
2305 case 1102:
2306 //---
2307 // STG
2308 //---
2309 case 7909:
2310 case 7910:
2311 case 7911:
2312 case 7912:
2313 case 7913:
2314 // do nothing, all Dirichlet is correct
2315 break;
2316
2317 //---
2318 // subsonic inflow conditions
2319 //---
2320 case 1001:
2321 case 1009:
2322 case 1011:
2323 case 1021:
2324 case 2011:
2325 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->P] = BC_NEUMANN;
2326 if(m_isEEGas || isDetChem<SysEqn>) {
2327 for(MInt s = 0; s < m_noSpecies; s++) {
2328 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->Y[s]] = BC_DIRICHLET;
2329 }
2330 }
2331 break;
2332
2333 case 2907:
2334 case 3011: // isothermal wall
2335 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->P] = BC_NEUMANN;
2336 if(m_isEEGas) {
2337 for(MInt s = 0; s < m_noSpecies; s++) {
2338 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->Y[s]] = BC_DIRICHLET;
2339 }
2340 }
2341 break;
2342
2343 //---
2344 // subsonic outflow condition
2345 //---
2346 case 1002:
2347 case 1012:
2348 case 1022:
2349 case 1099:
2350 for(MInt i = 0; i < nDim; i++) {
2351 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->VV[i]] = BC_NEUMANN;
2352 }
2353 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->RHO] = BC_NEUMANN;
2354 if(m_isEEGas) {
2355 for(MInt s = 0; s < m_noSpecies; s++) {
2356 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->Y[s]] = BC_DIRICHLET;
2357 }
2358 }
2359 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
2360 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
2361 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->NN[r]] = BC_NEUMANN;
2362 }
2363 }
2364 break;
2365
2366 //---
2367 // supersonic outflow conditions
2368 //---
2369 //---
2370 // adiabatic fixed wall conditions
2371 //---
2372 case 3002:
2373 case 30021:
2374 case 3003:
2375 case 3009:
2376 case 3399: // wall-modeling based on viscous fluxes
2377 case 3466:
2378 case 3600:
2379 case 4000:
2380 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->RHO] = BC_NEUMANN;
2381 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->P] = BC_NEUMANN;
2382 break;
2383
2384 //---
2385 // isothermal moving wall condition
2386 //---
2387 case 3008:
2388 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->P] = BC_NEUMANN;
2389 // labels:FV BC_ISOTHERMAL is a hack for MB
2390 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->RHO] = BC_ISOTHERMAL;
2391 break;
2392
2393 //---
2394 // adiabatic moving wall conditions
2395 //---
2396 case 3006:
2397 case 3067: // labels:FV euler/non euler hack
2398 case 3007: // labels:FV euler hack
2399 case 3060:
2400 case 3010:
2401 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->RHO] = BC_ROBIN;
2402 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->P] = BC_ROBIN;
2403 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_robinFactor = F0;
2404 break;
2405
2406 //---
2407 // symmetry condition about x-axis
2408 //---
2409 case 100100:
2410 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->P] = BC_NEUMANN;
2411 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->RHO] = BC_NEUMANN;
2412 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->U] = BC_NEUMANN;
2413
2414 IF_CONSTEXPR(SysEqn::m_noRansEquations > 0) {
2415 for(MInt r = 0; r < m_solver->m_noRansEquations; ++r) {
2416 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->NN[r]] = BC_NEUMANN;
2417 }
2418 }
2419 break;
2420
2421 //---
2422 // undefined -> reset to BC_UNSET
2423 //---
2424 default:
2425 for(MInt v = 0; v < noPVars; v++) {
2426 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] = BC_UNSET;
2427 }
2428 unhandledBCs.insert(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId);
2429 break;
2430 }
2431 }
2432 }
2433 }
2435 for(MInt unhandledBC : unhandledBCs) {
2436 cerr0 << "Boundary condition " << unhandledBC << " not handled in FvBndryCndXD::setBCTypes(). "
2437 << "Defaulting to Dirichlet-type behavior - but on occurrence of a small cell an error will be thrown."
2438 << endl;
2439 m_log << "Boundary condition " << unhandledBC << " not handled in FvBndryCndXD::setBCTypes(). "
2440 << "Defaulting to Dirichlet-type behavior - but on occurrence of a small cell an error will be thrown."
2441 << endl;
2442 }
2443 if(unhandledBCs.empty()) {
2444 m_log << "All boundary conditions handled in FvBndryCndXD::setBCTypes()." << endl;
2445 }
2446 m_firstUseSetBCTypes = false;
2447 }
2448}
std::ostream cerr0

◆ setGapGhostCellVariables()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::setGapGhostCellVariables ( MInt  bcId)
Author
Claudia Guenther

Definition at line 15737 of file fvcartesianbndrycndxd.cpp.

15737 {
15738 TRACE();
15739
15740 for(MInt id = m_bndryCndCells[bcId]; id < m_bndryCndCells[bcId + 1]; id++) {
15741 const MInt bndryId = m_sortedBndryCells->a[id];
15742 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
15743
15744 if(!m_solver->a_isGapCell(cellId)) continue;
15745 // if( m_solver->a_hasProperty( cellId , SolverCell::IsNotGradient) ) continue;
15746 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
15747
15748 const MInt gapCellId = m_solver->m_gapCellId[cellId];
15749 ASSERT(gapCellId > -1, "");
15750 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
15751 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
15752 for(MInt i = 0; i < nDim; i++) {
15753 const MFloat vel = m_solver->m_gapCells[gapCellId].surfaceVelocity[i];
15754 m_solver->a_pvariable(ghostCellId, PV->VV[i]) = F2 * vel - m_solver->a_pvariable(cellId, PV->VV[i]);
15755 }
15756 }
15757 }
15758}
std::vector< MInt > m_gapCellId
MBool a_isGapCell(const MInt cellId) const
Returns isGapCell of the cell cellId.

◆ setNearBoundaryRecNghbrs()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::setNearBoundaryRecNghbrs ( MInt  updateOnlyBndryCndId = -1)
Author
Lennart Schneiders

Definition at line 9157 of file fvcartesianbndrycndxd.cpp.

9157 {
9158 TRACE();
9159
9160 const MInt noBndryCells = m_bndryCells->size();
9161 const MInt maxNoNghbrs = 200;
9162 const MInt noLayersStencil = m_noFluxRedistributionLayers;
9163 if(noDomains() > 1 && noLayersStencil > mMin(m_noFluxRedistributionLayers, m_solver->noHaloLayers())) {
9164 cerr << "Warning: noLayersStencil smaller than flux redistribution layers!" << endl;
9165 }
9166
9167 MIntScratchSpace nghbrList(maxNoNghbrs, AT_, "nghbrList");
9168 MIntScratchSpace layerId(maxNoNghbrs, AT_, "layerId");
9170
9171 for(MInt s = 0; s < FvBndryCell<nDim, SysEqn>::m_maxNoSurfaces; s++) {
9173 if(dummyIds(s) < (m_solver->a_noCells())) {
9174 mTerm(1, AT_,
9175 "Increase cell collector! " + to_string(m_solver->a_noCells()) + " "
9177 }
9178 }
9179
9180 if(updateOnlyBndryCndId < 0) {
9181 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
9182 m_bndryCell[bndryId].m_recNghbrIds.resize(0);
9183 m_bndryCell[bndryId].m_cellVarsRecConst.resize(0);
9184 m_bndryCell[bndryId].m_cellDerivRecConst.resize(0);
9185 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
9186 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.resize(0);
9187 }
9188 }
9189 } else {
9190 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
9191 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
9192 if(m_solver->a_isPeriodic(cellId) || m_solver->a_isHalo(cellId)) {
9193 m_bndryCell[bndryId].m_cellVarsRecConst.resize(0);
9194 m_bndryCell[bndryId].m_cellDerivRecConst.resize(0);
9195 }
9196 MBool skip = false;
9197 // if( m_solver->a_isPeriodic( cellId ) ) skip = true;
9198 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitChild)) continue;
9199 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) skip = true;
9200 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) skip = true;
9201 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitCell)) skip = true;
9202 if(m_solver->c_noChildren(cellId) > 0) skip = true;
9203 if(skip) {
9204 m_bndryCell[bndryId].m_recNghbrIds.resize(0);
9205 m_bndryCell[bndryId].m_cellVarsRecConst.resize(0);
9206 m_bndryCell[bndryId].m_cellDerivRecConst.resize(0);
9207 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
9208 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.resize(0);
9209 }
9210 }
9211 }
9212 }
9213
9214 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
9215 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
9216 const MInt noSrfcs = m_bndryCells->a[bndryId].m_noSrfcs;
9217 MInt gridcellId = cellId;
9218 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitClone)) {
9219 gridcellId = m_solver->m_splitChildToSplitCell.find(cellId)->second;
9220 }
9221
9222 // if( m_solver->a_isPeriodic( cellId ) ) continue;
9223 if(!m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) continue;
9224 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
9225 if(!m_solver->a_hasProperty(cellId, SolverCell::IsSplitChild) && m_solver->c_noChildren(gridcellId) > 0) continue;
9226 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
9227
9228 MBool skip = false;
9229 if(updateOnlyBndryCndId > -1) {
9230 skip = true;
9231 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9232 if(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId == updateOnlyBndryCndId) skip = false;
9233 }
9234 }
9235 if(skip) continue;
9236
9237 m_bndryCell[bndryId].m_recNghbrIds.resize(0);
9238 m_bndryCell[bndryId].m_cellVarsRecConst.resize(0);
9239 m_bndryCell[bndryId].m_cellDerivRecConst.resize(0);
9240 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
9241 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.resize(0);
9242 }
9243
9244 nghbrList.fill(-1);
9245 const MInt rootCell = (m_solver->a_hasProperty(cellId, SolverCell::IsSplitChild)
9246 || m_solver->a_hasProperty(cellId, SolverCell::IsSplitClone))
9248 : cellId;
9249 ASSERT(rootCell > -1 && rootCell < m_solver->a_noCells(), "");
9250 const MInt addPoints = noSrfcs + 1;
9251 const MInt recSize = m_solver->template getAdjacentLeafCells<1, true>(rootCell, noLayersStencil, nghbrList, layerId)
9252 + addPoints; // my neighbors + my boundary-surface centroids + myself
9253
9254 if(recSize > maxNoNghbrs) {
9255 mTerm(1, AT_,
9256 "too many nghbrs " + to_string(recSize) + " " + to_string(cellId) + " "
9257 + to_string(m_solver->a_isHalo(cellId)));
9258 }
9259 if(recSize < nDim + 2) {
9260 cerr << "not enough neighbors " + to_string(recSize) + " " + to_string(recSize - addPoints) + " "
9261 + to_string(cellId)
9262 << " " << m_solver->a_isHalo(cellId) << endl;
9263 continue;
9264 }
9265 for(MInt k = recSize - 1; k >= addPoints; k--) {
9266 ASSERT(k - addPoints > -1, "");
9267 ASSERT(nghbrList(k - addPoints) > -1 && nghbrList(k - addPoints) < m_solver->a_noCells(), "");
9268 nghbrList(k) = nghbrList(k - addPoints);
9269 layerId(k) = layerId(k - addPoints);
9270 }
9271 for(MInt srfc = 0; srfc < noSrfcs; srfc++) {
9272 nghbrList(srfc) = dummyIds(srfc);
9273 layerId(srfc) = 0;
9274 }
9275 nghbrList(noSrfcs) = cellId;
9276 layerId(noSrfcs) = 0;
9277
9278 m_bndryCell[bndryId].m_recNghbrIds.resize(recSize);
9279 m_bndryCell[bndryId].m_cellVarsRecConst.resize(recSize);
9280 for(MInt k = 0; k < recSize; k++) {
9281 m_bndryCell[bndryId].m_recNghbrIds[k] = nghbrList(k);
9282 m_bndryCell[bndryId].m_cellVarsRecConst[k] = (MFloat)layerId(k);
9283 }
9284 }
9285}

◆ storeBoundaryVariables()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::storeBoundaryVariables

Definition at line 1313 of file fvcartesianbndrycndxd.cpp.

1313 {
1314 TRACE();
1315
1316 const MInt noBndryCells = m_bndryCells->size();
1317 const MInt noPVars = PV->noVariables;
1318#ifndef NDEBUG
1319 MInt nanCounter = 0;
1320 const MInt nanCounterMax = 5 * noPVars;
1321#endif
1322
1323#ifdef _OPENMP
1324#pragma omp parallel for
1325#endif
1326 for(MInt bndryId = 0; bndryId < noBndryCells; bndryId++) {
1327 const MInt cellId = m_bndryCells->a[bndryId].m_cellId;
1328 if(m_solver->a_hasProperty(cellId, SolverCell::IsSplitCell)) continue;
1329 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) continue;
1330 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
1331 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
1332 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
1333 for(MInt v = 0; v < noPVars; v++) {
1334 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v] =
1335 F1B2 * (m_solver->a_pvariable(ghostCellId, v) + m_solver->a_pvariable(cellId, v));
1336#ifndef NDEBUG
1337 if(std::isnan(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v]) && nanCounter < nanCounterMax) {
1338 cerr << domainId() << ": nan detected in boundary surface var " << v << " " << cellId << " ("
1339 << m_solver->c_globalId(cellId) << ") " << ghostCellId << " halo:" << m_solver->a_isHalo(cellId)
1340 << " (" << m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient) << ")"
1341 << " /vars " << m_solver->a_pvariable(ghostCellId, v) << " " << m_solver->a_pvariable(cellId, v) << " "
1342 << m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v] << " ("
1343 << &m_solver->a_pvariable(cellId, v) << ")"
1344 << " /coords " << m_solver->a_coordinate(cellId, 0) << " " << m_solver->a_coordinate(cellId, 1) << " "
1345 << m_solver->a_coordinate(cellId, 2) << " /bndCnd " << m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId
1346 << " /lvl " << m_solver->a_level(cellId) << " /halo " << m_solver->a_isHalo(cellId) << endl;
1347 nanCounter++;
1348 if(nanCounter == nanCounterMax) {
1349 cerr << domainId() << ": nan detected in boundary surface ... skipping further output" << std::endl;
1350 }
1351 }
1352#endif
1353 }
1354
1355 ASSERT((approx(sysEqn().temperature_ES(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO],
1356 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P]),
1357 m_Bc3011WallTemperature, F5 * MFloatEps))
1358 || (m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId != 3011 || isDetChem<SysEqn>),
1359 "isothermal wall 3011 fail");
1360 }
1361#ifdef _OPENMP
1362#pragma omp critical
1363 {
1364#endif
1365 MFloatScratchSpace dummyPvariables(m_bndryCells->a[bndryId].m_noSrfcs, PV->noVariables, AT_, "dummyPvariables");
1366 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
1367 // if ( m_bndryCell[ bndryId ].m_srfcs[srfc]->m_bndryCndId / 1000 != 3 ) continue;
1368 const MInt ghostCellId = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_ghostCellId;
1369 MFloat normal[3] = {F0, F0, F0};
1370 for(MInt i = 0; i < nDim; i++) {
1371 normal[i] = m_bndryCell[bndryId].m_srfcs[srfc]->m_normalVectorCentroid[i];
1372 }
1373 /*MFloat cnt = F0;
1374 for ( MInt i = 0; i < nDim; i++ ) {
1375 normal[i] = m_solver->a_coordinate( cellId , i ) - m_solver->a_coordinate( ghostCellId , i );
1376 cnt += POW2(normal[i]);
1377 }
1378 cnt = sqrt(cnt);
1379 for ( MInt i = 0; i < nDim; i++ ) {
1380 normal[i] /= cnt;
1381 }*/
1382 for(MInt v = 0; v < noPVars; v++) {
1383 if(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] == BC_DIRICHLET) {
1384 for(MInt s = 0;
1385 s < mMin((signed)m_bndryCell[bndryId].m_recNghbrIds.size(), m_bndryCells->a[bndryId].m_noSrfcs);
1386 s++) {
1387 dummyPvariables(s, v) = m_bndryCell[bndryId].m_srfcVariables[s]->m_primVars[v];
1388 }
1389 MFloat imageVar = F0;
1390 for(MInt n = 0; n < (signed)m_bndryCell[bndryId].m_recNghbrIds.size(); n++) {
1391 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[n];
1392 const MFloat nghbrPvariable = (n < m_bndryCells->a[bndryId].m_noSrfcs)
1393 ? dummyPvariables(n, v)
1394 : m_solver->a_pvariable(nghbrId, v);
1395 if(nghbrId < 0
1396 || m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size()
1397 != m_bndryCell[bndryId].m_recNghbrIds.size()) {
1398 cerr << nghbrId << " " << m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size()
1399 << " " << m_bndryCell[bndryId].m_recNghbrIds.size() << endl;
1400 }
1401 ASSERT(nghbrId > -1
1402 && m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size()
1403 == m_bndryCell[bndryId].m_recNghbrIds.size(),
1404 "");
1405 imageVar += m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariable;
1406 }
1407 // MFloat vf = m_solver->a_cellVolume( cellId ) /
1408 // pow(m_solver->c_cellLengthAtCell(cellId),(MFloat)nDim); MFloat fac = maia::math::deltaFun( vf, 0.90, F1
1409 // ); imageVar = ( fac*m_solver->a_pvariable( cellId , v ) + (F1-fac)*imageVar );
1410 m_solver->a_pvariable(ghostCellId, v) =
1411 F2 * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v] - imageVar;
1412 } else if(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] == BC_NEUMANN) {
1413 MFloat dn0 = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
1414 // MFloat dn0 = F0;
1415 MFloat dn = F0;
1416 for(MInt i = 0; i < nDim; i++) {
1417 // dn0 += ( m_solver->a_coordinate( cellId , i ) - m_bndryCell[ bndryId ].m_srfcs[srfc]->m_coordinates[
1418 // i ] ) * normal[ i ];
1419 dn += (m_solver->a_coordinate(cellId, i) - m_solver->a_coordinate(ghostCellId, i)) * normal[i];
1420 }
1421 m_solver->a_pvariable(ghostCellId, v) =
1422 m_solver->a_pvariable(cellId, v) - dn * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v];
1423 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v] =
1424 m_solver->a_pvariable(cellId, v) - dn0 * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v];
1425 } else if(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] == BC_ROBIN) {
1426 MFloat phi = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
1427 MFloat dn = F0;
1428 for(MInt i = 0; i < nDim; i++) {
1429 phi += (m_solver->a_coordinate(cellId, i) - m_bndryCell[bndryId].m_srfcs[srfc]->m_coordinates[i])
1430 * normal[i];
1431 // dn += ( m_bndryCell[ bndryId ].m_srfcs[srfc]->m_coordinates[ i ] - m_solver->a_coordinate(
1432 // ghostCellId , i )) * normal[ i ];
1433 dn += (m_solver->a_coordinate(cellId, i) - m_solver->a_coordinate(ghostCellId, i)) * normal[i];
1434 }
1435 dn -= m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
1436 if(dn + phi < 1e-8) {
1437 cerr << domainId() << ": warning very small distance " << m_solver->c_globalId(cellId) << " " << phi
1438 << " " << dn << " " << normal[0] << " " << normal[1] << " " << normal[2] << endl;
1439 }
1440 const MFloat beta = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_robinFactor;
1441 const MFloat delta = m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v];
1442 // const MFloat fac = ( F1 + beta*dn ) / ( F1 - beta*phi );
1443 const MFloat fac = (F1 + F1B2 * beta * (dn + phi)) / (F1 - F1B2 * beta * (dn + phi));
1444 // const MFloat fac2 = ( dn + phi ) / ( F1 - beta*phi );
1445 const MFloat fac2 = (dn + phi) / (F1 - F1B2 * beta * (dn + phi));
1446 m_solver->a_pvariable(ghostCellId, v) = fac * m_solver->a_pvariable(cellId, v) - fac2 * delta;
1447 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v] =
1448 (dn * m_solver->a_pvariable(cellId, v) + phi * m_solver->a_pvariable(ghostCellId, v)) / (dn + phi);
1449
1450 if(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId == 3007) {
1451 MFloat imageVar = F0;
1452 for(MInt s = 0;
1453 s < mMin((signed)m_bndryCell[bndryId].m_recNghbrIds.size(), m_bndryCells->a[bndryId].m_noSrfcs);
1454 s++) {
1455 dummyPvariables(s, v) = m_solver->a_pvariable(cellId, v);
1456 }
1457 for(MInt n = 0; n < (signed)m_bndryCell[bndryId].m_recNghbrIds.size(); n++) {
1458 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[n];
1459 const MFloat nghbrPvariable = (n < m_bndryCells->a[bndryId].m_noSrfcs)
1460 ? dummyPvariables(n, v)
1461 : m_solver->a_pvariable(nghbrId, v);
1462 imageVar += m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariable;
1463 }
1464
1465 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[v] =
1466 F0; //( imageVar - m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_primVars[v] ) / dn
1467 //+ beta * m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_primVars[v];
1468 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[v] = imageVar;
1469
1470 // imageVar = F2*m_solver->a_pvariable(cellId, v) - imageVar;
1471 // m_bndryCell[ bndryId ].m_srfcVariables[srfc]->m_primVars[v] = imageVar;
1472 }
1473 } else if(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v] == BC_ISOTHERMAL) {
1474 continue;
1475 } else {
1476 mTerm(1, AT_,
1477 "Unknown BC type: " + to_string(m_bndryCell[bndryId].m_srfcs[srfc]->m_bndryCndId) + "/"
1478 + to_string(v) + "/" + to_string(m_bndryCells->a[bndryId].m_noSrfcs) + "/"
1479 + to_string(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[v]) + " "
1480 + to_string(m_bndryCells->a[bndryId].m_srfcs[srfc]->m_area) + " "
1481 + to_string(m_solver->a_hasProperty(cellId, SolverCell::IsCutOff)));
1482 }
1483 }
1484 if(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_variablesType[PV->RHO] == BC_ISOTHERMAL) {
1485 // const MFloat Ts = bodyTemperatureRatio * m_solver->m_TInfinity;
1486 const MFloat Ts = sysEqn().temperature_ES(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO],
1487 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P]);
1488
1489 // if ( true) cerr << "bc: " << Ts/m_solver->m_TInfinity << endl;
1490 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] =
1491 sysEqn().density_ES(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P], Ts);
1492 for(MInt s = 0;
1493 s < mMin((signed)m_bndryCell[bndryId].m_recNghbrIds.size(), m_bndryCells->a[bndryId].m_noSrfcs);
1494 s++) {
1495 for(MInt vv = 0; vv < noPVars; vv++) {
1496 dummyPvariables(s, vv) = m_bndryCell[bndryId].m_srfcVariables[s]->m_primVars[vv];
1497 }
1498 }
1499
1500 MFloat dn00 = m_bndryCells->a[bndryId].m_srfcs[srfc]->m_centroidDistance;
1501 // MFloat dn00 = F0;
1502 // MFloat dn0 = F0;
1503 MFloat dn = F0;
1504 for(MInt i = 0; i < nDim; i++) {
1505 // dn0 += ( m_bndryCell[ bndryId ].m_srfcs[srfc]->m_coordinates[ i ] - m_solver->a_coordinate( ghostCellId
1506 // , i )) * normal[ i ];
1507 dn += (m_solver->a_coordinate(cellId, i) - m_solver->a_coordinate(ghostCellId, i)) * normal[i];
1508 // dn00 += (m_solver->a_coordinate( cellId , i ) - m_bndryCell[ bndryId ].m_srfcs[srfc]->m_coordinates[ i
1509 // ])
1510 // * normal[ i ];
1511 }
1512 MFloat dn0 = dn - dn00;
1513
1514 MFloat imageVar = F0;
1515 for(MInt n = 0; n < (signed)m_bndryCell[bndryId].m_recNghbrIds.size(); n++) {
1516 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[n];
1517 const MFloat nghbrPvariableP = (n < m_bndryCells->a[bndryId].m_noSrfcs)
1518 ? dummyPvariables(n, PV->P)
1519 : m_solver->a_pvariable(nghbrId, PV->P);
1520 imageVar += m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n] * nghbrPvariableP;
1521 }
1522 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] = m_solver->a_pvariable(cellId, PV->P);
1523 m_solver->a_pvariable(ghostCellId, PV->P) =
1524 F2 * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] - imageVar;
1525 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->P] =
1526 (imageVar - m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P]) / dn0;
1527 imageVar = F0;
1528 for(MInt n = 0; n < (signed)m_bndryCell[bndryId].m_recNghbrIds.size(); n++) {
1529 const MInt nghbrId = m_bndryCell[bndryId].m_recNghbrIds[n];
1530 const MInt noSrfcs = m_bndryCells->a[bndryId].m_noSrfcs;
1531 const MFloat nghbrPvariableP =
1532 (n < noSrfcs) ? dummyPvariables(n, PV->P) : m_solver->a_pvariable(nghbrId, PV->P);
1533 const MFloat nghbrPvariableRho =
1534 (n < noSrfcs) ? dummyPvariables(n, PV->RHO) : m_solver->a_pvariable(nghbrId, PV->RHO);
1535 if(nghbrId < 0
1536 || m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size()
1537 != m_bndryCell[bndryId].m_recNghbrIds.size()) {
1538 cerr << nghbrId << " " << m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size() << " "
1539 << m_bndryCell[bndryId].m_recNghbrIds.size() << endl;
1540 }
1541 ASSERT(nghbrId > -1
1542 && m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst.size()
1543 == m_bndryCell[bndryId].m_recNghbrIds.size(),
1544 "");
1545 imageVar += m_bndryCell[bndryId].m_srfcVariables[srfc]->m_imagePointRecConst[n]
1546 * sysEqn().temperature_ES(nghbrPvariableRho, nghbrPvariableP);
1547 }
1548
1549 MFloat dTdn = (imageVar - Ts) / dn0;
1550
1551 const MInt noNghbrIds = m_solver->a_noReconstructionNeighbors(cellId);
1552
1553 MInt maxIter = 100;
1554 MFloat res = 99999.9;
1555 MInt iter = 0;
1556 while(iter < maxIter && res > 1e-8) {
1557 MFloat pg = m_solver->a_pvariable(ghostCellId, PV->P);
1558 MFloat ps = m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P];
1559 for(MInt i = 0; i < nDim; i++) {
1560 m_solver->a_slope(cellId, PV->P, i) = F0;
1561 for(MInt nghbr = 0; nghbr < noNghbrIds; nghbr++) {
1562 const MInt nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
1563 const MInt offset0 = m_solver->a_reconstructionData(cellId) + nghbr;
1564 m_solver->a_slope(cellId, PV->P, i) +=
1565 m_solver->m_reconstructionConstants[nDim * offset0 + i]
1566 * (m_solver->a_pvariable(nghbrId, PV->P) - m_solver->a_pvariable(cellId, PV->P));
1567 }
1568 }
1569 m_solver->a_pvariable(ghostCellId, PV->P) = m_solver->a_pvariable(cellId, PV->P);
1570 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] = m_solver->a_pvariable(cellId, PV->P);
1571 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->P] = F0;
1572 for(MInt i = 0; i < nDim; i++) {
1573 m_solver->a_pvariable(ghostCellId, PV->P) +=
1574 (m_solver->a_coordinate(ghostCellId, i) - m_solver->a_coordinate(cellId, i))
1575 * m_solver->a_slope(cellId, PV->P, i);
1576 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] +=
1577 (m_bndryCell[bndryId].m_srfcs[srfc]->m_coordinates[i] - m_solver->a_coordinate(cellId, i))
1578 * m_solver->a_slope(cellId, PV->P, i);
1579 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->P] +=
1580 m_solver->a_slope(cellId, PV->P, i) * normal[i];
1581 }
1582 m_solver->a_pvariable(ghostCellId, PV->P) =
1583 m_solver->a_pvariable(cellId, PV->P)
1584 - dn * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->P];
1585 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] =
1586 m_solver->a_pvariable(cellId, PV->P)
1587 - dn00 * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->P];
1588
1589 res = mMax(fabs(m_solver->a_pvariable(ghostCellId, PV->P) - pg),
1590 fabs(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P] - ps));
1591 iter++;
1592 }
1593
1594 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] =
1595 sysEqn().density_ES(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->P], Ts);
1596
1597 m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->RHO] =
1598 sysEqn().density_ES(m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->P], Ts)
1599 - (m_bndryCell[bndryId].m_srfcVariables[srfc]->m_primVars[PV->RHO] * dTdn) / Ts;
1600
1601 m_solver->a_pvariable(ghostCellId, PV->RHO) =
1602 m_solver->a_pvariable(cellId, PV->RHO)
1603 - dn * m_bndryCell[bndryId].m_srfcVariables[srfc]->m_normalDeriv[PV->RHO];
1604 }
1605 }
1606#ifdef _OPENMP
1607 }
1608#endif
1609 }
1610 }
1611}

◆ sysEqn()

template<MInt nDim, class SysEqn >
SysEqn FvBndryCndXD< nDim, SysEqn >::sysEqn ( ) const
inline

Definition at line 166 of file fvcartesianbndrycndxd.h.

166{ return *m_sysEqn; };

◆ updateCutOffCellVariables()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::updateCutOffCellVariables

Definition at line 1630 of file fvcartesianbndrycndxd.cpp.

1630 {
1631 TRACE();
1632
1633 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++)
1634 (this->*bndryCndHandlerCutOffVariables[bcId])(bcId);
1635}

◆ updateCutOffSlopesInviscid()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::updateCutOffSlopesInviscid

Definition at line 2103 of file fvcartesianbndrycndxd.cpp.

2103 {
2104 TRACE();
2105
2106 // loop over all different boundary conditions
2107 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++) {
2108 (this->*bndryCndHandlerCutOffSlopesInviscid[bcId])(bcId);
2109 }
2110}

◆ updateCutOffSlopesViscous()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::updateCutOffSlopesViscous

Definition at line 2238 of file fvcartesianbndrycndxd.cpp.

2238 {
2239 TRACE();
2240
2241 for(MInt bcId = 0; bcId < m_noCutOffBndryCndIds; bcId++) {
2242 (this->*bndryCutOffViscousSlopes[bcId])(bcId);
2243 }
2244}

◆ updateGhostCellSlopesInviscid()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::updateGhostCellSlopesInviscid

Definition at line 2089 of file fvcartesianbndrycndxd.cpp.

2089 {
2090 TRACE();
2091
2092 // loop over all different boundary conditions
2093 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
2094 (this->*bndryCndHandlerSlopesInviscid[bcId])(bcId);
2095 }
2096}

◆ updateGhostCellSlopesViscous()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::updateGhostCellSlopesViscous

Definition at line 2117 of file fvcartesianbndrycndxd.cpp.

2117 {
2118 TRACE();
2119
2120 NEW_TIMER_GROUP_STATIC(tg_initTimer, "updateGhostCellSlopesViscous");
2121 NEW_TIMER_STATIC(t_timertotal, "total", tg_initTimer);
2122 NEW_SUB_TIMER_STATIC(t_viscSlopes, "bndryViscousSlopes", t_timertotal);
2123 NEW_SUB_TIMER_STATIC(t_cghost, "correctGhostCellSlopesViscous", t_timertotal);
2124
2125 RECORD_TIMER_START(t_timertotal);
2126 RECORD_TIMER_START(t_viscSlopes);
2127 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
2128 (this->*bndryViscousSlopes[bcId])(bcId);
2129 }
2130 RECORD_TIMER_STOP(t_viscSlopes);
2131
2132 RECORD_TIMER_START(t_cghost);
2133 if(!m_cellMerging) {
2135 }
2136 RECORD_TIMER_STOP(t_cghost);
2137 RECORD_TIMER_STOP(t_timertotal);
2138}

◆ updateGhostCellVariables()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::updateGhostCellVariables

Definition at line 1618 of file fvcartesianbndrycndxd.cpp.

1618 {
1619 TRACE();
1620 for(MInt bcId = 0; bcId < m_noBndryCndIds; bcId++) {
1621 (this->*bndryCndHandlerVariables[bcId])(bcId);
1622 }
1623}

◆ updateImagePointVariables()

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::updateImagePointVariables ( MInt  mode)

If the multiple ghost cells formulation is used where the ghost cells are located normal to the boundary surfaces from the surface centroids, this function is needed to update the mirrored image points or their variables, respectively.

input variable mode: Triggers the interpolation on the image points; mode 0 means that the interpolation is based on the slopes computed only on the regular cells surrounding the respective boundary cell without the ghost cells (first guess) mode 1 means that the interpolation is based on the regular slopes on the boundary cell (for iteration)

Author
Claudia Guenther, Mai 2010

Definition at line 13083 of file fvcartesianbndrycndxd.cpp.

13083 {
13084 TRACE();
13085
13086 MInt nghbrId = 0;
13087 MInt cellId;
13088 MInt linkedCell;
13089 MFloatScratchSpace dx_scratch(nDim, AT_, "dx_scratch");
13090 MFloat* dx = dx_scratch.getPointer();
13091 MFloat eps = F0;
13092 MFloat oldVar = F0;
13093 MFloat diff = F0;
13094
13095 for(MInt bndryId = 0; bndryId < m_bndryCells->size(); bndryId++) {
13096 for(MInt srfc = 0; srfc < m_bndryCells->a[bndryId].m_noSrfcs; srfc++) {
13097 cellId = m_bndryCells->a[bndryId].m_cellId;
13098 linkedCell = m_bndryCells->a[bndryId].m_linkedCellId;
13099 if(m_solver->a_hasProperty(cellId, SolverCell::IsOnCurrentMGLevel)) {
13100 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) {
13101 continue;
13102 }
13103 if(!m_solver->a_hasProperty(cellId, SolverCell::IsFlux)) {
13104 continue;
13105 }
13106
13107
13108 // if cell is a small cell with bndry cell Master, use this reconstruction stencil. Otherwise, use your own
13109 // stencil.
13110 if(linkedCell > -1) {
13111 cellId = linkedCell;
13112 }
13113
13114 if(m_solver->a_hasProperty(cellId, SolverCell::IsNotGradient)) {
13115 continue;
13116 }
13117 if(!m_solver->a_hasProperty(cellId, SolverCell::IsFlux)) {
13118 continue;
13119 }
13120
13121
13122 // compute the slopes based only on the fluid cells - no ghost cells (bndry cnd not taken into account)
13123 if(mode == 0) {
13124 // reset the slopes
13125 for(MInt i = 0; i < nDim; i++) {
13126 for(MInt varId = 0; varId < PV->noVariables; varId++) {
13127 m_solver->a_slope(cellId, varId, i) = F0;
13128 }
13129 }
13130
13131 // compute the slopes for the interpolation -
13132 for(MInt nghbr = 0; nghbr < m_solver->a_noReconstructionNeighbors(cellId); nghbr++) {
13133 nghbrId = m_solver->a_reconstructionNeighborId(cellId, nghbr);
13134 // skip ghost cells (reconstruction constants are set to zero - skip nevertheless!
13135 // important if ghost cell variables are not yet set properly!
13136 if(m_solver->a_isBndryGhostCell(nghbrId)) {
13137 continue;
13138 }
13139 for(MInt i = 0; i < nDim; i++) {
13140 for(MInt varId = 0; varId < PV->noVariables; varId++) {
13141 m_solver->a_slope(cellId, varId, i) +=
13142 m_reconstructionConstants[bndryId][nghbr * nDim + i]
13143 * (m_solver->a_pvariable(nghbrId, varId) - m_solver->a_pvariable(cellId, varId));
13144 }
13145 }
13146 }
13147 }
13148
13149 // compute the offset of mp relative to the cell center
13150 for(MInt i = 0; i < nDim; i++) {
13151 dx[i] =
13152 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageCoordinates[i] - m_solver->a_coordinate(cellId, i);
13153 }
13154
13155 // compute Image Point variable
13156 for(MInt varId = 0; varId < PV->noVariables; varId++) {
13157 // store old value for computation of max. rel. change
13158 oldVar = m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[varId];
13159
13160 // compute image point value
13161 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[varId] =
13162 m_solver->a_pvariable(cellId, varId);
13163 for(MInt i = 0; i < nDim; i++) {
13164 m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[varId] +=
13165 dx[i] * m_solver->a_slope(cellId, varId, i);
13166 }
13167 // compute relative change
13168 diff = abs((oldVar - m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[varId])
13169 / m_bndryCells->a[bndryId].m_srfcVariables[srfc]->m_imageVariables[varId]);
13170 if(diff > eps) {
13171 eps = diff;
13172 }
13173 }
13174 }
13175 }
13176 }
13177 return eps;
13178}

◆ updateRHSSmallCells()

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::updateRHSSmallCells

update RHS of small and corresponding master cells

Author
Daniel Hartmann, March 29, 2006

Definition at line 9016 of file fvcartesianbndrycndxd.cpp.

9016 {
9017 TRACE();
9018
9019 MInt bndryId;
9020 MInt cellId;
9021 MInt noCVars = CV->noVariables;
9022 MInt noFVars = FV->noVariables;
9023 MInt noCells = m_smallBndryCells->size();
9024 //---
9025
9026 for(MInt smallCellId = 0; smallCellId < noCells; smallCellId++) {
9027 bndryId = m_smallBndryCells->a[smallCellId];
9028 cellId = m_bndryCells->a[bndryId].m_cellId;
9029
9030 for(MInt varId = 0; varId < noCVars; varId++) {
9031 m_solver->a_tau(cellId, varId) = 0;
9032 }
9033 for(MInt varId = 0; varId < noFVars; varId++) {
9034 m_solver->a_rightHandSide(cellId, varId) = 0;
9035 }
9036 }
9037}
MFloat & a_tau(const MInt cellId, const MInt varId)
Returns the tau of the cell cellId for variable varId.

◆ vecScalarMul()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
MFloat * FvBndryCndXD< nDim, SysEqn >::vecScalarMul ( MFloat  ,
MFloat ,
MFloat  
)

◆ vecSub()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
MFloat * FvBndryCndXD< nDim, SysEqn >::vecSub ( MFloat ,
MFloat ,
MFloat  
)

◆ writeStlFileOfCell() [1/2]

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::writeStlFileOfCell ( MInt  ,
const char *   
)

◆ writeStlFileOfCell() [2/2]

template<MInt nDim, class SysEqn >
void FvBndryCndXD< nDim, SysEqn >::writeStlFileOfCell ( MInt  cellId,
const MChar fileName 
)
inlinevirtual

Definition at line 168 of file fvcartesianbndrycndxd.h.

168{};

◆ writeStlOfNodes()

template<MInt nDim, class SysEqn >
template<class X = void, std::enable_if_t< nDim==3, X * > = nullptr>
void FvBndryCndXD< nDim, SysEqn >::writeStlOfNodes ( MInt  ,
MInt *&  ,
const char *   
)

Friends And Related Function Documentation

◆ FvCartesianSolverXD< nDim, SysEqn >

template<MInt nDim, class SysEqn >
friend class FvCartesianSolverXD< nDim, SysEqn >
friend

Definition at line 121 of file fvcartesianbndrycndxd.h.

◆ FvZonalSTG< nDim, SysEqn >

template<MInt nDim, class SysEqn >
friend class FvZonalSTG< nDim, SysEqn >
friend

Definition at line 121 of file fvcartesianbndrycndxd.h.

Member Data Documentation

◆ AV

template<MInt nDim, class SysEqn >
SysEqn::AdditionalVariables* FvBndryCndXD< nDim, SysEqn >::AV {}

Definition at line 155 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerCutOffInit

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerCutOffInit = nullptr

Definition at line 277 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerCutOffSlopesInviscid

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerCutOffSlopesInviscid = nullptr

Definition at line 288 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerCutOffVariables

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerCutOffVariables = nullptr

Definition at line 281 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerInit

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerInit = nullptr

Definition at line 276 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerNeumann

template<MInt nDim, class SysEqn >
BndryCndHandlerVar* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerNeumann = nullptr

Definition at line 278 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerSlopesInviscid

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerSlopesInviscid = nullptr

Definition at line 287 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerSpongeVariables

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerSpongeVariables = nullptr

Definition at line 282 of file fvcartesianbndrycndxd.h.

◆ bndryCndHandlerVariables

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCndHandlerVariables = nullptr

Definition at line 280 of file fvcartesianbndrycndxd.h.

◆ bndryCutOffViscousSlopes

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryCutOffViscousSlopes = nullptr

Definition at line 291 of file fvcartesianbndrycndxd.h.

◆ bndryViscousSlopes

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::bndryViscousSlopes = nullptr

Definition at line 290 of file fvcartesianbndrycndxd.h.

◆ CV

template<MInt nDim, class SysEqn >
SysEqn::ConservativeVariables* FvBndryCndXD< nDim, SysEqn >::CV {}

Definition at line 152 of file fvcartesianbndrycndxd.h.

◆ FV

template<MInt nDim, class SysEqn >
SysEqn::FluxVariables* FvBndryCndXD< nDim, SysEqn >::FV {}

Definition at line 153 of file fvcartesianbndrycndxd.h.

◆ m_4000timeInterval

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_4000timeInterval

Definition at line 310 of file fvcartesianbndrycndxd.h.

◆ m_4000timeStepOffset

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_4000timeStepOffset

Definition at line 309 of file fvcartesianbndrycndxd.h.

◆ m_7901BcActive

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7901BcActive

Definition at line 410 of file fvcartesianbndrycndxd.h.

◆ m_7901faceNormalDir

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7901faceNormalDir

Definition at line 409 of file fvcartesianbndrycndxd.h.

◆ m_7901globalNoPeriodicLocations

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

Definition at line 415 of file fvcartesianbndrycndxd.h.

◆ m_7901globalNoWallNormalLocations

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7901globalNoWallNormalLocations = -1

Definition at line 414 of file fvcartesianbndrycndxd.h.

◆ m_7901globalWallNormalLocations

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvBndryCndXD< nDim, SysEqn >::m_7901globalWallNormalLocations

Definition at line 422 of file fvcartesianbndrycndxd.h.

◆ m_7901LESAverage

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_7901LESAverage = nullptr

Definition at line 416 of file fvcartesianbndrycndxd.h.

◆ m_7901LESAverageOld

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_7901LESAverageOld = nullptr

Definition at line 417 of file fvcartesianbndrycndxd.h.

◆ m_7901periodicDir

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7901periodicDir

Definition at line 412 of file fvcartesianbndrycndxd.h.

◆ m_7901periodicIndex

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

Definition at line 418 of file fvcartesianbndrycndxd.h.

◆ m_7901periodicLocations

template<MInt nDim, class SysEqn >
std::vector<MFloat>* FvBndryCndXD< nDim, SysEqn >::m_7901periodicLocations = nullptr

Definition at line 420 of file fvcartesianbndrycndxd.h.

◆ m_7901StartTimeStep

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7901StartTimeStep

Definition at line 411 of file fvcartesianbndrycndxd.h.

◆ m_7901wallDir

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7901wallDir

Definition at line 413 of file fvcartesianbndrycndxd.h.

◆ m_7901wallNormalLocations

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvBndryCndXD< nDim, SysEqn >::m_7901wallNormalLocations

Definition at line 421 of file fvcartesianbndrycndxd.h.

◆ m_7902BcActive

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7902BcActive

Definition at line 429 of file fvcartesianbndrycndxd.h.

◆ m_7902faceNormalDir

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7902faceNormalDir

Definition at line 428 of file fvcartesianbndrycndxd.h.

◆ m_7902globalNoPeriodicLocations

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

Definition at line 434 of file fvcartesianbndrycndxd.h.

◆ m_7902globalNoWallNormalLocations

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7902globalNoWallNormalLocations = -1

Definition at line 433 of file fvcartesianbndrycndxd.h.

◆ m_7902globalWallNormalLocations

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvBndryCndXD< nDim, SysEqn >::m_7902globalWallNormalLocations

Definition at line 441 of file fvcartesianbndrycndxd.h.

◆ m_7902LESAverage

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_7902LESAverage = nullptr

Definition at line 435 of file fvcartesianbndrycndxd.h.

◆ m_7902LESAverageOld

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_7902LESAverageOld = nullptr

Definition at line 436 of file fvcartesianbndrycndxd.h.

◆ m_7902periodicDir

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7902periodicDir

Definition at line 431 of file fvcartesianbndrycndxd.h.

◆ m_7902periodicIndex

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

Definition at line 437 of file fvcartesianbndrycndxd.h.

◆ m_7902periodicLocations

template<MInt nDim, class SysEqn >
std::vector<MFloat>* FvBndryCndXD< nDim, SysEqn >::m_7902periodicLocations = nullptr

Definition at line 439 of file fvcartesianbndrycndxd.h.

◆ m_7902StartTimeStep

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7902StartTimeStep

Definition at line 430 of file fvcartesianbndrycndxd.h.

◆ m_7902wallDir

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_7902wallDir

Definition at line 432 of file fvcartesianbndrycndxd.h.

◆ m_7902wallNormalLocations

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvBndryCndXD< nDim, SysEqn >::m_7902wallNormalLocations

Definition at line 440 of file fvcartesianbndrycndxd.h.

◆ m_azimuthalNearBoundaryHaloCells

template<MInt nDim, class SysEqn >
std::vector<std::vector<MInt> > FvBndryCndXD< nDim, SysEqn >::m_azimuthalNearBoundaryHaloCells

Definition at line 302 of file fvcartesianbndrycndxd.h.

◆ m_azimuthalNearBoundaryWindowCells

template<MInt nDim, class SysEqn >
std::vector<std::vector<MInt> > FvBndryCndXD< nDim, SysEqn >::m_azimuthalNearBoundaryWindowCells

Definition at line 300 of file fvcartesianbndrycndxd.h.

◆ m_azimuthalNearBoundaryWindowMap

template<MInt nDim, class SysEqn >
std::vector<std::vector<MInt> > FvBndryCndXD< nDim, SysEqn >::m_azimuthalNearBoundaryWindowMap

Definition at line 301 of file fvcartesianbndrycndxd.h.

◆ m_bc1251ForcingAmplitude

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_bc1251ForcingAmplitude

Definition at line 403 of file fvcartesianbndrycndxd.h.

◆ m_bc1251ForcingDirection

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_bc1251ForcingDirection

Definition at line 406 of file fvcartesianbndrycndxd.h.

◆ m_bc1251ForcingFrequency

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_bc1251ForcingFrequency

Definition at line 405 of file fvcartesianbndrycndxd.h.

◆ m_bc1251ForcingWavelength

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_bc1251ForcingWavelength

Definition at line 404 of file fvcartesianbndrycndxd.h.

◆ m_bc1601

template<MInt nDim, class SysEqn >
Bc1601Class<nDim>* FvBndryCndXD< nDim, SysEqn >::m_bc1601 = nullptr

Definition at line 398 of file fvcartesianbndrycndxd.h.

◆ m_bc1601_bcId

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_bc1601_bcId = -1

Definition at line 397 of file fvcartesianbndrycndxd.h.

◆ m_bc1601MoveGenOutOfSponge

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_bc1601MoveGenOutOfSponge = false

Definition at line 399 of file fvcartesianbndrycndxd.h.

◆ m_Bc2770TargetCells

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

Definition at line 360 of file fvcartesianbndrycndxd.h.

◆ m_Bc3011WallTemperature

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_Bc3011WallTemperature = NAN

Definition at line 375 of file fvcartesianbndrycndxd.h.

◆ m_bc_comm_pointer

template<MInt nDim, class SysEqn >
MInt* FvBndryCndXD< nDim, SysEqn >::m_bc_comm_pointer = nullptr
protected

Definition at line 476 of file fvcartesianbndrycndxd.h.

◆ m_bcCo_comm_pointer

template<MInt nDim, class SysEqn >
MInt* FvBndryCndXD< nDim, SysEqn >::m_bcCo_comm_pointer = nullptr
protected

Definition at line 479 of file fvcartesianbndrycndxd.h.

◆ m_besselModes

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_besselModes

Definition at line 373 of file fvcartesianbndrycndxd.h.

◆ m_besselTrig

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_besselTrig = nullptr

Definition at line 374 of file fvcartesianbndrycndxd.h.

◆ m_bndryCell

template<MInt nDim, class SysEqn >
FvBndryCell<nDim, SysEqn>* FvBndryCndXD< nDim, SysEqn >::m_bndryCell = nullptr

Definition at line 139 of file fvcartesianbndrycndxd.h.

◆ m_bndryCells

template<MInt nDim, class SysEqn >
Collector<FvBndryCell<nDim, SysEqn> >* FvBndryCndXD< nDim, SysEqn >::m_bndryCells = nullptr

Definition at line 164 of file fvcartesianbndrycndxd.h.

◆ m_bndryCndCells

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

Definition at line 334 of file fvcartesianbndrycndxd.h.

◆ m_bndryCndIds

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

Definition at line 319 of file fvcartesianbndrycndxd.h.

◆ m_bndryNghbrs

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

Definition at line 141 of file fvcartesianbndrycndxd.h.

◆ m_boundarySurfaces

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

Definition at line 336 of file fvcartesianbndrycndxd.h.

◆ m_cbcBndryCndIds

template<MInt nDim, class SysEqn >
std::vector<MInt> FvBndryCndXD< nDim, SysEqn >::m_cbcBndryCndIds

Definition at line 458 of file fvcartesianbndrycndxd.h.

◆ m_cbcCutOff

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_cbcCutOff = false

Definition at line 344 of file fvcartesianbndrycndxd.h.

◆ m_cbcDir

template<MInt nDim, class SysEqn >
std::vector<std::vector<MInt> > FvBndryCndXD< nDim, SysEqn >::m_cbcDir

Definition at line 463 of file fvcartesianbndrycndxd.h.

◆ m_cbcDomainMin

template<MInt nDim, class SysEqn >
std::vector<MInt> FvBndryCndXD< nDim, SysEqn >::m_cbcDomainMin

Definition at line 464 of file fvcartesianbndrycndxd.h.

◆ m_cbcInflowArea

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvBndryCndXD< nDim, SysEqn >::m_cbcInflowArea

Definition at line 456 of file fvcartesianbndrycndxd.h.

◆ m_cbcLref

template<MInt nDim, class SysEqn >
std::vector<MFloat> FvBndryCndXD< nDim, SysEqn >::m_cbcLref

Definition at line 462 of file fvcartesianbndrycndxd.h.

◆ m_cbcReferencePoint

template<MInt nDim, class SysEqn >
std::vector<std::vector<MFloat> > FvBndryCndXD< nDim, SysEqn >::m_cbcReferencePoint

Definition at line 457 of file fvcartesianbndrycndxd.h.

◆ m_cbcRelax

template<MInt nDim, class SysEqn >
std::vector<std::vector<MFloat> > FvBndryCndXD< nDim, SysEqn >::m_cbcRelax

Definition at line 459 of file fvcartesianbndrycndxd.h.

◆ m_cbcSmallCellCorrection

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_cbcSmallCellCorrection = false

Definition at line 345 of file fvcartesianbndrycndxd.h.

◆ m_cbcTurbulence

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_cbcTurbulence = false

Definition at line 465 of file fvcartesianbndrycndxd.h.

◆ m_cbcViscous

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_cbcViscous = false

Definition at line 466 of file fvcartesianbndrycndxd.h.

◆ m_cellCoordinatesCorrected

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_cellCoordinatesCorrected

Definition at line 150 of file fvcartesianbndrycndxd.h.

◆ m_cellMerging

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_cellMerging = false

Definition at line 304 of file fvcartesianbndrycndxd.h.

◆ m_cells

template<MInt nDim, class SysEqn >
maia::fv::collector::FvCellCollector<nDim>& FvBndryCndXD< nDim, SysEqn >::m_cells

Definition at line 131 of file fvcartesianbndrycndxd.h.

◆ m_cellsInsideSpongeLayer

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

Definition at line 321 of file fvcartesianbndrycndxd.h.

◆ m_changeAdiabBCToTemp

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_changeAdiabBCToTemp

Definition at line 145 of file fvcartesianbndrycndxd.h.

◆ m_clusterCutOffBcs

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_clusterCutOffBcs {}

Definition at line 368 of file fvcartesianbndrycndxd.h.

◆ m_combustion

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_combustion

Definition at line 393 of file fvcartesianbndrycndxd.h.

◆ m_comm_bc

template<MInt nDim, class SysEqn >
MPI_Comm* FvBndryCndXD< nDim, SysEqn >::m_comm_bc = nullptr
protected

Definition at line 474 of file fvcartesianbndrycndxd.h.

◆ m_comm_bc_init

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_comm_bc_init = 0
protected

Definition at line 475 of file fvcartesianbndrycndxd.h.

◆ m_comm_bcCo

template<MInt nDim, class SysEqn >
MPI_Comm* FvBndryCndXD< nDim, SysEqn >::m_comm_bcCo = nullptr
protected

Definition at line 477 of file fvcartesianbndrycndxd.h.

◆ m_comm_bcCo_init

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_comm_bcCo_init = 0
protected

Definition at line 478 of file fvcartesianbndrycndxd.h.

◆ m_commStg

template<MInt nDim, class SysEqn >
MPI_Comm FvBndryCndXD< nDim, SysEqn >::m_commStg

Definition at line 453 of file fvcartesianbndrycndxd.h.

◆ m_complexBoundaryMB

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_complexBoundaryMB

Definition at line 149 of file fvcartesianbndrycndxd.h.

◆ m_createBoundaryAtCutoff

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_createBoundaryAtCutoff

Definition at line 316 of file fvcartesianbndrycndxd.h.

◆ m_createSpongeBoundary

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_createSpongeBoundary

Definition at line 317 of file fvcartesianbndrycndxd.h.

◆ m_cutCandidates

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

Definition at line 481 of file fvcartesianbndrycndxd.h.

◆ m_cutOffBndryCndIds

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

Definition at line 320 of file fvcartesianbndrycndxd.h.

◆ m_deltaP

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_deltaP {}

Definition at line 388 of file fvcartesianbndrycndxd.h.

◆ m_deltaPL

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_deltaPL {}

Definition at line 389 of file fvcartesianbndrycndxd.h.

◆ m_dirNBc10970

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_dirNBc10970 = -1
private

Definition at line 890 of file fvcartesianbndrycndxd.h.

◆ m_dirNBc10980

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_dirNBc10980 = -1
private

Definition at line 894 of file fvcartesianbndrycndxd.h.

◆ m_dirNBc11110

template<MInt nDim, class SysEqn >
MInt* FvBndryCndXD< nDim, SysEqn >::m_dirNBc11110 = nullptr
private

Definition at line 897 of file fvcartesianbndrycndxd.h.

◆ m_dirNormal

template<MInt nDim, class SysEqn >
std::vector<std::vector<MFloat> > FvBndryCndXD< nDim, SysEqn >::m_dirNormal

Definition at line 461 of file fvcartesianbndrycndxd.h.

◆ m_dirTangent

template<MInt nDim, class SysEqn >
std::vector<std::vector<MFloat> > FvBndryCndXD< nDim, SysEqn >::m_dirTangent

Definition at line 460 of file fvcartesianbndrycndxd.h.

◆ m_firstUseBc10970

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_firstUseBc10970 = true
private

Definition at line 889 of file fvcartesianbndrycndxd.h.

◆ m_firstUseBc10980

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_firstUseBc10980 = true
private

Definition at line 893 of file fvcartesianbndrycndxd.h.

◆ m_firstUseBc11110

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_firstUseBc11110 = true
private

Definition at line 898 of file fvcartesianbndrycndxd.h.

◆ m_firstUseSetBCTypes

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_firstUseSetBCTypes = true
private

Definition at line 495 of file fvcartesianbndrycndxd.h.

◆ m_geometryIntersection

template<MInt nDim, class SysEqn >
GeometryIntersection<nDim>* FvBndryCndXD< nDim, SysEqn >::m_geometryIntersection
protected

Definition at line 482 of file fvcartesianbndrycndxd.h.

◆ m_gridCutTest

template<MInt nDim, class SysEqn >
MString FvBndryCndXD< nDim, SysEqn >::m_gridCutTest
protected

Definition at line 472 of file fvcartesianbndrycndxd.h.

◆ m_horTargetData

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_horTargetData = nullptr
private

Definition at line 1061 of file fvcartesianbndrycndxd.h.

◆ m_horTargetDataCount

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_horTargetDataCount
private

Definition at line 1062 of file fvcartesianbndrycndxd.h.

◆ m_inflowTemperatureRatio

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_inflowTemperatureRatio

Definition at line 390 of file fvcartesianbndrycndxd.h.

◆ m_ipVariableIterative

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_ipVariableIterative

Definition at line 338 of file fvcartesianbndrycndxd.h.

◆ m_isEEGas

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_isEEGas

Definition at line 394 of file fvcartesianbndrycndxd.h.

◆ m_jetHeight

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_jetHeight

Definition at line 381 of file fvcartesianbndrycndxd.h.

◆ m_jetInletTurbulence

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_jetInletTurbulence = false

Definition at line 400 of file fvcartesianbndrycndxd.h.

◆ m_Ma

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_Ma

Definition at line 387 of file fvcartesianbndrycndxd.h.

◆ m_maxLevel

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_maxLevel

Definition at line 158 of file fvcartesianbndrycndxd.h.

◆ m_maxNoBndryCells

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_maxNoBndryCells

Definition at line 349 of file fvcartesianbndrycndxd.h.

◆ m_maxNoBndryCndIds

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_maxNoBndryCndIds

Definition at line 350 of file fvcartesianbndrycndxd.h.

◆ m_meanCoord

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_meanCoord[3] {}

Definition at line 355 of file fvcartesianbndrycndxd.h.

◆ m_minLevel

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_minLevel

Definition at line 157 of file fvcartesianbndrycndxd.h.

◆ m_modeAmp

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_modeAmp = nullptr

Definition at line 365 of file fvcartesianbndrycndxd.h.

◆ m_modeEtaMin

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_modeEtaMin = nullptr

Definition at line 371 of file fvcartesianbndrycndxd.h.

◆ m_modeK

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_modeK = nullptr

Definition at line 367 of file fvcartesianbndrycndxd.h.

◆ m_modeOmega

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_modeOmega = nullptr

Definition at line 364 of file fvcartesianbndrycndxd.h.

◆ m_modePhi

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_modePhi = nullptr

Definition at line 370 of file fvcartesianbndrycndxd.h.

◆ m_modes

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_modes {}

Definition at line 372 of file fvcartesianbndrycndxd.h.

◆ m_modeType

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

Definition at line 366 of file fvcartesianbndrycndxd.h.

◆ m_momentumThickness

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_momentumThickness

Definition at line 385 of file fvcartesianbndrycndxd.h.

◆ m_multipleGhostCells

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_multipleGhostCells = 0

Definition at line 337 of file fvcartesianbndrycndxd.h.

◆ m_nearBoundaryHaloCells

template<MInt nDim, class SysEqn >
std::vector<MInt>* FvBndryCndXD< nDim, SysEqn >::m_nearBoundaryHaloCells = nullptr

Definition at line 298 of file fvcartesianbndrycndxd.h.

◆ m_nearBoundaryWindowCells

template<MInt nDim, class SysEqn >
std::vector<MInt>* FvBndryCndXD< nDim, SysEqn >::m_nearBoundaryWindowCells = nullptr

Definition at line 297 of file fvcartesianbndrycndxd.h.

◆ m_nmbrOfModes

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

Definition at line 369 of file fvcartesianbndrycndxd.h.

◆ m_noBndryCndIds

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noBndryCndIds

Definition at line 341 of file fvcartesianbndrycndxd.h.

◆ m_noBoundarySurfaces

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noBoundarySurfaces {}

Definition at line 340 of file fvcartesianbndrycndxd.h.

◆ m_noCellsInsideSpongeLayer

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noCellsInsideSpongeLayer

Definition at line 322 of file fvcartesianbndrycndxd.h.

◆ m_noCorners

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noCorners = nDim == 2 ? 4 : 8

Definition at line 121 of file fvcartesianbndrycndxd.h.

◆ m_noCutOffBndryCndIds

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noCutOffBndryCndIds

Definition at line 343 of file fvcartesianbndrycndxd.h.

◆ m_noDirs

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noDirs = 2 * nDim

Definition at line 119 of file fvcartesianbndrycndxd.h.

◆ m_noEdges

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noEdges = nDim == 2 ? 4 : 12

Definition at line 120 of file fvcartesianbndrycndxd.h.

◆ m_noFluxRedistributionLayers

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noFluxRedistributionLayers

Definition at line 306 of file fvcartesianbndrycndxd.h.

◆ m_noImagePointIterations

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noImagePointIterations

Definition at line 351 of file fvcartesianbndrycndxd.h.

◆ m_noLevelSetsUsedForMb

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noLevelSetsUsedForMb

Definition at line 148 of file fvcartesianbndrycndxd.h.

◆ m_noMaxSpongeBndryCells

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noMaxSpongeBndryCells

Definition at line 346 of file fvcartesianbndrycndxd.h.

◆ m_noRansEquations

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noRansEquations

Definition at line 392 of file fvcartesianbndrycndxd.h.

◆ m_noShockBcCells

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noShockBcCells {}

Definition at line 358 of file fvcartesianbndrycndxd.h.

◆ m_noSpecies

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noSpecies

Definition at line 391 of file fvcartesianbndrycndxd.h.

◆ m_noSpongeBndryCndIds

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_noSpongeBndryCndIds

Definition at line 342 of file fvcartesianbndrycndxd.h.

◆ m_nu

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_nu[10] {}

Definition at line 395 of file fvcartesianbndrycndxd.h.

◆ m_oldFluctChol

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_oldFluctChol = nullptr

Definition at line 467 of file fvcartesianbndrycndxd.h.

◆ m_oldTime

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_oldTime = F0

Definition at line 468 of file fvcartesianbndrycndxd.h.

◆ m_outputIGPoints

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_outputIGPoints

Definition at line 318 of file fvcartesianbndrycndxd.h.

◆ m_pModeBc10970

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_pModeBc10970 = 0
private

Definition at line 891 of file fvcartesianbndrycndxd.h.

◆ m_pressureRatioChannel

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_pressureRatioChannel

Definition at line 312 of file fvcartesianbndrycndxd.h.

◆ m_primaryJetRadius

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_primaryJetRadius

Definition at line 382 of file fvcartesianbndrycndxd.h.

◆ m_radiusFlameTube

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_radiusFlameTube

Definition at line 378 of file fvcartesianbndrycndxd.h.

◆ m_radiusVelFlameTube

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_radiusVelFlameTube

Definition at line 379 of file fvcartesianbndrycndxd.h.

◆ m_reconstructionConstants

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_reconstructionConstants = nullptr

Definition at line 294 of file fvcartesianbndrycndxd.h.

◆ m_reconstructionNghbrs

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

Definition at line 295 of file fvcartesianbndrycndxd.h.

◆ m_rntRoot

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_rntRoot

Definition at line 427 of file fvcartesianbndrycndxd.h.

◆ m_secondaryJetRadius

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_secondaryJetRadius

Definition at line 383 of file fvcartesianbndrycndxd.h.

◆ m_secondOrderRec

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_secondOrderRec

Definition at line 305 of file fvcartesianbndrycndxd.h.

◆ m_shearLayerStrength

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_shearLayerStrength

Definition at line 386 of file fvcartesianbndrycndxd.h.

◆ m_shearLayerThickness

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_shearLayerThickness

Definition at line 380 of file fvcartesianbndrycndxd.h.

◆ m_shockBcVars

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_shockBcVars = nullptr

Definition at line 357 of file fvcartesianbndrycndxd.h.

◆ m_shockFromInnerSolution

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_shockFromInnerSolution {}

Definition at line 359 of file fvcartesianbndrycndxd.h.

◆ m_sigmaEndSpongeBndryId

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_sigmaEndSpongeBndryId = nullptr

Definition at line 327 of file fvcartesianbndrycndxd.h.

◆ m_sigmaNonRefl

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_sigmaNonRefl

Definition at line 314 of file fvcartesianbndrycndxd.h.

◆ m_sigmaNonReflInflow

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_sigmaNonReflInflow

Definition at line 315 of file fvcartesianbndrycndxd.h.

◆ m_sigmaShock

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_sigmaShock {}

Definition at line 361 of file fvcartesianbndrycndxd.h.

◆ m_sigmaSpongeBndryId

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_sigmaSpongeBndryId = nullptr

Definition at line 326 of file fvcartesianbndrycndxd.h.

◆ m_smallBndryCells

template<MInt nDim, class SysEqn >
List<MInt>* FvBndryCndXD< nDim, SysEqn >::m_smallBndryCells = nullptr

Definition at line 133 of file fvcartesianbndrycndxd.h.

◆ m_smallCellRHSCorrection

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_smallCellRHSCorrection = false

Definition at line 353 of file fvcartesianbndrycndxd.h.

◆ m_smallCutCells

template<MInt nDim, class SysEqn >
std::vector<MInt> FvBndryCndXD< nDim, SysEqn >::m_smallCutCells

Definition at line 296 of file fvcartesianbndrycndxd.h.

◆ m_solver

template<MInt nDim, class SysEqn >
FvCartesianSolverXD<nDim, SysEqn>* FvBndryCndXD< nDim, SysEqn >::m_solver = nullptr

Definition at line 138 of file fvcartesianbndrycndxd.h.

◆ m_solverId

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_solverId = -1

Definition at line 144 of file fvcartesianbndrycndxd.h.

◆ m_sortedBndryCells

template<MInt nDim, class SysEqn >
List<MInt>* FvBndryCndXD< nDim, SysEqn >::m_sortedBndryCells = nullptr

Definition at line 134 of file fvcartesianbndrycndxd.h.

◆ m_sortedCutOffCells

template<MInt nDim, class SysEqn >
std::vector<List<MInt>*> FvBndryCndXD< nDim, SysEqn >::m_sortedCutOffCells {}

Definition at line 136 of file fvcartesianbndrycndxd.h.

◆ m_sortedSpongeBndryCells

template<MInt nDim, class SysEqn >
List<MInt>* FvBndryCndXD< nDim, SysEqn >::m_sortedSpongeBndryCells = nullptr

Definition at line 135 of file fvcartesianbndrycndxd.h.

◆ m_splitChildren

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

Definition at line 143 of file fvcartesianbndrycndxd.h.

◆ m_splitParents

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

Definition at line 142 of file fvcartesianbndrycndxd.h.

◆ m_splitSurfaces

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

Definition at line 140 of file fvcartesianbndrycndxd.h.

◆ m_spongeBeta

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_spongeBeta

Definition at line 347 of file fvcartesianbndrycndxd.h.

◆ m_spongeBndryCells

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

Definition at line 335 of file fvcartesianbndrycndxd.h.

◆ m_spongeBndryCndIds

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

Definition at line 323 of file fvcartesianbndrycndxd.h.

◆ m_spongeCoord

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_spongeCoord = nullptr

Definition at line 348 of file fvcartesianbndrycndxd.h.

◆ m_spongeDirections

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

Definition at line 325 of file fvcartesianbndrycndxd.h.

◆ m_spongeEndIteration

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_spongeEndIteration = nullptr

Definition at line 332 of file fvcartesianbndrycndxd.h.

◆ m_spongeFactor

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_spongeFactor = nullptr

Definition at line 324 of file fvcartesianbndrycndxd.h.

◆ m_spongeLayerLayout

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_spongeLayerLayout

Definition at line 329 of file fvcartesianbndrycndxd.h.

◆ m_spongeLayerThickness

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_spongeLayerThickness

Definition at line 328 of file fvcartesianbndrycndxd.h.

◆ m_spongeStartIteration

template<MInt nDim, class SysEqn >
MFloat* FvBndryCndXD< nDim, SysEqn >::m_spongeStartIteration = nullptr

Definition at line 331 of file fvcartesianbndrycndxd.h.

◆ m_spongeTimeDep

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_spongeTimeDep

Definition at line 330 of file fvcartesianbndrycndxd.h.

◆ m_spongeTimeDependent

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

Definition at line 333 of file fvcartesianbndrycndxd.h.

◆ m_startSTGTimeStep

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_startSTGTimeStep

Definition at line 450 of file fvcartesianbndrycndxd.h.

◆ m_static_bc1091MGC_edgeCellCounter

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_bc1091MGC_edgeCellCounter = 0
private

Definition at line 881 of file fvcartesianbndrycndxd.h.

◆ m_static_bc1091MGC_first

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_bc1091MGC_first = true
private

Definition at line 882 of file fvcartesianbndrycndxd.h.

◆ m_static_bc1091MGC_first2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_bc1091MGC_first2 = true
private

Definition at line 883 of file fvcartesianbndrycndxd.h.

◆ m_static_bc1091MGC_minTimeSteps

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_bc1091MGC_minTimeSteps = 0
private

Definition at line 879 of file fvcartesianbndrycndxd.h.

◆ m_static_bc1091MGC_nghbrDir

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_bc1091MGC_nghbrDir = -1
private

Definition at line 880 of file fvcartesianbndrycndxd.h.

◆ m_static_bc1099MGC_first

template<MInt nDim, class SysEqn >
bool FvBndryCndXD< nDim, SysEqn >::m_static_bc1099MGC_first = true
private

Definition at line 886 of file fvcartesianbndrycndxd.h.

◆ m_static_bc1099MGC_timeOfMaxPdiff

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_bc1099MGC_timeOfMaxPdiff = 0
private

Definition at line 885 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_dimN = -1
private

Definition at line 931 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_dimT1 = -1
private

Definition at line 932 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_dimT2 = -1
private

Definition at line 933 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_dirN = -1
private

Definition at line 930 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_domainMin

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_domainMin
private

Definition at line 936 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_first = true
private

Definition at line 929 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_inflowArea
private

Definition at line 934 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091_referencePoint[3]
private

Definition at line 935 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091a_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091a_solverProfile = false
private

Definition at line 938 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091b_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091b_dimN = -1
private

Definition at line 952 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091b_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091b_dimT1 = -1
private

Definition at line 953 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091b_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091b_dirN = -1
private

Definition at line 951 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091b_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091b_first = true
private

Definition at line 950 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091b_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091b_inflowArea
private

Definition at line 955 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091b_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091b_referencePoint[3]
private

Definition at line 956 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091b_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091b_solverProfile = false
private

Definition at line 954 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_after_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_after_dimN = -1
private

Definition at line 967 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_after_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_after_dimT1 = -1
private

Definition at line 968 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_after_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_after_dimT2 = -1
private

Definition at line 969 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_after_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_after_dirN = -1
private

Definition at line 966 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_after_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_after_first = true
private

Definition at line 965 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_dimN = -1
private

Definition at line 960 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_dimT1 = -1
private

Definition at line 961 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_dirN = -1
private

Definition at line 959 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_first = true
private

Definition at line 958 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_inflowArea
private

Definition at line 962 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091c_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091c_referencePoint[3]
private

Definition at line 963 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_after_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_after_dimN = -1
private

Definition at line 982 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_after_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_after_dimT1 = -1
private

Definition at line 983 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_after_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_after_dimT2 = -1
private

Definition at line 984 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_after_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_after_dirN = -1
private

Definition at line 981 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_after_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_after_first = true
private

Definition at line 980 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_dimN = -1
private

Definition at line 973 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_dimT1 = -1
private

Definition at line 974 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_dirN = -1
private

Definition at line 972 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_first = true
private

Definition at line 971 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_inflowArea
private

Definition at line 975 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_minDom

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_minDom = 0
private

Definition at line 978 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_referencePoint[3]
private

Definition at line 976 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091d_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091d_solverProfile = false
private

Definition at line 977 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091e_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091e_dimN = -1
private

Definition at line 988 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091e_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091e_dimT1 = -1
private

Definition at line 989 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091e_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091e_dirN = -1
private

Definition at line 987 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091e_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091e_first = true
private

Definition at line 986 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091e_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091e_inflowArea
private

Definition at line 991 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1091e_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1091e_solverProfile = false
private

Definition at line 990 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_dimN
private

Definition at line 1048 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_dimT1
private

Definition at line 1049 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_dimT2
private

Definition at line 1052 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_dirN
private

Definition at line 1047 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_domainMin

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_domainMin = 0
private

Definition at line 1051 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_first = true
private

Definition at line 1046 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_inflowArea
private

Definition at line 1050 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_normal

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_normal[3]
private

Definition at line 1053 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_engine_tangent

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_engine_tangent[3]
private

Definition at line 1054 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_comb_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_comb_dimN = -1
private

Definition at line 923 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_comb_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_comb_dimT1 = -1
private

Definition at line 924 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_comb_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_comb_dimT2 = -1
private

Definition at line 925 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_comb_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_comb_dirN = -1
private

Definition at line 922 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_comb_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_comb_first = true
private

Definition at line 921 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_comb_outFlowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_comb_outFlowArea
private

Definition at line 926 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_comb_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_comb_referencePoint[3]
private

Definition at line 927 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_dimN = -1
private

Definition at line 911 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_dimT1 = -1
private

Definition at line 912 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_dimT2 = -1
private

Definition at line 913 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_dirN = -1
private

Definition at line 910 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_domainMin

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_domainMin = 0
private

Definition at line 917 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_first = true
private

Definition at line 909 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_H

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_H
private

Definition at line 919 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_inflowArea
private

Definition at line 914 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_R

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_R = 0
private

Definition at line 918 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_referencePoint[3]
private

Definition at line 915 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091_local_targetPressure

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091_local_targetPressure
private

Definition at line 916 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_after_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_after_dimN = -1
private

Definition at line 1043 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_after_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_after_dirN = -1
private

Definition at line 1042 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_after_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_after_first = true
private

Definition at line 1041 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_after_interpolationFactor

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_after_interpolationFactor
private

Definition at line 1044 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_dimN = -1
private

Definition at line 1034 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_dimT1 = -1
private

Definition at line 1035 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_dimT2 = -1
private

Definition at line 1036 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_dirN = -1
private

Definition at line 1033 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_first = true
private

Definition at line 1032 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_inflowArea
private

Definition at line 1037 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_referencePoint[nDim]
private

Definition at line 1038 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_1091d_targetPressure

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_1091d_targetPressure
private

Definition at line 1039 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_dimN = -1
private

Definition at line 902 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_dimT1 = -1
private

Definition at line 903 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_dimT2 = -1
private

Definition at line 904 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_dirN = -1
private

Definition at line 901 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_domainMin

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_domainMin
private

Definition at line 907 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_first = true
private

Definition at line 900 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_outFlowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_outFlowArea
private

Definition at line 905 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc1099_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc1099_referencePoint[3]
private

Definition at line 906 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_dimN = -1
private

Definition at line 995 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_dimT1 = -1
private

Definition at line 996 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_dirN = -1
private

Definition at line 994 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_first = true
private

Definition at line 993 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_H

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_H
private

Definition at line 999 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_inflowArea
private

Definition at line 998 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_referencePoint[nDim]
private

Definition at line 1000 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091a_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091a_solverProfile = false
private

Definition at line 997 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_dimN = -1
private

Definition at line 1004 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_dimT1 = -1
private

Definition at line 1005 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_dirN = -1
private

Definition at line 1003 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_first = true
private

Definition at line 1002 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_H

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_H
private

Definition at line 1008 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_inflowArea
private

Definition at line 1007 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_referencePoint[nDim]
private

Definition at line 1009 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091b_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091b_solverProfile = false
private

Definition at line 1006 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_after_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_after_dimN = -1
private

Definition at line 1022 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_after_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_after_dimT1 = -1
private

Definition at line 1023 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_after_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_after_dirN = -1
private

Definition at line 1021 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_after_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_after_first = true
private

Definition at line 1020 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_dimN = -1
private

Definition at line 1013 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_dimT1 = -1
private

Definition at line 1014 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_dirN = -1
private

Definition at line 1012 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_first = true
private

Definition at line 1011 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_H

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_H
private

Definition at line 1016 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_inflowArea
private

Definition at line 1015 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_referencePoint[nDim]
private

Definition at line 1017 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2091d_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2091d_solverProfile = false
private

Definition at line 1018 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2099_1091_local_comb_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2099_1091_local_comb_dimN = -1
private

Definition at line 1027 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2099_1091_local_comb_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2099_1091_local_comb_dimT1 = -1
private

Definition at line 1028 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2099_1091_local_comb_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc2099_1091_local_comb_dirN = -1
private

Definition at line 1026 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2099_1091_local_comb_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc2099_1091_local_comb_first = true
private

Definition at line 1025 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2099_1091_local_comb_outFlowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2099_1091_local_comb_outFlowArea
private

Definition at line 1029 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc2099_1091_local_comb_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc2099_1091_local_comb_referencePoint[nDim]
private

Definition at line 1030 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_dimN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_dimN = -1
private

Definition at line 942 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_dimT1

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_dimT1 = -1
private

Definition at line 943 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_dimT2

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_dimT2 = -1
private

Definition at line 944 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_dirN

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_dirN = -1
private

Definition at line 941 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_first = true
private

Definition at line 940 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_inflowArea

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_inflowArea
private

Definition at line 946 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_R

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_R
private

Definition at line 947 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_referencePoint

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_referencePoint[3]
private

Definition at line 948 of file fvcartesianbndrycndxd.h.

◆ m_static_cbc3091a_solverProfile

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_cbc3091a_solverProfile = false
private

Definition at line 945 of file fvcartesianbndrycndxd.h.

◆ m_static_computeImagePointRecConst_firstRun

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_computeImagePointRecConst_firstRun = true
protected

Definition at line 506 of file fvcartesianbndrycndxd.h.

◆ m_static_correctInflowBoundary_iter

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_correctInflowBoundary_iter = 0
private

Definition at line 877 of file fvcartesianbndrycndxd.h.

◆ m_static_initSmallCellCorrection_firstRun

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_initSmallCellCorrection_firstRun = true
protected

Definition at line 504 of file fvcartesianbndrycndxd.h.

◆ m_static_plotEdges_iter

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_plotEdges_iter = 0
private

Definition at line 871 of file fvcartesianbndrycndxd.h.

◆ m_static_plotIntersectionPoints_iter

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_plotIntersectionPoints_iter = 0
private

Definition at line 873 of file fvcartesianbndrycndxd.h.

◆ m_static_sbc1000co_directions

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_sbc1000co_directions[s_sbc1000co_fixedMaxNoBndryCndIds] {}
protected

Definition at line 502 of file fvcartesianbndrycndxd.h.

◆ m_static_sbc1000co_first

template<MInt nDim, class SysEqn >
MBool FvBndryCndXD< nDim, SysEqn >::m_static_sbc1000co_first = true
protected

Definition at line 500 of file fvcartesianbndrycndxd.h.

◆ m_static_writeStlOfNodes_iter

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_static_writeStlOfNodes_iter = 0
private

Definition at line 875 of file fvcartesianbndrycndxd.h.

◆ m_stgBC

template<MInt nDim, class SysEqn >
std::map<MInt, MSTG<nDim, MAIA_FINITE_VOLUME, MAIA_FINITE_VOLUME>*> FvBndryCndXD< nDim, SysEqn >::m_stgBC

Definition at line 446 of file fvcartesianbndrycndxd.h.

◆ m_stgBcCells

template<MInt nDim, class SysEqn >
std::vector<MInt> FvBndryCndXD< nDim, SysEqn >::m_stgBcCells

Definition at line 449 of file fvcartesianbndrycndxd.h.

◆ m_stgBCStrcd

template<MInt nDim, class SysEqn >
std::map<MInt, MSTG<nDim, MAIA_STRUCTURED, MAIA_FINITE_VOLUME>*> FvBndryCndXD< nDim, SysEqn >::m_stgBCStrcd

Definition at line 447 of file fvcartesianbndrycndxd.h.

◆ m_stgLocal

template<MInt nDim, class SysEqn >
std::map<MInt, MBool> FvBndryCndXD< nDim, SysEqn >::m_stgLocal

Definition at line 448 of file fvcartesianbndrycndxd.h.

◆ m_surfaceGhostCell

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_surfaceGhostCell

Definition at line 339 of file fvcartesianbndrycndxd.h.

◆ m_surfaces

template<MInt nDim, class SysEqn >
maia::fv::surface_collector::FvSurfaceCollector<nDim>& FvBndryCndXD< nDim, SysEqn >::m_surfaces

Definition at line 132 of file fvcartesianbndrycndxd.h.

◆ m_sysEqn

template<MInt nDim, class SysEqn >
SysEqn* FvBndryCndXD< nDim, SysEqn >::m_sysEqn
private

Definition at line 127 of file fvcartesianbndrycndxd.h.

◆ m_targetValuesBC11110

template<MInt nDim, class SysEqn >
MFloat** FvBndryCndXD< nDim, SysEqn >::m_targetValuesBC11110 = nullptr
private

Definition at line 896 of file fvcartesianbndrycndxd.h.

◆ m_targetVelocityFactor

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_targetVelocityFactor

Definition at line 384 of file fvcartesianbndrycndxd.h.

◆ m_unTargetData

template<MInt nDim, class SysEqn >
std::pair<MFloat, MFloat>* FvBndryCndXD< nDim, SysEqn >::m_unTargetData = nullptr
private

Definition at line 1057 of file fvcartesianbndrycndxd.h.

◆ m_unTargetDataCount

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_unTargetDataCount
private

Definition at line 1059 of file fvcartesianbndrycndxd.h.

◆ m_vnTargetData

template<MInt nDim, class SysEqn >
std::pair<MFloat, MFloat>* FvBndryCndXD< nDim, SysEqn >::m_vnTargetData = nullptr
private

Definition at line 1058 of file fvcartesianbndrycndxd.h.

◆ m_vnTargetDataCount

template<MInt nDim, class SysEqn >
MInt FvBndryCndXD< nDim, SysEqn >::m_vnTargetDataCount
private

Definition at line 1060 of file fvcartesianbndrycndxd.h.

◆ m_volumeLimitOther

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_volumeLimitOther

Definition at line 354 of file fvcartesianbndrycndxd.h.

◆ m_volumeLimitWall

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_volumeLimitWall

Definition at line 352 of file fvcartesianbndrycndxd.h.

◆ m_wFactor

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_wFactor

Definition at line 311 of file fvcartesianbndrycndxd.h.

◆ m_wmSrfcToCellId

template<MInt nDim, class SysEqn >
std::list<std::pair<MInt, MInt> > FvBndryCndXD< nDim, SysEqn >::m_wmSrfcToCellId

Definition at line 189 of file fvcartesianbndrycndxd.h.

◆ m_ys

template<MInt nDim, class SysEqn >
MFloat FvBndryCndXD< nDim, SysEqn >::m_ys {}

Definition at line 362 of file fvcartesianbndrycndxd.h.

◆ nonReflectingBoundaryConditionAfterTreatmentCutOff

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::nonReflectingBoundaryConditionAfterTreatmentCutOff = nullptr

Definition at line 284 of file fvcartesianbndrycndxd.h.

◆ nonReflectingCutOffBoundaryCondition

template<MInt nDim, class SysEqn >
BndryCndHandler* FvBndryCndXD< nDim, SysEqn >::nonReflectingCutOffBoundaryCondition = nullptr

Definition at line 285 of file fvcartesianbndrycndxd.h.

◆ PV

template<MInt nDim, class SysEqn >
SysEqn::PrimitiveVariables* FvBndryCndXD< nDim, SysEqn >::PV {}

Definition at line 154 of file fvcartesianbndrycndxd.h.

◆ s_sbc1000co_fixedMaxNoBndryCndIds

template<MInt nDim, class SysEqn >
constexpr MInt FvBndryCndXD< nDim, SysEqn >::s_sbc1000co_fixedMaxNoBndryCndIds = 10
staticconstexprprotected

Definition at line 501 of file fvcartesianbndrycndxd.h.


The documentation for this class was generated from the following files: