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

#include <fvparticle.h>

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

Public Member Functions

 CouplerFvParticle (const MInt couplingId, LPT< nDim > *particle, FvCartesianSolver *fv)
 
void init () override
 performs the coupling after solver initialization More...
 
void finalizeCouplerInit () override
 
void finalizeSubCoupleInit (MInt) override
 
void preCouple (MInt) override
 preCoupler: reset external source terms before the LPT timestep More...
 
void postCouple (MInt) override
 postCouple: exchange source terms after the LPT timeStep More...
 
void subCouple (MInt, MInt, std::vector< MBool > &) override
 transfer the FV velocity slopes to the LPT solver More...
 
void postAdaptation () override
 
void finalizeAdaptation (const MInt) override
 prepate adaptation More...
 
void prepareAdaptation () override
 prepate adaptation More...
 
void finalizeBalance (const MInt unused) override
 postCouple: exchange source terms after the LPT timeStep More...
 
void balancePre () override
 Load balancing. More...
 
void balancePost () override
 
void cleanUp () override
 
void writeRestartFile (const MInt) override
 
MInt noCouplingTimers (const MBool NotUsed(allTimings)) const override
 Number of coupling timers. More...
 
void getCouplingTimings (std::vector< std::pair< MString, MFloat > > &timings, const MBool NotUsed(allTimings)) override
 
- Public Member Functions inherited from CouplingLpt< nDim, CouplingFv< nDim, SysEqn > >
 CouplingLpt (const MInt couplingId, Lpt *particle, FlowSolver *flowSolver)
 
virtual ~CouplingLpt ()=default
 
- Public Member Functions inherited from CouplingParticle< nDim >
 CouplingParticle (const MInt couplingId, LPT< nDim > *solver)
 
- Public Member Functions inherited from Coupling
 Coupling (const MInt couplingId)
 
virtual ~Coupling ()=default
 
 Coupling (const Coupling &)=delete
 
Couplingoperator= (const Coupling &)=delete
 
MInt couplerId () const
 
virtual void init ()=0
 
virtual void finalizeSubCoupleInit (MInt solverId)=0
 
virtual void finalizeCouplerInit ()=0
 
virtual void preCouple (MInt recipeStep)=0
 
virtual void subCouple (MInt recipeStep, MInt solverId, std::vector< MBool > &solverCompleted)=0
 
virtual void postCouple (MInt recipeStep)=0
 
virtual void cleanUp ()=0
 
virtual void balancePre ()
 Load balancing. More...
 
virtual void balancePost ()
 
virtual void reinitAfterBalance ()
 
virtual void prepareAdaptation ()
 
virtual void postAdaptation ()
 
virtual void finalizeAdaptation (const MInt)
 
virtual void writeRestartFile (const MInt)
 
virtual MInt noCellDataDlb () const
 Methods to inquire coupler data during balancing. More...
 
virtual MInt cellDataTypeDlb (const MInt NotUsed(dataId)) const
 
virtual MInt cellDataSizeDlb (const MInt NotUsed(dataId), const MInt NotUsed(cellId))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MInt *const NotUsed(data))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MLong *const NotUsed(data))
 
virtual void getCellDataDlb (const MInt NotUsed(dataId), const MInt NotUsed(oldNoCells), const MInt *const NotUsed(bufferIdToCellId), MFloat *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MInt *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MLong *const NotUsed(data))
 
virtual void setCellDataDlb (const MInt NotUsed(dataId), const MFloat *const NotUsed(data))
 
virtual void finalizeBalance (const MInt)
 
virtual MInt noCouplingTimers (const MBool NotUsed(allTimings)) const
 Number of coupling timers. More...
 
virtual void getCouplingTimings (std::vector< std::pair< MString, MFloat > > &NotUsed(timings), const MBool NotUsed(allTimings))
 Return coupling timings. More...
 
virtual void getDomainDecompositionInformation (std::vector< std::pair< MString, MInt > > &NotUsed(domainInfo))
 Return information on current domain decomposition (e.g. number of coupled cells/elements/...) More...
 
void setDlbTimer (const MInt timerId)
 
void startLoadTimer (const MString &name) const
 Start the load timer of the coupler. More...
 
void stopLoadTimer (const MString &name) const
 Stop the load timer of the coupler. More...
 
- Public Member Functions inherited from CouplingFv< nDim, SysEqn >
 CouplingFv (const MInt couplingId, std::vector< FvCartesianSolverXD< nDim, SysEqn > * > fvSolvers, const MInt noSolvers)
 
 CouplingFv (const MInt couplingId, Solver *solvers)
 
 ~CouplingFv () override=default
 
 CouplingFv (const CouplingFv &)=delete
 
CouplingFvoperator= (const CouplingFv &)=delete
 

Protected Member Functions

LPT< nDim > & lpt () const override
 
FvCartesianSolverXD< nDim, SysEqn > & fvSolver () const
 
virtual LPT< nDim > & lpt () const
 
- Protected Member Functions inherited from Coupling
MFloat returnLoadRecord () const
 
MFloat returnIdleRecord () const
 
- Protected Member Functions inherited from CouplingFv< nDim, SysEqn >
MInt noSolvers () const
 
solverTypefvSolver (const MInt solverId=0) const
 
MInt a_noFvCells () const
 
MInt a_noFvGridCells () const
 

Private Types

using FvCartesianSolver = FvCartesianSolverXD< nDim, SysEqn >
 
using BaseFv = CouplingFv< nDim, SysEqn >
 
using BaseLpt = CouplingParticle< nDim >
 
using BaseLptX = CouplingLpt< nDim, BaseFv >
 

Private Member Functions

void checkProperties () override
 Checks property-data which is read in by both lpt-and Fv-Solver. More...
 
void readProperties ()
 
void initData ()
 Initialize coupling-class-specific Data. More...
 
void initConversion ()
 Calculates the conversion factor for different non-dimensionalisations in the FV and LPT solvers. More...
 
void initParticleVelocity ()
 Sets the initial particle velocity based on the flow field velocity in that cell. NOTE: This can not be done in the LPT initialCondition, as the FV flow field has not been transfered before, its set in the FV initialCondition. More...
 
void transferNoParticlesInCell ()
 set a_noPart in Fv based on a_noParticlesInCell and a_noEllipsoidsInCell in LPT solver NOTE: this is only necessary if the particle sensor is used during adaptation More...
 
void writeParticleCellStats ()
 compute particle-cell binning and write to file More...
 
void transferExternalSources ()
 set external sources in Fv solver based on values in the LPT solver More...
 
void updateLPTBndry ()
 transfer all relevant bndryCell-data from FV to LPT solver before the LPT timeStep! More...
 
void transferFlowField ()
 transfer flow data from FV to LPT More...
 
void transferCellStatus ()
 set the isValid status for LPT cells based on the FV-solver cell properties More...
 
void transferVelocitySlopes ()
 transfer the FV velocity slopes to the LPT solver More...
 
void transferTimeStep ()
 transfer/enforce Fv timeStep onto LPT solver More...
 
void setExternalSourceInCell (const MInt, const MInt, const MFloat)
 set external source in FV-solver from LPT fluxes More...
 
void unifyTimeStep ()
 Find combinded maximum timeStep for Fv and LPT solvers only possible for interleafed execution assuming that both solvers have previously computed their independend timeSteps. More...
 
MInt childLoop (MInt cellId)
 compute particle-cell binning and write to file More...
 
MInt lpt2fvId (const MInt lptId)
 
MInt lpt2fvIdParent (const MInt lptId)
 
MInt fv2lptId (const MInt fvId)
 
MInt fv2lptIdParent (const MInt fvId)
 
void interpolateFVLPT (const MInt from, const MInt to)
 interpolate flow variables from the fv-grid to the LPT-cell position More...
 
void interpolateVelocitySlopesFVLPT (const MInt from, const MInt to)
 Interpolates the velocity slopes from the fv-grid to the LPT-cell. More...
 
MFloat interpolateVariable (MInt *, MFloat *, MInt)
 interpolates the fv-variable / More...
 
MFloat interpolateSlope (MInt *, MFloat *, MInt, MInt)
 interpolate fv slope More...
 

Private Attributes

ConversionFactor & conversionLptFv = BaseLptX::conversionLptFlow
 
ConversionFactor & conversionFvLpt = BaseLptX::conversionFlowLpt
 
LPT< nDim > * m_particle = nullptr
 
FvCartesianSolverXD< nDim, SysEqn > * m_fvSolver = nullptr
 
MInt m_lptSolverId {}
 
MInt m_fvSolverId {}
 
MInt m_lptSolverOrder {}
 
MInt m_fvSolverOrder {}
 
MInt m_noSolverSteps {}
 
MBool m_lptFvInterpolation = false
 
MInt m_fvLPTSpeciesId {}
 
SysEqn m_sysEqn
 
MInt m_solutionStep
 
MInt m_noSolutionSteps
 
MBool m_forceFvTimeStep
 
MBool m_interLeafed
 

Friends

class LPT< nDim >
 
class FvCartesianSolverXD< nDim, SysEqn >
 

Additional Inherited Members

- Public Types inherited from CouplingLpt< nDim, CouplingFv< nDim, SysEqn > >
using FlowSolver = typename CouplingFlowSolver::solverType
 
using Lpt = typename CouplingParticle< nDim >::solverType
 
- Public Types inherited from CouplingParticle< nDim >
using solverType = LPT< nDim >
 
- Public Types inherited from CouplingFv< nDim, SysEqn >
using solverType = FvCartesianSolverXD< nDim, SysEqn >
 
- Public Attributes inherited from CouplingLpt< nDim, CouplingFv< nDim, SysEqn > >
ConversionFactor conversionFlowLpt
 
ConversionFactor conversionLptFlow
 
- Protected Attributes inherited from CouplingFv< nDim, SysEqn >
std::vector< solverType * > m_fvSolvers {}
 

Detailed Description

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

Definition at line 21 of file fvparticle.h.

Member Typedef Documentation

◆ BaseFv

template<MInt nDim, class SysEqn >
using CouplerFvParticle< nDim, SysEqn >::BaseFv = CouplingFv<nDim, SysEqn>
private

Definition at line 28 of file fvparticle.h.

◆ BaseLpt

