MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
dgcartesiansponge.h
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
7#ifndef DGSPONGE_H_
8#define DGSPONGE_H_
9
10#include <algorithm>
11#include <array>
12#include <limits>
13#include <memory>
14#include <numeric>
15#include <set>
16#include <utility>
17#include <vector>
18
19#include "COMM/mpioverride.h"
21#include "INCLUDE/maiatypes.h"
22#include "IO/context.h"
23#include "MEMORY/collector.h"
24#include "MEMORY/scratch.h"
25#include "UTIL/functions.h"
26#include "config.h"
32#include "property.h"
33#include "typetraits.h"
34
41template <MInt nDim>
47 std::array<MFloat, nDim> m_minCoord;
48 std::array<MFloat, nDim> m_maxCoord;
49};
50
51
58template <MInt nDim, class SysEqn>
59class DgSponge {
61 using Grid = typename maia::grid::Proxy<nDim>;
66
67 public:
68 // Methods
70 MPI_Comm mpiComm() const { return m_mpiComm; }
72 MInt domainId() const { return m_domainId; }
74 MInt noDomains() const { return m_noDomains; }
75 DgSponge(const MInt solverId, const MPI_Comm comm);
76 void init(const MInt maxPolyDeg, Grid* grid_, ElementCollector* elements_, SurfaceCollector* surfaces_,
77 std::vector<BC>* boundaryConditions, SysEqn* sysEqn, const MPI_Comm comm);
78 void calcSourceTerms();
79
80 // Accessor methods
82 MInt elementId(const MInt seId) const { return m_spongeElements.elementId(seId); }
83 MInt spongeElementId(const MInt eId) const;
84 MFloat spongeEta(const MInt seId, const MInt pos) { return m_spongeElements.spongeEta(seId, pos); }
85
86 private:
87 // Sponge Layer
89 void initSpongeElements();
90 void initSpongeLayer(SpongeLayerType& spongeLayer, const BC& boundaryCondition);
91 void exchangeSpongeLayers(std::vector<SpongeLayerType>& spongeLayers);
92 void calcSpongeEtaForAllNodes(const MInt seId, const std::vector<SpongeLayerType>& spongeLayers);
93 MFloat distance(const SpongeLayerType& spongeLayer, const MFloat* otherPoint) const;
94 MBool pointInsideSpongeLayer(const SpongeLayerType& spongeLayer, const MFloat* otherPoint, MFloat& diff) const;
95
96 // Solver variables
97 const MInt m_solverId = -1;
98 MPI_Comm m_mpiComm = MPI_COMM_NULL;
101
102 // Grid variables
103 Grid* m_grid = nullptr;
104
105 // Polynomial degree variables
107
108 // Element variables
110
111 // Boundary condition variables
112 std::vector<BC>* m_boundaryConditions = nullptr;
113
114 // Surface variables
116
117 // Source calculation variables
118 SysEqn* m_sysEqn = nullptr;
119
120 // Sponge elements
122};
123
124
132template <MInt nDim, class SysEqn>
133DgSponge<nDim, SysEqn>::DgSponge(const MInt solverId, const MPI_Comm comm) : m_solverId(solverId), m_mpiComm(comm) {
134 TRACE();
135}
136
137
153template <MInt nDim, class SysEqn>
154void DgSponge<nDim, SysEqn>::init(const MInt maxPolyDeg, Grid* grid_, ElementCollector* elements_,
155 SurfaceCollector* surfaces_, std::vector<BC>* boundaryConditions, SysEqn* sysEqn,
156 const MPI_Comm comm) {
157 TRACE();
158
159 m_mpiComm = comm;
160 // Determine domain id and number of domains
161 MPI_Comm_rank(mpiComm(), &m_domainId);
162 MPI_Comm_size(mpiComm(), &m_noDomains);
163
164 m_maxPolyDeg = maxPolyDeg;
165 m_grid = grid_;
166 m_elements = elements_;
167 m_surfaces = surfaces_;
168 m_boundaryConditions = boundaryConditions;
169 m_sysEqn = sysEqn;
170
171 // Make sure that all BCs marked as spongeBCs are actually present in
172 // simulation setup (sanity check)
173 checkSpongeBoundaryConditions();
174
175 // Intialize a sponge element for each DG element affected by a sponge layer
176 initSpongeElements();
177}
178
179
186template <MInt nDim, class SysEqn>
188 TRACE();
189
190 // Get number of boundary conditions over all domains
191 const MInt noBcs = m_boundaryConditions->size();
192 const MInt noDomains1 = (domainId() != 0) ? 1 : noDomains();
193 MIntScratchSpace noBcsPerDomain(noDomains1, AT_, "noBcsPerDomain");
194 MPI_Gather(const_cast<MInt*>(&noBcs), 1, maia::type_traits<MInt>::mpiType(), &noBcsPerDomain[0], 1,
195 maia::type_traits<MInt>::mpiType(), 0, mpiComm(), AT_, "const_cast<MInt*>(&noBcs)", "noBcsPerDomain[0]");
196
198 // Gather information on root
200
201 // sendbuf
202 const MInt noBcs1 = (noBcs == 0) ? 1 : noBcs;
203 MIntScratchSpace bcIds(noBcs1, AT_, "bcIds");
204 for(MInt i = 0; i < noBcs; i++) {
205 bcIds[i] = (*m_boundaryConditions)[i]->id();
206 }
207
208 // recvbuf
209 const MInt noBcsTotal1 = (domainId() != 0) ? 1 : std::accumulate(noBcsPerDomain.begin(), noBcsPerDomain.end(), 0);
210 MIntScratchSpace bcIdsPerDomain(noBcsTotal1, AT_, "bcIdsPerDomain");
211
212 // displs
213 MIntScratchSpace displs(noDomains1, AT_, "displs");
214 displs[0] = 0;
215 for(MInt i = 1; i < noDomains1; i++) {
216 displs[i] = displs[i - 1] + noBcsPerDomain[i - 1];
217 }
218
219 // Get boundary condition ids for all domains
220 MPI_Gatherv(&bcIds[0], noBcs, maia::type_traits<MInt>::mpiType(), &bcIdsPerDomain[0], &noBcsPerDomain[0], &displs[0],
221 maia::type_traits<MInt>::mpiType(), 0, mpiComm(), AT_, "bcIds[0]", "bcIdsPerDomain[0]");
222
223 // Copy to set to eliminate repeated entries
224 std::set<MInt> bcIdsUnique(bcIdsPerDomain.begin(), bcIdsPerDomain.end());
225
227 // Read properties and set m_spongeBoundaryConditionIds
229
230 // get property
231 // MProperty* spongeBcProperty = nullptr;
232 if(Context::propertyExists("spongeBCs", m_solverId)) {
246 } else {
247 TERMM(1, "Sponge is activated, but spongeBCs property is not defined.");
248 }
249
250 // read sponge boundary condition ids
251 const MInt noSpongeBcs = Context::propertyLength("spongeBCs", m_solverId);
252 for(MInt i = 0; i < noSpongeBcs; i++) {
253 const MInt spongeBcId = Context::getSolverProperty<MInt>("spongeBCs", m_solverId, AT_, i);
254 // check whether boundary condition is valid
255 if(domainId() == 0 && bcIdsUnique.count(spongeBcId) == 0) {
256 TERMM(1, "BC " + std::to_string(spongeBcId) + " in spongeBCs is not a valid boundary condition id.");
257 }
258 }
259}
260
261
280template <MInt nDim, class SysEqn>
282 TRACE();
283
284 // Setting default sponge thickness to nonsense value, so it can be easily
285 // discerned later if default sponge thickness applies.
286 MFloat defaultThickness = -std::numeric_limits<MFloat>::infinity();
299 defaultThickness = Context::getSolverProperty<MFloat>("defaultSpongeThickness", m_solverId, AT_, &defaultThickness);
300
301 // get property
302 const MInt noSpongeBcs = Context::propertyLength("spongeBCs", m_solverId);
303
304 // 1. for sponge bc's calculate a boundary plane
305 std::vector<SpongeLayerType> spongeLayers(noSpongeBcs);
306 for(MInt i = 0; i < noSpongeBcs; i++) {
307 // Store for convenience
308 SpongeLayerType& layer = spongeLayers[i];
309
310 // Determine sponge BC id
311 const MInt spongeBcId = Context::getSolverProperty<MInt>("spongeBCs", m_solverId, AT_, i);
312
313 layer.m_bcId = spongeBcId;
314
315 // Determine thickness
316 const MString propName = "spongeThickness_" + std::to_string(spongeBcId);
328 layer.m_thickness = Context::getSolverProperty<MFloat>(propName, m_solverId, AT_, &defaultThickness);
329
330 if(layer.m_thickness < 0.0) {
331 TERMM(1,
332 "No valid definition for spongeThickness_" + std::to_string(spongeBcId)
333 + ". Specify positive value or check your default sponge size.");
334 }
335
336 // Initialize sponge layer
337 const auto boundaryConditionIt = std::find_if(m_boundaryConditions->begin(),
338 m_boundaryConditions->end(),
339 [spongeBcId](const BC& bc) { return bc->id() == spongeBcId; });
340 if(boundaryConditionIt == m_boundaryConditions->end()) {
341 // This should never happen, since all boundary conditions are initialized
342 // on all domains even if no actual boundary surfaces exist locally
343 TERMM(1, "Boundary condition id " + std::to_string(spongeBcId) + " not found");
344 }
345 if((*boundaryConditionIt)->count() > 0) {
346 // If sponge BC id has surfaces on current domain, initialize it properly
347 const BC& boundaryCondition = *boundaryConditionIt;
348 initSpongeLayer(layer, boundaryCondition);
349 } else {
350 // Otherwise use *sensible* default values for minimum and maximum extent
351 std::fill_n(layer.m_minCoord.begin(), nDim, std::numeric_limits<MFloat>::max());
352 std::fill_n(layer.m_maxCoord.begin(), nDim, -std::numeric_limits<MFloat>::max());
353 }
354 }
355
356 // 1.A if necessary exchange boundary planes
357 exchangeSpongeLayers(spongeLayers);
358
359 // 2. allocate memory for the sponge layer
360 MBoolScratchSpace spongeElementFlags(m_elements->size(), AT_, "spongeElementFlags");
361 std::fill(spongeElementFlags.begin(), spongeElementFlags.end(), false);
362
363// count the number of elements in the sponge layer
364#ifdef _OPENMP
365#pragma omp parallel for
366#endif
367 for(MInt eId = 0; eId < m_elements->size(); eId++) {
368 const MInt noNodes = m_elements->noNodesXD(eId);
369
370 const MFloat* const nodeCoordinates = &m_elements->nodeCoordinates(eId);
371 // check if any node of the element is inside the spongelayer
372 for(MInt nodeId = 0; nodeId < noNodes; nodeId++) {
373 const MFloat* const point = &nodeCoordinates[nodeId * nDim];
374
375 // check for each boundary plane
376 for(size_t i = 0; i < spongeLayers.size(); i++) {
377 MFloat diff = 0.0;
378 if(pointInsideSpongeLayer(spongeLayers[i], point, diff)) {
379 spongeElementFlags[eId] = true;
380 break;
381 }
382 }
383
384 // leave loop since already determined element is inside of sponge layer
385 if(spongeElementFlags[eId]) {
386 break;
387 }
388 }
389 }
390
391 // Allocate memory for sponge elements
392 const MInt spongeElementsCount = std::count(spongeElementFlags.begin(), spongeElementFlags.end(), true);
393 m_spongeElements.maxPolyDeg(m_maxPolyDeg);
394 m_spongeElements.reset(spongeElementsCount);
395
396 // Determine sponge element id and create sponge element in collector
397 for(size_t i = 0; i < spongeElementFlags.size(); i++) {
398 if(spongeElementFlags[i]) {
399 const MInt seId = noSpongeElements();
400 m_spongeElements.append();
401 m_spongeElements.elementId(seId) = i;
402 }
403 }
404
405// 3. calculate eta for all sponge elements
406#ifdef _OPENMP
407#pragma omp parallel for
408#endif
409 for(MInt seId = 0; seId < noSpongeElements(); seId++) {
410 calcSpongeEtaForAllNodes(seId, spongeLayers);
411 }
412}
413
414
421template <MInt nDim, class SysEqn>
422void DgSponge<nDim, SysEqn>::initSpongeLayer(SpongeLayerType& spongeLayer, const BC& boundaryCondition) {
423 TRACE();
424
425 const MInt firstSrfcId = boundaryCondition->begin();
426 const MFloat* srfcCoord = &m_surfaces->coords(firstSrfcId, 0);
427
428 // Store orientation
429 MInt orientation = m_surfaces->orientation(firstSrfcId);
430 MInt direction = m_surfaces->internalSideId(firstSrfcId);
431 spongeLayer.m_orientation = 2 * orientation + direction;
432
433 // Correct orientation of the boundary condition manually
434 // used for the direct-hybrid testcase of a acoustically
435 // exicted flame
436 if(spongeLayer.m_bcId == 200) {
437 orientation = 0;
438 direction = 0;
439 spongeLayer.m_orientation = 0;
440 }
441 if(spongeLayer.m_bcId == 201) {
442 orientation = 1;
443 direction = 1;
444 spongeLayer.m_orientation = 3;
445 }
446 if(spongeLayer.m_bcId == 202) {
447 orientation = 1;
448 direction = 1;
449 spongeLayer.m_orientation = 3;
450 }
451 if(spongeLayer.m_bcId == 203) {
452 orientation = 0;
453 direction = 1;
454 spongeLayer.m_orientation = 1;
455 }
456
457 // Store offset (distance to origin)
458 spongeLayer.m_offset = srfcCoord[orientation];
459
460 // Determine minimum and maximum coordinates
461 std::fill_n(&spongeLayer.m_minCoord[0], nDim, std::numeric_limits<MFloat>::max());
462 spongeLayer.m_minCoord[orientation] = srfcCoord[orientation];
463 std::fill_n(&spongeLayer.m_maxCoord[0], nDim, -std::numeric_limits<MFloat>::max());
464 spongeLayer.m_maxCoord[orientation] = srfcCoord[orientation];
465
466 // Determine minimum and maximum extent of boundary by checking each surface
467 for(MInt i = boundaryCondition->begin(); i < boundaryCondition->end(); i++) {
468 const MFloat* srfcCenter = &m_surfaces->coords(i, 0);
469 const MInt internalSideId = m_surfaces->internalSideId(i);
470 // FIXME labels:DG,toenhance Boundary surfaces with two neighbor elements should not exist. For
471 // now, they are simply skipped.
472 if(internalSideId == -1) {
473 continue;
474 }
475 const MInt eId = m_surfaces->nghbrElementIds(i, internalSideId);
476 const MInt cellId = m_elements->cellId(eId);
477 const MFloat halfCellLength = m_grid->halfCellLength(cellId);
478 for(MInt j = 0; j < nDim; j++) {
479 if(j != orientation) {
480 spongeLayer.m_minCoord[j] = std::min(spongeLayer.m_minCoord[j], srfcCenter[j] - halfCellLength);
481 spongeLayer.m_maxCoord[j] = std::max(spongeLayer.m_maxCoord[j], srfcCenter[j] + halfCellLength);
482 }
483 }
484 }
485}
486
487
494template <MInt nDim, class SysEqn>
495void DgSponge<nDim, SysEqn>::exchangeSpongeLayers(std::vector<SpongeLayerType>& spongeLayers) {
496 TRACE();
497
499 // Exchange sponge layer ids
501
502 // Set up communication buffer
503 const MInt noSpongeBcs = spongeLayers.size();
504 ScratchSpace<MChar> whichSpongeLayers(noDomains(), noSpongeBcs, AT_, "whichSpongeLayers");
505
506 // For each sponge BC id, store if it has surfaces on current domain
507 for(MInt i = 0; i < noSpongeBcs; i++) {
508 const MInt spongeBcId = spongeLayers[i].m_bcId;
509 whichSpongeLayers(domainId(), i) =
510 std::find_if(m_boundaryConditions->begin(),
511 m_boundaryConditions->end(),
512 [spongeBcId](const BC& bc) { return bc->id() == spongeBcId && bc->count() > 0; })
513 != m_boundaryConditions->end();
514 }
515
516 // Exchange with all domains
517 MPI_Allgather(MPI_IN_PLACE, noSpongeBcs, maia::type_traits<MChar>::mpiType(), &whichSpongeLayers(0, 0), noSpongeBcs,
518 maia::type_traits<MChar>::mpiType(), mpiComm(), AT_, "MPI_IN_PLACE", "whichSpongeLayers(0");
519
521 // Exchange boundary planes and thicknesses
523
524 // One broadcast per sponge BC:
525 // 1.) If whichSpongeLayerRecv is false, nothing has to be done.
526 // 2.) If whichSpongeLayerRecv is true, make sure that domains with higher id
527 // do not broadcast.
528 // 3.) Prepare and perform broadcast.
529 // Iterating through whichSpongeLayer is equivalent to iterating through
530 // all domains and sponge BCs
531 for(MInt i = 0; i < noDomains(); i++) {
532 for(MInt j = 0; j < noSpongeBcs; j++) {
533 // Step 1
534 if(!whichSpongeLayers(i, j)) {
535 continue;
536 }
537
538 // Step 2
539 for(MInt k = i + 1; k < noDomains(); k++) {
540 whichSpongeLayers(k, j) = false;
541 }
542
543 // Step 3
544 const MInt spongeBcId = spongeLayers[j].m_bcId;
545 SpongeLayerType& spongeLayer =
546 *std::find_if(spongeLayers.begin(), spongeLayers.end(),
547 [spongeBcId](const SpongeLayerType& sl) { return sl.m_bcId == spongeBcId; });
548 MPI_Bcast(&spongeLayer.m_orientation, 1, maia::type_traits<MInt>::mpiType(), i, mpiComm(), AT_,
549 "spongeLayer.m_orientation");
550 MPI_Bcast(&spongeLayer.m_offset, 1, maia::type_traits<MFloat>::mpiType(), i, mpiComm(), AT_,
551 "spongeLayer.m_offset");
552 MPI_Allreduce(MPI_IN_PLACE, &spongeLayer.m_minCoord[0], nDim, maia::type_traits<MFloat>::mpiType(), MPI_MIN,
553 mpiComm(), AT_, "MPI_IN_PLACE", "spongeLayer.m_minCoord[0]");
554 MPI_Allreduce(MPI_IN_PLACE, &spongeLayer.m_maxCoord[0], nDim, maia::type_traits<MFloat>::mpiType(), MPI_MAX,
555 mpiComm(), AT_, "MPI_IN_PLACE", "spongeLayer.m_maxCoord[0]");
556 }
557 }
558}
559
560
568template <MInt nDim, class SysEqn>
570 const MInt* const begin = &m_spongeElements.elementId(0);
571 const MInt* const end = &m_spongeElements.elementId(0) + noSpongeElements();
572 const MInt* const low = std::lower_bound(begin, end, eId);
573
574 // Return not found if std::lower_bound does not find anything
575 if(low == end || *low != eId) {
576 return -1;
577 }
578
579 // Otherwise return found sponge element id
580 return std::distance(begin, low);
581}
582
583
592template <MInt nDim, class SysEqn>
594 TRACE();
595
596 // const MInt* polyDeg = &m_elements->polyDeg(0);
597 const MInt* noNodes1D = &m_elements->noNodes1D(0);
598 const MInt maxDataBlockSize = m_elements->maxNoNodesXD() * SysEqn::noVars();
599
600 std::vector<MFloat> spongeSources(maxDataBlockSize);
601
602#ifdef _OPENMP
603#pragma omp parallel for firstprivate(spongeSources)
604#endif
605 for(MInt seId = 0; seId < noSpongeElements(); seId++) {
606 const MInt eId = m_spongeElements.elementId(seId);
607 const MInt dataBlockSize = m_elements->noNodesXD(eId) * SysEqn::noVars();
608 m_sysEqn->calcSpongeSource(&m_elements->nodeVars(eId),
609 &m_elements->variables(eId),
610 noNodes1D[eId],
611 &m_spongeElements.spongeEta(seId),
612 &spongeSources[0]);
613 MFloat* const rhs = &m_elements->rightHandSide(eId);
614 for(MInt dataId = 0; dataId < dataBlockSize; dataId++) {
615 rhs[dataId] += spongeSources[dataId];
616 }
617 }
618}
619
620
627template <MInt nDim, class SysEqn>
629 const std::vector<SpongeLayerType>& spongeLayers) {
630 TRACE();
631
632 const MInt eId = m_spongeElements.elementId(seId);
633 const MInt noNodes1D = m_elements->noNodes1D(eId);
634 const MInt noNodes1D3 = (nDim == 3) ? noNodes1D : 1;
635
636 MFloatTensor nodeCoordinates(&m_elements->nodeCoordinates(eId), noNodes1D, noNodes1D, noNodes1D3, nDim);
637
638 MFloatTensor sEta(&m_spongeElements.spongeEta(seId), noNodes1D, noNodes1D, noNodes1D3);
639 std::fill_n(&sEta(0, 0, 0), sEta.size(), 0.0);
640
641 for(MInt i = 0; i < noNodes1D; i++) {
642 for(MInt j = 0; j < noNodes1D; j++) {
643 for(MInt k = 0; k < noNodes1D3; k++) {
644 for(size_t s = 0; s < spongeLayers.size(); s++) {
645 MFloat diff = 0.0;
646 if(pointInsideSpongeLayer(spongeLayers[s], &nodeCoordinates(i, j, k, 0), diff)) {
647 const MFloat eta = POW2(diff / spongeLayers[s].m_thickness);
648 sEta(i, j, k) = std::max(sEta(i, j, k), eta);
649 }
650 }
651 }
652 }
653 }
654}
655
656
664template <MInt nDim, class SysEqn>
665MFloat DgSponge<nDim, SysEqn>::distance(const SpongeLayerType& spongeLayer, const MFloat* point) const {
666 // 0=x, 1=y, 2=z
667 const MInt orientation = (spongeLayer.m_orientation - spongeLayer.m_orientation % 2) / 2;
668 // 1=inside in positive direction, -1=inside in negative direction
669 const MInt direction = 2 * (spongeLayer.m_orientation % 2) - 1;
670
671 return direction * (point[orientation] - spongeLayer.m_offset);
672}
673
674
683template <MInt nDim, class SysEqn>
685 MFloat& diff) const {
686 // distance to boundary plane
687 MFloat dist = distance(spongeLayer, point);
688 if(dist < 0.0) {
689 return false;
690 }
691 diff = spongeLayer.m_thickness - dist;
692 if(diff < 0.0) {
693 return false;
694 }
695
696 // within min and max coordinates
697 for(MInt i = 0; i < nDim; i++) {
698 const MInt orientation = (spongeLayer.m_orientation - spongeLayer.m_orientation % 2) / 2;
699 if(orientation == i) {
700 continue;
701 }
702
703 if(point[i] < spongeLayer.m_minCoord[i] || point[i] > spongeLayer.m_maxCoord[i]) {
704 return false;
705 }
706 }
707
708 return true;
709}
710
711#endif // DGSPONGE_H_
static MInt propertyLength(const MString &name, MInt solverId=m_noSolvers)
Returns the number of elements of a property.
Definition: context.cpp:538
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Definition: context.cpp:494
std::unique_ptr< DgBoundaryCondition< nDim, SysEqn > > ReturnType
Container for sponge elements.
SpongeElementCollector m_spongeElements
MPI_Comm mpiComm() const
Return the MPI communicator used by the corresponding solver.
MPI_Comm m_mpiComm
MInt elementId(const MInt seId) const
std::vector< BC > * m_boundaryConditions
MInt spongeElementId(const MInt eId) const
Return sponge element id for given element id. If none exists, return -1.
void exchangeSpongeLayers(std::vector< SpongeLayerType > &spongeLayers)
Exchange sponge layers between all domains.
maia::dg::collector::ElementCollector< nDim, SysEqn > ElementCollector
MInt domainId() const
Return the domain id of the corresponding solver.
DgSpongeLayer< nDim > SpongeLayerType
void checkSpongeBoundaryConditions() const
Check whether boundary conditions specified to have a sponge exist.
void calcSpongeEtaForAllNodes(const MInt seId, const std::vector< SpongeLayerType > &spongeLayers)
Calculation of SpongeEta for all nodes of one DG-Element.
MBool pointInsideSpongeLayer(const SpongeLayerType &spongeLayer, const MFloat *otherPoint, MFloat &diff) const
Returns true if point is inside sponge layer. Calculates difference between thickness of sponge layer...
ElementCollector * m_elements
void initSpongeLayer(SpongeLayerType &spongeLayer, const BC &boundaryCondition)
Determines boundary plane.
void init(const MInt maxPolyDeg, Grid *grid_, ElementCollector *elements_, SurfaceCollector *surfaces_, std::vector< BC > *boundaryConditions, SysEqn *sysEqn, const MPI_Comm comm)
Sets attributes so that sponge can access necessary components in solver. Checks sponge boundary cond...
typename maia::grid::Proxy< nDim > Grid
SysEqn * m_sysEqn
maia::dg::collector::SurfaceCollector< nDim, SysEqn > SurfaceCollector
SurfaceCollector * m_surfaces
MFloat distance(const SpongeLayerType &spongeLayer, const MFloat *otherPoint) const
Calculates the distance between a point and a boundary plane. The distance is signed,...
void calcSourceTerms()
Calculates the sponge terms, that can be considered as an addition source terms for each node and add...
DgSponge(const MInt solverId, const MPI_Comm comm)
Constructor accepts solver id and MPI communicator.
const MInt m_solverId
MInt noDomains() const
Return the number of domains of the corresponding solver.
MFloat spongeEta(const MInt seId, const MInt pos)
void initSpongeElements()
Initialisation of SpongeLayer. Calculation of spongeEta. Sponge is an additional Sourceoperator: DelL...
MInt noSpongeElements() const
typename DgBoundaryConditionFactory< nDim, SysEqn >::ReturnType BC
This class is a ScratchSpace.
Definition: scratch.h:758
iterator end()
Definition: scratch.h:281
constexpr MInt size() const
Return size (i.e., currently used number of nodes)
Definition: container.h:89
Class that represents DG element collector.
Class that represents DG element collector.
MFloat & spongeEta(const MInt id)
Accessor for sponge eta.
MInt & elementId(const MInt id)
Accessor for element id.
Class that represents DG element collector.
size_type size() const
Returns the size of the array as product of all five dimensions (i.e. not the actual array size but t...
Definition: tensor.h:206
constexpr Real POW2(const Real x)
Definition: functions.h:119
int32_t MInt
Definition: maiatypes.h:62
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
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 dist(const Point< DIM > &p, const Point< DIM > &q)
Definition: pointbox.h:54
Container for attributes characterizing sponge layer.
std::array< MFloat, nDim > m_maxCoord
std::array< MFloat, nDim > m_minCoord