24template <MInt nDim,
class SysEqn>
29 m_log <<
"Create Zonal coupler for RANS Solver (" << RANSSolver().m_solverId <<
") and LES Solver ("
30 << LESSolver().m_solverId <<
")" << endl;
41 m_uvRANSFactor = Context::getBasicProperty<MFloat>(
"uvRANSFactor", AT_, &m_uvRANSFactor);
46template <MInt nDim,
class SysEqn>
50 m_RANSSolverId = RANSSolver().m_solverId;
51 m_LESSolverId = LESSolver().m_solverId;
53 LESSolver().m_LESNoVarAverage = LESVarAverageData::noAvgVars;
59 determineZonalPositions();
61 if(m_cylindricCommunication) {
62 initCylinderExchange();
64 calcRANSSectorValues();
72template <MInt nDim,
class SysEqn>
76 if(m_cylindricCommunication) {
77 initCylinderExchange();
80 if(m_cylindricCommunication) {
82 calcRANSSectorValues();
89template <MInt nDim,
class SysEqn>
93 if(solverId != m_RANSSolverId || solverId != m_LESSolverId)
return;
99template <MInt nDim,
class SysEqn>
103 transferSolverData();
107template <MInt nDim,
class SysEqn>
112 if(m_cylindricCommunication) {
115 calcRANSSectorValues();
118 transferSolverData();
123template <MInt nDim,
class SysEqn>
127 LESSolver().m_averagePos.clear();
128 LESSolver().m_averageDir.clear();
136 m_7901faceNormalDir = -1;
137 m_7909faceNormalDir = -1;
138 m_7901Position = std::numeric_limits<MFloat>::infinity();
139 m_7909Position = std::numeric_limits<MFloat>::infinity();
144 for(
MInt i = 0; i < propertyLength; i++) {
145 MInt bcId = Context::getSolverProperty<MFloat>(
"cutOffBndryIds", m_RANSSolverId, AT_, i);
147 m_7901faceNormalDir = Context::getSolverProperty<MFloat>(
"cutOffDirections", m_RANSSolverId, AT_, i);
151 if(m_7901faceNormalDir != -1) {
152 m_7901faceNormalDir = (m_7901faceNormalDir % 2 == 0) ? m_7901faceNormalDir + 1 : m_7901faceNormalDir - 1;
157 for(
MInt i = 0; i < propertyLength; i++) {
158 MInt bcId = Context::getSolverProperty<MFloat>(
"cutOffBndryIds", m_LESSolverId, AT_, i);
160 m_7909faceNormalDir = Context::getSolverProperty<MFloat>(
"cutOffDirections", m_LESSolverId, AT_, i);
164 if(m_7909faceNormalDir != -1) {
165 m_7909faceNormalDir = (m_7909faceNormalDir % 2 == 0) ? m_7909faceNormalDir + 1 : m_7909faceNormalDir - 1;
168 if(m_STGSponge && m_7901faceNormalDir == -1) {
169 TERMM(1,
"m_STGSponge true, bc7901 has to be set to determine spongeCells!");
173 m_7901periodicDir = 2;
176 m_7901wallDir = Context::getSolverProperty<MInt>(
"bc7901wallDir", m_RANSSolverId, AT_);
179 m_7901periodicDir = Context::getSolverProperty<MInt>(
"bc7901periodicDir", m_RANSSolverId, AT_);
183 MFloat tmpPos7901 = ((m_7901faceNormalDir + 1) % 2 > 0) ? -std::numeric_limits<MFloat>::infinity()
184 : std::numeric_limits<MFloat>::infinity();
185 MFloat tmpPos7909 = ((m_7909faceNormalDir + 1) % 2 > 0) ? -std::numeric_limits<MFloat>::infinity()
186 : std::numeric_limits<MFloat>::infinity();
187 MFloat compFactor7901 = ((m_7901faceNormalDir + 1) % 2 > 0) ? F1 : -F1;
188 MFloat compFactor7909 = ((m_7909faceNormalDir + 1) % 2 > 0) ? F1 : -F1;
190 if(LESSolver().grid().isActive()) {
191 for(
MInt cellId = 0; cellId < a_noFvGridCellsLES(); cellId++) {
194 MFloat pos = LESSolver().a_coordinate(cellId, 0);
195 if(compFactor7901 * pos > compFactor7901 * tmpPos7901) {
198 if(compFactor7909 * pos > compFactor7909 * tmpPos7909) {
204 if(compFactor7901 > 0) {
205 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7901, 1, MPI_DOUBLE, MPI_MAX, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
208 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7901, 1, MPI_DOUBLE, MPI_MIN, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
211 if(compFactor7909 > 0) {
212 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7909, 1, MPI_DOUBLE, MPI_MAX, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
215 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7909, 1, MPI_DOUBLE, MPI_MIN, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
219 if(m_7901faceNormalDir != -1) {
220 m_7901Position = tmpPos7901;
222 if(m_7909faceNormalDir != -1) {
223 m_7909Position = tmpPos7909;
227 if(RANSSolver().grid().isActive()) {
228 if(compFactor7901 > 0) {
229 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7901, 1, MPI_DOUBLE, MPI_MAX, RANSSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
232 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7901, 1, MPI_DOUBLE, MPI_MIN, RANSSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
235 if(compFactor7909 > 0) {
236 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7909, 1, MPI_DOUBLE, MPI_MAX, RANSSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
239 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7909, 1, MPI_DOUBLE, MPI_MIN, RANSSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
242 MPI_Allreduce(MPI_IN_PLACE, &tmpPos7909, 1, MPI_DOUBLE, MPI_MAX, RANSSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
245 if(m_7901faceNormalDir != -1) {
246 m_7901Position = tmpPos7901;
248 if(m_7909faceNormalDir != -1) {
249 m_7909Position = tmpPos7909;
253 m_averagePos = m_7901Position;
254 m_averageDir = abs(m_7901wallDir + m_7901periodicDir - nDim);
256 if(!std::isinf(m_7901Position)) {
258 LESSolver().m_7901Position = m_7901Position;
259 LESSolver().m_averagePos.push_back(m_averagePos);
260 LESSolver().m_averageDir.push_back(m_averageDir);
261 LESSolver().m_averageReconstructNut.push_back(
false);
266template <MInt nDim,
class SysEqn>
271 if(RANSSolver().grid().isActive()) {
272 if(!m_cylindricCommunication) {
273 for(
MInt cellId = 0; cellId < a_noFvGridCellsRANS(); cellId++) {
276 vector<MInt>::iterator findAvgId =
277 find(LESSolver().m_LESAverageCells.begin(), LESSolver().m_LESAverageCells.end(), LESId);
278 if(findAvgId != LESSolver().m_LESAverageCells.end()) {
279 MInt avgId = distance(LESSolver().m_LESAverageCells.begin(), findAvgId);
280 for(
MInt var = 0; var < noRANSVariables(); var++) {
281 ASSERT(cellId < (
MInt)RANSSolver().m_LESValues[var].size(),
282 "Trying to access data [" + to_string(var) +
"][" + to_string(cellId)
283 +
"] in LESSolver().m_LESVarAverage(RANS) with length "
284 + to_string(RANSSolver().m_LESValues[var].size())
285 +
", domainId: " + to_string(RANSSolver().domainId()));
287 RANSSolver().m_LESValues[var][cellId] = LESSolver().m_LESVarAverage[var][avgId];
294 if(m_cylindricCommunication && m_cylinderExchangeIdsOffset > -1) {
295 for(
MInt exchangeIndex = 0; exchangeIndex < m_noRANSExchangeCells; exchangeIndex++) {
296 MInt exchangeIndexOffset = exchangeIndex + m_cylinderExchangeIdsOffset;
297 MInt RANSId = m_globalCylinderExchangeIds[exchangeIndexOffset];
298 if(RANSSolver().a_isBndryGhostCell(RANSId))
continue;
299 for(
MInt var = 0; var < noRANSVariables(); var++) {
300 ASSERT(RANSId < (
MInt)RANSSolver().m_LESValues[var].size(),
301 "Trying to access data [" + to_string(var) +
"][" + to_string(RANSId)
302 +
"] in LESSolver().m_LESVarAverage(RANS) with length "
303 + to_string(RANSSolver().m_LESValues[var].size())
304 +
", domainId: " + to_string(RANSSolver().domainId()) +
" | "
305 << RANSSolver().c_noCells());
307 RANSSolver().m_LESValues[var][RANSId] =
308 m_globalCylinderLESExchangeValues[exchangeIndexOffset * LESSolver().m_LESNoVarAverage + var];
315 if(!m_cylindricCommunication) {
317 if(LESSolver().grid().isActive()) {
318 for(
MInt LESId = 0; LESId < a_noFvGridCellsLES(); LESId++) {
322 for(
MInt var = 0; var < noRANSVariables(); var++) {
323 ASSERT(LESId < (
MInt)LESSolver().m_RANSValues[var].size(),
324 "Trying to access data [" + to_string(var) +
"][" + to_string(LESId)
325 +
"] in m_RANSValues with length " + to_string(LESSolver().m_RANSValues[var].size())
326 +
", domainId: " + to_string(LESSolver().domainId()) +
" | "
327 << LESSolver().c_noCells());
329 LESSolver().m_RANSValues[var][LESId] = RANSSolver().a_pvariable(RANSId, var);
334 const MFloat fre = 1.0 / RANSSolver().sysEqn().m_Re0;
335 const MFloat nu_t = RANSSolver().a_pvariable(RANSId, RANSSolver().m_sysEqn.PV->N);
337 MFloat du[3][3]{{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}};
338 const MInt recData = RANSSolver().a_reconstructionData(RANSId);
339 const MFloat u[3] = {RANSSolver().a_pvariable(RANSId, RANSSolver().m_sysEqn.PV->U),
340 RANSSolver().a_pvariable(RANSId, RANSSolver().m_sysEqn.PV->V),
341 RANSSolver().a_pvariable(RANSId, RANSSolver().m_sysEqn.PV->W)};
343 for(
MInt nghbr = 0; nghbr < RANSSolver().a_noReconstructionNeighbors(RANSId); nghbr++) {
344 const MInt recNghbrId = RANSSolver().a_reconstructionNeighborId(RANSId, nghbr);
345 if(recNghbrId > -1) {
346 const MFloat recConst_x = RANSSolver().m_reconstructionConstants[nDim * (recData + nghbr) + 0];
347 const MFloat recConst_y = RANSSolver().m_reconstructionConstants[nDim * (recData + nghbr) + 1];
348 const MFloat recConst_z = RANSSolver().m_reconstructionConstants[nDim * (recData + nghbr) + 2];
349 for(
MInt dim = 0; dim < nDim; ++dim) {
351 RANSSolver().a_pvariable(recNghbrId, RANSSolver().m_sysEqn.PV->VV[dim]) - u[dim];
352 du[dim][0] += recConst_x * delta_u;
353 du[dim][1] += recConst_y * delta_u;
354 du[dim][2] += recConst_z * delta_u;
358 MFloat sij[3][3]{{F0, F0, F0}, {F0, F0, F0}, {F0, F0, F0}};
360 for(
MInt d1 = 0; d1 < nDim; d1++) {
361 for(
MInt d2 = 0; d2 < nDim; d2++) {
362 sij[d1][d2] = 0.5 * (du[d1][d2] + du[d2][d1]);
363 SijSij += sij[d1][d2] * sij[d1][d2];
366 const MFloat sr1 = (sij[0][1] + sij[1][0]) * (sij[0][1] + sij[1][0]);
367 const MFloat sr2 = (sij[1][2] + sij[2][1]) * (sij[1][2] + sij[2][1]);
368 const MFloat sr3 = (sij[0][2] + sij[2][0]) * (sij[0][2] + sij[2][0]);
369 const MFloat srt = std::max(sqrt(sr1 + sr2 + sr3), epss);
370 const MFloat rr1 = sqrt(sr1) / srt;
372 MFloat uvRans = -sqrt(2.0 * SijSij) * rr1 * nu_t * fre;
373 LESSolver().m_RANSValues[noRANSVariables()][LESId] = uvRans;
383template <MInt nDim,
class SysEqn>
388 if(LESSolver().grid().isActive()) {
389 if(m_cylindricCommunication) {
390 for(
MInt cellId = 0; cellId < a_noFvGridCellsLES(); cellId++) {
392 if(LESSolver().a_isHalo(cellId))
continue;
393 MFloat y = LESSolver().a_coordinate(cellId, 1);
394 MFloat z = LESSolver().a_coordinate(cellId, 2);
397 for(
MInt var = 0; var < nDim + 3; var++) {
398 ASSERT(cellId < (
MInt)LESSolver().m_STGSpongeFactor[var].size(),
399 "Trying to access data [" + to_string(var) +
"][" + to_string(cellId)
400 +
"] in m_STGSpongeFactor with length " + to_string(LESSolver().m_STGSpongeFactor[var].size())
401 +
", domainId: " + to_string(LESSolver().domainId()));
403 if(m_periodicSpongeInterpolationIndex[cellId].size() == 1) {
404 MInt interpolationIndex = m_periodicSpongeInterpolationIndex[cellId][0];
405 MInt exchangeIndex = m_periodicSpongeCylinderExchangeIndex[interpolationIndex];
408 data = LESSolver().a_pvariable(cellId, var)
409 - m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + var];
412 data = m_uvRans[interpolationIndex];
414 if(var == nDim + 1) {
415 data = alpha * m_uvErr[interpolationIndex] + beta * m_uvInt[interpolationIndex];
417 if(var == nDim + 2) {
419 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + noLESVariables()
421 - m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + 0]
422 * m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + 1];
425 LESSolver().m_STGSpongeFactor[var][cellId] = data;
428 if(m_periodicSpongeInterpolationIndex[cellId].size() > 1) {
440 for(
MInt i = 0; i < (
MInt)m_periodicSpongeInterpolationIndex[cellId].size(); i++) {
442 MInt interpolationIndex = m_periodicSpongeInterpolationIndex[cellId][i];
443 MInt exchangeIndex = m_periodicSpongeCylinderExchangeIndex[interpolationIndex];
445 MFloat yExchange = m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 1];
446 MFloat zExchange = m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 2];
448 -((sector - m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 3]) * m_azimuthalAngle)
450 MFloat yRotated = cos(rotationAngle) * yExchange + sin(rotationAngle) * zExchange;
451 MFloat zRotated = -sin(rotationAngle) * yExchange + cos(rotationAngle) * zExchange;
453 MFloat delta_y = LESSolver().a_coordinate(cellId, 1) - yRotated;
454 MFloat delta_z = LESSolver().a_coordinate(cellId, 2) - zRotated;
459 Eyi2 +=
POW2(delta_y);
461 Ezi2 +=
POW2(delta_z);
462 Eyizi += delta_y * delta_z;
466 data = LESSolver().a_pvariable(cellId, var)
467 - m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + var];
470 data = m_uvRans[interpolationIndex];
472 if(var == nDim + 1) {
473 data = alpha * m_uvErr[interpolationIndex] + beta * m_uvInt[interpolationIndex];
475 if(var == nDim + 2) {
477 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + noLESVariables()
479 - m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + 0]
480 * m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + 1];
484 Euiyi += data * delta_y;
485 Euizi += data * delta_z;
489 n * Eyi2 * Ezi2 + 2 * Eyi * Eyizi * Ezi - (Ezi * Eyi2 * Ezi + n * Eyizi * Eyizi + Ezi2 * Eyi * Eyi);
492 MInt interpolationIndex = m_periodicSpongeInterpolationIndex[cellId][0];
493 LESSolver().m_STGSpongeFactor[var][cellId] =
494 m_globalCylinderRANSExchangeValues[interpolationIndex * m_noRANSCylinderExchangeVariables + var];
496 LESSolver().m_STGSpongeFactor[var][cellId] =
498 * (Eui * (Eyi2 * Ezi2 - Eyizi * Eyizi) + Euiyi * (Ezi * Eyizi - Eyi * Ezi2)
499 + Euizi * (Eyi * Eyizi - Eyi2 * Ezi));
505 for(
MInt LESId = 0; LESId < a_noFvGridCellsLES(); LESId++) {
508 for(
MInt i = 0; i < LESSolver().m_globalNoSpongeLocations; i++) {
509 if(abs(LESSolver().m_globalSpongeLocations[i].first - RANSSolver().a_coordinate(RANSId, m_7901wallDir))
511 LESSolver().m_uvRans[i] = m_uvRans[i];
524template <MInt nDim,
class SysEqn>
528 if(LESSolver().grid().isActive()) {
529 std::vector<MFloat> RANSSectors;
530 RANSSectors.push_back(std::numeric_limits<MFloat>::max());
531 RANSSectors.push_back(-std::numeric_limits<MFloat>::max());
532 std::vector<MFloat> RANSSectorLimits;
533 RANSSectorLimits.push_back(std::numeric_limits<MFloat>::max());
534 RANSSectorLimits.push_back(-std::numeric_limits<MFloat>::max());
535 std::vector<MInt> cylinderExchangeIds;
536 std::vector<MFloat> cylinderExchangeLocations;
538 mAlloc(m_RANSSectors, 2,
"m_RANSSectors", F0, FUN_);
539 mAlloc(m_RANSSectorLimits, 2,
"m_RANSSectorLimits", F0, FUN_);
541 MInt noRANSExchangeCells = 0;
542 for(
MInt RANSId = 0; RANSId < a_noFvGridCellsRANS(); RANSId++) {
543 MFloat halfCellLength = RANSSolver().grid().halfCellLength(RANSId);
544 MFloat pos = RANSSolver().a_coordinate(RANSId, 0);
545 if(
approx(m_7901Position, pos, halfCellLength) ||
approx(m_7909Position, pos, halfCellLength)) {
548 if(RANSSolver().c_isLeafCell(RANSId) && !RANSSolver().a_isHalo(RANSId)) {
549 MFloat x = RANSSolver().a_coordinate(RANSId, 0);
550 MFloat y = RANSSolver().a_coordinate(RANSId, 1);
551 MFloat z = RANSSolver().a_coordinate(RANSId, 2);
555 if(sector < RANSSectors[0]) {
556 RANSSectors[0] = sector;
558 if(sector > RANSSectors[1]) {
559 RANSSectors[1] = sector;
561 if(angle < RANSSectorLimits[0]) {
562 RANSSectorLimits[0] = angle;
564 if(angle > RANSSectorLimits[1]) {
565 RANSSectorLimits[1] = angle;
568 noRANSExchangeCells++;
569 cylinderExchangeIds.push_back(RANSId);
570 cylinderExchangeLocations.push_back(x);
571 cylinderExchangeLocations.push_back(
y);
572 cylinderExchangeLocations.push_back(z);
579 if(noRANSExchangeCells > 0) {
580 MInt noRANSExchangeCells_ = noRANSExchangeCells;
582 for(
MInt i = 0; i < noRANSExchangeCells_; i++) {
583 MInt RANSId = cylinderExchangeIds[i];
584 MInt noNghbrIds = RANSSolver().a_noReconstructionNeighbors(RANSId);
585 for(
MInt n = 0; n < noNghbrIds; n++) {
586 MInt nghbrId = RANSSolver().a_reconstructionNeighborId(RANSId, n);
587 if(RANSSolver().a_isBndryGhostCell(nghbrId)) {
588 MFloat x = RANSSolver().a_coordinate(nghbrId, 0);
589 MFloat y = RANSSolver().a_coordinate(nghbrId, 1);
590 MFloat z = RANSSolver().a_coordinate(nghbrId, 2);
591 noRANSExchangeCells++;
592 cylinderExchangeIds.push_back(nghbrId);
593 cylinderExchangeLocations.push_back(x);
594 cylinderExchangeLocations.push_back(
y);
595 cylinderExchangeLocations.push_back(z);
604 if(noRANSExchangeCells > 0) {
607 f <<
"globalCylinderExchange_" << to_string(RANSSolver().domainId()) <<
".txt";
609 MString header =
"#id isHalo x1 x2 x3 sector";
613 data << header << endl;
614 for(
MInt i = 0; i < noRANSExchangeCells; i++) {
616 line.append(to_string(cylinderExchangeIds[i]) +
" "
617 + to_string(RANSSolver().a_isBndryGhostCell(cylinderExchangeIds[i])) +
" "
618 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 0]) +
" "
619 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 1]) +
" "
620 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 2]) +
" "
621 + to_string(cylinderExchangeLocations[i * (nDim + 1) + 3]));
622 data << line << endl;
630 MPI_Allreduce(MPI_IN_PLACE, &RANSSectors[0], 1, MPI_DOUBLE, MPI_MIN, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
632 MPI_Allreduce(MPI_IN_PLACE, &RANSSectors[1], 1, MPI_DOUBLE, MPI_MAX, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
634 MPI_Allreduce(MPI_IN_PLACE, &RANSSectorLimits[0], 1, MPI_DOUBLE, MPI_MIN, LESSolver().mpiComm(), AT_,
635 "MPI_IN_PLACE",
"RANSSectorLimits");
636 MPI_Allreduce(MPI_IN_PLACE, &RANSSectorLimits[1], 1, MPI_DOUBLE, MPI_MAX, LESSolver().mpiComm(), AT_,
637 "MPI_IN_PLACE",
"RANSSectorLimits");
639 m_RANSSectors[0] = RANSSectors[0];
640 m_RANSSectors[1] = RANSSectors[1];
641 m_RANSSectorLimits[0] = RANSSectorLimits[0];
642 m_RANSSectorLimits[1] = RANSSectorLimits[1];
644 m_noCylindricalGlobalExchangeLocations = 0;
645 m_noCylindricalGlobalRANSExchangeValues = 0;
646 m_noCylindricalGlobalLESExchangeValues = 0;
647 m_noCylindricalGlobalExchangeIds = 0;
648 m_noGlobalRANSExchangeCells = 0;
651 MPI_Allreduce(&noRANSExchangeCells, &m_noGlobalRANSExchangeCells, 1, MPI_INT, MPI_SUM, LESSolver().mpiComm(), AT_,
652 "noRANSExchangeCells",
"m_noGlobalRANSExchangeCells");
654 m_noRANSCylinderExchangeVariables = noRANSVariables() + (
MInt)m_STGSponge;
655 m_noCylindricalGlobalExchangeLocations = m_noGlobalRANSExchangeCells * (nDim + 1);
656 m_noCylindricalGlobalRANSExchangeValues = m_noGlobalRANSExchangeCells * m_noRANSCylinderExchangeVariables;
657 m_noCylindricalGlobalLESExchangeValues = m_noGlobalRANSExchangeCells * LESSolver().m_LESNoVarAverage;
658 m_noCylindricalGlobalExchangeIds = m_noGlobalRANSExchangeCells;
660 m_cylinderExchangeIdsOffset = -1;
661 m_noRANSExchangeCells = noRANSExchangeCells;
662 mAlloc(m_globalCylinderExchangeLocations, m_noCylindricalGlobalExchangeLocations,
663 "m_globalCylinderExchangeLocations", F0, FUN_);
664 mAlloc(m_globalCylinderRANSExchangeValues, m_noCylindricalGlobalRANSExchangeValues,
665 "m_globalCylinderRANSExchangeValues", F0, FUN_);
666 mAlloc(m_globalCylinderLESExchangeValues, m_noCylindricalGlobalLESExchangeValues,
667 "m_globalCylinderLESExchangeValues", F0, FUN_);
668 mAlloc(m_globalCylinderExchangeIds, m_noCylindricalGlobalExchangeIds,
"m_globalCylinderExchangeIds", 0, FUN_);
672 MPI_Comm_size(LESSolver().mpiComm(), &m_commSizeCylExchange);
673 std::vector<MInt> cellsPerDomain(m_commSizeCylExchange);
674 std::vector<MInt> cylRanks(m_commSizeCylExchange);
675 MInt myCylRank = LESSolver().domainId();
678 MPI_Allgather(&noRANSExchangeCells, 1, MPI_INT, &cellsPerDomain[0], 1, MPI_INT, LESSolver().mpiComm(), AT_,
679 "noBc7909Cells ",
"bc7909CellsperDomain");
680 MPI_Allgather(&myCylRank, 1, MPI_INT, &cylRanks[0], 1, MPI_INT, LESSolver().mpiComm(), AT_,
"myCylRank",
683 MInt noInvolvedRanks = 0;
684 std::vector<MInt> involvedRanks(m_commSizeCylExchange);
685 for(
MInt i = 0; i < m_commSizeCylExchange; i++) {
686 if(cellsPerDomain[i]) {
687 involvedRanks[noInvolvedRanks] = i;
696 MPI_Group_incl(group, noInvolvedRanks, &involvedRanks[0], &groupCyl, AT_);
698 MPI_Comm_create(LESSolver().mpiComm(), groupCyl, &commCyl, AT_,
"commCyl");
701 MInt myCommRank = -1;
702 for(
MInt r = 0; r < noInvolvedRanks; r++) {
703 if(myCylRank == involvedRanks[r]) {
709 m_cylRoot = involvedRanks[0];
715 if(noRANSExchangeCells > 0) {
716 m_cylCommActive =
true;
719 MInt noLocations = noRANSExchangeCells * (nDim + 1);
720 MInt noIds = noRANSExchangeCells;
721 if(noInvolvedRanks > 0) {
724 recvbufLocations.
fill(0);
728 MPI_Gather(&noLocations, 1, MPI_INT, &recvbufLocations[0], 1, MPI_INT, 0, commCyl, AT_,
"noLocations",
732 MPI_Gather(&noIds, 1, MPI_INT, &recvbufIds[0], 1, MPI_INT, 0, commCyl, AT_,
"noIds",
"recvbufIds");
735 if(myCommRank == 0) {
736 MInt offsetLocations = 0;
739 for(
MInt dom = 0; dom < noInvolvedRanks; dom++) {
740 displsLocations[dom] = offsetLocations;
741 displsIds[dom] = offsetIds;
742 offsetLocations += recvbufLocations[dom];
743 offsetIds += recvbufIds[dom];
747 MPI_Gatherv(&cylinderExchangeLocations[0], noLocations, MPI_DOUBLE, &m_globalCylinderExchangeLocations[0],
748 &recvbufLocations[myCommRank], &displsLocations[myCommRank], MPI_DOUBLE, 0, commCyl, AT_,
749 "cylinderExchangeLocations",
"m_globalCylinderExchangeLocations");
750 MPI_Gatherv(&cylinderExchangeIds[0], noIds, MPI_INT, &m_globalCylinderExchangeIds[0], &recvbufIds[myCommRank],
751 &displsIds[myCommRank], MPI_INT, 0, commCyl, AT_,
"cylinderExchangeIds",
752 "m_globalCylinderExchangeIds");
773 MPI_Bcast(&displsIds[0], noInvolvedRanks, MPI_INT, m_cylRoot, LESSolver().mpiComm(), AT_,
"displsIds");
774 for(
MInt dom = 0; dom < noInvolvedRanks; dom++) {
775 if(dom == myCommRank) {
776 m_cylinderExchangeIdsOffset = displsIds[dom];
780 MPI_Allreduce(MPI_IN_PLACE, &m_cylRoot, 1, MPI_INT, MPI_MAX, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
782 MPI_Bcast(&m_globalCylinderExchangeLocations[0], m_noCylindricalGlobalExchangeLocations, MPI_DOUBLE, m_cylRoot,
783 LESSolver().mpiComm(), AT_,
"m_globalCylinderExchangeLocations");
784 MPI_Bcast(&m_globalCylinderExchangeIds[0], m_noCylindricalGlobalExchangeIds, MPI_INT, m_cylRoot,
785 LESSolver().mpiComm(), AT_,
"m_globalCylinderExchangeIds");
790 if(LESSolver().domainId() == 0) {
793 fn2 <<
"globalCylinderExchange.txt";
795 MString header2 =
"#exchangeIndex id x1 x2 x3 sector";
799 data2 << header2 << endl;
800 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
802 line.append(to_string(exchangeIndex) +
" " + to_string(m_globalCylinderExchangeIds[exchangeIndex]) +
" "
803 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 0]) +
" "
804 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 1]) +
" "
805 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 2]) +
" "
806 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 3]));
807 data2 << line << endl;
817 mAlloc(m_globalCylinderInterpolationIndex, a_noFvGridCellsLES(),
"m_globalCylinderInterpolationIndex", FUN_);
818 mAlloc(m_cylinderInterpolationAngle, a_noFvGridCellsLES(),
"m_cylinderInterpolationAngle", FUN_);
819 mAlloc(m_globalCylinderInterpolationCell, m_noGlobalRANSExchangeCells,
"m_globalCylinderInterpolationCell", FUN_);
821 for(
MInt exchangeIndex = 0; exchangeIndex < m_noCylindricalGlobalLESExchangeValues; exchangeIndex++) {
822 m_globalCylinderInterpolationNumber.push_back(0);
825 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
826 m_globalCylinderInterpolationCell[exchangeIndex].clear();
829 MInt maxInterpCells = 4;
830 vector<vector<pair<MFloat, MInt>>> minDistIndex(
831 a_noFvGridCellsLES(),
832 vector<pair<MFloat, MInt>>(maxInterpCells, make_pair(std::numeric_limits<MFloat>::infinity(), -1)));
833 vector<vector<pair<MFloat, MInt>>> minDistCell(
834 m_noGlobalRANSExchangeCells,
835 vector<pair<MFloat, MInt>>(maxInterpCells, make_pair(std::numeric_limits<MFloat>::infinity(), -1)));
838 for(
MInt LESId = 0; LESId < a_noFvGridCellsLES(); LESId++) {
839 m_globalCylinderInterpolationIndex[LESId].clear();
840 MFloat x = LESSolver().a_coordinate(LESId, 0);
841 MFloat y = LESSolver().a_coordinate(LESId, 1);
842 MFloat z = LESSolver().a_coordinate(LESId, 2);
843 MFloat cellHalfLength = F1B2 * LESSolver().c_cellLengthAtLevel(LESSolver().a_level(LESId));
847 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
848 MFloat xExchange = m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 0];
849 MFloat yExchange = m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 1];
850 MFloat zExchange = m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 2];
853 for(
MInt r = 0; r < 2; r++) {
854 MFloat rotationAngle_ = -((sector - m_RANSSectors[r]) * m_azimuthalAngle) / 180.0 * PI;
855 MFloat yRotated_ = cos(rotationAngle_) *
y - sin(rotationAngle_) * z;
856 MFloat zRotated_ = sin(rotationAngle_) *
y + cos(rotationAngle_) * z;
857 if(
approx(x, xExchange, F3 * cellHalfLength) &&
approx(yRotated_, yExchange, F3 * cellHalfLength)
858 &&
approx(zRotated_, zExchange, F3 * cellHalfLength)) {
861 MInt RANSId_ = m_globalCylinderExchangeIds[exchangeIndex];
862 if(!RANSSolver().a_isBndryGhostCell(RANSId_) && LESSolver().c_isLeafCell(LESId)) {
863 m_globalCylinderInterpolationCell[exchangeIndex].push_back(
864 make_pair<MInt, MFloat>((
MInt)LESId, (
MFloat)rotationAngle_));
870 MFloat rotationAngle = F0;
871 MFloat rotationAngle1 = -((sector - m_RANSSectors[0]) * m_azimuthalAngle) / 180.0 * PI;
872 MFloat rotationAngle2 = -((sector - m_RANSSectors[1]) * m_azimuthalAngle) / 180.0 * PI;
873 MFloat minAngleDist1 = F0;
874 MFloat minAngleDist2 = F0;
875 if(angle + rotationAngle1 > m_RANSSectorLimits[0] || angle + rotationAngle1 < m_RANSSectorLimits[1]) {
876 if(abs(angle + rotationAngle1 - m_RANSSectorLimits[0])
877 < abs(angle + rotationAngle1 - m_RANSSectorLimits[1])) {
878 minAngleDist1 = abs(angle + rotationAngle1 - m_RANSSectorLimits[0]);
880 minAngleDist1 = abs(angle + rotationAngle1 - m_RANSSectorLimits[1]);
883 if(angle + rotationAngle2 > m_RANSSectorLimits[0] || angle + rotationAngle2 < m_RANSSectorLimits[1]) {
884 if(abs(angle + rotationAngle2 - m_RANSSectorLimits[0])
885 < abs(angle + rotationAngle2 - m_RANSSectorLimits[1])) {
886 minAngleDist2 = abs(angle + rotationAngle2 - m_RANSSectorLimits[0]);
888 minAngleDist2 = abs(angle + rotationAngle2 - m_RANSSectorLimits[1]);
891 if(minAngleDist2 > minAngleDist1) {
892 rotationAngle = rotationAngle2;
894 rotationAngle = rotationAngle1;
898 if(RANSId != -1) rotationAngle = 0;
899 m_cylinderInterpolationAngle[LESId] = rotationAngle;
900 MFloat yRotated_ = cos(rotationAngle) *
y - sin(rotationAngle) * z;
901 MFloat zRotated_ = sin(rotationAngle) *
y + cos(rotationAngle) * z;
902 if(
approx(x, xExchange, F3 * cellHalfLength) &&
approx(yRotated_, yExchange, F4 * cellHalfLength)
903 &&
approx(zRotated_, zExchange, F4 * cellHalfLength)) {
904 MFloat delta_y = yRotated_ - yExchange;
905 MFloat delta_z = zRotated_ - zExchange;
908 MBool checkWindowHalo =
false;
909 if(!checkWindowHalo) {
910 if(
dist < minDistIndex[LESId][maxInterpCells - 1].first) {
911 minDistIndex[LESId][maxInterpCells - 1] = make_pair(
dist, exchangeIndex);
913 sort(minDistIndex[LESId].begin(), minDistIndex[LESId].end());
920 for(
MInt LESId = 0; LESId < a_noFvGridCellsLES(); LESId++) {
921 MFloat minY = std::numeric_limits<MFloat>::infinity();
922 MFloat maxY = -std::numeric_limits<MFloat>::infinity();
923 MFloat minZ = std::numeric_limits<MFloat>::infinity();
924 MFloat maxZ = -std::numeric_limits<MFloat>::infinity();
925 MFloat rotationAngle = m_cylinderInterpolationAngle[LESId];
926 MFloat* coordLES = &LESSolver().a_coordinate(LESId, 0);
927 MFloat yRotated = cos(rotationAngle) * coordLES[1] - sin(rotationAngle) * coordLES[2];
928 MFloat zRotated = sin(rotationAngle) * coordLES[1] + cos(rotationAngle) * coordLES[2];
933 for(
MInt i = 0; i < maxInterpCells; i++) {
934 if(minDistIndex[LESId][i].second != -1) {
935 MInt exchangeIndex = minDistIndex[LESId][i].second;
936 MBool usePoint =
true;
937 MFloat* coordRANS = &m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1)];
938 if(i == maxInterpCells - 1) {
939 if(yRotated > minY && yRotated < maxY && zRotated > minZ && zRotated < maxZ) usePoint =
false;
941 if(coordRANS[1] > yRotated && coordRANS[1] > maxY) maxY = coordRANS[1];
942 if(coordRANS[1] < yRotated && coordRANS[1] < minY) minY = coordRANS[1];
943 if(coordRANS[2] > zRotated && coordRANS[2] > maxZ) maxZ = coordRANS[2];
944 if(coordRANS[2] < zRotated && coordRANS[2] < minZ) minZ = coordRANS[2];
945 if(usePoint) m_globalCylinderInterpolationIndex[LESId].push_back(exchangeIndex);
950 if(yRotated < minY || yRotated > maxY || zRotated < minZ || zRotated > maxZ) {
951 if(m_globalCylinderInterpolationIndex[LESId].size() > 1) {
952 m_globalCylinderInterpolationIndex[LESId].erase(m_globalCylinderInterpolationIndex[LESId].begin() + 1,
953 m_globalCylinderInterpolationIndex[LESId].end());
960 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
961 MInt testForOnlyHalo = 0;
962 for(
MInt i = 0; i < (
MInt)m_globalCylinderInterpolationCell[exchangeIndex].size(); i++) {
963 MInt cellId = m_globalCylinderInterpolationCell[exchangeIndex][i].first;
964 testForOnlyHalo += (
MInt)LESSolver().a_isHalo(cellId);
967 if(testForOnlyHalo == (
MInt)m_globalCylinderInterpolationCell[exchangeIndex].size()) {
968 m_globalCylinderInterpolationCell[exchangeIndex].clear();
977 fn3 <<
"globalCylinderLESCell_" << to_string(LESSolver().domainId()) <<
".txt";
979 MString header3 =
"#exchangeIndex ...";
983 data3 << header3 << endl;
984 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
985 MString line = to_string(exchangeIndex) +
" | ";
986 for(
MInt i = 0; i < (
MInt)m_globalCylinderInterpolationCell[exchangeIndex].size(); i++) {
987 MInt cellId = m_globalCylinderInterpolationCell[exchangeIndex][i].first;
988 MInt rotationAngle = m_globalCylinderInterpolationCell[exchangeIndex][i].second;
989 line.append(
"(" + to_string(cellId) +
" " + to_string(rotationAngle) +
" "
990 + to_string(LESSolver().a_isHalo(cellId)) +
" ," + to_string(LESSolver().a_coordinate(cellId, 0))
991 +
" " + to_string(LESSolver().a_coordinate(cellId, 1)) +
" "
992 + to_string(LESSolver().a_coordinate(cellId, 2)) +
") ");
994 data3 << line << endl;
1000 fn4 <<
"globalCylinderLESIndex_" << to_string(LESSolver().domainId()) <<
".txt";
1002 MString header4 =
"#LESId exchangeIndex ";
1004 data4.precision(16);
1006 data4 << header4 << endl;
1007 for(
MInt LESId = 0; LESId < a_noFvGridCellsLES(); LESId++) {
1008 if(m_globalCylinderInterpolationIndex[LESId].empty())
continue;
1010 to_string(LESId) +
" " + to_string(LESSolver().a_isHalo(LESId)) +
" "
1011 + to_string(LESSolver().c_isLeafCell(LESId)) +
" | " + to_string(LESSolver().a_coordinate(LESId, 0)) +
" "
1012 + to_string(LESSolver().a_coordinate(LESId, 1)) +
" " + to_string(LESSolver().a_coordinate(LESId, 2)) +
" ";
1013 for(
MInt i = 0; i < (
MInt)m_globalCylinderInterpolationIndex[LESId].size(); i++) {
1014 MInt exchangeIndex = m_globalCylinderInterpolationIndex[LESId][i];
1015 line.append(
"(" + to_string(exchangeIndex) +
", "
1016 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 0]) +
" "
1017 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 1]) +
" "
1018 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 2]) +
" "
1019 + to_string(m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 3]) +
") ");
1021 data4 << line << endl;
1033template <MInt nDim,
class SysEqn>
1037 if(LESSolver().grid().isActive()) {
1039 for(
MInt LESId = 0; LESId < a_noFvGridCellsLES(); LESId++) {
1041 if(LESSolver().a_isHalo(LESId))
continue;
1042 MFloat y = LESSolver().a_coordinate(LESId, 1);
1043 MFloat z = LESSolver().a_coordinate(LESId, 2);
1044 MFloat rotationAngle = m_cylinderInterpolationAngle[LESId];
1045 MFloat yRotated_ = cos(rotationAngle) *
y - sin(rotationAngle) * z;
1046 MFloat zRotated_ = sin(rotationAngle) *
y + cos(rotationAngle) * z;
1048 if(m_globalCylinderInterpolationIndex[LESId].empty())
continue;
1050 for(
MInt var = 0; var < noRANSVariables(); var++) {
1051 ASSERT(LESId < (
MInt)LESSolver().m_RANSValues[var].size(),
1052 "Trying to access data [" + to_string(var) +
"][" + to_string(LESId) +
"] in m_RANSValues with length "
1053 + to_string(LESSolver().m_RANSValues[var].size())
1054 +
", domainId: " + to_string(LESSolver().domainId()));
1056 if(m_globalCylinderInterpolationIndex[LESId].size() == 1) {
1057 MInt interpolationIndex = m_globalCylinderInterpolationIndex[LESId][0];
1058 LESSolver().m_RANSValues[var][LESId] =
1059 m_globalCylinderRANSExchangeValues[interpolationIndex * m_noRANSCylinderExchangeVariables + var];
1062 if(m_globalCylinderInterpolationIndex[LESId].size() > 1) {
1063 MInt interpolationIndex = m_globalCylinderInterpolationIndex[LESId][0];
1064 MFloat yExchange = m_globalCylinderExchangeLocations[interpolationIndex * (nDim + 1) + 1];
1065 MFloat zExchange = m_globalCylinderExchangeLocations[interpolationIndex * (nDim + 1) + 2];
1066 MFloat delta_y = yRotated_ - yExchange;
1067 MFloat delta_z = zRotated_ - zExchange;
1070 if(sqrt(pow(delta_y, 2) + pow(delta_z, 2)) < 1e-16 ) {
1071 LESSolver().m_RANSValues[var][LESId] =
1072 m_globalCylinderRANSExchangeValues[interpolationIndex * m_noRANSCylinderExchangeVariables + var];
1086 for(
MInt i = 0; i < (
MInt)m_globalCylinderInterpolationIndex[LESId].size(); i++) {
1087 interpolationIndex = m_globalCylinderInterpolationIndex[LESId][i];
1088 yExchange = m_globalCylinderExchangeLocations[interpolationIndex * (nDim + 1) + 1];
1089 zExchange = m_globalCylinderExchangeLocations[interpolationIndex * (nDim + 1) + 2];
1090 delta_y = yRotated_ - yExchange;
1091 delta_z = zRotated_ - zExchange;
1094 Eyi2 +=
POW2(delta_y);
1096 Ezi2 +=
POW2(delta_z);
1097 Eyizi += delta_y * delta_z;
1098 Eui += m_globalCylinderRANSExchangeValues[interpolationIndex * m_noRANSCylinderExchangeVariables + var];
1099 Euiyi += m_globalCylinderRANSExchangeValues[interpolationIndex * m_noRANSCylinderExchangeVariables + var]
1101 Euizi += m_globalCylinderRANSExchangeValues[interpolationIndex * m_noRANSCylinderExchangeVariables + var]
1106 n * Eyi2 * Ezi2 + 2 * Eyi * Eyizi * Ezi - (Ezi * Eyi2 * Ezi + n * Eyizi * Eyizi + Ezi2 * Eyi * Eyi);
1109 LESSolver().m_RANSValues[var][LESId] =
1111 * (Eui * (Eyi2 * Ezi2 - Eyizi * Eyizi) + Euiyi * (Ezi * Eyizi - Eyi * Ezi2)
1112 + Euizi * (Eyi * Eyizi - Eyi2 * Ezi));
1119 MInt vId = LESSolver().sysEqn().PV->V;
1120 MInt wId = LESSolver().sysEqn().PV->W;
1121 MFloat v_ = LESSolver().m_RANSValues[vId][LESId];
1122 MFloat w_ = LESSolver().m_RANSValues[wId][LESId];
1123 LESSolver().m_RANSValues[vId][LESId] = v_ * cos(-rotationAngle) - w_ * sin(-rotationAngle);
1124 LESSolver().m_RANSValues[wId][LESId] = v_ * sin(-rotationAngle) + w_ * cos(-rotationAngle);
1133template <MInt nDim,
class SysEqn>
1137 if(LESSolver().grid().isActive()) {
1138 ScratchSpace<MInt> numberCylinderExchangeValues(m_noCylindricalGlobalRANSExchangeValues,
1139 "numberCylinderExchangeValues", FUN_);
1140 numberCylinderExchangeValues.
fill(0);
1142 if(m_cylCommActive) {
1144 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
1145 for(
MInt var = 0; var < m_noRANSCylinderExchangeVariables; var++) {
1146 m_globalCylinderRANSExchangeValues[exchangeIndex * m_noRANSCylinderExchangeVariables + var] = F0;
1151 for(
MInt exchangeIndex_ = 0; exchangeIndex_ < m_noRANSExchangeCells; exchangeIndex_++) {
1152 MInt exchangeIndex = exchangeIndex_ + m_cylinderExchangeIdsOffset;
1153 MInt RANSId = m_globalCylinderExchangeIds[exchangeIndex];
1155 for(
MInt var = 0; var < noRANSVariables(); var++) {
1156 m_globalCylinderRANSExchangeValues[exchangeIndex * m_noRANSCylinderExchangeVariables + var] =
1157 RANSSolver().a_pvariable(RANSId, var);
1158 numberCylinderExchangeValues[exchangeIndex * m_noRANSCylinderExchangeVariables + var] = 1;
1163 MPI_Allreduce(MPI_IN_PLACE, &m_globalCylinderRANSExchangeValues[0], m_noCylindricalGlobalRANSExchangeValues,
1164 MPI_DOUBLE, MPI_SUM, m_commCyl, AT_,
"MPI_IN_PLACE",
"m_globalCylinderRANSExchangeValues");
1165 MPI_Allreduce(MPI_IN_PLACE, &numberCylinderExchangeValues[0], m_noCylindricalGlobalRANSExchangeValues, MPI_INT,
1166 MPI_SUM, m_commCyl, AT_,
"MPI_IN_PLACE",
"numberCylinderExchangeValues");
1169 MPI_Bcast(&m_globalCylinderRANSExchangeValues[0], m_noCylindricalGlobalRANSExchangeValues, MPI_DOUBLE, m_cylRoot,
1170 LESSolver().mpiComm(), AT_,
"m_globalCylinderRANSExchangeValues");
1171 MPI_Bcast(&numberCylinderExchangeValues[0], m_noCylindricalGlobalRANSExchangeValues, MPI_INT, m_cylRoot,
1172 LESSolver().mpiComm(), AT_,
"numberCylinderExchangeValues");
1175 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
1176 for(
MInt var = 0; var < noRANSVariables(); var++) {
1177 if(numberCylinderExchangeValues[exchangeIndex * m_noRANSCylinderExchangeVariables + var] > 0) {
1178 m_globalCylinderRANSExchangeValues[exchangeIndex * m_noRANSCylinderExchangeVariables + var] /=
1179 numberCylinderExchangeValues[exchangeIndex * m_noRANSCylinderExchangeVariables + var];
1190template <MInt nDim,
class SysEqn>
1194 if(LESSolver().grid().isActive()) {
1195 MInt vId = LESSolver().sysEqn().PV->V;
1196 MInt wId = LESSolver().sysEqn().PV->W;
1198 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
1199 if((
MInt)m_globalCylinderInterpolationCell[exchangeIndex].size() == 0)
continue;
1202 if((
MInt)m_globalCylinderInterpolationCell[exchangeIndex].size() == 1) {
1203 MInt cellId = m_globalCylinderInterpolationCell[exchangeIndex][0].first;
1205 MFloat rotationAngle = m_globalCylinderInterpolationCell[exchangeIndex][0].second;
1207 vector<MInt>::iterator findAvgId =
1208 find(LESSolver().m_LESAverageCells.begin(), LESSolver().m_LESAverageCells.end(), cellId);
1209 if(findAvgId != LESSolver().m_LESAverageCells.end()) {
1210 MInt avgId = distance(LESSolver().m_LESAverageCells.begin(), findAvgId);
1211 for(
MInt var = 0; var < LESSolver().m_LESNoVarAverage; var++) {
1212 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + var] =
1213 LESSolver().m_LESVarAverage[var][avgId];
1214 m_globalCylinderInterpolationNumber[exchangeIndex * LESSolver().m_LESNoVarAverage + var] = 1;
1218 MFloat v_ = LESSolver().m_LESVarAverage[vId][avgId];
1219 MFloat w_ = LESSolver().m_LESVarAverage[wId][avgId];
1220 MFloat v_rot = v_ * cos(rotationAngle) - w_ * sin(rotationAngle);
1221 MFloat w_rot = v_ * sin(rotationAngle) + w_ * cos(rotationAngle);
1222 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + vId] = v_rot;
1223 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + wId] = w_rot;
1229 if(m_globalCylinderInterpolationCell[exchangeIndex].size() > 1) {
1230 for(
MInt var = 0; var < LESSolver().m_LESNoVarAverage; var++) {
1231 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + var] = F0;
1243 for(
MInt i = 0; i < (
MInt)m_globalCylinderInterpolationCell[exchangeIndex].size(); i++) {
1244 MInt cellId = m_globalCylinderInterpolationCell[exchangeIndex][i].first;
1245 MFloat y = LESSolver().a_coordinate(cellId, 1);
1246 MFloat z = LESSolver().a_coordinate(cellId, 2);
1247 MFloat rotationAngle = m_globalCylinderInterpolationCell[exchangeIndex][i].second;
1248 MFloat yRotated_ = cos(rotationAngle) *
y - sin(rotationAngle) * z;
1249 MFloat zRotated_ = sin(rotationAngle) *
y + cos(rotationAngle) * z;
1250 MFloat yExchange = m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 1];
1251 MFloat zExchange = m_globalCylinderExchangeLocations[exchangeIndex * (nDim + 1) + 2];
1252 MFloat delta_y = yExchange - yRotated_;
1253 MFloat delta_z = zExchange - zRotated_;
1255 vector<MInt>::iterator findAvgId =
1256 find(LESSolver().m_LESAverageCells.begin(), LESSolver().m_LESAverageCells.end(), cellId);
1257 if(findAvgId != LESSolver().m_LESAverageCells.end()) {
1258 MInt avgId = distance(LESSolver().m_LESAverageCells.begin(), findAvgId);
1261 MFloat v_ = LESSolver().m_LESVarAverage[vId][avgId];
1262 MFloat w_ = LESSolver().m_LESVarAverage[wId][avgId];
1263 MFloat v_rot = v_ * cos(rotationAngle) - w_ * sin(rotationAngle);
1264 MFloat w_rot = v_ * sin(rotationAngle) + w_ * cos(rotationAngle);
1268 Eyi2 +=
POW2(delta_y);
1270 Ezi2 +=
POW2(delta_z);
1271 Eyizi += delta_y * delta_z;
1275 Euiyi += v_rot * delta_y;
1276 Euizi += v_rot * delta_z;
1277 }
else if(var == wId) {
1279 Euiyi += w_rot * delta_y;
1280 Euizi += w_rot * delta_z;
1282 Eui += LESSolver().m_LESVarAverage[var][avgId];
1283 Euiyi += LESSolver().m_LESVarAverage[var][avgId] * delta_y;
1284 Euizi += LESSolver().m_LESVarAverage[var][avgId] * delta_z;
1290 n * Eyi2 * Ezi2 + 2 * Eyi * Eyizi * Ezi - (Ezi * Eyi2 * Ezi + n * Eyizi * Eyizi + Ezi2 * Eyi * Eyi);
1293 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + var] =
1295 * (Eui * (Eyi2 * Ezi2 - Eyizi * Eyizi) + Euiyi * (Ezi * Eyizi - Eyi * Ezi2)
1296 + Euizi * (Eyi * Eyizi - Eyi2 * Ezi));
1299 if(!
approx(m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + var], F0,
1301 m_globalCylinderInterpolationNumber[exchangeIndex * LESSolver().m_LESNoVarAverage + var] = 1;
1307 MPI_Allreduce(MPI_IN_PLACE, &m_globalCylinderInterpolationNumber[0], m_noCylindricalGlobalLESExchangeValues,
1308 MPI_INT, MPI_SUM, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
"m_globalCylinderInterpolationNumber");
1310 MPI_Allreduce(MPI_IN_PLACE, &m_globalCylinderLESExchangeValues[0], m_noCylindricalGlobalLESExchangeValues,
1311 MPI_DOUBLE, MPI_SUM, LESSolver().mpiComm(), AT_,
"MPI_IN_PLACE",
"m_globalCylinderLESExchangeValues");
1314 for(
MInt exchangeIndex = 0; exchangeIndex < m_noGlobalRANSExchangeCells; exchangeIndex++) {
1315 for(
MInt var = 0; var < LESSolver().m_LESNoVarAverage; var++) {
1316 if(m_globalCylinderInterpolationNumber[exchangeIndex * LESSolver().m_LESNoVarAverage + var] > 0) {
1317 m_globalCylinderLESExchangeValues[exchangeIndex * LESSolver().m_LESNoVarAverage + var] /=
1318 m_globalCylinderInterpolationNumber[exchangeIndex * LESSolver().m_LESNoVarAverage + var];
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
void initCylinderExchange()
Create mapping for LES cells to equivalent RANS cells.
void balancePost() override
void determineZonalPositions()
FvZonalSTG(const MInt couplingId, RANS *R, LES *L)
void calcRANSSectorValues()
fill m_globalCylinderRANSExchangeValues with RANS values for exchange with LES Solver
void finalizeCouplerInit()
void transferSolverData()
void finalizeAdaptation(const MInt solverId) override
void cylinderExchange()
Interpolate RANS sector data to LES domain using mapping created in initCylinderExchange.
void calcLESSectorAverage()
fill m_globalCylinderLESExchangeValues with sector averaged LES values for exchange with RANS Solver
void transferSpongeData()
This class is a ScratchSpace.
void fill(T val)
fill the scratch with a given value
MInt convertId(SolverA &solverA, SolverB &solverB, const MInt solverAId)
Conversion from solverA id to the solverB id on the same-level only!
MInt convertIdParent(SolverA &solverA, SolverB &solverB, const MInt solverAId)
Conversion from solverA id to the solverB id If no cell on the same level is found,...
constexpr Real POW2(const Real x)
MBool approx(const T &, const U &, const T)
std::basic_string< char > MString
int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm, const MString &name, const MString &varname)
same as MPI_Comm_create, but updates the number of MPI communicators
int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group *newgroup, const MString &name)
same as MPI_Group_incl
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group, const MString &name, const MString &varname)
same as MPI_Comm_group
int MPI_Gatherv(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gatherv
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce
int MPI_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_Gather(const void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Gather
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
MFloat getSector(MFloat y, MFloat z, MFloat azimuthalAngle)
MFloat getAngle(MFloat y, MFloat z)
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)