template<MInt nDim, class SysEqn >
using CouplerFvParticle< nDim, SysEqn >::BaseLpt = CouplingParticle<nDim>
private

Definition at line 29 of file fvparticle.h.

◆ BaseLptX

template<MInt nDim, class SysEqn >
using CouplerFvParticle< nDim, SysEqn >::BaseLptX = CouplingLpt<nDim, BaseFv>
private

Definition at line 30 of file fvparticle.h.

◆ FvCartesianSolver

template<MInt nDim, class SysEqn >
using CouplerFvParticle< nDim, SysEqn >::FvCartesianSolver = FvCartesianSolverXD<nDim, SysEqn>
private

Definition at line 26 of file fvparticle.h.

Constructor & Destructor Documentation

◆ CouplerFvParticle()

template<MInt nDim, class SysEqn >
CouplerFvParticle< nDim, SysEqn >::CouplerFvParticle ( const MInt  couplingId,
LPT< nDim > *  particle,
FvCartesianSolver fv 
)

Definition at line 14 of file fvparticle.cpp.

15 : Coupling(couplingId), CouplingLpt<nDim, CouplingFv<nDim, SysEqn>>(couplingId, particle, fv), m_sysEqn(1, 0) {
16 TRACE();
17
18 m_particle = particle;
19 m_fvSolver = fv;
20
21 // get LPT-solver order
23 m_noSolverSteps = Context::getBasicProperty<MInt>("recipeMaxNoSteps", AT_, &m_noSolverSteps);
24
25 const MString propNameLpt = "solverOrder_" + std::to_string(lpt().solverId());
26 const MString propNameFv = "solverOrder_" + std::to_string(fvSolver().solverId());
27
28 for(MInt step = 0; step < m_noSolverSteps; step++) {
29 if(Context::getBasicProperty<MInt>(propNameLpt, AT_, step) > 0) {
30 m_lptSolverOrder = step;
31 }
32 if(Context::getBasicProperty<MInt>(propNameFv, AT_, step) > 0) {
33 m_fvSolverOrder = step;
34 }
35 }
36
37 m_interLeafed = false;
39
41 m_interLeafed = true;
43 lpt().m_noSolutionSteps = 5;
44 if(lpt().domainId() == 0) {
45 cerr << "Interleafed Fv - LPT execution at step " << m_lptSolverOrder << endl;
46 }
47 }
48
49 initData();
50}
FvCartesianSolverXD< nDim, SysEqn > & fvSolver() const
Definition: fvparticle.h:48
LPT< nDim > * m_particle
Definition: fvparticle.h:116
LPT< nDim > & lpt() const override
Definition: fvparticle.h:47
FvCartesianSolverXD< nDim, SysEqn > * m_fvSolver
Definition: fvparticle.h:117
void initData()
Initialize coupling-class-specific Data.
Definition: fvparticle.cpp:244
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55

Member Function Documentation

◆ balancePost()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::balancePost ( )
inlineoverridevirtual

Reimplemented from Coupling.

Definition at line 65 of file fvparticle.h.

65{};

◆ balancePre()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::balancePre ( )
inlineoverridevirtual

Reimplemented from Coupling.

Definition at line 64 of file fvparticle.h.

64{};

◆ checkProperties()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::checkProperties
overrideprivatevirtual
Author
Tim Wegmann

Reimplemented from CouplingParticle< nDim >.

Definition at line 338 of file fvparticle.cpp.

338 {
339 TRACE();
340
341 ASSERT(fabs(fvSolver().m_sutherlandConstant - lpt().m_sutherlandConstant) < MFloatEps, "");
342 ASSERT(fabs(lpt().m_sutherlandPlusOne - fvSolver().m_sutherlandPlusOne) < MFloatEps, "");
343 ASSERT(lpt().a_timeStepComputationInterval() == fvSolver().a_timeStepComputationInterval(), "");
344}

◆ childLoop()

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::childLoop ( MInt  cellId)
private
Author
Tim Wegmann

Definition at line 1484 of file fvparticle.cpp.

1484 {
1485 MInt sum = 0;
1486 if(fvSolver().c_noChildren(cellId) > 0) {
1487 for(MInt child = 0; child < fvSolver().c_noChildren(cellId); child++) {
1488 MInt childId = fvSolver().c_childId(cellId, child);
1489 if(childId < 0) {
1490 continue;
1491 }
1492 sum += childLoop(childId);
1493 }
1494 } else {
1495 sum += fvSolver().a_noPart(cellId);
1496 }
1497 return sum;
1498}
MInt childLoop(MInt cellId)
compute particle-cell binning and write to file
MLong c_childId(const MInt cellId, const MInt pos) const
Returns the grid child id of the grid cell cellId at position pos.
MInt & a_noPart(MInt cellId)
Return no particles.
MInt c_noChildren(const MInt cellId) const
Returns the number of children of the cell cellId.

◆ cleanUp()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::cleanUp ( )
inlineoverridevirtual

Reimplemented from CouplingParticle< nDim >.

Definition at line 67 of file fvparticle.h.

67{};

◆ finalizeAdaptation()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::finalizeAdaptation ( const MInt  solverId)
overridevirtual
Author
Tim Wegmann

Reimplemented from Coupling.

Definition at line 930 of file fvparticle.cpp.

930 {
931 TRACE();
932
933 // Post FV solver
934 if(solverId == fvSolver().solverId()) {
938 if(lpt().isActive()) {
939 lpt().receiveFlowField();
940 lpt().receiveVelocitySlopes();
941 lpt().waitForSendReqs();
942 }
943
945
946 } else if(solverId == lpt().solverId()) {
947 // set external sources in the FV-solver
948 // as they are reset there in finalizeAdaptation
949 if(fvSolver().m_hasExternalSource) {
952 }
953 }
954}
void transferVelocitySlopes()
transfer the FV velocity slopes to the LPT solver
void transferCellStatus()
set the isValid status for LPT cells based on the FV-solver cell properties
void updateLPTBndry()
transfer all relevant bndryCell-data from FV to LPT solver before the LPT timeStep!
Definition: fvparticle.cpp:607
void transferFlowField()
transfer flow data from FV to LPT
Definition: fvparticle.cpp:452
void transferExternalSources()
set external sources in Fv solver based on values in the LPT solver
Definition: fvparticle.cpp:736
void resetExternalSources()
Reset external sources.

◆ finalizeBalance()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::finalizeBalance ( const MInt  unused)
overridevirtual
Author
Tim Wegmann

Reimplemented from Coupling.

Definition at line 418 of file fvparticle.cpp.

418 {
419 // post LPT solver
420 if(id == lpt().solverId()) {
421 if(fvSolver().m_hasExternalSource) {
423 }
424 if(globalTimeStep < 0) {
426 } else {
429 }
430
431 } else if(id == fvSolver().solverId()) {
435 if(lpt().isActive()) {
436 lpt().receiveFlowField();
437 lpt().receiveVelocitySlopes();
438 lpt().waitForSendReqs();
439 }
440
442 }
443}
void prepareAdaptation() override
prepate adaptation
Definition: fvparticle.cpp:871
virtual void advanceExternalSource()
MInt globalTimeStep

◆ finalizeCouplerInit()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::finalizeCouplerInit
overridevirtual

Reimplemented from CouplingParticle< nDim >.

Definition at line 255 of file fvparticle.cpp.

255 {
256 TRACE();
257
258 // Transfer the flow field after the intial condition for FV has been applied
262 if(lpt().isActive()) {
263 lpt().receiveFlowField();
264 lpt().receiveVelocitySlopes();
265 lpt().waitForSendReqs();
266 }
267
269
270 if(!lpt().m_restartFile && fvSolver().m_restartFile) {
271 if(lpt().domainId() == 0) {
272 cerr << "Restart without LPT restartFile -> setting time from Fv-time!" << endl;
273 }
274 const MFloat conversionTime = conversionFvLpt.length / conversionFvLpt.velocity;
276 lpt().m_time = fvTime * conversionTime;
277 }
278
279 // set the timeStep in the LPT solver
282 } else {
284 }
285
286 MBool writeParticleStats = false;
287 if(writeParticleStats) {
289 }
290}
void initParticleVelocity()
Sets the initial particle velocity based on the flow field velocity in that cell. NOTE: This can not ...
Definition: fvparticle.cpp:227
void unifyTimeStep()
Find combinded maximum timeStep for Fv and LPT solvers only possible for interleafed execution assumi...
ConversionFactor & conversionFvLpt
Definition: fvparticle.h:40
MBool m_forceFvTimeStep
Definition: fvparticle.h:132
void writeParticleCellStats()
compute particle-cell binning and write to file
void transferTimeStep()
transfer/enforce Fv timeStep onto LPT solver
Definition: fvparticle.cpp:830
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58

◆ finalizeSubCoupleInit()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::finalizeSubCoupleInit ( MInt  )
inlineoverridevirtual

Reimplemented from CouplingParticle< nDim >.

Definition at line 53 of file fvparticle.h.

53{};

◆ fv2lptId()

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::fv2lptId ( const MInt  fvId)
inlineprivate

Definition at line 107 of file fvparticle.h.

107{ return convertId(fvSolver(), lpt(), fvId); };
MInt convertId(SolverA &solverA, SolverB &solverB, const MInt solverAId)
Conversion from solverA id to the solverB id on the same-level only!
Definition: couplingutils.h:21

◆ fv2lptIdParent()

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::fv2lptIdParent ( const MInt  fvId)
inlineprivate

Definition at line 108 of file fvparticle.h.

108{ return convertIdParent(fvSolver(), lpt(), fvId); };
MInt convertIdParent(SolverA &solverA, SolverB &solverB, const MInt solverAId)
Conversion from solverA id to the solverB id If no cell on the same level is found,...
Definition: couplingutils.h:46

◆ fvSolver()

template<MInt nDim, class SysEqn >
FvCartesianSolverXD< nDim, SysEqn > & CouplerFvParticle< nDim, SysEqn >::fvSolver ( ) const
inlineprotected

Definition at line 48 of file fvparticle.h.

48{ return *m_fvSolver; }

◆ getCouplingTimings()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::getCouplingTimings ( std::vector< std::pair< MString, MFloat > > &  timings,
const MBool   NotUsedallTimings 
)
inlineoverride

