| 188 | **************************************************************************/ |
| 189 | |
| 190 | int ArkodeSolver::init() { |
| 191 | TRACE("Initialising ARKODE solver"); |
| 192 | |
| 193 | Solver::init(); |
| 194 | |
| 195 | output.write("Initialising SUNDIALS' ARKODE solver\n"); |
| 196 | |
| 197 | // Calculate number of variables (in generic_solver) |
| 198 | const int local_N = getLocalN(); |
| 199 | |
| 200 | // Get total problem size |
| 201 | int neq; |
| 202 | if (bout::globals::mpi->MPI_Allreduce(&local_N, &neq, 1, MPI_INT, MPI_SUM, |
| 203 | BoutComm::get())) { |
| 204 | throw BoutException("Allreduce localN -> GlobalN failed!\n"); |
| 205 | } |
| 206 | |
| 207 | output.write("\t3d fields = {:d}, 2d fields = {:d} neq={:d}, local_N={:d}\n", n3Dvars(), |
| 208 | n2Dvars(), neq, local_N); |
| 209 | |
| 210 | // Allocate memory |
| 211 | uvec = callWithSUNContext(N_VNew_Parallel, suncontext, BoutComm::get(), local_N, neq); |
| 212 | if (uvec == nullptr) { |
| 213 | throw BoutException("SUNDIALS memory allocation failed\n"); |
| 214 | } |
| 215 | |
| 216 | // Put the variables into uvec |
| 217 | save_vars(N_VGetArrayPointer(uvec)); |
| 218 | |
| 219 | switch (treatment) { |
| 220 | case Treatment::ImEx: |
| 221 | arkode_mem = callWithSUNContext(ARKStepCreate, suncontext, arkode_rhs_explicit, |
| 222 | arkode_rhs_implicit, simtime, uvec); |
| 223 | break; |
| 224 | case Treatment::Explicit: |
| 225 | arkode_mem = |
| 226 | callWithSUNContext(ARKStepCreate, suncontext, arkode_rhs, nullptr, simtime, uvec); |
| 227 | break; |
| 228 | case Treatment::Implicit: |
| 229 | arkode_mem = |
| 230 | callWithSUNContext(ARKStepCreate, suncontext, nullptr, arkode_rhs, simtime, uvec); |
| 231 | break; |
| 232 | default: |
| 233 | throw BoutException("Invalid treatment: {}\n", toString(treatment)); |
| 234 | } |
| 235 | if (arkode_mem == nullptr) { |
| 236 | throw BoutException("ARKStepCreate failed\n"); |
| 237 | } |
| 238 | |
| 239 | // For callbacks, need pointer to solver object |
| 240 | if (ARKodeSetUserData(arkode_mem, this) != ARK_SUCCESS) { |
| 241 | throw BoutException("ARKodeSetUserData failed\n"); |
| 242 | } |
| 243 | |
| 244 | if (set_linear) { |
| 245 | constexpr bool is_time_dep = false; |
| 246 | if (ARKodeSetLinear(arkode_mem, is_time_dep) != ARK_SUCCESS) { |
| 247 | throw BoutException("ARKodeSetLinear failed\n"); |