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

#include <lsfvcombustion.h>

Inheritance diagram for LsFvCombustion< nDim_, SysEqn >:
[legend]
Collaboration diagram for LsFvCombustion< nDim_, SysEqn >:
[legend]

Public Types

using Cell = typename LsCartesianSolver< nDim_ >::Cell
 
using SolverCell = FvCell
 
using FvCartesianSolver = FvCartesianSolverXD< nDim_, SysEqn >
 
using LsSolver = LsCartesianSolver< nDim_ >
 

Public Member Functions

LsSolverlsSolver () const
 
FvCartesianSolverfvSolver () const
 
 LsFvCombustion (const MInt couplingId, LsSolver *ls, FvCartesianSolver *fv)
 
MInt a_noSets () const
 
MFloat a_levelSetFunctionG (MInt gcellId, MInt set) const
 
MFloat a_outsideGValue () const
 
void init ()
 
void finalizeSubCoupleInit (MInt)
 
void finalizeCouplerInit () override
 
void preCouple (MInt) override
 
void subCouple (MInt, MInt, std::vector< MBool > &)
 
void postCouple (MInt)
 
void cleanUp ()
 
void checkProperties ()
 
void readProperties ()
 
void computeSourceTerms ()
 
MFloat collectGFromCouplingClass (MInt)
 
MFloat collectCurvFromCouplingClass (MInt)
 
MInt noLevelSetFieldData ()
 
void saveOutputLS ()
 
void setRhoFlameTubeInLs ()
 
void setRhoInfinityInLs ()
 
MFloat collectFvDataForCollectGEquationModelDataOpt (MInt, MInt)
 
void computeGCellTimeStep ()
 
void setLsTimeStep (MFloat)
 
MInt ls2fvId (const MInt lsId)
 
MInt fv2lsId (const MInt fvId)
 
void collectGEquationModelDataOptInterpolate (MFloat *fluidDensity, MInt set)
 transfers v from the flow to the G-grid (highest level) via interpolation More...
 
void fastInterfaceExtensionVelocity ()
 
void exchangeCouplingData ()
 
void constructExtensionVelocity ()
 
void collectGEquationModelDataOpt (MFloat *fluidDensity, MInt set)
 
- 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 Attributes

LsSolverm_lsSolver
 
FvCartesianSolverm_fvSolver
 
MInt m_maxNoSets
 

Static Public Attributes

static constexpr MInt nDim = nDim_
 

Friends

class LsCartesianSolver< nDim >
 
class FvCartesianSolverXD< nDim, SysEqn >
 

Additional Inherited Members

- Protected Member Functions inherited from Coupling
MFloat returnLoadRecord () const
 
MFloat returnIdleRecord () const
 

Detailed Description

template<MInt nDim_, class SysEqn>
class LsFvCombustion< nDim_, SysEqn >

Definition at line 27 of file lsfvcombustion.h.

Member Typedef Documentation

◆ Cell

template<MInt nDim_, class SysEqn >
using LsFvCombustion< nDim_, SysEqn >::Cell = typename LsCartesianSolver<nDim_>::Cell

Definition at line 40 of file lsfvcombustion.h.

◆ FvCartesianSolver

template<MInt nDim_, class SysEqn >
using LsFvCombustion< nDim_, SysEqn >::FvCartesianSolver = FvCartesianSolverXD<nDim_, SysEqn>

Definition at line 43 of file lsfvcombustion.h.

◆ LsSolver

template<MInt nDim_, class SysEqn >
using LsFvCombustion< nDim_, SysEqn >::LsSolver = LsCartesianSolver<nDim_>

Definition at line 44 of file lsfvcombustion.h.

◆ SolverCell

template<MInt nDim_, class SysEqn >
using LsFvCombustion< nDim_, SysEqn >::SolverCell = FvCell

Definition at line 41 of file lsfvcombustion.h.

Constructor & Destructor Documentation

◆ LsFvCombustion()

template<MInt nDim, class SysEqn >
LsFvCombustion< nDim, SysEqn >::LsFvCombustion ( const MInt  couplingId,
LsSolver ls,
FvCartesianSolver fv 
)

Definition at line 23 of file lsfvcombustion.cpp.

24 : Coupling(couplingId),
25 // CouplingLS<nDim>(couplingId, ls),
26 // CouplingFv<nDim, SysEqn>(couplingId, dynamic_cast<Solver*>(fv)),
27 m_lsSolver(ls),
28 m_fvSolver(fv) {
29 TRACE();
30 // fvSolver().setCombustionCouplingClassPointer(this);
31 // lsSolver().setCombustionCouplingClassPointer(this);
33}
FvCartesianSolver * m_fvSolver
LsSolver * m_lsSolver
LsSolver & lsSolver() const

Member Function Documentation

◆ a_levelSetFunctionG()

template<MInt nDim_, class SysEqn >
MFloat LsFvCombustion< nDim_, SysEqn >::a_levelSetFunctionG ( MInt  gcellId,
MInt  set 
) const
inline

Definition at line 55 of file lsfvcombustion.h.

55{ return lsSolver().a_levelSetFunctionG(gcellId, set); }
MFloat & a_levelSetFunctionG(const MInt cellId, const MInt set)
Returns levelSetFunction of the cell cellId.

◆ a_noSets()

template<MInt nDim_, class SysEqn >
MInt LsFvCombustion< nDim_, SysEqn >::a_noSets ( ) const
inline

Definition at line 54 of file lsfvcombustion.h.

54{ return lsSolver().m_noSets; }

◆ a_outsideGValue()

template<MInt nDim_, class SysEqn >
MFloat LsFvCombustion< nDim_, SysEqn >::a_outsideGValue ( ) const
inline

Definition at line 56 of file lsfvcombustion.h.

56{ return lsSolver().m_outsideGValue; }

◆ checkProperties()

template<MInt nDim_, class SysEqn >
void LsFvCombustion< nDim_, SysEqn >::checkProperties ( )
inlinevirtual

Implements Coupling.

Definition at line 65 of file lsfvcombustion.h.

65{};

◆ cleanUp()

template<MInt nDim_, class SysEqn >
void LsFvCombustion< nDim_, SysEqn >::cleanUp ( )
inlinevirtual

Implements Coupling.

Definition at line 64 of file lsfvcombustion.h.

64{};

◆ collectCurvFromCouplingClass()

template<MInt nDim, class SysEqn >
MFloat LsFvCombustion< nDim, SysEqn >::collectCurvFromCouplingClass ( MInt  i)

Definition at line 225 of file lsfvcombustion.cpp.

225 {
226 if(i + 1 > fvSolver().grid().tree().size()) {
227 return -99;
228 }
229 if(fvSolver().grid().tree().hasProperty(i, Cell::IsHalo)) {
230 return -99;
231 }
232 MInt iLs = fv2lsId(i);
233 if(iLs < 0 || iLs > lsSolver().grid().tree().size()) {
234 return -99;
235 } else {
236 return (lsSolver().a_curvatureG(iLs, 0)); // numeric_limits<MFloat>::infinity() ;
237 }
238}
MInt fv2lsId(const MInt fvId)
FvCartesianSolver & fvSolver() const
int32_t MInt
Definition: maiatypes.h:62

◆ collectFvDataForCollectGEquationModelDataOpt()

template<MInt nDim, class SysEqn >
MFloat LsFvCombustion< nDim, SysEqn >::collectFvDataForCollectGEquationModelDataOpt ( MInt  flowCell,
MInt  id 
)

Definition at line 183 of file lsfvcombustion.cpp.

183 {
184 MInt flowCellFv = ls2fvId(flowCell);
185
186 if(flowCellFv == -1) {
187 return -99;
188 } else {
189 for(MInt i = 0; i < nDim; i++) {
190 lsSolver().a_extensionVelocityG(lsSolver().a_G0CellId(id, 0), i, 0) =
191 fvSolver().a_pvariable(flowCellFv, fvSolver().PV->VV[i]);
192 }
193
194 return F1 / fvSolver().a_pvariable(flowCellFv, fvSolver().PV->RHO);
195 }
196}
MFloat & a_pvariable(const MInt cellId, const MInt varId)
Returns primitive variable v of the cell cellId for variables varId.
MFloat & a_extensionVelocityG(const MInt cellId, const MInt dim, const MInt set)
Returns fExt of the cell cellId for index n.
static constexpr MInt nDim
MInt ls2fvId(const MInt lsId)

◆ collectGEquationModelDataOpt()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::collectGEquationModelDataOpt ( MFloat fluidDensity,
MInt  set 
)

Definition at line 92 of file lsfvcombustion.cpp.

92 {
93 TRACE();
94
95 MInt baseGCellId, cellId;
96 for(MInt id = 0; id < lsSolver().a_noBandCells(set); id++) {
97 cellId = lsSolver().a_bandCellId(id, set);
98 for(MInt i = 0; i < lsSolver().nDim; i++) {
99 lsSolver().a_extensionVelocityG(cellId, i, set) = F0;
100 }
101 lsSolver().a_correctedBurningVelocity(cellId, set) = F0;
102 }
103 //}
104
105 // take only non-ghost cells!
106 for(MInt id = 0; id < lsSolver().a_noG0Cells(set); id++) {
107 if(lsSolver().a_isHalo(lsSolver().a_G0CellId(id, set))
108 || lsSolver().a_level(lsSolver().a_G0CellId(id, set)) != lsSolver().a_maxGCellLevel()) {
109 for(MInt i = 0; i < lsSolver().nDim; i++)
110 lsSolver().a_extensionVelocityG(lsSolver().a_G0CellId(id, set), i, set) = F0;
111 fluidDensity[id] = -F1;
112
113 } else {
114 // find the parent cell which is connected to the flow grid
115 baseGCellId = lsSolver().a_G0CellId(id, set);
116
117 if(lsSolver().a_isGBoundaryCellG(baseGCellId, 0)) continue;
118 if(lsSolver().a_isBndryCellG(baseGCellId)) continue;
119
120 while(ls2fvId(baseGCellId) == -1) {
121 baseGCellId = lsSolver().c_parentId(baseGCellId);
122 }
123 if(baseGCellId == -1) {
124 cerr << "ERROR: no parent cell found for connecting" << endl;
125 }
126 MInt flowCell = baseGCellId;
127
128 fluidDensity[id] = collectFvDataForCollectGEquationModelDataOpt(flowCell, id);
129 }
130 }
131}
MBool a_isHalo(const MInt gCellId) const
Returns IsHalo of the cell cellId.
MInt a_maxGCellLevel(const MInt set=-1) const
constexpr MInt a_bandCellId(MInt id, MInt set) const
MInt a_level(const MInt gCellId) const
Returns the level of the gcell gCellId.
constexpr MInt a_noG0Cells(MInt set) const
static constexpr MInt nDim
constexpr MInt a_noBandCells(MInt set) const
MInt c_parentId(const MInt gCellId) const
constexpr MInt a_G0CellId(MInt id, MInt set) const
MFloat & a_correctedBurningVelocity(const MInt cellId, const MInt set)
Returns corrected burning velocity of the cell cellId for set set.
MFloat collectFvDataForCollectGEquationModelDataOpt(MInt, MInt)
MInt id
Definition: maiatypes.h:71
void const MInt cellId
Definition: collector.h:239

◆ collectGEquationModelDataOptInterpolate()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::collectGEquationModelDataOptInterpolate ( MFloat fluidDensity,
MInt  set 
)
Author
Stephan Schlimpert
Date
Feb 2012

guarantees pocket formation at the flame tip

currently out of use!

Definition at line 1778 of file lsfvcombustion.cpp.

