MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
lsfvcombustion.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#include "lsfvcombustion.h"
8
9#include <algorithm>
10#include <stack>
11#include "IO/parallelio.h"
12#include "MEMORY/alloc.h"
13#include "UTIL/functions.h"
14#include "COMM/mpioverride.h"
15#include "globals.h"
16#include "UTIL/kdtree.h"
17#include "coupling.h"
18#include "globalvariables.h"
19
20using namespace std;
21
22template <MInt nDim, class SysEqn>
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}
34
35template <MInt nDim, class SysEqn>
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_);
40 computeGCellTimeStep();
41}
42template <MInt nDim, class SysEqn>
44 computeGCellTimeStep();
45 exchangeCouplingData();
46}
47template <MInt nDim, class SysEqn>
49
50template <MInt nDim, class SysEqn>
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 }
57 computeGCellTimeStep();
58 setRhoFlameTubeInLs();
59 setRhoInfinityInLs();
60}
61
62template <MInt nDim, class SysEqn>
64 if(lsSolver().m_gRKStep != 0) return;
65 if(!lsSolver().m_computeExtVel) return;
66
67 if(!lsSolver().m_smoothExtVel) {
68 fastInterfaceExtensionVelocity();
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}
90
91template <MInt nDim, class SysEqn>
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}
132
133
134template <MInt nDim, class SysEqn>
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
162 fvSolver().a_levelSetFunction(c, 0) = lsSolver().a_levelSetFunctionG(gc, 0);
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
168 constructExtensionVelocity();
169}
170
171template <MInt nDim, class SysEqn>
173 lsSolver().m_timeStep = fvSolver().timeStep(true);
174}
175
176template <MInt nDim, class SysEqn>
178 lsSolver().m_timeStep = timeStep;
179}
180
181
182template <MInt nDim, class SysEqn>
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}
197
198template <MInt nDim, class SysEqn>
200 lsSolver().m_rhoFlameTube = fvSolver().m_rhoFlameTube;
201}
202template <MInt nDim, class SysEqn>
204 lsSolver().m_rhoInfinity = fvSolver().m_rhoInfinity;
205}
206
207
208template <MInt nDim, class SysEqn>
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}
224template <MInt nDim, class SysEqn>
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}
239template <MInt nDim, class SysEqn>
241 MInt noLevelSetFieldData = 0;
242 if(fvSolver().m_levelSet) {
243 if(lsSolver().m_writeOutAllLevelSetFunctions) {
244 noLevelSetFieldData += lsSolver().m_noSets;
245 noLevelSetFieldData += lsSolver().m_noSets;
246 } else
247 noLevelSetFieldData += 1;
248 if(lsSolver().m_writeOutAllCurvatures)
249 noLevelSetFieldData += lsSolver().m_noSets;
250 else
251 noLevelSetFieldData += 1;
252 }
253
254 return noLevelSetFieldData;
255}
256
257
258template <MInt nDim, class SysEqn>
260 if(fvSolver().m_combustion && fvSolver().m_recordPressure && globalTimeStep % 10 == 0) {
261 lsSolver().computeZeroLevelSetArcLength();
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) {
281 lsSolver().computeZeroLevelSetArcLength();
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;
317 MFloat St = fvSolver().m_flameStrouhal;
318 //---
319
320 // compute the cycle time and the cycle
321 sample = (MInt)(globalTimeStep / fvSolver().m_noTimeStepsBetweenSamples);
322
323 currentCycle = (MInt)(sample / fvSolver().m_samplesPerCycle);
324
325 // compute the flame surface area (unfiltered signal)
326 lsSolver().computeZeroLevelSetArcLength();
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;
418 if(fvSolver().a_hasNeighbor(fvSolver().m_activeCellIds[ac], 0) > 0
419 && fvSolver().a_hasNeighbor(fvSolver().m_activeCellIds[ac], 2)
420 > 0) // number of neighbors in -x and -y direction > 0
421 continue;
422 fvSolver().m_sweepStartFirstCell =
423 fvSolver().m_activeCellIds[ac];
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;
433 fvSolver().m_sweepStartFirstCell = fvSolver().m_activeCellIds[ac];
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");
451 current = fvSolver().m_sweepStartFirstCell;
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
533 current = fvSolver().m_sweepStartFirstCell;
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
889 fvSolver().setRestartFileOutputTimeStep();
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}
1012
1013
1014// works only with zeroth level-set function!
1015template <MInt nDim, class SysEqn>
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;
1059 MFloat rhoUFrhoB = fvSolver().m_burntUnburntTemperatureRatio;
1060 MFloat rhoBurnt = fvSolver().m_rhoInfinity / fvSolver().m_burntUnburntTemperatureRatio;
1061 MFloat rhoJump = F1 / fvSolver().m_burntUnburntTemperatureRatio - F1;
1062 MFloat FrhoBurnt = fvSolver().m_burntUnburntTemperatureRatio;
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
1077 fvSolver().m_maxReactionRate = F0;
1078 fvSolver().m_totalHeatReleaseRate = F0;
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 =
1109 (fvSolver().m_burntUnburntTemperatureRatioEnd - fvSolver().m_burntUnburntTemperatureRatioStart);
1110 fvSolver().m_burntUnburntTemperatureRatio = (diffTemp / diffTimeStep) * (globalTimeStep - m_restartTimeStep)
1111 + fvSolver().m_burntUnburntTemperatureRatioStart;
1112 }
1113 rhoBurnt = m_rhoFlameTube / fvSolver().m_burntUnburntTemperatureRatio;
1114 FrhoBurnt = fvSolver().m_burntUnburntTemperatureRatio * F1 / m_rhoFlameTube;
1115 rhoJump = F1 - fvSolver().m_burntUnburntTemperatureRatio;
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) -=
1253 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(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);
1260 fvSolver().m_totalHeatReleaseRate +=
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";
1269 fvSolver().saveSolverSolution(1);
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 =
1298 (fvSolver().m_burntUnburntTemperatureRatioEnd - fvSolver().m_burntUnburntTemperatureRatioStart);
1299 fvSolver().m_burntUnburntTemperatureRatio = (diffTemp / diffTimeStep) * (globalTimeStep - m_restartTimeStep)
1300 + fvSolver().m_burntUnburntTemperatureRatioStart;
1301 }
1302 rhoBurnt = m_rhoFlameTube / fvSolver().m_burntUnburntTemperatureRatio;
1303 FrhoBurnt = fvSolver().m_burntUnburntTemperatureRatio * F1 / m_rhoFlameTube;
1304 rhoJump = F1 - fvSolver().m_burntUnburntTemperatureRatio;
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) -=
1435 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(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);
1442 fvSolver().m_totalHeatReleaseRate +=
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 =
1472 (fvSolver().m_burntUnburntTemperatureRatioEnd - fvSolver().m_burntUnburntTemperatureRatioStart);
1473 fvSolver().m_burntUnburntTemperatureRatio = (diffTemp / diffTimeStep) * (globalTimeStep - m_restartTimeStep)
1474 + fvSolver().m_burntUnburntTemperatureRatioStart;
1475 }
1476 rhoBurnt = m_rhoFlameTube / fvSolver().m_burntUnburntTemperatureRatio;
1477
1478 FrhoBurnt = fvSolver().m_burntUnburntTemperatureRatio * F1 / m_rhoFlameTube;
1479
1480 rhoJump = F1 - fvSolver().m_burntUnburntTemperatureRatio;
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) -=
1629 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(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);
1636 fvSolver().m_totalHeatReleaseRate +=
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) -=
1745 fvSolver().a_reactionRate(c, 0) * fvSolver().a_cellVolume(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);
1751 fvSolver().m_totalHeatReleaseRate +=
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}
1764
1765// ----------------------------------------------------------------------------------------
1766
1777template <MInt nDim, class SysEqn>
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}
1873
1874//-----------------------------------------------------------------------------------------
1875
1876
1885template <MInt nDim, class SysEqn>
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}
1903
1904template class LsFvCombustion<2, FvSysEqnNS<2>>;
1905template class LsFvCombustion<3, FvSysEqnNS<3>>;
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
void postCouple(MInt)
void exchangeCouplingData()
void setRhoFlameTubeInLs()
MInt noLevelSetFieldData()
MFloat collectFvDataForCollectGEquationModelDataOpt(MInt, MInt)
void computeGCellTimeStep()
MFloat collectGFromCouplingClass(MInt)
void constructExtensionVelocity()
void collectGEquationModelDataOpt(MFloat *fluidDensity, MInt set)
MFloat collectCurvFromCouplingClass(MInt)
void setLsTimeStep(MFloat)
void fastInterfaceExtensionVelocity()
void finalizeCouplerInit() override
LsFvCombustion(const MInt couplingId, LsSolver *ls, FvCartesianSolver *fv)
void preCouple(MInt) override
LsSolver & lsSolver() const
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
T * getPointer() const
Deprecated: use begin() instead!
Definition: scratch.h:316
void fill(T val)
fill the scratch with a given value
Definition: scratch.h:311
iterator begin()
Definition: scratch.h:273
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
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
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
MInt id
Definition: maiatypes.h:71
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_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
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
Definition: contexttypes.h:19
define array structures