Definition at line 73 of file fvparticle.h.

73 {
74 const MString namePrefix = "c" + std::to_string(this->couplerId()) + "_";
75
76 timings.emplace_back(namePrefix + "loadCouplerFvParticle", returnLoadRecord());
77 timings.emplace_back(namePrefix + "idleCouplerFvParticle", returnIdleRecord());
78 };
MFloat returnIdleRecord() const
Definition: coupling.h:159
MFloat returnLoadRecord() const
Definition: coupling.h:158
MInt couplerId() const
Definition: coupling.h:67

◆ init()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::init
overridevirtual
Author
Tim Wegmann

Implements Coupling.

Definition at line 56 of file fvparticle.cpp.

56 {
57 TRACE();
58
60
62
63 // check for any in-active ranks
64 MInt noInactiveFv = 0;
65 MInt noInactiveLPT = 0;
66 if(!fvSolver().isActive()) {
67 noInactiveFv++;
68 }
69 if(!lpt().isActive()) {
70 noInactiveLPT++;
71 }
72
73 MPI_Allreduce(MPI_IN_PLACE, &noInactiveFv, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD, AT_, "MPI_IN_PLACE", "noInactiveFv");
74 MPI_Allreduce(MPI_IN_PLACE, &noInactiveLPT, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD, AT_, "MPI_IN_PLACE",
75 "noInactiveLPT");
76 if(noInactiveFv > 0) {
77 cerr0 << "Fv solver has " << noInactiveFv << " inactive ranks!" << endl;
78 }
79 if(noInactiveLPT > 0) {
80 cerr0 << "LPT solver has " << noInactiveLPT << " inactive ranks!" << endl;
81 }
82}
void initConversion()
Calculates the conversion factor for different non-dimensionalisations in the FV and LPT solvers.
void checkProperties() override
Checks property-data which is read in by both lpt-and Fv-Solver.
Definition: fvparticle.cpp:338
std::ostream cerr0
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

◆ initConversion()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::initConversion ( )
private
Author
Tim Wegmann

◆ initData()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::initData
private
Author
Tim Wegmann

Definition at line 244 of file fvparticle.cpp.

244 {
245 TRACE();
246
248 m_lptSolverId = lpt().m_solverId;
249
251}
const MInt m_solverId
a unique solver identifier
Definition: solver.h:90

◆ initParticleVelocity()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::initParticleVelocity
private
Author
Tim Wegmann

Definition at line 227 of file fvparticle.cpp.

227 {
228 if(!lpt().m_restart) {
229 // init fluid density and velocity, after the values have been transferred to the LPT solver!
230 for(MInt i = 0; i < lpt().a_noParticles(); i++) {
231 lpt().m_partList[i].initVelocityAndDensity();
232 }
233 // init fluid density and velocity for ellipsoidal particles
234 for(MInt i = 0; i < lpt().a_noEllipsoidalParticles(); i++) {
235 lpt().m_partListEllipsoid[i].initVelocityAndDensity();
236 }
237 }
238}

◆ interpolateFVLPT()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::interpolateFVLPT ( const MInt  from,
const MInt  to 
)
private
Author
Tim Wegmann
Date
March 2020

Definition at line 962 of file fvparticle.cpp.

962 {
963 TRACE();
964
965 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
966 MFloat point[3] = {lpt().c_coordinate(to, 0), lpt().c_coordinate(to, 1), lpt().c_coordinate(to, 2)};
967
968 std::function<MBool(const MInt, const MInt)> neighborCheck = [&](const MInt cellId, const MInt id) {
969 return static_cast<MBool>(fvSolver().checkNeighborActive(cellId, id));
970 };
971
972 const MInt position = fvSolver().setUpInterpolationStencil(from, interpolationCells, point, neighborCheck, true);
973
974 if(position < 0) {
975 for(MInt n = 0; n < nDim; n++) {
976 lpt().a_fluidVelocity(to, n) =
977 fvSolver().a_pvariable(from, fvSolver().m_sysEqn.PV->VV[n]) * conversionFvLpt.velocity;
978 }
979 lpt().a_fluidDensity(to) = fvSolver().a_pvariable(from, fvSolver().m_sysEqn.PV->RHO) * conversionFvLpt.density;
980 lpt().a_fluidPressure(to) = fvSolver().a_pvariable(from, fvSolver().m_sysEqn.PV->P) * conversionFvLpt.pressure;
981 lpt().a_fluidTemperature(to) =
982 fvSolver().sysEqn().temperature_ES(fvSolver().a_pvariable(from, fvSolver().m_sysEqn.PV->RHO),
983 fvSolver().a_pvariable(from, fvSolver().m_sysEqn.PV->P))
984 * conversionFvLpt.temperature;
985 if(lpt().m_evaporation && fvSolver().m_noSpecies > 0) {
986 lpt().a_fluidSpecies(to) = fvSolver().a_pvariable(from, fvSolver().m_sysEqn.PV->Y[m_fvLPTSpeciesId]);
987 }
988
989 } else {
990 for(MInt n = 0; n < nDim; n++) {
991 lpt().a_fluidVelocity(to, n) =
992 interpolateVariable(interpolationCells, point, fvSolver().m_sysEqn.PV->VV[n]) * conversionFvLpt.velocity;
993 }
994 const MFloat rho = interpolateVariable(interpolationCells, point, fvSolver().m_sysEqn.PV->RHO);
995 const MFloat p = interpolateVariable(interpolationCells, point, fvSolver().m_sysEqn.PV->P);
996 lpt().a_fluidDensity(to) = rho * conversionFvLpt.density;
997 lpt().a_fluidPressure(to) = p * conversionFvLpt.pressure;
998 lpt().a_fluidTemperature(to) = fvSolver().sysEqn().temperature_ES(rho, p) * conversionFvLpt.temperature;
999 if(lpt().m_evaporation && fvSolver().m_noSpecies > 0) {
1000 lpt().a_fluidSpecies(to) =
1001 interpolateVariable(interpolationCells, point, fvSolver().m_sysEqn.PV->Y[m_fvLPTSpeciesId]);
1002 }
1003 }
1004}
MFloat interpolateVariable(MInt *, MFloat *, MInt)
interpolates the fv-variable /
MFloat & a_pvariable(const MInt cellId, const MInt varId)
Returns primitive variable v of the cell cellId for variables varId.
MBool checkNeighborActive(const MInt cellId, const MInt dir) const
Cecks wether the cell cellId has a valid neighbor in direction dir.
MInt setUpInterpolationStencil(const MInt cellId, MInt *, const MFloat *, std::function< MBool(MInt, MInt)>, MBool allowIncompleteStencil)
MInt id
Definition: maiatypes.h:71
void const MInt cellId
Definition: collector.h:239
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.

◆ interpolateSlope()

template<MInt nDim, class SysEqn >
MFloat CouplerFvParticle< nDim, SysEqn >::interpolateSlope ( MInt interpolationCells,
MFloat point,
MInt  v,
MInt  dir 
)
private
Author
Laurent Andre
Date
August 2022

Definition at line 1067 of file fvparticle.cpp.

1067 {
1068 TRACE();
1069
1070 std::function<MFloat(const MInt, const MInt)> scalarField = [&](const MInt cellId, const MInt varId) {
1071 return static_cast<MFloat>(*(&fvSolver().a_slope(cellId, 0, 0) + varId));
1072 };
1073
1074 std::function<MFloat(const MInt, const MInt)> coordinate = [&](const MInt cellId, const MInt id) {
1075 return static_cast<MFloat>(fvSolver().a_coordinate(cellId, id));
1076 };
1077
1078 MInt valIndex = v * nDim + dir;
1079 return fvSolver().template interpolateFieldData<false>(&interpolationCells[0], &point[0], valIndex, scalarField,
1080 coordinate);
1081}
MFloat & a_slope(const MInt cellId, MInt const varId, const MInt dir) override
Returns the slope of the cell cellId for the variable varId in direction dir.
MFloat & a_coordinate(const MInt cellId, const MInt dir)
Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir.

◆ interpolateVariable()

template<MInt nDim, class SysEqn >
MFloat CouplerFvParticle< nDim, SysEqn >::interpolateVariable ( MInt interpolationCells,
MFloat point,
MInt  v 
)
private
Author
Tim Wegmann /
Date
2020-04-01

Definition at line 1047 of file fvparticle.cpp.

1047 {
1048 TRACE();
1049
1050 std::function<MFloat(const MInt, const MInt)> scalarField = [&](const MInt cellId, const MInt varId) {
1051 return static_cast<MFloat>(fvSolver().a_pvariable(cellId, varId));
1052 };
1053
1054 std::function<MFloat(const MInt, const MInt)> coordinate = [&](const MInt cellId, const MInt id) {
1055 return static_cast<MFloat>(fvSolver().a_coordinate(cellId, id));
1056 };
1057
1058 return fvSolver().template interpolateFieldData<false>(&interpolationCells[0], &point[0], v, scalarField, coordinate);
1059}

◆ interpolateVelocitySlopesFVLPT()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::interpolateVelocitySlopesFVLPT ( const MInt  from,
const MInt  to 
)
private
Author
Laurent Andre
Date
August 2022

Definition at line 1012 of file fvparticle.cpp.

1012 {
1013 TRACE();
1014
1015 MInt interpolationCells[8] = {0, 0, 0, 0, 0, 0, 0, 0};
1016 MFloat point[3] = {lpt().c_coordinate(to, 0), lpt().c_coordinate(to, 1), lpt().c_coordinate(to, 2)};
1017
1018 std::function<MBool(const MInt, const MInt)> neighborCheck = [&](const MInt cellId, const MInt id) {
1019 return static_cast<MBool>(fvSolver().checkNeighborActive(cellId, id));
1020 };
1021
1022 const MInt position = fvSolver().setUpInterpolationStencil(from, interpolationCells, point, neighborCheck, true);
1023
1024 if(position < 0) {
1025 for(MInt varId = 0; varId < nDim; varId++) {
1026 for(MInt dir = 0; dir < nDim; dir++) {
1027 lpt().a_velocitySlope(to, varId, dir) =
1028 fvSolver().a_slope(from, fvSolver().m_sysEqn.PV->VV[varId], dir) * conversionFvLpt.velocitySlope;
1029 }
1030 }
1031 } else {
1032 for(MInt varId = 0; varId < nDim; varId++) {
1033 for(MInt dir = 0; dir < nDim; dir++) {
1034 lpt().a_velocitySlope(to, varId, dir) =
1035 interpolateSlope(interpolationCells, point, fvSolver().m_sysEqn.PV->VV[varId], dir)
1036 * conversionFvLpt.velocitySlope;
1037 }
1038 }
1039 }
1040}
MFloat interpolateSlope(MInt *, MFloat *, MInt, MInt)
interpolate fv slope

