|
22 | 22 | #include <AMReX.H> |
23 | 23 | #include <AMReX_ParallelDescriptor.H> |
24 | 24 | #include <AMReX_ParmParse.H> |
| 25 | +#include <AMReX_TimeIntegrator.H> |
25 | 26 | #ifdef ALAMO_FFT |
26 | 27 | #include <AMReX_FFT.H> |
27 | 28 | #endif |
@@ -131,28 +132,47 @@ protected: |
131 | 132 | // the new one. |
132 | 133 | std::swap(*temp_mf[lev], *temp_old_mf[lev]); |
133 | 134 |
|
134 | | - // Get the cell size corresponding to this level |
135 | | - const Set::Scalar* DX = geom[lev].CellSize(); |
136 | | - |
137 | | - // Iterate over all of the patches on this level |
138 | | - for (amrex::MFIter mfi(*temp_mf[lev], amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) |
| 135 | + // Create the time integrator object |
| 136 | + amrex::TimeIntegrator timeintegrator(*temp_old_mf[lev], time); |
| 137 | + |
| 138 | + // Calculate the "RHS" of the function. |
| 139 | + // If using forward Euler, the RHS would be |
| 140 | + // T_new = T_old + dt * RHS |
| 141 | + timeintegrator.set_rhs([&](amrex::MultiFab & rhs_mf, amrex::MultiFab & temp_mf, const Set::Scalar /*time*/) |
139 | 142 | { |
140 | | - // Get the box (index dimensions) for this patch |
141 | | - const amrex::Box &bx = mfi.tilebox(); |
142 | | - |
143 | | - // Get an array-accessible handle to the data on this patch. |
144 | | - Set::Patch<const Set::Scalar> temp_old = temp_old_mf.Patch(lev,mfi); |
145 | | - Set::Patch<Set::Scalar> temp = temp_mf.Patch(lev,mfi); |
| 143 | + // Get the cell size corresponding to this level |
| 144 | + const Set::Scalar* DX = geom[lev].CellSize(); |
146 | 145 |
|
147 | | - // Iterate over the grid on this patch |
148 | | - amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) |
| 146 | + // Iterate over all of the patches on this level |
| 147 | + for (amrex::MFIter mfi(temp_mf, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi) |
149 | 148 | { |
150 | | - // Do the physics! |
151 | | - // Note that Numeric::Laplacian is an inlined function so there is no overhead. |
152 | | - // You can calculate the derivatives yourself if you want. |
153 | | - temp(i, j, k) = temp_old(i, j, k) + dt * alpha * Numeric::Laplacian(temp_old, i, j, k, 0, DX); |
154 | | - }); |
155 | | - } |
| 149 | + // Get the box (index dimensions) for this patch |
| 150 | + const amrex::Box &bx = mfi.tilebox(); |
| 151 | + |
| 152 | + // Get an array-accessible handle to the data on this patch. |
| 153 | + Set::Patch<const Set::Scalar> temp = temp_mf.array(mfi); |
| 154 | + Set::Patch<Set::Scalar> rhs = rhs_mf.array(mfi); |
| 155 | + |
| 156 | + // Iterate over the grid on this patch |
| 157 | + amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) |
| 158 | + { |
| 159 | + // Do the physics! |
| 160 | + // Note that Numeric::Laplacian is an inlined function so there is no overhead. |
| 161 | + // You can calculate the derivatives yourself if you want. |
| 162 | + rhs(i, j, k) = alpha * Numeric::Laplacian(temp, i, j, k, 0, DX); |
| 163 | + }); |
| 164 | + } |
| 165 | + }); |
| 166 | + |
| 167 | + // We must update the boundaries here and apply boundary conditions |
| 168 | + timeintegrator.set_post_stage_action([&](amrex::MultiFab & stage_mf, Set::Scalar time) |
| 169 | + { |
| 170 | + bc->FillBoundary(stage_mf,0,1,time,0); |
| 171 | + stage_mf.FillBoundary(true); |
| 172 | + }); |
| 173 | + |
| 174 | + // Do the update |
| 175 | + timeintegrator.advance(*temp_old_mf[lev], *temp_mf[lev], time, dt); |
156 | 176 | } |
157 | 177 |
|
158 | 178 |
|
|
0 commit comments