MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
lbsrctermsponge.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#include <unordered_map>
8#include "COMM/mpioverride.h"
9#include "IO/context.h"
10#include "UTIL/debug.h"
11#include "lbsolverdxqy.h"
12#include "lbsrcterm.h"
13#include "lbsrctermcontroller.h"
14
15namespace maia::lb {
16
21template <MInt nDim, MInt nDist, class SysEqn>
22class LbSrcTerm_sponge : public LbSrcTerm<nDim, nDist, SysEqn> {
23 private:
25
26 protected:
28
30
31 struct SpongeCell {
34 };
35
36 std::vector<SpongeCell> m_spongeCells;
37 std::unordered_map<MInt, MInt> m_mapCellId2SpongeCellId;
38
40 std::array<MFloat, 2 * nDim> m_spongeThicknessFactor{};
44 std::array<MFloat, nDim> m_trgU{};
45
50 MInt a_spongeCellId(const MInt cellId) {
51 MInt spongeCellId = -1;
52 auto search = m_mapCellId2SpongeCellId.find(cellId);
53 if(search != m_mapCellId2SpongeCellId.end()) {
54 spongeCellId = search->second;
55 }
56 return spongeCellId;
57 };
58
59 void readProperties() override;
60
61 public:
63
64 void init() override;
65};
66
71template <MInt nDim, MInt nDist, class SysEqn>
73 const MInt noSpongeCells = m_spongeCells.size();
74 m_mapCellId2SpongeCellId.clear();
75 m_mapCellId2SpongeCellId.reserve(noSpongeCells);
76 for(MInt spongeCellId = 0; spongeCellId < noSpongeCells; spongeCellId++) {
77 m_mapCellId2SpongeCellId.emplace(m_spongeCells[spongeCellId].cellId, spongeCellId);
78 }
79}
80
85template <MInt nDim, MInt nDist, class SysEqn>
87 TRACE();
88 const MInt solverId = m_solver->m_solverId;
89
90 std::stringstream ss;
91 ss << "--------------------------------------------------------------------------------" << std::endl;
92 ss << " Sponge properties" << std::endl;
93 ss << "--------------------------------------------------------------------------------" << std::endl;
94 ss << " [Sponge region]" << std::endl;
95
96 // sponge information
97 m_spongeSigma = Context::getSolverProperty<MFloat>("spongeSigma", solverId, AT_, &m_spongeSigma);
98 m_spongeLayerThickness =
99 Context::getSolverProperty<MFloat>("spongeLayerThickness", solverId, AT_, &m_spongeLayerThickness);
100 ss << " spongeSigma: " << m_spongeSigma << std::endl;
101 ss << " spongeLayerThickness: " << m_spongeLayerThickness << std::endl;
102 ss << " spongeThicknessFactor: [ ";
103 for(MInt i = 0; i < 2 * nDim; i++) {
104 m_spongeThicknessFactor[i] = Context::getSolverProperty<MFloat>("spongeThicknessFactor", solverId, AT_, i);
105 ss << m_spongeThicknessFactor[i] << " ";
106 }
107 ss << "]" << std::endl;
108 ss << " [Sponge shape]" << std::endl;
109 m_spongeBeta = Context::getSolverProperty<MFloat>("spongeBeta", solverId, AT_, &m_spongeBeta);
110 ss << " spongeBeta: " << m_spongeBeta << std::endl;
111 ss << " [Sponge target state]" << std::endl;
112 m_trgRho = (m_solver->m_densityFluctuations) ? 0.0 : 1.0;
113 m_trgRho = Context::getSolverProperty<MFloat>("spongeTrgRho", solverId, AT_, &m_trgRho);
114 ss << " spongeTrgRho: " << m_trgRho << std::endl;
115 m_trgU.fill(0.0);
116 for(MInt i = 0; i < nDim; i++) {
117 m_trgU[i] = Context::getSolverProperty<MFloat>("spongeTrgU", solverId, AT_, &m_trgU[i], i) * m_solver->m_Ma * LBCS;
118 }
119 ss << " spongeTrgU: ";
120 for(MInt i = 0; i < nDim; i++) {
121 ss << m_trgU[i] << " ";
122 }
123 ss << std::endl;
124 ss << "--------------------------------------------------------------------------------" << std::endl;
125
126 if(m_solver->domainId() == 0) std::cout << ss.str();
127 m_log << ss.str();
128}
129
134template <MInt nDim, MInt nDist, class SysEqn>
136 TRACE();
137 m_isActive = (m_spongeLayerThickness > 0.0) && m_solver->isActive();
138 if(!m_isActive) return;
139
140 const MFloat epsilon = m_solver->c_cellLengthAtLevel(m_solver->maxLevel()) / 1000.0;
141 std::array<MFloat, 2 * nDim> domainBoundaries{};
142 {
143 const MFloat halfCellWidth = F1B2 * m_solver->grid().cellLengthAtCell(0);
144 for(MInt i = 0; i < nDim; i++) {
145 domainBoundaries[2 * i + 0] = m_solver->a_coordinate(0, i) - halfCellWidth;
146 domainBoundaries[2 * i + 1] = m_solver->a_coordinate(0, i) + halfCellWidth;
147 }
148 }
149
150 for(MInt cellId = 0; cellId < m_solver->m_cells.size(); cellId++) {
151 if(!m_solver->c_isLeafCell(cellId)) continue;
152 const MFloat halfCellWidth = F1B2 * m_solver->grid().cellLengthAtCell(cellId);
153 for(MInt i = 0; i < nDim; i++) {
154 domainBoundaries[2 * i + 0] =
155 std::min(domainBoundaries[2 * i + 0], m_solver->a_coordinate(cellId, i) - halfCellWidth);
156 domainBoundaries[2 * i + 1] =
157 std::max(domainBoundaries[2 * i + 1], m_solver->a_coordinate(cellId, i) + halfCellWidth);
158 }
159 }
160 // exchange domain boundaries
161 std::array<MFloat, nDim> tmpMin{};
162 std::array<MFloat, nDim> tmpMax{};
163 for(MInt i = 0; i < nDim; i++) {
164 tmpMin[i] = domainBoundaries[2 * i + 0];
165 tmpMax[i] = domainBoundaries[2 * i + 1];
166 }
167 MPI_Allreduce(MPI_IN_PLACE, tmpMin.data(), nDim, maia::type_traits<MFloat>::mpiType(), MPI_MIN, m_solver->mpiComm(),
168 AT_, "MPI_IN_PLACE", "tmpMin");
169 MPI_Allreduce(MPI_IN_PLACE, tmpMax.data(), nDim, maia::type_traits<MFloat>::mpiType(), MPI_MAX, m_solver->mpiComm(),
170 AT_, "MPI_IN_PLACE", "tmpMax");
171 for(MInt i = 0; i < nDim; i++) {
172 domainBoundaries[2 * i + 0] = tmpMin[i];
173 domainBoundaries[2 * i + 1] = tmpMax[i];
174 }
175
176 // fill sponge coordinate
177 std::array<MFloat, 2 * nDim> spongeCoord{};
178 for(MInt i = 0; i < nDim; i++) {
179 spongeCoord[2 * i + 0] = domainBoundaries[2 * i + 0] + m_spongeLayerThickness * m_spongeThicknessFactor[2 * i + 0];
180 spongeCoord[2 * i + 1] = domainBoundaries[2 * i + 1] - m_spongeLayerThickness * m_spongeThicknessFactor[2 * i + 1];
181 }
182 std::array<MFloat, 2 * nDim> F1BspongeCoord{};
183 for(MInt i = 0; i < nDim; i++) {
184 F1BspongeCoord[2 * i + 0] = 1.0 / std::max(epsilon, m_spongeLayerThickness * m_spongeThicknessFactor[2 * i + 0]);
185 F1BspongeCoord[2 * i + 1] = 1.0 / std::max(epsilon, m_spongeLayerThickness * m_spongeThicknessFactor[2 * i + 1]);
186 }
187
188 // search sponge ids
189 for(MInt cellId = 0; cellId < m_solver->m_cells.size(); cellId++) {
190 if(m_solver->a_isHalo(cellId)) continue;
191
192 std::array<MFloat, nDim> dist{};
193 for(MInt i = 0; i < nDim; i++) {
194 const MUint distIdNegSide = 2 * i + 0;
195 const MUint distIdPosSide = 2 * i + 1;
196 const MFloat distNegSide =
197 (spongeCoord[distIdNegSide] - m_solver->a_coordinate(cellId, i)) * F1BspongeCoord[distIdNegSide];
198 const MFloat distPosSide =
199 (m_solver->a_coordinate(cellId, i) - spongeCoord[distIdPosSide]) * F1BspongeCoord[distIdPosSide];
200 dist[i] = std::max(distNegSide, distPosSide);
201 }
202
203 // choose the farthest sponge region
204 const MFloat relDist = *std::max_element(dist.begin(), dist.end());
205
206 if(relDist <= 0.0) continue;
207
208 const MFloat nodeDist = std::pow(relDist, m_spongeBeta);
209 const MFloat spongeFactor = m_spongeSigma * nodeDist;
210
211 constexpr MFloat epsSpongeFactor = 1e-15;
212 if(spongeFactor > epsSpongeFactor) {
213 auto& cell = m_spongeCells.emplace_back();
214 cell.cellId = cellId;
215 cell.spongeFactor = spongeFactor;
216 }
217 }
218 // Update map cellId->spongeCellId
219 updateMapCellId2PmlCellId();
220}
221
222} // namespace maia::lb
This class represents all LB models.
Definition: lbsolverdxqy.h:29
Base class for lb sponge layers.
LbSrcTerm_sponge(LbSolverDxQy< nDim, nDist, SysEqn > *p_solver)
std::array< MFloat, 2 *nDim > m_spongeThicknessFactor
MInt a_spongeCellId(const MInt cellId)
Get index of cellId in m_spongeCells, returns -1 if unavailable.
LbSolverDxQy< nDim, nDist, SysEqn > * m_solver
void readProperties() override
Reading basics properties common for all lb sponge terms.
std::array< MFloat, nDim > m_trgU
void updateMapCellId2PmlCellId()
Update m_mapCellIds2PmlCellId.
void init() override
Initialize properties common by all lb sponge terms.
std::vector< SpongeCell > m_spongeCells
std::unordered_map< MInt, MInt > m_mapCellId2SpongeCellId
Abstract class for lb source terms.
Definition: lbsrcterm.h:22
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
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
MFloat dist(const Point< DIM > &p, const Point< DIM > &q)
Definition: pointbox.h:54