◆ lpt()

template<MInt nDim, class SysEqn >
LPT< nDim > & CouplerFvParticle< nDim, SysEqn >::lpt ( ) const
inlineoverrideprotectedvirtual

Reimplemented from CouplingParticle< nDim >.

Definition at line 47 of file fvparticle.h.

47{ return *m_particle; }

◆ lpt2fvId()

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::lpt2fvId ( const MInt  lptId)
inlineprivate

Definition at line 105 of file fvparticle.h.

105{ return convertId(lpt(), fvSolver(), lptId); };

◆ lpt2fvIdParent()

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::lpt2fvIdParent ( const MInt  lptId)
inlineprivate

Definition at line 106 of file fvparticle.h.

106{ return convertIdParent(lpt(), fvSolver(), lptId); };

◆ noCouplingTimers()

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::noCouplingTimers ( const MBool   NotUsedallTimings) const
inlineoverridevirtual

Reimplemented from Coupling.

Definition at line 71 of file fvparticle.h.

71{ return 2; }

◆ postAdaptation()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::postAdaptation ( )
inlineoverridevirtual

Reimplemented from Coupling.

Definition at line 59 of file fvparticle.h.

59{};

◆ postCouple()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::postCouple ( MInt  recipeStep)
overridevirtual
Author
Tim Wegmann

Reimplemented from CouplingParticle< nDim >.

Definition at line 382 of file fvparticle.cpp.

382 {
383 // when using inter-leafed application, external sources and flow field are transfered in the subCouple!
384 if(m_interLeafed) {
385 if(recipeStep == m_fvSolverOrder) {
386 transferVelocitySlopes(); // transfer only after postTimestep
387 }
388 return;
389 }
390
391 // Post LPT (as the LPT-solver is called before the Fv-solver!)
392 if(recipeStep == m_lptSolverOrder) {
393 // reset and transfer external Sources to FV-solver
394 if(fvSolver().m_hasExternalSource) {
398 }
399 }
400
401 // POST FV
402 if(recipeStep == m_fvSolverOrder) {
405 if(lpt().isActive()) {
406 lpt().receiveFlowField();
407 lpt().receiveVelocitySlopes();
408 lpt().waitForSendReqs();
409 }
411 }
412}
virtual void applyExternalOldSource()

◆ preCouple()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::preCouple ( MInt  recipeStep)
overridevirtual
Author
Tim Wegmann

Reimplemented from CouplingParticle< nDim >.

Definition at line 350 of file fvparticle.cpp.

350 {
351 TRACE();
352
353 // PRE LPT
354 if(recipeStep == m_lptSolverOrder) {
355 m_solutionStep = 0;
356
357 // TODO-timw labels:COUPLER,FV,toenhance,totest check if this can be avoided when transfering variables at some
358 // other stage!
359 // when removed, testcase results are changed slightly!
361
362 // update LPT bndryCells for wall-collision
365
366
367 if(m_interLeafed) {
368 const MFloat conversionTime = conversionFvLpt.length / conversionFvLpt.velocity;
370 if(lpt().isActive() && fabs(fvTime * conversionTime - lpt().m_time) > MFloatEps) {
371 cerr << "LPT-time " << lpt().m_time << " Fv-time " << fvTime << endl;
372 mTerm(1, AT_, "Miss-matching time!");
373 }
374 }
375 }
376}
virtual void computeConservativeVariables()
Dispatches the computation of the conservative variables for different number of species.
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29

◆ prepareAdaptation()

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

Reimplemented from Coupling.

Definition at line 871 of file fvparticle.cpp.

871 {
872 TRACE();
873
874 // transfer the number of particles for the particle limit sensor!
876}
void transferNoParticlesInCell()
set a_noPart in Fv based on a_noParticlesInCell and a_noEllipsoidsInCell in LPT solver NOTE: this is ...
Definition: fvparticle.cpp:692

◆ readProperties()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::readProperties ( )
privatevirtual

Reimplemented from CouplingParticle< nDim >.

◆ setExternalSourceInCell()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::setExternalSourceInCell ( const MInt  fvCellId,
const MInt  lptCell,
const MFloat  factor 
)
private
Author
Tim Wegmann

Definition at line 882 of file fvparticle.cpp.

884 {
885 TRACE();
886
887 if(factor < 0) {
888 if(lpt().m_momentumCoupling) {
889 for(MInt i = 0; i < nDim; i++) {
890 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_VV[i]) +=
891 lpt().a_momentumFlux(lptCell, i) / conversionFvLpt.momentum;
892 }
893 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_E) += lpt().a_workFlux(lptCell) / conversionFvLpt.energy;
894 }
895 if(lpt().m_heatCoupling) {
896 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_E) += lpt().a_heatFlux(lptCell) / conversionFvLpt.energy;
897 }
898 if(lpt().m_massCoupling) {
899 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO) += lpt().a_massFlux(lptCell) / conversionFvLpt.mass;
900 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_Y[m_fvLPTSpeciesId]) +=
901 lpt().a_massFlux(lptCell) / conversionFvLpt.mass;
902 }
903 } else {
904 if(lpt().m_momentumCoupling) {
905 for(MInt i = 0; i < nDim; i++) {
906 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_VV[i]) +=
907 lpt().a_momentumFlux(lptCell, i) * factor / conversionFvLpt.momentum;
908 }
909 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_E) +=
910 lpt().a_workFlux(lptCell) * factor / conversionFvLpt.energy;
911 }
912 if(lpt().m_heatCoupling) {
913 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_E) +=
914 lpt().a_heatFlux(lptCell) * factor / conversionFvLpt.energy;
915 }
916 if(lpt().m_massCoupling) {
917 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO) +=
918 lpt().a_massFlux(lptCell) * factor / conversionFvLpt.mass;
919
920 fvSolver().a_externalSource(fvCellId, fvSolver().CV->RHO_Y[m_fvLPTSpeciesId]) +=
921 lpt().a_massFlux(lptCell) * factor / conversionFvLpt.mass;
922 }
923 }
924}
MFloat & a_externalSource(MInt cellId, MInt var)
Return external source.

◆ subCouple()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::subCouple ( MInt  recipeStep,
MInt  solverId,
std::vector< MBool > &   
)
overridevirtual
Author
Tim Wegmann

Reimplemented from CouplingParticle< nDim >.

Definition at line 1298 of file fvparticle.cpp.

1299 {
1300 if(!m_interLeafed) return;
1301
1302 if(fvSolver().isActive() && lpt().isActive()) {
1303 if(globalTimeStep % lpt().a_timeStepComputationInterval() != 0
1304 && fabs(lpt().m_timeStep - fvSolver().timeStep()) > MFloatEps) {
1305 mTerm(1, AT_, "TimeSteps of FV and LPT differ at TS " + to_string(globalTimeStep));
1306 }
1307 }
1308
1309 // only during FV-Lpt computation
1310 if(recipeStep == m_lptSolverOrder && (solverId == m_fvSolverId || solverId == m_lptSolverId)) {
1312
1313 // meaning after the 4th LPT solution step!
1314 if(m_solutionStep == 2 * m_noSolutionSteps - 3) {
1315 if(solverId == m_lptSolverId) {
1316 // set the source-terms before the last FV-Solution(=RK) Step
1317 // and before the 4th RK step for FvMb
1318
1319 if(fvSolver().m_hasExternalSource && !lpt().m_skipLPT) {
1322 } else if(lpt().m_skipLPT) {
1323 vector<MFloat> tmp(2 + nDim);
1324 for(MInt j = 0; j < (2 + nDim); j++) {
1325 tmp[j] = 0.0;
1326 }
1327 fvSolver().m_vapourData.insert(make_pair(globalTimeStep, tmp));
1328 }
1329 }
1330 }
1331
1332 if(m_solutionStep == 2 * m_noSolutionSteps - 2 && !lpt().m_skipLPT) {
1333 if(fvSolver().m_hasExternalSource) {
1335 }
1336 }
1337
1338 // meaning after the last RK-step!
1340 if(solverId == m_fvSolverId && !lpt().m_skipLPT) {
1341 // after the last FV-solution step!
1343 }
1344 }
1345
1346 if(m_solutionStep == 2 * m_noSolutionSteps && (fvSolver().m_timeStepUpdated || lpt().m_timeStepUpdated)) {
1347 if(!m_forceFvTimeStep) {
1348 unifyTimeStep();
1349 } else {
1351 }
1352 }
1353 }
1354}
std::map< MInt, std::vector< MFloat > > m_vapourData

◆ transferCellStatus()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::transferCellStatus
private
Author
Tim Wegmann

Definition at line 1087 of file fvparticle.cpp.

1087 {
1088 for(MInt lptCellId = 0; lptCellId < lpt().a_noCells(); lptCellId++) {
1089 MInt fvCellId = lpt2fvIdParent(lptCellId);
1090 if(fvCellId < 0 || fvCellId > fvSolver().a_noCells()) {
1091 lpt().a_isValidCell(lptCellId) = false;
1092 } else if(fvSolver().a_hasProperty(fvCellId, FvCell::IsCutOff) && !lpt().grid().isPeriodic(lptCellId)) {
1093 lpt().a_isValidCell(lptCellId) = false;
1094 } else if(fvSolver().a_hasProperty(fvCellId, FvCell::IsInSpongeLayer)) {
1095 lpt().a_isValidCell(lptCellId) = false;
1096 } else if(fvSolver().a_isInactive(fvCellId)) {
1097 lpt().a_isValidCell(lptCellId) = false;
1098 } else {
1099 lpt().a_isValidCell(lptCellId) = true;
1100 }
1101 }
1102}
MInt lpt2fvIdParent(const MInt lptId)
Definition: fvparticle.h:106