1778 {
1779 TRACE();
1780
1781 std::ignore = fluidDensity;
1782 std::ignore = set;
1783
1784 /*
1785 MInt baseGCell,flowCell,cellId;
1786 MFloat Fdx;
1787 MFloat FlengthLevel0 = F1 / grid().cellLengthAtLevel(0);
1788 //---
1789
1790 // reset extension velocity
1791 // if(globalTimeStep == m_restartTimeStep){
1792 for( MInt id = 0; id < lsSolver().a_noBandCells(set); id++ ){
1793 cellId = lsSolver().a_bandCellId(id, set);
1794 a_extensionVelocityG( cellId, 0 , set) = F0;
1795 a_extensionVelocityG( cellId, 1 , set) = F0;
1796 a_correctedBurningVelocity(cellId, set) = F0;
1797 }
1798 //}
1799
1800
1801 // take only non-ghost cells!
1802 for( MInt id=0; id < lsSolver().a_noG0Cells(set); id++ ) {
1803 if( a_isHalo( a_G0CellId(id, set))) {
1804 for( MInt i=0; i<nDim; i++ )
1805 a_extensionVelocityG( a_G0CellId(id, set), i, set) = F0;
1806 fluidDensity[ gc ] = -F1; //FrhoInf;
1807
1808 } else {
1809
1810 // find the parent cell which is connected to the flow grid
1811 baseGCell = a_G0CellId(id, set);
1812 while( combustion().ls2fvId( baseGCell ) == -1 ) {
1813 baseGCell = a_parentGId( baseGCell );
1814 }
1815 if(baseGCell==-1) {
1816 cerr << "ERROR: no parent cell found for connecting" << endl;
1817 }
1818 flowCell = combustion().ls2fvId( baseGCell );
1819 if(flowCell==-1)
1820 cerr << "ERROR: no parent cell found for connecting" << endl;
1821
1822
1823
1824 // compute the gradient on the flow cell (rewrite, just used for a proof of concept!!!)
1825 Fdx = FlengthLevel0 * FPOW2( grid().tree().level( flowCell ) );
1826 for( MInt v=0; v<fvSolverD().PV->noVariables; v++ ) {
1827 for( MInt i=0; i<nDim; i++ ) {
1828 if( grid().tree().hasNeighbor( flowCell , 2*i ) > 0 ){
1829 if( grid().tree().hasNeighbor( flowCell , 2*i+1 ) > 0 ){
1830 fvSolverD().a_slope( flowCell , v , i ) = F1B2 * Fdx *
1831 (fvSolverD().a_pvariable( grid().tree().neighbor( flowCell , 2*i+1 ) , v ) -
1832 fvSolverD().a_pvariable( grid().tree().neighbor( flowCell , 2*i ) , v ) );
1833 } else {
1834 fvSolverD().a_slope( flowCell , v , i ) = Fdx *
1835 (fvSolverD().a_pvariable( flowCell , v ) -
1836 fvSolverD().a_pvariable( grid().tree().neighbor( flowCell , 2*i ) , v ) );
1837 }
1838 }else{
1839 if( grid().tree().hasNeighbor( flowCell , 2*i+1 ) > 0 ) {
1840 fvSolverD().a_slope( flowCell , v , i ) = Fdx *
1841 (fvSolverD().a_pvariable( grid().tree().neighbor( flowCell , 2*i+1 ) , v ) -
1842 fvSolverD().a_pvariable( flowCell , v ) );
1843 } else {
1844 fvSolverD().a_slope( flowCell , v , i ) = F0;
1845 fvSolverD().a_slope( flowCell , v , i ) = F0;
1846 }
1847 }
1848 }
1849 }
1850
1851 // store the flow velocity
1852 for( MInt i=0; i<nDim; i++ ){
1853 a_extensionVelocityG( a_G0CellId(id, set), i, set) =fvSolverD().a_pvariable( flowCell ,
1854 fvSolverD().PV->VV[ i ] ); for( MInt j=0; j<nDim; j++ ){ a_extensionVelocityG( a_G0CellId(id, set), i
1855 , set) += fvSolverD().a_slope( flowCell , fvSolverD().PV->VV[ j ] , j ) * ( c_coordinate( a_G0CellId(
1856 id, set), j ) - grid().tree().coordinate( flowCell , j ) );
1857 }
1858 }
1859 fluidDensity[ gc ] =fvSolverD().a_pvariable( flowCell , fvSolverD().PV->RHO );
1860
1861 for( MInt i=0; i<nDim; i++ ){
1862 fluidDensity[ gc ] +=
1863 fvSolverD().a_slope( flowCell , fvSolverD().PV->RHO , i ) * ( c_coordinate( a_G0CellId(id, set),
1864 i ) - grid().tree().coordinate( flowCell , i ) );
1865
1866 }
1867 // store the density
1868 fluidDensity[ gc ] = F1 / fluidDensity[ gc ]; //fvSolverD().a_pvariable( flowCell , fvSolverD().PV->RHO );
1869 }
1870 }
1871 */
1872}

◆ collectGFromCouplingClass()

template<MInt nDim, class SysEqn >
MFloat LsFvCombustion< nDim, SysEqn >::collectGFromCouplingClass ( MInt  i)

Definition at line 209 of file lsfvcombustion.cpp.

209 {
210 if(i + 1 > fvSolver().grid().tree().size()) {
211 return -99;
212 }
213 if(fvSolver().grid().tree().hasProperty(i, Cell::IsHalo)) {
214 return -99;
215 }
216 MInt iLs = fv2lsId(i);
217 // sohel: for some reason iLs can be a big number in parallel runs.. maybe value is broken for halo cells?
218 if(iLs < 0 || iLs > lsSolver().grid().tree().size()) {
219 return -99;
220 } else {
221 return (lsSolver().a_levelSetFunctionG(iLs, 0)); // numeric_limits<MFloat>::infinity() ;
222 }
223}
MFloat a_levelSetFunctionG(MInt gcellId, MInt set) const

◆ computeGCellTimeStep()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::computeGCellTimeStep

Definition at line 172 of file lsfvcombustion.cpp.

172 {
174}
MFloat timeStep(MBool canSolver=false) noexcept

◆ computeSourceTerms()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::computeSourceTerms

brief important correction of jump condition (implemented like presented in Dissertation D. Hartmann)

Author
Stephan Schlimpert
Date
November 2011

<< fvSolver().a_pvariable(c, fvSolver().PV->C) << endl;

brief important correction of jump condition (implemented like presented in Dissertation D. Hartmann)

Author
Stephan Schlimpert
Date
November 2011

Definition at line 1016 of file lsfvcombustion.cpp.

