103 template <
typename F>
125 void forward (
MF const& inmf,
MF& outmf);
132 void forward (
MF const& inmf,
cMF& outmf);
138 void forward (
MF const& inmf);
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<detail::TransposeMetaData> m_cmd_cx2cy;
175 std::unique_ptr<detail::TransposeMetaData> m_cmd_rx2ry;
176 std::unique_ptr<detail::TransposeMetaData> m_cmd_cy2cz;
177 std::unique_ptr<detail::TransposeMetaData> m_cmd_ry2rz;
179 std::unique_ptr<detail::TransposeMetaData> m_cmd_cy2cx;
180 std::unique_ptr<detail::TransposeMetaData> m_cmd_ry2rx;
181 std::unique_ptr<detail::TransposeMetaData> m_cmd_cz2cy;
182 std::unique_ptr<detail::TransposeMetaData> 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;
212 bool m_owns_comm_active =
false;
219 Array<std::pair<Boundary,Boundary>,AMREX_SPACEDIM>
const& bc,
223 m_sub_helper(domain),
228 static_assert(std::is_same_v<float,T> || std::is_same_v<double,T>);
233 "FFT::R2X currently requires domain.smallEnd() == 0");
234#if (AMREX_SPACEDIM == 2)
237 if (m_info.twod_mode) {
239 int(domain.
length(1) > 1) +
240 int(domain.
length(2) > 1)) >= 2);
244 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
252 Box subbox = m_sub_helper.make_box(m_dom_0);
253 if (subbox.
size() != m_dom_0.size()) {
254 m_r2x_sub = std::make_unique<R2X<T>>
255 (subbox, m_sub_helper.make_array(bc), info);
270 m_rx.define(bax, dmx, 1, 0,
MFInfo().SetAlloc(
false));
279 for (
auto & b : bl) {
280 b.setBig(0, m_dom_cx.bigEnd(0));
283 m_cx.define(cbax, dmx, 1, 0,
MFInfo().SetAlloc(
false));
286#if (AMREX_SPACEDIM >= 2)
287 if (domain.
length(1) > 1 && !m_info.oned_mode) {
288 if (! m_cx.empty()) {
292 m_dom_cx.bigEnd(2))));
295 if (ba.size() == m_cx.size()) {
296 dm = m_cx.DistributionMap();
298 dm = detail::make_iota_distromap(ba.size());
309 m_dom_rx.bigEnd(2))));
312 if (ba.size() == m_rx.size()) {
313 dm = m_rx.DistributionMap();
315 dm = detail::make_iota_distromap(ba.size());
325 m_dom_ry.bigEnd(2))));
327 for (
auto & b : bl) {
328 b.setBig(0, m_dom_cy.bigEnd(0));
331 m_cy.define(cba, dm, 1, 0,
MFInfo().SetAlloc(
false));
337#if (AMREX_SPACEDIM == 3)
338 if (domain.
length(2) > 1 && !m_info.twod_mode) {
339 if (! m_cy.empty()) {
343 m_dom_cy.bigEnd(0))));
346 if (ba.size() == m_cy.size()) {
347 dm = m_cy.DistributionMap();
349 dm = detail::make_iota_distromap(ba.size());
360 m_dom_ry.bigEnd(0))));
363 if (ba.size() == m_ry.size()) {
364 dm = m_ry.DistributionMap();
366 dm = detail::make_iota_distromap(ba.size());
376 m_dom_rz.bigEnd(2))));
378 for (
auto & b : bl) {
379 b.setBig(0, m_dom_cz.bigEnd(0));
382 m_cz.define(cba, dm, 1, 0,
MFInfo().SetAlloc(
false));
410 if (! m_cx.empty()) {
411 m_data_1 = detail::make_mfs_share(m_rx, m_cy);
412 m_data_2 = detail::make_mfs_share(m_cx, m_cz);
413 }
else if (! m_cy.empty()) {
414 m_data_1 = detail::make_mfs_share(m_rx, m_cy);
415 m_data_2 = detail::make_mfs_share(m_ry, m_cz);
416 }
else if (! m_cz.empty()) {
417 m_data_1 = detail::make_mfs_share(m_rx, m_rz);
418 m_data_2 = detail::make_mfs_share(m_ry, m_cz);
420 m_data_1 = detail::make_mfs_share(m_rx, m_rz);
421 m_data_2 = detail::make_mfs_share(m_ry, m_cz);
428 int const nprocs_active = detail::count_active_procs({&m_rx, &m_ry, &m_rz, &m_cx, &m_cy, &m_cz});
430#if (AMREX_SPACEDIM >= 2)
431 if (!m_cy.empty() || !m_ry.empty()) {
432 if (! m_cx.empty()) {
434 m_cmd_cx2cy = detail::make_transpose
435 (nprocs_active, m_cy, m_dom_cy, m_cx,
IntVect(0), m_dtos_x2y);
436 m_cmd_cy2cx = detail::make_transpose
437 (nprocs_active, m_cx, m_dom_cx, m_cy,
IntVect(0), m_dtos_y2x);
440 m_cmd_rx2ry = detail::make_transpose
441 (nprocs_active, m_ry, m_dom_ry, m_rx,
IntVect(0), m_dtos_x2y);
442 m_cmd_ry2rx = detail::make_transpose
443 (nprocs_active, m_rx, m_dom_rx, m_ry,
IntVect(0), m_dtos_y2x);
448#if (AMREX_SPACEDIM == 3)
449 if (!m_cz.empty() || !m_rz.empty()) {
450 if (! m_cy.empty()) {
452 m_cmd_cy2cz = detail::make_transpose
453 (nprocs_active, m_cz, m_dom_cz, m_cy,
IntVect(0), m_dtos_y2z);
454 m_cmd_cz2cy = detail::make_transpose
455 (nprocs_active, m_cy, m_dom_cy, m_cz,
IntVect(0), m_dtos_z2y);
458 m_cmd_ry2rz = detail::make_transpose
459 (nprocs_active, m_rz, m_dom_rz, m_ry,
IntVect(0), m_dtos_y2z);
460 m_cmd_rz2ry = detail::make_transpose
461 (nprocs_active, m_ry, m_dom_ry, m_rz,
IntVect(0), m_dtos_z2y);
466 m_info.comm_strategy = detail::resolve_comm_strategy
467 (m_info.comm_strategy, std::max({detail::max_fab_bytes(m_rx),
468 detail::max_fab_bytes(m_ry),
469 detail::max_fab_bytes(m_rz),
470 detail::max_fab_bytes(m_cx),
471 detail::max_fab_bytes(m_cy),
472 detail::max_fab_bytes(m_cz)}),
473 detail::max_block_bytes({&m_cmd_cx2cy, &m_cmd_rx2ry, &m_cmd_cy2cz,
474 &m_cmd_ry2rz, &m_cmd_cy2cx, &m_cmd_ry2rx,
475 &m_cmd_cz2cy, &m_cmd_rz2ry}),
476 detail::transposes_dense({&m_cmd_cx2cy, &m_cmd_rx2ry, &m_cmd_cy2cz,
477 &m_cmd_ry2rz, &m_cmd_cy2cx, &m_cmd_ry2rx,
478 &m_cmd_cz2cy, &m_cmd_rz2ry}));
480 m_comm_active = detail::make_active_comm(nprocs_active, m_owns_comm_active);
489 if (myproc < m_rx.size())
491 Box const& box = m_rx.box(myproc);
492 auto* pf = m_rx[myproc].dataPtr();
494 auto* pb = (VendorComplex*) m_cx[myproc].dataPtr();
495 m_fft_fwd_x.template init_r2c<Direction::forward>(box, pf, pb);
496#if defined(AMREX_USE_SYCL)
497 m_fft_bwd_x = m_fft_fwd_x;
499 m_fft_bwd_x.template init_r2c<Direction::backward>(box, pf, pb);
502 m_fft_fwd_x.template init_r2r<Direction::forward>(box, pf, bc[0]);
503#if defined(AMREX_USE_GPU)
506 m_fft_bwd_x = m_fft_fwd_x;
510 m_fft_bwd_x.template init_r2r<Direction::backward>(box, pf, bc[0]);
515#if (AMREX_SPACEDIM >= 2)
517 if (myproc < m_cy.size()) {
518 Box const& box = m_cy.box(myproc);
519 auto*
p = (VendorComplex *)m_cy[myproc].dataPtr();
520 m_fft_fwd_y.template init_c2c<Direction::forward>(box,
p);
521#if defined(AMREX_USE_SYCL)
522 m_fft_bwd_y = m_fft_fwd_y;
524 m_fft_bwd_y.template init_c2c<Direction::backward>(box,
p);
528 if (myproc < m_ry.size()) {
529 Box const& box = m_ry.box(myproc);
530 auto* pr = m_ry[myproc].dataPtr();
531 auto* pc = (VendorComplex*)m_cy[myproc].dataPtr();
532 m_fft_fwd_y.template init_r2c<Direction::forward>(box, pr, pc);
533#if defined(AMREX_USE_SYCL)
534 m_fft_bwd_y = m_fft_fwd_y;
536 m_fft_bwd_y.template init_r2c<Direction::backward>(box, pr, pc);
539 }
else if (!m_cy.empty()) {
540 if (myproc < m_cy.size()) {
541 Box const& box = m_cy.box(myproc);
542 auto*
p = (VendorComplex*) m_cy[myproc].dataPtr();
543 m_fft_fwd_y.template init_r2r<Direction::forward>(box,
p, bc[1]);
544#if defined(AMREX_USE_GPU)
547 m_fft_bwd_y = m_fft_fwd_y;
551 m_fft_bwd_y.template init_r2r<Direction::backward>(box,
p, bc[1]);
555 if (myproc < m_ry.size()) {
556 Box const& box = m_ry.box(myproc);
557 auto*
p = m_ry[myproc].dataPtr();
558 m_fft_fwd_y.template init_r2r<Direction::forward>(box,
p, bc[1]);
559#if defined(AMREX_USE_GPU)
562 m_fft_bwd_y = m_fft_fwd_y;
566 m_fft_bwd_y.template init_r2r<Direction::backward>(box,
p, bc[1]);
572#if (AMREX_SPACEDIM == 3)
574 if (myproc < m_cz.size()) {
575 Box const& box = m_cz.box(myproc);
576 auto*
p = (VendorComplex*)m_cz[myproc].dataPtr();
577 m_fft_fwd_z.template init_c2c<Direction::forward>(box,
p);
578#if defined(AMREX_USE_SYCL)
579 m_fft_bwd_z = m_fft_fwd_z;
581 m_fft_bwd_z.template init_c2c<Direction::backward>(box,
p);
585 if (myproc < m_rz.size()) {
586 Box const& box = m_rz.box(myproc);
587 auto* pr = m_rz[myproc].dataPtr();
588 auto* pc = (VendorComplex*)m_cz[myproc].dataPtr();
589 m_fft_fwd_z.template init_r2c<Direction::forward>(box, pr, pc);
590#if defined(AMREX_USE_SYCL)
591 m_fft_bwd_z = m_fft_fwd_z;
593 m_fft_bwd_z.template init_r2c<Direction::backward>(box, pr, pc);
596 }
else if (!m_cz.empty()) {
597 if (myproc < m_cz.size()) {
598 Box const& box = m_cz.box(myproc);
599 auto*
p = (VendorComplex*) m_cz[myproc].dataPtr();
600 m_fft_fwd_z.template init_r2r<Direction::forward>(box,
p, bc[2]);
601#if defined(AMREX_USE_GPU)
604 m_fft_bwd_z = m_fft_fwd_z;
608 m_fft_bwd_z.template init_r2r<Direction::backward>(box,
p, bc[2]);
612 if (myproc < m_rz.size()) {
613 Box const& box = m_rz.box(myproc);
614 auto*
p = m_rz[myproc].dataPtr();
615 m_fft_fwd_z.template init_r2r<Direction::forward>(box,
p, bc[2]);
616#if defined(AMREX_USE_GPU)
619 m_fft_bwd_z = m_fft_fwd_z;
623 m_fft_bwd_z.template init_r2r<Direction::backward>(box,
p, bc[2]);
633 if (m_fft_bwd_x.plan != m_fft_fwd_x.plan) {
634 m_fft_bwd_x.destroy();
636 if (m_fft_bwd_y.plan != m_fft_fwd_y.plan) {
637 m_fft_bwd_y.destroy();
639 if (m_fft_bwd_z.plan != m_fft_fwd_z.plan) {
640 m_fft_bwd_z.destroy();
642 m_fft_fwd_x.destroy();
643 m_fft_fwd_y.destroy();
644 m_fft_fwd_z.destroy();
645 detail::free_active_comm(m_comm_active, m_owns_comm_active);
652 if (m_r2x_sub) {
return m_r2x_sub->scalingFactor(); }
656 for (
int idim = 0; idim < AMREX_SPACEDIM; ++idim) {
657 if ((idim == 1 && m_info.oned_mode) ||
658 (idim == 2 && m_info.twod_mode) ||
659 (m_dom_0.length(idim) == 1)) {
continue; }
660 r *= m_dom_0.length(idim);
672 "FFT::R2X::forwardThenBackward(post_forward) does not support twod_mode yet");
679 F const& post_forward,
686 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
687 MF inmf_sub, inmf_tmp;
689 inmf_sub = m_sub_helper.make_alias_mf(inmf);
691 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
692 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
693 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
696 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
697 MF outmf_sub, outmf_tmp;
699 outmf_sub = m_sub_helper.make_alias_mf(outmf);
701 IntVect const& ngtmp = m_sub_helper.make_safe_ghost(outmf.nGrowVect());
702 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, ngtmp);
703 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
706 IntVect const& subngout = m_sub_helper.make_iv(ngout);
707 Periodicity const& subperiod = m_sub_helper.make_periodicity(period);
709 m_r2x_sub->forwardThenBackward_doit_1
710 (inmf_sub, outmf_sub,
714 post_forward(idx[order[0]], idx[order[1]], idx[order[2]], sp);
716 subngout, subperiod);
719 outmf.LocalCopy(outmf_tmp, 0, 0, 1, outmf_tmp.nGrowVect());
731 F const& post_forward,
738 amrex::Abort(
"R2X::forwardThenBackward_doit_1: How did this happen?");
749#if (AMREX_SPACEDIM >= 2)
750 if (!m_ry.empty() || !m_cy.empty()) { actual_dim = 2; }
752#if (AMREX_SPACEDIM == 3)
753 if (!m_rz.empty() || !m_cz.empty()) { actual_dim = 3; }
756 if (actual_dim == 1) {
763#if (AMREX_SPACEDIM >= 2)
764 else if (actual_dim == 2) {
772#if (AMREX_SPACEDIM == 3)
773 else if (actual_dim == 3) {
784 outmf.ParallelCopy(m_rx, 0, 0, 1,
IntVect(0),
790void R2X<T>::forward (MF
const& inmf)
795 if (m_sub_helper.ghost_safe(inmf.nGrowVect())) {
796 m_r2x_sub->forward(m_sub_helper.make_alias_mf(inmf));
798 MF tmp(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
799 tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
800 m_r2x_sub->forward(m_sub_helper.make_alias_mf(tmp));
805 m_rx.ParallelCopy(inmf, 0, 0, 1);
807 m_fft_fwd_x.template compute_r2c<Direction::forward>();
809 m_fft_fwd_x.template compute_r2r<Direction::forward>();
812#if (AMREX_SPACEDIM >= 2)
814 detail::transpose(m_cy, m_cx, *m_cmd_cx2cy, 1, m_dtos_x2y, m_info.comm_strategy, m_comm_active);
815 }
else if ( m_cmd_rx2ry) {
816 detail::transpose(m_ry, m_rx, *m_cmd_rx2ry, 1, m_dtos_x2y, m_info.comm_strategy, m_comm_active);
820 m_fft_fwd_y.template compute_r2r<Direction::forward>();
824 m_fft_fwd_y.template compute_c2c<Direction::forward>();
828 m_fft_fwd_y.template compute_r2c<Direction::forward>();
832#if (AMREX_SPACEDIM == 3)
834 detail::transpose(m_cz, m_cy, *m_cmd_cy2cz, 1, m_dtos_y2z, m_info.comm_strategy, m_comm_active);
835 }
else if ( m_cmd_ry2rz) {
836 detail::transpose(m_rz, m_ry, *m_cmd_ry2rz, 1, m_dtos_y2z, m_info.comm_strategy, m_comm_active);
840 m_fft_fwd_z.template compute_r2r<Direction::forward>();
845 m_fft_fwd_z.template compute_c2c<Direction::forward>();
849 m_fft_fwd_z.template compute_r2c<Direction::forward>();
855void R2X<T>::forward (MF
const& inmf, MF& outmf)
859 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
860 MF inmf_sub, inmf_tmp;
862 inmf_sub = m_sub_helper.make_alias_mf(inmf);
864 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
865 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
866 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
869 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
870 MF outmf_sub, outmf_tmp;
872 outmf_sub = m_sub_helper.make_alias_mf(outmf);
874 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, 0);
875 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
878 m_r2x_sub->forward(inmf_sub, outmf_sub);
881 outmf.LocalCopy(outmf_tmp, 0, 0, 1,
IntVect(0));
888#if (AMREX_SPACEDIM == 3)
889 if (m_info.twod_mode) {
890 if (m_cy.empty() && !m_ry.empty()) {
892 }
else if (m_ry.empty() && m_cy.empty() && m_cx.empty()) {
893 outmf.ParallelCopy(m_rx, 0, 0, 1);
895 amrex::Abort(
"R2X::forward(MF,MF): How did this happen?");
907void R2X<T>::forward (MF
const& inmf, cMF& outmf)
911 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
912 MF inmf_sub, inmf_tmp;
914 inmf_sub = m_sub_helper.make_alias_mf(inmf);
916 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
917 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
918 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
921 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
922 cMF outmf_sub, outmf_tmp;
924 outmf_sub = m_sub_helper.make_alias_mf(outmf);
926 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, 0);
927 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
930 m_r2x_sub->forward(inmf_sub, outmf_sub);
933 outmf.LocalCopy(outmf_tmp, 0, 0, 1,
IntVect(0));
940#if (AMREX_SPACEDIM == 3)
941 if (m_info.twod_mode) {
943 auto lo = m_dom_cy.smallEnd();
944 auto hi = m_dom_cy.bigEnd();
945 std::swap(lo[0],lo[1]);
946 std::swap(hi[0],hi[1]);
949 }
else if (m_ry.empty() && m_cy.empty() && !m_cx.empty()) {
950 outmf.ParallelCopy(m_cx, 0, 0, 1);
952 amrex::Abort(
"R2X::forward(MF,cMF): How did this happen?");
964void R2X<T>::backward ()
970#if (AMREX_SPACEDIM == 3)
973 m_fft_bwd_z.template compute_r2r<Direction::backward>();
978 m_fft_bwd_z.template compute_c2c<Direction::backward>();
982 m_fft_bwd_z.template compute_r2c<Direction::backward>();
985 detail::transpose(m_cy, m_cz, *m_cmd_cz2cy, 1, m_dtos_z2y, m_info.comm_strategy, m_comm_active);
986 }
else if ( m_cmd_rz2ry) {
987 detail::transpose(m_ry, m_rz, *m_cmd_rz2ry, 1, m_dtos_z2y, m_info.comm_strategy, m_comm_active);
991#if (AMREX_SPACEDIM >= 2)
994 m_fft_bwd_y.template compute_r2r<Direction::backward>();
998 m_fft_bwd_y.template compute_c2c<Direction::backward>();
1002 m_fft_bwd_y.template compute_r2c<Direction::backward>();
1005 detail::transpose(m_cx, m_cy, *m_cmd_cy2cx, 1, m_dtos_y2x, m_info.comm_strategy, m_comm_active);
1006 }
else if ( m_cmd_ry2rx) {
1007 detail::transpose(m_rx, m_ry, *m_cmd_ry2rx, 1, m_dtos_y2x, m_info.comm_strategy, m_comm_active);
1012 m_fft_bwd_x.template compute_r2c<Direction::backward>();
1014 m_fft_bwd_x.template compute_r2r<Direction::backward>();
1018template <
typename T>
1019void R2X<T>::backward (MF
const& inmf, MF& outmf,
IntVect const& ngout,
1020 Periodicity
const& period)
1024 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
1025 MF inmf_sub, inmf_tmp;
1027 inmf_sub = m_sub_helper.make_alias_mf(inmf);
1029 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
1030 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
1031 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
1034 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
1035 MF outmf_sub, outmf_tmp;
1037 outmf_sub = m_sub_helper.make_alias_mf(outmf);
1039 IntVect const& ngtmp = m_sub_helper.make_safe_ghost(outmf.nGrowVect());
1040 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, ngtmp);
1041 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
1044 IntVect const& subngout = m_sub_helper.make_iv(ngout);
1045 Periodicity
const& subperiod = m_sub_helper.make_periodicity(period);
1046 m_r2x_sub->backward(inmf_sub, outmf_sub, subngout, subperiod);
1049 outmf.LocalCopy(outmf_tmp, 0, 0, 1, outmf_tmp.nGrowVect());
1054#if (AMREX_SPACEDIM == 3)
1055 if (m_info.twod_mode) {
1056 if (m_cy.empty() && !m_ry.empty()) {
1058 }
else if (m_ry.empty() && m_cy.empty() && m_cx.empty()) {
1059 m_rx.ParallelCopy(inmf, 0, 0, 1);
1061 amrex::Abort(
"R2X::backward(MF,MF): How did this happen?");
1072 outmf.ParallelCopy(m_rx, 0, 0, 1,
IntVect(0),
1077template <
typename T>
1078void R2X<T>::backward (cMF
const& inmf, MF& outmf,
IntVect const& ngout,
1079 Periodicity
const& period)
1083 bool inmf_safe = m_sub_helper.ghost_safe(inmf.nGrowVect());
1084 cMF inmf_sub, inmf_tmp;
1086 inmf_sub = m_sub_helper.make_alias_mf(inmf);
1088 inmf_tmp.define(inmf.boxArray(), inmf.DistributionMap(), 1, 0);
1089 inmf_tmp.LocalCopy(inmf, 0, 0, 1,
IntVect(0));
1090 inmf_sub = m_sub_helper.make_alias_mf(inmf_tmp);
1093 bool outmf_safe = m_sub_helper.ghost_safe(outmf.nGrowVect());
1094 MF outmf_sub, outmf_tmp;
1096 outmf_sub = m_sub_helper.make_alias_mf(outmf);
1098 IntVect const& ngtmp = m_sub_helper.make_safe_ghost(outmf.nGrowVect());
1099 outmf_tmp.define(outmf.boxArray(), outmf.DistributionMap(), 1, ngtmp);
1100 outmf_sub = m_sub_helper.make_alias_mf(outmf_tmp);
1103 IntVect const& subngout = m_sub_helper.make_iv(ngout);
1104 Periodicity
const& subperiod = m_sub_helper.make_periodicity(period);
1105 m_r2x_sub->backward(inmf_sub, outmf_sub, subngout, subperiod);
1108 outmf.LocalCopy(outmf_tmp, 0, 0, 1, outmf_tmp.nGrowVect());
1113#if (AMREX_SPACEDIM == 3)
1114 if (m_info.twod_mode) {
1115 if (!m_cy.empty()) {
1117 }
else if (m_ry.empty() && m_cy.empty() && !m_cx.empty()) {
1118 m_cx.ParallelCopy(inmf, 0, 0, 1);
1120 amrex::Abort(
"R2X::backward(cMF,MF): How did this happen?");
1131 outmf.ParallelCopy(m_rx, 0, 0, 1,
IntVect(0),
1136template <
typename T>
1137template <
int dim,
typename FAB,
typename F>
1140 if (m_info.twod_mode) {
1144 auto const& a = fab->array();
1148 if constexpr (dim == 0) {
1150 }
else if constexpr (dim == 1) {