◆ transferExternalSources()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::transferExternalSources
private
Author
Tim Wegmann

Definition at line 736 of file fvparticle.cpp.

736 {
737 TRACE();
738
739 if(!fvSolver().isActive()) return;
740
741 if(!lpt().m_momentumCoupling && !lpt().m_heatCoupling && !lpt().m_massCoupling) return;
742
743 if(lpt().isActive()) lpt().exchangeSourceTerms();
744
745#ifndef NDEBUG
746 // check that externalSource is set to zero!
747 for(MInt cellId = 0; cellId < fvSolver().a_noCells(); cellId++) {
748 for(MInt var = 0; var < fvSolver().CV->noVariables; var++) {
749 // NOTE: only valid for single particle coupling!
750 // ASSERT(abs(fvSolver().a_externalSource(cellId, var)) < MFloatEps, "");
751 if(abs(fvSolver().a_externalSource(cellId, var)) > MFloatEps) {
752 mTerm(1, AT_, "External Source not reset correctly!!");
753 }
754 }
755 }
756#endif
757
758 for(MInt lptCell = 0; lptCell < lpt().noInternalCells(); lptCell++) {
759 // the source term is only set on LPT leaf-cells
760 if(!lpt().c_isLeafCell(lptCell)) continue;
761 MInt fvCellId = lpt2fvId(lptCell);
762 if(fvCellId > -1 && fvSolver().c_isLeafCell(fvCellId)) {
763 // simple transfer
764 setExternalSourceInCell(fvCellId, lptCell, -1);
765
766 } else if(fvCellId > -1 && !fvSolver().c_isLeafCell(fvCellId)) {
767 // fv-cell is refined further: volume average from LPT to FV
768 // gather all fv-leaf-cell children for internal cells
769 vector<MInt> leafChildIds;
770 fvSolver().grid().getAllLeafChilds(fvCellId, leafChildIds);
771 MFloat totalVol = 0;
772 for(MUint i = 0; i < leafChildIds.size(); i++) {
773 const MInt cellId = leafChildIds[i];
774 totalVol += fvSolver().a_cellVolume(cellId);
775 }
776 for(MUint i = 0; i < leafChildIds.size(); i++) {
777 const MInt cellId = leafChildIds[i];
778 const MFloat vFrac = fvSolver().a_cellVolume(cellId) / totalVol;
779 setExternalSourceInCell(cellId, lptCell, vFrac);
780 }
781 } else {
782 // lpt-Cell is refined further
783 fvCellId = lpt2fvIdParent(lptCell);
784 if(fvCellId < 0) continue;
785 setExternalSourceInCell(fvCellId, lptCell, -1);
786 }
787 }
788
789 // count source-terms in the fv-solver:
790 MInt numVars = 2 + nDim;
791 MFloatScratchSpace conservativeSums(numVars, AT_, "conservativeSums");
792 conservativeSums.fill(0.0);
793 const MFloat dt = fvSolver().timeStep();
794 for(MInt cellId = 0; cellId < fvSolver().noInternalCells(); cellId++) {
795 if(!fvSolver().c_isLeafCell(cellId)) continue;
796 if(fvSolver().a_isInactive(cellId)) continue;
797
798 if(fvSolver().m_noSpecies > 0) {
799 conservativeSums[0] -= dt * fvSolver().a_externalSource(cellId, fvSolver().CV->RHO_Y[m_fvLPTSpeciesId]);
800 }
801 conservativeSums[1] -= dt * fvSolver().a_externalSource(cellId, fvSolver().CV->RHO_E);
802 for(MInt i = 0; i < nDim; i++) {
803 conservativeSums[2 + i] -= dt * fvSolver().a_externalSource(cellId, fvSolver().CV->RHO_VV[i]);
804 }
805 }
806
807 if(fvSolver().m_vapourData.size() > 0) {
808 auto it = fvSolver().m_vapourData.find(globalTimeStep - 1);
809 if(it != fvSolver().m_vapourData.end()) {
810 for(MInt i = 0; i < numVars; i++) {
811 MFloat lastSource = (it->second)[i];
812 conservativeSums[i] += lastSource;
813 }
814 }
815 }
816
817 vector<MFloat> tmp(numVars);
818 for(MInt j = 0; j < numVars; j++) {
819 tmp[j] = conservativeSums[j];
820 }
821
822 fvSolver().m_vapourData.insert(make_pair(globalTimeStep, tmp));
823}
MInt lpt2fvId(const MInt lptId)
Definition: fvparticle.h:105
void setExternalSourceInCell(const MInt, const MInt, const MFloat)
set external source in FV-solver from LPT fluxes
Definition: fvparticle.cpp:882
MBool a_isInactive(const MInt cellId) const
MInt noInternalCells() const override
Return the number of internal cells within this solver.
SysEqn::ConservativeVariables * CV
MInt a_noCells() const
Returns the number of cells.
MBool c_isLeafCell(const MInt cellId) const
MFloat & a_cellVolume(const MInt cellId)
Returns the cell volume of the cell from the fvcellcollector cellId.
MFloat timeStep(MBool canSolver=false) noexcept
This class is a ScratchSpace.
Definition: scratch.h:758
constexpr GridProxy & grid() const
uint32_t MUint
Definition: maiatypes.h:63

◆ transferFlowField()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::transferFlowField
private

NOTE: each LPT-cell must have at-least a matching FV-parent!

Author
Julian Vorspohl, Tim Wegmann

Definition at line 452 of file fvparticle.cpp.

452 {
453 TRACE();
454
455#ifndef NDEBUG
456 MBool diverged = false;
457#endif
458
459 for(MInt lptCellId = 0; lptCellId < lpt().noInternalCells(); lptCellId++) {
460 if(!lpt().c_isLeafCell(lptCellId)) continue;
461 MInt fvCellId = lpt2fvId(lptCellId);
462 if(fvCellId > -1 && fvSolver().c_isLeafCell(fvCellId)) {
463 // simple transfer if both cells are leaf-cells
464 for(MInt n = 0; n < nDim; n++) {
465 lpt().a_fluidVelocity(lptCellId, n) =
466 fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->VV[n]) * conversionFvLpt.velocity;
467 }
468 lpt().a_fluidDensity(lptCellId) =
469 fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->RHO) * conversionFvLpt.density;
470 lpt().a_fluidPressure(lptCellId) =
471 fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->P) * conversionFvLpt.pressure;
472#ifndef NDEBUG
473 if(std::isnan(lpt().a_fluidPressure(lptCellId)) && lpt().a_isValidCell(lptCellId)) {
474 diverged = true;
475 cerr << "Nan pressure " << lpt().a_fluidPressure(lptCellId) << " " << lpt().a_coordinate(lptCellId, 0) << " "
476 << lpt().a_coordinate(lptCellId, 1) << " " << lpt().a_coordinate(lptCellId, nDim - 1) << endl;
477 // mTerm(1, AT_, "Nan pressure detected!");
478 }
479#endif
480 lpt().a_fluidTemperature(lptCellId) =
481 fvSolver().sysEqn().temperature_ES(fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->RHO),
482 fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->P))
483 * conversionFvLpt.temperature;
484 if(lpt().m_evaporation && fvSolver().m_noSpecies > 0) {
485 lpt().a_fluidSpecies(lptCellId) =
486 mMax(0.0, mMin(1.0, fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->Y[m_fvLPTSpeciesId])));
487 }
488
489 } else if(fvCellId > -1 && !fvSolver().c_isLeafCell(fvCellId)) {
490 // interpolate from FV-leaf childs if the matching fv-Cell is not a leaf cell
491 if(lpt().a_isHalo(lptCellId)) continue;
492 // gather all fv-leaf-cell childs for internal cells
493 vector<MInt> leafChildIds;
494 fvSolver().grid().getAllLeafChilds(fvCellId, leafChildIds);
495 ASSERT(!leafChildIds.empty(), "");
496
497 // reset variables
498 for(MInt n = 0; n < nDim; n++) {
499 lpt().a_fluidVelocity(lptCellId, n) = 0;
500 }
501 lpt().a_fluidDensity(lptCellId) = 0;
502 lpt().a_fluidPressure(lptCellId) = 0;
503 lpt().a_fluidTemperature(lptCellId) = 0;
504 if(lpt().m_evaporation) {
505 lpt().a_fluidSpecies(lptCellId) = 0;
506 }
507 // interpolate variables by volume
508 MFloat volume = 0;
509 for(MUint i = 0; i < leafChildIds.size(); i++) {
510 const MInt cellId = leafChildIds[i];
511 if(fvSolver().a_isInactive(cellId)) continue;
512 const MFloat cellVolume = fvSolver().a_cellVolume(cellId);
513 ASSERT(fvSolver().c_isLeafCell(cellId), "");
514 // ASSERT(cellVolume > 0, "");
515 if(cellVolume < 1e-16) {
516 mTerm(1, AT_, "Invalid cell-volume!");
517 }
518 volume += cellVolume;
519 for(MInt n = 0; n < nDim; n++) {
520 lpt().a_fluidVelocity(lptCellId, n) +=
521 cellVolume * fvSolver().a_pvariable(cellId, fvSolver().m_sysEqn.PV->VV[n]);
522 }
523 lpt().a_fluidDensity(lptCellId) += cellVolume * fvSolver().a_pvariable(cellId, fvSolver().m_sysEqn.PV->RHO);
524 lpt().a_fluidPressure(lptCellId) += cellVolume * fvSolver().a_pvariable(cellId, fvSolver().m_sysEqn.PV->P);
525 lpt().a_fluidTemperature(lptCellId) +=
526 cellVolume
527 * fvSolver().sysEqn().temperature_ES(fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->RHO),
528 fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->P));
529 if(lpt().m_evaporation && fvSolver().m_noSpecies > 0) {
530 lpt().a_fluidSpecies(lptCellId) += mMax(
531 0.0,
532 mMin(1.0, cellVolume * fvSolver().a_pvariable(fvCellId, fvSolver().m_sysEqn.PV->Y[m_fvLPTSpeciesId])));
533 }
534 }
535
536 if(volume > 1e-16) {
537 // meaning at least one child is active
538 for(MInt n = 0; n < nDim; n++) {
539 lpt().a_fluidVelocity(lptCellId, n) *= conversionFvLpt.velocity / volume;
540 }
541 lpt().a_fluidDensity(lptCellId) *= conversionFvLpt.density / volume;
542 lpt().a_fluidPressure(lptCellId) *= conversionFvLpt.pressure / volume;
543 lpt().a_fluidTemperature(lptCellId) *= conversionFvLpt.temperature / volume;
544 if(lpt().m_evaporation && fvSolver().m_noSpecies > 0) {
545 lpt().a_fluidSpecies(lptCellId) *= 1 / volume;
546 }
547 } else {
548 // meaning completely outside
549 for(MInt n = 0; n < nDim; n++) {
550 lpt().a_fluidVelocity(lptCellId, n) = conversionFvLpt.velocity;
551 }
552 lpt().a_fluidDensity(lptCellId) = conversionFvLpt.density;
553 lpt().a_fluidPressure(lptCellId) = conversionFvLpt.pressure;
554 lpt().a_fluidTemperature(lptCellId) = conversionFvLpt.temperature;
555 if(lpt().m_evaporation && fvSolver().m_noSpecies > 0) {
556 lpt().a_fluidSpecies(lptCellId) = 1;
557 }
558 }
559 } else if(fvCellId < 0) {
560 if(lpt().a_isHalo(lptCellId)) continue;
561 // interpolate linear from the FV parents to the LPT-child
562 fvCellId = lpt2fvIdParent(lptCellId);
563 // ASSERT(fvCellId > -1, "LPT-cell has no matching FV-cell!");
564 if(fvCellId < 0) {
565 cerr << "LPT-cell is missing fv-cell parent" << lptCellId << " " << fvCellId << " " << lpt().a_level(lptCellId)
566 << endl;
567 }
568 interpolateFVLPT(fvCellId, lptCellId);
569 }
570 }
571
572 // NOTE: exchange is necessary as particles on window-cells interpolate the flow variables to their
573 // position and will need values on halo-cells to do so!
574 if(!lpt().m_nonBlockingComm) {
575 lpt().exchangeData(&lpt().a_fluidVariable(0, 0), lpt().PV.noVars());
576 if(lpt().m_evaporation) {
577 lpt().exchangeData(&lpt().a_fluidSpecies(0), 1);
578 }
579#ifndef NDEBUG
580 if(lpt().isActive()) {
581 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_C_BOOL, MPI_LOR, lpt().mpiComm(), AT_, "MPI_IN_PLACE", "divCheck");
582 if(diverged) {
583 lpt().saveDebugRestartFile();
584 }
585 }
586 if(fvSolver().isActive()) {
587 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_C_BOOL, MPI_LOR, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
588 "divCheck");
589 if(diverged) {
590 fvSolver().writeVtkXmlFiles("QOUT", "GEOM", false, true);
591 }
592 }
593#endif
594 } else {
595 if(lpt().isActive()) {
596 lpt().sendFlowField();
597 // the flow field data is received in the time-step
598 }
599 }
600}
void interpolateFVLPT(const MInt from, const MInt to)
interpolate flow variables from the fv-grid to the LPT-cell position
Definition: fvparticle.cpp:962
virtual void writeVtkXmlFiles(const MString, const MString, MBool, MBool)
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