1016 {
1017 TRACE();
1018
1019
1020 // get all the parameters from the fv solver...
1021 MInt m_constantFlameSpeed = fvSolver().m_constantFlameSpeed;
1022 MFloat m_subfilterVariance = fvSolver().m_subfilterVariance;
1023 MFloat m_rhoEInfinity = fvSolver().m_rhoEInfinity;
1024 MInt m_useCorrectedBurningVelocity = fvSolver().m_useCorrectedBurningVelocity;
1025 MFloat m_integralLengthScale = fvSolver().m_integralLengthScale;
1026 MFloat m_marksteinLength = fvSolver().m_marksteinLength;
1027 MFloat m_dampingDistanceFlameBase = fvSolver().m_dampingDistanceFlameBase;
1028 MFloat m_sutherlandConstant = fvSolver().m_sutherlandConstant;
1029 MFloat m_sutherlandPlusOne = fvSolver().m_sutherlandPlusOne;
1030 MFloat m_TInfinity = fvSolver().m_TInfinity;
1031 MFloat m_flameSpeed = fvSolver().m_flameSpeed;
1032 MFloat m_turbFlameSpeed = fvSolver().m_turbFlameSpeed;
1033 MFloat m_noReactionCells = fvSolver().m_noReactionCells;
1034 MFloat m_NuT = fvSolver().m_NuT;
1035 MFloat m_ScT = fvSolver().m_ScT;
1036 MFloat m_Pr = fvSolver().m_Pr;
1037 MFloat m_integralAmplitude = fvSolver().m_integralAmplitude;
1038 MFloat m_Re0 = fvSolver().m_sysEqn.m_Re0;
1039 MFloat m_yOffsetFlameTube = fvSolver().m_yOffsetFlameTube;
1040 MInt m_temperatureChange = fvSolver().m_temperatureChange;
1041 MInt m_heatReleaseDamp = fvSolver().m_heatReleaseDamp;
1042 MInt m_bndryGhostCellsOffset = fvSolver().m_bndryGhostCellsOffset;
1043 MInt m_initialCondition = fvSolver().m_initialCondition;
1044 MFloat m_rhoUnburnt = fvSolver().m_rhoUnburnt;
1045 MFloat m_rhoFlameTube = fvSolver().m_rhoFlameTube;
1046 MInt m_restartTimeStep = fvSolver().m_restartTimeStep;
1047 // #define debugOutput
1048
1049 const MInt noCells = fvSolver().a_noCells();
1050 MInt gc;
1051 MFloat factor, Psi, xi = F0, cbar, a = F0, a1 = F0, a2 = F0, b = F0, b2 = F0, b1 = F0, c1 = F0, FD, Rr,
1052 sigma; //,d,omega
1053 MFloat reactionEnthalpy, rhoBar;
1054 const MFloat gammaMinusOne = fvSolver().m_gamma - F1;
1055 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
1056 MFloat denominator;
1057 MFloat FlaminarFlameThickness = F1 / fvSolver().m_laminarFlameThickness;
1058 MFloat rhoU, Dth;
1061 MFloat rhoJump = F1 / fvSolver().m_burntUnburntTemperatureRatio - F1;
1063 MFloat factor1 = fvSolver().m_c0 / (F1 - fvSolver().m_c0);
1064 MFloat echekkiFerzigerPrefactor = F1 / (F1 - fvSolver().m_c0) * (F1 / (F1 - fvSolver().m_c0) - F1);
1065 const MFloat sq1F2 = sqrt(F1B2);
1066 const MFloat eps = fvSolver().c_cellLengthAtLevel(fvSolver().maxRefinementLevel()) * 0.00000000001;
1067 MFloat levelSetNegative = F0, levelSetPlus = F0;
1068
1069 if(lsSolver().m_noSets > 1) {
1070 mTerm(1, AT_,
1071 "This routine should only be called if lsSolver().m_noSets = 1, which is not the case here... Please "
1072 "check!");
1073 }
1074
1075 //---
1076 // reset
1079 // compute the heat release
1080 reactionEnthalpy = (fvSolver().m_burntUnburntTemperatureRatio - F1) * FgammaMinusOne;
1081 // save old reaction rate
1082 if(fvSolver().m_RKStep == 0) {
1083 // if(hasReactionRates() && hasReactionRatesBackup())
1084 memcpy(&fvSolver().a_reactionRateBackup(0, 0), &fvSolver().a_reactionRate(0, 0),
1085 sizeof(MFloat) * fvSolver().noInternalCells());
1086 }
1087 // reset
1088 for(MInt c = 0; c < noCells; c++) {
1089 fvSolver().a_reactionRate(c, 0) = F0;
1090 }
1091 // compute the subfilter variance
1092 sigma = m_subfilterVariance * fvSolver().c_cellLengthAtLevel(fvSolver().maxLevel());
1093 factor = F1 / (sqrt(F2) * sigma);
1094 // return for no-heat release combustion
1095 if(reactionEnthalpy < m_rhoEInfinity * 0.00001) {
1096 return;
1097 }
1098 switch(m_initialCondition) {
1099 case 17516: {
1105 MInt diverged = 0;
1106 MFloat diffTimeStep = 50000;
1107 if(m_temperatureChange && (globalTimeStep - m_restartTimeStep) <= diffTimeStep) {
1108 MFloat diffTemp =
1110 fvSolver().m_burntUnburntTemperatureRatio = (diffTemp / diffTimeStep) * (globalTimeStep - m_restartTimeStep)
1112 }
1113 rhoBurnt = m_rhoFlameTube / fvSolver().m_burntUnburntTemperatureRatio;
1114 FrhoBurnt = fvSolver().m_burntUnburntTemperatureRatio * F1 / m_rhoFlameTube;
1116 for(MInt c = 0; c < m_bndryGhostCellsOffset; c++) {
1117 if(fvSolver().grid().tree().hasProperty(c, Cell::IsHalo)) {
1118 continue;
1119 }
1120 if(!fvSolver().a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
1121 continue;
1122 }
1123 MInt cLs = fv2lsId(c);
1124 if(cLs < 0) {
1125 continue;
1126 }
1127 gc = cLs;
1128 // MInt gcFv= ls2fvId(gc);
1129 if(gc == -1) {
1130 continue;
1131 }
1132 // continue if the g cell is out of the band
1133 // the source term is in this case zero
1134 if(ABS(lsSolver().m_outsideGValue - ABS(lsSolver().a_levelSetFunctionG(gc, 0))) < 0.02) {
1135 continue;
1136 }
1137 if(lsSolver().a_level(gc) != fvSolver().maxRefinementLevel()) {
1138 continue;
1139 }
1140 // compute the Echekki-Ferziger constant
1141 // - compute the inverse eddy viscosity (s/m^2)
1142 // - - density of the unburnt gas rho^u = fvSolver().m_rhoInfinity
1143 // - - assuming m_TInfinity is the temperature of the unburnt gas -> muInf=SUTHERLANDLAW(m_TInfinity)
1144 // - - DthInf = muInf^u / ( rho^u *Pr )
1145 FD = F1 / fvSolver().m_DthInfinity;
1146 // - compute Rr
1147 levelSetNegative = lsSolver().a_levelSetFunctionG(gc, 0) - m_noReactionCells;
1148 levelSetPlus = lsSolver().a_levelSetFunctionG(gc, 0) + m_noReactionCells;
1149
1150 if(m_useCorrectedBurningVelocity) {
1151 if(lsSolver().m_sharpDamp) {
1152 Rr = echekkiFerzigerPrefactor * POW2(lsSolver().a_correctedBurningVelocity(gc, 0)) * FD * F1B4
1153 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
1154 } else {
1155 Rr = echekkiFerzigerPrefactor * POW2(lsSolver().a_correctedBurningVelocity(gc, 0)) * FD;
1156 }
1157 } else {
1158 if(lsSolver().m_sharpDamp) {
1159 Rr = echekkiFerzigerPrefactor
1160 * POW2(lsSolver().a_flameSpeedG(gc, 0) * (F1 - lsSolver().a_curvatureG(gc, 0) * m_marksteinLength))
1161 * FD * F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
1162 } else {
1163 Rr = echekkiFerzigerPrefactor
1164 * POW2(lsSolver().a_flameSpeedG(gc, 0) * (F1 - lsSolver().a_curvatureG(gc, 0) * m_marksteinLength))
1165 * FD;
1166 }
1167 }
1168
1169 // damp out the reaction rate to the wall w(y=0.0341) = 0 by damping the model constant Rr(y=0.0341)=0
1170 if(m_heatReleaseDamp) {
1171 if(lsSolver().c_coordinate(gc, 1) < (0.0234 + m_dampingDistanceFlameBase)) {
1172 if(lsSolver().c_coordinate(gc, 1) > 0.0234) {
1173 Rr *= 1. / m_dampingDistanceFlameBase * (lsSolver().c_coordinate(gc, 1) - 0.0234);
1174 }
1175 }
1176 if(lsSolver().c_coordinate(gc, 1) < 0.0234) {
1177 Rr = F0;
1178 }
1179 }
1180 // compute Psi
1181 // - compute xi
1182 xi = lsSolver().a_levelSetFunctionG(gc, 0) * factor; //< xi = G(x,t)/(sigma*sqrt(2))
1183
1184 // - compute c bar
1185 a = xi - sq1F2 * factor1 * sigma * FlaminarFlameThickness;
1186 a1 = F1B2 * (POW2(sigma * factor1 * FlaminarFlameThickness))
1187 - SQRT2 * xi * sigma * factor1 * FlaminarFlameThickness;
1188 if(a > F3) {
1189 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2
1190 * (-erfc(a) + F2); // erfc computes 1-erf and is more accurate for large a
1191 } else {
1192 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2 * (erf(a) + F1);
1193 }
1194 b = xi + sq1F2 * sigma * FlaminarFlameThickness;
1195 b1 = F1B2 * POW2(sigma * FlaminarFlameThickness) + SQRT2 * xi * sigma * FlaminarFlameThickness;
1196 if(b > F3) {
1197 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (-erfc(b)); // erfc computes 1-erf and is more accurate for large b
1198 } else {
1199 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (erf(b) - F1);
1200 }
1201 c1 = F1B2 * (erf(xi) - F1);
1202 cbar = F1 - (a2 + b2 - c1);
1203
1204 // - compute Psi
1205 if(ABS(F1 - cbar) < eps) {
1206 Psi = F1;
1207 } else {
1208 Psi = a2 / ((F1 - cbar) * POW2((rhoUFrhoB + cbar * rhoJump)));
1209 }
1210
1211 fvSolver().a_psi(c) = Psi;
1212
1213 // compute rhoBar
1214 rhoBar = m_rhoUnburnt / (1 - fvSolver().a_pvariable(c, fvSolver().PV->C) * rhoJump);
1215
1216 // compute the source term
1217 fvSolver().a_reactionRate(c, 0) =
1218 m_Re0 * rhoBar * rhoUFrhoB * Rr * (F1 - fvSolver().a_pvariable(c, fvSolver().PV->C)) * Psi;
1219
1220 // catch nan reaction rate
1221 if(!(fvSolver().a_reactionRate(c, 0) >= F0) && !(fvSolver().a_reactionRate(c, 0) <= F0)) {
1222 diverged = 1;
1223 cerr << "reaction rate is nan!!!" << endl;
1224 // cerr << "b=" << b << " " << "b1=" << b1 << " " << "exp(b1)=" << exp(b1) << " " << "b2=" << b2 << " " <<
1225 // "c1="
1226 // << c1 << endl;
1227 // cerr << "a=" << a << " " << "a1=" << a1 << " " << "a2=" << a2 << endl;
1228 // cerr << "g cell info for " << gc << endl;
1229 // cerr << "gc_coordx=" << lsSolver().c_coordinate(gc, 0) << " " << "gc_coordy=" <<
1230 // lsSolver().c_coordinate(gc, 1) << " glevel "
1231 // << lsSolver().a_level(gc) << " inBand " << lsSolver().a_inBandG(gc, 0) << " in shadow layer " <<
1232 // lsSolver().a_inShadowLayerG(gc)
1233 // << " no childs " << lsSolver().a_noChildrenG(gc) << endl;
1234 // cerr << "is GWindow Cell " << lsSolver().a_isGWindowCellG(gc) << endl;
1235 // cerr << "is GHalo Cell " << lsSolver().a_isGHaloCellG(gc) << endl;
1236 // cerr << "levelsetfunction=" << lsSolver().a_levelSetFunctionG(IDX_LSSET(gc, 0)] << " " << "xi=" << xi <<
1237 // endl; cerr << "cbar=" << cbar << " " << "Psi=" << Psi << " " << "rhoBar=" << rhoBar << " " << "c="
1239 // cerr << "rho=" << fvSolver().a_pvariable(c, fvSolver().PV->RHO) << endl;
1240 // cerr << "rhoUnburnt=" << m_rhoUnburnt << endl;
1241 // cerr << "global cell info for " << fvSolver().c_globalId(c) << endl;
1242 // cerr << "cell level " << a_level(c) << endl;
1243 // cerr << "window cell " << fvSolver().a_hasProperty(c, Cell::IsWindow) << endl;
1244 // cerr << "halo cell " << fvSolver().a_hasProperty(c, Cell::IsHalo) << endl;
1245 // cerr << "x=" << fvSolver().a_coordinate(c, 0) << " "
1246 //<< "y=" << fvSolver().a_coordinate(c, 1) << " "
1247 //<< "z=" << fvSolver().a_coordinate(c, 2) << endl;
1248 // fvSolver().a_reactionRate(c, 0) = 1000.0;
1249 }
1250
1251 // compute the source terms
1252 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_C) -=
1254 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_E) -=
1255 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1256
1257 // compute the maximum reaction rate and the total heat release
1258 if(!fvSolver().a_hasProperty(c, Cell::IsHalo)) {
1259 fvSolver().m_maxReactionRate = mMax(fvSolver().a_reactionRate(c, 0), fvSolver().m_maxReactionRate);
1261 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1262 }
1263 }
1264 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_INT, MPI_MAX, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1265 "diverged");
1266 if(diverged == 1) {
1267 cerr << "Solution diverged, writing NETCDF file for debugging" << endl;
1268 MString errorMessage = "reaction rate is nan";
1270 stringstream fileNameVtk;
1271 stringstream levelSetFileName;
1272 levelSetFileName << "restartLevelSetNewGCellGrid_"
1273 << "debug";
1274
1275 stringstream levelSetFileNameSol;
1276 levelSetFileNameSol << "restartLevelSetNew_"
1277 << "debug";
1278
1279 lsSolver().writeRestartLevelSetFileCG(1, (levelSetFileName.str()).c_str(), (levelSetFileNameSol.str()).c_str());
1280
1281 mTerm(1, AT_, errorMessage);
1282 }
1283
1284 break;
1285 }
1286 case 1751600: {
1292 // MFloat
1293 // minRr=10000,maxRr=-10000,minPsi=10000,maxPsi=-10000,minVol=10000,maxVol=-10000,minA2=10000,maxA2=-10000,maxCurvature=-10000,minCurvature=10000;
1294 MInt diverged = 0;
1295 MFloat diffTimeStep = 50000;
1296 if(m_temperatureChange && (globalTimeStep - m_restartTimeStep) <= diffTimeStep) {
1297 MFloat diffTemp =
1299 fvSolver().m_burntUnburntTemperatureRatio = (diffTemp / diffTimeStep) * (globalTimeStep - m_restartTimeStep)
1301 }
1302 rhoBurnt = m_rhoFlameTube / fvSolver().m_burntUnburntTemperatureRatio;
1303 FrhoBurnt = fvSolver().m_burntUnburntTemperatureRatio * F1 / m_rhoFlameTube;
1305 for(MInt c = 0; c < m_bndryGhostCellsOffset; c++) {
1306 if(fvSolver().grid().tree().hasProperty(c, Cell::IsHalo)) {
1307 continue;
1308 }
1309 if(!fvSolver().a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
1310 continue;
1311 }
1312 MInt cLs = fv2lsId(c);
1313 if(cLs < 0) {
1314 continue;
1315 }
1316 gc = cLs;
1317 if(gc == -1) {
1318 continue;
1319 }
1320 // continue if the g cell is out of the band
1321 // the source term is in this case zero
1322 if(ABS(lsSolver().m_outsideGValue - ABS(lsSolver().a_levelSetFunctionG(gc, 0))) < eps) {
1323 continue;
1324 }
1325 // compute the Echekki-Ferziger constant
1326 // - compute the inverse eddy viscosity (s/m^2)
1327 // - - density of the unburnt gas rho^u = fvSolver().m_rhoInfinity
1328 // - - assuming m_TInfinity is the temperature of the unburnt gas -> muInf=SUTHERLANDLAW(m_TInfinity)
1329 // - - DthInf = muInf^u / ( rho^u *Pr )
1330 FD = F1 / fvSolver().m_DthInfinity;
1331 // - compute Rr
1332 levelSetNegative = lsSolver().a_levelSetFunctionG(gc, 0) - m_noReactionCells;
1333 levelSetPlus = lsSolver().a_levelSetFunctionG(gc, 0) + m_noReactionCells;
1334
1335 if(!m_constantFlameSpeed) {
1336 if(lsSolver().m_sharpDamp) {
1337 Rr = echekkiFerzigerPrefactor
1338 * POW2(lsSolver().a_flameSpeedG(gc, 0) * (F1 - lsSolver().a_curvatureG(gc, 0) * m_marksteinLength))
1339 * FD * F1B4 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
1340 } else {
1341 Rr = echekkiFerzigerPrefactor
1342 * POW2(lsSolver().a_flameSpeedG(gc, 0) * (F1 - lsSolver().a_curvatureG(gc, 0) * m_marksteinLength))
1343 * FD;
1344 }
1345 } else {
1346 if(lsSolver().m_sharpDamp) {
1347 Rr = echekkiFerzigerPrefactor * POW2(lsSolver().a_flameSpeedG(gc, 0)) * FD * F1B4
1348 * (1 + tanh(levelSetPlus * 100.0)) * (1 - tanh(levelSetNegative * 100.0));
1349 } else {
1350 Rr = echekkiFerzigerPrefactor * POW2(lsSolver().a_flameSpeedG(gc, 0)) * FD;
1351 }
1352 }
1353 // damp out the reaction rate to the wall w(y=0.0341) = 0 by damping the model constant Rr(y=0.0341)=0
1354 if(m_heatReleaseDamp) {
1355 if(lsSolver().c_coordinate(gc, 1) < (m_yOffsetFlameTube + m_dampingDistanceFlameBase)) {
1356 if(lsSolver().c_coordinate(gc, 1) > m_yOffsetFlameTube) {
1357 Rr *= 1. / m_dampingDistanceFlameBase * (lsSolver().c_coordinate(gc, 1) - m_yOffsetFlameTube);
1358 }
1359 }
1360 if(lsSolver().c_coordinate(gc, 1) < m_yOffsetFlameTube) {
1361 Rr = F0;
1362 }
1363 }
1364
1365 xi = lsSolver().a_levelSetFunctionG(gc, 0) * factor; //< xi = G(x,t)/(sigma*sqrt(2))
1366
1367 // - compute c bar
1368 a = xi - sq1F2 * factor1 * sigma * FlaminarFlameThickness;
1369 a1 = F1B2 * (POW2(sigma * factor1 * FlaminarFlameThickness))
1370 - SQRT2 * xi * sigma * factor1 * FlaminarFlameThickness;
1371 if(a > F3) {
1372 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2
1373 * (-erfc(a) + F2); // erfc computes 1-erf and is more accurate for large a
1374 } else {
1375 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2 * (erf(a) + F1);
1376 }
1377 b = xi + sq1F2 * sigma * FlaminarFlameThickness;
1378 b1 = F1B2 * POW2(sigma * FlaminarFlameThickness) + SQRT2 * xi * sigma * FlaminarFlameThickness;
1379 if(b > F3) {
1380 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (-erfc(b)); // erfc computes 1-erf and is more accurate for large b
1381 } else {
1382 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (erf(b) - F1);
1383 }
1384 c1 = F1B2 * (erf(xi) - F1);
1385 cbar = F1 - (a2 + b2 - c1);
1386
1387 // - compute Psi
1388 if(ABS(F1 - cbar) < eps) {
1389 Psi = F1;
1390 } else {
1391 Psi = a2 / ((F1 - cbar) * POW2((rhoUFrhoB + cbar * rhoJump)));
1392 }
1393
1394 fvSolver().a_psi(c) = Psi;
1395
1396 // compute rhoBar
1397 rhoBar = m_rhoUnburnt / (1 - fvSolver().a_pvariable(c, fvSolver().PV->C) * rhoJump);
1398
1399 // compute the source term
1400 fvSolver().a_reactionRate(c, 0) =
1401 m_Re0 * rhoBar * rhoUFrhoB * Rr * (F1 - fvSolver().a_pvariable(c, fvSolver().PV->C)) * Psi;
1402
1403 // catch nan reaction rate
1404 if(!(fvSolver().a_reactionRate(c, 0) >= F0) && !(fvSolver().a_reactionRate(c, 0) <= F0)) {
1405 diverged = 1;
1406 // m_log << "reaction rate is nan!!!" << endl;
1407 // m_log << "b=" << b << " " << "b1=" << b1 << " " << "exp(b1)=" << exp(b1) << " " << "b2=" << b2 << " "
1408 //<< "c1=" << c1 << endl;
1409 // m_log << "a=" << a << " " << "a1=" << a1 << " " << "a2=" << a2 << endl;
1410 // m_log << "g cell info for " << gc << endl;
1411 // m_log << "gc_coordx=" << lsSolver().c_coordinate(gc, 0) << " " << "gc_coordy=" <<
1412 // lsSolver().c_coordinate(gc, 1) << " glevel "
1413 //<< lsSolver().a_level(gc) << " inBand " << lsSolver().a_inBandG(gc, 0) << " in shadow layer " <<
1414 // lsSolver().a_inShadowLayerG(gc)
1415 //<< " no childs " << lsSolver().a_noChildrenG(gc) << endl;
1416 // m_log << "is GWindow Cell " << lsSolver().a_isGWindowCellG(gc) << endl;
1417 // m_log << "is GHalo Cell " << lsSolver().a_isGHaloCellG(gc) << endl;
1418 // m_log << "levelsetfunction=" << lsSolver().a_levelSetFunctionG(IDX_LSSET(gc, 0)] << " " << "xi=" << xi
1419 // << endl; m_log << "cbar=" << cbar << " " << "Psi=" << Psi << " " << "rhoBar=" << rhoBar << " " << "c="
1420 //<< fvSolver().a_pvariable(c, fvSolver().PV->C) << endl;
1421 // m_log << "rho=" << fvSolver().a_pvariable(c, fvSolver().PV->RHO) << endl;
1422 // m_log << "rhoUnburnt=" << m_rhoUnburnt << endl;
1423 // m_log << "global cell info for " << fvSolver().c_globalId(c) << endl;
1424 // m_log << "cell level " << a_level(c) << endl;
1425 // m_log << "window cell " << fvSolver().a_hasProperty(c, Cell::IsWindow) << endl;
1426 // m_log << "halo cell " << fvSolver().a_hasProperty(c, Cell::IsHalo) << endl;
1427 // m_log << "x=" << fvSolver().a_coordinate(c, 0) << " "
1428 //<< "y=" << fvSolver().a_coordinate(c, 1) << " "
1429 //<< "z=" << fvSolver().a_coordinate(c, 2) << endl;
1430 // fvSolver().a_reactionRate(c, 0) = 1000.0;
1431 }
1432
1433 // compute the source terms
1434 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_C) -=
1436 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_E) -=
1437 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1438
1439 // compute the maximum reaction rate and the total heat release
1440 if(!fvSolver().a_hasProperty(c, Cell::IsHalo)) {
1441 fvSolver().m_maxReactionRate = mMax(fvSolver().a_reactionRate(c, 0), fvSolver().m_maxReactionRate);
1443 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1444 }
1445 }
1446 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_INT, MPI_MAX, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1447 "diverged");
1448 if(diverged == 1) {
1449 // m_log << "Solution diverged, writing NETCDF file for debugging" << endl;
1450 MString errorMessage = "reaction rate is nan";
1451 // saveSolverSolution(1);
1452 // stringstream fileNameVtk;
1453 // stringstream levelSetFileName;
1454 // levelSetFileName << "restartLevelSetNewGCellGrid_" << "debug";
1455 //
1456 // stringstream levelSetFileNameSol;
1457 // levelSetFileNameSol << "restartLevelSetNew_" << "debug";
1458 //
1459
1460 mTerm(1, AT_, errorMessage);
1461 }
1462
1463 break;
1464 }
1465 // new flame speed model for turbulent flames, see Pitsch et al. 2005
1466 case 5401000:
1467 case 2751600: {
1468 MInt diverged = 0;
1469 MFloat diffTimeStep = 50000;
1470 if(m_temperatureChange && (globalTimeStep - m_restartTimeStep) <= diffTimeStep) {
1471 MFloat diffTemp =
1473 fvSolver().m_burntUnburntTemperatureRatio = (diffTemp / diffTimeStep) * (globalTimeStep - m_restartTimeStep)
1475 }
1476 rhoBurnt = m_rhoFlameTube / fvSolver().m_burntUnburntTemperatureRatio;
1477
1478 FrhoBurnt = fvSolver().m_burntUnburntTemperatureRatio * F1 / m_rhoFlameTube;
1479
1481
1482 for(MInt c = 0; c < m_bndryGhostCellsOffset; c++) {
1483 if(fvSolver().grid().tree().hasProperty(c, Cell::IsHalo)) {
1484 continue;
1485 }
1486 if(!fvSolver().a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
1487 continue;
1488 }
1489 MInt cLs = fv2lsId(c);
1490 if(cLs < 0) {
1491 continue;
1492 }
1493 gc = cLs;
1494
1495 if(gc == -1) {
1496 continue;
1497 }
1498
1499 // continue if the g cell is out of the band
1500 // the source term is in this case zero
1501 if(ABS(lsSolver().m_outsideGValue - ABS(lsSolver().a_levelSetFunctionG(gc, 0))) < eps) {
1502 continue;
1503 }
1504
1505 // compute the Echekki-Ferziger constant
1506 // - compute the inverse eddy viscosity (s/m^2)
1507 // - - density of the unburnt gas rho^u = fvSolver().m_rhoInfinity
1508 // - - assuming m_TInfinity is the temperature of the unburnt gas -> muInf=SUTHERLANDLAW(m_TInfinity)
1509 // - - DthInf = muInf^u / ( rho^u *Pr )
1510 FD = F1 / fvSolver().m_DthInfinity;
1511 // - compute Rr
1512 levelSetNegative = lsSolver().a_levelSetFunctionG(gc, 0) - m_noReactionCells;
1513 levelSetPlus = lsSolver().a_levelSetFunctionG(gc, 0) + m_noReactionCells;
1514
1515 // turb. flame speed model, see Pitsch et al. 2005
1516 MFloat turbFlameSpeed = m_turbFlameSpeed; // once calculated
1517 MFloat delta = fvSolver().c_cellLengthAtLevel(fvSolver().maxLevel()); // LES filter width equals grid siz
1518 MFloat uAmpl = pow(m_integralAmplitude, 3); // filtered velocity
1519 uAmpl *= delta;
1520 uAmpl /= m_integralLengthScale;
1521 uAmpl = pow(uAmpl, F1B3); // filtered velocity Pitsch et al. 2005
1522 MFloat flameSpeed = m_flameSpeed;
1523
1524 MFloat Dt = m_NuT / m_ScT;
1525
1526 MFloat FDa = Dt;
1527 if(fvSolver().m_Da > 1) {
1528 FDa *= F1 / pow(fvSolver().m_Da, 2);
1529 }
1530 // flame stretch effects (Freitag et al. 2007)
1531 flameSpeed *= (F1
1532 - lsSolver().a_curvatureG(gc, 0)
1533 * m_marksteinLength); //(+=fvSolver().m_DthInfinity * lsSolver().a_curvatureG( gc , 0) );
1534 // turb. flame speed
1535 flameSpeed += turbFlameSpeed;
1536 // turb. stretch effects
1537 flameSpeed -= FDa * lsSolver().a_curvatureG(gc, 0);
1538 // take the power of 2
1539 flameSpeed = pow(flameSpeed, 2);
1540
1541
1542 Rr = echekkiFerzigerPrefactor * flameSpeed * FD;
1543
1544 // damp out the reaction rate to the wall w(y=0.0341) = 0 by damping the model constant Rr(y=0.0341)=0
1545 if(m_heatReleaseDamp) {
1546 if(lsSolver().c_coordinate(gc, 1) < (m_yOffsetFlameTube + m_dampingDistanceFlameBase)) {
1547 if(lsSolver().c_coordinate(gc, 1) > m_yOffsetFlameTube) {
1548 Rr *= 1. / m_dampingDistanceFlameBase * (lsSolver().c_coordinate(gc, 1) - m_yOffsetFlameTube);
1549 }
1550 }
1551 if(lsSolver().c_coordinate(gc, 1) < m_yOffsetFlameTube) {
1552 Rr = F0;
1553 }
1554 }
1555
1556 // compute Psi
1557 // - compute xi
1558
1559 xi = lsSolver().a_levelSetFunctionG(gc, 0) * factor; //< xi = G(x,t)/(sigma*sqrt(2))
1560
1561 // - compute c bar
1562 a = xi - sq1F2 * factor1 * sigma * FlaminarFlameThickness;
1563 a1 = F1B2 * (POW2(sigma * factor1 * FlaminarFlameThickness))
1564 - SQRT2 * xi * sigma * factor1 * FlaminarFlameThickness;
1565 if(a > F3) {
1566 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2
1567 * (-erfc(a) + F2); // erfc computes 1-erf and is more accurate for large a
1568 } else {
1569 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2 * (erf(a) + F1);
1570 }
1571 b = xi + sq1F2 * sigma * FlaminarFlameThickness;
1572 b1 = F1B2 * POW2(sigma * FlaminarFlameThickness) + SQRT2 * xi * sigma * FlaminarFlameThickness;
1573 if(b > F3) {
1574 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (-erfc(b)); // erfc computes 1-erf and is more accurate for large b
1575 } else {
1576 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (erf(b) - F1);
1577 }
1578 c1 = F1B2 * (erf(xi) - F1);
1579 cbar = F1 - (a2 + b2 - c1);
1580
1581 // - compute Psi
1582 if(ABS(F1 - cbar) < eps) {
1583 Psi = F1;
1584 } else {
1585 Psi = a2 / ((F1 - cbar) * POW2((rhoUFrhoB + cbar * rhoJump)));
1586 }
1587
1588 fvSolver().a_psi(c) = Psi;
1589
1590 // compute rhoBar
1591 rhoBar = m_rhoUnburnt / (1 - fvSolver().a_pvariable(c, fvSolver().PV->C) * rhoJump);
1592
1593 // compute the source term
1594 fvSolver().a_reactionRate(c, 0) =
1595 m_Re0 * rhoBar * rhoUFrhoB * Rr * (F1 - fvSolver().a_pvariable(c, fvSolver().PV->C)) * Psi;
1596
1597 // catch nan reaction rate
1598 if(!(fvSolver().a_reactionRate(c, 0) >= F0) && !(fvSolver().a_reactionRate(c, 0) <= F0)) {
1599 diverged = 1;
1600 // m_log << "reaction rate is nan!!!" << endl;
1601 // m_log << "b=" << b << " " << "b1=" << b1 << " " << "exp(b1)=" << exp(b1) << " " << "b2=" << b2 << " "
1602 //<< "c1=" << c1 << endl;
1603 // m_log << "a=" << a << " " << "a1=" << a1 << " " << "a2=" << a2 << endl;
1604 // m_log << "g cell info for " << gc << endl;
1605 // m_log << "gc_coordx=" << lsSolver().c_coordinate(gc, 0) << " " << "gc_coordy=" <<
1606 // lsSolver().c_coordinate(gc, 1) << " glevel "
1607 //<< lsSolver().a_level(gc) << " inBand " << lsSolver().a_inBandG(gc, 0) << " in shadow layer " <<
1608 // lsSolver().a_inShadowLayerG(gc)
1609 //<< " no childs " << lsSolver().a_noChildrenG(gc) << endl;
1610 // m_log << "is GWindow Cell " << lsSolver().a_isGWindowCellG(gc) << endl;
1611 // m_log << "is GHalo Cell " << lsSolver().a_isGHaloCellG(gc) << endl;
1612 // m_log << "levelsetfunction=" << lsSolver().a_levelSetFunctionG(IDX_LSSET(gc, 0)] << " " << "xi=" << xi
1613 // << endl; m_log << "cbar=" << cbar << " " << "Psi=" << Psi << " " << "rhoBar=" << rhoBar << " " << "c="
1614 //<< fvSolver().a_pvariable(c, fvSolver().PV->C) << endl;
1615 // m_log << "rho=" << fvSolver().a_pvariable(c, fvSolver().PV->RHO) << endl;
1616 // m_log << "rhoUnburnt=" << m_rhoUnburnt << endl;
1617 // m_log << "global cell info for " << fvSolver().c_globalId(c) << endl;
1618 // m_log << "cell level " << a_level(c) << endl;
1619 // m_log << "window cell " << fvSolver().a_hasProperty(c, Cell::IsWindow) << endl;
1620 // m_log << "halo cell " << fvSolver().a_hasProperty(c, Cell::IsHalo) << endl;
1621 // m_log << "x=" << fvSolver().a_coordinate(c, 0) << " "
1622 //<< "y=" << fvSolver().a_coordinate(c, 1) << " "
1623 //<< "z=" << fvSolver().a_coordinate(c, 2) << endl;
1624 // fvSolver().a_reactionRate(c, 0) = 1000.0;
1625 }
1626
1627 // compute the source terms
1628 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_C) -=
1630 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_E) -=
1631 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1632
1633 // compute the maximum reaction rate and the total heat release
1634 if(!fvSolver().a_hasProperty(c, Cell::IsHalo)) {
1635 fvSolver().m_maxReactionRate = mMax(fvSolver().a_reactionRate(c, 0), fvSolver().m_maxReactionRate);
1637 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1638 }
1639 }
1640 MPI_Allreduce(MPI_IN_PLACE, &diverged, 1, MPI_INT, MPI_MAX, fvSolver().mpiComm(), AT_, "MPI_IN_PLACE",
1641 "diverged");
1642 if(diverged == 1) {
1643 // m_log << "Solution diverged, writing NETCDF file for debugging" << endl;
1644 MString errorMessage = "reaction rate is nan";
1645 // saveSolverSolution(1);
1646 // stringstream fileNameVtk;
1647 mTerm(1, AT_, errorMessage);
1648 }
1649 break;
1650 }
1651 default: {
1652 for(MInt c = 0; c < m_bndryGhostCellsOffset; c++) {
1653 if(fvSolver().grid().tree().hasProperty(c, Cell::IsHalo)) {
1654 continue;
1655 }
1656 if(!fvSolver().a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
1657 continue;
1658 }
1659 MInt cLs = fv2lsId(c);
1660 if(cLs < 0) {
1661 continue;
1662 }
1663 gc = cLs;
1664 if(gc == -1) {
1665 continue;
1666 }
1667
1668 // continue if the g cell is out of the band
1669 // the source term is in this case zero
1670 if(ABS(lsSolver().m_outsideGValue - ABS(lsSolver().a_levelSetFunctionG(gc, 0))) < eps) {
1671 continue;
1672 }
1673
1674 // compute the Echekki-Ferziger constant
1675 // - compute the inverse eddy viscosity (s/m^2)
1676 // - - density of the unburnt gas
1677 rhoU = fvSolver().m_rhoInfinity;
1678 // - - assuming m_TInfinity is the temperature of the unburnt gas
1679 // - - Dth = mue^u / ( rho^u *Pr )
1680 Dth = SUTHERLANDLAW(m_TInfinity) / (rhoU * m_Pr);
1681 FD = F1 / Dth;
1682 // - compute Rr
1683 Rr = echekkiFerzigerPrefactor * POW2(lsSolver().a_correctedBurningVelocity(gc, 0)) * FD;
1684
1685 // compute Psi
1686 // - compute xi
1687 xi = lsSolver().a_levelSetFunctionG(gc, 0) * factor;
1688 // - compute c bar
1689 a = xi - sq1F2 * factor1 * sigma * FlaminarFlameThickness;
1690
1691 a1 = F1B2 * (POW2(sigma * factor1 * FlaminarFlameThickness))
1692 - SQRT2 * xi * sigma * factor1 * FlaminarFlameThickness;
1693 if(a > F3) {
1694 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2
1695 * (-erfc(a) + F2); // erfc computes 1-erf and is more accurate for large a
1696 } else {
1697 a2 = (F1 - fvSolver().m_c0) * exp(a1) * F1B2 * (erf(a) + F1);
1698 }
1699 b = xi + sq1F2 * sigma * FlaminarFlameThickness;
1700 b1 = F1B2 * POW2(sigma * FlaminarFlameThickness) + SQRT2 * xi * sigma * FlaminarFlameThickness;
1701 if(b > F3) {
1702 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (-erfc(b)); // erfc computes 1-erf and is more accurate for large b
1703 } else {
1704 b2 = fvSolver().m_c0 * exp(b1) * F1B2 * (erf(b) - F1);
1705 }
1706 c1 = F1B2 * (erf(xi) - F1);
1707 cbar = F1 - (a2 + b2 - c1);
1708 // - compute Psi
1709 denominator = (F1 - cbar) * POW2((rhoUFrhoB + cbar * rhoJump * FrhoBurnt));
1710 if(approx(denominator, 0.0, MFloatEps)) {
1711 Psi = F1;
1712 } else {
1713 Psi = a2 / denominator;
1714 }
1715
1716 // compute rhoBar
1717 rhoBar = fvSolver().m_rhoInfinity / (1 - fvSolver().a_pvariable(c, fvSolver().PV->C) * rhoJump / rhoBurnt);
1718
1719 // compute the source term
1720 fvSolver().a_reactionRate(c, 0) = m_Re0 * fvSolver().a_pvariable(c, fvSolver().PV->RHO) * rhoUFrhoB * Rr
1721 * (F1 - fvSolver().a_pvariable(c, fvSolver().PV->C)) * Psi;
1722
1723 // catch nan reaction rate
1724 if(!(fvSolver().a_reactionRate(c, 0) >= F0) && !(fvSolver().a_reactionRate(c, 0) <= F0)) {
1725 // cerr << "reaction rate is nan!!!" << endl;
1726 // cerr << b << " " << b1 << " " << exp(b1) << " " << b2 << " " << c1 << endl;
1727 // cerr << a << " " << a1 << " " << a2 << endl;
1728 // cerr << gc << " " << lsSolver().c_coordinate(gc, 0) << " " << lsSolver().c_coordinate(gc, 1) << " " <<
1729 // lsSolver().c_coordinate(gc, 2)
1730 //<< endl;
1731 // cerr << lsSolver().a_levelSetFunctionG(IDX_LSSET(gc, 0)] << " " << xi << endl;
1732 // cerr << cbar << " " << Psi << " " << rhoBar << " " << fvSolver().a_pvariable(c, fvSolver().PV->C) << endl;
1733 // cerr << "cell info for " << c << endl;
1734 // cerr << a_level(c) << endl;
1735 // cerr << fvSolver().a_coordinate(c, 0) << " "
1736 //<< fvSolver().a_coordinate(c, 1) << " "
1737 //<< fvSolver().a_coordinate(c, 2) << endl;
1738 // fvSolver().a_reactionRate(c, 0) = 1000.0;
1739 // saveSolverSolution(1);
1740 mTerm(1, AT_, "reaction rate is nan!!!");
1741 }
1742
1743 // compute the source terms
1744 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_C) -=
1746 fvSolver().a_rightHandSide(c, fvSolver().CV->RHO_E) -=
1747 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1748
1749 // compute the maximum reaction rate and the total heat release
1750 fvSolver().m_maxReactionRate = mMax(fvSolver().a_reactionRate(c, 0), fvSolver().m_maxReactionRate);
1752 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(c) * reactionEnthalpy;
1753 }
1754 break;
1755 }
1756 }
1757 if(fvSolver().noDomains() > 1) {
1758 MPI_Allreduce(MPI_IN_PLACE, &fvSolver().m_totalHeatReleaseRate, 1, MPI_DOUBLE, MPI_SUM, fvSolver().mpiComm(), AT_,
1759 "MPI_IN_PLACE", "fvSolver().m_totalHeatReleaseRate");
1760 MPI_Allreduce(MPI_IN_PLACE, &fvSolver().m_maxReactionRate, 1, MPI_DOUBLE, MPI_MAX, fvSolver().mpiComm(), AT_,
1761 "MPI_IN_PLACE", "fvSolver().m_maxReactionRate");
1762 }
1763}
MFloat & a_psi(const MInt cellId)
Returns psi of the cell cellId for variables varId.
MFloat & a_rightHandSide(const MInt cellId, MInt const varId)
Returns the right hand side of the cell cellId for the variable varId.
MFloat c_cellLengthAtLevel(const MInt level) const
Returns the length of the cell for level.
void saveSolverSolution(const MBool forceOutput=false, const MBool finalTimeStep=false) override
Manages solver-specific output.
MInt a_noCells() const
Returns the number of cells.
MFloat & a_reactionRate(const MInt cellId, const MInt reactionId)
Returns the reactionRate of the cell cellId for variables varId.
MFloat & a_cellVolume(const MInt cellId)
Returns the cell volume of the cell from the fvcellcollector cellId.
MFloat & a_curvatureG(const MInt cellId, const MInt set)
Returns curvature of the cell cellId for set set.
virtual void writeRestartLevelSetFileCG(MBool, const MString &, const MString &)
MFloat c_coordinate(const MInt gCellId, const MInt dim) const
Returns the coordinate of the cell cellId for direction dim.
MInt m_restartTimeStep
Definition: solver.h:80
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
constexpr Real POW2(const Real x)
Definition: functions.h:119
Real ABS(const Real x)
Definition: functions.h:85
MBool approx(const T &, const U &, const T)
Definition: functions.h:272
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
MInt globalTimeStep
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
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
Definition: contexttypes.h:19

