37 {
38#if defined(WITH_CANTERA)
39
41
43
44
45 std::vector<MFloat> X(noSpecies, 0.0);
46
47
48
49
50 std::vector<MFloat> YInlet(noSpecies, F0);
51 for(
MUint s = 0; s < noSpecies; ++s) {
53 }
54
55
58
60
62 std::vector<MFloat> YOutlet(noSpecies);
64
67
68
70 flow.setFreeFlow();
71
72
75 std::vector<MFloat> z(nz);
77 for(int iz = 0; iz < nz; iz++) {
79 }
80
81 flow.setupGrid(nz, &z[0]);
82
83 std::unique_ptr<Cantera::Transport> trmix(
85
86 flow.setTransport(*trmix);
89
90
91 Cantera::Inlet1D inlet;
92
93 inlet.setMoleFractions(X.data());
95 inlet.setMdot(massFlow);
97
98
99 Cantera::Outlet1D outlet;
100
101
102 std::vector<Cantera::Domain1D*> domains{&inlet, &flow, &outlet};
103 Cantera::Sim1D flame(domains);
104
105
106 std::vector<MFloat> locs{0.0, 0.3, 0.7, 1.0};
107 std::vector<MFloat> value;
108
109 const double UOutlet = inlet.mdot() / rhoOutlet;
110 value = {UInlet, UInlet, UOutlet, UOutlet};
111 flame.setInitialGuess("velocity", locs, value);
113 flame.setInitialGuess("T", locs, value);
114
115 for(size_t i = 0; i < noSpecies; i++) {
118 }
119
120 inlet.setMoleFractions(X.data());
121 inlet.setMdot(massFlow);
123
130
131 flame.setRefineCriteria(flowdomain, gridRatio, gridSlope, gridCurve, gridPrune);
132
133 flame.setMaxTimeStepCount(10000);
134 flame.setMaxGridPoints(flowdomain, 10000);
135
136 flame.setFixedTemperature(0.5 * (
m_TInlet + adiabaticT));
137
138 flame.solve(loglevel, false);
139 flow.solveEnergyEqn();
140 flame.solve(loglevel, true);
141
142 MFloat flameSpeedNew = flame.value(flowdomain, flow.componentIndex(
"velocity"), 0);
143 MFloat flameSpeedOld = 0.0;
144
145 gridRatio = 10.0;
146 MInt noIterations = 10;
147
148
149 for(
MInt iteration = 0; iteration < noIterations; ++iteration) {
150 gridSlope *= 0.5;
151 gridCurve *= 0.35;
152
153 flame.setRefineCriteria(flowdomain, gridRatio, gridSlope, gridCurve, gridPrune);
154
155 flame.solve(loglevel, true);
156
157 flameSpeedOld = flameSpeedNew;
158
159 flameSpeedNew = flame.value(flowdomain, flow.componentIndex("velocity"), 0);
160
161 MFloat relError = fabs(flameSpeedNew - flameSpeedOld) / fabs(flameSpeedNew);
162
164 }
165
166 MInt noGridPoints = flow.nPoints();
167
168
170 mAlloc(
m_profile.temperature, noGridPoints,
"temperature", -9999.9, AT_);
171 mAlloc(
m_profile.massFractions, noSpecies * noGridPoints,
"massFractions", -9999.9, AT_);
172
173 for(
MInt n = 0; n < noGridPoints; ++n) {
174 m_profile.velocity[n] = flame.value(flowdomain, flow.componentIndex(
"velocity"), n);
175 m_profile.temperature[n] = flame.value(flowdomain, flow.componentIndex(
"T"), n);
176 m_grid.push_back(flow.grid(n));
177
178 for(
MUint s = 0; s < noSpecies; ++s) {
179 m_profile.massFractions[noSpecies * n + s] = flame.value(flowdomain, flow.componentIndex(
m_speciesName[s]), n);
180 }
181 }
182
184 "Vector m_oneGridSize has incorrect number of values, terminating now...");
185
186 std::vector<MFloat> dTdx(noGridPoints, 0.0);
187 MFloat maximumSlope = 0.0;
188 for(
MInt n = 1; n < (noGridPoints - 1); ++n) {
191 dTdx[n] = deltaT / deltaX;
192 if(dTdx[n] > maximumSlope) maximumSlope = dTdx[n];
193 }
194
196
198#endif
199}
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
struct OneDFlame::@22 m_profile
std::vector< MFloat > m_grid
PtrCanteraThermo m_canteraThermo
PtrCanteraSolution m_canteraSolution
MFloat m_fixedTemperatureLocation