|
49 | 49 | #include <bout/sys/gettext.hxx> |
50 | 50 | #include <bout/sys/range.hxx> |
51 | 51 | #include <bout/sys/timer.hxx> |
| 52 | +#include <bout/sys/variant.hxx> |
52 | 53 | #include <bout/utils.hxx> |
53 | 54 |
|
54 | 55 | #include <fmt/format.h> |
@@ -1400,6 +1401,16 @@ comm_handle BoutMesh::sendY(FieldGroup& g, comm_handle handle) { |
1400 | 1401 | return static_cast<void*>(ch); |
1401 | 1402 | } |
1402 | 1403 |
|
| 1404 | +namespace { |
| 1405 | +// FieldGroup stores a vector of variants now, rather than a pointer to the |
| 1406 | +// FieldData base class, so we need this visitor as a shim |
| 1407 | +struct DoneCommsVisitor { |
| 1408 | + void operator()(Field3D* var) const { var->doneComms(); } |
| 1409 | + void operator()(Field2D* var) const { var->doneComms(); } |
| 1410 | + void operator()(FieldPerp* var) const { var->doneComms(); } |
| 1411 | +}; |
| 1412 | +} // namespace |
| 1413 | + |
1403 | 1414 | int BoutMesh::wait(comm_handle handle) { |
1404 | 1415 |
|
1405 | 1416 | if (handle == nullptr) { |
@@ -1545,7 +1556,7 @@ int BoutMesh::wait(comm_handle handle) { |
1545 | 1556 | #if CHECK > 0 |
1546 | 1557 | // Keeping track of whether communications have been done |
1547 | 1558 | for (const auto& var : ch->var_list) { |
1548 | | - var->doneComms(); |
| 1559 | + bout::utils::visit(DoneCommsVisitor{}, var); |
1549 | 1560 | } |
1550 | 1561 | #endif |
1551 | 1562 |
|
@@ -2218,9 +2229,9 @@ void BoutMesh::topology() { |
2218 | 2229 | } |
2219 | 2230 |
|
2220 | 2231 | for (int i = 0; i < limiter_count; ++i) { |
2221 | | - int const yind = limiter_yinds[i]; |
2222 | | - int const xstart = limiter_xstarts[i]; |
2223 | | - int const xend = limiter_xends[i]; |
| 2232 | + const int yind = limiter_yinds[i]; |
| 2233 | + const int xstart = limiter_xstarts[i]; |
| 2234 | + const int xend = limiter_xends[i]; |
2224 | 2235 | output_info.write("Adding a limiter between y={} and {}. X indices {} to {}\n", |
2225 | 2236 | yind, yind + 1, xstart, xend); |
2226 | 2237 | add_target(yind, xstart, xend); |
@@ -2397,72 +2408,121 @@ void BoutMesh::overlapHandleMemory(BoutMesh* yup, BoutMesh* ydown, BoutMesh* xin |
2397 | 2408 | * Communication utilities |
2398 | 2409 | ****************************************************************/ |
2399 | 2410 |
|
2400 | | -int BoutMesh::pack_data(const std::vector<FieldData*>& var_list, int xge, int xlt, |
2401 | | - int yge, int ylt, BoutReal* buffer) { |
2402 | | - |
2403 | | - int len = 0; |
| 2411 | +namespace { |
| 2412 | +// Visitor for packing data from a `FieldGroup::Item` into an existing buffer |
| 2413 | +struct PackDataVisitor { |
| 2414 | + int xge; |
| 2415 | + int xlt; |
| 2416 | + int yge; |
| 2417 | + int ylt; |
| 2418 | + int zge; |
| 2419 | + int zlt; |
| 2420 | + BoutReal* buffer; |
| 2421 | + int len; |
2404 | 2422 |
|
2405 | | - /// Loop over variables |
2406 | | - for (const auto& var : var_list) { |
2407 | | - if (var->is3D()) { |
2408 | | - // 3D variable |
2409 | | - auto* var3d_ref_ptr = dynamic_cast<Field3D*>(var); |
2410 | | - ASSERT0(var3d_ref_ptr != nullptr); |
2411 | | - auto& var3d_ref = *var3d_ref_ptr; |
2412 | | - ASSERT2(var3d_ref.isAllocated()); |
2413 | | - for (int jx = xge; jx != xlt; jx++) { |
2414 | | - for (int jy = yge; jy < ylt; jy++) { |
2415 | | - for (int jz = 0; jz < LocalNz; jz++, len++) { |
2416 | | - buffer[len] = var3d_ref(jx, jy, jz); |
2417 | | - } |
| 2423 | + int operator()(const Field3D* var) { |
| 2424 | + const auto& var3d_ref = *var; |
| 2425 | + ASSERT2(var3d_ref.isAllocated()); |
| 2426 | + for (int jx = xge; jx < xlt; jx++) { |
| 2427 | + for (int jy = yge; jy < ylt; jy++) { |
| 2428 | + for (int jz = zge; jz < zlt; jz++, len++) { |
| 2429 | + buffer[len] = var3d_ref(jx, jy, jz); |
2418 | 2430 | } |
2419 | 2431 | } |
2420 | | - } else { |
2421 | | - // 2D variable |
2422 | | - auto* var2d_ref_ptr = dynamic_cast<Field2D*>(var); |
2423 | | - ASSERT0(var2d_ref_ptr != nullptr); |
2424 | | - auto& var2d_ref = *var2d_ref_ptr; |
2425 | | - ASSERT2(var2d_ref.isAllocated()); |
2426 | | - for (int jx = xge; jx != xlt; jx++) { |
2427 | | - for (int jy = yge; jy < ylt; jy++, len++) { |
2428 | | - buffer[len] = var2d_ref(jx, jy); |
| 2432 | + } |
| 2433 | + return len; |
| 2434 | + } |
| 2435 | + |
| 2436 | + int operator()(const Field2D* var) { |
| 2437 | + const auto& var2d_ref = *var; |
| 2438 | + ASSERT2(var2d_ref.isAllocated()); |
| 2439 | + for (int jx = xge; jx < xlt; jx++) { |
| 2440 | + for (int jy = yge; jy < ylt; jy++, len++) { |
| 2441 | + buffer[len] = var2d_ref(jx, jy); |
| 2442 | + } |
| 2443 | + } |
| 2444 | + return len; |
| 2445 | + } |
| 2446 | + |
| 2447 | + int operator()(const FieldPerp* var) { |
| 2448 | + const auto& varperp_ref = *var; |
| 2449 | + ASSERT2(varperp_ref.isAllocated()); |
| 2450 | + for (int jx = xge; jx < xlt; jx++) { |
| 2451 | + for (int jz = zge; jz < zlt; jz++, len++) { |
| 2452 | + buffer[len] = varperp_ref(jx, jz); |
| 2453 | + } |
| 2454 | + } |
| 2455 | + return len; |
| 2456 | + } |
| 2457 | +}; |
| 2458 | + |
| 2459 | +// Visitor for unpacking a buffer into a `FieldGroup::Item` |
| 2460 | +struct UnpackDataVisitor { |
| 2461 | + int xge; |
| 2462 | + int xlt; |
| 2463 | + int yge; |
| 2464 | + int ylt; |
| 2465 | + int zge; |
| 2466 | + int zlt; |
| 2467 | + BoutReal* buffer; |
| 2468 | + int len; |
| 2469 | + |
| 2470 | + void operator()(Field3D* var) { |
| 2471 | + auto& var3d_ref = *var; |
| 2472 | + ASSERT2(var3d_ref.isAllocated()); |
| 2473 | + for (int jx = xge; jx < xlt; jx++) { |
| 2474 | + for (int jy = yge; jy < ylt; jy++) { |
| 2475 | + for (int jz = zge; jz < zlt; jz++, len++) { |
| 2476 | + var3d_ref(jx, jy, jz) = buffer[len]; |
2429 | 2477 | } |
2430 | 2478 | } |
2431 | 2479 | } |
2432 | 2480 | } |
2433 | 2481 |
|
2434 | | - return (len); |
| 2482 | + void operator()(Field2D* var) { |
| 2483 | + auto& var2d_ref = *var; |
| 2484 | + ASSERT2(var2d_ref.isAllocated()); |
| 2485 | + for (int jx = xge; jx < xlt; jx++) { |
| 2486 | + for (int jy = yge; jy < ylt; jy++, len++) { |
| 2487 | + var2d_ref(jx, jy) = buffer[len]; |
| 2488 | + } |
| 2489 | + } |
| 2490 | + } |
| 2491 | + |
| 2492 | + void operator()(FieldPerp* var) { |
| 2493 | + auto& varperp_ref = *var; |
| 2494 | + ASSERT2(varperp_ref.isAllocated()); |
| 2495 | + for (int jx = xge; jx < xlt; jx++) { |
| 2496 | + for (int jz = zge; jz < zlt; jz++, len++) { |
| 2497 | + varperp_ref(jx, jz) = buffer[len]; |
| 2498 | + } |
| 2499 | + } |
| 2500 | + } |
| 2501 | +}; |
| 2502 | +} // namespace |
| 2503 | + |
| 2504 | +int BoutMesh::pack_data(const std::vector<FieldGroup::Item>& var_list, int xge, int xlt, |
| 2505 | + int yge, int ylt, BoutReal* buffer) { |
| 2506 | + |
| 2507 | + auto visitor = PackDataVisitor{xge, xlt, yge, ylt, 0, LocalNz, buffer, 0}; |
| 2508 | + |
| 2509 | + for (const auto& var : var_list) { |
| 2510 | + bout::utils::visit(visitor, var); |
| 2511 | + } |
| 2512 | + |
| 2513 | + return visitor.len; |
2435 | 2514 | } |
2436 | 2515 |
|
2437 | | -int BoutMesh::unpack_data(const std::vector<FieldData*>& var_list, int xge, int xlt, |
| 2516 | +int BoutMesh::unpack_data(const std::vector<FieldGroup::Item>& var_list, int xge, int xlt, |
2438 | 2517 | int yge, int ylt, BoutReal* buffer) { |
2439 | 2518 |
|
2440 | | - int len = 0; |
| 2519 | + auto visitor = UnpackDataVisitor{xge, xlt, yge, ylt, 0, LocalNz, buffer, 0}; |
2441 | 2520 |
|
2442 | | - /// Loop over variables |
2443 | 2521 | for (const auto& var : var_list) { |
2444 | | - if (var->is3D()) { |
2445 | | - // 3D variable |
2446 | | - auto& var3d_ref = *dynamic_cast<Field3D*>(var); |
2447 | | - for (int jx = xge; jx != xlt; jx++) { |
2448 | | - for (int jy = yge; jy < ylt; jy++) { |
2449 | | - for (int jz = 0; jz < LocalNz; jz++, len++) { |
2450 | | - var3d_ref(jx, jy, jz) = buffer[len]; |
2451 | | - } |
2452 | | - } |
2453 | | - } |
2454 | | - } else { |
2455 | | - // 2D variable |
2456 | | - auto& var2d_ref = *dynamic_cast<Field2D*>(var); |
2457 | | - for (int jx = xge; jx != xlt; jx++) { |
2458 | | - for (int jy = yge; jy < ylt; jy++, len++) { |
2459 | | - var2d_ref(jx, jy) = buffer[len]; |
2460 | | - } |
2461 | | - } |
2462 | | - } |
| 2522 | + bout::utils::visit(visitor, var); |
2463 | 2523 | } |
2464 | 2524 |
|
2465 | | - return (len); |
| 2525 | + return visitor.len; |
2466 | 2526 | } |
2467 | 2527 |
|
2468 | 2528 | /**************************************************************** |
|
0 commit comments