◆ constructExtensionVelocity()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::constructExtensionVelocity

Definition at line 63 of file lsfvcombustion.cpp.

63 {
64 if(lsSolver().m_gRKStep != 0) return;
65 if(!lsSolver().m_computeExtVel) return;
66
67 if(!lsSolver().m_smoothExtVel) {
69 return;
70 }
71 switch(lsSolver().m_computeExtVel) {
72 case 700: {
73 for(MInt set = lsSolver().m_startSet; set < lsSolver().m_noSets; set++) {
74 MFloatScratchSpace fluidDensity(lsSolver().a_noG0Cells(set), AT_, "fluidDensity");
75 fluidDensity.fill(-F1);
76 if(!lsSolver().m_interpolateFlowFieldToFlameFront) {
77 collectGEquationModelDataOpt(fluidDensity.getPointer(), set);
78 } else {
79 collectGEquationModelDataOptInterpolate(fluidDensity.getPointer(), set);
80 }
81 lsSolver().computeExtensionVelocityGEQUPVMarksteinOpt(fluidDensity.getPointer(), set);
82 }
83 break;
84 }
85 default: {
86 break;
87 }
88 }
89}
void computeExtensionVelocityGEQUPVMarksteinOpt(MFloat *FfluidDensity, MInt set)
void collectGEquationModelDataOpt(MFloat *fluidDensity, MInt set)
void fastInterfaceExtensionVelocity()
void collectGEquationModelDataOptInterpolate(MFloat *fluidDensity, MInt set)
transfers v from the flow to the G-grid (highest level) via interpolation
This class is a ScratchSpace.
Definition: scratch.h:758

