Skip to content

Commit f7b1bbf

Browse files
committed
Skip FTCS solver for zero-diffusion grids
When the diffusion coefficient is 0 but decay is nonzero, apply decay as a simple element-wise multiply instead of running the full FTCS stencil. The Laplacian term vanishes with D=0, so the stencil computation is wasted work.
1 parent 67c8d6f commit f7b1bbf

2 files changed

Lines changed: 42 additions & 9 deletions

File tree

src/core/diffusion/diffusion_grid.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class DiffusionGrid : public ScalarField {
170170
[[deprecated("Use GetValue instead")]] real_t GetConcentration(
171171
const Real3& position) const {
172172
return GetValue(position);
173-
};
173+
}
174174
/// @brief Get the concentration at specified index
175175
/// @param idx Flat index of the grid
176176
/// @return c1_[idx]
@@ -337,9 +337,7 @@ class DiffusionGrid : public ScalarField {
337337
void PrintInfo(std::ostream& out = std::cout);
338338

339339
/// Print the information after initialization
340-
void PrintInfoWithInitialization() {
341-
print_info_with_initialization_ = true;
342-
};
340+
void PrintInfoWithInitialization() { print_info_with_initialization_ = true; }
343341

344342
/// Returns if the grid has been initialized
345343
bool IsInitialized() const { return initialized_; }
@@ -371,6 +369,16 @@ class DiffusionGrid : public ScalarField {
371369
const ParallelResizeVector<Real3>& old_gradients,
372370
size_t old_resolution);
373371

372+
/// Apply decay without diffusion (used when diffusion coefficient is 0).
373+
void ApplyDecayOnly(real_t dt) {
374+
const real_t decay = 1 - mu_ * dt;
375+
#pragma omp parallel for
376+
for (size_t i = 0; i < total_num_boxes_; i++) {
377+
c2_[i] = c1_[i] * decay;
378+
}
379+
c1_.swap(c2_);
380+
}
381+
374382
/// The side length of each box
375383
real_t box_length_ = 0;
376384
/// the volume of each box

src/core/diffusion/euler_grid.cc

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@
1919
namespace bdm {
2020

2121
void EulerGrid::DiffuseWithClosedEdge(real_t dt) {
22+
const real_t d = 1 - dc_[0];
23+
if (d == 0) {
24+
ApplyDecayOnly(dt);
25+
return;
26+
}
27+
2228
const auto nx = resolution_;
2329
const auto ny = resolution_;
2430
const auto nz = resolution_;
2531

2632
const real_t ibl2 = 1 / (box_length_ * box_length_);
27-
const real_t d = 1 - dc_[0];
2833

2934
constexpr size_t YBF = 16;
3035
#pragma omp parallel for collapse(2)
@@ -67,12 +72,17 @@ void EulerGrid::DiffuseWithClosedEdge(real_t dt) {
6772
}
6873

6974
void EulerGrid::DiffuseWithOpenEdge(real_t dt) {
75+
const real_t d = 1 - dc_[0];
76+
if (d == 0) {
77+
ApplyDecayOnly(dt);
78+
return;
79+
}
80+
7081
const auto nx = resolution_;
7182
const auto ny = resolution_;
7283
const auto nz = resolution_;
7384

7485
const real_t ibl2 = 1 / (box_length_ * box_length_);
75-
const real_t d = 1 - dc_[0];
7686
std::array<int, 4> l;
7787

7888
constexpr size_t YBF = 16;
@@ -155,12 +165,17 @@ void EulerGrid::DiffuseWithOpenEdge(real_t dt) {
155165
}
156166

157167
void EulerGrid::DiffuseWithDirichlet(real_t dt) {
168+
const real_t d = 1 - dc_[0];
169+
if (d == 0) {
170+
ApplyDecayOnly(dt);
171+
return;
172+
}
173+
158174
const auto nx = resolution_;
159175
const auto ny = resolution_;
160176
const auto nz = resolution_;
161177

162178
const real_t ibl2 = 1 / (box_length_ * box_length_);
163-
const real_t d = 1 - dc_[0];
164179

165180
const auto sim_time = GetSimulatedTime();
166181

@@ -211,13 +226,18 @@ void EulerGrid::DiffuseWithDirichlet(real_t dt) {
211226
}
212227

213228
void EulerGrid::DiffuseWithNeumann(real_t dt) {
229+
const real_t d = 1 - dc_[0];
230+
if (d == 0) {
231+
ApplyDecayOnly(dt);
232+
return;
233+
}
234+
214235
const size_t nx = resolution_;
215236
const size_t ny = resolution_;
216237
const size_t nz = resolution_;
217238
const size_t num_boxes = nx * ny * nz;
218239

219240
const real_t ibl2 = 1 / (box_length_ * box_length_);
220-
const real_t d = 1 - dc_[0];
221241

222242
const auto sim_time = GetSimulatedTime();
223243

@@ -302,12 +322,17 @@ void EulerGrid::DiffuseWithNeumann(real_t dt) {
302322
}
303323

304324
void EulerGrid::DiffuseWithPeriodic(real_t dt) {
325+
const real_t d = 1 - dc_[0];
326+
if (d == 0) {
327+
ApplyDecayOnly(dt);
328+
return;
329+
}
330+
305331
const size_t nx = resolution_;
306332
const size_t ny = resolution_;
307333
const size_t nz = resolution_;
308334

309335
const real_t dx = box_length_;
310-
const real_t d = 1 - dc_[0];
311336

312337
constexpr size_t YBF = 16;
313338
#pragma omp parallel for collapse(2)

0 commit comments

Comments
 (0)