◆ transferNoParticlesInCell()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::transferNoParticlesInCell
private
Author
Tim Wegmann

Definition at line 692 of file fvparticle.cpp.

692 {
693 TRACE();
694
695 if(!fvSolver().m_sensorParticle) return;
696
697 // reset
698 for(MInt fvCell = 0; fvCell < fvSolver().c_noCells(); fvCell++) {
699 fvSolver().a_noPart(fvCell) = 0;
700 }
701 for(MInt fvCell = fvSolver().c_noCells(); fvCell < fvSolver().a_noCells(); fvCell++) {
702#ifndef NDEBUG
703 if(fvSolver().a_noPart(fvCell) > 0) {
704 cerr << " Particles in " << fvCell << " " << fvSolver().a_noCells() << " " << fvSolver().a_isHalo(fvCell)
705 << fvSolver().a_isBndryGhostCell(fvCell) << endl;
706 }
707#endif
708 fvSolver().a_noPart(fvCell) = 0;
709 }
710
711 // transfer
712 for(MInt lptCell = 0; lptCell < lpt().noInternalCells(); lptCell++) {
713 if(lpt().a_noParticlesInCell(lptCell) < 1 && lpt().a_noEllipsoidsInCell(lptCell) < 1) continue;
714 MInt fvCellId = lpt2fvId(lptCell);
715 if(fvCellId < 0) {
716 ASSERT(m_lptFvInterpolation, "");
717 fvCellId = lpt2fvIdParent(lptCell);
718 if(fvCellId < 0) continue;
719 }
720
721 if(!fvSolver().c_isLeafCell(fvCellId)) {
722 ASSERT(m_lptFvInterpolation, "");
723 }
724
725 fvSolver().a_noPart(fvCellId) = lpt().a_noParticlesInCell(lptCell) + lpt().a_noEllipsoidsInCell(lptCell);
726 }
727
728 fvSolver().exchangeData(&fvSolver().a_noPart(0));
729}
MBool m_lptFvInterpolation
Definition: fvparticle.h:125
MBool a_isHalo(const MInt cellId) const
Returns IsHalo of the cell cellId.
MBool a_isBndryGhostCell(const MInt cellId) const
Returns isBndryGhostCell of the cell cellId.
void exchangeData(T *data, const MInt dataBlockSize=1)
Exchange memory in 'data' assuming a solver size of 'dataBlockSize' per cell.

◆ transferTimeStep()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::transferTimeStep
private
Author
Tim Wegmann

Definition at line 830 of file fvparticle.cpp.

830 {
831 TRACE();
832
833 ASSERT(m_forceFvTimeStep, "");
834
835 // set the timeStep in the LPT solver
836 const MFloat conversionTime = conversionFvLpt.length / conversionFvLpt.velocity;
837 lpt().forceTimeStep(fvSolver().timeStep(true) * conversionTime);
839 if(lpt().isActive()) {
840 if(fabs(fvTime * conversionTime - lpt().m_time) > MFloatEps) {
841 cerr << "LPT-time " << lpt().m_time << " Fv-time " << fvTime << " " << conversionTime << " " << globalTimeStep
842 << " " << lpt().isActive() << endl;
843 mTerm(1, AT_, "Miss-matching time!");
844 }
845 } else {
846 lpt().forceTimeStep(fvSolver().timeStep(true) * fvSolver().m_timeRef);
847
848 cerr0 << "Fv-LPT time step set as " << fvSolver().timeStep(true) * fvSolver().m_timeRef << endl;
849 }
850
851 // increasing CFL number after the injection!
852 if(lpt().m_sprayModel != nullptr && lpt().m_sprayModel->m_injectionCrankAngle > 0) {
853 const MFloat cad = fvSolver().crankAngle(fvTime, 0);
854 MFloat injDuration = 10;
855 injDuration = Context::getSolverProperty<MFloat>("injectorInjectionTime", lpt().solverId(), AT_, &injDuration);
856 MInt injCAD = 40;
857 if(injDuration > 15) {
858 injCAD = 55;
859 }
860 if(cad > lpt().m_sprayModel->m_injectionCrankAngle + injCAD && fvSolver().m_cfl < 0.7) {
861 cerr0 << "Increasing FV CFL for next computation from " << fvSolver().m_cfl << " to 0.95!" << endl;
862 fvSolver().m_cfl = 0.95;
863 }
864 }
865}
MFloat crankAngle(const MFloat, const MInt)
help-function for engine calculations which returns the crank-angle for a given time mode = 0: return...

◆ transferVelocitySlopes()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::transferVelocitySlopes
private

NOTE: each LPT-cell must have at-least a matching FV-parent!

Author
Tim Wegmann, update Laurent Andre
Date
August 2022 (edit)

Definition at line 1112 of file fvparticle.cpp.