◆ exchangeCouplingData()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::exchangeCouplingData

Definition at line 135 of file lsfvcombustion.cpp.

135 {
136 // set levelset function in the fv solver
137 for(MInt c = 0; c < fvSolver().m_bndryGhostCellsOffset; c++) {
138 if(fvSolver().grid().tree().hasProperty(c, Cell::IsHalo)) {
139 continue;
140 }
141 if(!fvSolver().a_hasProperty(c, SolverCell::IsOnCurrentMGLevel)) {
142 continue;
143 }
144 MInt cLs = fv2lsId(c);
145 // TODO labels:COUPLER,FV,LS,toenhance some cells need to be skipped in the FV solver.
146 // uses a very small dummy value for now.
147 if(cLs < 0) {
148 fvSolver().a_levelSetFunction(c, 0) = -999999;
149 continue;
150 }
151 MInt gc = cLs;
152
153 if(ABS(lsSolver().m_outsideGValue - ABS(lsSolver().a_levelSetFunctionG(gc, 0))) < 0.02) {
154 fvSolver().a_levelSetFunction(c, 0) = -999999;
155 continue;
156 }
157 if(lsSolver().a_level(gc) != fvSolver().maxRefinementLevel()) {
158 fvSolver().a_levelSetFunction(c, 0) = -999999;
159 continue;
160 }
161
163 fvSolver().a_flameSpeed(c, 0) = lsSolver().a_flameSpeedG(gc, 0);
164 fvSolver().a_curvatureG(c, 0) = lsSolver().a_curvatureG(gc, 0);
165 }
166
167 // set flow field data in the LS solver
169}
MFloat & a_levelSetFunction(const MInt cellId, const MInt set)
Returns the levelSet-value for fv-CellId cellId and set.
MFloat & a_curvatureG(const MInt cellId, const MInt set)
Returns the curvature-value for fv-CellId cellId and set.
MBool a_hasProperty(const MInt cellId, const Cell p) const
Returns grid cell property p of the cell cellId.
MFloat & a_flameSpeed(const MInt cellId, const MInt set)
Returns the flamespeed-value for fv-CellId cellId and set.
MFloat & a_flameSpeedG(const MInt cellId, const MInt set)
Returns flameSpeed of the cell cellId for index n.
void constructExtensionVelocity()
constexpr GridProxy & grid() const

◆ fastInterfaceExtensionVelocity()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::fastInterfaceExtensionVelocity
Author
Daniel Hartmann
Date
2007

currently out of use!

Definition at line 1886 of file lsfvcombustion.cpp.

1886 {
1887 TRACE();
1888
1889 for(MInt set = lsSolver().m_startSet; set < lsSolver().m_noSets; set++) {
1890 // compute the extension velocity of G0 cut cells
1891 for(MInt id = 0; id < lsSolver().a_bandLayer(0, set); id++) {
1892 MFloat correctedBurningVelocity =
1893 lsSolver().a_flameSpeedG(lsSolver().a_bandCellId(id, set), set)
1894 * (F1 - lsSolver().a_curvatureG(lsSolver().a_bandCellId(id, set), set) * lsSolver().m_marksteinLength);
1895
1896 for(MInt i = 0; i < nDim; i++)
1897 lsSolver().a_extensionVelocityG(lsSolver().a_bandCellId(id, set), i, set) =
1898 fvSolver().a_variable(lsSolver().a_bandCellId(id, set), fvSolver().PV->VV[i])
1899 + lsSolver().a_normalVectorG(lsSolver().a_bandCellId(id, set), i, set) * correctedBurningVelocity;
1900 }
1901 }
1902}
SysEqn::PrimitiveVariables * PV
MFloat & a_variable(const MInt cellId, const MInt varId)
Returns conservative variable v of the cell cellId for variables varId.
MFloat & a_normalVectorG(const MInt cellId, const MInt dim, const MInt set)
Returns normalVector of the cell cellId for index n.
MInt & a_bandLayer(MInt id, MInt set)

◆ finalizeCouplerInit()

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

Implements Coupling.

Definition at line 51 of file lsfvcombustion.cpp.

51 {
52 for(MInt s = 0; s < lsSolver().m_noSets; s++) {
53 fvSolver().m_levelSetValues[s].resize(fvSolver().a_noCells());
54 fvSolver().m_curvatureG[s].resize(fvSolver().a_noCells());
55 fvSolver().m_flameSpeedG[s].resize(fvSolver().a_noCells());
56 }
60}
std::vector< MFloat > * m_curvatureG
std::vector< MFloat > * m_flameSpeedG
std::vector< MFloat > * m_levelSetValues
void setRhoFlameTubeInLs()
void computeGCellTimeStep()

◆ finalizeSubCoupleInit()

template<MInt nDim_, class SysEqn >
void LsFvCombustion< nDim_, SysEqn >::finalizeSubCoupleInit ( MInt  )
inlinevirtual

Implements Coupling.

Definition at line 59 of file lsfvcombustion.h.

59{};

◆ fv2lsId()

template<MInt nDim_, class SysEqn >
MInt LsFvCombustion< nDim_, SysEqn >::fv2lsId ( const MInt  fvId)
inline

Definition at line 82 of file lsfvcombustion.h.

