ODT
Loading...
Searching...
No Matches
solver.cc
Go to the documentation of this file.
1
6#include "solver.h"
7#include "domain.h"
8#include <sstream>
9#include <string>
10#include <iomanip>
11#include <numeric> //accumulate
12
14
19void solver::init(domain *p_domn) {
20
21 domn = p_domn;
22
23 if(domn->pram->LES_type=="THIRDS"){
24 ed3 = new eddy;
25 eddl3 = new domain(domn, domn->pram);
26 eddl3->init(NULL,NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true);
27 ed3->init(domn, eddl3);
28 }
29
30}
31
33
37 if(ed3) delete ed3;
38 if(eddl3) delete eddl3;
39}
40
42
61
62
63 //-------------------------------------------------------------------------
64
65 double tLastDA = 0.0;
66 int cLastDA = 0;
67 bool LeddyAccepted = false;
68
69 stringstream ss1;
70 string s1;
71
72 time = domn->pram->trst; // 0.0 unless you are restarting
73 t0 = domn->pram->trst; // 0.0 unless you are restarting
74
75 PaSum = 0.0;
76 nPaSum = 0;
77 neddies = 0;
78 PaSumC = 0.0;
79 nPaSumC = 0;
80
81 iEtrials = 0;
82
83 //-------------------------------------------------------------------------
84
87
88 domn->io->writeDataFile("odt_init.dat", time);
89
90 domn->mesher->adaptGrid(0, domn->ngrd-1);
91
92 domn->io->writeDataFile("odt_init_adpt.dat", time);
93
95
96 //-------------------------------------------------------------------------
97
98 while(time <= domn->pram->tEnd) {
99
101
103
105
106 LeddyAccepted = sampleEddyAndImplementIfAccepted(); // ODT may reduce dtSmean; sets Pa
107
108 iEtrials++;
109
110 //----------------------
111
112 if(LeddyAccepted) {
113
114 if(++neddies % (domn->pram->modDisp*50) == 0)
115 domn->io->outputHeader();
116 if(neddies % domn->pram->modDisp ==0)
118
119 //if (neddies % domn->pram->modDump == 0) {
120 // ss1.clear(); ss1 << setfill('0') << setw(4) << neddies; ss1 >> s1;
121 // domn->io->writeDataFile("odt_"+s1+"_eddy.dat", time);
122 //}
123
124 domn->mesher->adaptEddyRegionOfMesh(time, tLastDA, cLastDA);
125
126 //if (neddies % domn->pram->modDump == 0) {
127 // ss1.clear(); ss1 << setfill('0') << setw(4) << neddies; ss1 >> s1;
128 // domn->io->writeDataFile("odt_"+s1+"_adptEd.dat", time);
129 //}
130
132
133 //if (neddies % domn->pram->modDump == 0) {
134 // ss1.clear(); ss1 << setfill('0') << setw(4) << neddies; ss1 >> s1;
135 // domn->io->writeDataFile("odt_"+s1+"_diffuse.dat", time);
136 //}
137
138
139 domn->mesher->adaptEddyRegionOfMesh(time, tLastDA, cLastDA);
140
141 if (neddies % domn->pram->modDump == 0) {
142 ss1.clear(); ss1 << setfill('0') << setw(4) << neddies; ss1 >> s1;
143 domn->io->writeDataFile("odt_"+s1+"_adptDif.dat", time);
144 }
145
146 }
147
148 //----------------------
149
150 time += sampleDt(); // advance the time
151
152 raiseDtSmean(); // may reset PaSum, nPaSum, dtSmean
153 }
154
155 time = domn->pram->tEnd;
156 if(t0 < time)
158
159 //-------------------------------------------------------------------------
160
161 domn->io->writeDataFile("odt_end.dat", time);
162}
163
165
170
171 if(!domn->pram->Lspatial)
172 dtSmean = 0.1*domn->pram->Pav * domn->Ldomain() * domn->Ldomain() /
174 else
175 dtSmean = 10.*domn->pram->Pav * domn->Ldomain() / domn->ngrd / domn->ngrd;
176
177}
178
180
185
186 return -dtSmean*log( max(1.0e-14, domn->rand->getRand()) );
187
188}
189
191
197
198 double dxmin = 1.0E10;
199 double d1;
200 for(int i=1; i<domn->ngrdf; i++) {
201 d1 = domn->posf->d.at(i) - domn->posf->d.at(i-1);
202 if(d1 < dxmin)
203 dxmin = d1;
204 }
205 if(!domn->pram->Lspatial)
206 dtCUmax = domn->pram->tdfac * dxmin * dxmin / domn->pram->kvisc0;
207 else
208 dtCUmax = 50.0 * domn->pram->tdfac * dxmin;
209
210}
211
213
218
219 if(!Ldoit && time-t0 < dtCUmax)
220 return;
221
222#ifndef SILENT
223 *domn->io->ostrm << endl << "# Catching up diffusion to eddies: time = " << time;
224#endif
225
227
228 t0 = time;
229
230}
231
233
238
239 if(iEtrials % domn->pram->nDtSmeanWait != 0)
240 return; // only do this once in a while
241
242 if(nPaSum > 0)
243 PaSum /= nPaSum; // PaSum is now average Pa of eddies
244
245 if(PaSum < domn->pram->Pav) {
246 if(PaSum < domn->pram->Pav/domn->pram->dtfac)
247 dtSmean *= domn->pram->dtfac; // increase by at most dtfac
248 else
249 dtSmean *= domn->pram->Pav/PaSum; // increase dtSmean to target value
250
251 *domn->io->ostrm << endl << "# increasing dtSmean to " << dtSmean
252 << " (neddies = " << neddies << " eddy trails = " << iEtrials << ")";
253 }
254
255 PaSum = 0.0; // reset values
256 nPaSum = 0;
257 if (iEtrials > 10000*domn->pram->nDtSmeanWait) {
258 *domn->io->ostrm << endl << "# reset iEtrials, PaSumC, nPaSumC after "
259 << 10000*domn->pram->nDtSmeanWait << " eddy trials.";
260 iEtrials = 0;
261 PaSumC = 0.0;
262 nPaSumC = 0;
263 }
264
265}
266
268
279
281
283 return false;
284
286
287
288 //---------- extract the eddy segment from domn into eddl
289
290 int iStart = domn->domainPositionToIndex(domn->ed->leftEdge, true, 4);
291 int iEnd = domn->domainPositionToIndex(domn->ed->rightEdge, false, 5);
292
293 if(!domn->ed->LperiodicEddy) {
294 if(iEnd - iStart < domn->pram->eddyMinCells)
295 return false;
296 }
297 else {
298 if( (domn->ngrd-iStart)+(iEnd)+1 < domn->pram->eddyMinCells)
299 return false;
300 }
301
302 domn->eddl->setDomainFromRegion(iStart, iEnd);
303
304 //---------- invoke the eddy
305
306 double cCoord_local = domn->pram->LplanarTau ? 1.0 : domn->pram->cCoord;
307
308 domn->ed->tripMap(domn->eddl, 0, domn->eddl->ngrd-1, cCoord_local);
309
310 if(!domn->ed->eddyTau(domn->pram->Z_param, cCoord_local))
311 return false;
312
313 double eddyTauOrSizeForLES = (domn->pram->Lspatial ? domn->ed->eddySize : 1.0/domn->ed->invTauEddy);
314 if(!testLES_elapsedTime(time, eddyTauOrSizeForLES))
315 return false;
316
318 return false;
319
321
322 //---------- lower dtSample if Pa too high; changes Pa, dtSmean
323
324 lowerDtSmean();
325
326 //---------- apply the eddy if accepted
327
328 double rnd = domn->rand->getRand();
329
330 if(rnd <= domn->ed->Pa) {
331
332 if(!testLES_thirds()) // large eddy supression test
333 return false;
334
335 if(domn->ed->LperiodicEddy) {
336 *domn->io->ostrm << endl << "# periodic eddy ";
337 double cycleDistance = domn->cyclePeriodicDomain(iEnd);
338 double bkp_rightEdge = domn->ed->rightEdge;
340 iStart = domn->domainPositionToIndex(domn->ed->leftEdge, true, 6);
341 iEnd = domn->domainPositionToIndex(domn->ed->rightEdge, false, 7);
342 domn->ed->tripMap(domn, iStart, iEnd, domn->pram->cCoord, true);
343 domn->backCyclePeriodicDomain(cycleDistance);
344 domn->ed->rightEdge = bkp_rightEdge;
345 }
346 else
347 domn->ed->tripMap(domn, iStart, iEnd, domn->pram->cCoord, true);
348
349 iStart = domn->domainPositionToIndex(domn->ed->leftEdge, true, 8);
350 iEnd = domn->domainPositionToIndex(domn->ed->rightEdge, false, 9);
351
352 if(domn->pram->Lspatial) { // vary domain to conserve mass flux for u changes from kernels
353 vector<double> dxc_or_rhoUdxc(domn->ngrd);
354 domn->mesher->setGridDxc(domn, dxc_or_rhoUdxc, domn->pram->cCoord);
355 for(int i=0; i<domn->ngrd; i++)
356 dxc_or_rhoUdxc[i] = dxc_or_rhoUdxc[i] * domn->rho->d[i] * domn->uvel->d[i];
357
358 domn->ed->applyVelocityKernels(domn, iStart, iEnd);
359
360 for(int i=0; i<domn->ngrd; i++)
361 dxc_or_rhoUdxc[i] = dxc_or_rhoUdxc[i] / (domn->rho->d[i] * domn->uvel->d[i]);
362 domn->mesher->setGridFromDxc(dxc_or_rhoUdxc);
363
364 domn->mesher->enforceDomainSize(); // chop the domain
365 }
366 else
367 domn->ed->applyVelocityKernels(domn, iStart, iEnd);
368
369 return true;
370 }
371
372 return false;
373}
374
376
382bool solver::testLES_elapsedTime(const double time, const double tauEddy) {
383
384 if(domn->pram->LES_type != "ELAPSEDTIME")
385 return true;
386
387 if( (time-domn->pram->x0virtual) < domn->pram->Z_LES * tauEddy ) //doldb
388 return false;
389
390 return true;
391}
392
394
398bool solver::testLES_fracDomain(const double eSize) {
399 if(domn->pram->LES_type != "FRACDOMAIN")
400 return true;
401 if(eSize/domn->Ldomain() > domn->pram->Z_LES)
402 return false;
403 return true;
404}
405
407
417bool solver::testLES_integralLength(const double time, const double eSize) {
418
419 if(domn->pram->LES_type != "INTEGRALSCALE")
420 return true;
421
422 double n = 1.1;
423 double t0 = 0.15899;
424 double L0 = 0.028323;
425 double integralLength = domn->pram->Z_LES * L0 * pow(time/t0, 1-0.5*n);
426
427 if(eSize > integralLength)
428 return false;
429 return true;
430}
431
433
438
439 if(domn->pram->LES_type != "THIRDS")
440 return true;
441
442 ed3->eddySize = domn->ed->eddySize/3.0;
443 ed3->LperiodicEddy = false;
444
445 double leftThird = domn->ed->leftEdge;
446 double rightThird = leftThird + domn->ed->eddySize/3.0;
447
448 double cCoord_local = domn->pram->LplanarTau ? 1.0 : domn->pram->cCoord;
449 for(int third=0; third<3; third++) {
450
451 ed3->leftEdge = leftThird;
452 ed3->rightEdge = rightThird;
453
454 int iStart = domn->domainPositionToIndex(leftThird, true,10);
455 int iEnd = domn->domainPositionToIndex(rightThird, false,11);
456
457 eddl3->setDomainFromRegion(iStart, iEnd);
458
459 //---------- invoke the eddy
460
461 ed3->tripMap(eddl3, 0, eddl3->ngrd-1, cCoord_local); // apply trip map to eddyLine
462
463 if(!ed3->eddyTau(domn->pram->Z_LES, cCoord_local))
464 return false;
465
466 leftThird = rightThird;
467 rightThird = leftThird + domn->ed->eddySize/3.0;
468
469 }
470
471 return true; // Eddy is allowed (not suppressed).
472}
473
475
479
480 if(domn->ed->Pa > domn->pram->Pmax) {
481 dtSmean *= domn->pram->Pmax/domn->ed->Pa;
482 domn->ed->Pa = domn->pram->Pmax;
483 *domn->io->ostrm << endl << "# reducing dtSmean to " << dtSmean;
484 *domn->io->ostrm << endl << "# ed.Pa, pram.Pmax = " << domn->ed->Pa << " " << domn->pram->Pmax;
485 *domn->io->ostrm << endl << "# time " << time;
486 }
487
488 //---------- update properties used to raise dtSample
489
490 PaSum += domn->ed->Pa;
491 nPaSum++;
492
493 PaSumC += domn->ed->Pa;
494 nPaSumC++;
495
496}
497
int ngrd
number of grid cells
Definition domain.h:42
domain * eddl
pointer to eddyline object
Definition domain.h:76
int domainPositionToIndex(double position, const bool LowSide, int dbg)
Definition domain.cc:234
void init(inputoutput *p_io, meshManager *p_mesher, streams *p_strm, IdealGasPhase *p_gas, Transport *p_tran, micromixer *p_mimx, eddy *p_ed, domain *p_eddl, solver *p_solv, randomGenerator *p_rand, bool LisEddyDomain=false)
Definition domain.cc:46
dv * uvel
Definition domain.h:51
double Ldomain()
Definition domain.cc:156
dv * posf
access as: posf->d[i], or posf->var_name, etc.
Definition domain.h:48
double cyclePeriodicDomain(const int icycle)
Definition domain.cc:304
void setDomainFromRegion(const int i1, const int i2)
Definition domain.cc:207
int ngrdf
number of grid cell faces = ngrd+1
Definition domain.h:43
void backCyclePeriodicDomain(const double backCycleDistance)
Definition domain.cc:336
meshManager * mesher
pointer to mesh manager object
Definition domain.h:78
inputoutput * io
pointer to input/output object
Definition domain.h:72
randomGenerator * rand
Definition domain.h:80
eddy * ed
pointer to object for eddy operations
Definition domain.h:75
micromixer * mimx
pointer to micromixer for diffusion, reaction, domain evolution.
Definition domain.h:74
param * pram
pointer to the parameters object
Definition domain.h:73
dv * rho
Definition domain.h:49
vector< double > d
the data
Definition dv.h:30
Definition eddy.h:21
bool LperiodicEddy
a wrap-around eddy
Definition eddy.h:35
double Pa
eddy acceptance probability
Definition eddy.h:34
double rightEdge
right edge location of eddy
Definition eddy.h:32
void init(domain *p_domn, domain *p_eddl)
Definition eddy.cc:19
void applyVelocityKernels(domain *line, const int iS, const int iE)
Definition eddy.cc:551
void computeEddyAcceptanceProb(const double dtSample)
Definition eddy.cc:528
double invTauEddy
inverse eddy timescale
Definition eddy.h:33
double eddySize
size of eddy
Definition eddy.h:30
double leftEdge
left edge location of eddy
Definition eddy.h:31
bool eddyTau(const double Z_value, const double C)
Definition eddy.cc:285
void tripMap(domain *line, const int iS, int iE, const double C, const bool LsplitAtEddy=false)
Definition eddy.cc:116
void sampleEddySize()
Definition eddy.cc:71
void sampleEddyPosition()
Definition eddy.cc:86
void outputProgress()
output data going with the header info
ostream * ostrm
Runtime: points to cout or to a file.
Definition inputoutput.h:33
void outputHeader()
output header info during odt solution
void writeDataFile(const string fnameRaw, const double time)
writes the gnuplot file and calls outputProperties
void adaptEddyRegionOfMesh(const double &time, double &tLastDA, int &cLastDA)
void setGridFromDxc(const vector< double > &dxc2)
void setGridDxc(const domain *line, vector< double > &dxc, double C)
void adaptGrid(int iLower, int iUpper)
void adaptAfterSufficientDiffTime(const double &time, double &tLastDA, int &cLastDA, double &dtCUmax)
void enforceDomainSize()
virtual void advanceOdt(const double p_tstart, const double p_tend, const int iLevel=-1)
Definition micromixer.cc:41
int nDtSmeanWait
number of eddy samples before increase dtSmean
Definition param.h:78
int cCoord
1 = planar, 2 = cylindrical, 3 = spherical
Definition param.h:68
int eddyMinCells
eddy must overlap at least this many cells
Definition param.h:79
bool Lspatial
spatial formulation if true
Definition param.h:62
double trst
restart time (from restart file), default is 0.0;
Definition param.h:108
int modDump
accepted eddies before output file
Definition param.h:87
double Z_param
Viscous penalty parameter.
Definition param.h:44
double Pmax
maximum eddy acceptance probability
Definition param.h:75
string LES_type
NONE, THIRDS, ELAPSEDTIME, FRACDOMAIN, INTEGRALSCALE.
Definition param.h:47
int modDisp
frequency to display results (# eddies)
Definition param.h:88
double dtfac
maximum factor to increase dtSmean
Definition param.h:77
double Z_LES
large eddy suppression (nonpositive prevents les test)
Definition param.h:48
double x0virtual
LES virtual origin.
Definition param.h:52
double Pav
Average acceptance probability.
Definition param.h:76
bool LplanarTau
true for computing cylindrical/spherical tau_eddy using a planar formulation. If accepted,...
Definition param.h:64
double kvisc0
initial uniform kinematic viscosity (m^2/s)
Definition param.h:37
double tdfac
factor between dtCUmax and dtCFL for temporal flows; DEFAULT = 1.0
Definition param.h:81
double tEnd
ending time of realization
Definition param.h:33
bool testLES_fracDomain(const double eSize)
Definition solver.cc:398
void raiseDtSmean()
Definition solver.cc:237
virtual void init(domain *p_domn)
Definition solver.cc:19
double PaSumC
sum of Pa of eddies
Definition solver.h:44
domain * eddl3
pointer to eddy line object
Definition solver.h:31
int nPaSum
number going into PaSum
Definition solver.h:42
void computeDtCUmax()
Definition solver.cc:196
bool sampleEddyAndImplementIfAccepted()
Definition solver.cc:278
bool LeddyAccepted
flag for accepted eddy
Definition solver.h:38
void computeDtSmean()
Definition solver.cc:169
int neddies
number of eddies accepted
Definition solver.h:43
virtual void calculateSolution()
Definition solver.cc:60
virtual ~solver()
Definition solver.cc:36
double t0
time of last eddy event; diffusion left off here.
Definition solver.h:34
bool testLES_elapsedTime(const double time, const double tauEddy)
Definition solver.cc:382
double dtCUmax
max time before catch up diff/eddy
Definition solver.h:36
domain * domn
pointer to domain object
Definition solver.h:28
bool testLES_integralLength(const double time, const double eSize)
Definition solver.cc:417
double dtSmean
initial mean eddy sample time
Definition solver.h:35
double time
odt time (during sampling)
Definition solver.h:33
int iEtrials
number of eddy trials
Definition solver.h:39
double sampleDt()
Definition solver.cc:184
eddy * ed3
pointer to eddy object for thirds
Definition solver.h:30
double PaSum
sum of Pa of eddies
Definition solver.h:41
void diffusionCatchUpIfNeeded(bool Ldoit=false)
Definition solver.cc:217
bool testLES_thirds()
Definition solver.cc:437
int nPaSumC
number going into PaSum
Definition solver.h:45
void lowerDtSmean()
Definition solver.cc:478
Header file for class domain.
Header file for class solver.