1112 {
1113 if(!lpt().m_ellipsoids) return;
1114
1115#ifndef NDEBUG
1116 MBool diverged = false;
1117#endif
1118
1119 for(MInt lptCellId = 0; lptCellId < lpt().noInternalCells(); lptCellId++) {
1120 if(!lpt().c_isLeafCell(lptCellId)) continue;
1121 MInt fvCellId = lpt2fvId(lptCellId);
1122 if(fvCellId > -1 && fvSolver().c_isLeafCell(fvCellId)) {
1123 // simple transfer if both cells are leaf-cells
1124 for(MInt varId = 0; varId < nDim; varId++) {
1125 for(MInt dir = 0; dir < nDim; dir++) {
1126 lpt().a_velocitySlope(lptCellId, varId, dir) =
1127 fvSolver().a_slope(fvCellId, fvSolver().m_sysEqn.PV->VV[varId], dir) * conversionFvLpt.velocitySlope;
1128#ifndef NDEBUG
1129 if(std::isnan(lpt().a_velocitySlope(lptCellId, varId, dir)) && lpt().a_isValidCell(lptCellId)
1130 && globalTimeStep > 0) {
1131 diverged = true;
1132 cerr << "Nan velocity slope: " << lpt().a_velocitySlope(lptCellId, varId, dir) << " "
1133 << lpt().a_coordinate(lptCellId, 0) << " " << lpt().a_coordinate(lptCellId, 1) << " "
1134 << lpt().a_coordinate(lptCellId, nDim - 1) << endl;
1135 mTerm(1, AT_, "FVParticle: Transfer of slope that is NAN");
1136 }
1137#endif
1138 }
1139 }
1140 } else if(fvCellId > -1 && !fvSolver().c_isLeafCell(fvCellId)) {
1141 // interpolate from FV-leaf childs if the matching fv-Cell is not a leaf cell
1142 if(lpt().a_isHalo(lptCellId)) continue;
1143 // gather all fv-leaf-cell childs for internal cells
1144 vector<MInt> leafChildIds;
1145 fvSolver().grid().getAllLeafChilds(fvCellId, leafChildIds);
1146 ASSERT(!leafChildIds.empty(), "");
1147
1148 // reset variables
1149 for(MInt varId = 0; varId < nDim; varId++) {
1150 for(MInt dir = 0; dir < nDim; dir++) {
1151 lpt().a_velocitySlope(lptCellId, varId, dir) = F0;
1152 }
1153 }
1154 // interpolate variables by volume
1155 MFloat volume = 0;
1156 for(MUint i = 0; i < leafChildIds.size(); i++) {
1157 const MInt cellId = leafChildIds[i];
1158 if(fvSolver().a_isInactive(cellId)) continue;
1159 const MFloat cellVolume = fvSolver().a_cellVolume(cellId);
1160 ASSERT(fvSolver().c_isLeafCell(cellId), "");
1161 if(cellVolume < 1e-16) mTerm(1, AT_, "Invalid cell-volume!");
1162 volume += cellVolume;
1163 for(MInt varId = 0; varId < nDim; varId++) {
1164 for(MInt dir = 0; dir < nDim; dir++) {
1165 lpt().a_velocitySlope(lptCellId, varId, dir) +=
1166 cellVolume * fvSolver().a_slope(fvCellId, fvSolver().m_sysEqn.PV->VV[varId], dir);
1167 }
1168 }
1169 }
1170 if(volume > 1e-16) {
1171 // meaning at least one child is active
1172 for(MInt varId = 0; varId < nDim; varId++) {
1173 for(MInt dir = 0; dir < nDim; dir++) {
1174 lpt().a_velocitySlope(lptCellId, varId, dir) *= conversionFvLpt.velocitySlope / volume;
1175 }
1176 }
1177 } else {
1178 // meaning completely outside
1179 for(MInt varId = 0; varId < nDim; varId++) {
1180 for(MInt dir = 0; dir < nDim; dir++) {
1181 lpt().a_velocitySlope(lptCellId, varId, dir) = conversionFvLpt.velocitySlope;
1182 }
1183 }
1184 }
1185 } else if(fvCellId < 0) {
1186 if(lpt().a_isHalo(lptCellId)) continue;
1187 // interpolate linear from the FV parents to the LPT-child
1188 fvCellId = lpt2fvIdParent(lptCellId);
1189 ASSERT(fvCellId > -1, "LPT-cell has no matching FV-cell!");
1190 interpolateVelocitySlopesFVLPT(fvCellId, lptCellId);
1191 }
1192 }
1193
1194 // NOTE: exchange is necessary as particles on window-cells interpolate the flow variables to their
1195 // position and will need values on halo-cells to do so!
1196 if(!lpt().m_nonBlockingComm) {
1197 lpt().exchangeData(&lpt().a_velocitySlope(0, 0, 0), nDim * nDim);
1198#ifndef NDEBUG
1199 if(lpt().isActive()) {
1200 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_C_BOOL, MPI_LOR, lpt().mpiComm(), AT_, "MPI_IN_PLACE", "divCheck");
1201 if(diverged) {
1202 lpt().saveDebugRestartFile();
1203 }
1204 }
1205 if(fvSolver().isActive()) {
1206 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_C_BOOL, MPI_LOR, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1207 "divCheck");
1208 if(diverged) {
1209 fvSolver().writeVtkXmlFiles("QOUT", "GEOM", false, true);
1210 }
1211 }
1212#endif
1213 } else {
1214 if(lpt().isActive()) {
1215 lpt().sendVelocitySlopes(); // the velocity slopes are received in the time-step
1216 }
1217 }
1218}
void interpolateVelocitySlopesFVLPT(const MInt from, const MInt to)
Interpolates the velocity slopes from the fv-grid to the LPT-cell.

◆ unifyTimeStep()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::unifyTimeStep
private
Author
Tim Wegmann

Definition at line 1226 of file fvparticle.cpp.

1226 {
1227 TRACE();
1228
1229 ASSERT(m_interLeafed, "");
1230
1231 cerr0 << "Unifying time-step LPT: " << lpt().m_timeStep << " FV: " << fvSolver().timeStep() << endl;
1232
1233 const MFloat invalidTimeStep = std::numeric_limits<MFloat>::max();
1234 const MFloat conversionTime = conversionFvLpt.length / conversionFvLpt.velocity;
1235 MFloat timeFv = invalidTimeStep;
1236 MFloat timeLpt = invalidTimeStep;
1237 MInt maxLevelFv = -1;
1238 MInt maxLevelLpt = -1;
1239 MFloat newTimeFv = invalidTimeStep;
1240 MFloat newTimeLpt = invalidTimeStep;
1241
1242 // determine the new/combined timeStep on ranks which have both Fv and Lpt solvers!
1243 if(fvSolver().isActive() && lpt().isActive()) {
1244 timeFv = fvSolver().timeStep(true);
1245 maxLevelFv = fvSolver().maxLevel();
1246 timeLpt = lpt().timeStep() / conversionTime;
1247 maxLevelLpt = lpt().maxLevel();
1248
1249 MInt levelDiff = maxLevelLpt - maxLevelFv;
1250 if(levelDiff == 0) {
1251 newTimeFv = mMin(timeFv, timeLpt);
1252 newTimeLpt = newTimeFv * conversionTime;
1253 } else {
1254 if(levelDiff == 1) {
1255 // LPT has higher level => lower timeStep!
1256 newTimeLpt = mMin(newTimeLpt, newTimeFv / 2.0);
1257 newTimeFv = 2.0 * newTimeLpt;
1258 } else if(levelDiff == -1) {
1259 // Fv has the higher level => lower timeStep!
1260 newTimeFv = mMin(newTimeFv, newTimeLpt / 2.0);
1261 newTimeLpt = 2.0 * newTimeFv;
1262 } else {
1263 mTerm(1, AT_, "TimeStepping currently only implemented for 1 level difference!");
1264 }
1265 }
1266 }
1267
1268 if(lpt().isActive()) {
1269 MPI_Allreduce(MPI_IN_PLACE, &newTimeLpt, 1, MPI_DOUBLE, MPI_MIN, lpt().mpiComm(), AT_, "MPI_IN_PLACE",
1270 "newTimeLpt");
1271 }
1272 if(fvSolver().isActive()) {
1273 MPI_Allreduce(MPI_IN_PLACE, &newTimeFv, 1, MPI_DOUBLE, MPI_MIN, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1274 "newTimeFv");
1275 }
1276
1277 if(fvSolver().domainId() == 0) {
1278 cerr << "Fv timestep was " << timeFv << " combined TS is " << newTimeFv << endl;
1279 }
1280
1281 if(lpt().domainId() == 0) {
1282 cerr << "LPT timestep was " << timeLpt << " combined TS is " << newTimeLpt << endl;
1283 }
1284
1285
1286 if(fvSolver().isActive()) {
1287 fvSolver().forceTimeStep(newTimeFv);
1288 }
1289 if(lpt().isActive()) {
1290 lpt().forceTimeStep(newTimeLpt);
1291 }
1292}
void forceTimeStep(const MFloat dt)
Force time step externally.

◆ updateLPTBndry()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::updateLPTBndry
private
Author
Tim Wegmann

Definition at line 607 of file fvparticle.cpp.

607 {
608 TRACE();
609
610 if(!lpt().m_wallCollisions) return;
611
612 if(!lpt().isActive()) return;
613
614 // reset all moving bndry-Cells
615 for(MInt lptCell = 0; lptCell < lpt().a_noCells(); lptCell++) {
616 if(lpt().a_bndryCellId(lptCell) >= lpt().m_noOuterBndryCells) {
617 lpt().a_bndryCellId(lptCell) = -1;
618 }
619 }
620
621 // reset size to stationary outer bndryCells
622 lpt().m_bndryCells->resetSize(lpt().m_noOuterBndryCells);
623
624 MFloatScratchSpace surfaceC(nDim, nDim + 1, AT_, "surfaceC");
625 MFloatScratchSpace surfaceN(nDim, AT_, "surfaceN");
626 MFloatScratchSpace surfaceV(nDim, AT_, "surfaceV");
627 MFloatScratchSpace bndryData(nDim + 1, AT_, "surfaceV");
628
629 // update moving bndryCells from FV
630 for(MInt bndryId = fvSolver().m_noOuterBndryCells; bndryId < fvSolver().m_fvBndryCnd->m_bndryCells->size();
631 bndryId++) {
632 const MInt fvCellId = fvSolver().m_bndryCells->a[bndryId].m_cellId;
633 // TODO: use splitChildToSplitcell for bndry-cells of sliptchilds!
634 if(fvCellId < 0 || fvCellId >= fvSolver().c_noCells()) continue;
635 if(!fvSolver().c_isLeafCell(fvCellId)) continue;
636 MInt lptCellId = fv2lptId(fvCellId);
637 if(lptCellId < 0) {
638 lptCellId = fv2lptIdParent(fvCellId);
639 if(lptCellId < 0) continue;
640 if(lpt().c_level(lptCellId) < lpt().maxRefinementLevel()) continue;
641 ASSERT(m_lptFvInterpolation, "");
642 }
643
644 if(!lpt().c_isLeafCell(lptCellId)) {
645 ASSERT(m_lptFvInterpolation, "");
646 }
647
648 MInt noSurf = fvSolver().m_bndryCells->a[bndryId].m_noSrfcs;
649
650 // bndryCell without a bndrySurface, how is that even possible?
651 // if(noSurf < 1 ) continue;
652
653 // ASSERT(noSurf == 1, "Only for single bndry-surfaces!");
654 if(noSurf > 1) noSurf = 1;
655
656 bndryData[0] = fvSolver().m_fvBndryCnd->m_bndryCells->a[bndryId].m_volume;
657 for(MInt i = 0; i < nDim; i++) {
658 bndryData[1 + i] = fvSolver().m_fvBndryCnd->m_bndryCells->a[bndryId].m_coordinates[i];
659 }
660
661 for(MInt s = 0; s < noSurf; s++) {
662 MInt bodyId = fvSolver().m_levelSetMb ? fvSolver().m_bndryCells->a[bndryId].m_srfcs[s]->m_bodyId[0] : -1;
663 for(MInt n = 0; n < nDim; n++) {
664 surfaceC(noSurf * s + n, 0) = fvSolver().m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[s]->m_coordinates[n];
665 for(MInt i = 0; i < nDim; i++) {
666 surfaceC(noSurf * s + n, i + 1) =
667 fvSolver().m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[s]->m_cutCoordinates[i][n];
668 }
669 // surfaceV[noSurf * s + n] = fvSolver()
670 // .m_fvBndryCnd->m_bndryCells->a[bndryId]
671 // .m_srfcVariables[s]
672 // ->m_primVars[fvSolver().m_sysEqn.PV->VV[n]];
673 if(bodyId > 0) {
674 surfaceV[noSurf * s + n] = fvSolver().m_bodyVelocity[bodyId * nDim + n];
675 } else {
676 surfaceV[noSurf * s + n] = 0.0;
677 }
678 surfaceN[noSurf * s + n] = fvSolver().m_fvBndryCnd->m_bndryCells->a[bndryId].m_srfcs[s]->m_normalVector[n];
679 }
680 }
681
682 // append new LPT bndryCell based on FV data
683 lpt().addBndryCell(lptCellId, &bndryData[0], &surfaceN[0], surfaceC, &surfaceV[0]);
684 }
685}
MInt size()
Definition: collector.h:29
MInt fv2lptId(const MInt fvId)
Definition: fvparticle.h:107
MInt fv2lptIdParent(const MInt fvId)
Definition: fvparticle.h:108
Collector< FvBndryCell< nDim, SysEqn > > * m_bndryCells
Collector< FvBndryCell< nDim, SysEqn > > * m_bndryCells
FvBndryCndXD< nDim_, SysEqn > * m_fvBndryCnd