82{ return convertId(fvSolver(), lsSolver(), 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

◆ fvSolver()

template<MInt nDim_, class SysEqn >
FvCartesianSolver & LsFvCombustion< nDim_, SysEqn >::fvSolver ( ) const
inline

Definition at line 50 of file lsfvcombustion.h.

50{ return *m_fvSolver; }

◆ init()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::init
virtual

Implements Coupling.

Definition at line 36 of file lsfvcombustion.cpp.

36 {
37 mAlloc(fvSolver().m_levelSetValues, lsSolver().m_noSets, "fvSolver().m_levelSetValues", AT_);
38 mAlloc(fvSolver().m_curvatureG, lsSolver().m_noSets, "fvSolver().m_curvatureG", AT_);
39 mAlloc(fvSolver().m_flameSpeedG, lsSolver().m_noSets, "fvSolver().m_flameSpeedG", AT_);
41}
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

◆ ls2fvId()

template<MInt nDim_, class SysEqn >
MInt LsFvCombustion< nDim_, SysEqn >::ls2fvId ( const MInt  lsId)
inline

Definition at line 81 of file lsfvcombustion.h.

81{ return convertId(lsSolver(), fvSolver(), lsId); };

◆ lsSolver()

template<MInt nDim_, class SysEqn >
LsSolver & LsFvCombustion< nDim_, SysEqn >::lsSolver ( ) const
inline

Definition at line 47 of file lsfvcombustion.h.

47{ return *m_lsSolver; }

◆ noLevelSetFieldData()

template<MInt nDim, class SysEqn >
MInt LsFvCombustion< nDim, SysEqn >::noLevelSetFieldData

Definition at line 240 of file lsfvcombustion.cpp.

240 {
242 if(fvSolver().m_levelSet) {
243 if(lsSolver().m_writeOutAllLevelSetFunctions) {
246 } else
248 if(lsSolver().m_writeOutAllCurvatures)
250 else
252 }
253
254 return noLevelSetFieldData;
255}
MInt noLevelSetFieldData()

◆ postCouple()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::postCouple ( MInt  )
virtual

Implements Coupling.

Definition at line 48 of file lsfvcombustion.cpp.

48{}

◆ preCouple()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::preCouple ( MInt  )
overridevirtual

Implements Coupling.

Definition at line 43 of file lsfvcombustion.cpp.

◆ readProperties()

template<MInt nDim_, class SysEqn >
void LsFvCombustion< nDim_, SysEqn >::readProperties ( )
inlinevirtual

Implements Coupling.

Definition at line 66 of file lsfvcombustion.h.

66{};

◆ saveOutputLS()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::saveOutputLS

Modified structured grid output (ASCII) of the calculated variables rho,c,v,u,... for the forced response cases

Author
Stephan Schlimpert
Date
15.11.2010, June 2011

Structured Output written for a single flame (case 1) or a flame with a plenum above. Used in Matlab in order to compute the transfer functions of the flames via the velocity perturbations of the centerline and the flame surface perturbations computed, see flameSurfaceArea.

  • flame with tube above (new version) + pd/dt information, correctded flame front amplitude computation

find cell on r_min in the left lower corner of the flame tube (= inlet of tube from plenum), only in the first iteration order of output: rows: x; columns: y

Structured Output starts from this founded Cell in every timestep

Definition at line 259 of file lsfvcombustion.cpp.

259 {
260 if(fvSolver().m_combustion && fvSolver().m_recordPressure && globalTimeStep % 10 == 0) {
262 if(fvSolver().domainId() == 0) {
263 FILE* datei;
264 datei = fopen("pressureSensor", "a+");
265 fprintf(datei, " %d", globalTimeStep);
266 fprintf(datei, " %f", fvSolver().m_time);
267 fprintf(datei, " %-10.10f", fvSolver().a_pvariable(fvSolver().m_cellToRecordData, fvSolver().PV->P));
268 fprintf(datei, " %-10.10f", fvSolver().m_meanPressure);
269 fprintf(datei, " %-10.10f", fvSolver().a_pvariable(fvSolver().m_cellToRecordData, fvSolver().PV->V));
270 fprintf(datei, " %-10.10f", lsSolver().m_arcLength);
271 fprintf(datei, " %-10.10f", fvSolver().m_totalHeatReleaseRate);
272 fprintf(datei, " %-10.10f", lsSolver().m_minFlameFrontPosition[1]);
273 fprintf(datei, " %-10.10f", lsSolver().m_maxFlameFrontPosition[1]);
274 fprintf(datei, " %-10.10f", lsSolver().m_meanFlameFrontPosition[1]);
275 fprintf(datei, "\n");
276 fclose(datei);
277 }
278 }
279
280 if(fvSolver().m_combustion && fvSolver().m_recordFlameFrontPosition && globalTimeStep % 10 == 0) {
282 if(fvSolver().domainId() == 0) {
283 FILE* datei;
284 datei = fopen("flameFrontData", "a+");
285 fprintf(datei, " %d", globalTimeStep);
286 fprintf(datei, " %f", fvSolver().m_time);
287 fprintf(datei, " %f", lsSolver().m_arcLength);
288 fprintf(datei, " %-10.15f", lsSolver().m_minFlameFrontPosition[1]);
289 fprintf(datei, " %-10.15f", lsSolver().m_maxFlameFrontPosition[1]);
290 fprintf(datei, "\n");
291 fclose(datei);
292 }
293 }
294
295 if(fvSolver().m_combustion && !fvSolver().m_forcing && !fvSolver().m_structuredFlameOutput
296 && fvSolver().domainId() == 0) {
297 FILE* datei00;
298 datei00 = fopen("flameSurfaceAreaROH_steady", "a+");
299 fprintf(datei00, " %d", globalTimeStep);
300 fprintf(datei00, " %f", fvSolver().m_time);
301 fprintf(datei00, " %-10.10f", lsSolver().m_massConsumption);
302 fprintf(datei00, " %-10.10f", fvSolver().m_totalHeatReleaseRate);
303 fprintf(datei00, " %-10.10f", lsSolver().m_arcLength);
304 fprintf(datei00, "\n");
305 fclose(datei00);
306 }
307
308
309 if(fvSolver().m_combustion && (fvSolver().m_structuredFlameOutput || fvSolver().m_structuredFlameOutputLevel == 7)) {
310 MInt sweepStart = 0;
311 MInt sweepStartRow = 0;
312 MInt current;
313 MInt sample, currentCycle;
314 MFloat forcingAmplitude;
315 MInt samplingStartCycle = fvSolver().m_samplingStartCycle;
316 MInt samplingEndCycle = fvSolver().m_samplingEndCycle;
318 //---
319
320 // compute the cycle time and the cycle
322
323 currentCycle = (MInt)(sample / fvSolver().m_samplesPerCycle);
324
325 // compute the flame surface area (unfiltered signal)
327 forcingAmplitude = fvSolver().m_forcingAmplitude * sin(St * fvSolver().m_time);
328
329 if(fvSolver().domainId() == 0) {
330 FILE* datei0;
331 datei0 = fopen("flameSurfaceAreaROH", "a+");
332 fprintf(datei0, " %d", globalTimeStep);
333 fprintf(datei0, " %d", currentCycle);
334 fprintf(datei0, " %d", sample);
335 fprintf(datei0, " %f", fvSolver().m_time);
336 fprintf(datei0, " %f", forcingAmplitude);
337 fprintf(datei0, " %-10.10f", lsSolver().m_massConsumption);
338 fprintf(datei0, " %-10.10f", fvSolver().m_totalHeatReleaseRate);
339 fprintf(datei0, " %-10.10f", lsSolver().m_arcLength);
340 fprintf(datei0, "\n");
341 fclose(datei0);
342 }
343
344 // really?...
345 switch(fvSolver().m_structuredFlameOutputLevel) {
346 default: {
347 if(globalTimeStep % fvSolver().m_noTimeStepsBetweenSamples != 0) {
348 return;
349 }
350 break;
351 }
352 }
353
354
355 if(fvSolver().domainId() == 0) {
356 // output heat release over velocity forcing (filtered signal)
357 FILE* datei;
358 datei = fopen("flameSurfaceArea", "a+");
359 fprintf(datei, " %d", globalTimeStep);
360 fprintf(datei, " %d", currentCycle);
361 fprintf(datei, " %d", sample);
362 fprintf(datei, " %f", fvSolver().m_time);
363 fprintf(datei, " %-10.10f", forcingAmplitude);
364 fprintf(datei, " %-10.10f", lsSolver().m_massConsumption);
365 fprintf(datei, " %-10.10f", fvSolver().m_totalHeatReleaseRate);
366 fprintf(datei, " %-10.10f", lsSolver().m_arcLength);
367 fprintf(datei, "\n");
368 fclose(datei);
369 }
370
371 // really?...
372 switch(fvSolver().m_structuredFlameOutputLevel) {
373 default: {
374 if(currentCycle < samplingStartCycle || currentCycle > samplingEndCycle) {
375 return;
376 }
377 break;
378 }
379 }
380
381
392 switch(fvSolver().m_structuredFlameOutputLevel) {
394 case 400: {
395 MFloat FtimeStep = 1 / fvSolver().timeStep();
396 MFloat dPdT = -9999999.0;
397 const MFloat gammaMinusOne = fvSolver().m_gamma - 1.0;
398 MFloat fRho = -9999999.0;
399 MFloat vel = -9999999.0;
400 MFloat velPOW2 = -9999999.0;
401 MFloat pold = -9999999.0;
402
409 if((MInt)sample
410 <= (MInt)(samplingStartCycle * fvSolver().m_samplesPerCycle + fvSolver().m_noTimeStepsBetweenSamples)
411 || globalTimeStep <= (MInt)(fvSolver().m_restartTimeStep + fvSolver().m_noTimeStepsBetweenSamples)) {
412 // for plenum simulation
413 if(fvSolver().m_plenum) {
414 for(MInt ac = 0; ac < fvSolver().m_noActiveCells; ac++) {
415 if(fvSolver().a_coordinate(fvSolver().m_activeCellIds[ac], 0) > -(fvSolver().m_radiusFlameTube + 0.1))
416 continue;
417 if(fvSolver().a_coordinate(fvSolver().m_activeCellIds[ac], 1) > -1.1) continue;
420 > 0) // number of neighbors in -x and -y direction > 0
421 continue;
424 break;
425 }
426 // only flame version
427 } else {
428 for(MInt ac = 0; ac < fvSolver().m_noActiveCells; ac++) {
429 if(fvSolver().a_hasNeighbor(fvSolver().m_activeCellIds[ac], 0) > 0) continue;
430 if(fvSolver().a_hasNeighbor(fvSolver().m_activeCellIds[ac], 2) > 0) continue;
431 if(fvSolver().a_coordinate(fvSolver().m_activeCellIds[ac], 1) > -0.8) continue;
432 if(fvSolver().a_level(fvSolver().m_activeCellIds[ac]) != fvSolver().maxRefinementLevel()) continue;
434 break;
435 }
436 }
437 m_log << "Structured Output starting from Cell ... :" << endl;
438 m_log << "cellId: " << fvSolver().m_sweepStartFirstCell << endl;
439 m_log << "x: " << fvSolver().a_coordinate(fvSolver().m_sweepStartFirstCell, 0) << endl;
440 m_log << "y: " << fvSolver().a_coordinate(fvSolver().m_sweepStartFirstCell, 1) << endl;
441
442 cerr << "Structured Output starting from Cell ... :" << endl;
443 cerr << "cellId: " << fvSolver().m_sweepStartFirstCell << endl;
444 cerr << "x: " << fvSolver().a_coordinate(fvSolver().m_sweepStartFirstCell, 0) << endl;
445 cerr << "y: " << fvSolver().a_coordinate(fvSolver().m_sweepStartFirstCell, 1) << endl;
446
447 FILE* pv6;
448 stringstream StartEndCoord;
449 StartEndCoord << "out/StartEndCoord_" << currentCycle << "_" << (MInt)sample;
450 pv6 = fopen((StartEndCoord.str()).c_str(), "w");
452 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 0));
453 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 1));
454 // writing next cell values in x -direction = row direction
455 while(fvSolver().a_hasNeighbor(current, 1) > 0) { // number of Neighbors in +x direction > 0
456 current = fvSolver().c_neighborId(current, 1); // get next neighbor as current cell Id
457 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 0));
458 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 1));
459 }
460 fprintf(pv6, "\n");
461
462 // get next cell in +y direction from first cell = fvSolver().m_sweepStartFirstCell
463 sweepStartRow = fvSolver().m_sweepStartFirstCell;
464 while(fvSolver().a_hasNeighbor(sweepStartRow, 3) > 0) {
465 sweepStartRow = fvSolver().c_neighborId(sweepStartRow, 3); // get next cell in +y direction from first cell
466 // = fvSolver().m_sweepStartFirstCell
467 // check if the geometry continues in -x direction
468 while(fvSolver().a_hasNeighbor(sweepStartRow, 0) > 0
469 && fvSolver().a_hasNeighbor(fvSolver().c_neighborId(sweepStartRow, 0), 3) > 0) {
470 sweepStartRow = fvSolver().c_neighborId(sweepStartRow, 0); // get next cell in -x direction
471 }
472 current = sweepStartRow;
473 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 0));
474 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 1));
475 // next element in +x direction
476 while(fvSolver().a_hasNeighbor(current, 1) > 0) {
477 current = fvSolver().c_neighborId(current, 1);
478 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 0));
479 fprintf(pv6, "%f ", fvSolver().a_coordinate(current, 1));
480 }
481 // check if the geometry continues in +y direction by searching cells in +x direction
482 while(fvSolver().a_hasNeighbor(sweepStartRow, 3) == 0 && fvSolver().a_hasNeighbor(sweepStartRow, 1) > 0) {
483 sweepStartRow = fvSolver().c_neighborId(sweepStartRow, 1); // get next cell in +x direction
484 }
485 fprintf(pv6, "\n");
486 }
487 fclose(pv6);
488 }
489 // skip output if samplingStartCycle not reached
490 if(((MInt)sample < (MInt)(samplingStartCycle * fvSolver().m_samplesPerCycle))
491 || globalTimeStep <= (MInt)(fvSolver().m_restartTimeStep + fvSolver().m_noTimeStepsBetweenSamples))
492 break;
493 if(lsSolver().m_noSets > 1) {
494 mTerm(1, AT_,
495 "This routine should only be called if lsSolver().m_noSets = 1, which is not the case here... "
496 "Please "
497 "check!");
498 }
499 // compute local flame front amplitude
500 // computeFlameFrontAmplitude(currentCycle,sample,0);
501
502 if(((MInt)sample < (MInt)(samplingStartCycle * fvSolver().m_samplesPerCycle))) break;
503
504 // write out primitive variables and G
505 FILE* pv0;
506 FILE* pv1;
507 FILE* pv2;
508 FILE* pv3;
509 FILE* pv4;
510 FILE* pv5;
511 FILE* pv6;
512 stringstream u, v, p, dpdt, rho, c, G;
513 u << "out/u_" << currentCycle << "_" << (MInt)sample;
514 v << "out/v_" << currentCycle << "_" << (MInt)sample;
515 p << "out/p_" << currentCycle << "_" << (MInt)sample;
516 dpdt << "out/dpdt_" << currentCycle << "_" << (MInt)sample;
517 rho << "out/rho_" << currentCycle << "_" << (MInt)sample;
518 c << "out/c_" << currentCycle << "_" << (MInt)sample;
519 G << "out/G_" << currentCycle << "_" << (MInt)sample;
520
521 pv0 = fopen((u.str()).c_str(), "w");
522 pv1 = fopen((v.str()).c_str(), "w");
523 pv2 = fopen((rho.str()).c_str(), "w");
524 pv3 = fopen((p.str()).c_str(), "w");
525 pv4 = fopen((c.str()).c_str(), "w");
526 pv5 = fopen((G.str()).c_str(), "w");
527 pv6 = fopen((dpdt.str()).c_str(), "w");
528 if(fvSolver().m_sweepStartFirstCell < 0) {
529 MString errorMessage = "sweep start cell is negative";
530 mTerm(1, AT_, errorMessage);
531 }
532 // write the first row from first founded cell in the flame tube
534
535 // writing first element on row
536 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
537 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
538 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
539 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
540 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
541 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
542 // compute the velocities
543 fRho = F1 / fvSolver().a_oldVariable(current, fvSolver().CV->RHO);
544 velPOW2 = F0;
545 for(MInt i = 0; i < nDim; i++) {
546 vel = fvSolver().a_oldVariable(current, fvSolver().CV->RHO_VV[i]) * fRho;
547 velPOW2 += POW2(vel);
548 }
549
550 dPdT = fvSolver().a_pvariable(current, 3);
551 // compute primitive old pressure from conservative variables
552 pold = gammaMinusOne
553 * (fvSolver().a_oldVariable(current, fvSolver().CV->RHO_E)
554 - F1B2 * fvSolver().a_oldVariable(current, fvSolver().CV->RHO) * velPOW2);
555 dPdT -= pold;
556 dPdT *= FtimeStep;
557 fprintf(pv6, "%f ", dPdT);
558 // writing next cell values in x -direction = row direction
559 while(fvSolver().a_hasNeighbor(current, 1) > 0) { // number of Neighbors in +x direction > 0
560 current = fvSolver().c_neighborId(current, 1); // get next neighbor as current cell Id
561 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
562 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
563 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
564 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
565 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
566 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
567 // compute the velocities
568 fRho = F1 / fvSolver().a_oldVariable(current, fvSolver().CV->RHO);
569 velPOW2 = F0;
570 for(MInt i = 0; i < nDim; i++) {
571 vel = fvSolver().a_oldVariable(current, fvSolver().CV->RHO_VV[i]) * fRho;
572 velPOW2 += POW2(vel);
573 }
574
575 dPdT = fvSolver().a_pvariable(current, 3);
576 // compute primitive old pressure from conservative variables
577 pold = gammaMinusOne
578 * (fvSolver().a_oldVariable(current, fvSolver().CV->RHO_E)
579 - F1B2 * fvSolver().a_oldVariable(current, fvSolver().CV->RHO) * velPOW2);
580 dPdT -= pold;
581 dPdT *= FtimeStep;
582 fprintf(pv6, "%f ", dPdT);
583 }
584 // space between this row and next row -> column direction is y direction
585 fprintf(pv0, "\n");
586 fprintf(pv1, "\n");
587 fprintf(pv2, "\n");
588 fprintf(pv3, "\n");
589 fprintf(pv4, "\n");
590 fprintf(pv5, "\n");
591 fprintf(pv6, "\n");
592 // get next cell in +y direction from first cell = fvSolver().m_sweepStartFirstCell
593 sweepStartRow = fvSolver().m_sweepStartFirstCell;
594 while(fvSolver().a_hasNeighbor(sweepStartRow, 3) > 0) {
595 sweepStartRow = fvSolver().c_neighborId(sweepStartRow, 3);
596 // check if the geometry continues in -x direction
597 while(fvSolver().a_hasNeighbor(sweepStartRow, 0) > 0
598 && fvSolver().a_hasNeighbor(fvSolver().c_neighborId(sweepStartRow, 0), 3) > 0) {
599 sweepStartRow = fvSolver().c_neighborId(sweepStartRow, 0); // get next cell in -x direction
600 }
601 current = sweepStartRow;
602 // write the next row
603 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
604 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
605 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
606 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
607 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
608 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
609 // compute the velocities
610 fRho = F1 / fvSolver().a_oldVariable(current, fvSolver().CV->RHO);
611 velPOW2 = F0;
612 for(MInt i = 0; i < nDim; i++) {
613 vel = fvSolver().a_oldVariable(current, fvSolver().CV->RHO_VV[i]) * fRho;
614 velPOW2 += POW2(vel);
615 }
616
617 dPdT = fvSolver().a_pvariable(current, 3);
618 // compute primitive old pressure from conservative variables
619 pold = gammaMinusOne
620 * (fvSolver().a_oldVariable(current, fvSolver().CV->RHO_E)
621 - F1B2 * fvSolver().a_oldVariable(current, fvSolver().CV->RHO) * velPOW2);
622 dPdT -= pold;
623 dPdT *= FtimeStep;
624 fprintf(pv6, "%f ", dPdT);
625
626 // next element in +x direction
627 while(fvSolver().a_hasNeighbor(current, 1) > 0) {
628 current = fvSolver().c_neighborId(current, 1);
629 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
630 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
631 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
632 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
633 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
634 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
635
636 // compute the velocities
637 fRho = F1 / fvSolver().a_oldVariable(current, fvSolver().CV->RHO);
638 velPOW2 = F0;
639 for(MInt i = 0; i < nDim; i++) {
640 vel = fvSolver().a_oldVariable(current, fvSolver().CV->RHO_VV[i]) * fRho;
641 velPOW2 += POW2(vel);
642 }
643 dPdT = fvSolver().a_pvariable(current, 3);
644 // compute primitive old pressure from conservative variables
645 pold = gammaMinusOne
646 * (fvSolver().a_oldVariable(current, fvSolver().CV->RHO_E)
647 - F1B2 * fvSolver().a_oldVariable(current, fvSolver().CV->RHO) * velPOW2);
648 dPdT -= pold;
649 dPdT *= FtimeStep;
650 fprintf(pv6, "%f ", dPdT);
651 }
652
653 fprintf(pv0, "\n");
654 fprintf(pv1, "\n");
655 fprintf(pv2, "\n");
656 fprintf(pv3, "\n");
657 fprintf(pv4, "\n");
658 fprintf(pv5, "\n");
659 fprintf(pv6, "\n");
660
661 // check if the geometry continues in +y direction by searching cells in +x direction
662 while(fvSolver().a_hasNeighbor(sweepStartRow, 3) == 0 && fvSolver().a_hasNeighbor(sweepStartRow, 1) > 0) {
663 sweepStartRow = fvSolver().c_neighborId(sweepStartRow, 1); // get next cell in +x direction
664 }
665 }
666 fclose(pv0);
667 fclose(pv1);
668 fclose(pv2);
669 fclose(pv3);
670 fclose(pv4);
671 fclose(pv5);
672 fclose(pv6);
673
674 break;
675 }
676 // netcdf output
677 case 5: {
678 {
679 const MFloat gammaMinusOne = fvSolver().m_gamma - F1;
680 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
681 MFloat reactionEnthalpy = (fvSolver().m_burntUnburntTemperatureRatio - F1) * FgammaMinusOne;
682 MFloat halfWidth = 9999999.0;
683 const MFloat eps = fvSolver().c_cellLengthAtLevel(fvSolver().maxRefinementLevel()) * 0.00000000001;
684 MInt cnt = 0;
685 MInt nghbrId = -1;
686 MFloat check = 9999.0;
687 MFloatScratchSpace heatRelease(fvSolver().noInternalCells(), AT_, "heatRelease");
688 MFloatScratchSpace pressure(fvSolver().noInternalCells(), AT_, "pressure");
689 MFloatScratchSpace coords(fvSolver().noInternalCells(), AT_, "coords");
690
691 // here comes our line output
692 for(MInt cell = 0; cell < fvSolver().noInternalCells(); cell++) {
693 if(!fvSolver().a_hasProperty(cell, SolverCell::IsOnCurrentMGLevel)) continue;
694
695 halfWidth = F1B2 * fvSolver().c_cellLengthAtCell(cell) + eps;
696
697 if(fvSolver().a_coordinate(cell, 0) > halfWidth || fvSolver().a_coordinate(cell, 0) < F0) continue;
698
699 // -x neighbor
700 nghbrId = fvSolver().c_neighborId(cell, 0);
701
702 check = fvSolver().a_coordinate(cell, 0) + fvSolver().a_coordinate(nghbrId, 0);
703
704 if(fabs(check) > eps) mTerm(1, AT_, "ERROR: coord check failed");
705
706 // interpolate to center line
707 pressure[cnt] = fvSolver().a_pvariable(cell, 3);
708 pressure[cnt] += fvSolver().a_pvariable(nghbrId, 3);
709 pressure[cnt] *= F1B2;
710
711 heatRelease[cnt] = fvSolver().a_reactionRate(cell, 0) * fvSolver().a_cellVolume(cell) * reactionEnthalpy;
712 heatRelease[cnt] +=
713 fvSolver().a_reactionRate(nghbrId, 0) * fvSolver().a_cellVolume(nghbrId) * reactionEnthalpy;
714 heatRelease[cnt] *= F1B2;
715
716 coords[cnt] = fvSolver().a_coordinate(cell, 1);
717
718 cnt++;
719 }
720 // communicate center line data if available
721
722 MInt root = 0;
723 MFloat totalCnt = 0;
724 MIntScratchSpace globalCnt(fvSolver().noDomains(), AT_, "globalCnt");
725 MIntScratchSpace offsetIO(fvSolver().noDomains(), AT_, "offsetIO");
726
727 MPI_Gather(&cnt, 1, MPI_INT, globalCnt.getPointer(), 1, MPI_INT, root, fvSolver().mpiComm(), AT_, "cnt",
728 "globalCnt.getPointer()");
729
730 for(MInt i = 0; i < fvSolver().noDomains(); i++) {
731 offsetIO[i] = totalCnt;
732 totalCnt += globalCnt[i];
733 }
734 if(fvSolver().domainId() != root) totalCnt = 0;
735
736 MFloatScratchSpace tmp(totalCnt, AT_, "tmp");
737 MFloatScratchSpace tmp1(totalCnt, AT_, "tmp1");
738 MFloatScratchSpace tmp2(totalCnt, AT_, "tmp2");
739
740 MPI_Gatherv(pressure.getPointer(), cnt, MPI_DOUBLE, tmp.getPointer(), globalCnt.getPointer(),
741 offsetIO.getPointer(), MPI_DOUBLE, root, fvSolver().mpiComm(), AT_, "pressure.getPointer()",
742 "tmp.getPointer()");
743 MPI_Gatherv(heatRelease.getPointer(), cnt, MPI_DOUBLE, tmp1.getPointer(), globalCnt.getPointer(),
744 offsetIO.getPointer(), MPI_DOUBLE, root, fvSolver().mpiComm(), AT_, "heatRelease.getPointer()",
745 "tmp1.getPointer()");
746 MPI_Gatherv(coords.getPointer(), cnt, MPI_DOUBLE, tmp2.getPointer(), globalCnt.getPointer(),
747 offsetIO.getPointer(), MPI_DOUBLE, root, fvSolver().mpiComm(), AT_, "coords.getPointer()",
748 "tmp2.getPointer()");
749
750 FILE* pv0;
751 FILE* pv1;
752 FILE* pv2;
753
754 stringstream p;
755 stringstream h;
756 stringstream y;
757
758 p << "out/centerline_p";
759 h << "out/centerline_h";
760 y << "out/centerline_y";
761 if(fvSolver().domainId() == root) {
762 pv0 = fopen((p.str()).c_str(), "a+");
763 pv1 = fopen((h.str()).c_str(), "a+");
764 pv2 = fopen((y.str()).c_str(), "w");
765
766 for(MInt c = 0; c < totalCnt; c++) {
767 fprintf(pv0, "%f ", tmp[c]);
768 fprintf(pv0, "\n");
769 fprintf(pv1, "%f ", tmp1[c]);
770 fprintf(pv1, "\n");
771 fprintf(pv2, "%f ", tmp2[c]);
772 fprintf(pv2, "\n");
773 }
774
775 fclose(pv0);
776 fclose(pv1);
777 fclose(pv2);
778 }
779 }
780 // output when time is equal to a sample time
781 if(globalTimeStep % fvSolver().m_noTimeStepsBetweenSamples != 0) {
782 return;
783 }
784 // skip output if samplingStartCycle not reached
785 if(((MInt)sample < (MInt)(samplingStartCycle * fvSolver().m_samplesPerCycle))) break;
786
787 stringstream varFileName;
788 varFileName << fvSolver().outputDir() << "Q_" << currentCycle << "_" << (MInt)sample << ParallelIo::fileExt();
789
790 MFloatScratchSpace dbVariables(fvSolver().a_noCells() * (fvSolver().CV->noVariables + 5), AT_, "dbVariables");
791 MIntScratchSpace idVariables(0, AT_, "idVariables");
792 MFloatScratchSpace dbParameters(5, AT_, "dbParameters");
793 MIntScratchSpace idParameters(4, AT_, "idParameters");
794 vector<MString> dbVariablesName;
795 vector<MString> idVariablesName;
796 vector<MString> dbParametersName;
797 vector<MString> idParametersName;
798 vector<MString> name;
799
800 if(fvSolver().m_levelSet) {
801 MFloatScratchSpace levelSetFunction(fvSolver().a_noCells(), AT_, "levelSetFunction");
802 MFloatScratchSpace curvature(fvSolver().a_noCells(), AT_, "curvature");
803
804 for(MInt cell = 0; cell < fvSolver().a_noCells(); cell++) {
805 const MInt gCellId = fv2lsId(cell);
806 levelSetFunction[cell] = lsSolver().a_levelSetFunctionG(gCellId, 0);
807 curvature[cell] = lsSolver().a_curvatureG(gCellId, 0);
808 }
809 stringstream gName;
810 stringstream gCurv;
811 gName << "G";
812 gCurv << "curv";
813
814 name.push_back(gName.str());
815 fvSolver().collectVariables(levelSetFunction.begin(), dbVariables, name, dbVariablesName, 1,
816 fvSolver().a_noCells());
817 name.clear();
818 name.push_back(gCurv.str());
819 fvSolver().collectVariables(curvature.begin(), dbVariables, name, dbVariablesName, 1, fvSolver().a_noCells());
820 }
821 {
822 const MFloat gammaMinusOne = fvSolver().m_gamma - F1;
823 const MFloat FgammaMinusOne = F1 / gammaMinusOne;
824 MFloat reactionEnthalpy = (fvSolver().m_burntUnburntTemperatureRatio - F1) * FgammaMinusOne;
825 MFloat FtimeStep = 1 / fvSolver().timeStep();
826 MFloat fRho;
827 MFloat vel = -9999999.0;
828 MFloat velPOW2 = -9999999.0;
829 MFloat pold;
830
831 MFloatScratchSpace dPdT(fvSolver().a_noCells(), AT_, "dPdT");
832 MFloatScratchSpace dHdT(fvSolver().a_noCells(), AT_, "dHdT");
833 MFloatScratchSpace h(fvSolver().a_noCells(), AT_, "h");
834
835 for(MInt cell = 0; cell < fvSolver().a_noCells(); cell++) {
836 dPdT[cell] = F0;
837 dHdT[cell] = F0;
838 h[cell] = F0;
839
840 if(!fvSolver().a_hasProperty(cell, SolverCell::IsOnCurrentMGLevel)) continue;
841
842 // compute the velocities
843 fRho = F1 / fvSolver().a_oldVariable(cell, fvSolver().CV->RHO);
844 velPOW2 = F0;
845 for(MInt i = 0; i < nDim; i++) {
846 vel = fvSolver().a_oldVariable(cell, fvSolver().CV->RHO_VV[i]) * fRho;
847 velPOW2 += POW2(vel);
848 }
849
850 dPdT[cell] = fvSolver().a_pvariable(cell, 3);
851 // compute primitive old pressure from conservative variables
852 pold = gammaMinusOne
853 * (fvSolver().a_oldVariable(cell, fvSolver().CV->RHO_E)
854 - F1B2 * fvSolver().a_oldVariable(cell, fvSolver().CV->RHO) * velPOW2);
855 dPdT[cell] -= pold;
856 dPdT[cell] *= FtimeStep;
857
858 h[cell] = fvSolver().a_reactionRate(cell, 0);
859 h[cell] *= fvSolver().a_cellVolume(cell) * reactionEnthalpy;
860 dHdT[cell] = fvSolver().a_reactionRate(cell, 0);
861 dHdT[cell] -= fvSolver().a_reactionRateBackup(cell, 0);
862 dHdT[cell] *= fvSolver().a_cellVolume(cell) * reactionEnthalpy;
863 dHdT[cell] *= FtimeStep;
864 }
865 stringstream dPdTname;
866 stringstream dHdTname;
867 stringstream hName;
868 dPdTname << "dPdT";
869 dHdTname << "dHdT";
870 hName << "h";
871 name.clear();
872 name.push_back(dPdTname.str());
873 fvSolver().collectVariables(dPdT.begin(), dbVariables, name, dbVariablesName, 1, fvSolver().a_noCells());
874 name.clear();
875 name.push_back(dHdTname.str());
876 fvSolver().collectVariables(dHdT.begin(), dbVariables, name, dbVariablesName, 1, fvSolver().a_noCells());
877 name.clear();
878 name.push_back(hName.str());
879 fvSolver().collectVariables(h.begin(), dbVariables, name, dbVariablesName, 1, fvSolver().a_noCells());
880 }
881
882 name.clear();
883 for(MInt v = 0; v < fvSolver().PV->noVariables; v++) {
884 name.push_back(fvSolver().m_variablesName[v]);
885 }
886 fvSolver().collectVariables(&fvSolver().a_pvariable(0, 0), dbVariables, name, dbVariablesName,
887 fvSolver().PV->noVariables, fvSolver().a_noCells());
888
890 fvSolver().collectParameters(fvSolver().m_noSamples, idParameters, "noSamples", idParametersName);
891 fvSolver().collectParameters(globalTimeStep, idParameters, "globalTimeStep", idParametersName);
892 fvSolver().collectParameters(fvSolver().m_time, dbParameters, "time", dbParametersName);
893 fvSolver().collectParameters(fvSolver().m_restartFileOutputTimeStep, dbParameters, "timeStep",
894 dbParametersName);
895 fvSolver().collectParameters(fvSolver().m_noTimeStepsBetweenSamples, idParameters, "noTimeStepsBetweenSamples",
896 idParametersName);
897 fvSolver().collectParameters(fvSolver().m_physicalTime, dbParameters, "physicalTime", dbParametersName);
898 fvSolver().collectParameters((MInt)fvSolver().m_forcing, idParameters, "forcing", idParametersName);
899
900
901 m_log << "Writing structured output at time setp " << globalTimeStep << endl;
902 switch(string2enum(fvSolver().m_outputFormat)) {
903 case NETCDF: {
904 fvSolver().saveGridFlowVarsPar((varFileName.str()).c_str(), fvSolver().a_noCells(),
905 fvSolver().noInternalCells(), dbVariables, dbVariablesName, 0, idVariables,
906 idVariablesName, 0, dbParameters, dbParametersName, idParameters,
907 idParametersName, fvSolver().m_recalcIds);
908 break;
909 }
910 default: {
911 mTerm(1, AT_, "change solution output format to NETCDF or change code");
912 break;
913 }
914 }
915 break;
916 }
917 default: {
918 // find cell on r_max in the left lower corner
919 // order of output: rows: x; columns: y
920 for(MInt ac = 0; ac < fvSolver().m_noActiveCells; ac++) {
921 if(fvSolver().a_hasNeighbor(fvSolver().m_activeCellIds[ac], 0) > 0) continue;
922 if(fvSolver().a_hasNeighbor(fvSolver().m_activeCellIds[ac], 2) > 0) continue;
923 if(ABS(fvSolver().a_coordinate(fvSolver().m_activeCellIds[ac], 0)) > 0.5) continue;
924 if(fvSolver().a_level(fvSolver().m_activeCellIds[ac]) != fvSolver().maxRefinementLevel()) continue;
925 sweepStart = fvSolver().m_activeCellIds[ac];
926 break;
927 }
928
929 // write out primitive variables and G
930 FILE* pv0;
931 FILE* pv1;
932 FILE* pv2;
933 FILE* pv3;
934 FILE* pv4;
935 FILE* pv5;
936 stringstream u, v, p, rho, c, G;
937 u << "out/u_" << currentCycle << "_" << (MInt)sample;
938 v << "out/v_" << currentCycle << "_" << (MInt)sample;
939 p << "out/p_" << currentCycle << "_" << (MInt)sample;
940 rho << "out/rho_" << currentCycle << "_" << (MInt)sample;
941 c << "out/c_" << currentCycle << "_" << (MInt)sample;
942 G << "out/G_" << currentCycle << "_" << (MInt)sample;
943 pv0 = fopen((u.str()).c_str(), "w");
944 pv1 = fopen((v.str()).c_str(), "w");
945 pv2 = fopen((rho.str()).c_str(), "w");
946 pv3 = fopen((p.str()).c_str(), "w");
947 pv4 = fopen((c.str()).c_str(), "w");
948 pv5 = fopen((G.str()).c_str(), "w");
949 // write the first row
950 current = sweepStart;
951 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
952 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
953 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
954 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
955 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
956 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
957 while(fvSolver().a_hasNeighbor(current, 1) > 0) {
958 current = fvSolver().c_neighborId(current, 1);
959 if(ABS(fvSolver().a_coordinate(current, 0)) > 0.5) break;
960 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
961 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
962 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
963 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
964 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
965 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
966 }
967 fprintf(pv0, "\n");
968 fprintf(pv1, "\n");
969 fprintf(pv2, "\n");
970 fprintf(pv3, "\n");
971 fprintf(pv4, "\n");
972 fprintf(pv5, "\n");
973
974 while(fvSolver().a_hasNeighbor(sweepStart, 3) > 0) {
975 sweepStart = fvSolver().c_neighborId(sweepStart, 3);
976 current = sweepStart;
977 // write the next row
978 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
979 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
980 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
981 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
982 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
983 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
984 while(fvSolver().a_hasNeighbor(current, 1) > 0) {
985 current = fvSolver().c_neighborId(current, 1);
986 if(ABS(fvSolver().a_coordinate(current, 0)) > 0.5) break;
987 fprintf(pv0, "%f ", fvSolver().a_pvariable(current, 0));
988 fprintf(pv1, "%f ", fvSolver().a_pvariable(current, 1));
989 fprintf(pv2, "%f ", fvSolver().a_pvariable(current, 2));
990 fprintf(pv3, "%f ", fvSolver().a_pvariable(current, 3));
991 fprintf(pv4, "%f ", fvSolver().a_pvariable(current, 4));
992 fprintf(pv5, "%f ", lsSolver().a_levelSetFunctionG(fv2lsId(current), 0));
993 }
994 fprintf(pv0, "\n");
995 fprintf(pv1, "\n");
996 fprintf(pv2, "\n");
997 fprintf(pv3, "\n");
998 fprintf(pv4, "\n");
999 fprintf(pv5, "\n");
1000 }
1001 fclose(pv0);
1002 fclose(pv1);
1003 fclose(pv2);
1004 fclose(pv3);
1005 fclose(pv4);
1006 fclose(pv5);
1007 break;
1008 }
1009 }
1010 }
1011}
const MChar ** m_variablesName
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.
MFloat c_cellLengthAtCell(const MInt cellId) const
Returns the length of the cell for level.
MFloat & a_oldVariable(const MInt cellId, const MInt varId)
Returns oldVariablesv of the cell cellId variables varId.
MInt noInternalCells() const override
Return the number of internal cells within this solver.
void saveGridFlowVarsPar(const MChar *fileName, MInt noTotalCells, MLong noInternalCells, MFloatScratchSpace &variables, std::vector< MString > &dbVariablesName, MInt, MIntScratchSpace &idVariables, std::vector< MString > &idVariablesName, MInt, MFloatScratchSpace &dbParameters, std::vector< MString > &dbParametersName, MIntScratchSpace &idParameters, std::vector< MString > &idParametersName, const MInt *recalcIds)
This function stores the massivley parallel flow information of the cells.
MFloat & a_coordinate(const MInt cellId, const MInt dir)
Returns the coordinate of the cell from the fvcellcollector cellId for dimension dir.
MInt noVariables() const override
Return the number of primitive variables.
MFloat & a_reactionRateBackup(const MInt cellId, const MInt reactionId)
Returns the reactionRateBackup of the cell cellId for variables varId.
MInt & a_level(const MInt cellId)
Returns the level of the cell from the fvcellcollector cellId.
MInt a_hasNeighbor(const MInt cellId, const MInt dir, const MBool assertNeighborState=true) const
Returns noNeighborIds of the cell CellId for direction dir.
void computeZeroLevelSetArcLength()
MString outputDir() const
Return the directory for output files.
Definition: solver.h:407
virtual MInt domainId() const
Return the domainId (rank)
Definition: solver.h:383
virtual MInt noDomains() const
Definition: solver.h:387
void collectVariables(T *variablesIn, ScratchSpace< T > &variablesOut, const std::vector< MString > &variablesNameIn, std::vector< MString > &variablesNameOut, const MInt noVars, const MInt noCells, const MBool reverseOrder=false)
generalised helper function for writing restart files! This is necessary for example if the minLevel ...
MInt maxRefinementLevel() const
void collectParameters(T, ScratchSpace< T > &, const MChar *, std::vector< MString > &)
This function collects a single parameters for the massivley parallel IO functions.
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
Definition: enums.cpp:20
@ NETCDF
Definition: enums.h:18
InfoOutFile m_log
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_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
constexpr std::underlying_type< FcCell >::type p(const FcCell property)
Converts property name to underlying integer value.
define array structures

