103 template <
typename F>
147 void backward (
MF const& inmf,
MF& outmf,
IntVect const& ngout,
157 void backward (
cMF const& inmf,
MF& outmf,
IntVect const& ngout,
169 Plan<T> m_fft_fwd_y{};
170 Plan<T> m_fft_bwd_y{};
171 Plan<T> m_fft_fwd_z{};
172 Plan<T> m_fft_bwd_z{};
174 std::unique_ptr<MultiBlockCommMetaData> m_cmd_cx2cy;
175 std::unique_ptr<MultiBlockCommMetaData> m_cmd_rx2ry;
176 std::unique_ptr<MultiBlockCommMetaData> m_cmd_cy2cz;
177 std::unique_ptr<MultiBlockCommMetaData> m_cmd_ry2rz;
179 std::unique_ptr<MultiBlockCommMetaData> m_cmd_cy2cx;
180 std::unique_ptr<MultiBlockCommMetaData> m_cmd_ry2rx;
181 std::unique_ptr<MultiBlockCommMetaData> m_cmd_cz2cy;
182 std::unique_ptr<MultiBlockCommMetaData> m_cmd_rz2ry;
196 std::unique_ptr<char,DataDeleter> m_data_1;
197 std::unique_ptr<char,DataDeleter> m_data_2;
206 std::unique_ptr<R2X<T>> m_r2x_sub;
207 detail::SubHelper m_sub_helper;
214 Array<std::pair<Boundary,Boundary>,AMREX_SPACEDIM>
const& bc,
218 m_sub_helper(domain),
223 static_assert(std::is_same_v<float,T> || std::is_same_v<double,T>);
228 "FFT::R2X currently requires domain.smallEnd() == 0");
229#if (AMREX_SPACEDIM == 2)
234 int(domain.
length(1) > 1) +
235 int(domain.
length(2) > 1)) >= 2);
239 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
247 Box subbox = m_sub_helper.make_box(m_dom_0);
248 if (subbox.
size() != m_dom_0.
size()) {
249 m_r2x_sub = std::make_unique<R2X<T>>
250 (subbox, m_sub_helper.make_array(bc), info);
265 m_rx.define(bax, dmx, 1, 0,
MFInfo().SetAlloc(
false));
274 for (
auto & b : bl) {
275 b.setBig(0, m_dom_cx.
bigEnd(0));
281#if (AMREX_SPACEDIM >= 2)
283 if (! m_cx.
empty()) {
290 if (ba.size() == m_cx.
size()) {
293 dm = detail::make_iota_distromap(ba.size());
307 if (ba.size() == m_rx.size()) {
308 dm = m_rx.DistributionMap();
310 dm = detail::make_iota_distromap(ba.size());
312 m_ry.define(ba, dm, 1, 0,
MFInfo().SetAlloc(
false));
322 for (
auto & b : bl) {
323 b.setBig(0, m_dom_cy.
bigEnd(0));
332#if (AMREX_SPACEDIM == 3)
334 if (! m_cy.
empty()) {
341 if (ba.size() == m_cy.
size()) {
344 dm = detail::make_iota_distromap(ba.size());
358 if (ba.size() == m_ry.size()) {
359 dm = m_ry.DistributionMap();
361 dm = detail::make_iota_distromap(ba.size());
363 m_rz.define(ba, dm, 1, 0,
MFInfo().SetAlloc(
false));
373 for (
auto & b : bl) {
374 b.setBig(0, m_dom_cz.
bigEnd(0));
405 if (! m_cx.
empty()) {
406 m_data_1 = detail::make_mfs_share(m_rx, m_cy);
407 m_data_2 = detail::make_mfs_share(m_cx, m_cz);
408 }
else if (! m_cy.
empty()) {
409 m_data_1 = detail::make_mfs_share(m_rx, m_cy);
410 m_data_2 = detail::make_mfs_share(m_ry, m_cz);
411 }
else if (! m_cz.
empty()) {
412 m_data_1 = detail::make_mfs_share(m_rx, m_rz);
413 m_data_2 = detail::make_mfs_share(m_ry, m_cz);
415 m_data_1 = detail::make_mfs_share(m_rx, m_rz);
416 m_data_2 = detail::make_mfs_share(m_ry, m_cz);
423#if (AMREX_SPACEDIM >= 2)
424 if (!m_cy.
empty() || !m_ry.empty()) {
425 if (! m_cx.
empty()) {
427 m_cmd_cx2cy = std::make_unique<MultiBlockCommMetaData>
428 (m_cy, m_dom_cy, m_cx,
IntVect(0), m_dtos_x2y);
429 m_cmd_cy2cx = std::make_unique<MultiBlockCommMetaData>
430 (m_cx, m_dom_cx, m_cy,
IntVect(0), m_dtos_y2x);
433 m_cmd_rx2ry = std::make_unique<MultiBlockCommMetaData>
434 (m_ry, m_dom_ry, m_rx,
IntVect(0), m_dtos_x2y);
435 m_cmd_ry2rx = std::make_unique<MultiBlockCommMetaData>
436 (m_rx, m_dom_rx, m_ry,
IntVect(0), m_dtos_y2x);
441#if (AMREX_SPACEDIM == 3)
442 if (!m_cz.
empty() || !m_rz.empty()) {
443 if (! m_cy.
empty()) {
445 m_cmd_cy2cz = std::make_unique<MultiBlockCommMetaData>
446 (m_cz, m_dom_cz, m_cy,
IntVect(0), m_dtos_y2z);
447 m_cmd_cz2cy = std::make_unique<MultiBlockCommMetaData>
448 (m_cy, m_dom_cy, m_cz,
IntVect(0), m_dtos_z2y);
451 m_cmd_ry2rz = std::make_unique<MultiBlockCommMetaData>
452 (m_rz, m_dom_rz, m_ry,
IntVect(0), m_dtos_y2z);
453 m_cmd_rz2ry = std::make_unique<MultiBlockCommMetaData>
454 (m_ry, m_dom_ry, m_rz,
IntVect(0), m_dtos_z2y);
465 if (myproc < m_rx.size())
467 Box const& box = m_rx.box(myproc);
468 auto* pf = m_rx[myproc].dataPtr();
470 auto* pb = (VendorComplex*) m_cx[myproc].dataPtr();
471 m_fft_fwd_x.template init_r2c<Direction::forward>(box, pf, pb);
472#if defined(AMREX_USE_SYCL)
473 m_fft_bwd_x = m_fft_fwd_x;
475 m_fft_bwd_x.template init_r2c<Direction::backward>(box, pf, pb);
478 m_fft_fwd_x.template init_r2r<Direction::forward>(box, pf, bc[0]);
479#if defined(AMREX_USE_GPU)
482 m_fft_bwd_x = m_fft_fwd_x;
486 m_fft_bwd_x.template init_r2r<Direction::backward>(box, pf, bc[0]);
491#if (AMREX_SPACEDIM >= 2)
493 if (myproc < m_cy.
size()) {
494 Box const& box = m_cy.
box(myproc);
495 auto* p = (VendorComplex *)m_cy[myproc].dataPtr();
496 m_fft_fwd_y.template init_c2c<Direction::forward>(box, p);
497#if defined(AMREX_USE_SYCL)
498 m_fft_bwd_y = m_fft_fwd_y;
500 m_fft_bwd_y.template init_c2c<Direction::backward>(box, p);
504 if (myproc < m_ry.size()) {
505 Box const& box = m_ry.box(myproc);
506 auto* pr = m_ry[myproc].dataPtr();
507 auto* pc = (VendorComplex*)m_cy[myproc].dataPtr();
508 m_fft_fwd_y.template init_r2c<Direction::forward>(box, pr, pc);
509#if defined(AMREX_USE_SYCL)
510 m_fft_bwd_y = m_fft_fwd_y;
512 m_fft_bwd_y.template init_r2c<Direction::backward>(box, pr, pc);
515 }
else if (!m_cy.
empty()) {
516 if (myproc < m_cy.
size()) {
517 Box const& box = m_cy.
box(myproc);
518 auto* p = (VendorComplex*) m_cy[myproc].dataPtr();
519 m_fft_fwd_y.template init_r2r<Direction::forward>(box, p, bc[1]);
520#if defined(AMREX_USE_GPU)
523 m_fft_bwd_y = m_fft_fwd_y;
527 m_fft_bwd_y.template init_r2r<Direction::backward>(box, p, bc[1]);
531 if (myproc < m_ry.size()) {
532 Box const& box = m_ry.box(myproc);
533 auto* p = m_ry[myproc].dataPtr();
534 m_fft_fwd_y.template init_r2r<Direction::forward>(box, p, bc[1]);
535#if defined(AMREX_USE_GPU)
538 m_fft_bwd_y = m_fft_fwd_y;
542 m_fft_bwd_y.template init_r2r<Direction::backward>(box, p, bc[1]);
548#if (AMREX_SPACEDIM == 3)
550 if (myproc < m_cz.
size()) {
551 Box const& box = m_cz.
box(myproc);
552 auto* p = (VendorComplex*)m_cz[myproc].dataPtr();
553 m_fft_fwd_z.template init_c2c<Direction::forward>(box, p);
554#if defined(AMREX_USE_SYCL)
555 m_fft_bwd_z = m_fft_fwd_z;
557 m_fft_bwd_z.template init_c2c<Direction::backward>(box, p);
561 if (myproc < m_rz.size()) {
562 Box const& box = m_rz.box(myproc);
563 auto* pr = m_rz[myproc].dataPtr();
564 auto* pc = (VendorComplex*)m_cz[myproc].dataPtr();
565 m_fft_fwd_z.template init_r2c<Direction::forward>(box, pr, pc);
566#if defined(AMREX_USE_SYCL)
567 m_fft_bwd_z = m_fft_fwd_z;
569 m_fft_bwd_z.template init_r2c<Direction::backward>(box, pr, pc);
572 }
else if (!m_cz.
empty()) {
573 if (myproc < m_cz.
size()) {
574 Box const& box = m_cz.
box(myproc);
575 auto* p = (VendorComplex*) m_cz[myproc].dataPtr();
576 m_fft_fwd_z.template init_r2r<Direction::forward>(box, p, bc[2]);
577#if defined(AMREX_USE_GPU)
580 m_fft_bwd_z = m_fft_fwd_z;
584 m_fft_bwd_z.template init_r2r<Direction::backward>(box, p, bc[2]);
588 if (myproc < m_rz.size()) {
589 Box const& box = m_rz.box(myproc);
590 auto* p = m_rz[myproc].dataPtr();
591 m_fft_fwd_z.template init_r2r<Direction::forward>(box, p, bc[2]);
592#if defined(AMREX_USE_GPU)
595 m_fft_bwd_z = m_fft_fwd_z;
599 m_fft_bwd_z.template init_r2r<Direction::backward>(box, p, bc[2]);
609 if (m_fft_bwd_x.plan != m_fft_fwd_x.plan) {
610 m_fft_bwd_x.destroy();
612 if (m_fft_bwd_y.plan != m_fft_fwd_y.plan) {
613 m_fft_bwd_y.destroy();
615 if (m_fft_bwd_z.plan != m_fft_fwd_z.plan) {
616 m_fft_bwd_z.destroy();
618 m_fft_fwd_x.destroy();
619 m_fft_fwd_y.destroy();
620 m_fft_fwd_z.destroy();
627 if (m_r2x_sub) {
return m_r2x_sub->scalingFactor(); }
631 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
632 if ((idim == 1 && m_info.oned_mode) ||
633 (idim == 2 && m_info.twod_mode) ||
634 (m_dom_0.length(idim) == 1)) {
continue; }
635 r *= m_dom_0.length(idim);
647 "FFT::R2X::forwardThenBackward(post_forward) does not support twod_mode yet");
648 forwardThenBackward_doit_0(inmf, outmf, post_forward);
654 F const& post_forward,
661 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
662 MF inmf_sub, inmf_tmp;
664 inmf_sub = m_sub_helper.make_alias_mf(inmf);
666 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
667 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
668 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
671 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
672 MF outmf_sub, outmf_tmp;
674 outmf_sub = m_sub_helper.make_alias_mf(outmf);
676 IntVect const& ngtmp = m_sub_helper.make_safe_ghost(outmf.nGrowVect());
677 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, ngtmp);
678 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
681 IntVect const& subngout = m_sub_helper.make_iv(ngout);
682 Periodicity const& subperiod = m_sub_helper.make_periodicity(period);
684 m_r2x_sub->forwardThenBackward_doit_1
685 (inmf_sub, outmf_sub,
689 post_forward(idx[order[0]], idx[order[1]], idx[order[2]], sp);
691 subngout, subperiod);
694 outmf.LocalCopy(outmf_tmp, 0, 0, 1, outmf_tmp.nGrowVect());
699 this->forwardThenBackward_doit_1(inmf, outmf, post_forward, ngout, period);
706 F const& post_forward,
713 amrex::Abort(
"R2X::forwardThenBackward_doit_1: How did this happen?");
724#if (AMREX_SPACEDIM >= 2)
725 if (!m_ry.empty() || !m_cy.empty()) { actual_dim = 2; }
727#if (AMREX_SPACEDIM == 3)
728 if (!m_rz.empty() || !m_cz.empty()) { actual_dim = 3; }
731 if (actual_dim == 1) {
733 post_forward_doit<0>(detail::get_fab(m_rx), post_forward);
735 post_forward_doit<0>(detail::get_fab(m_cx), post_forward);
738#if (AMREX_SPACEDIM >= 2)
739 else if (actual_dim == 2) {
741 post_forward_doit<1>(detail::get_fab(m_ry), post_forward);
743 post_forward_doit<1>(detail::get_fab(m_cy), post_forward);
747#if (AMREX_SPACEDIM == 3)
748 else if (actual_dim == 3) {
750 post_forward_doit<2>(detail::get_fab(m_rz), post_forward);
752 post_forward_doit<2>(detail::get_fab(m_cz), post_forward);
759 outmf.ParallelCopy(m_rx, 0, 0, 1,
IntVect(0),
770 if (m_sub_helper.ghost_safe(inmf.nGrowVect())) {
771 m_r2x_sub->forward(m_sub_helper.make_alias_mf(inmf));
773 MF tmp(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
774 tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
775 m_r2x_sub->forward(m_sub_helper.make_alias_mf(tmp));
780 m_rx.ParallelCopy(inmf, 0, 0, 1);
782 m_fft_fwd_x.template compute_r2c<Direction::forward>();
784 m_fft_fwd_x.template compute_r2r<Direction::forward>();
787#if (AMREX_SPACEDIM >= 2)
789 ParallelCopy(m_cy, m_cx, *m_cmd_cx2cy, 0, 0, 1, m_dtos_x2y);
790 }
else if ( m_cmd_rx2ry) {
791 ParallelCopy(m_ry, m_rx, *m_cmd_rx2ry, 0, 0, 1, m_dtos_x2y);
795 m_fft_fwd_y.template compute_r2r<Direction::forward>();
799 m_fft_fwd_y.template compute_c2c<Direction::forward>();
803 m_fft_fwd_y.template compute_r2c<Direction::forward>();
807#if (AMREX_SPACEDIM == 3)
809 ParallelCopy(m_cz, m_cy, *m_cmd_cy2cz, 0, 0, 1, m_dtos_y2z);
810 }
else if ( m_cmd_ry2rz) {
811 ParallelCopy(m_rz, m_ry, *m_cmd_ry2rz, 0, 0, 1, m_dtos_y2z);
815 m_fft_fwd_z.template compute_r2r<Direction::forward>();
820 m_fft_fwd_z.template compute_c2c<Direction::forward>();
824 m_fft_fwd_z.template compute_r2c<Direction::forward>();
830void R2X<T>::forward (MF
const& inmf, MF& outmf)
834 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
835 MF inmf_sub, inmf_tmp;
837 inmf_sub = m_sub_helper.make_alias_mf(inmf);
839 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
840 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
841 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
844 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
845 MF outmf_sub, outmf_tmp;
847 outmf_sub = m_sub_helper.make_alias_mf(outmf);
849 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, 0);
850 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
853 m_r2x_sub->forward(inmf_sub, outmf_sub);
856 outmf.LocalCopy(outmf_tmp, 0, 0, 1,
IntVect(0));
863#if (AMREX_SPACEDIM == 3)
864 if (m_info.twod_mode) {
865 if (m_cy.empty() && !m_ry.empty()) {
867 }
else if (m_ry.empty() && m_cy.empty() && m_cx.empty()) {
868 outmf.ParallelCopy(m_rx, 0, 0, 1);
870 amrex::Abort(
"R2X::forward(MF,MF): How did this happen?");
882void R2X<T>::forward (MF
const& inmf, cMF& outmf)
886 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
887 MF inmf_sub, inmf_tmp;
889 inmf_sub = m_sub_helper.make_alias_mf(inmf);
891 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
892 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
893 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
896 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
897 cMF outmf_sub, outmf_tmp;
899 outmf_sub = m_sub_helper.make_alias_mf(outmf);
901 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, 0);
902 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
905 m_r2x_sub->forward(inmf_sub, outmf_sub);
908 outmf.LocalCopy(outmf_tmp, 0, 0, 1,
IntVect(0));
915#if (AMREX_SPACEDIM == 3)
916 if (m_info.twod_mode) {
918 auto lo = m_dom_cy.smallEnd();
919 auto hi = m_dom_cy.bigEnd();
920 std::swap(lo[0],lo[1]);
921 std::swap(hi[0],hi[1]);
924 }
else if (m_ry.empty() && m_cy.empty() && !m_cx.empty()) {
925 outmf.ParallelCopy(m_cx, 0, 0, 1);
927 amrex::Abort(
"R2X::forward(MF,cMF): How did this happen?");
939void R2X<T>::backward ()
945#if (AMREX_SPACEDIM == 3)
948 m_fft_bwd_z.template compute_r2r<Direction::backward>();
953 m_fft_bwd_z.template compute_c2c<Direction::backward>();
957 m_fft_bwd_z.template compute_r2c<Direction::backward>();
960 ParallelCopy(m_cy, m_cz, *m_cmd_cz2cy, 0, 0, 1, m_dtos_z2y);
961 }
else if ( m_cmd_rz2ry) {
962 ParallelCopy(m_ry, m_rz, *m_cmd_rz2ry, 0, 0, 1, m_dtos_z2y);
966#if (AMREX_SPACEDIM >= 2)
969 m_fft_bwd_y.template compute_r2r<Direction::backward>();
973 m_fft_bwd_y.template compute_c2c<Direction::backward>();
977 m_fft_bwd_y.template compute_r2c<Direction::backward>();
980 ParallelCopy(m_cx, m_cy, *m_cmd_cy2cx, 0, 0, 1, m_dtos_y2x);
981 }
else if ( m_cmd_ry2rx) {
982 ParallelCopy(m_rx, m_ry, *m_cmd_ry2rx, 0, 0, 1, m_dtos_y2x);
987 m_fft_bwd_x.template compute_r2c<Direction::backward>();
989 m_fft_bwd_x.template compute_r2r<Direction::backward>();
994void R2X<T>::backward (MF
const& inmf, MF& outmf,
IntVect const& ngout,
995 Periodicity
const& period)
999 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
1000 MF inmf_sub, inmf_tmp;
1002 inmf_sub = m_sub_helper.make_alias_mf(inmf);
1004 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
1005 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
1006 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
1009 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
1010 MF outmf_sub, outmf_tmp;
1012 outmf_sub = m_sub_helper.make_alias_mf(outmf);
1014 IntVect const& ngtmp = m_sub_helper.make_safe_ghost(outmf.nGrowVect());
1015 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, ngtmp);
1016 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
1019 IntVect const& subngout = m_sub_helper.make_iv(ngout);
1020 Periodicity
const& subperiod = m_sub_helper.make_periodicity(period);
1021 m_r2x_sub->backward(inmf_sub, outmf_sub, subngout, subperiod);
1024 outmf.LocalCopy(outmf_tmp, 0, 0, 1, outmf_tmp.nGrowVect());
1029#if (AMREX_SPACEDIM == 3)
1030 if (m_info.twod_mode) {
1031 if (m_cy.empty() && !m_ry.empty()) {
1033 }
else if (m_ry.empty() && m_cy.empty() && m_cx.empty()) {
1034 m_rx.ParallelCopy(inmf, 0, 0, 1);
1036 amrex::Abort(
"R2X::backward(MF,MF): How did this happen?");
1047 outmf.ParallelCopy(m_rx, 0, 0, 1,
IntVect(0),
1052template <
typename T>
1053void R2X<T>::backward (cMF
const& inmf, MF& outmf,
IntVect const& ngout,
1054 Periodicity
const& period)
1058 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
1059 cMF inmf_sub, inmf_tmp;
1061 inmf_sub = m_sub_helper.make_alias_mf(inmf);
1063 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
1064 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
1065 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
1068 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
1069 MF outmf_sub, outmf_tmp;
1071 outmf_sub = m_sub_helper.make_alias_mf(outmf);
1073 IntVect const& ngtmp = m_sub_helper.make_safe_ghost(outmf.nGrowVect());
1074 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, ngtmp);
1075 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
1078 IntVect const& subngout = m_sub_helper.make_iv(ngout);
1079 Periodicity
const& subperiod = m_sub_helper.make_periodicity(period);
1080 m_r2x_sub->backward(inmf_sub, outmf_sub, subngout, subperiod);
1083 outmf.LocalCopy(outmf_tmp, 0, 0, 1, outmf_tmp.nGrowVect());
1088#if (AMREX_SPACEDIM == 3)
1089 if (m_info.twod_mode) {
1090 if (!m_cy.empty()) {
1092 }
else if (m_ry.empty() && m_cy.empty() && !m_cx.empty()) {
1093 m_cx.ParallelCopy(inmf, 0, 0, 1);
1095 amrex::Abort(
"R2X::backward(cMF,MF): How did this happen?");
1106 outmf.ParallelCopy(m_rx, 0, 0, 1,
IntVect(0),
1111template <
typename T>
1112template <
int dim,
typename FAB,
typename F>
1115 if (m_info.twod_mode) {
1119 auto const& a = fab->array();
1123 if constexpr (dim == 0) {
1125 }
else if constexpr (dim == 1) {