◆ writeParticleCellStats()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::writeParticleCellStats
private
Author
Tim Wegmann

Definition at line 1360 of file fvparticle.cpp.

1360 {
1361 TRACE();
1362
1363 // count particles in cells
1364 lpt().countParticlesInCells();
1365
1366 if(!fvSolver().isActive()) {
1367 return;
1368 }
1369
1370 // transfer to FV-grid
1372
1373 // determine max. No Particles in a FV-cell
1374 MInt maxNoParticles = 0;
1375 MInt maxParticlesSum = 0;
1376 for(MInt cellId = 0; cellId < fvSolver().noInternalCells(); cellId++) {
1377 if(fvSolver().a_noPart(cellId) > maxNoParticles) {
1378 maxNoParticles = fvSolver().a_noPart(cellId);
1379 }
1380 maxParticlesSum += fvSolver().a_noPart(cellId);
1381 }
1382 // create binning ranges
1383 MPI_Allreduce(MPI_IN_PLACE, &maxNoParticles, 1, MPI_INT, MPI_MAX, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1384 "maxParticles");
1385
1386 MPI_Allreduce(MPI_IN_PLACE, &maxParticlesSum, 1, MPI_INT, MPI_MAX, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1387 "maxParticlesSum");
1388
1389 {
1390 MFloatScratchSpace noCells(maxNoParticles + 1, AT_, "noCells");
1391 noCells.fill(0);
1392
1393 // perform cell-binning
1394 for(MInt cellId = 0; cellId < fvSolver().noInternalCells(); cellId++) {
1395 if(!fvSolver().c_isLeafCell(cellId)) {
1396 continue;
1397 }
1398 if(!fvSolver().a_isActive(cellId)) {
1399 continue;
1400 }
1401
1402 const MInt pos = fvSolver().a_noPart(cellId);
1403 noCells(pos)++;
1404 }
1405
1406 // communicate results
1407 MPI_Allreduce(MPI_IN_PLACE, &noCells(0), maxNoParticles + 1, MPI_DOUBLE, MPI_SUM, fvSolver().mpiComm(), AT_,
1408 "MPI_IN_PLACE", "noCells");
1409
1410 // write to file
1411 if(fvSolver().domainId() == 0) {
1412 struct stat buffer {};
1413 MString name = "noParticlesInCells_" + to_string(fvSolver().solverId()) + "_" + to_string(globalTimeStep);
1414 const char* cstr = name.c_str();
1415 if(stat(cstr, &buffer) == 0) {
1416 rename(cstr, "noParticlesInCells_BAK");
1417 }
1418 ofstream ofl;
1419 ofl.open(name, ios_base::out | ios_base::app);
1420 ofl << "# 1:noParticles 2:noCells " << endl;
1421 for(MInt i = 0; i < maxNoParticles + 1; i++) {
1422 ofl << i << " " << noCells(i) << endl;
1423 }
1424 ofl.close();
1425 }
1426 }
1427
1428 // perform min-cell binning
1429 MIntScratchSpace noMinCells(maxParticlesSum + 1, AT_, "noMinCells");
1430 noMinCells.fill(0);
1431
1432 // reset particles to zero on halo-cells
1433 for(MInt cellId = fvSolver().noInternalCells(); cellId < fvSolver().a_noCells(); cellId++) {
1434 fvSolver().a_noPart(cellId) = 0;
1435 }
1436
1437 MFloat minCellVolume = -1;
1438 for(MInt id = 0; id < fvSolver().grid().noMinCells(); id++) {
1439 const MInt cellId = fvSolver().grid().minCell(id);
1440 if(cellId < 0) {
1441 continue;
1442 }
1443 minCellVolume = fvSolver().c_cellVolumeAtLevel(fvSolver().a_level(cellId));
1444
1445 // loop over all children and sum particles
1446 MInt curCount = childLoop(cellId);
1447
1448 if(curCount > maxParticlesSum || curCount < 0) {
1449 cerr << "Strange particle count!" << curCount << endl;
1450 }
1451
1452 noMinCells(curCount)++;
1453 }
1454
1455 // communicate results
1456 MPI_Allreduce(MPI_IN_PLACE, &noMinCells(0), maxParticlesSum + 1, MPI_INT, MPI_SUM, fvSolver().mpiComm(), AT_,
1457 "MPI_IN_PLACE", "noMinCells");
1458
1459 // write to file
1460 if(fvSolver().domainId() == 0) {
1461 struct stat buffer {};
1462 MString name = "noParticlesInMinCells_" + to_string(fvSolver().solverId()) + "_" + to_string(globalTimeStep);
1463 const char* cstr = name.c_str();
1464 if(stat(cstr, &buffer) == 0) {
1465 rename(cstr, "noParticlesInMinCells_BAK");
1466 }
1467
1468 MString header = "# Min-cell volume : " + to_string(minCellVolume) + " \n";
1469 ofstream ofl;
1470 ofl.open(name, ios_base::out | ios_base::trunc);
1471 ofl << header << endl;
1472
1473 for(MInt i = 0; i < maxParticlesSum + 1; i++) {
1474 ofl << i << " " << noMinCells(i) << endl;
1475 }
1476 ofl.close();
1477 }
1478}
MFloat c_cellVolumeAtLevel(const MInt level) const
Returns the grid Volume of the cell for level.
MBool a_isActive(const MInt cellId) const

◆ writeRestartFile()

template<MInt nDim, class SysEqn >
void CouplerFvParticle< nDim, SysEqn >::writeRestartFile ( const  MInt)
inlineoverridevirtual

Reimplemented from Coupling.

Definition at line 69 of file fvparticle.h.

69{};

Friends And Related Function Documentation

◆ FvCartesianSolverXD< nDim, SysEqn >

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

Definition at line 1 of file fvparticle.h.

◆ LPT< nDim >

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

Definition at line 1 of file fvparticle.h.

Member Data Documentation

◆ conversionFvLpt

template<MInt nDim, class SysEqn >
ConversionFactor& CouplerFvParticle< nDim, SysEqn >::conversionFvLpt = BaseLptX::conversionFlowLpt
private

Definition at line 40 of file fvparticle.h.

◆ conversionLptFv

template<MInt nDim, class SysEqn >
ConversionFactor& CouplerFvParticle< nDim, SysEqn >::conversionLptFv = BaseLptX::conversionLptFlow
private

Definition at line 39 of file fvparticle.h.

◆ m_forceFvTimeStep

template<MInt nDim, class SysEqn >
MBool CouplerFvParticle< nDim, SysEqn >::m_forceFvTimeStep
private

Definition at line 132 of file fvparticle.h.

◆ m_fvLPTSpeciesId

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_fvLPTSpeciesId {}
private

Definition at line 126 of file fvparticle.h.

◆ m_fvSolver

template<MInt nDim, class SysEqn >
FvCartesianSolverXD<nDim, SysEqn>* CouplerFvParticle< nDim, SysEqn >::m_fvSolver = nullptr
private

Definition at line 117 of file fvparticle.h.

◆ m_fvSolverId

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_fvSolverId {}
private

Definition at line 120 of file fvparticle.h.

◆ m_fvSolverOrder

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_fvSolverOrder {}
private

Definition at line 122 of file fvparticle.h.

◆ m_interLeafed

template<MInt nDim, class SysEqn >
MBool CouplerFvParticle< nDim, SysEqn >::m_interLeafed
private

Definition at line 133 of file fvparticle.h.

◆ m_lptFvInterpolation

template<MInt nDim, class SysEqn >
MBool CouplerFvParticle< nDim, SysEqn >::m_lptFvInterpolation = false
private

Definition at line 125 of file fvparticle.h.

◆ m_lptSolverId

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_lptSolverId {}
private

Definition at line 119 of file fvparticle.h.

◆ m_lptSolverOrder

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_lptSolverOrder {}
private

Definition at line 121 of file fvparticle.h.

◆ m_noSolutionSteps

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_noSolutionSteps
private

Definition at line 131 of file fvparticle.h.

◆ m_noSolverSteps

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_noSolverSteps {}
private

Definition at line 123 of file fvparticle.h.

◆ m_particle

template<MInt nDim, class SysEqn >
LPT<nDim>* CouplerFvParticle< nDim, SysEqn >::m_particle = nullptr
private

Definition at line 116 of file fvparticle.h.

◆ m_solutionStep

template<MInt nDim, class SysEqn >
MInt CouplerFvParticle< nDim, SysEqn >::m_solutionStep
private

Definition at line 130 of file fvparticle.h.

◆ m_sysEqn

template<MInt nDim, class SysEqn >
SysEqn CouplerFvParticle< nDim, SysEqn >::m_sysEqn
private

Definition at line 128 of file fvparticle.h.


The documentation for this class was generated from the following files: