24template <MInt nDim, MInt nDist,
class SysEqn>
27 :
LbSolver<nDim>(
id, noDistributions, gridProxy_, geometry_, comm),
28 m_srcTermController(this),
41 if(grid().isActive()) {
42 this->prepareCommunication();
43 if(m_geometry->m_parallelGeometry) {
44 this->receiveWindowTriangles();
48 m_log <<
"noCells(offset) =" << this->noInternalCells() << endl;
49 m_log <<
"noCells(size) =" << this->m_cells.size() << endl;
59template <MInt nDim, MInt nDist,
class SysEqn>
62 if(m_isRefined || this->m_adaptation)
delete m_interface;
73template <MInt nDim, MInt nDist,
class SysEqn>
79 const MInt noCells = a_noCells();
83 const MInt maxLevel_ = maxLevel();
85 maia::parallelFor<true>(0, noCells, [=](
MInt i) {
86 if(gTS %
IPOW2(maxLevel_ - this->a_level(i)) != 0)
return;
87 const MInt lastId = nDist - 1;
88 for(
MInt j = 0; j < lastId; ++j) {
89 if(
auto n = c_neighborId(i, j); n > -1) {
90 a_oldDistribution(n, j) = a_distribution(i, j);
93 a_oldDistribution(i, lastId) = a_distribution(i, lastId);
96 postPropagationSrcTerm();
112template <MInt nDim, MInt nDist,
class SysEqn>
116 MInt nghbrId, nghbrId2;
118 if(m_isRefined) prolongation();
120 for(
MInt i = 0; i < a_noCells(); i++) {
122 for(
MInt j = 0; j < nDist - 1; j += 2) {
123 nghbrId = c_neighborId(i, j);
124 nghbrId2 = c_neighborId(i, j + 1);
126 if(nghbrId > -1) a_oldDistribution(nghbrId, j) = a_distribution(i, j);
127 if(nghbrId2 > -1) a_oldDistribution(nghbrId2, j + 1) = a_distribution(i, j + 1);
129 a_oldDistribution(i, nDist - 1) = a_distribution(i, nDist - 1);
138#ifdef WRITECELLVALUES
142 if(domainId() == 7) {
143 ofl.open(
"x0p75.dat", ios_base::app);
144 ofl <<
globalTimeStep <<
" " << a_variable(212707, 0) <<
" " << a_variable(212707, 1) <<
" "
145 << a_variable(212707, 2) <<
" " << a_variable(212707, 3) << endl;
148 ofl.open(
"x1p5.dat", ios_base::app);
149 ofl <<
globalTimeStep <<
" " << a_variable(235107, 0) <<
" " << a_variable(235107, 1) <<
" "
150 << a_variable(235107, 2) <<
" " << a_variable(235107, 3) << endl;
159template <MInt nDim, MInt nDist,
class SysEqn>
165 const MInt noCells = a_noCells();
169 const MInt maxLevel_ = maxLevel();
171 maia::parallelFor<true>(0, noCells, [=](
MInt i) {
172 if(gTS %
IPOW2(maxLevel_ - this->a_level(i)) != 0)
return;
173 const MInt lastId = nDist - 1;
174 for(
MInt j = 0; j < lastId; ++j) {
175 if(
auto n = c_neighborId(i, j); n > -1) {
176 a_oldDistribution(n, j) = a_distribution(i, j);
177 a_oldDistributionThermal(n, j) = a_distributionThermal(i, j);
180 a_oldDistribution(i, lastId) = a_distribution(i, lastId);
181 a_oldDistributionThermal(i, lastId) = a_distributionThermal(i, lastId);
197template <MInt nDim, MInt nDist,
class SysEqn>
203 const MInt noCells = a_noCells();
207 const MInt maxLevel_ = maxLevel();
209 maia::parallelFor<true>(0, noCells, [=](
MInt i) {
210 if(gTS %
IPOW2(maxLevel_ - this->a_level(i)) != 0)
return;
211 const MInt lastId = nDist - 1;
212 for(
MInt j = 0; j < lastId; ++j) {
213 if(
auto n = c_neighborId(i, j); n > -1) {
214 a_oldDistribution(n, j) = a_distribution(i, j);
215 a_oldDistributionTransport(n, j) = a_distributionTransport(i, j);
218 a_oldDistribution(i, lastId) = a_distribution(i, lastId);
219 a_oldDistributionTransport(i, lastId) = a_distributionTransport(i, lastId);
235template <MInt nDim, MInt nDist,
class SysEqn>
241 const MInt noCells = a_noCells();
245 const MInt maxLevel_ = maxLevel();
247 maia::parallelFor<true>(0, noCells, [=](
MInt i) {
248 if(gTS %
IPOW2(maxLevel_ - this->a_level(i)) != 0)
return;
249 const MInt lastId = nDist - 1;
250 for(
MInt j = 0; j < lastId; ++j) {
251 if(
auto n = c_neighborId(i, j); n > -1) {
252 a_oldDistribution(n, j) = a_distribution(i, j);
253 a_oldDistributionThermal(n, j) = a_distributionThermal(i, j);
254 a_oldDistributionTransport(n, j) = a_distributionTransport(i, j);
257 a_oldDistribution(i, lastId) = a_distribution(i, lastId);
258 a_oldDistributionThermal(i, lastId) = a_distributionThermal(i, lastId);
259 a_oldDistributionTransport(i, lastId) = a_distributionTransport(i, lastId);
276template <MInt nDim, MInt nDist,
class SysEqn>
280 MInt nghbrId, nghbrId2;
282 if(m_isRefined) prolongation();
284 for(
MInt i = 0; i < a_noCells(); i++) {
286 for(
MInt j = 0; j < nDist - 1; j += 2) {
287 nghbrId = c_neighborId(i, j);
288 nghbrId2 = c_neighborId(i, j + 1);
290 a_oldDistribution(nghbrId, j) = a_distribution(i, j);
291 a_oldDistributionThermal(nghbrId, j) = a_distributionThermal(i, j);
294 a_oldDistribution(nghbrId2, j + 1) = a_distribution(i, j + 1);
295 a_oldDistributionThermal(nghbrId2, j + 1) = a_distributionThermal(i, j + 1);
298 a_oldDistribution(i, nDist - 1) = a_distribution(i, nDist - 1);
299 a_oldDistributionThermal(i, nDist - 1) = a_distributionThermal(i, nDist - 1);
313template <MInt nDim, MInt nDist,
class SysEqn>
317 MInt nghbrId, nghbrId2;
319 if(m_isRefined) prolongation();
321 for(
MInt i = 0; i < a_noCells(); i++) {
323 for(
MInt j = 0; j < nDist - 1; j += 2) {
324 nghbrId = c_neighborId(i, j);
325 nghbrId2 = c_neighborId(i, j + 1);
327 a_oldDistribution(nghbrId, j) = a_distribution(i, j);
328 a_oldDistributionTransport(nghbrId, j) = a_distributionTransport(i, j);
331 a_oldDistribution(nghbrId2, j + 1) = a_distribution(i, j + 1);
332 a_oldDistributionTransport(nghbrId2, j + 1) = a_distributionTransport(i, j + 1);
335 a_oldDistribution(i, nDist - 1) = a_distribution(i, nDist - 1);
336 a_oldDistributionTransport(i, nDist - 1) = a_distributionTransport(i, nDist - 1);
348template <MInt nDim, MInt nDist,
class SysEqn>
352 MInt nghbrId, nghbrId2;
354 if(m_isRefined) prolongation();
356 for(
MInt i = 0; i < a_noCells(); i++) {
358 for(
MInt j = 0; j < nDist - 1; j += 2) {
359 nghbrId = c_neighborId(i, j);
360 nghbrId2 = c_neighborId(i, j + 1);
362 a_oldDistribution(nghbrId, j) = a_distribution(i, j);
363 a_oldDistributionThermal(nghbrId, j) = a_distributionThermal(i, j);
364 a_oldDistributionTransport(nghbrId, j) = a_distributionTransport(i, j);
367 a_oldDistribution(nghbrId2, j + 1) = a_distribution(i, j + 1);
368 a_oldDistributionThermal(nghbrId2, j + 1) = a_distributionThermal(i, j + 1);
369 a_oldDistributionTransport(nghbrId2, j + 1) = a_distributionTransport(i, j + 1);
372 a_oldDistribution(i, nDist - 1) = a_distribution(i, nDist - 1);
373 a_oldDistributionThermal(i, nDist - 1) = a_distributionThermal(i, nDist - 1);
374 a_oldDistributionTransport(i, nDist - 1) = a_distributionTransport(i, nDist - 1);
381template <MInt nDim, MInt nDist,
class SysEqn>
382template <MInt timeStepOffset>
386 const MInt maxLevel_ = maxLevel();
388 if(this->isCompressible()) {
389 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt index) {
390 const MInt pCellId = m_activeCellList[index];
391 const MInt lvlDiff = maxLevel_ - a_level(pCellId);
392 if(gTSmOffset %
IPOW2(lvlDiff) != 0)
return;
393 swap_variables(pCellId);
396 for(
MInt d = 0; d < nDim; d++) {
397 u[d] = a_variable(pCellId, d);
399 MFloat l_rho = a_variable(pCellId, PV->RHO);
400 calculateMacroscopicVariables<true>(pCellId, l_rho, u);
401 for(
MInt d = 0; d < nDim; d++) {
402 a_variable(pCellId, d) = u[d];
404 a_variable(pCellId, PV->RHO) = l_rho;
406 calculateMacroscopicVariables<true>(pCellId, a_variable(pCellId, PV->RHO), &a_variable(pCellId, PV->U));
410 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt index) {
411 const MInt pCellId = m_activeCellList[index];
412 const MInt lvlDiff = maxLevel_ - a_level(pCellId);
413 if(gTSmOffset %
IPOW2(lvlDiff) != 0)
return;
414 swap_variables(pCellId);
417 for(
MInt d = 0; d < nDim; d++) {
418 u[d] = a_variable(pCellId, d);
420 MFloat l_rho = a_variable(pCellId, PV->RHO);
421 calculateMacroscopicVariables(pCellId, l_rho, u);
422 for(
MInt d = 0; d < nDim; d++) {
423 a_variable(pCellId, d) = u[d];
425 a_variable(pCellId, PV->RHO) = l_rho;
427 calculateMacroscopicVariables(pCellId, a_variable(pCellId, PV->RHO), &a_variable(pCellId, PV->U));
433template <MInt nDim, MInt nDist,
class SysEqn>
435 updateVariablesFromOldDist_<0>();
438template <MInt nDim, MInt nDist,
class SysEqn>
444 updateVariablesFromOldDist_<1>();
455template <MInt nDim, MInt nDist,
class SysEqn>
460 if(m_controlVelocity) controlVelocity();
464 const MInt maxLevel_ = maxLevel();
467 if(this->m_externalForcing) {
469 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt index) {
470 const MInt pCellId = m_activeCellList[index];
471 const MInt lvlDiff = maxLevel_ - a_level(pCellId);
472 if((gTS) %
IPOW2(lvlDiff) != 0)
return;
473 for(
MInt j = 0; j < nDist - 1; j++) {
474 a_oldDistribution(pCellId, j) +=
FPOW2(maxLevel_ - this->a_level(pCellId)) * m_Fext[j];
479 if(m_isEELiquid && m_EELiquid.gravity) {
480 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt index) {
481 const MInt pCellId = m_activeCellList[index];
482 const MInt lvlDiff = maxLevel_ - a_level(pCellId);
483 if((gTS) %
IPOW2(lvlDiff) != 0)
return;
484 const MFloat alpha = a_alphaGasLim(pCellId);
486 for(
MInt j = 0; j < nDist - 1; j++) {
490 a_oldDistribution(pCellId, j) -=
FPOW2(maxLevel_ - this->a_level(pCellId)) * m_EELiquid.Fg[j] * alpha;
503template <MInt nDim, MInt nDist,
class SysEqn>
507 averageGlobalVelocity(
508 m_velocityControl.dir);
509 const MFloat velocityGoal = m_Ma / F1BCS;
510 if((m_velocityControl.lastGlobalAvgV > 5.0 * velocityGoal) || (m_velocityControl.lastGlobalAvgV < 0.0)
511 || !std::isfinite(m_velocityControl.lastGlobalAvgV)) {
512 if(domainId() == 0) cerr <<
"TS " <<
globalTimeStep <<
" avVel " << m_velocityControl.lastGlobalAvgV << endl;
514 TERMM(1,
"Velocity control failed!");
516 const MFloat error = (m_velocityControl.lastGlobalAvgV - velocityGoal) / velocityGoal;
517 m_velocityControl.integratedError += (error + m_velocityControl.previousError) / 2.0 * m_velocityControl.interval;
518 m_velocityControl.derivedError = (error - m_velocityControl.previousError) / m_velocityControl.interval;
520 MFloat controlSignal = m_velocityControl.KT
521 * (error + F1 / m_velocityControl.KI * m_velocityControl.integratedError
522 + m_velocityControl.KD * m_velocityControl.derivedError);
524 controlSignal =
mMax(
mMin(controlSignal, 100.0), -100.0);
526 m_volumeAccel[m_velocityControl.dir] =
527 m_volumeAccelBase[m_velocityControl.dir] - controlSignal * m_volumeAccelBase[m_velocityControl.dir];
529 this->initVolumeForces();
532 ss <<
"Average velocity at TS " <<
globalTimeStep <<
" is " << m_velocityControl.lastGlobalAvgV
533 <<
" (goal: " << velocityGoal <<
") accel set to: [" << m_volumeAccel[0] <<
", " << m_volumeAccel[1];
535 ss <<
", " << m_volumeAccel[2];
537 ss <<
"] (base was [" << m_volumeAccelBase[0] <<
", " << m_volumeAccelBase[1];
539 ss <<
", " << m_volumeAccelBase[2];
542 ss <<
"Error: " << error <<
" previousError: " << m_velocityControl.previousError
543 <<
" integratedError: " << m_velocityControl.integratedError
544 <<
" derivedError: " << m_velocityControl.derivedError << endl;
545 if(domainId() == 0) {
550 m_velocityControl.previousError = error;
562template <MInt nDim, MInt nDist,
class SysEqn>
569 for(
MInt cellId = 0; cellId < this->grid().noInternalCells(); cellId++) {
570 if(this->c_noChildren(cellId) != 0)
continue;
571 const MFloat cellVolume = this->grid().cellVolumeAtLevel(this->c_level(cellId));
573 const MFloat y1 = a_variable(cellId, dir) * cellVolume - c1;
574 const MFloat t1 = sumV[0] + y1;
575 c1 = (t1 - sumV[0]) - y1;
577 sumV[1] += cellVolume;
582 m_velocityControl.lastGlobalAvgV = sumV[0] / sumV[1];
585template <MInt nDim, MInt nDist,
class SysEqn>
586template <MBool useSmagorinsky>
589 std::stringstream ss;
590 if constexpr(useSmagorinsky) {
591 ss <<
"CLB_SMAGORINSKY collision step not defined for d" << nDim <<
"q" << nDist <<
" !";
593 ss <<
"CLB collision step not defined for d" << nDim <<
"q" << nDist <<
" !";
602 constexpr MInt nDist = 9;
605 {1.0, 0.0, 0.0, -4.0, 0.0, 0.0, 0.0, 0.0, 4.0}, {1.0, -1.0, 1.0, 2.0, 0.0, 1.0, -1.0, 1.0, 1.0},
606 {1.0, -1.0, 0.0, -1.0, 1.0, 0.0, 0.0, -2.0, -2.0}, {1.0, -1.0, -1.0, 2.0, 0.0, -1.0, 1.0, 1.0, 1.0},
607 {1.0, 0.0, -1.0, -1.0, -1.0, 0.0, -2.0, 0.0, -2.0}, {1.0, 1.0, -1.0, 2.0, 0.0, 1.0, 1.0, -1.0, 1.0},
608 {1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 2.0, -2.0}, {1.0, 1.0, 1.0, 2.0, 0.0, -1.0, -1.0, -1.0, 1.0},
609 {1.0, 0.0, 1.0, -1.0, -1.0, 0.0, 2.0, 0.0, -2.0}};
611 for(
MInt id = 0;
id < a_noCells();
id++) {
613 m_nu = m_Ma * LBCS / m_Re * m_referenceLength *
FFPOW2(maxLevel() - this->a_level(
id));
615 MLongFloat omega[9] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
616 m_omega = 2.0 / (1.0 + 6.0 * m_nu);
623 for(
MInt j = 0; j < nDist; j++) {
624 a_variable(
id, PV->RHO) += a_oldDistribution(
id, j);
626 const MFloat rho = a_variable(
id, PV->RHO);
628 a_variable(
id, PV->U) = (a_oldDistribution(
id, 1) + a_oldDistribution(
id, 4) + a_oldDistribution(
id, 5)
629 - a_oldDistribution(
id, 7) - a_oldDistribution(
id, 6) - a_oldDistribution(
id, 0))
632 a_variable(
id, PV->V) = (a_oldDistribution(
id, 7) + a_oldDistribution(
id, 3) + a_oldDistribution(
id, 4)
633 - a_oldDistribution(
id, 6) - a_oldDistribution(
id, 2) - a_oldDistribution(
id, 5))
636 const MFloat u = a_variable(
id, PV->U);
637 const MFloat v = a_variable(
id, PV->V);
639 const MFloat r = a_oldDistribution(
id, 8);
640 const MFloat nw = a_oldDistribution(
id, 7);
641 const MFloat w = a_oldDistribution(
id, 0);
642 const MFloat sw = a_oldDistribution(
id, 6);
643 const MFloat s = a_oldDistribution(
id, 2);
644 const MFloat se = a_oldDistribution(
id, 5);
645 const MFloat e = a_oldDistribution(
id, 1);
646 const MFloat ne = a_oldDistribution(
id, 4);
647 const MFloat n = a_oldDistribution(
id, 3);
654 keq[3] = omega[3] * (rho * (u * u + v * v) - e - n - s - w - 2.0 * (se + sw + ne + nw - F1B3 * rho)) / 12.0;
656 keq[4] = omega[4] * (n + s - e - w + rho * (u * u - v * v)) / 4.0;
658 keq[5] = omega[5] * ((ne + sw - nw - se) - u * v * rho) / 4.0;
662 * ((se + sw - ne - nw - 2 * u * u * v * rho + v * (rho - n - s - r)) / 4.0
663 + u / 2.0 * (ne - nw - se + sw)))
664 - v / 2.0 * (-3.0 * keq[3] - keq[4]) - 2.0 * u * keq[5];
667 * ((sw + nw - se - ne - 2 * v * v * u * rho + u * (rho - w - e - r)) / 4.0
668 + v / 2.0 * (ne - nw - se + sw) / 2.0))
669 - u / 2.0 * (-3.0 * keq[3] + keq[4]) - 2.0 * v * keq[5];
672 * (F1B9 * rho - ne - nw - se - sw + 2.0 * (u * (ne - nw + se - sw) + v * (ne + nw - se - sw))
673 + 4.0 * u * v * (nw - ne + se - sw) - u * u * (n + ne + nw + s + se + sw)
674 + v * v * (3.0 * u * u * rho - e - ne - nw - se - sw - w)))
675 - 2.0 * keq[3] - 2.0 * u * keq[7] - 2.0 * v * keq[6] + 4 * u * v * keq[5]
676 - (1.5 * keq[3] - F1B2 * keq[4]) * (u * u + v * v);
680 for(
MInt l = 0; l < 9; l++) {
681 k[l] = std::inner_product(&K[l][0], &K[l][9], &keq[0], F0);
684 a_distribution(
id, 8) = a_oldDistribution(
id, 8) + k[0];
685 a_distribution(
id, 7) = a_oldDistribution(
id, 7) + k[1];
686 a_distribution(
id, 0) = a_oldDistribution(
id, 0) + k[2];
687 a_distribution(
id, 6) = a_oldDistribution(
id, 6) + k[3];
688 a_distribution(
id, 2) = a_oldDistribution(
id, 2) + k[4];
689 a_distribution(
id, 5) = a_oldDistribution(
id, 5) + k[5];
690 a_distribution(
id, 1) = a_oldDistribution(
id, 1) + k[6];
691 a_distribution(
id, 4) = a_oldDistribution(
id, 4) + k[7];
692 a_distribution(
id, 3) = a_oldDistribution(
id, 3) + k[8];
701 constexpr MInt nDist = 19;
703 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
704 const MInt pCellId = m_activeCellList[i];
707 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
709 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId)));
712 swap_variables(pCellId);
715 a_variable(pCellId, PV->RHO) = 0.0;
716 for(
MInt j = 0; j < nDist; j++) {
717 a_variable(pCellId, PV->RHO) += a_oldDistribution(pCellId, j);
720 a_variable(pCellId, PV->U) = 0.0;
721 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
722 a_variable(pCellId, PV->U) += a_oldDistribution(pCellId, Ld::pFld(0, j));
723 a_variable(pCellId, PV->U) -= a_oldDistribution(pCellId, Ld::nFld(0, j));
725 a_variable(pCellId, PV->U) /= a_variable(pCellId, PV->RHO);
727 a_variable(pCellId, PV->V) = 0.0;
728 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
729 a_variable(pCellId, PV->V) += a_oldDistribution(pCellId, Ld::pFld(1, j));
730 a_variable(pCellId, PV->V) -= a_oldDistribution(pCellId, Ld::nFld(1, j));
732 a_variable(pCellId, PV->V) /= a_variable(pCellId, PV->RHO);
734 a_variable(pCellId, PV->W) = 0.0;
735 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
736 a_variable(pCellId, PV->W) += a_oldDistribution(pCellId, Ld::pFld(2, j));
737 a_variable(pCellId, PV->W) -= a_oldDistribution(pCellId, Ld::nFld(2, j));
739 a_variable(pCellId, PV->W) /= a_variable(pCellId, PV->RHO);
741 const MFloat R = a_oldDistribution(pCellId, 18);
742 const MFloat Nw = a_oldDistribution(pCellId, 7);
743 const MFloat W = a_oldDistribution(pCellId, 0);
744 const MFloat Sw = a_oldDistribution(pCellId, 6);
745 const MFloat S = a_oldDistribution(pCellId, 2);
746 const MFloat Se = a_oldDistribution(pCellId, 8);
747 const MFloat E = a_oldDistribution(pCellId, 1);
748 const MFloat Ne = a_oldDistribution(pCellId, 9);
749 const MFloat N = a_oldDistribution(pCellId, 3);
750 const MFloat Nf = a_oldDistribution(pCellId, 17);
751 const MFloat Nb = a_oldDistribution(pCellId, 16);
752 const MFloat Sf = a_oldDistribution(pCellId, 15);
753 const MFloat Sb = a_oldDistribution(pCellId, 14);
754 const MFloat Ef = a_oldDistribution(pCellId, 13);
755 const MFloat Eb = a_oldDistribution(pCellId, 12);
756 const MFloat Wf = a_oldDistribution(pCellId, 11);
757 const MFloat Wb = a_oldDistribution(pCellId, 10);
758 const MFloat F = a_oldDistribution(pCellId, 5);
759 const MFloat B = a_oldDistribution(pCellId, 4);
761 const MFloat rho = Nw + W + Sw + S + Se + E + Ne + N + R + Nf + Nb + Sf + Sb + Ef + Eb + Wf + Wb + F + B;
762 const MFloat pi_x = (Ne + E + Se + Ef + Eb - Nw - W - Sw - Wf - Wb);
763 const MFloat pi_y = (Ne + N + Nw + Nf + Nb - Se - S - Sw - Sf - Sb);
764 const MFloat pi_z = (Nf + Sf + Wf + Ef + F - Nb - Sb - Wb - Eb - B);
765 const MFloat vv_x = pi_x / rho;
766 const MFloat vv_y = pi_y / rho;
767 const MFloat vv_z = pi_z / rho;
768 const MFloat vx2 = vv_x * vv_x;
769 const MFloat vy2 = vv_y * vv_y;
770 const MFloat vz2 = vv_z * vv_z;
771 const MFloat uxy = (omega * (Ne - Nw - Se + Sw + vv_x * vv_y * rho - pi_x * vv_y - pi_y * vv_x) * 0.25);
772 const MFloat uxz = (omega * (-Eb + Ef + Wb - Wf + vv_x * vv_z * rho - pi_x * vv_z - pi_z * vv_x) * 0.25);
773 const MFloat uyz = (omega * (-Nb + Nf + Sb - Sf + vv_z * vv_y * rho - pi_z * vv_y - pi_y * vv_z) * 0.25);
775 const MFloat vxy = (omega * (1. / 6.)
776 * (-B - E - F + Nb + Ne + Nf + Nw + Sb + Se + Sf + Sw - W + 2 * (-Eb - Ef + N + S - Wb - Wf)
777 + 2 * (-2 * pi_y * vv_y + pi_x * vv_x + pi_z * vv_z) - rho * (vz2 - 2 * vy2 + vx2)));
778 const MFloat vxz = (omega * (1. / 6.)
779 * (-E + Eb + Ef - N + Nb + Nf - S + Sb + Sf - W + Wb + Wf + 2 * (B + F - Ne - Nw - Se - Sw)
780 + 2 * (-2 * pi_z * vv_z + pi_x * vv_x + pi_y * vv_y) - rho * (vx2 + vy2 - 2 * vz2)));
781 const MFloat pe = ((1. / 126.)
782 * (-B - E - F - N - S - W + 2 * (-Eb - Ef - Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw - Wb - Wf)
783 + (rho + vv_y * (2 * pi_y - vv_y * rho) + vv_z * (2 * pi_z - vv_z * rho)
784 + vv_x * (2 * pi_x - vv_x * rho))));
786 const MFloat UXY = -Ne + Nw + Se - Sw + 4 * uxy;
787 const MFloat UXZ = Eb - Ef - Wb + Wf + 4 * uxz;
788 const MFloat UYZ = Nb - Nf - Sb + Sf + 4 * uyz;
791 * (Nw + Sw + Wf + Wb - Eb - Ef - Ne - Se
793 * (B + Eb + Ef + 84 * pe + F + N + Ne + Nw + S + Se + Sw + Wb + Wf
794 + 2 * (Nb + Nf + Sb + Sf - vxy - vxz)))
795 + 0.25 * (-vv_y * UXY - vv_z * UXZ) - 0.25 * vv_x * (vv_y * pi_y + vv_z * pi_z)
796 + 0.125 * (vy2 + vz2) * (vv_x * rho - pi_x)));
798 * (Sb + Sf + Se + Sw - Nw - Ne - Nf - Nb
800 * (B + E + 84 * pe + F + Nb + Ne + Nf + Nw + Sb + Se + Sf + Sw + W
801 + 2 * (Eb + Ef + Wb + Wf + vxy)))
802 + 0.25 * (-vv_x * UXY - vv_z * UYZ) - 0.25 * vv_y * (vv_z * pi_z + vv_x * pi_x)
803 + 0.125 * (vx2 + vz2) * (vv_y * rho - pi_y)));
805 * (Eb + Nb + Sb + Wb - Ef - Nf - Sf - Wf
807 * (E + Eb + Ef + N + Nb + Nf + S + Sb + Sf + W + Wb + Wf + 84 * pe
808 + 2 * (Ne + Nw + Se + Sw + vxz)))
809 + 0.25 * (-vv_x * UXZ - vv_y * UYZ) - 0.25 * vv_z * (vv_x * pi_x + vv_y * pi_y)
810 + 0.125 * (vx2 + vy2) * (vv_z * rho - pi_z)));
812 const MFloat xxx = ((0.125
813 * (Eb + Ef - Ne + Nw - Se + Sw - Wb - Wf
814 + vv_x * (-B - Eb - Ef - F + N + Ne + Nw + S + Se + Sw - Wb - Wf + 2 * (vxz - vxy)))
815 + 0.25 * (vv_z * UXZ - vv_y * UXY + vv_x * (vv_z * pi_z - vv_y * pi_y))
816 + 0.125 * ((pi_x - vv_x * rho) * (vz2 - vy2))));
819 * (Ne - Nb - Nf + Nw + Sb - Se + Sf - Sw
820 + vv_y * (-E + B + F + Nb - Ne + Nf - Nw + Sb - Se + Sf - Sw - W + 2 * (-vxy - 2 * vxz)))
821 + 0.25 * (vv_x * UXY - vv_z * UYZ + vv_y * (vv_x * pi_x - vv_z * pi_z))
822 + 0.125 * ((pi_y - vv_y * rho) * (vx2 - vz2))));
825 * (Eb - Ef - Nb + Nf - Sb + Sf + Wb - Wf
826 + vv_z * (E + Eb + Ef - N - Nb - Nf - S - Sb - Sf + W + Wb + Wf + 2 * (vxz + 2 * vxy)))
827 + 0.25 * (vv_y * UYZ - vv_x * UXZ + vv_z * (vv_y * pi_y - vv_x * pi_x))
828 + 0.125 * ((pi_z - vv_z * rho) * (vy2 - vx2))));
832 const MFloat X_ = (Eb + Ef + Ne - Nw + Se - Sw - Wb - Wf + 8 * x);
833 const MFloat Y_ = (Nb + Ne + Nf + Nw - Sb - Se - Sf - Sw + 8 *
y);
834 const MFloat Z_ = (Ef - Eb - Nb + Nf - Sb + Sf - Wb + Wf + 8 * z);
848 const MFloat p = ((1. / 12.)
849 * (rho / (3.) - 96 * pe - Eb - Ef - Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw - Wb - Wf
850 + 2 * (+vv_x * X_ + vv_y * Y_ + vv_z * Z_)
852 * (-84 * pe - B - Eb - Ef - F - N - Ne - Nw - S - Se - Sw - Wb - Wf
853 + 2 * (vxy + vxz - Nb - Nf - Sb - Sf))
855 * (-84 * pe - B - E - F - Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw - W
856 + 2 * (-vxy - Eb - Ef - Wb - Wf))
858 * (-84 * pe - E - Eb - Ef - N - Nb - Nf - S - Sb - Sf - W - Wb - Wf
859 + 2 * (-vxz - Ne - Nw - Se - Sw))
860 + 4 * (vv_x * vv_y * UXY + vv_x * vv_z * UXZ + vv_y * vv_z * UYZ)
861 - rho * (vx2 * vy2 + vx2 * vz2 + vy2 * vz2)
862 + 2 * (pi_y * vv_y * (vx2 + vz2) + pi_x * vv_x * (vy2 + vz2) + pi_z * vv_z * (vx2 + vy2))));
866 * (-Eb - Ef - Ne - Nw - Se - Sw - Wb - Wf
868 * (Nb + Nf + Sb + Sf + vv_x * X_
869 + vv_y * (Ne + Nw - Se - Sw + 2 * (Sf + Sb - Nb - Nf - 2 *
y - 6 * yyy))
870 + vv_z * (Ef - Eb - Wb + Wf + 2 * (Nb - Nf + Sb - Sf - 2 * z + 6 * zzz)))
872 * (-B - Eb - Ef - F - N - Ne - Nw - S - Se - Sw - Wb - Wf - 84 * pe
873 - 2 * (Nb + Nf + Sb + Sf - vxy - vxz))
875 * (Eb - E + Ef - Ne - Nw - Se - Sw - W + Wb + Wf + 42 * pe
876 + 2 * (B + F + Nb + Nf + Sb + Sf - vxy - 3 * vxz))
878 * (Ne - E - Eb - Ef + Nw + Se + Sw - W - Wb - Wf + 42 * pe
879 + 2 * (N + Nb + Nf + S + Sb + Sf - vxz - 3 * vxy))
880 + 4 * (vv_x * (vv_y * UXY + vv_z * UXZ)) - 8 * vv_y * vv_z * UYZ
881 + (2 * vy2 * vz2 - vx2 * (vy2 + vz2)) * rho
882 + 2 * (pi_y * vv_y * (vx2 - 2 * vz2) + pi_z * vv_z * (vx2 - 2 * vy2) + pi_x * vv_x * (vy2 + vz2))));
885 * (-Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw
887 * (Eb + Ef + Wb + Wf + vv_x * (Ne - Nw + Se - Sw + 2 * (Wb + Wf - Eb - Ef - 2 * x + 6 * xxx))
888 + vv_y * Y_ + vv_z * (Nf - Nb - Sb + Sf + 2 * (Eb - Ef + Wb - Wf - 2 * z - 6 * zzz)))
890 * (Nb - N - Ne + Nf - Nw - S + Sb - Se + Sf - Sw + 42 * pe
891 + 2 * (B + Eb + Ef + F + Wb + Wf + vxy - 2 * vxz))
892 - vy2 * (B + E + F + Nb + Ne + Nf + Nw + Sb + Se + Sf + Sw + W + 84 * pe + 2 * (Eb + Ef + Wb + Wf + vxy))
894 * (Ne - N - Nb - Nf + Nw - S - Sb + Se - Sf + Sw + 42 * pe
895 + 2 * (E + Eb + Ef + W + Wb + Wf + 3 * vxy + 2 * vxz))
896 + 4 * vv_y * (vv_x * UXY + vv_z * UYZ) - 8 * vv_x * vv_z * UXZ + (2 * vx2 * vz2 - (vx2 + vz2) * vy2) * rho
897 + 2 * (pi_x * vv_x * (vy2 - 2 * vz2) + pi_z * vv_z * (vy2 - 2 * vx2) + pi_y * vv_y * (vx2 + vz2))));
899 a_distribution(pCellId, 18) = R + (12 * p - 30 * pe);
900 a_distribution(pCellId, 7) = Nw + c +
a - xxx - yyy - x +
y + uxy + p + 8 * pe;
901 a_distribution(pCellId, 0) = W - 2 *
a + 4 * x - 11 * pe + vxy + vxz - 4 * p;
902 a_distribution(pCellId, 6) = Sw +
a + c - xxx + yyy - x -
y - uxy + p + 8 * pe;
903 a_distribution(pCellId, 2) = S - 2 * c + 4 *
y - 11 * pe - vxy - 4 * p;
904 a_distribution(pCellId, 8) = Se +
a + c + xxx + yyy + x -
y + uxy + p + 8 * pe;
905 a_distribution(pCellId, 1) = E - 2 *
a - 4 * x - 11 * pe + vxy + vxz - 4 * p;
906 a_distribution(pCellId, 9) = Ne + c +
a + x +
y + xxx - yyy - uxy + p + 8 * pe;
907 a_distribution(pCellId, 3) = N - 2 * c - 4 *
y - 11 * pe - vxy - 4 * p;
908 a_distribution(pCellId, 17) = Nf -
a + yyy - zzz +
y + z - uyz + p + 8 * pe;
909 a_distribution(pCellId, 16) = Nb -
a + yyy + zzz +
y - z + uyz + p + 8 * pe;
910 a_distribution(pCellId, 15) = Sf -
a - yyy - zzz -
y + z + uyz + p + 8 * pe;
911 a_distribution(pCellId, 14) = Sb -
a - yyy + zzz -
y - z - uyz + p + 8 * pe;
912 a_distribution(pCellId, 13) = Ef - c - xxx + zzz + x + z - uxz + p + 8 * pe;
913 a_distribution(pCellId, 12) = Eb - c - xxx - zzz + x - z + uxz + p + 8 * pe;
914 a_distribution(pCellId, 11) = Wf - c + xxx + zzz - x + z + uxz + p + 8 * pe;
915 a_distribution(pCellId, 10) = Wb - c + xxx - zzz - x - z - uxz + p + 8 * pe;
916 a_distribution(pCellId, 5) = F + 2 *
a + 2 * c - 4 * z - 11 * pe - vxz - 4 * p;
917 a_distribution(pCellId, 4) = B + 2 *
a + 2 * c + 4 * z - 11 * pe - vxz - 4 * p;
920 if(m_calculateDissipation &&
globalTimeStep % m_solutionInterval == 0) {
921 calculateDissipation();
926template <MBool useSmagorinsky>
929 constexpr MInt nDist = 27;
930 constexpr MInt nDim = 3;
931 constexpr MInt nDimSqr = 9;
933 [[maybe_unused]]
constexpr MFloat C_s = 0.1;
935 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
936 const MInt pCellId = m_activeCellList[i];
939 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
941 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId)));
942 swap_variables(pCellId);
945 a_variable(pCellId, PV->RHO) = 0.0;
946 for(
MInt j = 0; j < nDist; j++) {
947 a_variable(pCellId, PV->RHO) += a_oldDistribution(pCellId, j);
950 a_variable(pCellId, PV->U) = 0.0;
951 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
952 a_variable(pCellId, PV->U) += a_oldDistribution(pCellId, Ld::pFld(0, j));
953 a_variable(pCellId, PV->U) -= a_oldDistribution(pCellId, Ld::nFld(0, j));
955 a_variable(pCellId, PV->U) /= a_variable(pCellId, PV->RHO);
957 a_variable(pCellId, PV->V) = 0.0;
958 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
959 a_variable(pCellId, PV->V) += a_oldDistribution(pCellId, Ld::pFld(1, j));
960 a_variable(pCellId, PV->V) -= a_oldDistribution(pCellId, Ld::nFld(1, j));
962 a_variable(pCellId, PV->V) /= a_variable(pCellId, PV->RHO);
964 a_variable(pCellId, PV->W) = 0.0;
965 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
966 a_variable(pCellId, PV->W) += a_oldDistribution(pCellId, Ld::pFld(2, j));
967 a_variable(pCellId, PV->W) -= a_oldDistribution(pCellId, Ld::nFld(2, j));
969 a_variable(pCellId, PV->W) /= a_variable(pCellId, PV->RHO);
971 if constexpr(useSmagorinsky) {
973 std::array<MFloat, nDist> eqDist{};
974 std::array<MFloat, nDist> d{};
975 std::array<MFloat, nDim> u{};
976 for(
MInt dim = 0; dim < nDim; dim++) {
977 u[dim] = a_variable(pCellId, dim);
979 eqDist = getEqDists(a_variable(pCellId, PV->RHO), u.data());
981 for(
MInt j = 0; j < nDist; j++) {
982 d[j] = a_oldDistribution(pCellId, j) - eqDist[j];
986 std::array<MFloat, nDimSqr> Q{};
988 * (d[0] + d[1] + d[6] + d[7] + d[8] + d[9] + d[10] + d[11] + d[12] + d[13] + d[18] + d[19] + d[20]
989 + d[21] + d[22] + d[23] + d[24] + d[25])
990 - F1B3 * (d[2] + d[3] + d[4] + d[5] + d[14] + d[15] + d[16] + d[17] + d[26]);
991 Q[1] = (d[6] - d[7] - d[8] + d[9] + d[18] + d[19] - d[20] - d[21] - d[22] - d[23] + d[24] + d[25]);
992 Q[2] = (d[10] - d[11] - d[12] + d[13] + d[18] - d[19] + d[20] - d[21] - d[22] + d[23] - d[24] + d[25]);
995 * (d[2] + d[3] + d[6] + d[7] + d[8] + d[9] + d[14] + d[15] + d[16] + d[17] + d[18] + d[19] + d[20]
996 + d[21] + d[22] + d[23] + d[24] + d[25])
997 - F1B3 * (d[0] + d[1] + d[4] + d[5] + d[10] + d[11] + d[12] + d[13] + d[26]);
998 Q[5] = (d[14] - d[15] - d[16] + d[17] + d[18] - d[19] - d[20] + d[21] + d[22] - d[23] - d[24] + d[25]);
1002 * (d[4] + d[5] + d[10] + d[11] + d[12] + d[13] + d[14] + d[15] + d[16] + d[17] + d[18] + d[19]
1003 + d[20] + d[21] + d[22] + d[23] + d[24] + d[25])
1004 - F1B3 * (d[0] + d[1] + d[2] + d[3] + d[6] + d[7] + d[8] + d[9] + d[26]);
1006 const MFloat Q_mean = sqrt(2.0 * std::inner_product(&Q[0], &Q[nDimSqr], &Q[0], .0));
1009 const MFloat nu_t = C_s * C_s * Q_mean;
1011 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
1013 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId)));
1016 const MFloat R = a_oldDistribution(pCellId, 26);
1017 const MFloat Nw = a_oldDistribution(pCellId, 7);
1018 const MFloat W = a_oldDistribution(pCellId, 0);
1019 const MFloat Sw = a_oldDistribution(pCellId, 6);
1020 const MFloat S = a_oldDistribution(pCellId, 2);
1021 const MFloat Se = a_oldDistribution(pCellId, 8);
1022 const MFloat E = a_oldDistribution(pCellId, 1);
1023 const MFloat Ne = a_oldDistribution(pCellId, 9);
1024 const MFloat N = a_oldDistribution(pCellId, 3);
1025 const MFloat Nf = a_oldDistribution(pCellId, 17);
1026 const MFloat Nb = a_oldDistribution(pCellId, 16);
1027 const MFloat Sf = a_oldDistribution(pCellId, 15);
1028 const MFloat Sb = a_oldDistribution(pCellId, 14);
1029 const MFloat Ef = a_oldDistribution(pCellId, 13);
1030 const MFloat Eb = a_oldDistribution(pCellId, 12);
1031 const MFloat Wf = a_oldDistribution(pCellId, 11);
1032 const MFloat Wb = a_oldDistribution(pCellId, 10);
1033 const MFloat F = a_oldDistribution(pCellId, 5);
1034 const MFloat B = a_oldDistribution(pCellId, 4);
1035 const MFloat Nwf = a_oldDistribution(pCellId, 21);
1036 const MFloat Nwb = a_oldDistribution(pCellId, 20);
1037 const MFloat Nef = a_oldDistribution(pCellId, 25);
1038 const MFloat Neb = a_oldDistribution(pCellId, 24);
1039 const MFloat Swf = a_oldDistribution(pCellId, 19);
1040 const MFloat Swb = a_oldDistribution(pCellId, 18);
1041 const MFloat Sef = a_oldDistribution(pCellId, 23);
1042 const MFloat Seb = a_oldDistribution(pCellId, 22);
1044 const MFloat rho = Nw + W + Sw + S + Se + E + Ne + N + R + Nf + Nb + Sf + Sb + Ef + Eb + Wf + Wb + Nwf + Nwb + Nef
1045 + Neb + Swf + Swb + Sef + Seb + F + B;
1047 (Ne + E + Se + Ef + Eb - Nw - W - Sw - Wf - Wb + Nef + Neb + Sef + Seb - Nwf - Nwb - Swf - Swb);
1049 (Ne + N + Nw + Nf + Nb - Se - S - Sw - Sf - Sb + Nef + Neb + Nwf + Nwb - Sef - Seb - Swf - Swb);
1051 (Nf + Sf + Wf + Ef + F - Nb - Sb - Wb - Eb - B + Nef + Nwf + Sef + Swf - Neb - Nwb - Seb - Swb);
1052 const MFloat vv_x = pi_x / rho;
1053 const MFloat vv_y = pi_y / rho;
1054 const MFloat vv_z = pi_z / rho;
1055 const MFloat vx2 = vv_x * vv_x;
1056 const MFloat vy2 = vv_y * vv_y;
1057 const MFloat vz2 = vv_z * vv_z;
1058 const MFloat uxy = (m_omega
1059 * (Ne + Neb + Nef - Nw - Nwb - Nwf - Se - Seb - Sef + Sw + Swb + Swf + vv_x * vv_y * rho
1060 - pi_x * vv_y - pi_y * vv_x)
1062 const MFloat uxz = (m_omega
1063 * (-Eb + Ef - Neb + Nef + Nwb - Nwf - Seb + Sef + Swb - Swf + Wb - Wf + vv_x * vv_z * rho
1064 - pi_x * vv_z - pi_z * vv_x)
1066 const MFloat uyz = (m_omega
1067 * (-Nb - Neb + Nef + Nf - Nwb + Nwf + Sb + Seb - Sef - Sf + Swb - Swf + vv_z * vv_y * rho
1068 - pi_z * vv_y - pi_y * vv_z)
1071 const MFloat vxy = (m_omega * (1. / 6.)
1072 * (-B - E - F + Nb + Ne + Nf + Nw + Sb + Se + Sf + Sw - W + 2 * (-Eb - Ef + N + S - Wb - Wf)
1073 + 2 * (-2 * pi_y * vv_y + pi_x * vv_x + pi_z * vv_z) - rho * (vz2 - 2 * vy2 + vx2)));
1074 const MFloat vxz = (m_omega * (1. / 6.)
1075 * (-E + Eb + Ef - N + Nb + Nf - S + Sb + Sf - W + Wb + Wf + 2 * (B + F - Ne - Nw - Se - Sw)
1076 + 2 * (-2 * pi_z * vv_z + pi_x * vv_x + pi_y * vv_y) - rho * (vx2 + vy2 - 2 * vz2)));
1077 const MFloat pe = ((1. / 126.)
1078 * (-B - E - F - N - S - W + 2 * (-Eb - Ef - Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw - Wb - Wf)
1079 + 3 * (-Neb - Nef - Nwb - Nwf - Seb - Sef - Swb - Swf)
1080 + (rho + vv_y * (2 * pi_y - vv_y * rho) + vv_z * (2 * pi_z - vv_z * rho)
1081 + vv_x * (2 * pi_x - vv_x * rho))));
1083 const MFloat UXY = -Ne - Neb - Nef + Nw + Nwb + Nwf + Se + Seb + Sef - Sw - Swb - Swf + 4 * uxy;
1084 const MFloat UXZ = Eb - Ef + Neb - Nef - Nwb + Nwf + Seb - Sef - Swb + Swf - Wb + Wf + 4 * uxz;
1085 const MFloat UYZ = Nb + Neb - Nef - Nf + Nwb - Nwf - Sb - Seb + Sef + Sf - Swb + Swf + 4 * uyz;
1089 * (Nw + Sw + Wf + Wb - Eb - Ef - Ne - Se
1091 * (B + Eb + Ef + 84 * pe + F + N + Ne + Nw + S + Se + Sw + Wb + Wf
1092 + 2 * (Nb + Neb + Nef + Nf + Nwb + Nwf + Sb + Seb + Sef + Sf + Swb + Swf - vxy - vxz)))
1093 + 0.25 * (-Neb - Nef + Nwb + Nwf - Seb - Sef + Swb + Swf - vv_y * UXY - vv_z * UXZ)
1094 - 0.25 * vv_x * (vv_y * pi_y + vv_z * pi_z) + 0.125 * (vy2 + vz2) * (vv_x * rho - pi_x)));
1097 * (Sb + Sf + Se + Sw - Nw - Ne - Nf - Nb
1099 * (B + E + 84 * pe + F + Nb + Ne + Nf + Nw + Sb + Se + Sf + Sw + W
1100 + 2 * (Eb + Ef + Neb + Nef + Nwb + Nwf + Seb + Sef + Swb + Swf + Wb + Wf + vxy)))
1101 + 0.25 * (-Neb - Nef - Nwb - Nwf + Seb + Sef + Swb + Swf - vv_x * UXY - vv_z * UYZ)
1102 - 0.25 * vv_y * (vv_z * pi_z + vv_x * pi_x) + 0.125 * (vx2 + vz2) * (vv_y * rho - pi_y)));
1105 * (Eb + Nb + Sb + Wb - Ef - Nf - Sf - Wf
1107 * (E + Eb + Ef + N + Nb + Nf + S + Sb + Sf + W + Wb + Wf + 84 * pe
1108 + 2 * (Ne + Neb + Nef + Nw + Nwb + Nwf + Se + Seb + Sef + Sw + Swb + Swf + vxz)))
1109 + 0.25 * (-Nef + Neb + Nwb - Nwf + Seb - Sef + Swb - Swf - vv_x * UXZ - vv_y * UYZ)
1110 - 0.25 * vv_z * (vv_x * pi_x + vv_y * pi_y) + 0.125 * (vx2 + vy2) * (vv_z * rho - pi_z)));
1112 const MFloat xxx = ((0.125
1113 * (Eb + Ef - Ne + Nw - Se + Sw - Wb - Wf
1114 + vv_x * (-B - Eb - Ef - F + N + Ne + Nw + S + Se + Sw - Wb - Wf + 2 * (vxz - vxy)))
1115 + 0.25 * (vv_z * UXZ - vv_y * UXY + vv_x * (vv_z * pi_z - vv_y * pi_y))
1116 + 0.125 * ((pi_x - vv_x * rho) * (vz2 - vy2))));
1119 * (Ne - Nb - Nf + Nw + Sb - Se + Sf - Sw
1120 + vv_y * (-E + B + F + Nb - Ne + Nf - Nw + Sb - Se + Sf - Sw - W + 2 * (-vxy - 2 * vxz)))
1121 + 0.25 * (vv_x * UXY - vv_z * UYZ + vv_y * (vv_x * pi_x - vv_z * pi_z))
1122 + 0.125 * ((pi_y - vv_y * rho) * (vx2 - vz2))));
1125 * (Eb - Ef - Nb + Nf - Sb + Sf + Wb - Wf
1126 + vv_z * (E + Eb + Ef - N - Nb - Nf - S - Sb - Sf + W + Wb + Wf + 2 * (vxz + 2 * vxy)))
1127 + 0.25 * (vv_y * UYZ - vv_x * UXZ + vv_z * (vv_y * pi_y - vv_x * pi_x))
1128 + 0.125 * ((pi_z - vv_z * rho) * (vy2 - vx2))));
1132 * (Neb - Nef - Nwb + Nwf - Seb + Sef + Swb - Swf - vv_x * UYZ - vv_y * UXZ - vv_z * UXY
1133 + rho * vv_x * vv_y * vv_z - (vv_x * vv_y * pi_z + vv_x * pi_y * vv_z + pi_x * vv_y * vv_z)));
1136 (Eb + Ef + Ne - Nw + Se - Sw - Wb - Wf + 2 * (Neb + Nef - Nwb - Nwf + Seb + Sef - Swb - Swf) + 8 * x);
1138 (Nb + Ne + Nf + Nw - Sb - Se - Sf - Sw + 2 * (Neb + Nef + Nwb + Nwf - Seb - Sef - Swb - Swf) + 8 *
y);
1140 (Ef - Eb - Nb + Nf - Sb + Sf - Wb + Wf + 2 * (Nef - Neb - Nwb + Nwf - Seb + Sef - Swb + Swf) + 8 * z);
1142 const MFloat XnXXX = Eb + Ef + Neb + Nef - Nwb - Nwf + Seb + Sef - Swb - Swf - Wb - Wf + 4 * (x - xxx);
1143 const MFloat XpXXX = Ne + Neb + Nef - Nw - Nwb - Nwf + Se + Seb + Sef - Sw - Swb - Swf + 4 * (x + xxx);
1144 const MFloat YnYYY = Ne + Neb + Nef + Nw + Nwb + Nwf - Se - Seb - Sef - Sw - Swb - Swf + 4 * (
y - yyy);
1145 const MFloat YpYYY = Nb + Neb + Nef + Nf + Nwb + Nwf - Sb - Seb - Sef - Sf - Swb - Swf + 4 * (
y + yyy);
1146 const MFloat ZnZZZ = Nef - Nb - Neb + Nf - Nwb + Nwf - Sb - Seb + Sef + Sf - Swb + Swf + 4 * (z - zzz);
1147 const MFloat ZpZZZ = Nef - Eb + Ef - Neb - Nwb + Nwf - Seb + Sef - Swb + Swf - Wb + Wf + 4 * (z + zzz);
1149 const MFloat XYZ = -Neb + Nef + Nwb - Nwf + Seb - Sef - Swb + Swf + 8 * xyz;
1150 const MFloat EPa = -42 * pe - E - Eb - Ef - Ne - Neb - Nef - Nw - Nwb - Nwf - Se - Seb - Sef - Sw - Swb - Swf - W
1151 - Wb - Wf - 2 * (vxy + vxz);
1152 const MFloat EPb = -42 * pe - B - Eb - Ef - F - Nb - Neb - Nef - Nf - Nwb - Nwf - Sb - Seb - Sef - Sf - Swb - Swf
1153 - Wb - Wf + 2 * vxz;
1154 const MFloat EPc = -42 * pe - N - Nb - Ne - Neb - Nef - Nf - Nw - Nwb - Nwf - S - Sb - Se - Seb - Sef - Sf - Sw
1155 - Swb - Swf + 2 * vxy;
1159 * (rho / (3.) - 96 * pe - Eb - Ef - Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw - Wb - Wf
1160 - 3 * (Nwf + Nwb + Nef + Neb + Swf + Swb + Sef + Seb) + 2 * (+vv_x * X_ + vv_y * Y_ + vv_z * Z_)
1162 * (-84 * pe - B - Eb - Ef - F - N - Ne - Nw - S - Se - Sw - Wb - Wf
1163 + 2 * (vxy + vxz - Nb - Neb - Nef - Nf - Nwb - Nwf - Sb - Seb - Sef - Sf - Swb - Swf))
1165 * (-84 * pe - B - E - F - Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw - W
1166 + 2 * (-vxy - Eb - Ef - Neb - Nef - Nwb - Nwf - Seb - Sef - Swb - Swf - Wb - Wf))
1168 * (-84 * pe - E - Eb - Ef - N - Nb - Nf - S - Sb - Sf - W - Wb - Wf
1169 + 2 * (-vxz - Ne - Neb - Nef - Nw - Nwb - Nwf - Se - Seb - Sef - Sw - Swb - Swf))
1170 + 4 * (vv_x * vv_y * UXY + vv_x * vv_z * UXZ + vv_y * vv_z * UYZ)
1171 - rho * (vx2 * vy2 + vx2 * vz2 + vy2 * vz2)
1172 + 2 * (pi_y * vv_y * (vx2 + vz2) + pi_x * vv_x * (vy2 + vz2) + pi_z * vv_z * (vx2 + vy2))));
1175 * (-Eb - Ef - Ne - Nw - Se - Sw - Wb - Wf
1177 * (Nb + Nf + Sb + Sf + vv_x * X_
1179 * (Ne - Neb - Nef + Nw - Nwb - Nwf - Se + Seb + Sef - Sw + Swb + Swf
1180 + 2 * (Sf + Sb - Nb - Nf - 2 *
y - 6 * yyy))
1182 * (Ef - Eb + Neb - Nef + Nwb - Nwf + Seb - Sef + Swb - Swf - Wb + Wf
1183 + 2 * (Nb - Nf + Sb - Sf - 2 * z + 6 * zzz)))
1185 * (-B - Eb - Ef - F - N - Ne - Nw - S - Se - Sw - Wb - Wf - 84 * pe
1186 - 2 * (Nb + Neb + Nef + Nf + Nwb + Nwf + Sb + Seb + Sef + Sf + Swb + Swf - vxy - vxz))
1188 * (Eb - E + Ef - Ne + Neb + Nef - Nw + Nwb + Nwf - Se + Seb + Sef - Sw + Swb + Swf - W + Wb + Wf
1189 + 42 * pe + 2 * (B + F + Nb + Nf + Sb + Sf - vxy - 3 * vxz))
1191 * (Ne - E - Eb - Ef + Neb + Nef + Nw + Nwb + Nwf + Se + Seb + Sef + Sw + Swb + Swf - W - Wb - Wf
1192 + 42 * pe + 2 * (N + Nb + Nf + S + Sb + Sf - vxz - 3 * vxy))
1193 + 4 * (vv_x * (vv_y * UXY + vv_z * UXZ)) - 8 * vv_y * vv_z * UYZ
1194 + (2 * vy2 * vz2 - vx2 * (vy2 + vz2)) * rho
1195 + 2 * (pi_y * vv_y * (vx2 - 2 * vz2) + pi_z * vv_z * (vx2 - 2 * vy2) + pi_x * vv_x * (vy2 + vz2))));
1198 * (-Nb - Ne - Nf - Nw - Sb - Se - Sf - Sw
1200 * (Eb + Ef + Wb + Wf
1202 * (Ne - Neb - Nef - Nw + Nwb + Nwf + Se - Seb - Sef - Sw + Swb + Swf
1203 + 2 * (Wb + Wf - Eb - Ef - 2 * x + 6 * xxx))
1206 * (Nf - Nb + Neb - Nef + Nwb - Nwf - Sb + Seb - Sef + Sf + Swb - Swf
1207 + 2 * (Eb - Ef + Wb - Wf - 2 * z - 6 * zzz)))
1209 * (Nb - N - Ne + Neb + Nef + Nf - Nw + Nwb + Nwf - S + Sb - Se + Seb + Sef + Sf - Sw + Swb + Swf
1210 + 42 * pe + 2 * (B + Eb + Ef + F + Wb + Wf + vxy - 2 * vxz))
1212 * (B + E + F + Nb + Ne + Nf + Nw + Sb + Se + Sf + Sw + W + 84 * pe
1213 + 2 * (Eb + Ef + Neb + Nef + Nwb + Nwf + Seb + Sef + Swb + Swf + Wb + Wf + vxy))
1215 * (Ne - N - Nb + Neb + Nef - Nf + Nw + Nwb + Nwf - S - Sb + Se + Seb + Sef - Sf + Sw + Swb + Swf
1216 + 42 * pe + 2 * (E + Eb + Ef + W + Wb + Wf + 3 * vxy + 2 * vxz))
1217 + 4 * vv_y * (vv_x * UXY + vv_z * UYZ) - 8 * vv_x * vv_z * UXZ + (2 * vx2 * vz2 - (vx2 + vz2) * vy2) * rho
1218 + 2 * (pi_x * vv_x * (vy2 - 2 * vz2) + pi_z * vv_z * (vy2 - 2 * vx2) + pi_y * vv_y * (vx2 + vz2))));
1219 const MFloat uxxyz = ((1. / 8.)
1220 * (Neb - Nef + Nwb - Nwf - Seb + Sef - Swb + Swf + vv_y * ZpZZZ + vv_z * YnYYY
1221 + 2 * vv_x * (XYZ + vv_y * UXZ + vv_z * UXY) + vx2 * UYZ + vv_y * vv_z * EPa
1222 + (2 * pi_x - rho * vv_x) * vv_x * vv_y * vv_z + vx2 * (pi_y * vv_z + pi_z * vv_y)));
1223 const MFloat uxyyz = ((1. / 8.)
1224 * (Neb - Nef - Nwb + Nwf + Seb - Sef - Swb + Swf + vv_x * ZnZZZ + vv_z * XpXXX
1225 + 2 * vv_y * (XYZ + vv_x * UYZ + vv_z * UXY) + vy2 * UXZ
1228 + (2 * pi_y - vv_y * rho) * vv_y * vv_x * vv_z + vy2 * (pi_x * vv_z + pi_z * vv_x)));
1229 const MFloat uxyzz = ((1. / 8.)
1230 * (Nwb - Neb - Nef + Nwf + Seb + Sef - Swb - Swf + vv_x * YpYYY + vv_y * XnXXX
1231 + 2 * vv_z * (XYZ + vv_y * UXZ + vv_x * UYZ) + vz2 * UXY + vv_x * vv_y * EPb
1232 + (2 * pi_z - vv_z * rho) * vv_x * vv_y * vv_z + vz2 * (pi_y * vv_x + pi_x * vv_y)));
1234 const MFloat A = 4 *
a - 32 * pe - Nb - Neb - Nef - Nf - Nwb - Nwf - 4 * p - Sb - Seb - Sef - Sf - Swb - Swf;
1235 const MFloat C = 4 * (c - p) - Eb - Ef - 32 * pe - Neb - Nef - Nwb - Nwf - Seb - Sef - Swb - Swf - Wb - Wf;
1236 const MFloat CA = -4 * (
a + c + p) - 32 * pe - Ne - Neb - Nef - Nw - Nwb - Nwf - Se - Seb - Sef - Sw - Swb - Swf;
1237 const MFloat UXYZZ = Nwb - Neb - Nef + Nwf + Seb + Sef - Swb - Swf - 8 * uxyzz;
1238 const MFloat UXYYZ = Neb - Nef - Nwb + Nwf + Seb - Sef - Swb + Swf - 8 * uxyyz;
1239 const MFloat UXXYZ = Neb - Nef + Nwb - Nwf - Seb + Sef - Swb + Swf - 8 * uxxyz;
1243 * (Nwb - Neb - Nef + Nwf - Seb - Sef + Swb + Swf - vv_x * A - 2 * (vv_y * UXYZZ + vv_z * UXYYZ) - vy2 * XnXXX
1244 - vz2 * XpXXX + 2 * vv_x * (-vv_y * YpYYY - vv_z * ZnZZZ) - 4 * vv_y * vv_z * (XYZ + vv_x * UYZ)
1245 - vv_x * (vz2 * EPc + vy2 * EPb)
1246 - 2 * (vy2 * vv_z * UXZ + vv_y * vz2 * UXY)
1248 - 2 * vv_x * vv_y * vv_z * (pi_y * vv_z + pi_z * vv_y) + vy2 * vz2 * (vv_x * rho - pi_x)));
1251 * (Seb - Neb - Nef - Nwb - Nwf + Sef + Swb + Swf - vv_y * C - 2 * (vv_x * UXYZZ + vv_z * UXXYZ) - vx2 * YpYYY
1252 - vz2 * YnYYY + 2 * vv_y * (-vv_x * XnXXX - vv_z * ZpZZZ) - 4 * vv_x * vv_z * (XYZ + vv_y * UXZ)
1253 - vv_y * (vx2 * EPb + vz2 * EPa)
1254 - 2 * (vx2 * vv_z * UYZ + vv_x * vz2 * UXY)
1256 - 2 * vv_x * vv_y * vv_z * (pi_x * vv_z + pi_z * vv_x) + vx2 * vz2 * (vv_y * rho - pi_y)));
1259 * (Neb - Nef + Nwb - Nwf + Seb - Sef + Swb - Swf - vv_z * CA - 2 * (vv_x * UXYYZ + vv_y * UXXYZ)
1260 - vx2 * ZnZZZ - vy2 * ZpZZZ + 2 * vv_z * (-vv_x * XpXXX - vv_y * YnYYY)
1261 - 4 * vv_x * vv_y * (XYZ + vv_z * UXY) - vv_z * (vx2 * EPc + vy2 * EPa)
1262 - 2 * (vx2 * vv_y * UYZ + vv_x * vy2 * UXZ)
1264 - 2 * vv_x * vv_y * vv_z * (pi_x * vv_y + pi_y * vv_x) + vx2 * vy2 * (vv_z * rho - pi_z)));
1268 * (rho / 27. - Neb - Nef - Nwb - Nwf - Seb - Sef - Swb - Swf
1270 * (+vv_x * (Neb + Nef - Nwb - Nwf + Seb + Sef - Swb - Swf + 8 * xyyzz)
1271 + vv_y * (Neb + Nef + Nwb + Nwf - Seb - Sef - Swb - Swf + 8 * xxyzz)
1272 + vv_z * (-Neb + Nef - Nwb + Nwf - Seb + Sef - Swb + Swf + 8 * xxyyz))
1273 + vx2 * A + vy2 * C + vz2 * CA + 4 * (vv_x * vv_y * UXYZZ + vv_x * vv_z * UXYYZ + vv_y * vv_z * UXXYZ)
1275 * (vx2 * vv_y * YpYYY + vx2 * vv_z * ZnZZZ + vy2 * vv_z * ZpZZZ + vv_x * vy2 * XnXXX
1276 + vv_x * vz2 * XpXXX + vz2 * vv_y * YnYYY)
1277 + 8 * vv_x * vv_y * vv_z * XYZ + vx2 * vz2 * EPc + vx2 * vy2 * EPb + vy2 * vz2 * EPa
1278 + 4 * vv_x * vv_y * vv_z * (vv_z * UXY + vv_y * UXZ + vv_x * UYZ)
1279 + 2 * (vx2 * vy2 * vv_z * pi_z + vx2 * vv_y * pi_y * vz2 + vv_x * pi_x * vy2 * vz2)
1280 - rho * vx2 * vy2 * vz2));
1282 a_distribution(pCellId, 26) = R + (12 * p - 30 * pe - 8 * xxyyzz);
1283 a_distribution(pCellId, 7) =
1284 Nw + c +
a - xxx - yyy - x +
y + uxy + p + 8 * pe + 2 * (-xxyyzz - xxyzz + xyyzz + uxyzz);
1285 a_distribution(pCellId, 0) = W - 2 *
a + 4 * x - 11 * pe + vxy + vxz - 4 * p + 4 * (-xyyzz + xxyyzz);
1286 a_distribution(pCellId, 6) =
1287 Sw +
a + c - xxx + yyy - x -
y - uxy + p + 8 * pe + 2 * (-xxyyzz + xxyzz + xyyzz - uxyzz);
1288 a_distribution(pCellId, 2) = S - 2 * c + 4 *
y - 11 * pe - vxy - 4 * p + 4 * (-xxyzz + xxyyzz);
1289 a_distribution(pCellId, 8) =
1290 Se +
a + c + xxx + yyy + x -
y + uxy + p + 8 * pe + 2 * (-xxyyzz + xxyzz - xyyzz + uxyzz);
1291 a_distribution(pCellId, 1) = E - 2 *
a - 4 * x - 11 * pe + vxy + vxz - 4 * p + 4 * (xyyzz + xxyyzz);
1292 a_distribution(pCellId, 9) =
1293 Ne + c +
a + x +
y + xxx - yyy - uxy + p + 8 * pe + 2 * (-xxyyzz - xxyzz - xyyzz - uxyzz);
1294 a_distribution(pCellId, 3) = N - 2 * c - 4 *
y - 11 * pe - vxy - 4 * p + 4 * (xxyzz + xxyyzz);
1295 a_distribution(pCellId, 17) =
1296 Nf -
a + yyy - zzz +
y + z - uyz + p + 8 * pe + 2 * (-xxyyzz - xxyzz - xxyyz - uxxyz);
1297 a_distribution(pCellId, 16) =
1298 Nb -
a + yyy + zzz +
y - z + uyz + p + 8 * pe + 2 * (-xxyyzz - xxyzz + xxyyz + uxxyz);
1299 a_distribution(pCellId, 15) =
1300 Sf -
a - yyy - zzz -
y + z + uyz + p + 8 * pe + 2 * (-xxyyzz + xxyzz - xxyyz + uxxyz);
1301 a_distribution(pCellId, 14) =
1302 Sb -
a - yyy + zzz -
y - z - uyz + p + 8 * pe + 2 * (-xxyyzz + xxyzz + xxyyz - uxxyz);
1303 a_distribution(pCellId, 13) =
1304 Ef - c - xxx + zzz + x + z - uxz + p + 8 * pe + 2 * (-xxyyzz - xyyzz - xxyyz - uxyyz);
1305 a_distribution(pCellId, 12) =
1306 Eb - c - xxx - zzz + x - z + uxz + p + 8 * pe + 2 * (-xxyyzz - xyyzz + xxyyz + uxyyz);
1307 a_distribution(pCellId, 11) =
1308 Wf - c + xxx + zzz - x + z + uxz + p + 8 * pe + 2 * (-xxyyzz + xyyzz - xxyyz + uxyyz);
1309 a_distribution(pCellId, 10) =
1310 Wb - c + xxx - zzz - x - z - uxz + p + 8 * pe + 2 * (-xxyyzz + xyyzz + xxyyz - uxyyz);
1311 a_distribution(pCellId, 5) = F + 2 *
a + 2 * c - 4 * z - 11 * pe - vxz - 4 * p + 4 * (xxyyzz + xxyyz);
1312 a_distribution(pCellId, 4) = B + 2 *
a + 2 * c + 4 * z - 11 * pe - vxz - 4 * p + 4 * (-xxyyz + xxyyzz);
1313 a_distribution(pCellId, 21) = Nwf - xyz + uxxyz - uxyyz - uxyzz - (-xxyyz + xyyzz - xxyzz) + xxyyzz;
1314 a_distribution(pCellId, 20) = Nwb + xyz - uxxyz + uxyyz - uxyzz - (xxyyz + xyyzz - xxyzz) + xxyyzz;
1315 a_distribution(pCellId, 25) = Nef + xyz + uxxyz + uxyyz + uxyzz - (-xxyyz - xyyzz - xxyzz) + xxyyzz;
1316 a_distribution(pCellId, 24) = Neb - xyz - uxxyz - uxyyz + uxyzz - (xxyyz - xyyzz - xxyzz) + xxyyzz;
1317 a_distribution(pCellId, 19) = Swf + xyz - uxxyz - uxyyz + uxyzz - (-xxyyz + xyyzz + xxyzz) + xxyyzz;
1318 a_distribution(pCellId, 18) = Swb - xyz + uxxyz + uxyyz + uxyzz - (xxyyz + xyyzz + xxyzz) + xxyyzz;
1319 a_distribution(pCellId, 23) = Sef - xyz - uxxyz + uxyyz - uxyzz - (-xxyyz - xyyzz + xxyzz) + xxyyzz;
1320 a_distribution(pCellId, 22) = Seb + xyz + uxxyz - uxyyz - uxyzz - (xxyyz - xyyzz + xxyzz) + xxyyzz;
1323 if(m_calculateDissipation &&
globalTimeStep % m_solutionInterval == 0) {
1324 calculateDissipation();
1337template <MInt nDim, MInt nDist,
class SysEqn>
1339 clb_collision_step_base<false>();
1351template <MInt nDim, MInt nDist,
class SysEqn>
1353 clb_collision_step_base<true>();
1365template <MInt nDim, MInt nDist,
class SysEqn>
1367 TERMM(1,
"Cumulant collision step only available for D3Q27, yet!");
1374 constexpr MInt nDist = 27;
1376 constexpr MFloat omega2 = F1;
1377 constexpr MFloat omega3 = F1;
1378 constexpr MFloat omega4 = F1;
1379 constexpr MFloat omega5 = F1;
1380 constexpr MFloat omega6 = F1;
1381 constexpr MFloat omega7 = F1;
1382 constexpr MFloat omega8 = F1;
1383 constexpr MFloat omega9 = F1;
1384 constexpr MFloat omega10 = F1;
1388 const MInt maxLevel_ = maxLevel();
1390 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt index) {
1391 const MInt pCellId = m_activeCellList[index];
1392 const MInt lvlDiff = maxLevel_ - a_level(pCellId);
1393 if((gTS - 1) %
IPOW2(lvlDiff) != 0)
return;
1395 const MFloat l_u = a_variable(pCellId, PV->U);
1396 const MFloat l_v = a_variable(pCellId, PV->V);
1397 const MFloat l_w = a_variable(pCellId, PV->W);
1398 const MFloat l_rho = a_variable(pCellId, PV->RHO);
1402 const MFloat tau = F1B2 + F1BCSsq * a_nu(pCellId) *
FFPOW2(lvlDiff);
1403 const MFloat omega1 = 1.0 / tau;
1407 const MFloat F1Brho = F1 / l_rho;
1408 const MFloat u[3] = {l_u, l_v, l_w};
1409 const MFloat uSq[3] = {u[0] * u[0], u[1] * u[1], u[2] * u[2]};
1411 MFloat centralMoments[3][3][3] = {{{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}},
1412 {{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}},
1413 {{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}}};
1417#ifdef WAR_NVHPC_PSTL
1418 const MFloat xDir = (m_idFld[
dist][0] - F1) - u[0];
1419 const MFloat yDir = (m_idFld[
dist][1] - F1) - u[1];
1420 const MFloat zDir = (m_idFld[
dist][2] - F1) - u[2];
1422 const MFloat xDir = (Ld::idFld(
dist, 0) - F1) - u[0];
1423 const MFloat yDir = (Ld::idFld(
dist, 1) - F1) - u[1];
1424 const MFloat zDir = (Ld::idFld(
dist, 2) - F1) - u[2];
1426 const MFloat oldDist = a_oldDistribution(pCellId,
dist);
1427 const MFloat pow012[3][3] = {{F1, xDir, xDir * xDir}, {F1, yDir, yDir * yDir}, {F1, zDir, zDir * zDir}};
1429 for(
MInt i = 0; i < 3; i++) {
1430 for(
MInt j = 0; j < 3; j++) {
1431 const MFloat tmp = pow012[0][i] * pow012[1][j] * oldDist;
1432 centralMoments[i][j][0] += pow012[2][0] * tmp;
1433 centralMoments[i][j][1] += pow012[2][1] * tmp;
1434 centralMoments[i][j][2] += pow012[2][2] * tmp;
1441 MFloat cumulants[3][3][3];
1443 cumulants[0][0][0] = centralMoments[0][0][0];
1444 cumulants[1][0][0] = centralMoments[1][0][0];
1445 cumulants[0][1][0] = centralMoments[0][1][0];
1446 cumulants[0][0][1] = centralMoments[0][0][1];
1447 cumulants[2][0][0] = centralMoments[2][0][0];
1448 cumulants[0][2][0] = centralMoments[0][2][0];
1449 cumulants[0][0][2] = centralMoments[0][0][2];
1450 cumulants[1][1][0] = centralMoments[1][1][0];
1451 cumulants[1][0][1] = centralMoments[1][0][1];
1452 cumulants[0][1][1] = centralMoments[0][1][1];
1453 cumulants[1][2][0] = centralMoments[1][2][0];
1454 cumulants[1][0][2] = centralMoments[1][0][2];
1455 cumulants[0][1][2] = centralMoments[0][1][2];
1456 cumulants[2][0][1] = centralMoments[2][0][1];
1457 cumulants[2][1][0] = centralMoments[2][1][0];
1458 cumulants[0][2][1] = centralMoments[0][2][1];
1459 cumulants[1][1][1] = centralMoments[1][1][1];
1461 cumulants[2][1][1] =
1462 (centralMoments[2][1][1]
1463 - (centralMoments[2][0][0] * centralMoments[0][1][1] + F2 * centralMoments[1][1][0] * centralMoments[1][0][1])
1465 cumulants[1][2][1] =
1466 (centralMoments[1][2][1]
1467 - (centralMoments[0][2][0] * centralMoments[1][0][1] + F2 * centralMoments[1][1][0] * centralMoments[0][1][1])
1469 cumulants[1][1][2] =
1470 (centralMoments[1][1][2]
1471 - (centralMoments[0][0][2] * centralMoments[1][1][0] + F2 * centralMoments[0][1][1] * centralMoments[1][0][1])
1474 cumulants[2][2][0] =
1475 (centralMoments[2][2][0]
1476 - (centralMoments[2][0][0] * centralMoments[0][2][0] + F2 * centralMoments[1][1][0] * centralMoments[1][1][0])
1478 cumulants[2][0][2] =
1479 (centralMoments[2][0][2]
1480 - (centralMoments[2][0][0] * centralMoments[0][0][2] + F2 * centralMoments[1][0][1] * centralMoments[1][0][1])
1482 cumulants[0][2][2] =
1483 (centralMoments[0][2][2]
1484 - (centralMoments[0][0][2] * centralMoments[0][2][0] + F2 * centralMoments[0][1][1] * centralMoments[0][1][1])
1487 cumulants[1][2][2] =
1488 (centralMoments[1][2][2]
1489 - (centralMoments[0][0][2] * centralMoments[1][2][0] + centralMoments[0][2][0] * centralMoments[1][0][2]
1490 + F4 * centralMoments[0][1][1] * centralMoments[1][1][1]
1492 * (centralMoments[1][0][1] * centralMoments[0][2][1]
1493 + centralMoments[1][1][0] * centralMoments[0][1][2]))
1495 cumulants[2][1][2] =
1496 (centralMoments[2][1][2]
1497 - (centralMoments[2][0][0] * centralMoments[0][1][2] + centralMoments[0][0][2] * centralMoments[2][1][0]
1498 + F4 * centralMoments[1][0][1] * centralMoments[1][1][1]
1500 * (centralMoments[1][1][0] * centralMoments[1][0][2]
1501 + centralMoments[0][1][1] * centralMoments[2][0][1]))
1503 cumulants[2][2][1] =
1504 (centralMoments[2][2][1]
1505 - (centralMoments[2][0][0] * centralMoments[0][2][1] + centralMoments[0][2][0] * centralMoments[2][0][1]
1506 + F4 * centralMoments[1][1][0] * centralMoments[1][1][1]
1508 * (centralMoments[1][0][1] * centralMoments[1][2][0]
1509 + centralMoments[0][1][1] * centralMoments[2][1][0]))
1513 F4 * centralMoments[1][1][1] * centralMoments[1][1][1] + centralMoments[2][0][0] * centralMoments[0][2][2]
1514 + centralMoments[0][2][0] * centralMoments[2][0][2] + centralMoments[0][0][2] * centralMoments[2][2][0];
1516 const MFloat B1 = centralMoments[0][1][1] * centralMoments[2][1][1]
1517 + centralMoments[1][0][1] * centralMoments[1][2][1]
1518 + centralMoments[1][1][0] * centralMoments[1][1][2];
1520 const MFloat B2 = centralMoments[1][2][0] * centralMoments[1][0][2]
1521 + centralMoments[2][1][0] * centralMoments[0][1][2]
1522 + centralMoments[2][0][1] * centralMoments[0][2][1];
1524 const MFloat B3 = centralMoments[1][1][0] * centralMoments[1][0][1] * centralMoments[0][1][1];
1526 const MFloat B4 = centralMoments[1][0][1] * centralMoments[1][0][1] * centralMoments[0][2][0]
1527 + centralMoments[1][1][0] * centralMoments[1][1][0] * centralMoments[0][0][2]
1528 + centralMoments[0][1][1] * centralMoments[0][1][1] * centralMoments[2][0][0];
1530 const MFloat B5 = centralMoments[2][0][0] * centralMoments[0][2][0] * centralMoments[0][0][2];
1532 cumulants[2][2][2] = (centralMoments[2][2][2] - (F1 * B0 + F4 * B1 + F2 * B2) * F1Brho
1533 + (16.0 * B3 + F4 * B4 + F2 * B5) * F1Brho * F1Brho);
1537 const MFloat sum = cumulants[2][0][0] + cumulants[0][2][0] + cumulants[0][0][2];
1538 const MFloat diff1 = cumulants[2][0][0] - cumulants[0][2][0];
1539 const MFloat diff2 = cumulants[2][0][0] - cumulants[0][0][2];
1541 -omega1 * F1Brho * F1B2 * (diff1 + diff2) - omega2 * F1Brho * F1B2 * (sum - centralMoments[0][0][0]);
1542 const MFloat Dyv = Dxu + F3B2 * omega1 * F1Brho * diff1;
1543 const MFloat Dzw = Dxu + F3B2 * omega1 * F1Brho * diff2;
1544 const MFloat A1 = (F1 - omega1) * diff1 - F3 * l_rho * (F1 - F1B2 * omega1) * (uSq[0] * Dxu - uSq[1] * Dyv);
1545 const MFloat A2 = (F1 - omega1) * diff2 - F3 * l_rho * (F1 - F1B2 * omega1) * (uSq[0] * Dxu - uSq[2] * Dzw);
1546 const MFloat A3 = (F1 - omega2) * sum
1547 - F3 * l_rho * (F1 - F1B2 * omega2) * (uSq[0] * Dxu + uSq[1] * Dyv + uSq[2] * Dzw)
1548 + omega2 * centralMoments[0][0][0];
1550 const MFloat A4 = (F1 - omega3) * (cumulants[1][2][0] + cumulants[1][0][2]);
1551 const MFloat A5 = (F1 - omega3) * (cumulants[2][1][0] + cumulants[0][1][2]);
1552 const MFloat A6 = (F1 - omega3) * (cumulants[2][0][1] + cumulants[0][2][1]);
1553 const MFloat A7 = (F1 - omega4) * (cumulants[1][2][0] - cumulants[1][0][2]);
1554 const MFloat A8 = (F1 - omega4) * (cumulants[2][1][0] - cumulants[0][1][2]);
1555 const MFloat A9 = (F1 - omega4) * (cumulants[2][0][1] - cumulants[0][2][1]);
1557 const MFloat A10 = (F1 - omega6) * (cumulants[2][2][0] - F2 * cumulants[2][0][2] + cumulants[0][2][2]);
1558 const MFloat A11 = (F1 - omega6) * (cumulants[2][2][0] + cumulants[2][0][2] - F2 * cumulants[0][2][2]);
1559 const MFloat A12 = (F1 - omega7) * (cumulants[2][2][0] + cumulants[2][0][2] + cumulants[0][2][2]);
1561 cumulants[1][1][0] *= (F1 - omega1);
1562 cumulants[0][1][1] *= (F1 - omega1);
1563 cumulants[1][0][1] *= (F1 - omega1);
1564 cumulants[2][0][0] = (A1 + A2 + A3) * F1B3;
1565 cumulants[0][0][2] = (A1 - F2 * A2 + A3) * F1B3;
1566 cumulants[0][2][0] = (-F2 * A1 + A2 + A3) * F1B3;
1567 cumulants[1][2][0] = (A4 + A5) * F1B2;
1568 cumulants[1][0][2] = (A4 - A5) * F1B2;
1569 cumulants[2][1][0] = (A6 + A7) * F1B2;
1570 cumulants[0][1][2] = (A6 - A7) * F1B2;
1571 cumulants[2][0][1] = (A8 + A9) * F1B2;
1572 cumulants[0][2][1] = (A8 - A9) * F1B2;
1573 cumulants[1][1][1] *= (F1 - omega5);
1574 cumulants[2][2][0] = F1B3 * (A10 + A11 + A12);
1575 cumulants[2][0][2] = F1B3 * (A12 - A10);
1576 cumulants[0][2][2] = F1B3 * (A12 - A11);
1577 cumulants[2][1][1] *= (F1 - omega8);
1578 cumulants[1][2][1] *= (F1 - omega8);
1579 cumulants[1][1][2] *= (F1 - omega8);
1580 cumulants[2][2][1] *= (F1 - omega9);
1581 cumulants[2][1][2] *= (F1 - omega9);
1582 cumulants[1][2][2] *= (F1 - omega9);
1583 cumulants[2][2][2] *= (F1 - omega10);
1587 centralMoments[0][0][0] = cumulants[0][0][0];
1588 centralMoments[1][0][0] = -cumulants[1][0][0];
1589 centralMoments[0][1][0] = -cumulants[0][1][0];
1590 centralMoments[0][0][1] = -cumulants[0][0][1];
1591 centralMoments[1][1][0] = cumulants[1][1][0];
1592 centralMoments[1][0][1] = cumulants[1][0][1];
1593 centralMoments[0][1][1] = cumulants[0][1][1];
1594 centralMoments[2][0][0] = cumulants[2][0][0];
1595 centralMoments[0][2][0] = cumulants[0][2][0];
1596 centralMoments[0][0][2] = cumulants[0][0][2];
1597 centralMoments[2][1][0] = cumulants[2][1][0];
1598 centralMoments[2][0][1] = cumulants[2][0][1];
1599 centralMoments[0][2][1] = cumulants[0][2][1];
1600 centralMoments[1][2][0] = cumulants[1][2][0];
1601 centralMoments[1][0][2] = cumulants[1][0][2];
1602 centralMoments[0][1][2] = cumulants[0][1][2];
1603 centralMoments[1][1][1] = cumulants[1][1][1];
1605 centralMoments[2][1][1] =
1607 + (centralMoments[2][0][0] * centralMoments[0][1][1] + F2 * centralMoments[1][1][0] * centralMoments[1][0][1])
1609 centralMoments[1][2][1] =
1611 + (centralMoments[0][2][0] * centralMoments[1][0][1] + F2 * centralMoments[1][1][0] * centralMoments[0][1][1])
1613 centralMoments[1][1][2] =
1615 + (centralMoments[0][0][2] * centralMoments[1][1][0] + F2 * centralMoments[0][1][1] * centralMoments[1][0][1])
1618 centralMoments[2][2][0] =
1620 + (centralMoments[2][0][0] * centralMoments[0][2][0] + F2 * centralMoments[1][1][0] * centralMoments[1][1][0])
1622 centralMoments[2][0][2] =
1624 + (centralMoments[2][0][0] * centralMoments[0][0][2] + F2 * centralMoments[1][0][1] * centralMoments[1][0][1])
1626 centralMoments[0][2][2] =
1628 + (centralMoments[0][0][2] * centralMoments[0][2][0] + F2 * centralMoments[0][1][1] * centralMoments[0][1][1])
1631 centralMoments[1][2][2] =
1633 + (centralMoments[0][0][2] * centralMoments[1][2][0] + centralMoments[0][2][0] * centralMoments[1][0][2]
1634 + F4 * centralMoments[0][1][1] * centralMoments[1][1][1]
1636 * (centralMoments[1][0][1] * centralMoments[0][2][1]
1637 + centralMoments[1][1][0] * centralMoments[0][1][2]))
1639 centralMoments[2][1][2] =
1641 + (centralMoments[2][0][0] * centralMoments[0][1][2] + centralMoments[0][0][2] * centralMoments[2][1][0]
1642 + F4 * centralMoments[1][0][1] * centralMoments[1][1][1]
1644 * (centralMoments[1][1][0] * centralMoments[1][0][2]
1645 + centralMoments[0][1][1] * centralMoments[2][0][1]))
1647 centralMoments[2][2][1] =
1649 + (centralMoments[2][0][0] * centralMoments[0][2][1] + centralMoments[0][2][0] * centralMoments[2][0][1]
1650 + F4 * centralMoments[1][1][0] * centralMoments[1][1][1]
1652 * (centralMoments[1][0][1] * centralMoments[1][2][0]
1653 + centralMoments[0][1][1] * centralMoments[2][1][0]))
1657 F4 * centralMoments[1][1][1] * centralMoments[1][1][1] + centralMoments[2][0][0] * centralMoments[0][2][2]
1658 + centralMoments[0][2][0] * centralMoments[2][0][2] + centralMoments[0][0][2] * centralMoments[2][2][0];
1660 const MFloat D1 = centralMoments[0][1][1] * centralMoments[2][1][1]
1661 + centralMoments[1][0][1] * centralMoments[1][2][1]
1662 + centralMoments[1][1][0] * centralMoments[1][1][2];
1664 const MFloat D2 = centralMoments[1][2][0] * centralMoments[1][0][2]
1665 + centralMoments[2][1][0] * centralMoments[0][1][2]
1666 + centralMoments[2][0][1] * centralMoments[0][2][1];
1668 const MFloat D3 = centralMoments[1][1][0] * centralMoments[1][0][1] * centralMoments[0][1][1];
1670 const MFloat D4 = centralMoments[1][0][1] * centralMoments[1][0][1] * centralMoments[0][2][0]
1671 + centralMoments[1][1][0] * centralMoments[1][1][0] * centralMoments[0][0][2]
1672 + centralMoments[0][1][1] * centralMoments[0][1][1] * centralMoments[2][0][0];
1674 const MFloat D5 = centralMoments[2][0][0] * centralMoments[0][2][0] * centralMoments[0][0][2];
1676 centralMoments[2][2][2] = (cumulants[2][2][2] + (F1 * D0 + F4 * D1 + F2 * D2) * F1Brho
1677 - (16.0 * D3 + F4 * D4 + F2 * D5) * F1Brho * F1Brho);
1679 const MFloat coeff0[3][3] = {{(uSq[0] - u[0]) * F1B2, u[0] - F1B2, F1B2},
1680 {F1 - uSq[0], -F2 * u[0], -F1},
1681 {(uSq[0] + u[0]) * F1B2, u[0] + F1B2, F1B2}};
1682 const MFloat coeff1[3][3] = {{(uSq[1] - u[1]) * F1B2, u[1] - F1B2, F1B2},
1683 {F1 - uSq[1], -F2 * u[1], -F1},
1684 {(uSq[1] + u[1]) * F1B2, u[1] + F1B2, F1B2}};
1685 const MFloat coeff2[3][3] = {{(uSq[2] - u[2]) * F1B2, u[2] - F1B2, F1B2},
1686 {F1 - uSq[2], -F2 * u[2], -F1},
1687 {(uSq[2] + u[2]) * F1B2, u[2] + F1B2, F1B2}};
1691#ifdef WAR_NVHPC_PSTL
1700 const MFloat ki_00 = coeff0[i][0] * centralMoments[0][0][0] + coeff0[i][1] * centralMoments[1][0][0]
1701 + coeff0[i][2] * centralMoments[2][0][0];
1702 const MFloat ki_01 = coeff0[i][0] * centralMoments[0][0][1] + coeff0[i][1] * centralMoments[1][0][1]
1703 + coeff0[i][2] * centralMoments[2][0][1];
1704 const MFloat ki_02 = coeff0[i][0] * centralMoments[0][0][2] + coeff0[i][1] * centralMoments[1][0][2]
1705 + coeff0[i][2] * centralMoments[2][0][2];
1706 const MFloat ki_10 = coeff0[i][0] * centralMoments[0][1][0] + coeff0[i][1] * centralMoments[1][1][0]
1707 + coeff0[i][2] * centralMoments[2][1][0];
1708 const MFloat ki_11 = coeff0[i][0] * centralMoments[0][1][1] + coeff0[i][1] * centralMoments[1][1][1]
1709 + coeff0[i][2] * centralMoments[2][1][1];
1710 const MFloat ki_12 = coeff0[i][0] * centralMoments[0][1][2] + coeff0[i][1] * centralMoments[1][1][2]
1711 + coeff0[i][2] * centralMoments[2][1][2];
1712 const MFloat ki_20 = coeff0[i][0] * centralMoments[0][2][0] + coeff0[i][1] * centralMoments[1][2][0]
1713 + coeff0[i][2] * centralMoments[2][2][0];
1714 const MFloat ki_21 = coeff0[i][0] * centralMoments[0][2][1] + coeff0[i][1] * centralMoments[1][2][1]
1715 + coeff0[i][2] * centralMoments[2][2][1];
1716 const MFloat ki_22 = coeff0[i][0] * centralMoments[0][2][2] + coeff0[i][1] * centralMoments[1][2][2]
1717 + coeff0[i][2] * centralMoments[2][2][2];
1719 const MFloat kij_0 = coeff1[j][0] * ki_00 + coeff1[j][1] * ki_10 + coeff1[j][2] * ki_20;
1720 const MFloat kij_1 = coeff1[j][0] * ki_01 + coeff1[j][1] * ki_11 + coeff1[j][2] * ki_21;
1721 const MFloat kij_2 = coeff1[j][0] * ki_02 + coeff1[j][1] * ki_12 + coeff1[j][2] * ki_22;
1723 a_distribution(pCellId,
dist) = coeff2[k][0] * kij_0 + coeff2[k][1] * kij_1 + coeff2[k][2] * kij_2;
1736template <MInt nDim, MInt nDist,
class SysEqn>
1741 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt i) {
1742 const MInt pCellId = m_activeCellList[i];
1743 const MInt lvlDiff = maxLevel() - this->a_level(pCellId);
1744 if((globalTimeStep_ - 1) %
IPOW2(lvlDiff) != 0)
return;
1746 const MFloat rho = a_variable(pCellId, PV->RHO);
1747 std::array<MFloat, nDim> uu;
1748 for(
MInt j = 0; j < nDim; j++) {
1749 uu[j] = a_variable(pCellId, PV->U + j);
1752 const MFloat omega = 1.0 / (0.5 + F1BCSsq * a_nu(pCellId) *
FFPOW2(lvlDiff));
1753 std::array<MFloat, nDist> eqDist;
1754 eqDist = getEqDists(rho, uu.data());
1755 for(
MInt j = 0; j < nDist; j++) {
1756 a_distribution(pCellId, j) = a_oldDistribution(pCellId, j) + omega * (eqDist[j] - a_oldDistribution(pCellId, j));
1769template <MInt nDim, MInt nDist,
class SysEqn>
1773 const MInt pvrho = PV->RHO;
1775 constexpr MInt fldlen = Ld::dxQyFld();
1783 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
1793 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
1795#ifndef WAR_NVHPC_PSTL
1797 const MInt*
const RESTRICT activeCellList = ALIGNED_I(m_activeCellList);
1798 MFloat*
const RESTRICT cnu = ALIGNED_MF(&(a_nu(0)));
1799 const MInt*
const RESTRICT clevel = ALIGNED_I(&(this->m_cells.level(0)));
1800 MFloat*
const RESTRICT oldDistributions = ALIGNED_MF(&(a_oldDistribution(0, 0)));
1801 MFloat*
const RESTRICT distributions = ALIGNED_MF(&(a_distribution(0, 0)));
1802 MFloat*
const RESTRICT variables = ALIGNED_MF(&(a_variable(0, 0)));
1804 const MInt maxLevel_ = maxLevel();
1806 const MInt distNu = &a_nu(1) - &a_nu(0);
1807 const MInt distLevel = &(this->m_cells.level(1)) - &(this->m_cells.level(0));
1808 const MInt distVars = &(a_variable(1, 0)) - &(a_variable(0, 0));
1814 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt i) {
1815#ifdef WAR_NVHPC_PSTL
1816 const MInt pCellId = m_activeCellList[i];
1817 const MInt index = maxLevel() - this->a_level(pCellId);
1819 const MInt pCellId = activeCellList[i];
1820 const MInt index = maxLevel_ - clevel[pCellId * distLevel];
1825 if((gTS - 1) %
IPOW2(index) == 0) {
1827#ifndef WAR_NVHPC_PSTL
1828 cnu[pCellId * distNu] = m_nu;
1830 const MInt distStart = pCellId * nDist;
1833 const MInt varStart = pCellId * distVars;
1835 MFloat*
const oldDistributionsStart = &oldDistributions[distStart];
1836 MFloat*
const distributionsStart = &distributions[distStart];
1837 MFloat*
const variablesStart = &variables[varStart];
1839 a_nu(pCellId) = m_nu;
1844 const MFloat l_omega = 2.0 / (1.0 + 6.0 * m_nu * tmp_FFPOW2);
1846 swap_variables(pCellId);
1849 MFloat l_v[nDim] = {0.0};
1851 std::array<
MFloat, nDist - 1> externalForcing{};
1853 if(m_particleMomentumCoupling) {
1854 for(
MInt dir = 0; dir < nDim; dir++) {
1855 for(
MInt mi = 0; mi < fldlen; mi++) {
1856#ifdef WAR_NVHPC_PSTL
1857 externalForcing[m_nFld[dir * fldlen + mi]] +=
1858 m_tp[m_distType[m_nFld[dir * fldlen + mi]]] * -1.0 * a_externalForces(pCellId, dir) * F1BCSsq;
1859 externalForcing[m_pFld[dir * fldlen + mi]] +=
1860 m_tp[m_distType[m_pFld[dir * fldlen + mi]]] * 1.0 * a_externalForces(pCellId, dir) * F1BCSsq;
1862 externalForcing.at(Ld::nFld(dir, mi)) +=
1863 Ld::tp(Ld::distType(Ld::nFld(dir, mi))) * -1.0 * a_externalForces(pCellId, dir) * F1BCSsq;
1864 externalForcing.at(Ld::pFld(dir, mi)) +=
1865 Ld::tp(Ld::distType(Ld::pFld(dir, mi))) * 1.0 * a_externalForces(pCellId, dir) * F1BCSsq;
1870#ifdef WAR_NVHPC_PSTL
1872 for(
MInt j = 0; j < nDist - 1; j++) {
1873 if(m_particleMomentumCoupling) {
1874 a_oldDistribution(pCellId, j) += tmp_FPOW2 * externalForcing[j];
1877 l_rho += a_oldDistribution(pCellId, j);
1880 l_rho += a_oldDistribution(pCellId, nDist - 1);
1883 for(
MInt j = 0; j < nDist - 1; j++) {
1884 if(m_particleMomentumCoupling) {
1885 oldDistributionsStart[j] += tmp_FPOW2 * externalForcing.at(j);
1888 l_rho += oldDistributionsStart[j];
1891 l_rho += oldDistributionsStart[nDist - 1];
1896#ifndef WAR_NVHPC_PSTL
1897 if constexpr(nDim == 2) {
1901 l_v[0] = oldDistributionsStart[1] + oldDistributionsStart[4] + oldDistributionsStart[5]
1902 - oldDistributionsStart[7] - oldDistributionsStart[6] - oldDistributionsStart[0];
1904 l_v[1] = oldDistributionsStart[7] + oldDistributionsStart[3] + oldDistributionsStart[4]
1905 - oldDistributionsStart[6] - oldDistributionsStart[2] - oldDistributionsStart[5];
1908 for(
MInt j = 0; j < fldlen; j++) {
1909 for(
MInt d = 0; d < nDim; d++) {
1910#ifdef WAR_NVHPC_PSTL
1911 l_v[d] += a_oldDistribution(pCellId, m_pFld[d * fldlen + j]);
1912 l_v[d] -= a_oldDistribution(pCellId, m_nFld[d * fldlen + j]);
1914 l_v[d] += oldDistributionsStart[Ld::pFld(d, j)];
1915 l_v[d] -= oldDistributionsStart[Ld::nFld(d, j)];
1919#ifndef WAR_NVHPC_PSTL
1924#ifdef WAR_NVHPC_PSTL
1925 for(
MInt d = 0; d < nDim; d++) {
1926 a_variable(pCellId, d) = l_v[d];
1928 a_variable(pCellId, nDim) = l_rho;
1930 for(
MInt d = 0; d < nDim; d++) {
1931 variablesStart[d] = l_v[d];
1933 variablesStart[pvrho] = l_rho;
1936 const MFloat sqVel = std::inner_product(&l_v[0], &l_v[nDim], &l_v[0], F0);
1938 std::array<MFloat, nDist> eqDist;
1939 eqDist = getEqDists(l_rho, sqVel, l_v);
1942#ifdef WAR_NVHPC_PSTL
1943 for(
MInt j = 0; j < nDist; j++) {
1944 a_distribution(pCellId, j) =
1945 a_oldDistribution(pCellId, j) + l_omega * (eqDist[j] - a_oldDistribution(pCellId, j));
1948 for(
MInt j = 0; j < nDist; j++) {
1949 distributionsStart[j] = oldDistributionsStart[j] + l_omega * (eqDist[j] - oldDistributionsStart[j]);
1967template <MInt nDim, MInt nDist,
class SysEqn>
1971 if(!m_particleMomentumCoupling)
1972 std::cerr <<
"Momentum Coupling is not activated, use MAIA_LATTIC_BGK instead!" << std::endl;
1974 const MInt pvrho = PV->RHO;
1976 constexpr MInt fldlen = Ld::dxQyFld();
1984 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
1994 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
1997 const MInt*
const RESTRICT activeCellList = ALIGNED_I(m_activeCellList);
1998 MFloat*
const RESTRICT cnu = ALIGNED_MF(&(a_nu(0)));
1999 const MInt*
const RESTRICT clevel = ALIGNED_I(&(this->m_cells.level(0)));
2000 MFloat*
const RESTRICT oldDistributions = ALIGNED_MF(&(a_oldDistribution(0, 0)));
2001 MFloat*
const RESTRICT distributions = ALIGNED_MF(&(a_distribution(0, 0)));
2002 MFloat*
const RESTRICT variables = ALIGNED_MF(&(a_variable(0, 0)));
2009 const MInt maxLevel_ = maxLevel();
2012 const MInt distNu = &a_nu(1) - &a_nu(0);
2013 const MInt distLevel = &(this->m_cells.level(1)) - &(this->m_cells.level(0));
2014 const MInt distVars = &(a_variable(1, 0)) - &(a_variable(0, 0));
2017 maia::parallelFor<false>(0, m_currentMaxNoCells, [=](
MInt i) {
2018 const MInt pCellId = activeCellList[i];
2019 const MInt index = maxLevel_ - clevel[pCellId * distLevel];
2023 if((gTS - 1) %
IPOW2(index) == 0) {
2025 cnu[pCellId * distNu] = nu;
2027 const MInt distStart = pCellId * nDist;
2030 const MInt varStart = pCellId * distVars;
2032 MFloat*
const oldDistributionsStart = &oldDistributions[distStart];
2033 MFloat*
const distributionsStart = &distributions[distStart];
2035 MFloat*
const variablesStart = &variables[varStart];
2039 const MFloat l_omega = 2.0 / (1.0 + 6.0 * nu * tmp_FFPOW2);
2041 swap_variables(pCellId);
2044 MFloat l_v[nDim] = {0.0};
2046 std::array<MFloat, nDist> externalForcing{0.0};
2049 for(
MInt j = 0; j < nDist - 1; j++) {
2051 l_rho += oldDistributionsStart[j];
2054 l_rho += oldDistributionsStart[nDist - 1];
2056 for(
MInt j = 0; j < fldlen; j++) {
2057 for(
MInt d = 0; d < nDim; d++) {
2058 l_v[d] += oldDistributionsStart[Ld::pFld(d, j)];
2059 l_v[d] -= oldDistributionsStart[Ld::nFld(d, j)];
2064 for(
MInt d = 0; d < nDim; d++) {
2065 l_v[d] += tmp_FPOW2 * F1B2 * a_externalForces(pCellId, d);
2069 for(
MInt d = 0; d < nDim; d++) {
2070 variablesStart[d] = l_v[d];
2072 variablesStart[pvrho] = l_rho;
2074 const MFloat sqVel = std::inner_product(&l_v[0], &l_v[nDim], &l_v[0], F0);
2077 for(
MInt j = 0; j < nDist - 1; j++) {
2079 std::array<MFloat, nDim> velDiff{};
2080 MFloat scalarProductVel{};
2081 for(
MInt dir = 0; dir < nDim; dir++) {
2082 velDiff.at(dir) = Ld::ppdfDir(j, dir) - l_v[dir];
2083 scalarProductVel += Ld::ppdfDir(j, dir) * l_v[dir];
2085 for(
MInt dir = 0; dir < nDim; dir++) {
2086 externalForcing.at(j) +=
2087 tmp_FPOW2 * (F1 - F1B2 * l_omega) * Ld::tp(Ld::distType(j))
2088 * (F1BCSsq * velDiff.at(dir) +
POW2(F1BCSsq) * scalarProductVel * Ld::ppdfDir(j, dir))
2089 * a_externalForces(pCellId, dir);
2093 std::array<MFloat, nDist> eqDist;
2094 eqDist = getEqDists(l_rho, sqVel, l_v);
2097 for(
MInt j = 0; j < nDist; j++) {
2098 distributionsStart[j] =
2099 oldDistributionsStart[j] + l_omega * (eqDist[j] - oldDistributionsStart[j]) + externalForcing.at(j);
2110template <MInt nDim, MInt nDist,
class SysEqn>
2114 const MInt pvrho = PV->RHO;
2115 const MInt pvc = PV->C;
2117 constexpr MInt fldlen = Ld::dxQyFld();
2125 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
2135 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
2138 m_diffusivity = m_nu * (m_Re / m_Pe);
2140#ifndef WAR_NVHPC_PSTL
2142 const MInt*
const RESTRICT activeCellList = ALIGNED_I(m_activeCellList);
2143 MFloat*
const RESTRICT cnu = ALIGNED_MF(&(a_nu(0)));
2144 MFloat*
const RESTRICT cdiffusivity = ALIGNED_MF(&(a_diffusivity(0)));
2145 const MInt*
const RESTRICT clevel = ALIGNED_I(&(this->m_cells.level(0)));
2146 MFloat*
const RESTRICT oldDistributions = ALIGNED_MF(&(a_oldDistribution(0, 0)));
2147 MFloat*
const RESTRICT distributions = ALIGNED_MF(&(a_distribution(0, 0)));
2148 MFloat*
const RESTRICT oldDistributionsTransport = ALIGNED_MF(&(a_oldDistributionTransport(0, 0)));
2149 MFloat*
const RESTRICT distributionsTransport = ALIGNED_MF(&(a_distributionTransport(0, 0)));
2150 MFloat*
const RESTRICT variables = ALIGNED_MF(&(a_variable(0, 0)));
2153 const MInt maxLevel_ = maxLevel();
2155 const MInt distNu = &a_nu(1) - &a_nu(0);
2156 const MInt distDiffusivity = &a_diffusivity(1) - &a_diffusivity(0);
2157 const MInt distLevel = &(this->m_cells.level(1)) - &(this->m_cells.level(0));
2158 const MInt distVars = &(a_variable(1, 0)) - &(a_variable(0, 0));
2164 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt i) {
2165#ifdef WAR_NVHPC_PSTL
2166 const MInt pCellId = m_activeCellList[i];
2167 const MInt index = maxLevel() - this->a_level(pCellId);
2169 const MInt pCellId = activeCellList[i];
2170 const MInt index = maxLevel_ - clevel[pCellId * distLevel];
2175 if((gTS - 1) %
IPOW2(index) == 0) {
2177#ifndef WAR_NVHPC_PSTL
2178 cnu[pCellId * distNu] = m_nu;
2179 cdiffusivity[pCellId * distDiffusivity] = m_diffusivity;
2181 const MInt distStart = pCellId * nDist;
2184 const MInt varStart = pCellId * distVars;
2186 MFloat*
const oldDistributionsStart = &oldDistributions[distStart];
2187 MFloat*
const distributionsStart = &distributions[distStart];
2188 MFloat*
const oldDistributionsTransportStart = &oldDistributionsTransport[distStart];
2189 MFloat*
const distributionsTransportStart = &distributionsTransport[distStart];
2191 MFloat*
const variablesStart = &variables[varStart];
2193 a_nu(pCellId) = m_nu;
2194 a_kappa(pCellId) = m_kappa;
2198 const MFloat l_omega = 2.0 / (1.0 + 6.0 * m_nu * tmp_FFPOW2);
2199 const MFloat l_omegaD = 2.0 / (1.0 + 6.0 * m_diffusivity * tmp_FFPOW2);
2201 swap_variables(pCellId);
2204 MFloat l_v[nDim] = {0.0};
2208#ifdef WAR_NVHPC_PSTL
2210 for(
MInt j = 0; j < nDist - 1; j++) {
2212 l_rho += a_oldDistribution(pCellId, j);
2213 l_c += a_oldDistributionTransport(pCellId, j);
2216 l_rho += a_oldDistribution(pCellId, nDist - 1);
2217 l_c += a_oldDistributionTransport(pCellId, nDist - 1);
2220 for(
MInt j = 0; j < nDist - 1; j++) {
2221 l_rho += oldDistributionsStart[j];
2222 l_c += oldDistributionsTransportStart[j];
2225 l_rho += oldDistributionsStart[nDist - 1];
2226 l_c += oldDistributionsTransportStart[nDist - 1];
2230#ifndef WAR_NVHPC_PSTL
2231 if constexpr(nDim == 2) {
2235 l_v[0] = oldDistributionsStart[1] + oldDistributionsStart[4] + oldDistributionsStart[5]
2236 - oldDistributionsStart[7] - oldDistributionsStart[6] - oldDistributionsStart[0];
2238 l_v[1] = oldDistributionsStart[7] + oldDistributionsStart[3] + oldDistributionsStart[4]
2239 - oldDistributionsStart[6] - oldDistributionsStart[2] - oldDistributionsStart[5];
2242 for(
MInt j = 0; j < fldlen; j++) {
2243 for(
MInt d = 0; d < nDim; d++) {
2244#ifdef WAR_NVHPC_PSTL
2245 l_v[d] += a_oldDistribution(pCellId, m_pFld[d * fldlen + j]);
2246 l_v[d] -= a_oldDistribution(pCellId, m_nFld[d * fldlen + j]);
2248 l_v[d] += oldDistributionsStart[Ld::pFld(d, j)];
2249 l_v[d] -= oldDistributionsStart[Ld::nFld(d, j)];
2253#ifndef WAR_NVHPC_PSTL
2258#ifdef WAR_NVHPC_PSTL
2259 for(
MInt d = 0; d < nDim; d++) {
2260 a_variable(pCellId, d) = l_v[d];
2262 a_variable(pCellId, pvrho) = l_rho;
2263 a_variable(pCellId, pvc) = l_c;
2265 for(
MInt d = 0; d < nDim; d++) {
2266 variablesStart[d] = l_v[d];
2268 variablesStart[pvrho] = l_rho;
2269 variablesStart[pvc] = l_c;
2273 for(
MInt d = 0; d < nDim; d++) {
2274 u[d] = l_v[d] / l_rho;
2277 std::array<MFloat, nDist> eqDist;
2278 eqDist = getEqDists(l_rho, u);
2279 std::array<MFloat, nDist> eqDistC;
2280 eqDistC = getEqDistsTransport(l_c, u);
2283 for(
MInt j = 0; j < nDist; j++) {
2284#ifdef WAR_NVHPC_PSTL
2285 a_distribution(pCellId, j) =
2286 a_oldDistribution(pCellId, j) + l_omega * (eqDist[j] - a_oldDistribution(pCellId, j));
2287 a_distributionTransport(pCellId, j) =
2288 a_oldDistributionTransport(pCellId, j) + l_omegaD * (eqDistC[j] - a_oldDistributionTransport(pCellId, j));
2290 distributionsStart[j] = oldDistributionsStart[j] + l_omega * (eqDist[j] - oldDistributionsStart[j]);
2291 distributionsTransportStart[j] = oldDistributionsTransportStart[j] + l_omegaD * (eqDistC[j] - oldDistributionsTransportStart[j]);
2303template <MInt nDim, MInt nDist,
class SysEqn>
2304template <MInt thermalMode>
2308 const MInt pvrho = PV->RHO;
2309 const MInt pvt = PV->T;
2310 const MInt pvc = PV->C;
2312 constexpr MInt fldlen = Ld::dxQyFld();
2320 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
2330 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
2333 m_kappa = m_nu / m_Pr;
2334 m_diffusivity = m_nu * (m_Re / m_Pe);
2336#ifndef WAR_NVHPC_PSTL
2338 const MInt*
const RESTRICT activeCellList = ALIGNED_I(m_activeCellList);
2339 MFloat*
const RESTRICT cnu = ALIGNED_MF(&(a_nu(0)));
2340 MFloat*
const RESTRICT ckappa = ALIGNED_MF(&(a_kappa(0)));
2341 MFloat*
const RESTRICT cdiffusivity = ALIGNED_MF(&(a_diffusivity(0)));
2342 const MInt*
const RESTRICT clevel = ALIGNED_I(&(this->m_cells.level(0)));
2343 MFloat*
const RESTRICT oldDistributions = ALIGNED_MF(&(a_oldDistribution(0, 0)));
2344 MFloat*
const RESTRICT distributions = ALIGNED_MF(&(a_distribution(0, 0)));
2345 MFloat*
const RESTRICT oldDistributionsThermal = ALIGNED_MF(&(a_oldDistributionThermal(0, 0)));
2346 MFloat*
const RESTRICT distributionsThermal = ALIGNED_MF(&(a_distributionThermal(0, 0)));
2347 MFloat*
const RESTRICT oldDistributionsTransport = ALIGNED_MF(&(a_oldDistributionTransport(0, 0)));
2348 MFloat*
const RESTRICT distributionsTransport = ALIGNED_MF(&(a_distributionTransport(0, 0)));
2349 MFloat*
const RESTRICT variables = ALIGNED_MF(&(a_variable(0, 0)));
2352 const MInt maxLevel_ = maxLevel();
2354 const MInt distNu = &a_nu(1) - &a_nu(0);
2355 const MInt distKappa = &a_kappa(1) - &a_kappa(0);
2356 const MInt distDiffusivity = &a_diffusivity(1) - &a_diffusivity(0);
2357 const MInt distLevel = &(this->m_cells.level(1)) - &(this->m_cells.level(0));
2358 const MInt distVars = &(a_variable(1, 0)) - &(a_variable(0, 0));
2363 const MFloat factor = (thermalMode == 1) ? ((nDim == 2) ? 3.0 : 18.0 / 5.0) : F6;
2366 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt i) {
2367#ifdef WAR_NVHPC_PSTL
2368 const MInt pCellId = m_activeCellList[i];
2369 const MInt index = maxLevel() - this->a_level(pCellId);
2371 const MInt pCellId = activeCellList[i];
2372 const MInt index = maxLevel_ - clevel[pCellId * distLevel];
2377 if((gTS - 1) %
IPOW2(index) == 0) {
2379#ifndef WAR_NVHPC_PSTL
2380 cnu[pCellId * distNu] = m_nu;
2381 ckappa[pCellId * distKappa] = m_kappa;
2382 cdiffusivity[pCellId * distDiffusivity] = m_diffusivity;
2384 const MInt distStart = pCellId * nDist;
2387 const MInt varStart = pCellId * distVars;
2389 MFloat*
const oldDistributionsStart = &oldDistributions[distStart];
2390 MFloat*
const distributionsStart = &distributions[distStart];
2391 MFloat*
const oldDistributionsTStart = &oldDistributionsThermal[distStart];
2392 MFloat*
const distributionsTStart = &distributionsThermal[distStart];
2393 MFloat*
const oldDistributionsTransportStart = &oldDistributionsTransport[distStart];
2394 MFloat*
const distributionsTransportStart = &distributionsTransport[distStart];
2396 MFloat*
const variablesStart = &variables[varStart];
2398 a_nu(pCellId) = m_nu;
2399 a_kappa(pCellId) = m_kappa;
2400 a_diffusivity(pCellId) = m_diffusivity;
2404 const MFloat l_omega = 2.0 / (1.0 + 6.0 * m_nu * tmp_FFPOW2);
2405 const MFloat l_omegaT = 2.0 / (1.0 + factor * m_kappa * tmp_FFPOW2);
2406 const MFloat l_omegaD = 2.0 / (1.0 + 6.0 * m_diffusivity * tmp_FFPOW2);
2408 swap_variables(pCellId);
2411 MFloat l_v[nDim] = {0.0};
2416#ifdef WAR_NVHPC_PSTL
2418 for(
MInt j = 0; j < nDist - 1; j++) {
2420 l_rho += a_oldDistribution(pCellId, j);
2421 l_t += a_oldDistributionThermal(pCellId, j);
2422 l_c += a_oldDistributionTransport(pCellId, j);
2425 l_rho += a_oldDistribution(pCellId, nDist - 1);
2426 l_t += a_oldDistributionThermal(pCellId, nDist - 1);
2427 l_c += a_oldDistributionTransport(pCellId, nDist - 1);
2430 for(
MInt j = 0; j < nDist - 1; j++) {
2431 l_rho += oldDistributionsStart[j];
2432 l_t += oldDistributionsTStart[j];
2433 l_c += oldDistributionsTransportStart[j];
2436 l_rho += oldDistributionsStart[nDist - 1];
2437 l_t += oldDistributionsTStart[nDist - 1];
2438 l_c += oldDistributionsTransportStart[nDist - 1];
2442#ifndef WAR_NVHPC_PSTL
2443 if constexpr(nDim == 2) {
2447 l_v[0] = oldDistributionsStart[1] + oldDistributionsStart[4] + oldDistributionsStart[5]
2448 - oldDistributionsStart[7] - oldDistributionsStart[6] - oldDistributionsStart[0];
2450 l_v[1] = oldDistributionsStart[7] + oldDistributionsStart[3] + oldDistributionsStart[4]
2451 - oldDistributionsStart[6] - oldDistributionsStart[2] - oldDistributionsStart[5];
2454 for(
MInt j = 0; j < fldlen; j++) {
2455 for(
MInt d = 0; d < nDim; d++) {
2456#ifdef WAR_NVHPC_PSTL
2457 l_v[d] += a_oldDistribution(pCellId, m_pFld[d * fldlen + j]);
2458 l_v[d] -= a_oldDistribution(pCellId, m_nFld[d * fldlen + j]);
2460 l_v[d] += oldDistributionsStart[Ld::pFld(d, j)];
2461 l_v[d] -= oldDistributionsStart[Ld::nFld(d, j)];
2465#ifndef WAR_NVHPC_PSTL
2469 std::array<MFloat, nDim> u{};
2470 for(
MInt d = 0; d < nDim; d++) {
2471 u[d] = l_v[d] / l_rho;
2475#ifdef WAR_NVHPC_PSTL
2476 for(
MInt d = 0; d < nDim; d++) {
2477 a_variable(pCellId, d) = l_v[d];
2479 a_variable(pCellId, pvrho) = l_rho;
2480 a_variable(pCellId, pvc) = l_c;
2481 IF_CONSTEXPR(thermalMode == 0) { a_variable(pCellId, pvt) = l_t; }
2482 IF_CONSTEXPR(thermalMode == 1) {
2484 const MFloat l_ie_rho = l_t;
2485 l_t = l_ie_rho * F2 / (D * l_rho);
2486 a_variable(pCellId, pvt) = l_t;
2488 IF_CONSTEXPR(thermalMode == 2) {
2490 const MFloat sqVel = std::inner_product(&u[0], &u[nDim], &u[0], F0);
2491 const MFloat l_te_rho = l_t;
2492 l_t = (l_te_rho / l_rho - sqVel * F1B2) * F2 / D;
2493 a_variable(pCellId, pvt) = l_t;
2494 for(
MInt d = 0; d < nDim; d++) {
2495 a_variable(pCellId, d) = l_v[d];
2499 for(
MInt d = 0; d < nDim; d++) {
2500 variablesStart[d] = l_v[d];
2502 variablesStart[pvrho] = l_rho;
2503 variablesStart[pvc] = l_c;
2504 IF_CONSTEXPR(thermalMode == 0) { variablesStart[pvt] = l_t; }
2505 IF_CONSTEXPR(thermalMode == 1) {
2507 const MFloat l_ie_rho = l_t;
2508 l_t = l_ie_rho * F2 / (D * l_rho);
2509 variablesStart[pvt] = l_t;
2511 IF_CONSTEXPR(thermalMode == 2) {
2513 const MFloat sqVel = std::inner_product(&u[0], &u[nDim], &u[0], F0);
2514 const MFloat l_te_rho = l_t;
2515 l_t = (l_te_rho / l_rho - sqVel * F1B2) * F2 / D;
2516 variablesStart[pvt] = l_t;
2517 for(
MInt d = 0; d < nDim; d++) {
2518 variablesStart[d] = l_v[d];
2523 std::array<MFloat, nDist> eqDist;
2524 eqDist = getEqDists(l_rho, u.data());
2525 std::array<MFloat, nDist> eqDistT;
2526 eqDistT = getEqDistsThermal_<thermalMode>(l_t, l_rho, u.data());
2527 std::array<MFloat, nDist> eqDistC;
2528 eqDistC = getEqDistsTransport(l_c, u.data());
2530 std::array<MFloat, nDist> Sj;
2531 IF_CONSTEXPR(thermalMode == 2) {
2532 std::array<MFloat, 2 * nDim>
b{};
2533 for(
MInt d = 0; d < nDim; d++) {
2535 b[2 * d + 1] = u[d];
2537 const MFloat sqVel = std::inner_product(&u[0], &u[nDim], &u[0], F0);
2538#ifdef WAR_NVHPC_PSTL
2539 for(
MInt j = 0; j < m_distFld[0]; j++) {
2540 Sj[j] = (l_omegaT - l_omega) * (
b[j] - sqVel * F1B2) * (a_oldDistribution(pCellId, j) - eqDist[j]);
2542 for(
MInt j = 0; j < m_distFld[1]; j++) {
2543 const MInt p = 2 * j;
2544 const MInt pos = j + m_distFld[0];
2545 const MFloat tmp = (
b[m_mFld1[p]] +
b[m_mFld1[p + 1]]);
2546 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2) * (a_oldDistribution(pCellId, pos) - eqDist[pos]);
2548 for(
MInt j = 0; j < m_distFld[2]; j++) {
2549 const MInt p = 3 * j;
2550 const MInt pos = j + m_distFld[0] + m_distFld[1];
2551 const MFloat tmp = (
b[m_mFld2[p]] +
b[m_mFld2[p + 1]] +
b[m_mFld2[p + 2]]);
2552 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2) * (a_oldDistribution(pCellId, pos) - eqDist[pos]);
2554 Sj[Ld::lastId()] = (l_omegaT - l_omega) * (F0 - sqVel * F1B2)
2555 * (a_oldDistribution(pCellId, Ld::lastId()) - eqDist[Ld::lastId()]);
2557 for(
MInt j = 0; j < Ld::distFld(0); j++) {
2558 Sj[j] = (l_omegaT - l_omega) * (
b[j] - sqVel * F1B2) * (oldDistributionsStart[j] - eqDist[j]);
2560 for(
MInt j = 0; j < Ld::distFld(1); j++) {
2561 const MInt p = 2 * j;
2562 const MInt pos = j + Ld::distFld(0);
2563 const MFloat tmp = (
b[Ld::mFld1(p)] +
b[Ld::mFld1(p + 1)]);
2564 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2) * (oldDistributionsStart[pos] - eqDist[pos]);
2566 for(
MInt j = 0; j < Ld::distFld(2); j++) {
2567 const MInt p = 3 * j;
2568 const MInt pos = j + Ld::distFld(0) + Ld::distFld(1);
2569 const MFloat tmp = (
b[Ld::mFld2(p)] +
b[Ld::mFld2(p + 1)] +
b[Ld::mFld2(p + 2)]);
2570 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2) * (oldDistributionsStart[pos] - eqDist[pos]);
2573 (l_omegaT - l_omega) * (F0 - sqVel * F1B2) * (oldDistributionsStart[Ld::lastId()] - eqDist[Ld::lastId()]);
2578 for(
MInt j = 0; j < nDist; j++) {
2579#ifdef WAR_NVHPC_PSTL
2580 a_distribution(pCellId, j) =
2581 a_oldDistribution(pCellId, j) + l_omega * (eqDist[j] - a_oldDistribution(pCellId, j));
2582 a_distributionThermal(pCellId, j) =
2583 a_oldDistributionThermal(pCellId, j) + l_omegaT * (eqDistT[j] - a_oldDistributionThermal(pCellId, j));
2584 a_distributionTransport(pCellId, j) =
2585 a_oldDistributionTransport(pCellId, j) + l_omegaD * (eqDistC[j] - a_oldDistributionTransport(pCellId, j));
2586 IF_CONSTEXPR(thermalMode == 2) { a_distributionThermal(pCellId, j) += Sj[j]; }
2588 distributionsStart[j] = oldDistributionsStart[j] + l_omega * (eqDist[j] - oldDistributionsStart[j]);
2589 distributionsTStart[j] = oldDistributionsTStart[j] + l_omegaT * (eqDistT[j] - oldDistributionsTStart[j]);
2590 IF_CONSTEXPR(thermalMode == 2) { distributionsTStart[j] += Sj[j]; }
2591 distributionsTransportStart[j] = oldDistributionsTransportStart[j] + l_omegaD * (eqDistC[j] - oldDistributionsTransportStart[j]);
2603template <MInt nDim, MInt nDist,
class SysEqn>
2607 bgki_thermal_and_transport_collision_step_base<0>();
2615template <MInt nDim, MInt nDist,
class SysEqn>
2619 bgki_thermal_and_transport_collision_step_base<1>();
2627template <MInt nDim, MInt nDist,
class SysEqn>
2631 bgki_thermal_and_transport_collision_step_base<2>();
2634template <MInt nDim, MInt nDist,
class SysEqn>
2635template <MInt thermalMode>
2639 const MInt pvrho = PV->RHO;
2640 const MInt pvt = PV->T;
2642 constexpr MInt fldlen = Ld::dxQyFld();
2650 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
2660 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
2663 m_kappa = m_nu / m_Pr;
2665#ifndef WAR_NVHPC_PSTL
2667 const MInt*
const RESTRICT activeCellList = ALIGNED_I(m_activeCellList);
2668 MFloat*
const RESTRICT cnu = ALIGNED_MF(&(a_nu(0)));
2669 MFloat*
const RESTRICT ckappa = ALIGNED_MF(&(a_kappa(0)));
2670 const MInt*
const RESTRICT clevel = ALIGNED_I(&(this->m_cells.level(0)));
2671 MFloat*
const RESTRICT oldDistributions = ALIGNED_MF(&(a_oldDistribution(0, 0)));
2672 MFloat*
const RESTRICT distributions = ALIGNED_MF(&(a_distribution(0, 0)));
2673 MFloat*
const RESTRICT oldDistributionsThermal = ALIGNED_MF(&(a_oldDistributionThermal(0, 0)));
2674 MFloat*
const RESTRICT distributionsThermal = ALIGNED_MF(&(a_distributionThermal(0, 0)));
2675 MFloat*
const RESTRICT variables = ALIGNED_MF(&(a_variable(0, 0)));
2676 const MFloat*
const Fp = ALIGNED_MF(m_Fext);
2678 const MInt maxLevel_ = maxLevel();
2680 const MInt distNu = &a_nu(1) - &a_nu(0);
2681 const MInt distKappa = &a_kappa(1) - &a_kappa(0);
2682 const MInt distLevel = &(this->m_cells.level(1)) - &(this->m_cells.level(0));
2683 const MInt distVars = &(a_variable(1, 0)) - &(a_variable(0, 0));
2688 const MFloat factor = (thermalMode == 1) ? ((nDim == 2) ? 3.0 : 18.0 / 5.0) : F6;
2691 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt i) {
2692#ifdef WAR_NVHPC_PSTL
2693 const MInt pCellId = m_activeCellList[i];
2694 const MInt index = maxLevel() - this->a_level(pCellId);
2696 const MInt pCellId = activeCellList[i];
2697 const MInt index = maxLevel_ - clevel[pCellId * distLevel];
2702 if((gTS - 1) %
IPOW2(index) == 0) {
2704#ifndef WAR_NVHPC_PSTL
2705 cnu[pCellId * distNu] = m_nu;
2706 ckappa[pCellId * distKappa] = m_kappa;
2708 const MInt distStart = pCellId * nDist;
2711 const MInt varStart = pCellId * distVars;
2713 MFloat*
const oldDistributionsStart = &oldDistributions[distStart];
2714 MFloat*
const distributionsStart = &distributions[distStart];
2715 MFloat*
const oldDistributionsTStart = &oldDistributionsThermal[distStart];
2716 MFloat*
const distributionsTStart = &distributionsThermal[distStart];
2718 MFloat*
const variablesStart = &variables[varStart];
2720 a_nu(pCellId) = m_nu;
2721 a_kappa(pCellId) = m_kappa;
2726 const MFloat l_omega = 2.0 / (1.0 + 6.0 * m_nu * tmp_FFPOW2);
2727 const MFloat l_omegaT = 2.0 / (1.0 + factor * m_kappa * tmp_FFPOW2);
2729 swap_variables(pCellId);
2732 MFloat l_v[nDim] = {0.0};
2736#ifdef WAR_NVHPC_PSTL
2738 for(
MInt j = 0; j < nDist - 1; j++) {
2739 IF_CONSTEXPR(thermalMode != 2) a_oldDistribution(pCellId, j) += tmp_FPOW2 * m_Fext[j];
2741 l_rho += a_oldDistribution(pCellId, j);
2742 l_t += a_oldDistributionThermal(pCellId, j);
2745 l_rho += a_oldDistribution(pCellId, nDist - 1);
2746 l_t += a_oldDistributionThermal(pCellId, nDist - 1);
2749 for(
MInt j = 0; j < nDist - 1; j++) {
2750 IF_CONSTEXPR(thermalMode != 2) oldDistributionsStart[j] += tmp_FPOW2 * Fp[j];
2751 l_rho += oldDistributionsStart[j];
2752 l_t += oldDistributionsTStart[j];
2755 l_rho += oldDistributionsStart[nDist - 1];
2756 l_t += oldDistributionsTStart[nDist - 1];
2760#ifndef WAR_NVHPC_PSTL
2761 if constexpr(nDim == 2) {
2765 l_v[0] = oldDistributionsStart[1] + oldDistributionsStart[4] + oldDistributionsStart[5]
2766 - oldDistributionsStart[7] - oldDistributionsStart[6] - oldDistributionsStart[0];
2768 l_v[1] = oldDistributionsStart[7] + oldDistributionsStart[3] + oldDistributionsStart[4]
2769 - oldDistributionsStart[6] - oldDistributionsStart[2] - oldDistributionsStart[5];
2772 for(
MInt j = 0; j < fldlen; j++) {
2773 for(
MInt d = 0; d < nDim; d++) {
2774#ifdef WAR_NVHPC_PSTL
2775 l_v[d] += a_oldDistribution(pCellId, m_pFld[d * fldlen + j]);
2776 l_v[d] -= a_oldDistribution(pCellId, m_nFld[d * fldlen + j]);
2778 l_v[d] += oldDistributionsStart[Ld::pFld(d, j)];
2779 l_v[d] -= oldDistributionsStart[Ld::nFld(d, j)];
2783#ifndef WAR_NVHPC_PSTL
2787 std::array<MFloat, nDim> u{};
2788 for(
MInt d = 0; d < nDim; d++) {
2789 u[d] = l_v[d] / l_rho;
2793#ifdef WAR_NVHPC_PSTL
2794 for(
MInt d = 0; d < nDim; d++) {
2795 a_variable(pCellId, d) = l_v[d];
2797 a_variable(pCellId, pvrho) = l_rho;
2798 IF_CONSTEXPR(thermalMode == 0) { a_variable(pCellId, pvt) = l_t; }
2799 IF_CONSTEXPR(thermalMode == 1) {
2801 const MFloat l_ie_rho = l_t;
2802 l_t = l_ie_rho * F2 / (D * l_rho);
2803 a_variable(pCellId, pvt) = l_t;
2805 IF_CONSTEXPR(thermalMode == 2) {
2806 const MFloat accelerationForce = (this->m_externalForcing) ? m_densityGradient * F1B3 : F0;
2810 std::array<MFloat, nDim>
a{};
2811 a[0] = accelerationForce;
2812 for(
MInt d = 0; d < nDim; d++) {
2813 l_v[d] += l_rho * tmp_FPOW2 *
a[d] * F1B2;
2814 u[d] = l_v[d] / l_rho;
2816 const MFloat sqVel = std::inner_product(&u[0], &u[nDim], &u[0], F0);
2819 for(
MInt d = 0; d < nDim; d++) {
2820 u_x_a += u[d] *
a[d];
2822 const MFloat l_te_rho = l_t + F1B2 * tmp_FPOW2 * l_rho * u_x_a;
2823 l_t = (l_te_rho / l_rho - sqVel * F1B2) * F2 / D;
2824 a_variable(pCellId, pvt) = l_t;
2825 for(
MInt d = 0; d < nDim; d++) {
2826 a_variable(pCellId, d) = l_v[d];
2830 for(
MInt d = 0; d < nDim; d++) {
2831 variablesStart[d] = l_v[d];
2833 variablesStart[pvrho] = l_rho;
2834 IF_CONSTEXPR(thermalMode == 0) { variablesStart[pvt] = l_t; }
2835 IF_CONSTEXPR(thermalMode == 1) {
2837 const MFloat l_ie_rho = l_t;
2838 l_t = l_ie_rho * F2 / (D * l_rho);
2839 variablesStart[pvt] = l_t;
2841 IF_CONSTEXPR(thermalMode == 2) {
2842 const MFloat accelerationForce = (this->m_externalForcing) ? m_densityGradient * F1B3 : F0;
2846 std::array<MFloat, nDim>
a{};
2847 a[0] = accelerationForce;
2848 for(
MInt d = 0; d < nDim; d++) {
2849 l_v[d] += l_rho * tmp_FPOW2 *
a[d] * F1B2;
2850 u[d] = l_v[d] / l_rho;
2852 const MFloat sqVel = std::inner_product(&u[0], &u[nDim], &u[0], F0);
2855 for(
MInt d = 0; d < nDim; d++) {
2856 u_x_a += u[d] *
a[d];
2858 const MFloat l_te_rho = l_t + F1B2 * tmp_FPOW2 * l_rho * u_x_a;
2859 l_t = (l_te_rho / l_rho - sqVel * F1B2) * F2 / D;
2860 variablesStart[pvt] = l_t;
2861 for(
MInt d = 0; d < nDim; d++) {
2862 variablesStart[d] = l_v[d];
2867 std::array<MFloat, nDist> eqDist;
2868 eqDist = getEqDists(l_rho, u.data());
2869 std::array<MFloat, nDist> eqDistT;
2870 eqDistT = getEqDistsThermal_<thermalMode>(l_t, l_rho, u.data());
2872 std::array<MFloat, nDist> forcing;
2873 std::array<MFloat, nDist> forcingT;
2874 std::array<MFloat, nDist> Sj;
2875 IF_CONSTEXPR(thermalMode == 2) {
2876 const MFloat accelerationForce = (this->m_externalForcing) ? m_densityGradient * F1B3 : F0;
2877 std::array<MFloat, 2 * nDim>
a{};
2878 a[0] = -accelerationForce;
2879 a[1] = accelerationForce;
2881 std::array<MFloat, 2 * nDim>
b;
2882 for(
MInt d = 0; d < nDim; d++) {
2884 b[2 * d + 1] = u[d];
2885 u_x_a +=
b[d * 2 + 1] *
a[d * 2 + 1];
2888 const MFloat sqVel = std::inner_product(&u[0], &u[nDim], &u[0], F0);
2889 const MFloat l_te_rho = (l_t * D * F1B2 + sqVel * F1B2) * l_rho;
2890#ifdef WAR_NVHPC_PSTL
2891 for(
MInt j = 0; j < m_distFld[0]; j++) {
2892 forcing[j] = m_tp[1] * F1BCSsq * l_rho * (
a[j] +
a[j] *
b[j] * F1BCSsq - u_x_a);
2893 Sj[j] = (l_omegaT - l_omega) * (
b[j] - sqVel * F1B2)
2894 * (a_oldDistribution(pCellId, j) - eqDist[j] + F1B2 * tmp_FPOW2 * forcing[j]);
2895 forcingT[j] = m_tp[1] * F1BCSsq * l_te_rho *
a[j] + a_oldDistribution(pCellId, j) *
a[j];
2896 forcing[j] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2897 forcingT[j] *= tmp_FPOW2 * (F1 - l_omegaT * F1B2);
2899 for(
MInt j = 0; j < m_distFld[1]; j++) {
2900 const MInt p = 2 * j;
2901 const MInt pos = j + m_distFld[0];
2902 const MFloat tmp = (
b[m_mFld1[p]] +
b[m_mFld1[p + 1]]);
2903 const MFloat tmpT = (
a[m_mFld1[p]] +
a[m_mFld1[p + 1]]);
2904 forcing[pos] = m_tp[2] * F1BCSsq * l_rho * (tmpT + tmpT * tmp * F1BCSsq - u_x_a);
2905 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2)
2906 * (a_oldDistribution(pCellId, pos) - eqDist[pos] + F1B2 * tmp_FPOW2 * forcing[pos]);
2907 forcingT[pos] = m_tp[2] * F1BCSsq * l_te_rho * tmpT + a_oldDistribution(pCellId, pos) * tmpT;
2908 forcing[pos] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2909 forcingT[pos] *= tmp_FPOW2 * (F1 - l_omegaT * F1B2);
2911 for(
MInt j = 0; j < m_distFld[2]; j++) {
2912 const MInt p = 3 * j;
2913 const MInt pos = j + m_distFld[0] + m_distFld[1];
2914 const MFloat tmp = (
b[m_mFld2[p]] +
b[m_mFld2[p + 1]] +
b[m_mFld2[p + 2]]);
2915 const MFloat tmpT = (
a[m_mFld2[p]] +
a[m_mFld2[p + 1]] +
a[m_mFld2[p + 2]]);
2916 forcing[pos] = m_tp[3] * F1BCSsq * l_rho * (tmpT + tmpT * tmp * F1BCSsq - u_x_a);
2917 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2)
2918 * (a_oldDistribution(pCellId, pos) - eqDist[pos] + F1B2 * tmp_FPOW2 * forcing[pos]);
2919 forcingT[pos] = m_tp[3] * F1BCSsq * l_te_rho * tmpT + a_oldDistribution(pCellId, pos) * tmpT;
2920 forcing[pos] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2921 forcingT[pos] *= tmp_FPOW2 * (F1 - l_omegaT * F1B2);
2923 forcing[Ld::lastId()] = m_tp[0] * l_rho * (-F1BCSsq * u_x_a);
2924 Sj[Ld::lastId()] = (l_omegaT - l_omega) * (F0 - sqVel * F1B2)
2925 * (a_oldDistribution(pCellId, Ld::lastId()) - eqDist[Ld::lastId()]
2926 + F1B2 * tmp_FPOW2 * forcing[Ld::lastId()]);
2927 forcingT[Ld::lastId()] = F0;
2928 forcing[Ld::lastId()] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2930 for(
MInt j = 0; j < Ld::distFld(0); j++) {
2931 forcing[j] = Ld::tp(1) * F1BCSsq * l_rho * (
a[j] +
a[j] *
b[j] * F1BCSsq - u_x_a);
2932 Sj[j] = (l_omegaT - l_omega) * (
b[j] - sqVel * F1B2)
2933 * (oldDistributionsStart[j] - eqDist[j] + F1B2 * tmp_FPOW2 * forcing[j]);
2934 forcingT[j] = Ld::tp(1) * F1BCSsq * l_te_rho *
a[j] + oldDistributionsStart[j] *
a[j];
2935 forcing[j] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2936 forcingT[j] *= tmp_FPOW2 * (F1 - l_omegaT * F1B2);
2938 for(
MInt j = 0; j < Ld::distFld(1); j++) {
2939 const MInt p = 2 * j;
2940 const MInt pos = j + Ld::distFld(0);
2941 const MFloat tmp = (
b[Ld::mFld1(p)] +
b[Ld::mFld1(p + 1)]);
2942 const MFloat tmpT = (
a[Ld::mFld1(p)] +
a[Ld::mFld1(p + 1)]);
2943 forcing[pos] = Ld::tp(2) * F1BCSsq * l_rho * (tmpT + tmpT * tmp * F1BCSsq - u_x_a);
2944 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2)
2945 * (oldDistributionsStart[pos] - eqDist[pos] + F1B2 * tmp_FPOW2 * forcing[pos]);
2946 forcingT[pos] = Ld::tp(2) * F1BCSsq * l_te_rho * tmpT + oldDistributionsStart[pos] * tmpT;
2947 forcing[pos] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2948 forcingT[pos] *= tmp_FPOW2 * (F1 - l_omegaT * F1B2);
2950 for(
MInt j = 0; j < Ld::distFld(2); j++) {
2951 const MInt p = 3 * j;
2952 const MInt pos = j + Ld::distFld(0) + Ld::distFld(1);
2953 const MFloat tmp = (
b[Ld::mFld2(p)] +
b[Ld::mFld2(p + 1)] +
b[Ld::mFld2(p + 2)]);
2954 const MFloat tmpT = (
a[Ld::mFld2(p)] +
a[Ld::mFld2(p + 1)] +
a[Ld::mFld2(p + 2)]);
2955 forcing[pos] = Ld::tp(3) * F1BCSsq * l_rho * (tmpT + tmpT * tmp * F1BCSsq - u_x_a);
2956 Sj[pos] = (l_omegaT - l_omega) * (tmp - sqVel * F1B2)
2957 * (oldDistributionsStart[pos] - eqDist[pos] + F1B2 * tmp_FPOW2 * forcing[pos]);
2958 forcingT[pos] = Ld::tp(3) * F1BCSsq * l_te_rho * tmpT + oldDistributionsStart[pos] * tmpT;
2959 forcing[pos] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2960 forcingT[pos] *= tmp_FPOW2 * (F1 - l_omegaT * F1B2);
2962 forcing[Ld::lastId()] = Ld::tp(0) * l_rho * (-F1BCSsq * u_x_a);
2964 (l_omegaT - l_omega) * (F0 - sqVel * F1B2)
2965 * (oldDistributionsStart[Ld::lastId()] - eqDist[Ld::lastId()] + F1B2 * tmp_FPOW2 * forcing[Ld::lastId()]);
2966 forcingT[Ld::lastId()] = F0;
2967 forcing[Ld::lastId()] *= tmp_FPOW2 * (F1 - l_omega * F1B2);
2972 for(
MInt j = 0; j < nDist; j++) {
2973#ifdef WAR_NVHPC_PSTL
2974 a_distribution(pCellId, j) =
2975 a_oldDistribution(pCellId, j) + l_omega * (eqDist[j] - a_oldDistribution(pCellId, j));
2976 a_distributionThermal(pCellId, j) =
2977 a_oldDistributionThermal(pCellId, j) + l_omegaT * (eqDistT[j] - a_oldDistributionThermal(pCellId, j));
2978 IF_CONSTEXPR(thermalMode == 2) {
2979 a_distribution(pCellId, j) += forcing[j];
2980 a_distributionThermal(pCellId, j) += forcingT[j] + Sj[j];
2983 distributionsStart[j] = oldDistributionsStart[j] + l_omega * (eqDist[j] - oldDistributionsStart[j]);
2984 distributionsTStart[j] = oldDistributionsTStart[j] + l_omegaT * (eqDistT[j] - oldDistributionsTStart[j]);
2985 IF_CONSTEXPR(thermalMode == 2) {
2986 distributionsStart[j] += forcing[j];
2987 distributionsTStart[j] += forcingT[j] + Sj[j];
3003template <MInt nDim, MInt nDist,
class SysEqn>
3007 bgki_thermal_collision_step_base<0>();
3034template <MInt nDim, MInt nDist,
class SysEqn>
3038 bgki_thermal_collision_step_base<1>();
3060template <MInt nDim, MInt nDist,
class SysEqn>
3064 bgki_thermal_collision_step_base<2>();
3075template <MInt nDim, MInt nDist,
class SysEqn>
3077 bgki_smagorinsky_collision_step_base<0>();
3089template <MInt nDim, MInt nDist,
class SysEqn>
3091 bgki_smagorinsky_collision_step_base<1>();
3103template <MInt nDim, MInt nDist,
class SysEqn>
3105 bgki_smagorinsky_collision_step_base<2>();
3108template <MInt nDim, MInt nDist,
class SysEqn>
3120 MFloat actualCellLength = F0;
3121 constexpr MInt direction = 1;
3134 for(
MInt i = 0; i < m_arraySize[direction]; i++) {
3146 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
3154 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
3156 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
3157 const MInt pCellId = m_activeCellList[i];
3163 swap_variables(pCellId);
3166 a_variable(pCellId, PV->RHO) = 0.0;
3167 for(
MInt j = 0; j < nDist; j++) {
3168 a_variable(pCellId, PV->RHO) += a_oldDistribution(pCellId, j);
3170 rho = a_variable(pCellId, PV->RHO);
3173 for(
MInt j = 0; j < nDim; j++) {
3177 if constexpr(nDim == 2) {
3181 u[0] = a_oldDistribution(pCellId, 1) + a_oldDistribution(pCellId, 4) + a_oldDistribution(pCellId, 5)
3182 - a_oldDistribution(pCellId, 7) - a_oldDistribution(pCellId, 6) - a_oldDistribution(pCellId, 0);
3184 u[1] = a_oldDistribution(pCellId, 7) + a_oldDistribution(pCellId, 3) + a_oldDistribution(pCellId, 4)
3185 - a_oldDistribution(pCellId, 6) - a_oldDistribution(pCellId, 2) - a_oldDistribution(pCellId, 5);
3187 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
3188 for(
MInt d = 0; d < nDim; d++) {
3189 u[d] += a_oldDistribution(pCellId, Ld::pFld(d, j));
3190 u[d] -= a_oldDistribution(pCellId, Ld::nFld(d, j));
3195 for(
MInt j = 0; j < nDim; j++) {
3196 a_variable(pCellId, j) = u[j];
3200 std::array<MFloat, nDist> eqDist;
3201 eqDist = getEqDists(rho, u);
3204 for(
MInt j = 0; j < nDist; j++) {
3205 nonEqDist[j] = a_oldDistribution(pCellId, j) - eqDist[j];
3213 tau = F1B2 + 3.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId));
3216 calculateMomentumFlux(pCellId);
3220 for(
MInt k = 0; k < nDim * nDim; k++) {
3221 Q += m_momentumFlux[pCellId][k] * m_momentumFlux[pCellId][k];
3227 const MFloat aPlus = 26.0;
3228 MFloat tmpWidth = m_referenceLength * m_smallestCellLength;
3229 MFloat yPlus = m_ReTau * (1.0 - fabs(a_coordinate(pCellId, 1)) / tmpWidth);
3230 MFloat lambda = m_Cs * m_deltaX * (F1 - exp(-yPlus / aPlus));
3233 + 2.0 * SQRT2 * lambda * lambda * (F1BCSsq * F1BCSsq) * Q
3234 *
FPOW2(maxLevel() - this->a_level(pCellId)))
3239 + 2.0 * SQRT2 * m_Cs * m_Cs * m_deltaX * m_deltaX * (F1BCSsq * F1BCSsq) * Q
3240 *
FPOW2(maxLevel() - this->a_level(pCellId)))
3244 m_omega = 1.0 / tau;
3247 a_nu(pCellId) =
FPOW2(maxLevel() - this->a_level(pCellId)) * (tau - F1B2) / 3.0;
3252 for(
MInt j = 0; j < nDist; j++) {
3253 a_distribution(pCellId, j) = a_oldDistribution(pCellId, j) - m_omega * nonEqDist[j];
3260 actualCellLength = this->c_cellLengthAtLevel(this->a_level(pCellId));
3262 (F1B2 * m_arraySize[direction]
3263 + (a_coordinate(pCellId, direction) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
3267 S = F1B2 * F1BCSsq * m_omega * Q;
3270 if(pCellId < this->grid().noInternalCells()) {
3271 diss[index] += m_nu * S * S;
3272 SGSDiss[index] += m_Cs * m_Cs * m_deltaX * m_deltaX * S * S * S *
FPOW4(maxLevel() - this->a_level(pCellId));
3273 for(
MInt d = 0; d < nDim; d++) {
3274 energy += F1B2 * (a_variable(pCellId, d) * a_variable(pCellId, d));
3288 if(domainId() != 0) {
3289 MPI_Send(&(diss[0]), m_arraySize[direction], MPI_DOUBLE, 0, 0, mpiComm(), AT_,
"(diss[0])");
3290 MPI_Send(&(SGSDiss[0]), m_arraySize[direction], MPI_DOUBLE, 0, 0, mpiComm(), AT_,
"(SGSDiss[0])");
3291 MPI_Send(&energy, 1, MPI_DOUBLE, 0, 0, mpiComm(), AT_,
"energy");
3294 if(domainId() == 0) {
3297 for(
MInt i = 0; i < m_arraySize[direction]; i++) {
3298 totalDiss[i] = diss[i];
3299 totalSGSDiss[i] = SGSDiss[i];
3302 for(
MInt j = 1; j < noDomains(); j++) {
3303 MPI_Recv(&(diss[0]), m_arraySize[direction], MPI_DOUBLE, j, 0, mpiComm(), &status, AT_,
"(diss[0])");
3304 MPI_Recv(&(SGSDiss[0]), m_arraySize[direction], MPI_DOUBLE, j, 0, mpiComm(), &status, AT_,
"(SGSDiss[0])");
3305 MPI_Recv(&energy, 1, MPI_DOUBLE, j, 0, mpiComm(), &status, AT_,
"energy");
3306 for(
MInt i = 0; i < m_arraySize[direction]; i++) {
3307 totalDiss[i] += diss[i];
3308 totalSGSDiss[i] += SGSDiss[i];
3312 fileName =
"totalDiss_";
3316 m_log <<
"writing diss file: " << fileName << endl;
3317 ofl.
open(fileName.c_str(), ios_base::out);
3318 for(
MInt i = 0; i < m_arraySize[direction]; i++)
3319 ofl <<
globalTimeStep <<
" " << i <<
" " << totalDiss[i] <<
" " << totalSGSDiss[i] <<
" " << energy << endl;
3333template <MInt nDim, MInt nDist,
class SysEqn>
3337 updateMacroscopicVariables();
3338 for(
MInt i = 0; i < this->noInternalCells(); i++) {
3339 calculateMomentumFlux(i);
3341 calculateSGSTensors();
3343 std::vector<MFloat> dynamicCs;
3344 constexpr MInt direction = 1;
3346 averageSGSTensors(direction, count, dynamicCs);
3348 for(
MInt i = 0; i < count; i++) {
3349 if(dynamicCs[i] < 0.0) dynamicCs[i] = 0.0;
3360 MFloat actualCellLength = F0;
3367 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
3375 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
3377 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
3378 const MInt pCellId = m_activeCellList[i];
3381 rho = a_variable(pCellId, PV->RHO);
3383 for(
MInt d = 0; d < nDim; d++) {
3384 u[d] = a_variable(pCellId, d);
3388 std::array<MFloat, nDist> eqDist;
3389 eqDist = getEqDists(rho, u);
3391 for(
MInt j = 0; j < nDist; j++) {
3392 nonEqDist[j] = a_oldDistribution(pCellId, j) - eqDist[j];
3400 tau = F1B2 + 3.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId));
3404 for(
MInt k = 0; k < nDim * nDim; k++) {
3405 Q += m_momentumFlux[pCellId][k] * m_momentumFlux[pCellId][k];
3412 index = floor((F1B2 * count
3413 + (a_coordinate(pCellId, 1) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
3418 + 2.0 * SQRT2 * dynamicCs[index] * m_deltaX * m_deltaX * (F1BCSsq * F1BCSsq) * Q
3419 *
FPOW2(maxLevel() - this->a_level(pCellId)))
3422 m_omega = 1.0 / tau;
3425 a_nu(pCellId) =
FPOW2(maxLevel() - this->a_level(pCellId)) * (tau - F1B2) / 3.0;
3428 for(
MInt j = 0; j < nDist; j++) {
3429 a_distribution(pCellId, j) = a_oldDistribution(pCellId, j) - m_omega * nonEqDist[j];
3444template <MInt nDim, MInt nDist,
class SysEqn>
3448 const MInt pvrho = PV->RHO;
3450 constexpr MInt fldlen = Ld::dxQyFld();
3453 MFloat l_v[nDim] = {0.0};
3463 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
3473 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
3476 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
3477 const MInt pCellId = m_activeCellList[i];
3480 a_oldVariable(i, PV->RHO) = a_variable(i, PV->RHO);
3481 a_oldVariable(i, PV->U) = a_variable(i, PV->U);
3482 a_oldVariable(i, PV->V) = a_variable(i, PV->V);
3486 for(
MInt j = 0; j < nDist - 1; j++) {
3487 l_rho += a_oldDistribution(pCellId, j);
3490 l_rho += a_oldDistribution(pCellId, nDist - 1);
3496 if constexpr(nDim == 3) l_v[2] = F0;
3498 if constexpr(nDim == 2) {
3502 l_v[0] = a_oldDistribution(pCellId, 1) + a_oldDistribution(pCellId, 4) + a_oldDistribution(pCellId, 5)
3503 - a_oldDistribution(pCellId, 7) - a_oldDistribution(pCellId, 6) - a_oldDistribution(pCellId, 0);
3505 l_v[1] = a_oldDistribution(pCellId, 7) + a_oldDistribution(pCellId, 3) + a_oldDistribution(pCellId, 4)
3506 - a_oldDistribution(pCellId, 6) - a_oldDistribution(pCellId, 2) - a_oldDistribution(pCellId, 5);
3508 for(
MInt j = 0; j < fldlen; j++) {
3509 for(
MInt d = 0; d < nDim; d++) {
3510 l_v[d] += a_oldDistribution(pCellId, Ld::pFld(d, j));
3511 l_v[d] -= a_oldDistribution(pCellId, Ld::nFld(d, j));
3517 for(
MInt d = 0; d < nDim; d++) {
3518 a_variable(pCellId, d) = l_v[d];
3520 a_variable(pCellId, pvrho) = l_rho;
3522 calculateMomentumFlux(pCellId);
3526 for(
MInt k = 0; k < nDim * nDim; k++) {
3527 Q += m_momentumFlux[pCellId][k] * m_momentumFlux[pCellId][k];
3531 for(
MInt d = 0; d < nDim; d++) {
3532 l_v[d] = a_variable(pCellId, d);
3534 l_rho = a_variable(pCellId, pvrho);
3536 const MFloat sqVel = std::inner_product(&l_v[0], &l_v[nDim], &l_v[0], F0);
3538 std::array<MFloat, nDist> eqDist;
3539 eqDist = getEqDists(l_rho, sqVel, l_v);
3543 const MFloat l_omega = 2.0 / (1.0 + 6.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId)));
3546 for(
MInt j = 0; j < nDist; j++) {
3547 a_distribution(pCellId, j) =
3548 a_oldDistribution(pCellId, j) + l_omega * (eqDist[j] - a_oldDistribution(pCellId, j));
3552 for(
MInt j = 0; j < nDist; j++) {
3553 a_distribution(pCellId, j) = eqDist[j];
3563template <MInt nDim, MInt nDist,
class SysEqn>
3571 constexpr MInt nDimSqr = nDim * nDim;
3572 constexpr MInt direction = 1;
3581 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
3583 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
3584 const MInt pCellId = m_activeCellList[i];
3586 calculateMomentumFlux(pCellId);
3589 if(this->a_level(pCellId) < maxLevel())
continue;
3612 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FPOW2(maxLevel() - this->a_level(pCellId)));
3614 for(
MInt k = 0; k < nDimSqr; k++) {
3615 Sij[k] = -F1B2 * F1BCSsq * m_omega * m_momentumFlux[i][k];
3619 const MFloat Ssqr = 2.0 * std::inner_product(&Sij[0], &Sij[nDimSqr], &Sij[0], .0);
3620 const MFloat S = sqrt(Ssqr);
3623 const MInt actualCellLength = this->c_cellLengthAtLevel(this->a_level(pCellId));
3624 const MInt index = floor(
3625 (F1B2 * m_arraySize[direction]
3626 + (a_coordinate(pCellId, direction) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
3628 diss[index] += m_nu * Ssqr;
3629 SGSDiss[index] += m_Cs * m_Cs * m_deltaX * m_deltaX * S * S * S *
FPOW4(maxLevel() - this->a_level(pCellId));
3633 for(
MInt k = 0; k < nDim; k++) {
3634 tmp += a_variable(pCellId, k) * a_variable(pCellId, k);
3636 energy += F1B2 * tmp;
3640 constexpr MInt rootId = 0;
3641 MPI_Reduce(MPI_IN_PLACE, &diss[0], m_arraySize[direction], MPI_DOUBLE, MPI_SUM, rootId, mpiComm(), AT_,
3642 "MPI_IN_PLACE",
"diss");
3643 MPI_Reduce(MPI_IN_PLACE, &SGSDiss[0], m_arraySize[direction], MPI_DOUBLE, MPI_SUM, rootId, mpiComm(), AT_,
3644 "MPI_IN_PLACE",
"SGSDiss");
3645 MPI_Reduce(MPI_IN_PLACE, &energy, m_arraySize[direction], MPI_DOUBLE, MPI_SUM, rootId, mpiComm(), AT_,
"MPI_IN_PLACE",
3649 if(domainId() == rootId) {
3651 MString fileName =
"totalDiss_";
3656 m_log <<
"writing diss file: " << fileName << endl;
3657 ofl.
open(fileName.c_str(), ios_base::out);
3658 for(
MInt i = 0; i < m_arraySize[direction]; i++)
3659 ofl <<
globalTimeStep <<
" " << i <<
" " << diss[i] <<
" " << SGSDiss[i] <<
" " << energy << endl;
3674template <MInt nDim, MInt nDist,
class SysEqn>
3675template <MBool optimized, MBool useSmagorinsky>
3677 TERMM(1,
"MRT collision step only available for D2Q9 and D3Q19 !");
3681template <MBool optimized, MBool useSmagorinsky>
3684 constexpr MInt nDist = 9;
3687 constexpr MFloat c1 = -2.0, alpha2 = -8.0, alpha3 = 4.0, gamma1 = F2B3, gamma3 = F2B3, gamma2 = 18.0, gamma4 = -18.0;
3689 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
3690 const MInt pCellId = m_activeCellList[i];
3691 const MInt lvlDiff = maxLevel() - this->a_level(pCellId);
3693 std::array<MFloat, nDist> d{};
3694 for(
MInt j = 0; j < nDist; j++) {
3695 d[j] = a_oldDistribution(pCellId, j);
3698 std::array<MFloat, nDist> m{};
3699 m[0] = d[8] + d[1] + d[3] + d[0] + d[2] + d[4] + d[7] + d[6] + d[5];
3700 m[1] = -4 * d[8] - d[1] - d[3] - d[0] - d[2] + 2 * (d[4] + d[7] + d[6] + d[5]);
3701 m[2] = 4 * d[8] + 2 * (-d[1] - d[3] - d[0] - d[2]) + d[4] + d[7] + d[6] + d[5];
3702 m[3] = d[1] - d[0] + d[4] - d[7] - d[6] + d[5];
3703 m[4] = -2 * (d[1] - d[0]) + d[4] - d[7] - d[6] + d[5];
3704 m[5] = d[3] - d[2] + d[4] + d[7] - d[6] - d[5];
3705 m[6] = -2 * (d[3] - d[2]) + d[4] + d[7] - d[6] - d[5];
3706 m[7] = d[1] - d[3] + d[0] - d[2];
3707 m[8] = d[4] - d[7] + d[6] - d[5];
3711 std::array<MFloat, nDist> omega{};
3718 omega[7] = (2.0 - c1) / (12.0 * a_nu(pCellId) *
FFPOW2(lvlDiff) + 1.0 - c1 / 2.0);
3719 omega[8] = 1.0 / ((2.0 / omega[7] - 1.0) * ((c1 + 4.0) / (2.0 - c1)) + 0.5);
3720 omega[4] = 3.0 * (2.0 - omega[7]) / (3.0 - omega[7]);
3723 std::array<MFloat, nDist> EqM{};
3727 EqM[1] = 0.25 * alpha2 * m[0] + F1B6 * gamma2 * (m[3] * m[3] + m[5] * m[5]);
3728 EqM[2] = 0.25 * alpha3 * m[0] + F1B6 * gamma4 * (m[3] * m[3] + m[5] * m[5]);
3729 EqM[4] = 0.5 * c1 * m[3];
3730 EqM[6] = 0.5 * c1 * m[5];
3731 EqM[7] = F3B2 * gamma1 * (m[3] * m[3] - m[5] * m[5]);
3732 EqM[8] = F3B2 * gamma3 * (m[3] * m[5]);
3735 for(
MInt j = 0; j < nDist; j++) {
3736 m[j] = m[j] - omega[j] * (m[j] - EqM[j]);
3739 a_distribution(pCellId, 8) = F1B9 * m[0] - F1B9 * m[1] + F1B9 * m[2];
3740 a_distribution(pCellId, 1) = F1B9 * m[0] - F1B36 * m[1] - F1B18 * m[2] + F1B6 * m[3] - F1B6 * m[4] + F1B4 * m[7];
3741 a_distribution(pCellId, 3) = F1B9 * m[0] - F1B36 * m[1] - F1B18 * m[2] + F1B6 * m[5] - F1B6 * m[6] - F1B4 * m[7];
3742 a_distribution(pCellId, 0) = F1B9 * m[0] - F1B36 * m[1] - F1B18 * m[2] - F1B6 * m[3] + F1B6 * m[4] + F1B4 * m[7];
3743 a_distribution(pCellId, 2) = F1B9 * m[0] - F1B36 * m[1] - F1B18 * m[2] - F1B6 * m[5] + F1B6 * m[6] - F1B4 * m[7];
3744 a_distribution(pCellId, 4) = F1B9 * m[0] + F1B18 * m[1] + F1B36 * m[2] + F1B6 * m[3] + F1B12 * m[4] + F1B6 * m[5]
3745 + F1B12 * m[6] + F1B4 * m[8];
3746 a_distribution(pCellId, 7) = F1B9 * m[0] + F1B18 * m[1] + F1B36 * m[2] - F1B6 * m[3] - F1B12 * m[4] + F1B6 * m[5]
3747 + F1B12 * m[6] - F1B4 * m[8];
3748 a_distribution(pCellId, 6) = F1B9 * m[0] + F1B18 * m[1] + F1B36 * m[2] - F1B6 * m[3] - F1B12 * m[4] - F1B6 * m[5]
3749 - F1B12 * m[6] + F1B4 * m[8];
3750 a_distribution(pCellId, 5) = F1B9 * m[0] + F1B18 * m[1] + F1B36 * m[2] + F1B6 * m[3] + F1B12 * m[4] - F1B6 * m[5]
3751 - F1B12 * m[6] - F1B4 * m[8];
3757template <MBool optimized, MBool useSmagorinsky>
3760 constexpr MInt nDist = 19;
3761 constexpr MInt nDim = 3;
3762 constexpr MInt nDimSqr = nDim * nDim;
3764 const MFloat rho_offset = (m_densityFluctuations) ? 1.0 : 0.0;
3767 [[maybe_unused]]
const MFloat tmpWidth = m_referenceLength * m_smallestCellLength;
3768 [[maybe_unused]]
constexpr MFloat aPlus = 26.0;
3770 for(
MInt id = 0;
id < m_currentMaxNoCells;
id++) {
3771 const MInt pCellId = m_activeCellList[
id];
3774 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
3777 for(
MInt j = 0; j < nDist; j++) {
3778 d[j] = a_oldDistribution(pCellId, j);
3782 for(
MInt j = 0; j < nDim + 1; j++) {
3783 a_oldVariable(pCellId, j) = a_variable(pCellId, j);
3787 m[0] = d[18] + d[1] + d[0] + d[3] + d[2] + d[5] + d[4] + d[9] + d[7] + d[8] + d[6] + d[13] + d[11] + d[12] + d[10]
3788 + d[17] + d[15] + d[16] + d[14];
3789 m[1] = -30 * d[18] - 11 * (d[1] + d[0] + d[3] + d[2] + d[5] + d[4])
3790 + 8 * (d[9] + d[7] + d[8] + d[6] + d[13] + d[11] + d[12] + d[10] + d[17] + d[15] + d[16] + d[14]);
3791 m[2] = 12 * d[18] - 4 * (d[1] + d[0] + d[3] + d[2] + d[5] + d[4]) + d[9] + d[7] + d[8] + d[6] + d[13] + d[11]
3792 + d[12] + d[10] + d[17] + d[15] + d[16] + d[14];
3793 m[3] = d[1] - d[0] + d[9] - d[7] + d[8] - d[6] + d[13] - d[11] + d[12] - d[10];
3794 m[4] = -4 * (d[1] - d[0]) + d[9] - d[7] + d[8] - d[6] + d[13] - d[11] + d[12] - d[10];
3795 m[5] = d[3] - d[2] + d[9] + d[7] - d[8] - d[6] + d[17] - d[15] + d[16] - d[14];
3796 m[6] = -4 * (d[3] - d[2]) + d[9] + d[7] - d[8] - d[6] + d[17] - d[15] + d[16] - d[14];
3797 m[7] = d[5] - d[4] + d[13] + d[11] - d[12] - d[10] + d[17] + d[15] - d[16] - d[14];
3798 m[8] = -4 * (d[5] - d[4]) + d[13] + d[11] - d[12] - d[10] + d[17] + d[15] - d[16] - d[14];
3799 m[9] = 2 * (d[1] + d[0] - d[15] - d[16] - d[14]) - d[3] - d[2] - d[5] - d[4] + d[9] + d[7] + d[8] + d[6] + d[13]
3800 + d[11] + d[12] + d[10] - 2 * d[17];
3801 m[10] = -4 * (d[1] + d[0]) + 2 * (d[3] + d[2] + d[5] + d[4] - d[17] - d[15] - d[16] - d[14]) + d[9] + d[7] + d[8]
3802 + d[6] + d[13] + d[11] + d[12] + d[10];
3803 m[11] = d[3] + d[2] - d[5] - d[4] + d[9] + d[7] + d[8] + d[6] - d[13] - d[11] - d[12] - d[10];
3804 m[12] = -2 * (d[3] + d[2] - d[5] - d[4]) + d[9] + d[7] + d[8] + d[6] - d[13] - d[11] - d[12] - d[10];
3805 m[13] = d[9] - d[7] - d[8] + d[6];
3806 m[14] = d[17] - d[15] - d[16] + d[14];
3807 m[15] = d[13] - d[11] - d[12] + d[10];
3808 m[16] = d[9] - d[7] + d[8] - d[6] - d[13] + d[11] - d[12] + d[10];
3809 m[17] = -d[9] - d[7] + d[8] + d[6] + d[17] - d[15] + d[16] - d[14];
3810 m[18] = d[13] + d[11] - d[12] - d[10] - d[17] - d[15] + d[16] + d[14];
3815 const MFloat tmp = (optimized) ? 0.0 : 1.0;
3825 P[9] = 2.0 / (
FFPOW2(maxLevel() - this->a_level(pCellId)) * 6.0 * m_nu + 1.0);
3846 EqM[1] = -11.0 * m[0] + 19.0 * (m[3] * m[3] + m[5] * m[5] + m[7] * m[7]) / (m[0] + rho_offset);
3848 if constexpr(optimized) {
3849 EqM[2] = -F475B63 * (m[3] * m[3] + m[5] * m[5] + m[7] * m[7]) / (m[0] + rho_offset);
3851 EqM[2] = 3.0 * m[0] - 5.5 * (m[3] * m[3] + m[5] * m[5] + m[7] * m[7]) / (m[0] + rho_offset);
3854 EqM[4] = -F2B3 * m[3];
3855 EqM[6] = -F2B3 * m[5];
3856 EqM[8] = -F2B3 * m[7];
3858 EqM[9] = (2 * m[3] * m[3] - (m[5] * m[5] + m[7] * m[7])) / (m[0] + rho_offset);
3860 if constexpr(optimized) {
3863 EqM[10] = -0.5 * EqM[9];
3865 EqM[11] = (m[5] * m[5] - m[7] * m[7]) / (m[0] + rho_offset);
3866 if constexpr(optimized) {
3869 EqM[12] = -0.5 * EqM[11];
3871 EqM[13] = m[3] * m[5] / (m[0] + rho_offset);
3872 EqM[14] = m[5] * m[7] / (m[0] + rho_offset);
3873 EqM[15] = m[3] * m[7] / (m[0] + rho_offset);
3902 a_variable(pCellId, PV->RHO) = EqM[0];
3903 for(
MInt i = 0; i < nDim; i++) {
3904 a_variable(pCellId, PV->VV[i]) = EqM[3 + i * 2] / EqM[0];
3908 if constexpr(useSmagorinsky) {
3911#ifdef WAR_NVHPC_PSTL
3914 for(
MInt dir = 0; dir < nDist; dir++) {
3915 dist[dir] = a_oldDistribution(pCellId, dir);
3917 for(
MInt dir = 0; dir < nDim; dir++) {
3918 u[dir] = a_variable(pCellId, dir);
3920 MFloat l_rho = a_variable(pCellId, PV->RHO);
3921 lbfunc::calcNonEqDists<nDim, nDist>(l_rho, u,
dist, &nonEq[0]);
3923 lbfunc::calcNonEqDists<nDim, nDist>(a_variable(pCellId, PV->RHO), &a_variable(pCellId, PV->U),
3924 &a_oldDistribution(pCellId, 0), &nonEq[0]);
3928 const MFloat yPlus = m_ReTau * (1.0 - fabs(a_coordinate(pCellId, 1)) / tmpWidth);
3929 const MFloat lambda = m_Cs * m_deltaX * (F1 - exp(-yPlus / aPlus));
3933 c[0] = (nonEq[0] + nonEq[1] + nonEq[6] + nonEq[7] + nonEq[8] + nonEq[9] + nonEq[10] + nonEq[11] + nonEq[12]
3935 c[1] = (nonEq[6] - nonEq[7] - nonEq[8] + nonEq[9]);
3936 c[2] = (nonEq[10] - nonEq[11] - nonEq[12] + nonEq[13]);
3938 c[4] = (nonEq[2] + nonEq[3] + nonEq[6] + nonEq[7] + nonEq[8] + nonEq[9] + nonEq[14] + nonEq[15] + nonEq[16]
3940 c[5] = (nonEq[14] - nonEq[15] - nonEq[16] + nonEq[17]);
3943 c[8] = (nonEq[4] + nonEq[5] + nonEq[10] + nonEq[11] + nonEq[12] + nonEq[13] + nonEq[14] + nonEq[15] + nonEq[16]
3947 const MFloat Q = sqrt(2.0 * std::inner_product(&c[0], &c[nDimSqr], &c[0], .0));
3951 MFloat tau = F1B2 + 3.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId));
3955 + 2.0 * SQRT2 * lambda * lambda * (F1BCSsq * F1BCSsq) * Q
3956 *
FPOW2(maxLevel() - this->a_level(pCellId)))
3959 m_omega = 1.0 / tau;
3962 a_nu(pCellId) =
FPOW2(maxLevel() - this->a_level(pCellId)) * (tau - F1B2) / 3.0;
3969 for(
MInt i = 0; i < nDist; i++) {
3970 m[i] = m[i] - P[i] * (m[i] - EqM[i]);
3973 const MFloat ra = F1B19 * m[0];
3974 const MFloat rb = F11B2394 * m[1];
3975 const MFloat rc = F1B63 * m[2];
3976 const MFloat rd = F4B1197 * m[1];
3977 const MFloat re = F1B252 * m[2];
3978 const MFloat rf = F1B12 * m[11];
3979 const MFloat rg = F1B24 * m[12];
3980 const MFloat rh = 0.25 * m[13];
3981 const MFloat ri = 0.25 * m[15];
3982 const MFloat rj = F1B36 * m[9];
3983 const MFloat rk = 2.0 * rj;
3984 const MFloat rl = F1B72 * m[10];
3985 const MFloat rm = 2.0 * rl;
3986 const MFloat rn = 0.1 * (m[3] - m[4]);
3987 const MFloat ro = 0.1 * (m[5] - m[6]);
3988 const MFloat rp = 0.1 * (m[7] - m[8]);
3989 const MFloat rq = F1B18 * (m[9] - m[10]);
3990 const MFloat rr = F1B12 * (m[11] - m[12]);
3991 const MFloat rs = 0.25e-1 * (m[4] + m[6]);
3992 const MFloat rt = 0.25e-1 * (m[4] - m[6]);
3993 const MFloat ru = 0.25e-1 * (m[4] - m[8]);
3994 const MFloat rv = 0.25e-1 * (m[4] + m[8]);
3995 const MFloat rw = 0.25e-1 * (m[6] + m[8]);
3996 const MFloat rx = 0.25e-1 * (m[6] - m[8]);
3997 const MFloat ry = 0.125 * (m[16] - m[17]);
3998 const MFloat rz = 0.125 * (m[16] + m[17]);
3999 const MFloat r0 = 0.125 * (m[16] - m[18]);
4000 const MFloat r1 = 0.125 * (m[16] + m[18]);
4001 const MFloat r2 = 0.125 * (m[17] + m[18]);
4002 const MFloat r3 = 0.125 * (m[17] - m[18]);
4003 const MFloat r4 = 0.1 * (m[5] + m[7]);
4004 const MFloat r5 = 0.1 * (m[5] - m[7]);
4005 const MFloat r6 = 0.1 * (m[3] + m[5]);
4006 const MFloat r7 = 0.1 * (m[3] - m[5]);
4007 const MFloat r8 = 0.5 * rq;
4008 const MFloat r9 = 0.1 * (m[3] + m[7]);
4009 const MFloat r10 = 0.1 * (m[3] - m[7]);
4010 const MFloat r11 = 0.25 * m[14];
4051 a_distribution(pCellId, 18) = ra - F5B399 * m[1] + F1B21 * m[2];
4052 a_distribution(pCellId, 1) = ra - rb - rc + rn + rq;
4053 a_distribution(pCellId, 0) = ra - rb - rc - rn + rq;
4054 a_distribution(pCellId, 3) = ra - rb - rc + ro - r8 + rr;
4055 a_distribution(pCellId, 2) = ra - rb - rc - ro - r8 + rr;
4056 a_distribution(pCellId, 5) = ra - rb - rc + rp - r8 - rr;
4057 a_distribution(pCellId, 4) = ra - rb - rc - rp - r8 - rr;
4058 a_distribution(pCellId, 9) = ra + rd + re + r6 + rs + rj + rl + rf + rg + rh + ry;
4059 a_distribution(pCellId, 7) = ra + rd + re - r7 - rt + rj + rl + rf + rg - rh - rz;
4060 a_distribution(pCellId, 8) = ra + rd + re + r7 + rt + rj + rl + rf + rg - rh + rz;
4061 a_distribution(pCellId, 6) = ra + rd + re - r6 - rs + rj + rl + rf + rg + rh - ry;
4062 a_distribution(pCellId, 13) = ra + rd + re + r9 + rv + rj + rl - rf - rg + ri - r0;
4063 a_distribution(pCellId, 11) = ra + rd + re - r10 - ru + rj + rl - rf - rg - ri + r1;
4064 a_distribution(pCellId, 12) = ra + rd + re + r10 + ru + rj + rl - rf - rg - ri - r1;
4065 a_distribution(pCellId, 10) = ra + rd + re - r9 - rv + rj + rl - rf - rg + ri + r0;
4066 a_distribution(pCellId, 17) = ra + rd + re + r4 + rw - rk - rm + r11 + r3;
4067 a_distribution(pCellId, 15) = ra + rd + re - r5 - rx - rk - rm - r11 - r2;
4068 a_distribution(pCellId, 16) = ra + rd + re + r5 + rx - rk - rm - r11 + r2;
4069 a_distribution(pCellId, 14) = ra + rd + re - r4 - rw - rk - rm + r11 - r3;
4073 if(m_calculateDissipation &&
globalTimeStep % m_solutionInterval == 0) {
4074 calculateDissipation();
4088template <MInt nDim, MInt nDist,
class SysEqn>
4090 mrt_collision_step_base<false, false>();
4103template <MInt nDim, MInt nDist,
class SysEqn>
4105 mrt_collision_step_base<true, false>();
4120template <MInt nDim, MInt nDist,
class SysEqn>
4122 if constexpr(nDim == 3 || nDist == 19) {
4123 mrt_collision_step_base<false, true>();
4125 TERMM(1,
"MRT_SMAGORINSKY collision step only available for D3Q19!");
4129template <MInt nDim, MInt nDist,
class SysEqn>
4130template <MBool useSmagorinsky>
4139 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
4147 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
4149 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
4150 const MInt pCellId = m_activeCellList[i];
4154 a_nu(pCellId) = m_nu;
4156 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId)));
4157 swap_variables(pCellId);
4160 a_variable(pCellId, PV->RHO) = 0.0;
4161 for(
MInt j = 0; j < nDist; j++) {
4162 a_variable(pCellId, PV->RHO) += a_oldDistribution(pCellId, j);
4165 const MFloat rho = a_variable(pCellId, PV->RHO);
4168 for(
MInt j = 0; j < nDim; j++) {
4172 if constexpr(nDim == 2) {
4176 u[0] = a_oldDistribution(pCellId, 1) + a_oldDistribution(pCellId, 4) + a_oldDistribution(pCellId, 5)
4177 - a_oldDistribution(pCellId, 7) - a_oldDistribution(pCellId, 6) - a_oldDistribution(pCellId, 0);
4179 u[1] = a_oldDistribution(pCellId, 7) + a_oldDistribution(pCellId, 3) + a_oldDistribution(pCellId, 4)
4180 - a_oldDistribution(pCellId, 6) - a_oldDistribution(pCellId, 2) - a_oldDistribution(pCellId, 5);
4182 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
4183 for(
MInt d = 0; d < nDim; d++) {
4184 u[d] += a_oldDistribution(pCellId, Ld::pFld(d, j));
4185 u[d] -= a_oldDistribution(pCellId, Ld::nFld(d, j));
4190 for(
MInt j = 0; j < nDim; j++) {
4191 a_variable(pCellId, j) = u[j];
4195 std::array<MFloat, nDist> eqDist;
4196 eqDist = getEqDists(rho, u);
4202 calculateMomentumFlux(pCellId);
4204 if constexpr(useSmagorinsky) {
4209 MFloat tau = F1B2 + 3.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId));
4213 for(
MInt l = 0; l < nDim * nDim; l++) {
4214 Q += m_momentumFlux[pCellId][l] * m_momentumFlux[pCellId][l];
4221 + 2.0 * SQRT2 * m_Cs * m_Cs * m_deltaX * m_deltaX * (F1BCSsq * F1BCSsq) * Q
4222 *
FPOW2(maxLevel() - this->a_level(pCellId)))
4225 m_omega = 1.0 / tau;
4228 a_nu(pCellId) =
FPOW2(maxLevel() - this->a_level(pCellId)) * (tau - F1B2) / 3.0;
4234 if constexpr(nDim == 2) {
4235 trace = m_momentumFlux[pCellId][0] + m_momentumFlux[pCellId][3];
4237 trace = m_momentumFlux[pCellId][0] + m_momentumFlux[pCellId][4] + m_momentumFlux[pCellId][8];
4240 for(
MInt j = 0; j < nDist - 1; j++) {
4241 const MInt t = Ld::tp(Ld::distType(j));
4243 a_distribution(pCellId, j) = eqDist[j] - (1.0 - m_omega) * t * F1BCSsq * F1B2 * trace;
4245 for(
MInt k = 0; k < nDim; k++) {
4246 for(
MInt l = 0; l < nDim; l++) {
4247 a_distribution(pCellId, j) += (1.0 - m_omega) * t * F1BCSsq * F1BCSsq * F1B2 * (Ld::idFld(j, k) - 1)
4248 * (Ld::idFld(j, l) - 1) * m_momentumFlux[pCellId][l + nDim * k];
4253 a_distribution(pCellId, Ld::lastId()) =
4254 eqDist[Ld::lastId()] - (1.0 - m_omega) * Ld::tp(0) * F1BCSsq * F1B2 * trace;
4258 if(m_calculateDissipation &&
globalTimeStep % m_solutionInterval == 0) {
4259 calculateDissipation();
4269template <MInt nDim, MInt nDist,
class SysEqn>
4271 rbgk_collision_step_base<false>();
4280template <MInt nDim, MInt nDist,
class SysEqn>
4282 rbgk_collision_step_base<true>();
4291template <MInt nDim, MInt nDist,
class SysEqn>
4295 updateMacroscopicVariables();
4296 for(
MInt i = 0; i < this->noInternalCells(); i++) {
4297 calculateMomentumFlux(i);
4299 calculateSGSTensors();
4301 std::vector<MFloat> dynamicCs;
4302 constexpr MInt direction = 1;
4304 averageSGSTensors(direction, count, dynamicCs);
4306 for(
MInt i = 0; i < count; i++) {
4307 if(dynamicCs[i] < 0.0) dynamicCs[i] = 0.0;
4319 MFloat actualCellLength = F0;
4333 for(
MInt i = 0; i < count; i++) {
4344 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
4352 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
4354 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
4355 const MInt pCellId = m_activeCellList[i];
4358 rho = a_variable(pCellId, PV->RHO);
4360 for(
MInt d = 0; d < nDim; d++) {
4361 u[d] = a_variable(pCellId, d);
4365 std::array<MFloat, nDist> eqDist;
4366 eqDist = getEqDists(rho, u);
4373 tau = F1B2 + 3.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId));
4377 for(
MInt k = 0; k < nDim * nDim; k++) {
4378 Q += m_momentumFlux[pCellId][k] * m_momentumFlux[pCellId][k];
4386 + (a_coordinate(pCellId, direction) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
4391 + 2.0 * SQRT2 * dynamicCs[index] * m_deltaX * m_deltaX * (F1BCSsq * F1BCSsq) * Q
4392 *
FPOW2(maxLevel() - this->a_level(pCellId)))
4395 m_omega = 1.0 / tau;
4398 a_nu(pCellId) =
FPOW2(maxLevel() - this->a_level(pCellId)) * (tau - F1B2) / 3.0;
4405 if constexpr(nDim == 2) {
4406 trace = m_momentumFlux[pCellId][0] + m_momentumFlux[pCellId][3];
4408 trace = m_momentumFlux[pCellId][0] + m_momentumFlux[pCellId][4] + m_momentumFlux[pCellId][8];
4411 for(
MInt j = 0; j < (nDist - 1); j++) {
4413 if(j < Ld::distFld(0)) {
4415 }
else if(j < Ld::distFld(1) + Ld::distFld(0)) {
4421 a_distribution(pCellId, j) = eqDist[j] - (1.0 - m_omega) * t * F1BCSsq * F1B2 * trace;
4423 for(
MInt k = 0; k < nDim; k++) {
4424 for(
MInt l = 0; l < nDim; l++) {
4425 a_distribution(pCellId, j) += (1.0 - m_omega) * t * F1BCSsq * F1BCSsq * F1B2 * (Ld::idFld(j, k) - 1)
4426 * (Ld::idFld(j, l) - 1) * m_momentumFlux[pCellId][l + nDim * k];
4431 a_distribution(pCellId, Ld::lastId()) =
4432 eqDist[Ld::lastId()] - (1.0 - m_omega) * Ld::tp(0) * F1BCSsq * F1B2 * trace;
4438 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId)));
4439 S = -F1B2 * F1BCSsq * m_omega * Q;
4442 diss[index] += m_nu * S * S;
4443 SGSDiss[index] += dynamicCs[index] * m_deltaX * m_deltaX * S * S * S *
FPOW4(maxLevel() - this->a_level(pCellId));
4444 for(
MInt d = 0; d < nDim; d++) {
4445 energy += F1B2 * (a_variable(pCellId, d) * a_variable(pCellId, d));
4452 if(m_calculateDissipation &&
globalTimeStep % m_solutionInterval == 0) {
4458 if(domainId() != 0) {
4459 MPI_Send(&(diss[0]), count, MPI_DOUBLE, 0, 0, mpiComm(), AT_,
"(diss[0])");
4460 MPI_Send(&(SGSDiss[0]), count, MPI_DOUBLE, 0, 0, mpiComm(), AT_,
"(SGSDiss[0])");
4461 MPI_Send(&energy, 1, MPI_DOUBLE, 0, 0, mpiComm(), AT_,
"energy");
4464 if(domainId() == 0) {
4467 for(
MInt i = 0; i < count; i++) {
4468 totalDiss[i] = diss[i];
4469 totalSGSDiss[i] = SGSDiss[i];
4472 for(
MInt j = 1; j < noDomains(); j++) {
4473 MPI_Recv(&(diss[0]), count, MPI_DOUBLE, j, 0, mpiComm(), &status, AT_,
"(diss[0])");
4474 MPI_Recv(&(SGSDiss[0]), count, MPI_DOUBLE, j, 0, mpiComm(), &status, AT_,
"(SGSDiss[0])");
4475 MPI_Recv(&energy, 1, MPI_DOUBLE, j, 0, mpiComm(), &status, AT_,
"energy");
4476 for(
MInt i = 0; i < count; i++) {
4477 totalDiss[i] += diss[i];
4478 totalSGSDiss[i] += SGSDiss[i];
4482 fileName =
"totalDiss_";
4486 m_log <<
"writing diss file: " << fileName << endl;
4487 ofl.
open(fileName.c_str(), ios_base::out);
4488 for(
MInt i = 0; i < count; i++)
4489 ofl <<
globalTimeStep <<
" " << i <<
" " << totalDiss[i] <<
" " << totalSGSDiss[i] <<
" " << energy << endl;
4504template <MInt nDim, MInt nDist,
class SysEqn>
4509 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
4510 const MInt pCellId = m_activeCellList[i];
4513 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
4515 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FFPOW2(maxLevel() - this->a_level(pCellId)));
4517 swap_variables(pCellId);
4520 a_variable(pCellId, PV->RHO) = 0.0;
4521 for(
MInt j = 0; j < nDist; j++) {
4522 a_variable(pCellId, PV->RHO) += a_oldDistribution(pCellId, j);
4525 const MFloat rho = a_variable(pCellId, PV->RHO);
4527 for(
MInt d = 0; d < nDim; d++) {
4528 u[d] = a_variable(pCellId, d);
4532 std::array<MFloat, nDist> eqDist;
4533 eqDist = getEqDists(rho, u);
4538 calculateMomentumFlux(pCellId);
4543 if constexpr(nDim == 2) {
4544 trace = m_momentumFlux[pCellId][0] + m_momentumFlux[pCellId][3];
4546 trace = m_momentumFlux[pCellId][0] + m_momentumFlux[pCellId][4] + m_momentumFlux[pCellId][8];
4549 for(
MInt j = 0; j < (nDist - 1); j++) {
4550 const MFloat t = Ld::tp(Ld::distType(j));
4552 a_distribution(pCellId, j) = eqDist[j] - (1.0 - m_omega) * t * F1BCSsq * F1B2 * trace;
4554 for(
MInt k = 0; k < nDim; k++) {
4555 for(
MInt l = 0; l < nDim; l++) {
4556 a_distribution(pCellId, j) += (1.0 - m_omega) * t * F1BCSsq * F1BCSsq * F1B2 * (Ld::idFld(j, k) - 1)
4557 * (Ld::idFld(j, l) - 1) * m_momentumFlux[pCellId][l + nDim * k];
4562 a_distribution(pCellId, Ld::lastId()) =
4563 eqDist[Ld::lastId()] - (1.0 - m_omega) * Ld::tp(0) * F1BCSsq * F1B2 * trace;
4577template <MInt nDim, MInt nDist,
class SysEqn>
4579 std::vector<MFloat>& meanTensors) {
4631 const MInt(&tmpCt)[nDim] = m_arraySize;
4632 count = tmpCt[direction];
4636 meanTensors.resize(tmpCt[direction]);
4638 for(
MInt i = 0; i < tmpCt[direction]; i++) {
4641 meanTensors[i] = F0;
4645 for(
MInt i = 0; i < this->grid().noInternalCells(); i++) {
4646 const MFloat actualCellLength = this->grid().cellLengthAtCell(i);
4652 floor((F1B2 * tmpCt[direction]
4653 + (a_coordinate(i, direction) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
4656 if(index < 0 || index >= tmpCt[direction]) {
4657 cerr <<
"error: index=" << index << endl;
4658 m_log <<
"error: index=" << index << endl;
4661 ML[index] += m_MijLij[i];
4662 MM[index] += m_MijMij[i];
4665 m_log.precision(12);
4668 MPI_Allreduce(MPI_IN_PLACE, MM.
data(), count, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"MM");
4669 MPI_Allreduce(MPI_IN_PLACE, ML.
data(), count, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"ML");
4678 for(
MInt i = 2; i < tmpCt[direction] - 2; i++) {
4679 if(MM[i] > 1e-12) meanTensors[i] = ML[i] / MM[i];
4688template <MInt nDim, MInt nDist,
class SysEqn>
4697 m_Re = m_initRe + scale * (m_finalRe - m_initRe);
4706 const MInt maxLevel_ = maxLevel();
4708 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
4709 if(m_cells.saveOldNu()) {
4710 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt index) {
4711 const MInt pCellId = m_activeCellList[index];
4712 const MInt lvlDiff = maxLevel_ - a_level(pCellId);
4713 if((gTS - 1) %
IPOW2(lvlDiff) != 0)
return;
4714 this->a_oldNu(pCellId) = a_nu(pCellId);
4715 a_nu(pCellId) = m_nu;
4718 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt index) {
4719 const MInt pCellId = m_activeCellList[index];
4720 const MInt lvlDiff = maxLevel_ - a_level(pCellId);
4721 if((gTS - 1) %
IPOW2(lvlDiff) != 0)
return;
4722 a_nu(pCellId) = m_nu;
4729template <MInt nDim, MInt nDist,
class SysEqn>
4733 for(
MInt i = 0; i < m_currentMaxNoCells; i++) {
4734 const MInt pCellId = m_activeCellList[i];
4735 swap_variables(pCellId);
4738 a_variable(pCellId, PV->RHO) = 0.0;
4739 for(
MInt j = 0; j < nDist; j++) {
4740 a_variable(pCellId, PV->RHO) += a_oldDistribution(pCellId, j);
4742 for(
MInt d = 0; d < nDim; d++) {
4743 a_variable(pCellId, PV->U + d) = 0.0;
4744 for(
MInt j = 0; j < Ld::dxQyFld(); j++) {
4745 a_variable(pCellId, PV->U + d) += a_oldDistribution(pCellId, Ld::pFld(d, j));
4746 a_variable(pCellId, PV->U + d) -= a_oldDistribution(pCellId, Ld::nFld(d, j));
4760template <MInt nDim, MInt nDist,
class SysEqn>
4764 constexpr MFloat coefficients[4] = {F1B8, F1B16, F1B32, F1B64};
4765 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
4767 for(
MInt id = 0;
id < this->grid().noInternalCells();
id++) {
4772 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FPOW2(maxLevel() - this->a_level(
id)));
4774 for(
MInt k = 0; k < 9; k++) {
4775 Sij[k] = -F1B2 * F1BCSsq * m_omega * m_momentumFlux[
id][k];
4778 MFloat S = sqrt(2.0 * std::inner_product(&Sij[0], &Sij[9], &Sij[0], .0));
4783 for(
MInt j = 0; j < 9; j++) {
4784 Mij[j] += coefficients[0] * 2.0 * m_deltaX * m_deltaX * S * Sij[j];
4785 SijTilde[j] += coefficients[0] * Sij[j];
4788 for(
MInt k = 0; k < 3; k++) {
4789 for(
MInt l = 0; l < 3; l++) {
4790 uuTilde[l + 3 * k] += coefficients[0] * a_variable(
id, k) * a_variable(
id, l);
4794 for(
MInt k = 0; k < 3; k++) {
4795 uTilde[k] += coefficients[0] * a_variable(
id, k);
4797 MFloat STilde = coefficients[0] * S;
4802 for(
MInt j = 0; j < Ld::distFld(0); j++) {
4803 if(!a_hasNeighbor(
id, j))
continue;
4805 const MInt currentNghbr = c_neighborId(
id, j);
4808 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FPOW2(maxLevel() - this->a_level(currentNghbr)));
4809 for(
MInt k = 0; k < 9; k++) {
4810 Sij[k] = -F1B2 * F1BCSsq * m_omega * m_momentumFlux[currentNghbr][k];
4813 S = sqrt(2.0 * std::inner_product(&Sij[0], &Sij[9], &Sij[0], .0));
4816 for(
MInt k = 0; k < 9; k++) {
4817 Mij[k] += coefficients[1] * 2.0 * m_deltaX * m_deltaX * S * Sij[k];
4818 SijTilde[k] += coefficients[1] * Sij[k];
4820 for(
MInt k = 0; k < 3; k++) {
4821 for(
MInt l = 0; l < 3; l++) {
4822 uuTilde[l + 3 * k] += coefficients[1] * a_variable(
id, k) * a_variable(
id, l);
4825 for(
MInt k = 0; k < 3; k++) {
4826 uTilde[k] += coefficients[1] * a_variable(
id, k);
4828 STilde += coefficients[1] * S;
4831 MInt tmpDir = Ld::distFld(0);
4832 for(
MInt j = 0; j < Ld::distFld(1); j++) {
4833 if(!a_hasNeighbor(
id, tmpDir + j))
continue;
4835 const MInt currentNghbr = c_neighborId(
id, tmpDir + j);
4838 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FPOW2(maxLevel() - this->a_level(currentNghbr)));
4839 for(
MInt k = 0; k < 9; k++) {
4840 Sij[k] = -F1B2 * F1BCSsq * m_omega * m_momentumFlux[currentNghbr][k];
4843 S = sqrt(2.0 * std::inner_product(&Sij[0], &Sij[9], &Sij[0], .0));
4846 for(
MInt i = 0; i < 9; i++) {
4847 Mij[i] += coefficients[2] * 2.0 * m_deltaX * m_deltaX * S * Sij[i];
4848 SijTilde[i] += coefficients[2] * Sij[i];
4850 for(
MInt k = 0; k < 3; k++) {
4851 for(
MInt l = 0; l < 3; l++) {
4852 uuTilde[l + 3 * k] += coefficients[2] * a_variable(
id, k) * a_variable(
id, l);
4855 for(
MInt k = 0; k < 3; k++) {
4856 uTilde[k] += coefficients[2] * a_variable(
id, k);
4858 STilde += coefficients[2] * S;
4861 tmpDir = Ld::distFld(0) + Ld::distFld(1);
4862 for(
MInt j = 0; j < Ld::distFld(2); j++) {
4863 if(!a_hasNeighbor(
id, tmpDir + j))
continue;
4865 const MInt currentNghbr = c_neighborId(
id, tmpDir + j);
4868 m_omega = 2.0 / (1.0 + 6.0 * m_nu *
FPOW2(maxLevel() - this->a_level(currentNghbr)));
4869 for(
MInt k = 0; k < 9; k++) {
4870 Sij[k] = -F1B2 * F1BCSsq * m_omega * m_momentumFlux[currentNghbr][k];
4873 S = sqrt(2.0 * std::inner_product(&Sij[0], &Sij[9], &Sij[0], .0));
4876 for(
MInt k = 0; k < 9; k++) {
4877 Mij[k] += coefficients[3] * 2.0 * m_deltaX * m_deltaX * S * Sij[k];
4878 SijTilde[k] += coefficients[3] * Sij[k];
4880 for(
MInt k = 0; k < 3; k++) {
4881 for(
MInt l = 0; l < 3; l++) {
4882 uuTilde[l + 3 * k] += coefficients[3] * a_variable(
id, k) * a_variable(
id, l);
4885 for(
MInt k = 0; k < 3; k++) {
4886 uTilde[k] += coefficients[3] * a_variable(
id, k);
4888 STilde += coefficients[3] * S;
4894 for(
MInt j = 0; j < 9; j++) {
4895 Mij[j] -= 2.0 * 4.0 * m_deltaX * m_deltaX * STilde * SijTilde[j];
4899 for(
MInt k = 0; k < 3; k++) {
4900 for(
MInt l = 0; l < 3; l++) {
4901 Lij[l + 3 * k] += uuTilde[l + 3 * k] - uTilde[k] * uTilde[l];
4907 for(
MInt k = 0; k < 9; k++) {
4908 m_MijMij[
id] += Mij[k] * Mij[k];
4913 for(
MInt k = 0; k < 9; k++) {
4914 m_MijLij[
id] += Mij[k] * Lij[k];
4923template <MInt nDim, MInt nDist,
class SysEqn>
4926 m_srcTermController.init();
4933template <MInt nDim, MInt nDist,
class SysEqn>
4936 m_srcTermController.initSrcTerms();
4943template <MInt nDim, MInt nDist,
class SysEqn>
4946 m_srcTermController.apply_preCollision();
4953template <MInt nDim, MInt nDist,
class SysEqn>
4956 m_srcTermController.apply_postCollision();
4963template <MInt nDim, MInt nDist,
class SysEqn>
4966 m_srcTermController.apply_postPropagation();
4972template <MInt nDim, MInt nDist,
class SysEqn>
4976 m_bndCnd->updateVariables();
4982template <MInt nDim, MInt nDist,
class SysEqn>
4986 m_bndCnd->updateRHS();
4992template <MInt nDim, MInt nDist,
class SysEqn>
4995 initEqDistFunctions();
4998 initThermalEqDistFunctions();
5001 initTransportEqDistFunctions();
5013template <MInt nDim, MInt nDist,
class SysEqn>
5017 m_log <<
" + Initializing flow field..." << endl;
5018 m_log <<
" - init method: " << m_initMethod << endl;
5020 m_smallestCellLength = (this->c_cellLengthAtLevel(maxLevel()));
5021 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
5022 m_omega = 2.0 / (1.0 + 6.0 * m_nu);
5025 m_log <<
" - flow init: turbulent" << endl;
5044 m_log <<
"lbsolverdxqy::() unknown Init-Method type in combination with FftInit" << endl;
5045 cerr <<
"lbsolverdxqy::() unknown Init-Method type in combination with FftInit" << endl;
5046 DEBUG(
"lbsolverdxqy::() unknown Init-Method type in combination with FftInit" << endl, MAIA_DEBUG_ASSERTION);
5047 TERMM(1,
"unknown Init-Method type in combination with FftInit");
5051 m_log <<
" - flow init: laminar" << endl;
5109 m_log <<
"lbsolverdxqy::() unknown Init-Method type" << endl;
5110 cerr <<
"lbsolverdxqy::() unknown Init-Method type" << endl;
5111 DEBUG(
"lbsolverdxqy::() unknown Init-Method type" << endl, MAIA_DEBUG_ASSERTION);
5112 TERMM(1,
"unknown Init-Method type");
5117 if(m_densityFluctuations)
5118 m_log <<
" - init density: fluctuations enanbled" << endl;
5120 m_log <<
" - init density: absolute" << endl;
5122 (this->*m_initMethodPtr)();
5136template <MInt nDim, MInt nDist,
class SysEqn>
5141 const MFloat rho = (m_densityFluctuations) ? 0.0 : 1.0;
5143 for(
MInt i = 0; i < a_noCells(); i++) {
5144 a_variable(i, PV->RHO) = rho;
5145 a_oldVariable(i, PV->RHO) = rho;
5151 a_kappa(i) = m_kappa;
5152 a_variable(i, PV->T) = 1.0;
5153 a_oldVariable(i, PV->T) = 1.0;
5156 a_diffusivity(i) = m_diffusivity;
5157 a_variable(i, PV->C) = 1.0;
5158 a_oldVariable(i, PV->C) = 1.0;
5161 for(
MInt dir = 1; dir < nDim; dir++) {
5162 a_variable(i, PV->VV[dir]) = 0.0;
5165 std::array<MFloat, 2 * nDim> bBox{};
5166 this->m_geometry->getBoundingBox(bBox.data());
5167 if(this->m_nonNewtonian) {
5168 const MFloat tmpWidth = fabs(bBox[nDim + 1] - bBox[1]) * F1B2;
5169 const MFloat exp = F1 + F1 / this->m_n;
5171 const MFloat relPos = fabs(a_coordinate(i, 1) / tmpWidth - F1);
5172 const MFloat parabola = F1 - pow(relPos, exp);
5174 a_variable(i, PV->VV[0]) = m_Ma * LBCS * parabola;
5176 const MFloat halfWidth = std::max(fabs(bBox[1 + nDim]), fabs(bBox[1]));
5177 a_variable(i, PV->VV[0]) =
5179 * ((1 - this->m_CouettePoiseuilleRatio) * a_coordinate(i, 1) / halfWidth + this->m_CouettePoiseuilleRatio
5180 - this->m_CouettePoiseuilleRatio * (a_coordinate(i, 1) / halfWidth) * (a_coordinate(i, 1) / halfWidth));
5181 a_oldVariable(i, PV->VV[0]) = a_variable(i, PV->VV[0]);
5184 for(
MInt d = 0; d < nDim; d++) {
5185 a_oldVariable(i, PV->VV[d]) = a_variable(i, PV->VV[d]);
5189 initEqDistFunctions();
5192 initThermalEqDistFunctions();
5195 initTransportEqDistFunctions();
5198 if(this->m_nonNewtonian) {
5199 initNonEqDistFunctions();
5201 this->exchangeOldDistributions();
5216template <MInt nDim, MInt nDist,
class SysEqn>
5224 MFloat* bBoxPtr = &bBox[0];
5225 m_geometry->getBoundingBox(bBoxPtr);
5232 for(
MInt d = 0; d < nDim; d++) {
5233 if(fabs(bBox[d + nDim] - bBox[d]) > maxLength) {
5235 maxLength = fabs(bBox[d + nDim] - bBox[d]);
5237 o_dirs[otherDirs] = d;
5243 if(m_densityFluctuations)
5248 for(
MInt i = 0; i < a_noCells(); i++) {
5250 for(
MInt dir = 0; dir < nDim; dir++) {
5251 if(dir == mainDir)
continue;
5252 radius += a_coordinate(i, dir) * a_coordinate(i, dir);
5254 radius = sqrt(radius);
5256 const MFloat tmpWidth = 0.5 * fabs(bBox[o_dirs[0] + nDim] - bBox[o_dirs[0]]);
5258 yPlus = radius / tmpWidth;
5260 for(
MInt dir = 0; dir < nDim; dir++) {
5261 a_variable(i, PV->VV[dir]) = 0.0;
5263 a_variable(i, PV->VV[mainDir]) = 2.0 * (1.0 - yPlus * yPlus) * m_Ma * LBCS;
5265 a_variable(i, PV->T) =
5266 this->m_initTemperatureKelvin - (this->m_initTemperatureKelvin - F1) * (1.0 - yPlus * yPlus);
5269 a_variable(i, PV->C) = this->m_initCon - (this->m_initCon - F1) * (1.0 - yPlus * yPlus);
5272 a_variable(i, PV->RHO) = rho;
5277 a_kappa(i) = m_kappa;
5278 a_variable(i, PV->T) = 1.0;
5279 a_oldVariable(i, PV->T) = 1.0;
5284 initEqDistFunctions();
5287 initThermalEqDistFunctions();
5290 initTransportEqDistFunctions();
5305template <MInt nDim, MInt nDist,
class SysEqn>
5308 IF_CONSTEXPR(nDim != 3) TERMM(1,
"Only implemented for 3D");
5317 for(
MInt i = 0; i < a_noCells(); i++) {
5318 const MFloat xCoord = a_coordinate(i, 0);
5319 const MFloat yCoord = a_coordinate(i, 1);
5320 const MFloat zCoord = a_coordinate(i, 2);
5322 const MFloat x = (cos(F2 * zCoord) + F2) * (cos(F2 * xCoord) + cos(F2 * yCoord));
5323 const MFloat y = sin(xCoord) * cos(yCoord) * cos(zCoord);
5324 const MFloat z = cos(xCoord) * sin(yCoord) * cos(zCoord);
5326 p = p0 + rho0 * (m_Ma * m_Ma) * F1B3 / 16.0 * x;
5328 u[0] = m_Ma * LBCS *
y;
5329 u[1] = -m_Ma * LBCS * z;
5332 a_variable(i, PV->RHO) = rho;
5338 a_variable(i, PV->U) = u[0];
5339 a_variable(i, PV->V) = u[1];
5340 a_variable(i, PV->W) = u[2];
5342 initEqDistFunctions();
5356template <MInt nDim, MInt nDist,
class SysEqn>
5362 MFloat uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
5364 MFloat* bBoxPtr = &bBox[0];
5365 m_geometry->getBoundingBox(bBoxPtr);
5370 if(m_densityFluctuations)
5375 const MFloat tmpWidth = fabs(bBox[1 + nDim] - bBox[1]);
5377 for(
MInt i = 0; i < a_noCells(); i++) {
5378 a_variable(i, PV->RHO) = rho;
5380 yPlus = m_ReTau * (fabs(a_coordinate(i, 1)) / tmpWidth + 0.5);
5383 a_variable(i, PV->U) = uTau * yPlus;
5385 if(yPlus <= 30 && yPlus > 5.0) {
5386 a_variable(i, PV->U) = uTau * (C1 * log(yPlus) + C2);
5389 a_variable(i, PV->U) = uTau * (C3 * log(yPlus) + C4);
5395 a_variable(i, PV->U) += amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->U);
5397 for(
MInt dir = 1; dir < nDim; dir++) {
5398 a_variable(i, PV->VV[dir]) = amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->U);
5405 initEqDistFunctions();
5419template <MInt nDim, MInt nDist,
class SysEqn>
5425 MFloat uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
5430 if(m_densityFluctuations)
5437 const MFloat tmpWidth = m_referenceLength * this->c_cellLengthAtLevel(maxLevel());
5439 for(
MInt i = 0; i < a_noCells(); i++) {
5440 a_variable(i, PV->RHO) = rho;
5442 yPlus = m_ReTau * (1.0 - fabs(a_coordinate(i, 1)) / tmpWidth);
5445 a_variable(i, PV->U) = uTau * yPlus;
5447 if(yPlus <= 30 && yPlus > 5.0) {
5448 a_variable(i, PV->U) = uTau * (C1 * log(yPlus) + C2);
5451 a_variable(i, PV->U) = uTau * (C3 * log(yPlus) + C4);
5457 a_variable(i, PV->U) += amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->U);
5459 for(
MInt dir = 1; dir < nDim; dir++) {
5460 a_variable(i, PV->VV[dir]) = amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->U);
5467 initEqDistFunctions();
5481template <MInt nDim, MInt nDist,
class SysEqn>
5484 IF_CONSTEXPR(nDim != 3) TERMM(1,
"Only implemented for 3D. For 2D use a channel!");
5489 MFloat uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
5493 MFloat* bBoxPtr = &bBox[0];
5494 m_geometry->getBoundingBox(bBoxPtr);
5499 if(m_densityFluctuations)
5504 const MFloat tmpWidth = fabs(bBox[1 + nDim] - bBox[1]);
5506 for(
MInt i = 0; i < a_noCells(); i++) {
5507 radius = sqrt(a_coordinate(i, 1) * a_coordinate(i, 1) + a_coordinate(i, 2) * a_coordinate(i, 2));
5509 yPlus = (1.0 - radius / tmpWidth * 2.0) * m_ReTau;
5511 a_variable(i, PV->U) = uTau * yPlus;
5513 if(yPlus <= 30 && yPlus > 5.0) {
5514 a_variable(i, PV->U) = uTau * (C1 * log(yPlus) + C2);
5517 a_variable(i, PV->U) = uTau * (C3 * log(yPlus) + C4);
5522 deltaU = amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->U);
5523 a_variable(i, PV->U) += deltaU;
5527 deltaW = amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->U);
5528 a_variable(i, PV->V) = 0.0;
5529 a_variable(i, PV->W) = deltaW;
5530 a_variable(i, PV->RHO) = rho;
5536 initEqDistFunctions();
5550template <MInt nDim, MInt nDist,
class SysEqn>
5553 IF_CONSTEXPR(nDim != 3)
mTerm(1, AT_,
"Only implemented for 3D. For 2D use a channel!");
5555 MFloat amp = 0.2 * m_Ma * LBCS;
5556 MFloat GaussFactor, sigma, deltaOmega0;
5560 MFloat* bBoxPtr = &bBox[0];
5561 m_geometry->getBoundingBox(bBoxPtr);
5564 if(m_densityFluctuations)
5570 deltaOmega0 = m_referenceLength * m_smallestCellLength;
5572 m_log <<
" initial macroscopic vorticity thickness: " << deltaOmega0 << endl;
5576 sigma = deltaOmega0;
5578 for(
MInt i = 0; i < a_noCells(); i++) {
5580 a_variable(i, PV->U) = m_Ma * LBCS * tanh(2.0 * a_coordinate(i, 1) / deltaOmega0);
5581 for(
MInt dir = 1; dir < nDim; dir++) {
5582 a_variable(i, PV->VV[dir]) = 0.0;
5584 a_variable(i, PV->RHO) = rho;
5586 GaussFactor = exp(-(a_coordinate(i, 1) / sigma) * (a_coordinate(i, 1) / sigma) * F1B2);
5588 a_variable(i, PV->U) += amp * F2 * (distrib(randNumGen) - F1B2) * GaussFactor;
5590 for(
MInt dir = 1; dir < nDim; dir++) {
5591 a_variable(i, PV->VV[dir]) = amp * F2 * (distrib(randNumGen) - F1B2) * GaussFactor;
5600 initNonEqDistFunctions();
5614template <MInt nDim, MInt nDist,
class SysEqn>
5620 MFloat uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
5623 MFloat* bBoxPtr = &bBox[0];
5625 m_geometry->getBoundingBox(bBoxPtr);
5630 if(m_densityFluctuations)
5636 const MFloat tmpWidth = 0.5 * fabs(bBox[1 + nDim] - bBox[1]);
5638 for(
MInt i = 0; i < a_noCells(); i++) {
5639 for(
MInt dir = 0; dir < nDim - 1; dir++) {
5640 radius += a_coordinate(i, dir) * a_coordinate(i, dir);
5642 radius = sqrt(radius);
5644 yPlus = m_ReTau * (1.0 - radius / tmpWidth);
5647 a_variable(i, PV->VV[nDim - 1]) = uTau * yPlus;
5649 if(yPlus <= 30 && yPlus > 5.0) {
5650 a_variable(i, PV->VV[nDim - 1]) = uTau * (C1 * log(yPlus) + C2);
5653 a_variable(i, PV->VV[nDim - 1]) = uTau * (C3 * log(yPlus) + C4);
5658 for(
MInt dir = 0; dir < nDim - 1; dir++) {
5659 a_variable(i, PV->VV[dir]) =
5660 amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->VV[nDim - 1]);
5662 a_variable(i, PV->VV[nDim - 1]) +=
5663 amp * 2.0 * (0.5 - (
MFloat)(1.0 * rand() / (RAND_MAX + 1.0))) * a_variable(i, PV->VV[nDim - 1]);
5664 a_variable(i, PV->RHO) = rho;
5670 initEqDistFunctions();
5689template <MInt nDim, MInt nDist,
class SysEqn>
5694 std::array<MFloat, 2> position;
5695 MBool eqInit =
false;
5698 coreRadius = Context::getSolverProperty<MFloat>(
"vortexCoreRadius", this->m_solverId, AT_, &coreRadius);
5699 const MFloat umax = Context::getSolverProperty<MFloat>(
"vortexMachMax", this->m_solverId, AT_, &m_Ma) * LBCS;
5700 eqInit = Context::getSolverProperty<MBool>(
"vortexEqInit", this->m_solverId, AT_, &eqInit);
5702 for(
MInt d = 0; d < 2; d++) {
5703 position[d] = Context::getSolverProperty<MFloat>(
"vortexPosition", this->m_solverId, AT_, d);
5707 std::array<MFloat, 2> u_b = {0.0, 0.0};
5709 u_b[0] = m_Ma * LBCS;
5712 if(domainId() == 0) {
5713 std::stringstream ss;
5714 ss <<
"Info: " <<
string2enum(m_initMethod) << std::endl;
5715 ss <<
" vortexCoreRadius : " << coreRadius << std::endl;
5716 ss <<
" vortexUmax : " << umax << std::endl;
5717 ss <<
" vortexPosition : " << position[0] <<
", " << position[1] << std::endl;
5718 std::cout << ss.str();
5721 maia::parallelFor<false>(0, a_noCells(), [=](
MInt cellId) {
5722 const MFloat x = a_coordinate(cellId, 0) - position[0];
5723 const MFloat y = a_coordinate(cellId, 1) - position[1];
5725 const MFloat theta = std::atan2(
y, x);
5726 const MFloat factor = umax * std::exp(0.5);
5728 MFloat up[2] = {0.0, 0.0};
5730 const MFloat u_tan = factor * r_rel * std::exp(-0.5 *
POW2(r_rel));
5731 up[0] = -std::sin(theta) * u_tan;
5732 up[1] = std::cos(theta) * u_tan;
5736 const MFloat rho = rho0 * std::exp(-0.5 *
POW2(factor * F1BCS) * std::exp(-
POW2(r_rel)));
5737 a_variable(cellId, PV->RHO) = rho;
5738 a_variable(cellId, PV->U) = (u_b[0] + up[0]);
5739 a_variable(cellId, PV->V) = (u_b[1] + up[1]);
5740 if constexpr(nDim == 3) a_variable(cellId, PV->W) = 0.0;
5741 initNu(cellId, m_nu);
5744 initEqDistFunctions();
5746 initNonEqDistFunctions();
5761template <MInt nDim, MInt nDist,
class SysEqn>
5771 const MFloat r0 = Context::getSolverProperty<MFloat>(
"r0", this->m_solverId, AT_);
5772 const MFloat rC = Context::getSolverProperty<MFloat>(
"coreRadius", this->m_solverId, AT_);
5775 nC = Context::getSolverProperty<MInt>(
"coreModelExponent", this->m_solverId, AT_, &nC);
5777 const MFloat gamma = m_Ma * LBCS * 4.0 * PI * r0;
5778 const MFloat dx = (this->c_cellLengthAtLevel(maxLevel()));
5779 const MFloat omega = m_Ma * LBCS / (r0 / dx);
5780 const MFloat bx = r0 * cos(omega * t);
5781 const MFloat by = r0 * sin(omega * t);
5783 const MFloat periode = 2.0 * PI / omega;
5784 m_log <<
" Info spinning vorticities init: " << std::endl
5785 <<
" * Iterations for one full rotation: " << periode << std::endl;
5786 const MFloat resolutionFactor = rC / dx;
5787 m_log <<
" * coreRadius / dx_maxLevel = " << resolutionFactor << std::endl;
5791 maia::parallelFor<false>(0, a_noCells(), [=](
MInt cellId) {
5793 const MFloat x = a_coordinate(cellId, 0);
5794 const MFloat y = a_coordinate(cellId, 1);
5796 const MFloat thetaPos = std::atan2(
y - by, x - bx);
5798 const MFloat thetaNeg = std::atan2(
y + by, x + bx);
5801 MFloat u[2] = {0.0, 0.0};
5803 const MFloat factorPos = (nC == 1) ? rPos / (rC * rC + rPos * rPos)
5804 : rPos / std::pow(std::pow(rC, 2 * nC) + std::pow(rPos, 2 * nC), 1.0 / nC);
5805 const MFloat factorNeg = (nC == 1) ? rNeg / (rC * rC + rNeg * rNeg)
5806 : rNeg / std::pow(std::pow(rC, 2 * nC) + std::pow(rNeg, 2 * nC), 1.0 / nC);
5807 u[0] = (factorPos * std::sin(thetaPos) + factorNeg * std::sin(thetaNeg)) * (-gamma / 2.0 / PI);
5808 u[1] = (factorPos * std::cos(thetaPos) + factorNeg * std::cos(thetaNeg)) * (gamma / 2.0 / PI);
5813 const MFloat usqrB2 = 0.5 * (u[0] * u[0] + u[1] * u[1]);
5815 const MFloat rho = 1.0 / (1.0 + usqrB2 * F1BCSsq);
5816 a_variable(cellId, PV->RHO) = rho;
5817 a_variable(cellId, PV->U) = rho * u[0];
5818 a_variable(cellId, PV->V) = rho * u[1];
5819 a_oldVariable(cellId, PV->U) = a_variable(cellId, PV->U);
5820 a_oldVariable(cellId, PV->V) = a_variable(cellId, PV->V);
5821 if constexpr(nDim == 3) {
5822 a_variable(cellId, PV->W) = 0.0;
5823 a_oldVariable(cellId, PV->W) = 0.0;
5825 initNu(cellId, m_nu);
5828 initEqDistFunctions();
5845template <MInt nDim, MInt nDist,
class SysEqn>
5851 if constexpr(nDim == 2) {
5852 m_log <<
" - parameters: u=0.0, v=0.0, " << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0")
5853 << ((m_isThermal) ?
", T=1.0" :
"") << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5855 m_log <<
" - parameters: u=0.0, v=0.0, w=0, " << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0")
5856 << ((m_isThermal) ?
", T=1.0" :
"") << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5858 initLatticeBgkLaminarDir(-1);
5861 if constexpr(nDim == 2) {
5862 m_log <<
" - parameters: u=" << m_Ma * LBCS <<
", v=0.0, "
5863 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5864 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5866 m_log <<
" - parameters: u=" << m_Ma * LBCS <<
", v=0.0, w=0, "
5867 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5868 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5870 initLatticeBgkLaminarDir(0);
5873 if constexpr(nDim == 2) {
5874 m_log <<
" - parameters: u=-" << m_Ma * LBCS <<
", v=0.0, "
5875 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5876 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5878 m_log <<
" - parameters: u=-" << m_Ma * LBCS <<
", v=0.0, w=0, "
5879 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5880 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5882 initLatticeBgkLaminarDir(1);
5885 if constexpr(nDim == 2) {
5886 m_log <<
" - parameters: u=0.0, v=" << m_Ma * LBCS <<
", "
5887 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5888 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5890 m_log <<
" - parameters: u=0.0, v=" << m_Ma * LBCS <<
", w=0.0, "
5891 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5892 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5894 initLatticeBgkLaminarDir(2);
5897 if constexpr(nDim == 2) {
5898 m_log <<
" - parameters: u=0.0, v=-" << m_Ma * LBCS <<
", "
5899 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5900 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5902 m_log <<
" - parameters: u=0.0, v=-" << m_Ma * LBCS <<
", w=0.0, "
5903 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5904 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5906 initLatticeBgkLaminarDir(3);
5909 if constexpr(nDim == 2) {
5910 m_log <<
" - parameters: u=0.0, v=0.0, " << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0")
5911 << ((m_isThermal) ?
", T=1.0" :
"") << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5912 initLatticeBgkLaminarDir(-1);
5914 m_log <<
" - parameters: u=0.0, v=0.0, w=" << m_Ma * LBCS <<
", "
5915 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5916 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5917 initLatticeBgkLaminarDir(4);
5921 if constexpr(nDim == 2) {
5922 m_log <<
" - parameters: u=0.0, v=0.0, " << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0")
5923 << ((m_isThermal) ?
", T=1.0" :
"") << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5924 initLatticeBgkLaminarDir(-1);
5926 m_log <<
" - parameters: u=0.0, v=0.0, w=-" << m_Ma * LBCS <<
", "
5927 << (m_densityFluctuations ?
"rho=0.0" :
"rho=1.0") << ((m_isThermal) ?
", T=1.0" :
"")
5928 << ((m_isTransport) ?
", C=1.0" :
"") << endl;
5929 initLatticeBgkLaminarDir(5);
5948template <MInt nDim, MInt nDist,
class SysEqn>
5952 const MFloat rho0 = (m_densityFluctuations) ? 0.0 : 1.0;
5953 const MFloat origin[3] = {F0, F0, F0};
5955 const MFloat radius = 0.01;
5957 initLatticeBgkLaminarDir(-1);
5958 maia::parallelFor<false>(0, a_noCells(), [&](
MInt i) {
5960 for(
MInt j = 0; j < nDim; j++)
5961 r[j] = a_coordinate(i, j) - origin[j];
5962 const MFloat distance = std::sqrt(std::inner_product(&r[0], &r[nDim], &r[0], .0));
5963 const MFloat rhoFluct = amp * std::exp(-(distance * distance) / radius);
5964 a_variable(i, PV->RHO) = rho0 + rhoFluct;
5965 a_oldVariable(i, PV->RHO) = a_variable(i, PV->RHO);
5967 initEqDistFunctions();
5974template <MInt nDim, MInt nDist,
class SysEqn>
5978 const MFloat origin[2] = {F0, F0};
5979 const MFloat width = 20.0 * this->c_cellLengthAtLevel(this->maxLevel());
5980 const MFloat maxConcentration = this->m_initCon;
5981 const MFloat maxTemp = this->m_initTemperatureKelvin;
5983 maia::parallelFor<false>(0, a_noCells(), [=](
MInt i) {
5985 a_variable(i, PV->U) = F0;
5986 a_variable(i, PV->V) = F0;
5987 a_oldVariable(i, PV->U) = F0;
5988 a_oldVariable(i, PV->V) = F0;
5992 a_variable(i, PV->RHO) = rho;
5993 a_oldVariable(i, PV->RHO) = rho;
5996 if((m_isTransport) && nDim == 2) {
5998 for(
MInt d = 0; d < nDim; d++)
5999 r[d] = a_coordinate(i, d) - origin[d];
6000 const MFloat distSq = pow(r[0], 2) + pow(r[1], 2);
6001 const MFloat C = maxConcentration * exp(-(distSq) / (2 * pow(width, 2)));
6002 a_variable(i, PV->C) = C;
6003 a_oldVariable(i, PV->C) = C;
6006 if((m_isThermal) && nDim == 2) {
6008 for(
MInt d = 0; d < nDim; d++)
6009 r[d] = a_coordinate(i, d) - origin[d];
6010 const MFloat distSq = pow(r[0], 2) + pow(r[1], 2);
6011 const MFloat T = maxTemp * exp(-(distSq) / (2 * pow(width, 2)));
6012 a_variable(i, PV->T) = T;
6013 a_oldVariable(i, PV->T) = T;
6022 initEqDistFunctions();
6025 initThermalEqDistFunctions();
6028 initTransportEqDistFunctions();
6036template <MInt nDim, MInt nDist,
class SysEqn>
6040 const MFloat origin[2] = {F0, F0};
6041 const MFloat width = 20.0 * this->c_cellLengthAtLevel(this->maxLevel());
6042 const MFloat maxConcentration = this->m_initCon;
6043 const MFloat maxTemp = this->m_initTemperatureKelvin;
6045 maia::parallelFor<false>(0, a_noCells(), [&](
MInt i) {
6047 MFloat velocity = m_Ma * LBCS;
6048 a_variable(i, PV->U) = velocity;
6049 a_variable(i, PV->V) = velocity;
6050 a_oldVariable(i, PV->U) = velocity;
6051 a_oldVariable(i, PV->V) = velocity;
6055 a_variable(i, PV->RHO) = rho;
6056 a_oldVariable(i, PV->RHO) = rho;
6059 if((m_isTransport) && nDim == 2) {
6061 for(
MInt d = 0; d < nDim; d++)
6062 r[d] = a_coordinate(i, d) - origin[d];
6063 const MFloat distSq = pow(r[0], 2) + pow(r[1], 2);
6064 const MFloat C = maxConcentration * exp(-(distSq) / (2 * pow(width, 2)));
6065 a_variable(i, PV->C) = C;
6066 a_oldVariable(i, PV->C) = C;
6069 if((m_isThermal) && nDim == 2) {
6071 for(
MInt d = 0; d < nDim; d++)
6072 r[d] = a_coordinate(i, d) - origin[d];
6073 const MFloat distSq = pow(r[0], 2) + pow(r[1], 2);
6074 const MFloat T = maxTemp * exp(-(distSq) / (2 * pow(width, 2)));
6075 a_variable(i, PV->T) = T;
6076 a_oldVariable(i, PV->T) = T;
6085 initEqDistFunctions();
6088 initThermalEqDistFunctions();
6091 initTransportEqDistFunctions();
6107template <MInt nDim, MInt nDist,
class SysEqn>
6110 initLatticeBgkLaminarDir(0);
6112 constexpr MFloat factor = 0.1;
6114 maia::parallelFor<false>(0, a_noCells(), [=](
MInt i) {
6115 const MFloat x = a_coordinate(i, 0);
6116 const MFloat y = a_coordinate(i, 1);
6118 if(-bb < x && x < bb && -bb <
y &&
y < bb) {
6119 const MFloat pertFactor = (1.0 + factor * std::sin(
y / 2.0 * PI));
6120 a_variable(i, PV->U) *= pertFactor;
6123 initEqDistFunctions();
6140template <MInt nDim, MInt nDist,
class SysEqn>
6144 MFloat value = m_Ma * LBCS;
6145 std::array<
MInt, nDim - 1> o_dirs{};
6147 if constexpr(nDim == 3) o_dirs[1] = PV->W;
6153 if(dir % 2) value *= -1.0;
6169 if constexpr(nDim == 3) o_dirs[1] = PV->V;
6176 maia::parallelFor<false>(0, a_noCells(), [=](
MInt i) {
6177 a_variable(i, dir) = value;
6178 a_oldVariable(i, dir) = value;
6179 for(
MInt j = 0; j < nDim - 1; j++) {
6180 a_variable(i, o_dirs[j]) = 0.0;
6181 a_oldVariable(i, o_dirs[j]) = 0.0;
6184 MFloat rho = m_densityFluctuations ? 0.0 : 1.0;
6185 if(m_initDensityGradient) {
6186 for(
MInt j = 0; j < nDim; j++) {
6187 rho += a_coordinate(i, j) / this->c_cellLengthAtLevel(maxLevel()) * m_volumeAccel[j] * F1BCSsq;
6190 a_variable(i, PV->RHO) = rho;
6191 a_oldVariable(i, PV->RHO) = rho;
6194 a_kappa(i) = m_kappa;
6195 a_variable(i, PV->T) = 1.0;
6196 a_oldVariable(i, PV->T) = 1.0;
6199 a_variable(i, PV->C) = 0.0;
6200 a_oldVariable(i, PV->C) = 0.0;
6208 initEqDistFunctions();
6211 initThermalEqDistFunctions();
6214 initTransportEqDistFunctions();
6223template <MInt nDim, MInt nDist,
class SysEqn>
6227 for(
MInt i = 0; i < a_noCells(); i++) {
6228 const MFloat rho = a_variable(i, PV->RHO);
6229 std::array<MFloat, nDim> u;
6230 for(
MInt d = 0; d < nDim; d++) {
6231 u[d] = a_variable(i, d);
6233 setEqDists(i, rho, u.data());
6237template <MInt nDim, MInt nDist,
class SysEqn>
6241 initEqDistFunctions();
6244 maia::parallelFor<false>(0, a_noCells(), [&](
MInt i) {
6247 this->calculateVelocityDerivative(i, c);
6250 for(
MInt d = 0; d < nDim; d++) {
6256 const MInt lvlDiff = maxLevel() - a_level(i);
6257 const MFloat tau = F1B2 + F1BCSsq * a_nu(i) *
FFPOW2(lvlDiff);
6258 const MFloat tauRho = tau * a_variable(i, PV->RHO);
6261 a_distribution(i,
dist) += t * tauRho * trace;
6262 for(
MInt k = 0; k < nDim; k++) {
6263 for(
MInt l = 0; l < nDim; l++) {
6264 a_distribution(i,
dist) -=
6265 t * tauRho * F1BCSsq * (Ld::idFld(
dist, k) - 1) * (Ld::idFld(
dist, l) - 1) * c[l][k];
6269 a_distribution(i, Ld::lastId()) += Ld::tp(0) * tauRho * trace;
6272 for(
MInt j = 0; j < Ld::lastId() + 1; j++) {
6273 a_oldDistribution(i, j) = a_distribution(i, j);
6287template <MInt nDim, MInt nDist,
class SysEqn>
6291 for(
MInt i = 0; i < a_noCells(); i++) {
6292 const MFloat rho = a_variable(i, PV->RHO);
6293 const MFloat t = a_variable(i, PV->T);
6294 std::array<MFloat, nDim> u;
6295 for(
MInt d = 0; d < nDim; d++) {
6296 u[d] = a_variable(i, d);
6299 setEqDistsThermal(i, t, rho, u.data());
6312template <MInt nDim, MInt nDist,
class SysEqn>
6316 for(
MInt i = 0; i < a_noCells(); i++) {
6317 const MFloat c = a_variable(i, PV->C);
6318 std::array<MFloat, nDim> u;
6319 for(
MInt d = 0; d < nDim; d++) {
6320 u[d] = a_variable(i, d);
6323 setEqDistsTransport(i, c, u.data());
6339template <MInt nDim, MInt nDist,
class SysEqn>
6343 if(domainId() == 0) mRes.open(m_resFileName, std::ofstream::app);
6345 constexpr MInt noVars = 1 + nDim;
6346 for(
MInt v = 0; v < noVars; v++) {
6348 m_tmpResidual[v] = F0;
6349 m_tmpResidualLvl[v] = 0;
6356 for(
MInt id = 0;
id < m_currentMaxNoCells;
id++) {
6357 MInt l_id = m_activeCellList[
id];
6360 if(l_id >= this->grid().noInternalCells())
continue;
6362 const MInt pCellId = l_id;
6365 if(a_isInterfaceChild(pCellId))
continue;
6367 MFloat diff[noVars] = {F0};
6368 const MFloat*
const pcoordinates = &a_coordinate(pCellId, 0);
6369 MInt level = this->a_level(pCellId);
6371 for(
MInt v = 0; v < noVars; v++) {
6372 diff[v] = fabs(a_variable(pCellId, v) - a_oldVariable(pCellId, v));
6373 m_residual[v] += diff[v];
6374 if(m_tmpResidual[v] * m_tmpResidual[v] <= diff[v] * diff[v]) {
6375 m_tmpResidual[v] = diff[v];
6376 m_maxResId[v] = l_id;
6377 for(
MInt d = 0; d < nDim; d++) {
6378 m_rescoordinates[v][d] = pcoordinates[d];
6380 m_tmpResidualLvl[v] = level;
6389 MString res_t_f = res_t.str();
6391 stringstream res_Re;
6392 res_Re << (m_referenceLength * m_Ma * LBCS / m_nu);
6393 MString res_Re_f = res_Re.str();
6398 } sendBufRes[noVars], rcvBufRes[noVars];
6400 MFloat sendBufResAvg[noVars] = {0.0};
6401 for(
MInt v = 0; v < noVars; v++) {
6402 sendBufResAvg[v] = m_residual[v];
6403 sendBufRes[v].val = m_tmpResidual[v];
6405 MFloat rcvBufResAvg[noVars];
6407 for(
MInt i = 0; i < noVars; i++)
6408 sendBufRes[i].rank = domainId();
6413 if constexpr(nDim == 3) strs[2] =
"W";
6416 MPI_Allreduce(sendBufRes, rcvBufRes, noVars, MPI_DOUBLE_INT, MPI_MAXLOC, mpiComm(), AT_,
"sendBufRes",
"rcvBufRes");
6417 MPI_Reduce(sendBufResAvg, rcvBufResAvg, noVars, MPI_DOUBLE, MPI_SUM, 0, mpiComm(), AT_,
"sendBufResAvg",
6421 if(noDomains() == 1) {
6426 MPI_Reduce(&count, &sumCount, 1, MPI_INT, MPI_SUM, 0, mpiComm(), AT_,
"count",
"sumCount");
6430 if(domainId() == 0) {
6432 mRes <<
"#------------------------------" << std::endl;
6433 mRes <<
"In timestep: " << res_t_f <<
", with Re: " << res_Re_f <<
";" << std::endl;
6435 for(
MInt i = 0; i < noVars; i++)
6436 mRes <<
" Max. averaged residual found for " << strs[i] <<
" is " << (rcvBufResAvg[i] / sumCount) <<
"\n";
6439 if(noDomains() > 1) {
6440 for(
MInt i = 0; i < noVars; i++) {
6441 MInt noElements2Snd = 0;
6442 std::array<MFloat, nDim> sndBufFloat;
6443 std::array<MInt, 2> sndBufInt;
6444 std::array<MFloat, nDim> recvElementsF;
6445 std::array<MInt, 2> recvElementsI;
6446 MIntScratchSpace noElements2SndPerCPU(noDomains(), AT_,
"noElements2SndPerCPU");
6447 MIntScratchSpace posElements2SndPerCPU(noDomains(), AT_,
"posElements2SndPerCPU");
6449 for(
MInt dom = 0; dom < noDomains(); dom++) {
6450 noElements2SndPerCPU[dom] = 0;
6451 posElements2SndPerCPU[dom] = 0;
6452 if(rcvBufRes[i].rank == dom) {
6453 noElements2SndPerCPU[dom] = nDim;
6456 posElements2SndPerCPU[dom] = posElements2SndPerCPU[dom - 1] + noElements2SndPerCPU[dom - 1];
6460 if(rcvBufRes[i].rank == domainId() && m_maxResId[i] != -1) {
6461 noElements2Snd = nDim;
6462 for(
MInt d = 0; d < nDim; d++) {
6463 sndBufFloat[d] = m_rescoordinates[i][d];
6467 MPI_Gatherv(sndBufFloat.data(), noElements2Snd, MPI_DOUBLE, recvElementsF.data(), noElements2SndPerCPU.
data(),
6468 posElements2SndPerCPU.
data(), MPI_DOUBLE, 0, mpiComm(), AT_,
"sndBufFloat.data()",
6469 "recvElementsF.data()");
6471 for(
MInt dom = 0; dom < noDomains(); dom++) {
6472 noElements2SndPerCPU[dom] = 0;
6473 posElements2SndPerCPU[dom] = 0;
6474 if(rcvBufRes[i].rank == dom) {
6475 noElements2SndPerCPU[dom] = 2;
6478 posElements2SndPerCPU[dom] = posElements2SndPerCPU[dom - 1] + noElements2SndPerCPU[dom - 1];
6482 if(rcvBufRes[i].rank == domainId() && m_maxResId[i] != -1) {
6484 sndBufInt[0] = m_tmpResidualLvl[i];
6485 sndBufInt[1] = m_maxResId[i];
6488 MPI_Gatherv(&sndBufInt, noElements2Snd, MPI_INT, recvElementsI.data(), noElements2SndPerCPU.
data(),
6489 posElements2SndPerCPU.
data(), MPI_INT, 0, mpiComm(), AT_,
"sndBufInt",
"recvElementsI.data()");
6492 if(domainId() == 0) {
6493 mRes <<
"\n Max. local residual found for " << strs[i] <<
" on proc.: " << rcvBufRes[i].rank <<
" with "
6494 << rcvBufRes[i].val <<
"\n"
6495 <<
" Level: " << recvElementsI[0] <<
"\n"
6496 <<
" ID: " << recvElementsI[1] <<
"\n"
6497 <<
" Coordinates: (";
6498 for(
MInt d = 0; d < nDim - 1; d++) {
6499 mRes << recvElementsF[d] <<
", ";
6501 mRes << recvElementsF[nDim - 1] <<
")" << endl;
6507 for(
MInt i = 0; i < noVars; i++) {
6508 mRes <<
"\n Max. local residual found for " << strs[i] <<
" on proc.: " << domainId() <<
" with "
6509 << rcvBufRes[i].val <<
"\n"
6510 <<
" Level: " << m_tmpResidualLvl[i] <<
"\n"
6511 <<
" ID: " << m_maxResId[i] <<
"\n"
6512 <<
" Coordinates: (";
6513 for(
MInt d = 0; d < nDim - 1; d++) {
6514 mRes << m_rescoordinates[i][d] <<
", ";
6516 mRes << m_rescoordinates[i][nDim - 1] <<
")" << endl;
6521 if(domainId() == 0) {
6528template <MInt nDim, MInt nDist,
class SysEqn>
6531 m_interface->prolongation();
6535template <MInt nDim, MInt nDist,
class SysEqn>
6538 m_interface->restriction();
6547template <MInt nDim, MInt nDist,
class SysEqn>
6549 m_interface->removeChildren(parentId);
6559template <MInt nDim, MInt nDist,
class SysEqn>
6561 m_interface->refineCell(parentId, childIds);
6576template <MInt nDim, MInt nDist,
class SysEqn>
6578 std::vector<std::bitset<64>>& sensorCellFlag,
6579 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
6581 m_log <<
" - Sensor preparation for the boundary sensor for " << m_maxNoSets <<
" starting from " << m_levelSetId
6583 cerr0 <<
" - Sensor preparation for the boundary sensor for " << m_maxNoSets <<
" starting from " << m_levelSetId
6592 MInt interfaceCellCounter = 0;
6593 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
6594 if(a_isHalo(cellId))
continue;
6595 if(inList[cellId] > 0)
continue;
6597 if(this->a_isBndryCell(cellId)) {
6598 if(a_level(cellId) <= this->m_maxSensorRefinementLevel[sen]) {
6600 interfaceCellCounter++;
6603 MInt currentCellId = cellId;
6604 for(
MInt parentLevel = this->a_level(cellId); parentLevel >= minLevel(); parentLevel--) {
6605 const MInt parentCellId = this->c_parentId(currentCellId);
6606 if(parentCellId == -1) {
6609 inList[parentCellId] = 1;
6610 interfaceCellCounter++;
6611 currentCellId = parentCellId;
6617 std::cout <<
"Found " << interfaceCellCounter <<
" static boundary cells..." << std::endl;
6620 interfaceCellCounter = 0;
6621 MInt startSet = m_levelSetId;
6622 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
6623 if(a_isHalo(cellId))
continue;
6624 for(
MInt set = startSet; set < m_maxNoSets; set++) {
6625 if(inList[cellId] > 0)
continue;
6626 if(fabs(a_levelSetFunctionMB(cellId, set)) < this->c_cellLengthAtCell(cellId)) {
6627 if(a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
6629 interfaceCellCounter++;
6632 for(
MInt dir = 0; dir < 2 * nDim; dir++) {
6633 if(a_hasNeighbor(cellId, dir) > 0) {
6634 MInt nghbrId = c_neighborId(cellId, dir);
6635 if((a_levelSetFunctionMB(nghbrId, set) * a_levelSetFunctionMB(cellId, set) < F0)) {
6636 if(a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
6638 interfaceCellCounter++;
6648 std::cout <<
"Found " << interfaceCellCounter <<
" moving boundary cells..." << std::endl;
6651 for(
MInt level = minLevel(); level < this->m_maxSensorRefinementLevel[sen]; level++) {
6652 this->exchangeData(inList.
data());
6653 this->markSurrndCells(inList, m_bandWidth[level], level, this->m_refineDiagonals);
6657 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
6658 ASSERT(!a_isHalo(cellId),
"");
6659 if(inList(cellId) == 0) {
6660 if(a_level(cellId) == minLevel())
continue;
6661 if(inList(c_parentId(cellId)))
continue;
6662 if(c_isLeafCell(cellId)) {
6663 const MInt gridCellId = grid().tree().solver2grid(cellId);
6664 sensors[sensorOffset + sen][gridCellId] = -1.0;
6665 sensorCellFlag[gridCellId][sensorOffset + sen] =
true;
6668 if(a_level(cellId) < this->m_maxSensorRefinementLevel[sen]) {
6669 if(c_noChildren(cellId) > 0)
continue;
6670 const MInt gridCellId = grid().tree().solver2grid(cellId);
6671 sensors[sensorOffset + sen][gridCellId] = 1.0;
6672 sensorCellFlag[gridCellId][sensorOffset + sen] =
true;
6676 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
6685template <MInt nDim, MInt nDist,
class SysEqn>
6687 std::vector<std::bitset<64>>& sensorCellFlag,
6688 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
6690 m_log <<
" - Sensor preparation for the vorticity sensor" << endl;
6691 cerr0 <<
" - Sensor preparation for the vorticity sensor" << endl;
6695 std::array<MFloat, nDim> u{};
6696 std::array<std::array<MFloat, nDim>, nDim> u_p{};
6697 std::array<std::array<MFloat, nDim>, nDim> u_m{};
6700 MFloat rho_p[nDim] = {0.0};
6701 MFloat rho_m[nDim] = {0.0};
6711 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
6715 MFloat cellSizeWeight_v = 1.5;
6717 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
6718 ASSERT(!a_isHalo(cellId),
"");
6719 const MInt gridId = this->grid().tree().solver2grid(cellId);
6723 if(!a_isActive(cellId)) {
6724 sensorCellFlag[gridId][sensorOffset + sen] = 0;
6729 dx = grid().cellLengthAtLevel(c_level(cellId));
6738 calculateMacroscopicVariables(cellId, rho, u.data());
6739 if(a_hasNeighbor(cellId, 0) && a_isActive(c_neighborId(cellId, 0))) {
6740 MInt nghbrId = c_neighborId(cellId, 0);
6741 calculateMacroscopicVariables(nghbrId, rho_m[0], u_m[0].data());
6743 if(a_hasNeighbor(cellId, 1) && a_isActive(c_neighborId(cellId, 1))) {
6744 MInt nghbrId = c_neighborId(cellId, 1);
6745 calculateMacroscopicVariables(nghbrId, rho_p[0], u_p[0].data());
6747 if(a_hasNeighbor(cellId, 2) && a_isActive(c_neighborId(cellId, 2))) {
6748 MInt nghbrId = c_neighborId(cellId, 2);
6749 calculateMacroscopicVariables(nghbrId, rho_m[1], u_m[1].data());
6751 if(a_hasNeighbor(cellId, 3) && a_isActive(c_neighborId(cellId, 3))) {
6752 MInt nghbrId = c_neighborId(cellId, 3);
6753 calculateMacroscopicVariables(nghbrId, rho_p[1], u_p[1].data());
6755 if constexpr(nDim == 3) {
6756 if(a_hasNeighbor(cellId, 4) && a_isActive(c_neighborId(cellId, 4))) {
6757 MInt nghbrId = c_neighborId(cellId, 4);
6758 calculateMacroscopicVariables(nghbrId, rho_m[2], u_m[2].data());
6760 if(a_hasNeighbor(cellId, 5) && a_isActive(c_neighborId(cellId, 5))) {
6761 MInt nghbrId = c_neighborId(cellId, 5);
6762 calculateMacroscopicVariables(nghbrId, rho_p[2], u_p[2].data());
6770 if((a_hasNeighbor(cellId, 0) && a_isActive(c_neighborId(cellId, 0)))
6771 && (a_hasNeighbor(cellId, 1) && a_isActive(c_neighborId(cellId, 1)))) {
6772 dvdx = (u_p[0][1] - u_m[0][1]) / (2.0 * dx);
6773 if constexpr(nDim == 3) dwdx = (u_p[0][2] - u_m[0][2]) / (2.0 * dx);
6776 else if((!a_hasNeighbor(cellId, 0) || !a_isActive(c_neighborId(cellId, 0)))
6777 && (a_hasNeighbor(cellId, 1) && a_isActive(c_neighborId(cellId, 1)))) {
6778 dvdx = (u_p[0][1] - u[1]) / dx;
6779 if constexpr(nDim == 3) dwdx = (u_p[0][2] - u[2]) / dx;
6782 else if((a_hasNeighbor(cellId, 0) && a_isActive(c_neighborId(cellId, 0)))
6783 && (!a_hasNeighbor(cellId, 1) || !a_isActive(c_neighborId(cellId, 1)))) {
6784 dvdx = (u[1] - u_m[0][1]) / dx;
6785 if constexpr(nDim == 3) dwdx = (u[2] - u_m[0][2]) / dx;
6788 if((a_hasNeighbor(cellId, 2) && a_isActive(c_neighborId(cellId, 2)))
6789 && (a_hasNeighbor(cellId, 3) && a_isActive(c_neighborId(cellId, 3)))) {
6790 dudy = (u_p[1][0] - u_m[1][0]) / (2.0 * dx);
6791 if constexpr(nDim == 3) dwdy = (u_p[1][2] - u_m[1][2]) / (2.0 * dx);
6794 else if((!a_hasNeighbor(cellId, 2) || !a_isActive(c_neighborId(cellId, 2)))
6795 && (a_hasNeighbor(cellId, 3) && a_isActive(c_neighborId(cellId, 3)))) {
6796 dudy = (u_p[1][0] - u[0]) / dx;
6797 if constexpr(nDim == 3) dwdy = (u_p[1][2] - u[2]) / dx;
6800 else if((a_hasNeighbor(cellId, 2) && a_isActive(c_neighborId(cellId, 2)))
6801 && (!a_hasNeighbor(cellId, 3) || !a_isActive(c_neighborId(cellId, 3)))) {
6802 dudy = (u[0] - u_m[1][0]) / dx;
6803 if constexpr(nDim == 3) dwdy = (u[2] - u_m[1][2]) / dx;
6805 if constexpr(nDim == 3) {
6809 if((a_hasNeighbor(cellId, 4) && a_isActive(c_neighborId(cellId, 4)))
6810 && (a_hasNeighbor(cellId, 5) && a_isActive(c_neighborId(cellId, 5)))) {
6811 dudz = (u_p[2][0] - u_m[2][0]) / (2.0 * dx);
6812 dvdz = (u_p[2][1] - u_m[2][1]) / (2.0 * dx);
6815 else if((!a_hasNeighbor(cellId, 4) || !a_isActive(c_neighborId(cellId, 4)))
6816 && (a_hasNeighbor(cellId, 5) && a_isActive(c_neighborId(cellId, 5)))) {
6817 dudz = (u_p[2][0] - u[0]) / dx;
6818 dvdz = (u_p[2][1] - u[1]) / dx;
6821 else if((a_hasNeighbor(cellId, 4) && a_isActive(c_neighborId(cellId, 4)))
6822 && (!a_hasNeighbor(cellId, 5) || !a_isActive(c_neighborId(cellId, 5)))) {
6823 dudz = (u[0] - u_m[2][0]) / dx;
6824 dvdz = (u[1] - u_m[2][1]) / dx;
6827 phi_v = sqrt(pow((dwdy - dvdz), 2) + pow((dudz - dwdx), 2) + pow((dvdx - dudy), 2)) * pow(dx, cellSizeWeight_v);
6829 if constexpr(nDim == 2) phi_v = abs(dvdx - dudy) * pow(dx, cellSizeWeight_v);
6831 sensors[sensorOffset + sen][gridId] = phi_v;
6832 sensorCellFlag[gridId][sensorOffset + sen] = 1;
6842template <MInt nDim, MInt nDist,
class SysEqn>
6844 std::vector<std::bitset<64>>& sensorCellFlag,
6845 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
6847 m_log <<
" - Sensor preparation for the divergence sensor" << endl;
6848 cerr0 <<
" - Sensor preparation for the divergence sensor" << endl;
6852 std::array<MFloat, nDim> u{};
6853 std::array<std::array<MFloat, nDim>, nDim> u_p{};
6854 std::array<std::array<MFloat, nDim>, nDim> u_m{};
6857 MFloat rho_p[nDim] = {0.0};
6858 MFloat rho_m[nDim] = {0.0};
6866 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
6870 MFloat cellSizeWeight_m = 1.0;
6872 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
6873 ASSERT(!a_isHalo(cellId),
"");
6874 const MInt gridId = this->grid().tree().solver2grid(cellId);
6878 if(!a_isActive(cellId)) {
6879 sensorCellFlag[gridId][sensorOffset + sen] = 0;
6884 dx = grid().cellLengthAtLevel(c_level(cellId));
6893 calculateMacroscopicVariables(cellId, rho, u.data());
6894 if(a_hasNeighbor(cellId, 0) && a_isActive(c_neighborId(cellId, 0))) {
6895 MInt nghbrId = c_neighborId(cellId, 0);
6896 calculateMacroscopicVariables(nghbrId, rho_m[0], u_m[0].data());
6898 if(a_hasNeighbor(cellId, 1) && a_isActive(c_neighborId(cellId, 1))) {
6899 MInt nghbrId = c_neighborId(cellId, 1);
6900 calculateMacroscopicVariables(nghbrId, rho_p[0], u_p[0].data());
6902 if(a_hasNeighbor(cellId, 2) && a_isActive(c_neighborId(cellId, 2))) {
6903 MInt nghbrId = c_neighborId(cellId, 2);
6904 calculateMacroscopicVariables(nghbrId, rho_m[1], u_m[1].data());
6906 if(a_hasNeighbor(cellId, 3) && a_isActive(c_neighborId(cellId, 3))) {
6907 MInt nghbrId = c_neighborId(cellId, 3);
6908 calculateMacroscopicVariables(nghbrId, rho_p[1], u_p[1].data());
6910 if constexpr(nDim == 3) {
6911 if(a_hasNeighbor(cellId, 4) && a_isActive(c_neighborId(cellId, 4))) {
6912 MInt nghbrId = c_neighborId(cellId, 4);
6913 calculateMacroscopicVariables(nghbrId, rho_m[2], u_m[2].data());
6915 if(a_hasNeighbor(cellId, 5) && a_isActive(c_neighborId(cellId, 5))) {
6916 MInt nghbrId = c_neighborId(cellId, 5);
6917 calculateMacroscopicVariables(nghbrId, rho_p[2], u_p[2].data());
6922 if((a_hasNeighbor(cellId, 0) && a_isActive(c_neighborId(cellId, 0)))
6923 && (a_hasNeighbor(cellId, 1) && a_isActive(c_neighborId(cellId, 1)))) {
6924 dudx = (rho_p[0] * u_p[0][0] - rho_m[0] * u_m[0][0]) / (2.0 * dx);
6927 else if((!a_hasNeighbor(cellId, 0) || !a_isActive(c_neighborId(cellId, 0)))
6928 && (a_hasNeighbor(cellId, 1) && a_isActive(c_neighborId(cellId, 1)))) {
6929 dudx = (rho_p[0] * u_p[0][0] - rho * u[0]) / dx;
6932 else if((a_hasNeighbor(cellId, 0) && a_isActive(c_neighborId(cellId, 0)))
6933 && (!a_hasNeighbor(cellId, 1) || !a_isActive(c_neighborId(cellId, 1)))) {
6934 dudx = (rho * u[0] - rho_m[0] * u_m[0][0]) / dx;
6937 if((a_hasNeighbor(cellId, 2) && a_isActive(c_neighborId(cellId, 2)))
6938 && (a_hasNeighbor(cellId, 3) && a_isActive(c_neighborId(cellId, 3)))) {
6939 dvdy = (rho_p[1] * u_p[1][1] - rho_m[1] * u_m[1][1]) / (2.0 * dx);
6942 else if((!a_hasNeighbor(cellId, 2) || !a_isActive(c_neighborId(cellId, 2)))
6943 && (a_hasNeighbor(cellId, 3) && a_isActive(c_neighborId(cellId, 3)))) {
6944 dvdy = (rho_m[1] * u_p[1][1] - rho * u[1]) / dx;
6947 else if((a_hasNeighbor(cellId, 2) && a_isActive(c_neighborId(cellId, 2)))
6948 && (!a_hasNeighbor(cellId, 3) || !a_isActive(c_neighborId(cellId, 3)))) {
6949 dvdy = (rho * u[1] - rho_m[1] * u_m[1][1]) / dx;
6951 if constexpr(nDim == 3) {
6954 if((a_hasNeighbor(cellId, 4) && a_isActive(c_neighborId(cellId, 4)))
6955 && (a_hasNeighbor(cellId, 5) && a_isActive(c_neighborId(cellId, 5)))) {
6956 dwdz = (rho_p[2] * u_p[2][2] - rho_m[2] * u_m[2][2]) / (2.0 * dx);
6959 else if((!a_hasNeighbor(cellId, 4) || !a_isActive(c_neighborId(cellId, 4)))
6960 && (a_hasNeighbor(cellId, 5) && a_isActive(c_neighborId(cellId, 5)))) {
6961 dwdz = (rho_p[2] * u_p[2][2] - rho * u[2]) / dx;
6964 else if((a_hasNeighbor(cellId, 4) && a_isActive(c_neighborId(cellId, 4)))
6965 && (!a_hasNeighbor(cellId, 5) || !a_isActive(c_neighborId(cellId, 5)))) {
6966 dwdz = (rho * u[2] - rho_m[2] * u_m[2][2]) / dx;
6969 phi_m = abs(dudx + dvdy + dwdz) * pow(dx, cellSizeWeight_m);
6973 if constexpr(nDim == 2) phi_m = abs(dudx + dvdy) * pow(dx, cellSizeWeight_m);
6975 sensors[sensorOffset + sen][gridId] = phi_m;
6976 sensorCellFlag[gridId][sensorOffset + sen] = 1;
6986template <MInt nDim, MInt nDist,
class SysEqn>
6988 std::vector<std::bitset<64>>& sensorCellFlag,
6989 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
6991 m_log <<
" - Sensor preparation for the total pressure sensor" << endl;
6992 cerr0 <<
" - Sensor preparation for the total pressure sensor" << endl;
6995 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
6999 MFloat cellSizeWeight_p = 1.0;
7001 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
7002 ASSERT(!a_isHalo(cellId),
"");
7003 const MInt gridId = this->grid().tree().solver2grid(cellId);
7007 if(!a_isActive(cellId)) {
7008 sensorCellFlag[gridId][sensorOffset + sen] = 0;
7013 const MFloat dx = grid().cellLengthAtLevel(c_level(cellId));
7023 std::array<MFloat, nDim> u{};
7024 calculateMacroscopicVariables(cellId, rho, u.data());
7029 const MFloat rho_0 = 1.0;
7030 const MFloat p_0 = rho_0 / 3.0;
7031 const MFloat p = rho / 3.0;
7032 const MFloat pTotal_0 = 0.5 * rho_0 * (m_Ma * LBCS) * (m_Ma * LBCS) + p_0;
7033 const MFloat squaredVelocity = std::inner_product(u.begin(), u.end(), u.begin(), 0.0);
7034 const MFloat pTotal = 0.5 * rho * squaredVelocity + p;
7035 const MFloat phi_p = abs(pTotal_0 - pTotal) * pow(dx, cellSizeWeight_p);
7036 sensors[sensorOffset + sen][gridId] = phi_p;
7037 sensorCellFlag[gridId][sensorOffset + sen] = 1;
7049template <MInt nDim, MInt nDist,
class SysEqn>
7051 std::vector<std::bitset<64>>& sensorCellFlag,
7052 std::vector<MFloat>& sensorWeight,
MInt sensorOffset,
7055 TERMM(1,
"Not implemented for 3D");
7059 m_log <<
" - Sensor preparation for the mean stress sensor" << endl;
7060 cerr0 <<
" - Sensor preparation for the mean stress sensor" << endl;
7063 sensorWeight[sensorOffset + sen] = this->m_sensorWeight[sen];
7067 const MFloat cellSizeWeight = 1.0;
7069 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
7070 ASSERT(!a_isHalo(cellId),
"");
7071 const MInt gridId = this->grid().tree().solver2grid(cellId);
7075 if(!a_isActive(cellId)) {
7076 sensorCellFlag[gridId][sensorOffset + sen] = 0;
7081 const MFloat rho = a_variable(cellId, PV->RHO);
7082 std::array<MFloat, 2> u = {a_variable(cellId, PV->U), a_variable(cellId, PV->V)};
7084 std::array<MFloat, nDist> eqDist{};
7085 eqDist = getEqDists(rho, u.data());
7088 std::array<MFloat, 9> d{};
7089 for(
MInt j = 0; j < 9; j++) {
7090 d[j] = a_oldDistribution(cellId, j) - eqDist[j];
7094 std::array<MFloat, 4> Q{};
7095 Q[0] = (d[0] + d[1] + d[4] + d[5] + d[6] + d[7]);
7096 Q[1] = (d[4] - d[5] + d[6] - d[7]);
7099 Q[3] = (d[2] + d[3] + d[4] + d[5] + d[6] + d[7]);
7102 for(
MInt k = 0; k < 4; k++) {
7103 Qmean += Q[k] * Q[k];
7106 Qmean = sqrt(2 * Qmean);
7109 const MFloat dx = grid().cellLengthAtLevel(c_level(cellId));
7111 const MFloat phi = Qmean * pow(dx, cellSizeWeight);
7113 sensors[sensorOffset + sen][gridId] = phi;
7114 sensorCellFlag[gridId][sensorOffset + sen] = 1;
7122template <MInt nDim, MInt nDist,
class SysEqn>
7124 if(m_isRefined || this->m_adaptation) {
7133 m_bndCnd->initializeBcData();
7136template <MInt nDim, MInt nDist,
class SysEqn>
7142 if constexpr(nDim == 3) {
7143 MInt startSet = this->m_levelSetId;
7144 static constexpr MInt maxNoDistributions = IPOW3[nDim];
7145 static constexpr MInt firstCornerDist = 18;
7146 static constexpr MInt firstEdgeDist = 6;
7147 static constexpr MInt noEdges = 12;
7151 static constexpr MInt lb_CornerMappingForSurfaces[6][4] = {{18, 19, 20, 21}, {22, 23, 24, 25}, {18, 19, 22, 23},
7152 {20, 21, 24, 25}, {18, 20, 22, 24}, {19, 21, 23, 25}};
7154 static constexpr MInt lb_CornerMappingForEdges[12][2] = {{18, 19}, {20, 21}, {22, 23}, {24, 25},
7155 {18, 20}, {19, 21}, {22, 24}, {23, 25},
7156 {18, 22}, {19, 23}, {20, 24}, {21, 25}};
7158 static constexpr MInt lb_geomIntersToLb[8] = {0, 4, 2, 6, 1, 5, 3, 7};
7160 static constexpr MFloat factor[26] = {F1, F1, F1, F1, F1, F1, SQRT2, SQRT2, SQRT2,
7161 SQRT2, SQRT2, SQRT2, SQRT2, SQRT2, SQRT2, SQRT2, SQRT2, SQRT2,
7162 SQRT3, SQRT3, SQRT3, SQRT3, SQRT3, SQRT3, SQRT3, SQRT3};
7168 this->m_currentNoG0Cells = 0;
7169 m_bndCnd->m_boundaryCellsMb.noDistances(nDist - 1);
7170 m_bndCnd->m_boundaryCellsMb.reset(this->m_noG0CandidatesTotal);
7171 m_bndCnd->m_boundaryCellMappingMb.clear();
7173 for(
MInt candidate = 0; candidate < this->m_noG0CandidatesTotal; candidate++) {
7174 for(
MInt set = startSet; set < this->m_maxNoSets; set++) {
7175 const MInt arrayPosNGV = set * (maxNoDistributions - 1);
7177 this->m_nodalGValues[candidate][arrayPosNGV + firstCornerDist + lb_geomIntersToLb[i]] =
7178 this->m_G0Candidates[candidate].nodalValues[set][i];
7182 MInt edgeCounter = 0;
7183 for(
MInt edge = 0; edge < noEdges; edge++) {
7184 MFloat edgeGValue = this->m_nodalGValues[candidate][arrayPosNGV + Ld::nodalConnectivityVector(edge, 0)]
7185 * this->m_nodalGValues[candidate][arrayPosNGV + Ld::nodalConnectivityVector(edge, 1)];
7187 if(edgeGValue < 0) edgeCounter++;
7191 const MInt pCellId = this->m_G0Candidates[candidate].cellId;
7192 const MInt actualSet = set - startSet;
7193 if(edgeCounter < 2) {
7194 this->a_isG0CandidateOfSet(pCellId, actualSet) =
false;
7197 this->a_isG0CandidateOfSet(pCellId, actualSet) =
true;
7198 this->m_G0CellMapping[pCellId] = this->m_currentNoG0Cells;
7200 m_bndCnd->m_boundaryCellMappingMb[pCellId] = this->m_currentNoG0Cells;
7205 const MInt boundaryCellId = m_bndCnd->m_boundaryCellsMb.size();
7206 m_bndCnd->m_boundaryCellsMb.append();
7207 m_bndCnd->m_boundaryCellsMb.cellId(boundaryCellId) = pCellId;
7210 this->m_G0CellList[this->m_currentNoG0Cells] = pCellId;
7212 for(
MInt i = 0; i < 4; i++) {
7213 this->m_nodalGValues[candidate][arrayPosNGV +
dist] +=
7214 this->m_nodalGValues[candidate][arrayPosNGV + lb_CornerMappingForSurfaces[
dist][i]];
7216 this->m_nodalGValues[candidate][arrayPosNGV +
dist] /= F4;
7219 for(
MInt i = 0; i < 2; i++) {
7220 this->m_nodalGValues[candidate][arrayPosNGV +
dist] +=
7221 this->m_nodalGValues[candidate][arrayPosNGV + lb_CornerMappingForEdges[
dist - firstEdgeDist][i]];
7223 this->m_nodalGValues[candidate][arrayPosNGV +
dist] /= F2;
7227 MInt arrayPosWallDists = (set - startSet) * (nDist - 1);
7229 for(
MInt dir = 0; dir < nDist - 1; dir++) {
7230 if((this->a_levelSetFunctionMB(pCellId, set) * this->m_nodalGValues[candidate][arrayPosNGV + dir]) > 0) {
7232 m_bndCnd->m_boundaryCellsMb.distance(boundaryCellId, arrayPosWallDists + dir) = F2;
7235 abs(this->m_nodalGValues[candidate][arrayPosNGV + dir] / this->a_levelSetFunctionMB(pCellId, set));
7236 MFloat cellLength = this->c_cellLengthAtLevel(this->a_level(pCellId)) * F1B2 * factor[dir];
7237 m_bndCnd->m_boundaryCellsMb.distance(boundaryCellId, arrayPosWallDists + dir) =
7238 cellLength / (levelSetRatio + F1);
7243 for(
MInt n = 0; n < nDim; n++) {
7244 m_bndCnd->m_boundaryCellsMb.surfaceCenter(boundaryCellId, dir, n) =
7245 a_coordinate(pCellId, n)
7246 + m_bndCnd->m_boundaryCellsMb.distance(boundaryCellId, dir) * Ld::ppdfDir(dir, n) * 1 / factor[dir];
7249 for(
MInt n = 0; n < nDim; n++) {
7250 m_bndCnd->m_boundaryCellsMb.cellCenter(boundaryCellId, n) = a_coordinate(pCellId, n);
7253 this->m_currentNoG0Cells++;
7285 const MInt startSet = this->m_levelSetId;
7286 constexpr MInt maxNoDistributions = 9;
7287 constexpr MInt firstCornerDist = 4;
7288 constexpr MInt noEdges = 4;
7293 m_bndCnd->m_boundaryCellsMb.noDistances(nDist - 1);
7294 m_bndCnd->m_boundaryCellsMb.reset(this->m_noG0CandidatesTotal);
7295 constexpr MInt lb_CornerMappingForEdges[4][2] = {{6, 7}, {4, 5}, {5, 6}, {7, 4}};
7296 constexpr MFloat factor[8] = {F1, F1, F1, F1, SQRT2, SQRT2, SQRT2, SQRT2};
7303 this->m_currentNoG0Cells = 0;
7304 m_bndCnd->m_boundaryCellsMb.noDistances(nDist - 1);
7305 m_bndCnd->m_boundaryCellsMb.reset(this->m_noG0CandidatesTotal);
7306 m_bndCnd->m_boundaryCellMappingMb.clear();
7308 for(
MInt candidate = 0; candidate < this->m_noG0CandidatesTotal; candidate++) {
7309 for(
MInt set = startSet; set < this->m_maxNoSets; set++) {
7310 MInt arrayPosNGV = set * (maxNoDistributions - 1);
7311 this->m_nodalGValues[candidate][arrayPosNGV + firstCornerDist + 2] =
7312 this->m_G0Candidates[candidate].nodalValues[set][0];
7313 this->m_nodalGValues[candidate][arrayPosNGV + firstCornerDist + 1] =
7314 this->m_G0Candidates[candidate].nodalValues[set][1];
7315 this->m_nodalGValues[candidate][arrayPosNGV + firstCornerDist + 3] =
7316 this->m_G0Candidates[candidate].nodalValues[set][2];
7317 this->m_nodalGValues[candidate][arrayPosNGV + firstCornerDist + 0] =
7318 this->m_G0Candidates[candidate].nodalValues[set][3];
7322 MInt edgeCounter = 0;
7323 for(
MInt edge = 0; edge < noEdges; edge++) {
7324 MFloat edgeGValue = this->m_nodalGValues[candidate][arrayPosNGV + Ld::nodalConnectivityVector(edge, 0)]
7325 * this->m_nodalGValues[candidate][arrayPosNGV + Ld::nodalConnectivityVector(edge, 1)];
7326 if(edgeGValue <= 0) edgeCounter++;
7331 MInt pCellId = this->m_G0Candidates[candidate].cellId;
7332 MInt actualSet = set - startSet;
7333 if(edgeCounter < 2) {
7334 this->a_isG0CandidateOfSet(pCellId, actualSet) =
false;
7337 this->a_isG0CandidateOfSet(pCellId, actualSet) =
true;
7338 this->m_G0CellMapping[pCellId] = this->m_currentNoG0Cells;
7340 m_bndCnd->m_boundaryCellMappingMb[pCellId] = this->m_currentNoG0Cells;
7345 const MInt boundaryCellId = m_bndCnd->m_boundaryCellsMb.size();
7346 m_bndCnd->m_boundaryCellsMb.append();
7347 m_bndCnd->m_boundaryCellsMb.cellId(boundaryCellId) = pCellId;
7350 this->m_G0CellList[this->m_currentNoG0Cells] = pCellId;
7352 for(
MInt i = 0; i < 2; i++) {
7353 this->m_nodalGValues[candidate][arrayPosNGV +
dist] +=
7354 this->m_nodalGValues[candidate][arrayPosNGV + lb_CornerMappingForEdges[
dist][i]];
7356 this->m_nodalGValues[candidate][arrayPosNGV +
dist] /= F2;
7359 MInt arrayPosWallDists = (set - startSet) * (nDist - 1);
7361 for(
MInt dir = 0; dir < nDist - 1; dir++) {
7362 if((this->a_levelSetFunctionMB(pCellId, set) * this->m_nodalGValues[candidate][arrayPosNGV + dir]) > 0) {
7364 m_bndCnd->m_boundaryCellsMb.distance(boundaryCellId, arrayPosWallDists + dir) = F2;
7366 const MFloat levelSetRatio =
7367 abs(this->m_nodalGValues[candidate][arrayPosNGV + dir] / this->a_levelSetFunctionMB(pCellId, set));
7368 const MFloat cellLength = this->c_cellLengthAtLevel(this->a_level(pCellId)) * F1B2 * factor[dir];
7370 m_bndCnd->m_boundaryCellsMb.distance(boundaryCellId, arrayPosWallDists + dir) =
7371 cellLength / (levelSetRatio + F1);
7378 for(
MInt n = 0; n < nDim; n++) {
7379 m_bndCnd->m_boundaryCellsMb.surfaceCenter(boundaryCellId, dir, n) =
7380 a_coordinate(pCellId, n)
7381 + m_bndCnd->m_boundaryCellsMb.distance(boundaryCellId, n) * Ld::ppdfDir(dir, n) * 1 / factor[dir];
7384 for(
MInt n = 0; n < nDim; n++) {
7385 m_bndCnd->m_boundaryCellsMb.cellCenter(boundaryCellId, n) = a_coordinate(pCellId, n);
7388 this->m_currentNoG0Cells++;
7394template <MInt nDim, MInt nDist,
class SysEqn>
7399 calculateResidual();
7412template <MInt nDim, MInt nDist,
class SysEqn>
7424 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
7426 m_densityGradient = m_Ma * LBCS * 9.0 * m_nu / (m_referenceLength * m_referenceLength);
7428 constexpr MInt dir = 0;
7429 for(
MInt mi = 0; mi < Ld::dxQyFld(); mi++) {
7430 m_Fext[Ld::nFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * -1.0 * m_densityGradient;
7431 m_Fext[Ld::pFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * 1.0 * m_densityGradient;
7445 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
7446 uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
7451 m_densityGradient = 3.0 * uTau * uTau / m_referenceLength;
7453 constexpr MInt dir = 0;
7454 for(
MInt mi = 0; mi < Ld::dxQyFld(); mi++) {
7455 m_Fext[Ld::nFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * -1.0 * m_densityGradient;
7456 m_Fext[Ld::pFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * 1.0 * m_densityGradient;
7467 uTau = (
MFloat)m_ReTau / m_Re * m_Ma * LBCS;
7468 MFloat ratio = m_domainLength / (m_referenceLength * F1B2);
7470 m_densityGradient = 3.0 * uTau * uTau * ratio / m_domainLength;
7472 constexpr MInt dir = 0;
7473 for(
MInt mi = 0; mi < Ld::dxQyFld(); mi++) {
7474 m_Fext[Ld::nFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * -1.0 * m_densityGradient;
7475 m_Fext[Ld::pFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * 1.0 * m_densityGradient;
7490 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
7491 uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
7500 m_densityGradient = 3.0 * 2.0 * uTau * uTau / (F1B2 * m_referenceLength);
7502 if constexpr(nDim != 3) {
7503 std::stringstream ss;
7504 ss <<
"Init method " << m_initMethod <<
" is only available for 3D." << std::endl;
7507 constexpr MInt dir = 2;
7508 for(
MInt mi = 0; mi < Ld::dxQyFld(); mi++) {
7509 m_Fext[Ld::nFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * -1.0 * m_densityGradient;
7510 m_Fext[Ld::pFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * 1.0 * m_densityGradient;
7518 m_nu = m_Ma * LBCS / m_Re * m_referenceLength;
7524 3.0 * 8.0 * (m_Ma * LBCS) * m_nu / ((F1B2 * m_referenceLength) * (F1B2 * m_referenceLength));
7526 if constexpr(nDim != 3) {
7527 std::stringstream ss;
7528 ss <<
"Init method " << m_initMethod <<
" is only available for 3D." << std::endl;
7531 constexpr MInt dir = 2;
7532 for(
MInt mi = 0; mi < Ld::dxQyFld(); mi++) {
7533 m_Fext[Ld::nFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * -1.0 * m_densityGradient;
7534 m_Fext[Ld::pFld(dir, mi)] = Ld::tp(Ld::distType(mi)) * 1.0 * m_densityGradient;
7539template <MInt nDim, MInt nDist,
class SysEqn>
7541 static MBool firstCall =
true;
7542 static MFloat origFext[nDist];
7546 for(
MInt i = 0; i < nDist; i++) {
7547 origFext[i] = m_Fext[i];
7550 for(
MInt dir = 0; dir < nDim; dir++) {
7551 for(
MInt mi = 0; mi < Ld::dxQyFld(); mi++) {
7552 m_Fext[Ld::nFld(dir, mi)] =
7553 origFext[Ld::nFld(dir, mi)] + Ld::tp(Ld::distType(Ld::nFld(dir, mi))) * -1.0 * m_volumeAccel[dir] * 3.0;
7554 m_Fext[Ld::pFld(dir, mi)] =
7555 origFext[Ld::pFld(dir, mi)] + Ld::tp(Ld::distType(Ld::pFld(dir, mi))) * 1.0 * m_volumeAccel[dir] * 3.0;
7560 for(
MInt dir = 0; dir < nDim; dir++) {
7561 for(
MInt mi = 0; mi < Ld::dxQyFld(); mi++) {
7562 m_EELiquid.Fg[Ld::nFld(dir, mi)] =
7563 Ld::tp(Ld::distType(Ld::nFld(dir, mi))) * -1.0 * m_EELiquid.gravityAccelM[dir] * 3.0;
7564 m_EELiquid.Fg[Ld::pFld(dir, mi)] =
7565 Ld::tp(Ld::distType(Ld::pFld(dir, mi))) * 1.0 * m_EELiquid.gravityAccelM[dir] * 3.0;
7584template <MInt nDim, MInt nDist,
class SysEqn>
7585template <MBool compressible>
7591 maia::parallelFor<true>(0, m_currentMaxNoCells, [=](
MInt i) {
7592 const MInt pCellId = m_activeCellList[i];
7593 const MInt lvlDiff = maxLevel() - c_level(pCellId);
7594 if((gTS) %
IPOW2(lvlDiff) != 0)
return;
7598#ifdef WAR_NVHPC_PSTL
7600 for(
MInt d = 0; d < nDim; d++) {
7601 u[d] = a_variable(pCellId, d);
7603 calculateMacroscopicVariables<compressible>(pCellId, a_variable(pCellId, PV->RHO), u);
7604 for(
MInt d = 0; d < nDim; d++) {
7605 a_variable(pCellId, d) = u[d];
7608 calculateMacroscopicVariables<compressible>(pCellId, a_variable(pCellId, PV->RHO), &a_variable(pCellId, PV->U));
7610 MFloat eqDist[nDist], trgEqDist[nDist];
7611#ifdef WAR_NVHPC_PSTL
7612 for(
MInt d = 0; d < nDim; d++) {
7613 u[d] = a_variable(pCellId, d);
7615 sysEqn().calcEqDists(a_variable(pCellId, PV->RHO), u, &eqDist[0], m_mFld1.data(), m_mFld2.data(), m_tp.data(),
7618 sysEqn().calcEqDists(a_variable(pCellId, PV->RHO), &a_variable(pCellId, PV->U), &eqDist[0]);
7621 for(
MInt d = 0; d < nDim; d++) {
7622 a_variable(pCellId, PV->U + d) = a_oldVariable(pCellId, PV->U + d);
7624#ifdef WAR_NVHPC_PSTL
7625 for(
MInt d = 0; d < nDim; d++) {
7626 u[d] = a_variable(pCellId, d);
7628 sysEqn().calcEqDists(a_variable(pCellId, PV->RHO), u, &trgEqDist[0], m_mFld1.data(), m_mFld2.data(), m_tp.data(),
7631 sysEqn().calcEqDists(a_variable(pCellId, PV->RHO), &a_variable(pCellId, PV->U), &trgEqDist[0]);
7634 for(
MInt j = 0; j < nDist; j++) {
7635 a_oldDistribution(pCellId, j) = a_oldDistribution(pCellId, j) + trgEqDist[j] - eqDist[j];
7640template <MInt nDim, MInt nDist,
class SysEqn>
7642 if(this->isCompressible()) {
7643 initRunCorrection_<true>();
7645 initRunCorrection_<false>();
7659template <MInt nDim, MInt nDist,
class SysEqn>
7663 MInt xPos, yPos, zPos;
7664 MInt lx = 0, ly = 0, lz = 0;
7668 lx = m_arraySize[0] /
FPOW2(maxLevel() - minLevel());
7669 ly = m_arraySize[1] /
FPOW2(maxLevel() - minLevel());
7670 if(nDim == 3) lz = m_arraySize[2] /
FPOW2(maxLevel() - minLevel());
7672 fftw_complex *uPhysField, *vPhysField, *wPhysField;
7675 uPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
7676 vPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
7677 wPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
7684 if(domainId() == 0) {
7689 for(
MInt p = 0; p < lx; p++) {
7690 for(
MInt q = 0; q < ly; q++) {
7691 for(
MInt r = 0; r < lz; r++) {
7692 sendRecvBufferU[r + lz * (q + ly * p)] = uPhysField[r + lz * (q + ly * p)][0];
7693 sendRecvBufferV[r + lz * (q + ly * p)] = vPhysField[r + lz * (q + ly * p)][0];
7694 sendRecvBufferW[r + lz * (q + ly * p)] = wPhysField[r + lz * (q + ly * p)][0];
7700 MPI_Bcast(&sendRecvBufferU[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferU[0]");
7701 MPI_Bcast(&sendRecvBufferV[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferV[0]");
7702 MPI_Bcast(&sendRecvBufferW[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferW[0]");
7704 if(domainId() != 0) {
7706 for(
MInt p = 0; p < lx; p++) {
7707 for(
MInt q = 0; q < ly; q++) {
7708 for(
MInt r = 0; r < lz; r++) {
7709 uPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferU[r + lz * (q + ly * p)];
7710 vPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferV[r + lz * (q + ly * p)];
7711 wPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferW[r + lz * (q + ly * p)];
7718 MFloat rho, u[3] = {0.0, 0.0, 0.0}, uTau, yPlus;
7721 if(m_densityFluctuations)
7726 uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
7730 MFloat tmpWidth = m_referenceLength * m_smallestCellLength;
7733 cerr <<
" --- prescribing mean velocity profile for turbulent channel ---" << endl;
7734 for(
MInt i = 0; i < a_noCells(); i++) {
7737 yPlus = m_ReTau * (1.0 - fabs(a_coordinate(i, 1)) / tmpWidth);
7740 if(yPlus < 0 || yPlus > m_ReTau) {
7741 stringstream errorMessage;
7742 errorMessage <<
"incorrect value for yPlus: " << yPlus <<
" exiting...";
7743 TERMM(1, errorMessage.str());
7748 u[0] = uTau * yPlus;
7750 if(yPlus <= 30 && yPlus > 5.0) {
7751 u[0] = uTau * (C1 * log(yPlus) + C2);
7754 u[0] = uTau * (C3 * log(yPlus) + C4);
7762 actualCellLength = this->grid().cellLengthAtCell(i);
7765 (F1B2 * lx + (a_coordinate(i, 0) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
7767 (F1B2 * ly + (a_coordinate(i, 1) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
7769 (F1B2 * lz + (a_coordinate(i, 2) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
7771 if(xPos > lx - 1 || xPos < 0 || yPos > ly - 1 || yPos < 0 || zPos > lz - 1 || zPos < 0) {
7772 cerr <<
"ERROR: wrong array position!" << endl;
7773 cerr <<
"pos=" << xPos <<
", " << yPos <<
", " << zPos << endl;
7774 cerr <<
"coorda = (" << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2) <<
")"
7776 cerr <<
"actuallength=" << actualCellLength <<
", smallestlength=" << m_smallestCellLength << endl;
7777 cerr <<
"minlevel=" << minLevel() <<
", maxLevel=" << maxLevel() << endl;
7778 cerr <<
"lenght on level0=" << this->c_cellLengthAtLevel(0) << endl;
7779 TERMM(1,
"Wrong array position");
7783 u[0] += uPhysField[zPos + lz * (yPos + ly * xPos)][0];
7784 u[1] += vPhysField[zPos + lz * (yPos + ly * xPos)][0];
7785 u[2] += wPhysField[zPos + lz * (yPos + ly * xPos)][0];
7792 a_variable(i, PV->RHO) = rho;
7793 a_oldVariable(i, PV->RHO) = rho;
7795 a_variable(i, PV->U) = u[0];
7796 a_oldVariable(i, PV->U) = u[0];
7798 a_variable(i, PV->V) = u[1];
7799 a_oldVariable(i, PV->V) = u[1];
7801 a_variable(i, PV->W) = u[2];
7802 a_oldVariable(i, PV->W) = u[2];
7807 initEqDistFunctions();
7810 fftw_free(uPhysField);
7811 fftw_free(vPhysField);
7812 fftw_free(wPhysField);
7816 TERMM(1,
"Init method only available for D3Qy, yet!");
7829template <MInt nDim, MInt nDist,
class SysEqn>
7832 MInt xPos, yPos, zPos;
7833 MInt lx = 0, ly = 0, lz = 0;
7837 lx = m_arraySize[0] /
FPOW2(maxLevel() - minLevel());
7838 ly = m_arraySize[1] /
FPOW2(maxLevel() - minLevel());
7839 if(nDim == 3) lz = m_arraySize[2] /
FPOW2(maxLevel() - minLevel());
7841 fftw_complex *uPhysField, *vPhysField, *wPhysField;
7844 uPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
7845 vPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
7846 wPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
7854 if(domainId() == 0) {
7859 for(
MInt p = 0; p < lx; p++) {
7860 for(
MInt q = 0; q < ly; q++) {
7861 for(
MInt r = 0; r < lz; r++) {
7862 sendRecvBufferU[r + lz * (q + ly * p)] = uPhysField[r + lz * (q + ly * p)][0];
7863 sendRecvBufferV[r + lz * (q + ly * p)] = vPhysField[r + lz * (q + ly * p)][0];
7864 sendRecvBufferW[r + lz * (q + ly * p)] = wPhysField[r + lz * (q + ly * p)][0];
7870 MPI_Bcast(&sendRecvBufferU[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferU[0]");
7871 MPI_Bcast(&sendRecvBufferV[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferV[0]");
7872 MPI_Bcast(&sendRecvBufferW[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferW[0]");
7874 if(domainId() != 0) {
7876 for(
MInt p = 0; p < lx; p++) {
7877 for(
MInt q = 0; q < ly; q++) {
7878 for(
MInt r = 0; r < lz; r++) {
7879 uPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferU[r + lz * (q + ly * p)];
7880 vPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferV[r + lz * (q + ly * p)];
7881 wPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferW[r + lz * (q + ly * p)];
7889 MFloat rho, u[3] = {0.0, 0.0, 0.0}, uTau, yPlus;
7893 if(m_densityFluctuations)
7898 uTau = (
MFloat)m_ReTau * m_nu / m_referenceLength;
7901 MFloat tmpWidth = F1B2 * m_referenceLength * m_smallestCellLength;
7903 cerr <<
" --- prescribing mean velocity profile for turbulent pipe ---" << endl;
7904 for(
MInt i = 0; i < a_noCells(); i++) {
7907 radius = sqrt(a_coordinate(i, 0) * a_coordinate(i, 0) + a_coordinate(i, 1) * a_coordinate(i, 1));
7909 yPlus = m_ReTau * (1.0 - radius / tmpWidth);
7915 u[2] = uTau * yPlus;
7917 if(yPlus <= 30 && yPlus > 5.0) {
7918 u[2] = uTau * (C1 * log(yPlus) + C2);
7921 u[2] = uTau * (C3 * log(yPlus) + C4);
7926 actualCellLength = this->grid().cellLengthAtCell(i);
7929 (F1B2 * lx + (a_coordinate(i, 0) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
7931 (F1B2 * ly + (a_coordinate(i, 1) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
7934 zPos = floor(((a_coordinate(i, 2) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
7936 if(xPos > lx - 1 || xPos < 0 || yPos > ly - 1 || yPos < 0 || zPos > lz - 1 || zPos < 0) {
7937 stringstream errorMessage;
7938 errorMessage <<
"ERROR: wrong array position!" << endl;
7939 errorMessage <<
"pos=" << xPos <<
", " << yPos <<
", " << zPos << endl;
7940 errorMessage <<
"coorda = (" << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2)
7942 errorMessage <<
"actuallength=" << actualCellLength <<
", smallestlength=" << m_smallestCellLength << endl;
7943 errorMessage <<
"minlevel=" << minLevel() <<
", maxLevel=" << maxLevel() << endl;
7944 errorMessage <<
"length on level0=" << this->c_cellLengthAtLevel(0) << endl;
7945 TERMM(1, errorMessage.str());
7954 u[0] += 2.0 * uPhysField[zPos + lz * (yPos + ly * xPos)][0] * u[2] / (uTau * (C3 * log(m_ReTau) + C4));
7955 u[1] += 2.0 * vPhysField[zPos + lz * (yPos + ly * xPos)][0] * u[2] / (uTau * (C3 * log(m_ReTau) + C4));
7956 u[2] += 2.0 * wPhysField[zPos + lz * (yPos + ly * xPos)][0] * u[2] / (uTau * (C3 * log(m_ReTau) + C4));
7958 a_variable(i, PV->RHO) = rho;
7959 a_oldVariable(i, PV->RHO) = rho;
7961 a_variable(i, PV->U) = u[0];
7962 a_oldVariable(i, PV->U) = u[0];
7964 a_variable(i, PV->V) = u[1];
7965 a_oldVariable(i, PV->V) = u[1];
7967 a_variable(i, PV->W) = u[2];
7968 a_oldVariable(i, PV->W) = u[2];
7973 initEqDistFunctions();
7976 fftw_free(uPhysField);
7977 fftw_free(vPhysField);
7978 fftw_free(wPhysField);
7982 TERMM(1,
"Init method only available for D3Qy, yet!");
7996template <MInt nDim, MInt nDist,
class SysEqn>
7999 MInt xPos, yPos, zPos;
8000 MInt lx = 0, ly = 0, lz = 0;
8003 MFloat GaussFactor, sigma, deltaOmega0;
8005 MFloat rho = 1.0, u[3] = {0.0, 0.0, 0.0};
8009 lx = m_arraySize[0] /
FPOW2(maxLevel() - minLevel());
8010 ly = m_arraySize[1] /
FPOW2(maxLevel() - minLevel());
8011 if(nDim == 3) lz = m_arraySize[2] /
FPOW2(maxLevel() - minLevel());
8013 fftw_complex *uPhysField, *vPhysField, *wPhysField;
8016 uPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
8017 vPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
8018 wPhysField = (fftw_complex*)fftw_malloc(lx * ly * lz *
sizeof(fftw_complex));
8024 if(domainId() == 0) {
8029 for(
MInt p = 0; p < lx; p++) {
8030 for(
MInt q = 0; q < ly; q++) {
8031 for(
MInt r = 0; r < lz; r++) {
8032 sendRecvBufferU[r + lz * (q + ly * p)] = uPhysField[r + lz * (q + ly * p)][0];
8033 sendRecvBufferV[r + lz * (q + ly * p)] = vPhysField[r + lz * (q + ly * p)][0];
8034 sendRecvBufferW[r + lz * (q + ly * p)] = wPhysField[r + lz * (q + ly * p)][0];
8040 MPI_Bcast(&sendRecvBufferU[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferU[0]");
8041 MPI_Bcast(&sendRecvBufferV[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferV[0]");
8042 MPI_Bcast(&sendRecvBufferW[0], lx * ly * lz, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferW[0]");
8044 if(domainId() != 0) {
8046 for(
MInt p = 0; p < lx; p++) {
8047 for(
MInt q = 0; q < ly; q++) {
8048 for(
MInt r = 0; r < lz; r++) {
8049 uPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferU[r + lz * (q + ly * p)];
8050 vPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferV[r + lz * (q + ly * p)];
8051 wPhysField[r + lz * (q + ly * p)][0] = sendRecvBufferW[r + lz * (q + ly * p)];
8059 MFloat* bBoxPtr = &bBox[0];
8061 m_geometry->getBoundingBox(bBoxPtr);
8064 if(m_densityFluctuations)
8070 deltaOmega0 = m_referenceLength * m_smallestCellLength;
8074 sigma = F1B2 * deltaOmega0;
8076 m_log <<
" initial macroscopic vorticity thickness: " << deltaOmega0 << endl;
8078 cerr <<
" --- prescribing mean velocity profile for turbulent mixing layer ---" << endl;
8079 for(
MInt i = 0; i < a_noCells(); i++) {
8082 GaussFactor = exp(-(a_coordinate(i, 1) / sigma) * (a_coordinate(i, 1) / sigma) * F1B2);
8084 u[0] = m_Ma * LBCS * tanh(2.0 * a_coordinate(i, 1) / deltaOmega0);
8088 actualCellLength = this->grid().cellLengthAtCell(i);
8091 (F1B2 * lx + (a_coordinate(i, 0) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
8093 (F1B2 * ly + (a_coordinate(i, 1) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
8096 (F1B2 * lz + (a_coordinate(i, 2) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(minLevel()))) + 0.1);
8098 if(xPos > lx - 1 || xPos < 0 || yPos > ly - 1 || yPos < 0 || zPos > lz - 1 || zPos < 0) {
8099 stringstream errorMessage;
8100 errorMessage <<
"ERROR: wrong array position!" << endl;
8101 errorMessage <<
"pos=" << xPos <<
", " << yPos <<
", " << zPos << endl;
8102 errorMessage <<
"coorda = (" << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2)
8104 errorMessage <<
"actuallength=" << actualCellLength <<
", smallestlength=" << m_smallestCellLength << endl;
8105 errorMessage <<
"minlevel=" << minLevel() <<
", maxLevel=" << maxLevel() << endl;
8106 errorMessage <<
"lenght on level0=" << this->c_cellLengthAtLevel(0) << endl;
8107 TERMM(1, errorMessage.str());
8115 u[0] += uPhysField[zPos + lz * (yPos + ly * xPos)][0] * GaussFactor;
8116 u[1] += vPhysField[zPos + lz * (yPos + ly * xPos)][0] * GaussFactor;
8117 u[2] += wPhysField[zPos + lz * (yPos + ly * xPos)][0] * GaussFactor;
8119 a_variable(i, PV->RHO) = rho;
8120 a_variable(i, PV->U) = u[0];
8121 a_variable(i, PV->V) = u[1];
8122 a_variable(i, PV->W) = u[2];
8124 a_oldVariable(i, PV->RHO) = rho;
8127 a_oldVariable(i, PV->U) = u[0];
8130 a_oldVariable(i, PV->V) = u[1];
8133 a_oldVariable(i, PV->W) = u[2];
8140 initNonEqDistFunctions();
8143 fftw_free(uPhysField);
8144 fftw_free(vPhysField);
8145 fftw_free(wPhysField);
8149 TERMM(1,
"Init method only available for D3Qy, yet!");
8164template <MInt nDim, MInt nDist,
class SysEqn>
8168 MInt xPos, yPos, zPos;
8169 MInt lx = 0, ly = 0, lz = 0;
8170 MInt lxCoarse = 0, lyCoarse = 0, lzCoarse = 0;
8173 MFloat GaussFactor, sigma, deltaOmega0;
8175 MFloat rho, u[3] = {0.0, 0.0, 0.0};
8178 if(m_densityFluctuations)
8185 lx = m_arraySize[0];
8186 ly = m_arraySize[1];
8187 if(nDim == 3) lz = m_arraySize[2];
8195 ScratchSpace<MFloat> uPhysFieldCoarse(lxCoarse * lyCoarse * lzCoarse, AT_,
"uPhysFieldCoarse");
8196 ScratchSpace<MFloat> vPhysFieldCoarse(lxCoarse * lyCoarse * lzCoarse, AT_,
"vPhysFieldCoarse");
8197 ScratchSpace<MFloat> wPhysFieldCoarse(lxCoarse * lyCoarse * lzCoarse, AT_,
"wPhysFieldCoarse");
8204 if(domainId() == 0) {
8206 MFloat* uPhysFieldCoarsePtr = &uPhysFieldCoarse[0];
8207 MFloat* vPhysFieldCoarsePtr = &vPhysFieldCoarse[0];
8208 MFloat* wPhysFieldCoarsePtr = &wPhysFieldCoarse[0];
8210 lyCoarse, lzCoarse, m_noPeakModes, m_Ma);
8213 for(
MInt p = 0; p < lxCoarse; p++) {
8214 for(
MInt q = 0; q < lyCoarse; q++) {
8215 for(
MInt r = 0; r < lzCoarse; r++) {
8216 sendRecvBufferU[r + lzCoarse * (q + lyCoarse * p)] = uPhysFieldCoarse[r + lzCoarse * (q + lyCoarse * p)];
8217 sendRecvBufferV[r + lzCoarse * (q + lyCoarse * p)] = vPhysFieldCoarse[r + lzCoarse * (q + lyCoarse * p)];
8218 sendRecvBufferW[r + lzCoarse * (q + lyCoarse * p)] = wPhysFieldCoarse[r + lzCoarse * (q + lyCoarse * p)];
8224 MPI_Bcast(&sendRecvBufferU[0], lxCoarse * lyCoarse * lzCoarse, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferU[0]");
8225 MPI_Bcast(&sendRecvBufferV[0], lxCoarse * lyCoarse * lzCoarse, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferV[0]");
8226 MPI_Bcast(&sendRecvBufferW[0], lxCoarse * lyCoarse * lzCoarse, MPI_DOUBLE, 0, mpiComm(), AT_,
"sendRecvBufferW[0]");
8228 if(domainId() != 0) {
8230 for(
MInt p = 0; p < lxCoarse; p++) {
8231 for(
MInt q = 0; q < lyCoarse; q++) {
8232 for(
MInt r = 0; r < lzCoarse; r++) {
8233 uPhysFieldCoarse[r + lzCoarse * (q + lyCoarse * p)] = sendRecvBufferU[r + lzCoarse * (q + lyCoarse * p)];
8234 vPhysFieldCoarse[r + lzCoarse * (q + lyCoarse * p)] = sendRecvBufferV[r + lzCoarse * (q + lyCoarse * p)];
8235 wPhysFieldCoarse[r + lzCoarse * (q + lyCoarse * p)] = sendRecvBufferW[r + lzCoarse * (q + lyCoarse * p)];
8242 MFloat* bBoxPtr = &bBox[0];
8243 m_geometry->getBoundingBox(bBoxPtr);
8246 deltaOmega0 = m_referenceLength * m_smallestCellLength;
8250 sigma = deltaOmega0;
8252 m_log <<
" initial macroscopic vorticity thickness: " << deltaOmega0 << endl;
8254 cerr <<
" --- prescribing mean velocity profile for turbulent mixing layer ---" << endl;
8255 for(
MInt i = 0; i < a_noCells(); i++) {
8258 GaussFactor = exp(-(a_coordinate(i, 1) / sigma) * (a_coordinate(i, 1) / sigma) * F1B2);
8260 u[0] = m_Ma * LBCS * tanh(2.0 * a_coordinate(i, 1) / deltaOmega0);
8264 actualCellLength = this->grid().cellLengthAtCell(i);
8267 (F1B2 * lxCoarse + (a_coordinate(i, 0) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
8270 (F1B2 * lyCoarse + (a_coordinate(i, 1) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
8274 (F1B2 * lzCoarse + (a_coordinate(i, 2) - F1B2 * (actualCellLength)) / (this->c_cellLengthAtLevel(maxLevel())))
8277 if(xPos > lxCoarse - 1 || xPos < 0 || yPos > lyCoarse - 1 || yPos < 0 || zPos > lzCoarse - 1 || zPos < 0) {
8278 cerr <<
"ERROR: wrong array position!" << endl;
8279 cerr <<
"pos=" << xPos <<
", " << yPos <<
", " << zPos << endl;
8280 cerr <<
"coorda = (" << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2) <<
", " << a_coordinate(i, 2) <<
")"
8282 cerr <<
"actuallength=" << actualCellLength <<
", smallestlength=" << m_smallestCellLength << endl;
8283 cerr <<
"minlevel=" << minLevel() <<
", maxLevel=" << maxLevel() << endl;
8284 cerr <<
"lenght on level0=" << this->c_cellLengthAtLevel(0) << endl;
8285 TERMM(1,
"Wrong array position");
8293 u[0] += uPhysFieldCoarse[zPos + lzCoarse * (yPos + lyCoarse * xPos)] * GaussFactor;
8294 u[1] += vPhysFieldCoarse[zPos + lzCoarse * (yPos + lyCoarse * xPos)] * GaussFactor;
8295 u[2] += wPhysFieldCoarse[zPos + lzCoarse * (yPos + lyCoarse * xPos)] * GaussFactor;
8297 a_variable(i, PV->RHO) = rho;
8298 a_variable(i, PV->U) = u[0];
8299 a_variable(i, PV->V) = u[1];
8300 a_variable(i, PV->W) = u[2];
8302 a_oldVariable(i, PV->RHO) = rho;
8305 a_oldVariable(i, PV->U) = u[0];
8308 a_oldVariable(i, PV->V) = u[1];
8311 a_oldVariable(i, PV->W) = u[2];
8318 initNonEqDistFunctions();
8323 TERMM(1,
"Init method only available for D3Qy, yet!");
8340template <MInt nDim, MInt nDist,
class SysEqn>
8344 IF_CONSTEXPR(nDim == 2) TERMM(-1,
"Only works for 3D!");
8345 const MFloat time0 = MPI_Wtime();
8346 const MInt fftLevel = grid().maxUniformRefinementLevel();
8347 const MFloat DX = c_cellLengthAtLevel(fftLevel);
8348 if(fftLevel > grid().maxUniformRefinementLevel()) {
8349 mTerm(1, AT_,
"Isotropic mesh expected (0).");
8351 MInt noVars = nDim + 1;
8353 std::array<MFloat, nDim * 2> bBox;
8354 m_geometry->getBoundingBox(bBox.data());
8378 const MFloat dxeps = 0.1 * DX;
8379 MInt nx = (bBox[3] - bBox[0] + dxeps) / DX;
8380 MInt ny = (bBox[4] - bBox[1] + dxeps) / DX;
8381 MInt nz = (bBox[5] - bBox[2] + dxeps) / DX;
8382 const MInt size = nx * ny * nz;
8384 getReLambdaAndUrmsInit();
8385 if(domainId() == 0) cerr <<
"UrmsInit: " << m_UrmsInit << endl <<
"ReLambdaInit: " << m_ReLambda << endl;
8388 const MFloat nuCheck = m_referenceLength * m_UrmsInit / m_Re;
8389 if(abs(nuCheck - m_nu) > 0.01 * m_nu)
8390 mTerm(1, AT_,
"nu_LB and nu_check are not consistent! Check Re, Ma and UrmsInit");
8393 MFloat UInfinity = m_UrmsInit;
8395 MBool goodSpectrum =
false;
8398 MInt spectrumId = 2;
8399 spectrumId = Context::getSolverProperty<MInt>(
"spectrumId", this->m_solverId, AT_, &spectrumId);
8401 kpRatio = Context::getSolverProperty<MFloat>(
"kpRatio", this->m_solverId, AT_, &kpRatio);
8403 while(!goodSpectrum) {
8404 fftw_complex* uPhysField;
8405 fftw_complex* nabla2P =
nullptr;
8408 seed =
maia::math::initFft(uPhysField, nabla2P, nx, ny, nz, kpRatio, spectrumId, fftInfo, mpiComm(),
8411 if(domainId() == 0) {
8412 std::cerr <<
"Theoretical SPECTRUM: kinetic energy: " << 1.5 *
POW2(m_UrmsInit)
8413 <<
", dissipation rate * Box length / Urms,0^3: "
8414 << 72.0 *
POW2(kpRatio * PI) * m_nu / (m_UrmsInit * nx) <<
")"
8415 <<
", integral length/unit length: " << F3B8 / kpRatio <<
")" << std::endl;
8418 MInt maxRank = fftInfo[0];
8419 MInt local_n0 = fftInfo[1];
8420 MInt local_0_start = fftInfo[2];
8421 MInt alloc_local = fftInfo[3];
8424 MInt sendIdsSize = 0;
8427 MPI_Allgather(&locOffsetIds, 1, MPI_INT, &offsetsIds[0], 1, MPI_INT, mpiComm(), AT_,
"locOffsetIds",
8433 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8434 if(a_isHalo(cellId))
continue;
8435 if(a_isBndryGhostCell(cellId))
continue;
8436 if(a_level(cellId) != fftLevel)
continue;
8437 MFloat actualCellLength = grid().cellLengthAtLevel(a_level(cellId));
8438 MInt xPos = floor((F1B2 * nx + (a_coordinate(cellId, 0) - F1B2 * (actualCellLength)) / DX) + 0.1);
8439 MInt yPos = floor((F1B2 * ny + (a_coordinate(cellId, 1) - F1B2 * (actualCellLength)) / DX) + 0.1);
8440 MInt zPos = floor((F1B2 * nz + (a_coordinate(cellId, 2) - F1B2 * (actualCellLength)) / DX) + 0.1);
8442 MInt nghbrDomain =
mMin(maxRank - 1, pos / (size / maxRank));
8443 while(pos < offsetsIds(nghbrDomain) || pos >= offsetsIds(nghbrDomain + 1)) {
8444 if(pos < offsetsIds(nghbrDomain)) nghbrDomain--;
8445 if(pos >= offsetsIds(nghbrDomain + 1)) nghbrDomain++;
8447 if(nghbrDomain >= maxRank)
mTerm(1, AT_,
"wrong domain");
8448 noSendIds(nghbrDomain)++;
8453 sendIdsOffsets[0] = 0;
8454 sendIdsOffsetsTmp[0] = 0;
8456 sendIdsOffsets[nghbrDomain + 1] = sendIdsOffsets[nghbrDomain] + noSendIds[nghbrDomain];
8457 sendIdsOffsetsTmp[nghbrDomain + 1] = sendIdsOffsets[nghbrDomain] + noSendIds[nghbrDomain];
8462 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8463 if(a_isHalo(cellId))
continue;
8464 if(a_isBndryGhostCell(cellId))
continue;
8465 if(a_level(cellId) != fftLevel)
continue;
8466 MFloat actualCellLength = grid().cellLengthAtLevel(a_level(cellId));
8467 MInt xPos = floor((F1B2 * nx + (a_coordinate(cellId, 0) - F1B2 * (actualCellLength)) / DX) + 0.1);
8468 MInt yPos = floor((F1B2 * ny + (a_coordinate(cellId, 1) - F1B2 * (actualCellLength)) / DX) + 0.1);
8469 MInt zPos = floor((F1B2 * nz + (a_coordinate(cellId, 2) - F1B2 * (actualCellLength)) / DX) + 0.1);
8471 MInt nghbrDomain =
mMin(maxRank - 1, pos / (size / maxRank));
8472 while(pos < offsetsIds(nghbrDomain) || pos >= offsetsIds(nghbrDomain + 1)) {
8473 if(pos < offsetsIds(nghbrDomain)) nghbrDomain--;
8474 if(pos >= offsetsIds(nghbrDomain + 1)) nghbrDomain++;
8476 if(nghbrDomain >= maxRank)
mTerm(1, AT_,
"wrong domain");
8477 sendIds[sendIdsOffsetsTmp[nghbrDomain]++] = pos;
8481 MPI_Alltoall(&noSendIds[0], 1, MPI_INT, &noRecvIds[0], 1, MPI_INT, mpiComm(), AT_,
"noSendIds[0]",
"noRecvIds[0]");
8484 recvIdsOffsets[0] = 0;
8485 MInt recvIdsSize = 0;
8487 recvIdsOffsets[nghbrDomain + 1] = recvIdsOffsets[nghbrDomain] + noRecvIds[nghbrDomain];
8488 recvIdsSize += noRecvIds[nghbrDomain];
8494 MPI_Alltoallv(&sendIds[0], &noSendIds[0], &sendIdsOffsets[0], MPI_INT, &recvIds[0], &noRecvIds[0],
8495 &recvIdsOffsets[0], MPI_INT, mpiComm(), AT_,
"sendIds[0]",
"recvIds[0]");
8500 sendVarsOffsets[0] = 0;
8501 sendVarsOffsetsTmp[0] = 0;
8502 MInt sendVarsSize = 0;
8504 sendVarsOffsets[i + 1] = sendVarsOffsets[i] + noRecvIds[i] * 3;
8505 sendVarsOffsetsTmp[i + 1] = sendVarsOffsetsTmp[i] + noRecvIds[i] * 3;
8506 noSendVars[i] = noRecvIds[i] * 3;
8507 sendVarsSize += noRecvIds[i] * 3;
8509 if(recvIdsSize != 0) {
8518 MFloat upr[3] = {F0, F0, F0};
8519 for(
MInt i = 0; i < recvIdsSize; i++) {
8520 MInt pos = recvIds[i];
8521 ASSERT(pos > -1 && pos < size,
"");
8522 if(!(pos >= ((
MInt)local_0_start) * nx * ny && pos < ((
MInt)(local_0_start + local_n0) * ny * nx))) {
8523 mTerm(1, AT_,
"Position not available on this domain(1).");
8525 MInt localPos = pos - (((
MInt)local_0_start) * ny * nz);
8526 if(3 * localPos + 2 > alloc_local) {
8527 mTerm(1, AT_,
"index exceeds array(1)");
8529 sendVars[i * 3] = uPhysField[3 * localPos][0];
8530 sendVars[i * 3 + 1] = uPhysField[3 * localPos + 1][0];
8531 sendVars[i * 3 + 2] = uPhysField[3 * localPos + 2][0];
8533 MFloat u = uPhysField[3 * localPos][0];
8534 MFloat v = uPhysField[3 * localPos + 1][0];
8535 MFloat w = uPhysField[3 * localPos + 2][0];
8542 MPI_Allreduce(MPI_IN_PLACE, &cnt, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"cnt");
8543 MPI_Allreduce(MPI_IN_PLACE, &upr, 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"upr");
8545 MFloat uprime0 = sqrt(F1B3 * (upr[0] + upr[1] + upr[2]) / cnt);
8547 fftw_free(uPhysField);
8551 recvVarsOffsets[0] = 0;
8552 MInt recvVarsSize = 0;
8554 recvVarsOffsets[i + 1] = recvVarsOffsets[i] + noSendIds[i] * 3;
8555 noRecvVars[i] = noSendIds[i] * 3;
8556 recvVarsSize += noSendIds[i] * 3;
8564 MPI_Alltoallv(&sendVars[0], &noSendVars[0], &sendVarsOffsets[0], MPI_DOUBLE, &recvVars[0], &noRecvVars[0],
8565 &recvVarsOffsets[0], MPI_DOUBLE, mpiComm(), AT_,
"sendVars[0]",
"recvVars[0]");
8571 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8572 if(a_isHalo(cellId))
continue;
8573 if(a_isBndryGhostCell(cellId))
continue;
8574 if(a_level(cellId) != fftLevel)
continue;
8575 MFloat actualCellLength = grid().cellLengthAtLevel(a_level(cellId));
8576 MInt xPos = floor((F1B2 * nx + (a_coordinate(cellId, 0) - F1B2 * (actualCellLength)) / DX) + 0.1);
8577 MInt yPos = floor((F1B2 * ny + (a_coordinate(cellId, 1) - F1B2 * (actualCellLength)) / DX) + 0.1);
8578 MInt zPos = floor((F1B2 * nz + (a_coordinate(cellId, 2) - F1B2 * (actualCellLength)) / DX) + 0.1);
8580 MInt nghbrDomain =
mMin(maxRank - 1, pos / (size / maxRank));
8581 while(pos < offsetsIds(nghbrDomain) || pos >= offsetsIds(nghbrDomain + 1)) {
8582 if(pos < offsetsIds(nghbrDomain)) nghbrDomain--;
8583 if(pos >= offsetsIds(nghbrDomain + 1)) nghbrDomain++;
8585 if(nghbrDomain >= maxRank)
mTerm(1, AT_,
"wrong domain");
8586 if(sendIds[sendIdsOffsets[nghbrDomain]] != pos)
mTerm(1, AT_,
"pos mismatch");
8587 MFloat u = recvVars[sendIdsOffsets[nghbrDomain] * 3];
8588 MFloat v = recvVars[sendIdsOffsets[nghbrDomain] * 3 + 1];
8589 MFloat w = recvVars[sendIdsOffsets[nghbrDomain] * 3 + 2];
8591 sendIdsOffsets[nghbrDomain]++;
8595 a_variable(cellId, PV->U) = u;
8596 a_variable(cellId, PV->V) = v;
8597 a_variable(cellId, PV->W) = w;
8598 a_variable(cellId, PV->RHO) = rhoInfinity;
8603 MPI_Allreduce(MPI_IN_PLACE, &cnt, 1, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"cnt");
8604 MPI_Allreduce(MPI_IN_PLACE, &upr, 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"upr");
8606 MFloat uprime1 = sqrt(F1B3 * (upr[0] + upr[1] + upr[2]) / cnt);
8607 upr[0] = sqrt(upr[0] / cnt);
8608 upr[1] = sqrt(upr[1] / cnt);
8609 upr[2] = sqrt(upr[2] / cnt);
8611 if(fabs(uprime0 - uprime1) > exp(-10))
mTerm(1, AT_,
"Communication went wrong.");
8614 cerr <<
"initial urpime: " << upr[0] <<
" " << upr[1] <<
" " << upr[2] <<
" (" << uprime1 <<
")" << endl;
8624 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8625 if(a_isHalo(cellId))
continue;
8626 if(a_isBndryGhostCell(cellId))
continue;
8627 if(a_level(cellId) != fftLevel)
continue;
8629 MFloat u = a_variable(cellId, PV->U) * UInfinity / uprime1;
8630 MFloat v = a_variable(cellId, PV->V) * UInfinity / uprime1;
8631 MFloat w = a_variable(cellId, PV->W) * UInfinity / uprime1;
8633 a_variable(cellId, PV->U) = u;
8634 a_variable(cellId, PV->V) = v;
8635 a_variable(cellId, PV->W) = w;
8638 exchangeData(&a_variable(0, 0), noVars);
8640 MFloat umean[3] = {F0, F0, F0};
8641 MFloat urms[6] = {F0, F0, F0, F0, F0, F0};
8642 MFloat reyn[6] = {F0, F0, F0, F0, F0, F0};
8643 MFloat aniso[6] = {F0, F0, F0, F0, F0, F0};
8644 MFloat dudx[3] = {F0, F0, F0};
8645 MFloat skew[4] = {F0, F0, F0, F0};
8646 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8647 if(a_isHalo(cellId))
continue;
8648 if(a_isBndryGhostCell(cellId))
continue;
8649 if(a_level(cellId) != fftLevel)
continue;
8650 MFloat u = a_variable(cellId, PV->U);
8651 MFloat v = a_variable(cellId, PV->V);
8652 MFloat w = a_variable(cellId, PV->W);
8653 for(
MInt i = 0; i < nDim; i++) {
8654 MInt n0 = (a_hasNeighbor(cellId, 2 * i) > 0) ? c_neighborId(cellId, 2 * i) : cellId;
8655 MInt n1 = (a_hasNeighbor(cellId, 2 * i + 1) > 0) ? c_neighborId(cellId, 2 * i + 1) : cellId;
8656 if(n0 == n1)
continue;
8657 dudx[i] +=
POW2((a_variable(n1, PV->VV[i]) - a_variable(n0, PV->VV[i]))
8658 / ((a_coordinate(n1, i) - a_coordinate(n0, i)) / DX));
8659 skew[i] +=
POW3((a_variable(n1, PV->VV[i]) - a_variable(n0, PV->VV[i]))
8660 / ((a_coordinate(n1, i) - a_coordinate(n0, i)) / DX));
8672 MPI_Allreduce(MPI_IN_PLACE, &urms[0], 6, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"urms[0]");
8673 MPI_Allreduce(MPI_IN_PLACE, &umean[0], 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"umean[0]");
8674 MPI_Allreduce(MPI_IN_PLACE, &dudx[0], 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"dudx[0]");
8675 MPI_Allreduce(MPI_IN_PLACE, &skew[0], 3, MPI_DOUBLE, MPI_SUM, mpiComm(), AT_,
"MPI_IN_PLACE",
"skew[0]");
8676 skew[3] = ((skew[0] + skew[1] + skew[2]) / (F3 * cnt)) / pow((dudx[0] + dudx[1] + dudx[2]) / (F3 * cnt), 1.5);
8677 for(
MInt i = 0; i < 3; i++)
8678 skew[i] = (skew[i] / cnt) / pow(dudx[i] / cnt, 1.5);
8679 for(
MInt i = 0; i < 6; i++)
8680 reyn[i] = urms[i] / cnt;
8681 for(
MInt i = 0; i < 6; i++)
8682 aniso[i] = urms[i] / (urms[0] + urms[1] + urms[2]);
8683 for(
MInt i = 0; i < 3; i++)
8685 for(
MInt i = 0; i < 6; i++)
8686 urms[i] = sqrt(fabs(urms[i]) / cnt);
8687 for(
MInt i = 0; i < 3; i++)
8689 for(
MInt i = 0; i < 3; i++)
8694 for(
MInt i = 0; i < 3; i++)
8695 lambda[i] = urms[i] / sqrt(dudx[i]);
8698 cerr <<
"u_mean: " << umean[0] <<
" " << umean[1] <<
" " << umean[2] <<
" (" << (
MInt)cnt <<
")" << endl;
8700 cerr <<
"u_rms/u_inf: " << urms[0] / UInfinity <<
" " << urms[1] / UInfinity <<
" " << urms[2] / UInfinity <<
" "
8701 << urms[3] / UInfinity <<
" " << urms[4] / UInfinity <<
" " << urms[5] / UInfinity <<
" ("
8702 << F1B3 * (urms[0] + urms[1] + urms[2]) / UInfinity <<
")" << endl;
8704 cerr <<
"skewness: " << skew[0] <<
" " << skew[1] <<
" " << skew[2] <<
" (" << skew[3] <<
")" << endl;
8706 cerr <<
"Anisotropy: " << aniso[0] <<
" " << aniso[1] <<
" " << aniso[2] <<
" " << aniso[3] <<
" " << aniso[4]
8707 <<
" " << aniso[5] << endl;
8709 cerr <<
"Reynolds stress: " << reyn[0] <<
" " << reyn[1] <<
" " << reyn[2] <<
" " << reyn[3] <<
" " << reyn[4]
8710 <<
" " << reyn[5] << endl;
8712 cerr <<
"Realizability 1: " << reyn[3] * reyn[3] <<
" <= " << reyn[0] * reyn[1] <<
", " << reyn[4] * reyn[4]
8713 <<
" <= " << reyn[0] * reyn[2] <<
", " << reyn[5] * reyn[5] <<
" <= " << reyn[1] * reyn[2] << endl;
8715 cerr <<
"Realizability 2: det = "
8716 << reyn[0] * reyn[1] * reyn[2] + F2 * reyn[3] * reyn[4] * reyn[5] - reyn[0] * reyn[5] * reyn[5]
8717 - reyn[1] * reyn[4] * reyn[4] - reyn[2] * reyn[4] * reyn[4]
8723 const MFloat time1 = MPI_Wtime();
8724 m_log <<
"initFFT time " << time1 - time0 << endl;
8750 for(
MInt i = 0; i < 3; i++)
8751 Rel[i] = urms[i] * lambda[i] / m_nu;
8752 Rel[3] = F1B3 * (urms[0] + urms[1] + urms[2]) * F1B3 * (lambda[0] + lambda[1] + lambda[2]) / m_nu;
8754 if(domainId() == 0) {
8755 cerr <<
"Re_lambda: " << Rel[0] <<
" " << Rel[1] <<
" " << Rel[2] <<
" (" << Rel[3] <<
", "
8756 << F1B3 * (Rel[0] + Rel[1] + Rel[2]) <<
")" << endl;
8758 const MFloat lambdaAvg = F1B3 * (lambda[0] + lambda[1] + lambda[2]);
8759 cerr <<
"lambda: " << lambda[0] <<
" " << lambda[1] <<
" " << lambda[2] <<
" (" << lambdaAvg <<
") "
8760 <<
"lambda / Lb: " << lambdaAvg / m_referenceLength << endl;
8764 for(
MInt i = 0; i < 3; i++) {
8765 eps[i] = (15.0 * m_nu * dudx[i]) * m_referenceLength /
POW3(urms[i]);
8766 eps2[i] = 15.0 * m_nu *
POW2(urms[i] / lambda[i]);
8769 if(domainId() == 0) {
8770 cerr <<
"eps: " << eps[0] <<
" " << eps[1] <<
" " << eps[2] <<
" (" << F1B3 * (eps[0] + eps[1] + eps[2]) <<
")"
8773 const MFloat eps2Avg = F1B3 * (eps2[0] + eps2[1] + eps2[2]);
8774 cerr <<
"eps2: " << eps2[0] <<
" " << eps2[1] <<
" " << eps2[2] <<
" (" << eps2Avg <<
")"
8775 <<
" eps2 * Box length / Urms,0^3: " << eps2Avg * m_referenceLength /
POW3(m_UrmsInit) << endl;
8779 / pow(F1B3 * (eps2[0] + eps2[1] + eps2[2]), 0.25);
8780 cerr <<
"Kolmogorov length: " << eta <<
" Kolmogorov length / Lb: " << eta / m_referenceLength << endl;
8782 MFloat maxd =
mMax(fabs(Rel[0] - Rel[1]),
mMax(fabs(Rel[0] - Rel[2]), fabs(Rel[1] - Rel[2])));
8783 if(maxd < F1)
m_log <<
"spectrum " << maxd <<
" " << F1B3 * (Rel[0] + Rel[1] + Rel[2]) <<
" " << seed << endl;
8786 goodSpectrum =
true;
8787 if(domainId() == 0)
m_log <<
"spectrum " << seed << endl;
8791 if(domainId() == 0) cerr <<
"seed " << seed << endl;
8796 if(fftLevel < grid().maxUniformRefinementLevel()) {
8797 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8798 if(a_isHalo(cellId))
continue;
8799 if(a_isBndryGhostCell(cellId))
continue;
8800 if(a_level(cellId) <= fftLevel)
continue;
8801 if(c_noChildren(cellId) > 0)
continue;
8802 MInt parentId = c_parentId(cellId);
8803 while(a_level(parentId) != fftLevel) {
8804 parentId = c_parentId(parentId);
8806 if(a_level(parentId) == fftLevel) {
8807 for(
MInt varId = 0; varId < noVars; varId++) {
8808 a_variable(cellId, varId) = a_variable(parentId, varId);
8809 std::cout <<
"a_variable(" << cellId <<
"," << varId <<
"): " << a_variable(parentId, varId) << std::endl;
8814 exchangeData(&a_variable(0, 0), noVars);
8816 for(
MInt cellId = 0; cellId < a_noCells(); cellId++) {
8817 for(
MInt varId = 0; varId < noVars; varId++) {
8818 a_oldVariable(cellId, varId) = a_variable(cellId, varId);
8823 initEqDistFunctions();
8825 m_log <<
"**************************" << endl;
8826 m_log <<
"Initial Condition summary" << endl;
8827 m_log <<
"**************************" << endl;
8828 m_log <<
"Re = " << m_Re << endl;
8829 m_log <<
"Ma = " << m_Ma << endl;
8830 m_log <<
"UInfinity = " << UInfinity << endl;
8831 m_log <<
"rhoInfinity = " << rhoInfinity << endl;
8834 for(
MInt cellId = 0; cellId < noInternalCells(); cellId++) {
8835 for(
MInt v = 0; v < PV->noVariables; v++) {
8836 if(std::isnan(a_variable(cellId, v))) {
8837 cerr <<
"Variable " << v <<
" cellId : " << cellId << endl;
8838 mTerm(1, AT_,
"Invalid initialcondition formulation!");
8844 computeFFTStatistics();
8848 mTerm(1, AT_,
"Init method only available for D3Qy, yet!");
8851#ifdef WAR_NVHPC_PSTL
8852template <MInt nDim, MInt nDist,
class SysEqn>
8861 m_oppositeDist.fill(-1);
8863 for(
MInt i = 0; i < 50; i++) {
8864 m_faculty[i] = faculty[i];
8867 MInt fldlen = Ld::dxQyFld();
8868 for(
MInt i = 0; i < fldlen; i++) {
8869 for(
MInt d = 0; d < nDim; d++) {
8870 m_nFld[d * fldlen + i] = Ld::nFld(d, i);
8871 m_pFld[d * fldlen + i] = Ld::pFld(d, i);
8875 for(
MInt i = 0; i <
POWX(3, nDim); i++) {
8876 for(
MInt j = 0; j <
POWX(3, nDim); j++) {
8877 m_idFld[i][j] = Ld::idFld(i, j);
8881 for(
MInt i = 0; i < 24; i++) {
8882 m_mFld1[i] = Ld::mFld1(i);
8883 m_mFld2[i] = Ld::mFld2(i);
8886 for(
MInt i = 0; i < nDist; i++) {
8887 m_oppositeDist[i] = Ld::oppositeDist(i);
8890 for(
MInt i = 0; i < 4; i++) {
8891 m_tp[i] = Ld::tp(i);
8894 for(
MInt i = 0; i < 3; i++) {
8895 m_distFld[i] = Ld::distFld(i);
8898 for(
MInt i = 0; i < nDist; i++) {
8899 for(
MInt j = 0; j < nDim; j++) {
8900 m_ppdfDir[i * nDim + j] = Ld::ppdfDir(i, j);
8904 for(
MInt i = 0; i < nDist; i++) {
8905 m_distType[i] = Ld::distType(i);
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
void open(const MString &filename, const MString &projectName, MInt fileType=0, MPI_Comm mpiComm=MPI_COMM_WORLD, MBool rootOnlyHardwired=false)
Opens a file by passing the parameters to InfoOut_<xyz>FileBuffer::open(...).
Interface class holding all relevant data and methods for treating prolongation, restriction and init...
This class represents all LB models.
void updateViscosity() override
Update viscosity (a_nu and a_oldNu)
void sensorInterface(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
Simple boundary sensor for ensuring boundary refinement during adaptation.
void postPropagationSrcTerm() override
Calls the post collision routine of the source term controller.
void sensorDivergence(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
virtual void bgkc_transport_collision_step()
Collision step for Transport Lattice-Boltzmann.
void sensorTotalPressure(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
void initLatticeBgkGaussDiffusion()
virtual void averageGlobalVelocity(const MInt dir)
calculate average velocity of velocity component dir
LbSolverDxQy(MInt id, MInt noDistributions, GridProxy &gridProxy_, Geometry< nDim > &geometry_, const MPI_Comm comm)
void calculateSGSTensors()
Calculate tensors for dynamic Smagorinsky constant.
void bgki_euler_collision_step() override
void bgki_thermal_collision_step_base()
virtual void propagation_step_transport() override
Propagation step for Transport Lattice-Boltzmann.
void initNonEqDistFunctions()
void bgki_thermal_and_transport_collision_step_base()
Collision step for coupled Thermal Transport Lattice-Boltzmann.
typename LbSolver< nDim >::GridProxy GridProxy
void initSrcTerms() override
Initialize the source term controller.
void initRunCorrection() override
virtual void propagation_step_thermaltransport() override
Propagation step for coupled Thermal Transport Lattice-Boltzmann.
virtual void propagation_step_thermal() override
virtual void restartInitLb()
void bgkc_collision_step() override
virtual void refineCellLb(const MInt parentId, const MInt *childIds)
: Initialize child variables from parent
void clb_collision_step_base()
void rbgk_collision_step_base()
virtual void bgki_innerEnergy_collision_step()
virtual void initLatticeBgkTurbulentDuct()
void bgki_smagorinsky_collision_step() override
void calculateDissipation()
Calculate total energy, dissipation, and subgrid dissipation for Smagorinsky.
void initLatticeBgkFftMixingFilter()
virtual void bgki_thermal_collision_step()
void rbgk_dynamic_smago_collision_step() override
void bgki_dynamic_smago_collision_step() override
void initLatticeBgkFftChannel()
void initLatticeBgkLaminarCylinder()
virtual void propagation_step_thermal_vol() override
Propagation step for Thermal Lattice-Boltzmann.
void cumulant_collision_step() override
virtual void initLatticeBgkTurbulentMixing()
void bgki_smago_wall_collision_step() override
virtual void bgkc_totalenergy_transport_collision_step()
Collision step for coupled Thermal Transport Lattice-Boltzmann.
void initPressureForce() override
void bgki_init_collision_step() override
Consistent initialization step of the LBGK algorithm.
void bgki_smagorinsky_collision_step_base()
void updateMacroscopicVariables()
Update macroscopic variables according to incoming PPDF.
virtual void initLatticeBgkLaminar()
virtual void propagation_step_thermaltransport_vol() override
Propagation step for coupled Thermal Transport Lattice-Boltzmann.
void mrt_smagorinsky_collision_step() override
void bgki_smagorinsky_collision_step2() override
virtual void initLatticeBgkTurbulentPipe()
virtual void propagation_step() override
standard OpenMP propagation step
void rbgk_smagorinsky_collision_step() override
virtual void initTransportEqDistFunctions()
Calculates equilibrium distribution functions after initialization of macroscopic variables.
void clb_collision_step() override
void mrt_collision_step() override
virtual void propagation_step_vol() override
This function propagates the locally calculated PPDFs to the neighboring cells after the collision st...
void mrt_collision_step_base()
Collision step for the MRT-Algorithm.
void mrt2_collision_step() override
void initLatticeBgkFftPipe()
virtual void initThermalEqDistFunctions()
Calculates equilibrium distribution functions after initialization of macroscopic variables.
LbInterfaceDxQy< nDim, nDist, SysEqn > * m_interface
virtual void bgki_totalEnergy_collision_step()
void initLatticeBgkFftMixing()
void initLatticeBgkFftIsotropicTurbulence()
void postPropagationBc() override
LbBndCndDxQy< nDim, nDist, SysEqn > LbBndCnd
void initRunCorrection_()
Iterative initialize routine to obtained a valid density and non-eq field.
void sensorVorticity(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
LbBndCnd * m_bndCnd
Pointers for the Boundary Conditions, for flow solving.
void rbgk_collision_step() override
void initEqDistFunctions()
Calculates equilibrium distribution functions after initialization of macroscopic variables.
virtual void restartBndCnd()
Restart bndCnd object.
virtual void updateVariablesFromOldDist_preCollision() override
virtual void initLatticeBgkTGV()
void preCollisionSrcTerm() override
Calls the pre collision routine of the source term controller.
void postCollisionBc() override
void clb_smagorinsky_collision_step() override
virtual void initLatticeBgkLaminarDir(MInt dir)
Initializes standard Lattice BGK laminar with or without a direction.
void initLatticeBgkGaussAdvection()
virtual MBool maxResidual()
virtual void initLatticeBgkVortex()
void initLatticeBgkGaussPulse()
void initLatticeBgkSpinningVorticies()
virtual void initializeLatticeBgk()
Initializes standard Lattice BGK.
virtual void initLatticeBgkTurbulentBoundary()
virtual void initLatticeBgkLaminarChannel()
virtual void controlVelocity()
control velocity of a periodic channel flow via volume forces
void sensorMeanStress(std::vector< std::vector< MFloat > > &sensors, std::vector< std::bitset< 64 > > &sensorCellFlag, std::vector< MFloat > &sensorWeight, MInt sensorOffset, MInt sen) override
virtual void initLatticeBgkLaminarPipe()
virtual void calcNodalLsValues()
virtual void removeChildsLb(const MInt parentId)
: Initialize parent variables from children
void updateVariablesFromOldDist_()
virtual void initLatticeBgkTurbulentChannel()
void averageSGSTensors(const MInt direction, MInt &count, std::vector< MFloat > &meanTensors)
Calculate average SGS tensor.
void bgki_collision_step_Guo_forcing() override
void initSrcTermController() override
Initialize the source term controller.
virtual void calculateResidual()
Calculates residuals and prints to file.
void postCollisionSrcTerm() override
Calls the post collision routine of the source term controller.
virtual void bgkc_thermal_transport_collision_step()
Collision step for coupled Thermal Transport Lattice-Boltzmann.
virtual void bgki_collision_step()
virtual void volumeForces()
apply volumeForces to the oldDistributions
virtual void bgkc_innerenergy_transport_collision_step()
Collision step for coupled Thermal Transport Lattice-Boltzmann.
virtual void updateVariablesFromOldDist() override
virtual void propagation_step_transport_vol() override
Propagation step for Transport Lattice-Boltzmann.
void initVolumeForces() override
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
MInt string2enum(MString theString)
This global function translates strings in their corresponding enum values (integer values)....
@ LB_TURBULENT_MIXING_FILTER_INIT
@ LB_LAMINAR_CYLINDER_INIT
@ LB_GAUSS_DIFFUSION_INIT
@ LB_TURBULENCE_ISOTROPIC_INIT
@ LB_TURBULENT_CHANNEL_INIT
@ LB_GAUSS_ADVECTION_INIT
@ LB_SPINNING_VORTICIES_INIT
@ LB_CONVECTING_VORTEX_INIT
@ LB_TURBULENT_MIXING_INIT
@ LB_LAMINAR_CHANNEL_INIT
@ MAIA_LATTICE_BGK_TOTALENERGY
void mTerm(const MInt errorCode, const MString &location, const MString &message)
constexpr Real POW3(const Real x)
constexpr Real POW2(const Real x)
constexpr T mMin(const T &x, const T &y)
T constexpr POWX(T base, MUint exponent)
Compile time power calculation.
constexpr T mMax(const T &x, const T &y)
MInt globalNoDomains()
Return global number of domains.
MInt globalDomainId()
Return global domain id.
constexpr MLong IPOW2(MInt x)
constexpr MFloat FPOW2(MInt x)
constexpr MFloat FPOW4(MInt x)
constexpr MFloat FFPOW2(MInt x)
std::basic_string< char > MString
int MPI_Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status, const MString &name, const MString &varname)
same as MPI_Recv
int MPI_Barrier(MPI_Comm comm, const MString &name)
same as MPI_Barrier
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_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Reduce
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_Alltoall(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Alltoall
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
int MPI_Allgather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allgather
int MPI_Alltoallv(const void *sendbuf, const int sendcounts[], const int sdispls[], MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int rdispls[], MPI_Datatype recvtype, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Alltoallv
int MPI_Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Send
void initFftFilter(MFloat *uPhysFieldCoarse, MFloat *vPhysFieldCoarse, MFloat *wPhysFieldCoarse, MInt lx, MInt ly, MInt lz, MInt lxCoarse, MInt lyCoarse, MInt lzCoarse, MInt noPeakModes, const MFloat Ma)
Generates a velocity field from Fourier-modes using FFTW The disturbances are generated and filtered ...
void initFft(fftw_complex *uPhysField, fftw_complex *vPhysField, fftw_complex *wPhysField, MInt lx, MInt ly, MInt lz, MInt noPeakModes, const MFloat Ma)
Generates a velocity field from Fourier-modes using FFTW.
MInt getGlobalPosFFTW(MInt i0, MInt i1, MInt i2, MInt ny, MInt nz)
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)