7#ifndef DGBOUNDARYCONDITIONACOUSTICPERTURBRBC_H_
8#define DGBOUNDARYCONDITIONACOUSTICPERTURBRBC_H_
61 MString name()
const override {
return "radiation boundary condition"; }
207 RECORD_TIMER_START(m_timers[Timers::Init]);
222 for(
MInt i = 0; i < nDim; i++) {
223 m_rbcReferencePos[i] = Context::getSolverProperty<MFloat>(
"rbcReferencePos", solver().solverId(), AT_, i);
227 std::map<MInt, MInt> elementMap;
228 MInt noRbElements = 0;
232 for(
MInt srfcId = begin(); srfcId < end(); srfcId++) {
233 const MInt internalSide = surfaces().internalSideId(srfcId);
234 const MInt elementId = surfaces().nghbrElementIds(srfcId, internalSide);
237 const auto it = elementMap.find(elementId);
238 if(it != elementMap.end()) {
240 m_rbElementId.push_back(it->second);
245 const MInt rbElementId = noRbElements++;
248 elementMap[elementId] = rbElementId;
251 m_rbElementId.push_back(rbElementId);
254 MInt maxNoSurfaces = 2 * nDim * noRbElements;
255 MInt noHRbElements = 0;
261 for(
const auto& it : elementMap) {
262 const MInt elementId = it.first;
263 m_elementId.push_back(elementId);
266 const MInt cellId = elements().cellId(elementId);
267 if(needHElementForCell(cellId)) {
268 hRbElementIds[noHRbElements] = it.second;
272 maxNoSurfaces += 2 * nDim * (2 * (nDim - 1) - 1);
277 m_rbElements.maxPolyDeg(maxPolyDeg());
278 m_rbElements.maxNoNodes1D(maxNoNodes1D());
279 m_rbElements.noNodeVars(s_noNodeVars);
280 m_rbElements.reset(noRbElements);
283 m_rbSurfaces.maxPolyDeg(maxPolyDeg());
284 m_rbSurfaces.maxNoNodes1D(maxNoNodes1D());
285 m_rbSurfaces.noNodeVars(s_noNodeVars);
286 m_rbSurfaces.reset(maxNoSurfaces);
289 m_hRbElements.reset(noHRbElements);
292 for(
MInt rbId = 0; rbId < noRbElements; rbId++) {
293 m_rbElements.append();
296 m_rbElements.copy(elements(), m_elementId[rbId], rbId);
300 for(
MInt hRbId = 0; hRbId < noHRbElements; hRbId++) {
301 m_hRbElements.append();
304 m_hRbElements.elementId(hRbId) = hRbElementIds[hRbId];
308 m_rbSurfaceId.assign(end() - begin() + 1, -1);
309 std::map<MInt, MInt> srfcMap;
310 const MInt noDirs = 2 * nDim;
312 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
313 const MInt eId = m_elementId[rbId];
316 for(
MInt dir = 0; dir < noDirs; dir++) {
317 const MInt sId = elements().surfaceIds(eId, dir);
319 const MInt nghbrSideId = dir % 2;
320 const MInt elementSideId = (nghbrSideId + 1) % 2;
323 const auto srfcMapIt = srfcMap.find(sId);
324 if(srfcMapIt == srfcMap.end()) {
325 const MInt rbSurfaceId = m_rbSurfaces.size();
326 m_rbSurfaces.append();
329 srfcMap[sId] = rbSurfaceId;
332 m_surfaceId.push_back(sId);
335 if(begin() <= sId && sId < end()) {
336 m_rbSurfaceId[sId - begin()] = rbSurfaceId;
340 m_rbElements.surfaceIds(rbId, dir) = rbSurfaceId;
343 m_rbSurfaces.copy(surfaces(), sId, rbSurfaceId);
346 m_rbSurfaces.nghbrElementIds(rbSurfaceId, elementSideId) = rbId;
347 m_rbSurfaces.nghbrElementIds(rbSurfaceId, nghbrSideId) = -1;
349 const MInt internalSide = surfaces().internalSideId(sId);
356 if(internalSide != -1 && (sId < begin() || sId >= end()) && !isMpiSurface(sId)) {
360 m_addBndrySrfcIds.push_back(std::make_pair(rbSurfaceId, rbId));
363 const MInt rbSurfaceId = srfcMapIt->second;
364 m_rbElements.surfaceIds(rbId, dir) = rbSurfaceId;
367 m_rbSurfaces.nghbrElementIds(rbSurfaceId, elementSideId) = rbId;
373 const MInt noSurfs = 2 * (nDim - 1);
374 for(
MInt hRbId = 0; hRbId < noHRbElements; hRbId++) {
375 const MInt rbId = m_hRbElements.elementId(hRbId);
376 const MInt eId = m_elementId[rbId];
377 const MInt hId = getHElementId(eId);
379 for(
MInt dir = 0; dir < 2 * nDim; dir++) {
380 const MInt side = 1 - dir % 2;
381 const MInt oppositeSide = dir % 2;
383 for(
MInt hSurfId = 0; hSurfId < noSurfs; hSurfId++) {
385 const MInt sId = helements().hrefSurfaceIds(hId, dir, hSurfId);
388 const auto it = srfcMap.find(sId);
391 if(sId != -1 && it != srfcMap.end()) {
395 m_rbSurfaces.nghbrElementIds(hSId, side) = rbId;
396 }
else if(sId != -1 && hSId == -1) {
400 hSId = m_rbSurfaces.size();
401 m_rbSurfaces.append();
404 m_surfaceId.push_back(sId);
407 m_rbSurfaces.copy(surfaces(), sId, hSId);
410 m_rbSurfaces.nghbrElementIds(hSId, side) = rbId;
411 m_rbSurfaces.nghbrElementIds(hSId, oppositeSide) = -1;
416 m_hRbElements.hrefSurfaceIds(hRbId, dir, hSurfId) = hSId;
422 const MInt dataSize = Base::SysEqn::noVars() *
ipow(maxNoNodes1D(), nDim);
424 if(noRbElements > 0) {
425 mAlloc(m_rbSolution, noRbElements, dataSize,
"m_rbSolution", F0, AT_);
427 m_internalDataSize = noRbElements * dataSize;
429 RECORD_TIMER_STOP(m_timers[Timers::Init]);
442 NEW_TIMER_GROUP_NOCREATE(m_timers[Timers::TimerGroup],
443 "DgBcAcousticPerturbRBC (solverId = " + std::to_string(solver().solverId())
444 +
", bcId = " + std::to_string(
id()) +
")");
445 NEW_TIMER_NOCREATE(m_timers[Timers::Class],
"total object lifetime", m_timers[Timers::TimerGroup]);
446 RECORD_TIMER_START(m_timers[Timers::Class]);
449 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Init],
"init", m_timers[Timers::Class]);
451 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Apply],
"apply", m_timers[Timers::Class]);
452 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::InitializeVars],
"initializeVars", m_timers[Timers::Apply]);
453 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::CopySurfaceVars],
"copySurfaceVars", m_timers[Timers::Apply]);
454 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::Prolong],
"prolong", m_timers[Timers::Apply]);
455 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::TimeDeriv],
"timeDeriv", m_timers[Timers::Apply]);
456 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::RungeKuttaStep],
"RungeKuttaStep", m_timers[Timers::Apply]);
457 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::ApplyAtSurface],
"applyAtSurface", m_timers[Timers::Apply]);
459 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::SetRestartVars],
"setRestartVars", m_timers[Timers::Class]);
460 NEW_SUB_TIMER_NOCREATE(m_timers[Timers::GetRestartVars],
"getRestartVars", m_timers[Timers::Class]);
485 if(m_rbElements.size() == 0) {
489 RECORD_TIMER_START(m_timers[Timers::Apply]);
492 const MInt*
const noNodes = &m_rbElements.noNodes1D(0);
493 if(!m_isInitialized) {
494 RECORD_TIMER_START(m_timers[Timers::InitializeVars]);
498 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
499 const MInt eId = m_elementId[rbId];
500 const MInt noNodes1D = noNodes[rbId];
501 const MInt noNodesXD =
ipow(noNodes1D, nDim);
502 const MInt dataSize = noNodesXD * Base::SysEqn::noVars();
505 std::copy_n(&elements().variables(eId), dataSize, &m_rbElements.variables(rbId));
510 for(
MInt srfcId = begin(); srfcId < end(); srfcId++) {
511 const MInt noNodes1D = surfaces().noNodes1D(srfcId);
512 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
513 const MInt noNodesXD = noNodes1D * noNodes1D3;
514 const MInt internalSide = surfaces().internalSideId(srfcId);
515 const MInt outerSide = (internalSide + 1) % 2;
518 std::copy_n(&surfaces().nodeVars(srfcId, internalSide),
519 noNodesXD * Base::SysEqn::noNodeVars(),
520 &surfaces().nodeVars(srfcId, outerSide));
524 const MInt noAddBcIds = m_addBndrySrfcIds.size();
525 for(
MInt sId = 0; sId < noAddBcIds; sId++) {
526 const MInt rbSrfcId = m_addBndrySrfcIds[sId].first;
527 const MInt srfcId = m_surfaceId[rbSrfcId];
529 const MInt noNodes1D = surfaces().noNodes1D(srfcId);
530 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
531 const MInt noNodesXD = noNodes1D * noNodes1D3;
532 const MInt internalSide = surfaces().internalSideId(srfcId);
533 const MInt outerSide = (internalSide + 1) % 2;
536 std::copy_n(&surfaces().nodeVars(srfcId, internalSide),
537 noNodesXD * Base::SysEqn::noNodeVars(),
538 &surfaces().nodeVars(srfcId, outerSide));
542 calcElementNodeVars();
543 calcSurfaceNodeVars();
548 m_isInitialized =
true;
550 RECORD_TIMER_STOP(m_timers[Timers::InitializeVars]);
556 RECORD_TIMER_START(m_timers[Timers::CopySurfaceVars]);
558 for(
MInt rbSId = 0; rbSId < m_rbSurfaces.size(); rbSId++) {
559 const MInt sId = m_surfaceId[rbSId];
561 const MInt noNodesXD =
ipow(maxNoNodes1D(), nDim - 1);
562 const MInt dataSize = noNodesXD * Base::SysEqn::noVars();
564 std::copy_n(&surfaces().variables(sId, 0), dataSize, &m_rbSurfaces.variables(rbSId, 0));
565 std::copy_n(&surfaces().variables(sId, 1), dataSize, &m_rbSurfaces.variables(rbSId, 1));
568 RECORD_TIMER_STOP(m_timers[Timers::CopySurfaceVars]);
571 RECORD_TIMER_START(m_timers[Timers::Prolong]);
573 for(
MInt srfcId = begin(); srfcId < end(); srfcId++) {
575 const MInt rbId = m_rbElementId[srfcId - begin()];
577 const MInt polyDeg = m_rbElements.polyDeg(rbId);
578 const MInt noNodes1D = m_rbElements.noNodes1D(rbId);
579 const MInt orientation = surfaces().orientation(srfcId);
580 const MInt internalSide = surfaces().internalSideId(srfcId);
581 const MInt outerSide = (internalSide + 1) % 2;
582 const MInt dir = 2 * orientation + outerSide;
585 MFloat* src = &m_rbElements.variables(rbId);
586 MFloat* dest = &surfaces().variables(srfcId, outerSide);
589 prolongToFaceGauss<nDim, Base::SysEqn::noVars()>(src, dir, noNodes1D,
590 &interpolation(polyDeg, noNodes1D).m_LFace[0][0],
591 &interpolation(polyDeg, noNodes1D).m_LFace[1][0], dest);
593 prolongToFaceGaussLobatto<nDim, Base::SysEqn::noVars()>(src, dir, noNodes1D, dest);
596 const MInt rbSId = m_rbSurfaceId[srfcId - begin()];
597 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
598 const MInt noNodesXD = noNodes1D * noNodes1D3;
599 const MInt dataSize = noNodesXD * Base::SysEqn::noVars();
602 std::copy_n(dest, dataSize, &m_rbSurfaces.variables(rbSId, 0));
603 std::copy_n(dest, dataSize, &m_rbSurfaces.variables(rbSId, 1));
607 const MInt noAddBcIds = m_addBndrySrfcIds.size();
608 for(
MInt srfcId = 0; srfcId < noAddBcIds; srfcId++) {
609 const MInt rbSrfcId = m_addBndrySrfcIds[srfcId].first;
610 const MInt rbId = m_addBndrySrfcIds[srfcId].second;
612 const MInt polyDeg = m_rbElements.polyDeg(rbId);
613 const MInt noNodes1D = m_rbElements.noNodes1D(rbId);
614 const MInt orientation = m_rbSurfaces.orientation(rbSrfcId);
615 const MInt internalSide = m_rbSurfaces.internalSideId(rbSrfcId);
616 const MInt outerSide = (internalSide + 1) % 2;
617 const MInt dir = 2 * orientation + outerSide;
620 MFloat* src = &m_rbElements.variables(rbId);
621 MFloat* dest = &m_rbSurfaces.variables(rbSrfcId, 0);
624 prolongToFaceGauss<nDim, Base::SysEqn::noVars()>(src, dir, noNodes1D,
625 &interpolation(polyDeg, noNodes1D).m_LFace[0][0],
626 &interpolation(polyDeg, noNodes1D).m_LFace[1][0], dest);
628 prolongToFaceGaussLobatto<nDim, Base::SysEqn::noVars()>(src, dir, noNodes1D, dest);
631 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
632 const MInt dataSize = noNodes1D * noNodes1D3 * Base::SysEqn::noVars();
635 std::copy_n(&m_rbSurfaces.variables(rbSrfcId, 0), dataSize, &m_rbSurfaces.variables(rbSrfcId, 1));
638 RECORD_TIMER_STOP(m_timers[Timers::Prolong]);
641 RECORD_TIMER_START(m_timers[Timers::TimeDeriv]);
644 resetBuffer(m_internalDataSize, &m_rbElements.rightHandSide(0));
648 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
649 const MInt eId = m_elementId[rbId];
650 const MInt noNodes1D = noNodes[rbId];
651 const MInt noNodesXD =
ipow(noNodes1D, nDim);
652 const MInt dataSize = noNodesXD * Base::SysEqn::noVars();
655 std::copy_n(&m_rbElements.variables(rbId), dataSize, m_rbSolution[rbId]);
658 std::copy_n(&elements().variables(eId), dataSize, &m_rbElements.variables(rbId));
662 calcVolumeIntegral(m_rbElements.size(), m_rbElements, *
this);
668 calcRegularSurfaceFlux(0, m_rbSurfaces.size(), m_rbSurfaces, *
this);
671 calcSurfaceIntegral(0, m_rbElements.size(), m_rbElements, m_rbSurfaces, m_hRbElements, m_hRbElements.size());
674 applyJacobian(m_rbElements.size(), m_rbElements);
677 calcSourceTerms(time, m_rbElements.size(), m_rbElements, *
this);
680 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
681 const MInt noNodes1D = noNodes[rbId];
682 const MInt noNodesXD =
ipow(noNodes1D, nDim);
683 const MInt dataSize = noNodesXD * Base::SysEqn::noVars();
685 std::copy_n(m_rbSolution[rbId], dataSize, &m_rbElements.variables(rbId));
688 RECORD_TIMER_STOP(m_timers[Timers::TimeDeriv]);
691 RECORD_TIMER_START(m_timers[Timers::RungeKuttaStep]);
692 subTimeStepRk(dt(), m_rkStage, m_internalDataSize, &m_rbElements.rightHandSide(0), &m_rbElements.variables(0),
693 &m_rbElements.timeIntStorage(0));
697 m_rkStage = (m_rkStage + 1) % 5;
699 m_rkStage = (m_rkStage + 1) % 8;
701 m_rkStage = (m_rkStage + 1) % 14;
703 m_rkStage = (m_rkStage + 1) % 13;
705 m_rkStage = (m_rkStage + 1) % 7;
707 m_rkStage = (m_rkStage + 1) % 8;
710 RECORD_TIMER_STOP(m_timers[Timers::RungeKuttaStep]);
713 RECORD_TIMER_START(m_timers[Timers::ApplyAtSurface]);
715 RECORD_TIMER_STOP(m_timers[Timers::ApplyAtSurface]);
717 RECORD_TIMER_STOP(m_timers[Timers::Apply]);
729 MFloat* nodeVarsL = &surfaces().nodeVars(surfaceId, 0);
730 MFloat* nodeVarsR = &surfaces().nodeVars(surfaceId, 1);
731 MFloat* stateL = &surfaces().variables(surfaceId, 0);
732 MFloat* stateR = &surfaces().variables(surfaceId, 1);
733 const MInt noNodes1D = surfaces().noNodes1D(surfaceId);
734 const MInt dirId = surfaces().orientation(surfaceId);
738 MFloat* f = flux(surfaceId);
739 sysEqn().calcRiemann(nodeVarsL, nodeVarsR, stateL, stateR, noNodes1D, dirId, f);
753 const MInt noNodes1D,
757 const MInt noVars = Base::SysEqn::noVars();
758 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
759 const MFloatTensor U(
const_cast<MFloat*
>(q), noNodes1D, noNodes1D, noNodes1D3, noVars);
760 const MFloatTensor coeff(
const_cast<MFloat*
>(nodeVars), noNodes1D, noNodes1D, noNodes1D3, s_noNodeVars);
762 MFloatTensor f(flux_, noNodes1D, noNodes1D, noNodes1D3, nDim, noVars);
790 for(
MInt i = 0; i < noNodes1D; i++) {
791 for(
MInt j = 0; j < noNodes1D; j++) {
792 for(
MInt k = 0; k < noNodes1D3; k++) {
793 for(
MInt d = 0; d < nDim; d++) {
794 for(
MInt var = 0; var < noVars; var++) {
795 f(i, j, k, d, var) = coeff(i, j, k, d) * U(i, j, k, var);
817 const MInt noVars = Base::SysEqn::noVars();
818 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
820 const MFloatTensor coeff(
const_cast<MFloat*
>(nodeVars), noNodes1D, noNodes1D3, s_noNodeVars);
823 for(
MInt i = 0; i < noNodes1D; i++) {
824 for(
MInt j = 0; j < noNodes1D3; j++) {
825 for(
MInt var = 0; var < noVars; var++) {
826 f(i, j, var) = coeff(i, j, dirId) * U(i, j, var);
845 const MInt noNodes1D,
851 const MInt noVars = Base::SysEqn::noVars();
853 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
854 MFloatTensor s(src, noNodes1D, noNodes1D, noNodes1D3, noVars);
856 const MFloatTensor U(
const_cast<MFloat*
>(u), noNodes1D, noNodes1D, noNodes1D3, noVars);
857 const MFloatTensor coeff(
const_cast<MFloat*
>(nodeVars), noNodes1D, noNodes1D, noNodes1D3, nDim + 2);
859 for(
MInt i = 0; i < noNodes1D; i++) {
860 for(
MInt j = 0; j < noNodes1D; j++) {
861 for(
MInt k = 0; k < noNodes1D3; k++) {
862 for(
MInt var = 0; var < noVars; var++) {
863 s(i, j, k, var) = coeff(i, j, k, nDim + 1) * U(i, j, k, var);
883 const MInt noNodes1D,
888 const MInt noVars = Base::SysEqn::noVars();
889 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
900 const MFloatTensor cL(
const_cast<MFloat*
>(nodeVarsL), noNodes1D, noNodes1D3, s_noNodeVars);
901 const MFloatTensor cR(
const_cast<MFloat*
>(nodeVarsR), noNodes1D, noNodes1D3, s_noNodeVars);
904 for(
MInt i = 0; i < noNodes1D; i++) {
905 for(
MInt j = 0; j < noNodes1D3; j++) {
906 maxLambda(i, j) = std::max(fabs(cL(i, j, nDim)), fabs(cR(i, j, nDim)));
919 calcFlux1D(nodeVarsL, stateL, noNodes1D, dirId, &fluxL[0]);
920 calcFlux1D(nodeVarsR, stateR, noNodes1D, dirId, &fluxR[0]);
923 MFloatTensor riemann(flux_, noNodes1D, noNodes1D3, noVars);
924 for(
MInt i = 0; i < noNodes1D; i++) {
925 for(
MInt j = 0; j < noNodes1D3; j++) {
926 for(
MInt n = 0; n < noVars; n++) {
927 riemann(i, j, n) = 0.5 * ((fluxL(i, j, n) + fluxR(i, j, n)) - maxLambda(i, j) * (uR(i, j, n) - uL(i, j, n)));
946 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
947 const MInt eId = m_elementId[rbId];
948 const MInt noNodesXD = m_rbElements.noNodesXD(rbId);
949 const MFloat* coordinates = &m_rbElements.nodeCoordinates(rbId);
951 for(
MInt pId = 0; pId < noNodesXD; pId++) {
952 calcNodeVars(&coordinates[pId * nDim],
953 &elements().nodeVars(eId) + pId * Base::SysEqn::noNodeVars(),
954 &m_rbElements.nodeVars(rbId) + pId * s_noNodeVars);
972 for(
MInt rbSId = 0; rbSId < m_rbSurfaces.size(); rbSId++) {
973 const MInt sId = m_surfaceId[rbSId];
974 const MFloat* coordinates = &m_rbSurfaces.nodeCoords(rbSId);
975 const MInt noNodesXD = m_rbSurfaces.noNodesXD(rbSId);
977 for(
MInt pId = 0; pId < noNodesXD; pId++) {
978 calcNodeVars(&coordinates[pId * nDim],
979 &((&surfaces().nodeVars(sId, 0))[pId * Base::SysEqn::noNodeVars()]),
980 &((&m_rbSurfaces.nodeVars(rbSId, 0))[pId * s_noNodeVars]));
982 calcNodeVars(&coordinates[pId * nDim],
983 &((&surfaces().nodeVars(sId, 1))[pId * Base::SysEqn::noNodeVars()]),
984 &((&m_rbSurfaces.nodeVars(rbSId, 1))[pId * s_noNodeVars]));
1013 const MFloat c = nodeVarsAPE[Base::SysEqn::CV::C0];
1015 IF_CONSTEXPR(nDim == 2) {
1019 const MFloat x0 = m_rbcReferencePos[0];
1020 const MFloat y0 = m_rbcReferencePos[1];
1026 const MFloat cosPhi = (x - x0) * rInv;
1027 const MFloat sinPhi = (
y - y0) * rInv;
1030 const MFloat u0 = nodeVarsAPE[Base::SysEqn::CV::U0];
1031 const MFloat v0 = nodeVarsAPE[Base::SysEqn::CV::V0];
1043 const MFloat vg = u0 * cosPhi + v0 * sinPhi + sqrt(
POW2(c) -
POW2(-u0 * sinPhi + v0 * cosPhi));
1047 nodeVars[0] = vg * cosPhi;
1048 nodeVars[1] = vg * sinPhi;
1054 nodeVars[3] = 0.5 * vg * rInv;
1061 const MFloat x0 = m_rbcReferencePos[0];
1062 const MFloat y0 = m_rbcReferencePos[1];
1063 const MFloat z0 = m_rbcReferencePos[2];
1073 const MFloat cosPhi = (x - x0) * r2Inv;
1074 const MFloat sinPhi = (
y - y0) * r2Inv;
1075 const MFloat cosTheta = (z - z0) * rInv;
1076 const MFloat sinTheta = sqrt(1 -
POW2(cosTheta));
1079 const MFloat u0 = nodeVarsAPE[Base::SysEqn::CV::UU0[0]];
1080 const MFloat v0 = nodeVarsAPE[Base::SysEqn::CV::UU0[1]];
1081 const MFloat w0 = nodeVarsAPE[Base::SysEqn::CV::UU0[2]];
1084 const MFloat u_er = u0 * sinTheta * cosPhi + v0 * sinTheta * sinPhi + w0 * cosTheta;
1087 const MFloat u_et = u0 * cosTheta * cosPhi + v0 * cosTheta * sinPhi + w0 * (-sinTheta);
1090 const MFloat u_ep = u0 * (-sinPhi) + v0 * cosPhi;
1112 nodeVars[0] = vg * sinTheta * cosPhi;
1113 nodeVars[1] = vg * sinTheta * sinPhi;
1114 nodeVars[2] = vg * cosTheta;
1120 nodeVars[4] = vg * rInv;
1133 MInt localNoNodes = 0;
1134 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
1135 const MInt noNodesXD = m_rbElements.noNodesXD(rbId);
1137 localNoNodes += noNodesXD;
1140 return localNoNodes;
1154 std::stringstream varName;
1155 varName <<
"bc" <<
id() <<
"_" << Base::SysEqn::consVarNames(id_);
1157 return varName.str();
1171 RECORD_TIMER_START(m_timers[Timers::SetRestartVars]);
1175 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
1176 const MInt noNodesXD = m_rbElements.noNodesXD(rbId);
1177 MFloat*
const vars = &m_rbElements.variables(rbId);
1178 for(
MInt n = 0; n < noNodesXD; n++) {
1179 vars[n * Base::SysEqn::noVars() + id_] = data[offset + n];
1182 offset += noNodesXD;
1185 RECORD_TIMER_STOP(m_timers[Timers::SetRestartVars]);
1199 RECORD_TIMER_START(m_timers[Timers::GetRestartVars]);
1203 for(
MInt rbId = 0; rbId < m_rbElements.size(); rbId++) {
1204 const MInt noNodesXD = m_rbElements.noNodesXD(rbId);
1206 for(
MInt n = 0; n < noNodesXD; n++) {
1207 data[offset + n] = m_rbElements.variables(rbId, n * Base::SysEqn::noVars() + id_);
1210 offset += noNodesXD;
1213 RECORD_TIMER_STOP(m_timers[Timers::GetRestartVars]);
1225 if(dataId < 0 || dataId > Base::SysEqn::noVars()) {
1226 TERMM(1,
"Invalid dataId.");
1230 const MInt elementId = getElementByCellId(cellId);
1231 auto rbElemIt = std::find(m_elementId.begin(), m_elementId.end(), elementId);
1234 if(rbElemIt != m_elementId.end()) {
1236 const MInt rbId = std::distance(m_elementId.begin(), rbElemIt);
1237 const MInt noNodesXD = m_rbElements.noNodesXD(rbId);
1239 dataSize = noNodesXD;
1253 return std::find(m_elementId.begin(), m_elementId.end(), elementId) != m_elementId.end();
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
MBool mDeallocate(T *&a)
deallocates the memory previously allocated for element 'a'
void apply(const MFloat time) override
Apply RBC.
MInt getLocalNoNodes() const override
Return local number of nodes.
void setCellDataDlb(const MInt dataId, const MFloat *const data) override
MBool hasBcElement(const MInt elementId) const override
Check if there is a boundary condition element associated with the given element.
MInt cellDataTypeDlb(const MInt NotUsed(dataId)) const override
void getCellDataDlb(const MInt dataId, MFloat *const data) const override
std::array< MFloat, MAX_SPACE_DIMENSIONS > m_rbcReferencePos
void calcFlux1D(const MFloat *nodeVars, const MFloat *q, const MInt noNodes1D, const MInt dirId, MFloat *flux_) const
Calculates the physical fluxes in direction 'dirId' on a surface.
void applyAtSurface(const MInt surfaceId, const MFloat NotUsed(time))
Calculate boundary surface flux.
MInt noRestartVars() const override
static const constexpr MInt s_noNodeVars
std::vector< MInt > m_rbElementId
SurfaceCollector m_rbSurfaces
MInt noBcElements() const override
MString restartVarName(const MInt id_) const override
Return name of restart variable.
HElementCollector m_hRbElements
void calcFlux(const MFloat *nodeVars, const MFloat *q, const MInt noNodes1D, MFloat *flux_) const
Calculates the physical fluxes in all directions for all integration points in an element.
MInt noCellDataDlb() const override
Dynamic load balancing.
ElementCollector m_rbElements
void getRestartVariable(const MInt id_, MFloat *const data) const override
Copy restart variable data to pointer.
MString name() const override
Returns name of boundary condition.
void init() override
Initialize RBC.
void initTimers()
Initialize all timers and start the class timer.
void setRestartVariable(const MInt id_, const MFloat *const data) override
Copy restart variable data to boundary conditon.
void calcNodeVars(const MFloat *pos, const MFloat *nodeVarsAPE, MFloat *nodeVars)
Calculate RBC node variables at a given position.
void calcSurfaceNodeVars()
Calculate node variables of rb-surfaces.
void calcSource(const MFloat *nodeVars, const MFloat *u, const MInt noNodes1D, const MFloat t, const MFloat *x, MFloat *src) const
Calculates the source terms of the RBC system.
void calcElementNodeVars()
Calculate node variables of rb-elements.
std::vector< std::pair< MInt, MInt > > m_addBndrySrfcIds
std::array< MInt, Timers::_count > m_timers
~DgBcAcousticPerturbRBC()
DgBcAcousticPerturbRBC(SolverType &solver_, MInt bcId)
void calcRiemann(const MFloat *nodeVarsL, const MFloat *nodeVarsR, const MFloat *stateL, const MFloat *stateR, const MInt noNodes1D, const MInt dirId, MFloat *flux_) const
Calculates the numerical flux at a surface given two states.
std::vector< MInt > m_rbSurfaceId
std::vector< MInt > m_surfaceId
std::vector< MInt > m_elementId
MInt cellDataSizeDlb(const MInt dataId, const MInt cellId) const override
Solution data size for given cell and data id.
const DgInterpolation & interpolation(const MInt polyDeg, const MInt noNodes1D) const
Return interpolation.
void calcSourceTerms(const MFloat t, const MInt noElements, ElementCollector &elem, F &sourceFct)
MInt id() const
Return boundary condition if of this boundary condition.
SurfaceCollector & surfaces()
Return reference to surfaces.
MInt timeIntegrationScheme() const
Return time integration scheme.
MBool needHElementForCell(const MInt cellId)
Return if h-element is needed for given cell.
ElementCollector & elements()
Return reference to elements.
MBool isRestart() const
Return if a restart is performed.
DgCartesianSolver< nDim, SysEqn > SolverType
MInt getElementByCellId(const MInt cellId) const
Return element id corresponding to given cell id.
void calcSurfaceIntegral(const MInt begin_, const MInt end_, ElementCollector &elem, SurfaceCollector &surf, HElementCollector &helem, const MInt noHElements)
void applyJacobian(const MInt noElements, ElementCollector &elem)
void subTimeStepRk(const MFloat dt_, const MInt stage, const MInt totalSize, const MFloat *const rhs, MFloat *const variables, MFloat *const timeIntStorage)
Access to time integration method.
SysEqn & sysEqn()
Return reference to SysEqn object.
SolverType & solver()
Return reference to solver.
HElementCollector & helements()
Return reference to h-elements.
MInt getHElementId(const MInt elementId)
Return h-element id for an element.
MInt maxPolyDeg() const
Return maximum polynomial degree.
MBool isMpiSurface(const MInt id_) const
Return true if surface is a MPI surface.
MFloat dt() const
Return current time step size.
void calcVolumeIntegral(const MInt noElements, ElementCollector &elem, F &fluxFct)
DgSysEqnAcousticPerturb< nDim > SysEqn
MInt begin() const
Return index of first surface.
void resetBuffer(const MInt totalSize, MFloat *const buffer)
MInt end() const
Return index of one-past-last surface.
MInt integrationMethod() const
Return integration method.
void calcRegularSurfaceFlux(const MInt begin_, const MInt end_, SurfaceCollector &surf, F &riemannFct)
MInt maxNoNodes1D() const
Return maximum number of nodes.
MFloat * flux(const MInt i)
Return pointer to surface flux.
This class is a ScratchSpace.
constexpr MInt size() const
Return size (i.e., currently used number of nodes)
Class that represents DG element collector.
Class that represents DG element collector.
Class that represents DG element collector.
@ DG_INTEGRATE_GAUSS_LOBATTO
@ DG_TIMEINTEGRATION_CARPENTER_4_5
@ DG_TIMEINTEGRATION_TOULORGEC_3_7
@ DG_TIMEINTEGRATION_TOULORGEC_4_8
@ DG_TIMEINTEGRATION_TOULORGEF_4_8
@ DG_TIMEINTEGRATION_NIEGEMANN_4_13
@ DG_TIMEINTEGRATION_NIEGEMANN_4_14
constexpr Real POW2(const Real x)
MInt ipow(MInt base, MInt exp)
Integer exponent function for non-negative exponents.
std::basic_string< char > MString
void loop(Functor &&fun, Class *object, const IdType begin, const IdType end, Args... args)
Holds helper functions for the interpolation.