|
[Sponsors] |
Issues in FGM combustion model implementation |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
September 12, 2015, 17:46 |
Issues in FGM combustion model implementation
|
#1 |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
Hello,
I will divide this text a bit in order to organize the information: 1. If you want to be situated in the project I am doing You can find information about the FGM combustion model at: http://www.fgm-combustion.org/ My final project consists in implement such method to solve a non-premixed laminar jet flame (2D domain). The deadline is 1st of November and I am struggling a bit to understand some parts of a code I have. 2. Basic idea of implementation of FGM in OpenFOAM The base idea is to solve 2 additional transport equations instead of specie transport and energy equation (in my case, but there are other dimensions of manifold to solve), and update the diffusion coefficients reading a table (called manifold). The properties I need to read are: - viscosity for N-S equation - density for continuity and N-S equation - Cp and thermal conductivity for the 2 additional transport equations Such values are parametrized with a combination of the other 2 added transport variables and read from table according to the such transport variables values at table. This table is created by 1D simulations varying the stretch rate flame value to take int account different curvatures of the flame in the 2D simulation. 3. Problems in OpenFOAM understanding I got some files of a FGM implementation done in OpenFOAM and I am trying to debug some parts of the code. I will start putting the difficulties I am facing to here. 3.1 basicPsiThermo class in OF 2.3.0 It uses as base class the basicPsiThermo class. I am using OpenFOAM 2.3.0 version and there is not such class on it. I read in a thread that it's name have been changed to psiThermo however that was not an official statement. I could't find in OpenFOAM releases anything talking about such change. 3.2 Inheritance concept Analysing the following pieces of code.. hPsiFanzy.H file: Code:
class hPsiFanzy : public basicPsiThermo { // Private data //- Sensible enthalpy field [J/kg] volScalarField h_; //- Table look up routines const fanzyLookUp& fgmTable_; //- Reference to CV1 & CV2 const volScalarField& foamCV1_; const volScalarField& foamCV2_; //- FGM table index maps (CpIndex, RIndex, muIndex, alphaIndex) const labelList fgmThermoTransportIndices_; // Private Member Functions //- Calculate the thermo variables void calculate(); //- Construct as copy (not implemented) hPsiFanzy(const hPsiFanzy&); public: //- Runtime type information TypeName("hPsiFanzy"); // Constructors //- Construct from mesh hPsiFanzy ( const fvMesh&, const fanzyLookUp&, const volScalarField&, const volScalarField& ); //- Destructor ~hPsiFanzy(); etc.. Then in the hPsiFanzy.C file, the definition of the constructor is as follows: Code:
Foam::hPsiFanzy::hPsiFanzy ( const fvMesh& mesh, const fanzyLookUp& fanzyLookUp, const volScalarField& foamCV1, const volScalarField& foamCV2 ) : basicPsiThermo(mesh), h_ ( IOobject ( "h", mesh.time().timeName(), mesh, IOobject::NO_READ, IOobject::AUTO_WRITE ), mesh, dimEnergy/dimMass, this->hBoundaryTypes() ), fgmTable_(fanzyLookUp), foamCV1_(foamCV1), foamCV2_(foamCV2), fgmThermoTransportIndices_(lookup("fgmThermoTransportIndices")) { .... //implementation of functionalities of constructor That's what I meant it should be a standard derived class definition: Code:
class base { protected: int i; public: base(int x) { i = x; } ~base() {} }; class derived : public base { int j; public: derived(int x, int y) : base(y) { j = x;} ~derived() {} }; Another thing that bothers me is that in the hPsiFanzy.H file the object h_ is declared as being from volScalarField class and has been constructed with no arguments (see blue). Then later in the constructor definition it has been constructed with IOobject argument. I was not able to understand that, maybe I am misunderstanding a lot some concepts.. Briefing, I would like to understand the concept behind this hPsiFanzy as a class, because it is one of the most important classes in the FGM implementation. Understanding it I will be able to start understanding the whole implementation.. 3.3 variable_ vs. variable Is there some meaning of naming a variable like this variable_ instead of variable in OpenFOAM? I mean, in general it is used to identify some type of variable or usability of it? Thanks for any reply! I really need such help with this. Best regards, Lisandro |
|
September 13, 2015, 13:18 |
|
#2 | ||||
Senior Member
Hassan Kassem
Join Date: May 2010
Location: Germany
Posts: 242
Rep Power: 18 |
Hello,
Most of your questions are more related to C++ programming concepts more than they are related to OpenFOAM. I will try to give you concise answers and clues to your questions. Quote:
Quote:
Quote:
Quote:
I hope that, I gave you a hint about your problem and good luck with your project. Best wishes, Hassan |
|||||
September 13, 2015, 16:35 |
|
#3 |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
Dear Hassan,
thanks a lot! I was able to understand everything and also check some c++ concepts in order to ensure I have understood. Thank you very much, your answer was clear and good. Best regards, Lisandro |
|
September 18, 2015, 21:51 |
|
#4 |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
Hi again,
now I am struggling a bit to understand the logic of OpenFOAM fields updating. What I want to do: I want the following properties to be read from a table --> rho, mu, alpha and Cp. Therefore, I do not need to calculate such properties using a transport model, equation of state or thermodynamics model as it is in most cases. The problem: let's say that the way I started doing it was creating a thermophysical model based in some existent one (like psiThermo or rhoThermo) and did it by deriving my model from one of these. Let's say I am using the psiThermo as example and I want to debug how the Cp is being calculated. The protected members of psiThermo are written below, at psiThermo.H file: Code:
class psiThermo : public fluidThermo { protected: // Protected data //- Compressibility [s^2/m^2] volScalarField psi_; //- Dynamic viscosity [kg/m/s] volScalarField mu_; Code:
class fluidThermo : public basicThermo { Code:
class basicThermo : public IOdictionary { protected: // Protected data //- Phase-name const word& phaseName_; // Fields //- Pressure [Pa] volScalarField& p_; //- Temperature [K] volScalarField T_; //- Laminar thermal diffusuvity [kg/m/s] volScalarField alpha_; ...... ....... ...... ...... //- Heat capacity at constant pressure [J/kg/K] virtual tmp<volScalarField> Cp() const = 0; //- Heat capacity at constant pressure for patch [J/kg/K] virtual tmp<scalarField> Cp ( const scalarField& p, const scalarField& T, const label patchi ) const = 0; ... .... .... ..... So my question is, I can imagine that the Cp is calculated through the thermodynamic model you choose at the thermoPhysicalProperties dictionary like janaf or hConst, but where is it being called? And thinking about my problem, that I do not need to calculate such values (only need to read them at a table and use them in the diffusion terms of transport equations) which is the best way to implement it? Thank you in advance for any attempt of help! Regards, Lisandro |
|
September 20, 2015, 07:07 |
|
#5 |
Senior Member
Hassan Kassem
Join Date: May 2010
Location: Germany
Posts: 242
Rep Power: 18 |
Hello,
The thermodynamic library in OF is really hard to follow. It has a very clever implementation but it is not straightforward. Unfortunately, I cannot give you a definitive answer to your question. You conclusion is quiet right but please note that hConst and janaf are template classes, therefore the cp values are calculated not only based on hConst or janaf but also depend on equationOfState. best wishes, Hassan |
|
September 21, 2015, 11:33 |
|
#6 |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
Yes I understand it is not that trivial.. Even if what I post above is quiet right, it is still not enough for me to understand properly how can I deal with such fields in order to make them to be read from a table and use such updated values in equations instead of using the thermodynamics and transport models (and equation of state for rho)..
What I have done so far is to right a new thermophysical model based on basicPsiThermo, and tried to explicitly assign the table values to the properties trough commands like this: Code:
rhoCells[celli] = myTable_.getValue2D ( inputVar1Cells[celli], inputVar2Cells[celli], fgmThermoTransportIndices_[6] ); Of course I have instantiated a rho_ object since the basicPsiThermo did not have it.. What the function getValue2D does is only to read 2 other variables in table, make a combination of their values, interpolate and then take the correspondent rho value in table. The function is 100% sure working fine (since it was working for other properties in another solver), but when I plot the rho in paraView I cannot see any variations of my initial condition, what makes me think that it is not properly reading or writing such field. Also, my big doubt is whether the equations are using the rho from table or still using the equationOfState calculation. I know my post is very general, but if anyone has experience in dealing with fields or, even better, have already experienced working with tables for properties reading, and are available to give some tips to me I can clarify the post. Thanks a lot, Lisandro |
|
September 21, 2015, 19:25 |
|
#7 |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
If someone wants to help me a lot so just try to answer this following question, then I will be able to figure out the other stuff..
I have a thermophysical model class called hPsiNew. It is derived from basicPsiThermo (it is from OF2.1.0), which is derived from basicThermo class. Remembering that what I want is to read some fields from a table, I have the following code for hPsiNew class: 1. hPsiNew.H file Code:
class hPsiNew : public basicPsiThermo { const fanzyLookUp& fgmTable_; const volScalarField& foamCV1_; const volScalarField& foamCV2_; const labelList fgmThermoTransportIndices_; // Private Member Functions void calculate(); //- Construct as copy (not implemented) hPsiNew(const hPsiNew&); public: TypeName("hPsiNew); //- Construct from mesh hPsiNew ( const fvMesh&, const fanzyLookUp&, const volScalarField&, const volScalarField& ); //- Destructor ~hPsiFanzy(); void correct(); tmp<scalarField> Cp ( const scalarField& T, const label patchi ) const; tmp<volScalarField> Cp() const; }; } Code:
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // void Foam::hPsiFanzy::calculate() { scalarField& TCells = this->T_.internalField(); scalarField& psiCells = this->psi_.internalField(); scalarField& muCells = this->mu_.internalField(); scalarField& alphaCells = this->alpha_.internalField(); const scalarField& foamCV1Cells = foamCV1_.internalField(); const scalarField& foamCV2Cells = foamCV2_.internalField(); forAll(TCells, celli) { scalar Ttab = fgmTable_.getValue2D ( foamCV1Cells[celli], foamCV2Cells[celli], fgmThermoTransportIndices_[4] ); TCells[celli] = Ttab; // psi = 1.0/(R*T); psiCells[celli] = 1.0/(TCells[celli]*fgmTable_.getValue2D ( foamCV1Cells[celli], foamCV2Cells[celli], fgmThermoTransportIndices_[1] )); } forAll(T_.boundaryField(), patchi) { fvPatchScalarField& pT = this->T_.boundaryField()[patchi]; fvPatchScalarField& ppsi = this->psi_.boundaryField()[patchi]; fvPatchScalarField& pmu = this->mu_.boundaryField()[patchi]; fvPatchScalarField& palpha = this->alpha_.boundaryField()[patchi]; const fvPatchScalarField& pfoamCV1 = foamCV1_.boundaryField()[patchi]; const fvPatchScalarField& pfoamCV2 = foamCV2_.boundaryField()[patchi]; if (pT.fixesValue()) { forAll(pT, facei) { scalar Ttab = fgmTable_.getValue2D ( pfoamCV1[facei], pfoamCV2[facei], fgmThermoTransportIndices_[4] ); ppsi[facei] = 1.0/(pT[facei]*fgmTable_.getValue2D ( pfoamCV1[facei], pfoamCV2[facei], fgmThermoTransportIndices_[1] )); } } ... ... ... // Constructor Foam::hPsiFanzy::hPsiFanzy ( const fvMesh& mesh, const fanzyLookUp& fanzyLookUp, const volScalarField& foamCV1, const volScalarField& foamCV2 ) : basicPsiThermo(mesh), fgmTable_(fanzyLookUp), foamCV1_(foamCV1), foamCV2_(foamCV2), fgmThermoTransportIndices_(lookup("fgmThermoTransportIndices")) { scalarField& TCells = this->T_.internalField(); const scalarField& foamCV1Cells = foamCV1_.internalField(); const scalarField& foamCV2Cells = foamCV2_.internalField(); forAll(TCells, celli) { // Initialize enthalpy and temperature with values from the FGM table TCells[celli] = fgmTable_.getValue2D ( foamCV1Cells[celli], foamCV2Cells[celli], fgmThermoTransportIndices_[4] ); } ... ... ... forAll(T_.boundaryField(), patchi) { fvPatchScalarField& pT = this->T_.boundaryField()[patchi]; const fvPatchScalarField& pfoamCV1 = foamCV1_.boundaryField()[patchi]; const fvPatchScalarField& pfoamCV2 = foamCV2_.boundaryField()[patchi]; // Initialize enthalpy and temperature with values from the FGM table if (pT.fixesValue()) { forAll(pT, facei) { scalar Ttab = fgmTable_.getValue2D ( pfoamCV1[facei], pfoamCV2[facei], fgmThermoTransportIndices_[4] ); } } else { forAll(pT, facei) { pT[facei] = fgmTable_.getValue2D ( pfoamCV1[facei], pfoamCV2[facei], fgmThermoTransportIndices_[4] ); } } } ... ... ... So my questions are: 1. T_ object The first line of calculate() member function does this Code:
scalarField& TCells = this->T_.internalField(); Code:
scalar Ttab = fgmTable_.getValue2D ( foamCV1Cells[celli], foamCV2Cells[celli], fgmThermoTransportIndices_[4] ); TCells[celli] = Ttab; 2. psi field As you can see, the psi field is calculated by 1/(R*T), being both R and T values taken from table. The thing is: a) this is the psi field when I solved the hEqn together with the other equations. It means it was calculating some T field (but I am not sure which one was used to calculate psi). These area the results for psi (at some time -not important) See FIgure a) in next post b) Then, when I only deactivate the hEqn these are the results for psi (at the same time): See Figure b) in next post So, my conclusion is that it is not properly doing the following command: Code:
psiCells[celli] = 1.0/(TCells[celli]*fgmTable_.getValue2D ( foamCV1Cells[celli], foamCV2Cells[celli], fgmThermoTransportIndices_[1] )); Code:
scalar Ttab = fgmTable_.getValue2D ( foamCV1Cells[celli], foamCV2Cells[celli], fgmThermoTransportIndices_[4] ); TCells[celli] = Ttab; So I am struggling to deal with field's writting and reading stuff... If anyone could help me on this it would be great! Best regards, Lisandro |
|
September 21, 2015, 19:28 |
|
#8 |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
Figure a) is the most non-uniform one
Figure b) is the most uniform one Obs: I struggled to put images I do not know why,sorry about this confusion.. |
|
September 29, 2015, 11:30 |
|
#9 |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
I solved my problem regarding to properties being taken from table. It is working fine now. If anyone have troubles with this in future ask me then I can give a help. I will not post here because I was doing so many things wrong but now I understood how to do this and a bit more how to deal with fields in OpenFOAM.
Lisandro |
|
November 10, 2016, 06:37 |
|
#10 |
New Member
Bah.Mah
Join Date: Jun 2016
Posts: 18
Rep Power: 10 |
Hallo Lisandro Maders
Now I am working on the implementation of the FGM combustion model into OpenFOAM and I would really appreciate if you can help on that by posting the code that you worked on or if you know another code with more recent OF version. Thanks |
|
November 30, 2017, 19:51 |
|
#11 |
New Member
Sid Nigam
Join Date: Feb 2016
Posts: 4
Rep Power: 10 |
I would also like to know if there are implementations of the FGM model in newer versions like OF 4.1.
|
|
November 30, 2017, 22:45 |
|
#12 | |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
Quote:
I coded the FGM model for non-premixed laminar flames in OpenFOAM 2.1.x and since then I have been working with this version when I want to use FGM. I did not put effort to adapt it to newer versions. If you want I can share the code with you. It was the first big code I did in OpenFOAM so it is not perfectly programmed in terms of OpenFOAM style. Let me know if such solver for non-premixed laminar flames suits for you. Regards, Lisandro Maders |
||
November 30, 2017, 22:48 |
|
#13 | |
Member
Lisandro Maders
Join Date: Feb 2013
Posts: 98
Rep Power: 13 |
Quote:
Regards, Lisandro Maders |
||
April 18, 2020, 13:02 |
|
#14 |
Super Moderator
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52 |
Dear Lisandro,
I re-activate this thread as I want to know a few things here which you might be able to answer:
Kind regards and thanks in advance, Tobias
__________________
Keep foaming, Tobias Holzmann |
|
April 21, 2020, 10:54 |
|
#15 | |
Senior Member
Yan Zhang
Join Date: May 2014
Posts: 120
Rep Power: 12 |
Quote:
There is a widely-used open source 1D chemical calculator, called FlameMaster. You can find it here: https://www.itv.rwth-aachen.de/index.php?id=13 FlameMaster can solve 1D flamelets equations on the mixture fraction coordinate. And another one from a personal developer: https://github.com/ZX114/ChemFlow And some related repositories: https://github.com/weixian001/FPVFoam-v3.0.1 https://github.com/CCChuanfeng/premixedFGMFoam https://github.com/ZX114/sprayFlameletFoam
__________________
https://openfoam.top |
||
April 22, 2020, 20:18 |
|
#16 |
Member
Join Date: Oct 2015
Location: Finland
Posts: 39
Rep Power: 11 |
Just to chime in, Ember is also another open-source unsteady flamelet solver, developed by the same people developing Cantera. I have been testing its performance with respect to Chem1D (another closed-source flamelet solver, however possible to get from TU Eindhoven), and it looks quite promising.
https://github.com/speth/ember Bulut |
|
Tags |
constructor, fgm, inheritance |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Diff in Combustion Modelling By Species Transport Model & Non-Premixed Combustion | bhanuday.sharma | FLUENT | 0 | June 23, 2015 03:50 |
Liquid rocket engine non-premixed combustion model | Erik | FLUENT | 2 | November 28, 2013 15:09 |
eddy dissipation model: combustion doesn't occur | roukaia | FLUENT | 0 | December 24, 2011 10:10 |
the combustion model problem | hanshandiaoke | Siemens | 0 | November 25, 2011 21:37 |
combustion model | Hennie van der Westhuizen | Siemens | 7 | February 27, 2002 03:10 |