| 13 | using namespace amrex; |
| 14 | |
| 15 | void Castro::problem_post_init() |
| 16 | { |
| 17 | BL_ASSERT(level == 0); |
| 18 | |
| 19 | // Add up the mass on the domain and then update the density |
| 20 | // in the sphere so that it has the 'correct' amount of total mass. |
| 21 | |
| 22 | Real actual_mass = 0.0; |
| 23 | |
| 24 | bool local_flag = true; |
| 25 | Real time = state[State_Type].curTime(); |
| 26 | |
| 27 | for (int lev = 0; lev <= parent->finestLevel(); ++lev) { |
| 28 | actual_mass += getLevel(lev).volWgtSum("density", time, local_flag); |
| 29 | } |
| 30 | |
| 31 | ParallelDescriptor::ReduceRealSum(actual_mass); |
| 32 | |
| 33 | // The correct amount of mass is the mass of a sphere |
| 34 | // with the given diameter and density. |
| 35 | |
| 36 | Real target_mass = problem::density * (1.0e0 / 6.0e0) * M_PI * std::pow(problem::diameter, 3); |
| 37 | |
| 38 | Real update_factor = target_mass / actual_mass; |
| 39 | |
| 40 | // Now update the density given this factor. |
| 41 | |
| 42 | amrex::Print() << "\n"; |
| 43 | amrex::Print() << " Updating density by the factor " << update_factor << " to ensure total mass matches target mass.\n"; |
| 44 | amrex::Print() << "\n"; |
| 45 | |
| 46 | problem::density = problem::density * update_factor; |
| 47 | |
| 48 | for (int lev = 0; lev <= parent->finestLevel(); lev++) |
| 49 | { |
| 50 | MultiFab& state = getLevel(lev).get_new_data(State_Type); |
| 51 | |
| 52 | const auto dx = getLevel(lev).geom.CellSizeArray(); |
| 53 | const auto problo = getLevel(lev).geom.ProbLoArray(); |
| 54 | |
| 55 | #ifdef _OPENMP |
| 56 | #pragma omp parallel |
| 57 | #endif |
| 58 | for (MFIter mfi(state, TilingIfNotGPU()); mfi.isValid(); ++mfi) { |
| 59 | |
| 60 | const Box& box = mfi.tilebox(); |
| 61 | |
| 62 | auto u = state[mfi].array(); |
| 63 | |
| 64 | // Update the density field. This ensures that the sum of the |
| 65 | // mass on the domain is what we intend it to be. |
| 66 | |
| 67 | amrex::ParallelFor(box, |
| 68 | [=] AMREX_GPU_HOST_DEVICE (int i, int j, int k) |
| 69 | { |
| 70 | Real xx = problo[0] + dx[0] * (static_cast<Real>(i) + 0.5_rt) - problem::center[0]; |
| 71 | |
| 72 | #if AMREX_SPACEDIM >= 2 |
nothing calls this directly
no test coverage detected