7#include <unordered_map>
21template <MInt nDim, MInt nDist,
class SysEqn>
51 MInt spongeCellId = -1;
54 spongeCellId = search->second;
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);
85template <MInt nDim, MInt nDist,
class SysEqn>
88 const MInt solverId = m_solver->m_solverId;
91 ss <<
"--------------------------------------------------------------------------------" << std::endl;
92 ss <<
" Sponge properties" << std::endl;
93 ss <<
"--------------------------------------------------------------------------------" << std::endl;
94 ss <<
" [Sponge region]" << std::endl;
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] <<
" ";
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;
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;
119 ss <<
" spongeTrgU: ";
120 for(
MInt i = 0; i < nDim; i++) {
121 ss << m_trgU[i] <<
" ";
124 ss <<
"--------------------------------------------------------------------------------" << std::endl;
126 if(m_solver->domainId() == 0) std::cout << ss.str();
134template <MInt nDim, MInt nDist,
class SysEqn>
137 m_isActive = (m_spongeLayerThickness > 0.0) && m_solver->isActive();
138 if(!m_isActive)
return;
140 const MFloat epsilon = m_solver->c_cellLengthAtLevel(m_solver->maxLevel()) / 1000.0;
141 std::array<MFloat, 2 * nDim> domainBoundaries{};
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;
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);
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];
168 AT_,
"MPI_IN_PLACE",
"tmpMin");
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];
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];
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]);
189 for(
MInt cellId = 0; cellId < m_solver->m_cells.size(); cellId++) {
190 if(m_solver->a_isHalo(cellId))
continue;
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);
204 const MFloat relDist = *std::max_element(
dist.begin(),
dist.end());
206 if(relDist <= 0.0)
continue;
208 const MFloat nodeDist = std::pow(relDist, m_spongeBeta);
209 const MFloat spongeFactor = m_spongeSigma * nodeDist;
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;
219 updateMapCellId2PmlCellId();
This class represents all LB models.
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.
MFloat m_spongeLayerThickness
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.
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)