| 356 | /////////////////////////////// PRIVATE ////////////////////////////////////// |
| 357 | |
| 358 | void |
| 359 | CCPoissonHypreLevelSolver::allocateHypreData() |
| 360 | { |
| 361 | // Get the MPI communicator. |
| 362 | MPI_Comm communicator = IBTK_MPI::getCommunicator(); |
| 363 | |
| 364 | // Setup the hypre grid. |
| 365 | Pointer<CartesianGridGeometry<NDIM>> grid_geometry = d_hierarchy->getGridGeometry(); |
| 366 | const IntVector<NDIM>& ratio = d_level->getRatio(); |
| 367 | const IntVector<NDIM>& periodic_shift = grid_geometry->getPeriodicShift(ratio); |
| 368 | |
| 369 | HYPRE_StructGridCreate(communicator, NDIM, &d_grid); |
| 370 | for (PatchLevel<NDIM>::Iterator p(d_level); p; p++) |
| 371 | { |
| 372 | const Box<NDIM>& patch_box = d_level->getPatch(p())->getBox(); |
| 373 | std::array<HYPRE_Int, NDIM> lower = hypre_array(patch_box.lower()); |
| 374 | std::array<HYPRE_Int, NDIM> upper = hypre_array(patch_box.upper()); |
| 375 | HYPRE_StructGridSetExtents(d_grid, lower.data(), upper.data()); |
| 376 | } |
| 377 | |
| 378 | std::array<HYPRE_Int, 3> hypre_periodic_shift; |
| 379 | for (unsigned int d = 0; d < NDIM; ++d) |
| 380 | { |
| 381 | hypre_periodic_shift[d] = periodic_shift(d); |
| 382 | } |
| 383 | for (int d = NDIM; d < 3; ++d) |
| 384 | { |
| 385 | hypre_periodic_shift[d] = 0; |
| 386 | } |
| 387 | HYPRE_StructGridSetPeriodic(d_grid, hypre_periodic_shift.data()); |
| 388 | HYPRE_StructGridAssemble(d_grid); |
| 389 | |
| 390 | // Allocate stencil data and set stencil offsets. |
| 391 | if (d_grid_aligned_anisotropy) |
| 392 | { |
| 393 | static const int stencil_sz = 2 * NDIM + 1; |
| 394 | d_stencil_offsets.resize(stencil_sz); |
| 395 | std::fill(d_stencil_offsets.begin(), d_stencil_offsets.end(), hier::Index<NDIM>(0)); |
| 396 | for (unsigned int axis = 0, stencil_index = 1; axis < NDIM; ++axis) |
| 397 | { |
| 398 | for (int side = 0; side <= 1; ++side, ++stencil_index) |
| 399 | { |
| 400 | d_stencil_offsets[stencil_index](axis) = (side == 0 ? -1 : +1); |
| 401 | } |
| 402 | } |
| 403 | HYPRE_StructStencilCreate(NDIM, stencil_sz, &d_stencil); |
| 404 | for (int s = 0; s < stencil_sz; ++s) |
| 405 | { |
| 406 | auto stencil_offset = hypre_array(d_stencil_offsets[s]); |
| 407 | HYPRE_StructStencilSetElement(d_stencil, s, stencil_offset.data()); |
| 408 | std::copy(stencil_offset.begin(), stencil_offset.end(), static_cast<int*>(d_stencil_offsets[s])); |
| 409 | } |
| 410 | } |
| 411 | else |
| 412 | { |
| 413 | static const int stencil_sz = (NDIM == 2) ? 9 : 19; |
| 414 | d_stencil_offsets.resize(stencil_sz); |
| 415 | std::fill(d_stencil_offsets.begin(), d_stencil_offsets.end(), hier::Index<NDIM>(0)); |