◆ setLsTimeStep()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::setLsTimeStep ( MFloat  timeStep)

Definition at line 177 of file lsfvcombustion.cpp.

177 {
178 lsSolver().m_timeStep = timeStep;
179}

◆ setRhoFlameTubeInLs()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::setRhoFlameTubeInLs

Definition at line 199 of file lsfvcombustion.cpp.

◆ setRhoInfinityInLs()

template<MInt nDim, class SysEqn >
void LsFvCombustion< nDim, SysEqn >::setRhoInfinityInLs

Definition at line 203 of file lsfvcombustion.cpp.

◆ subCouple()

template<MInt nDim_, class SysEqn >
void LsFvCombustion< nDim_, SysEqn >::subCouple ( MInt  ,
MInt  ,
std::vector< MBool > &   
)
inlinevirtual

Implements Coupling.

Definition at line 62 of file lsfvcombustion.h.

62{};

Friends And Related Function Documentation

◆ FvCartesianSolverXD< nDim, SysEqn >

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

Definition at line 29 of file lsfvcombustion.h.

◆ LsCartesianSolver< nDim >

template<MInt nDim_, class SysEqn >
friend class LsCartesianSolver< nDim >
friend

Definition at line 29 of file lsfvcombustion.h.

Member Data Documentation

◆ m_fvSolver

template<MInt nDim_, class SysEqn >
FvCartesianSolver* LsFvCombustion< nDim_, SysEqn >::m_fvSolver

Definition at line 49 of file lsfvcombustion.h.

◆ m_lsSolver

template<MInt nDim_, class SysEqn >
LsSolver* LsFvCombustion< nDim_, SysEqn >::m_lsSolver

Definition at line 46 of file lsfvcombustion.h.

◆ m_maxNoSets

template<MInt nDim_, class SysEqn >
MInt LsFvCombustion< nDim_, SysEqn >::m_maxNoSets

Definition at line 76 of file lsfvcombustion.h.

◆ nDim

template<MInt nDim_, class SysEqn >
constexpr MInt LsFvCombustion< nDim_, SysEqn >::nDim = nDim_
staticconstexpr

Definition at line 29 of file lsfvcombustion.h.


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