@@ -186,6 +186,8 @@ private:
186186 std::unique_ptr<MultiBlockCommMetaData> m_cmd_z2y; // (z,x,y) -> (y,x,z)
187187 std::unique_ptr<MultiBlockCommMetaData> m_cmd_x2z; // (x,y,z) -> (z,x,y)
188188 std::unique_ptr<MultiBlockCommMetaData> m_cmd_z2x; // (z,x,y) -> (x,y,z)
189+ std::unique_ptr<MultiBlockCommMetaData> m_cmd_x2z_half; // for openbc
190+ std::unique_ptr<MultiBlockCommMetaData> m_cmd_z2x_half; // for openbc
189191 Swap01 m_dtos_x2y{};
190192 Swap01 m_dtos_y2x{};
191193 Swap02 m_dtos_y2z{};
@@ -209,6 +211,7 @@ private:
209211 Info m_info;
210212
211213 bool m_slab_decomp = false ;
214+ bool m_openbc_half = false ;
212215};
213216
214217template <typename T, Direction D, DomainStrategy S>
@@ -415,7 +418,24 @@ void R2C<T,D,S>::forward (MF const& inmf)
415418 }
416419#if (AMREX_SPACEDIM == 3)
417420 else if ( m_cmd_x2z) {
418- ParallelCopy (m_cz, m_cx, *m_cmd_x2z, 0 , 0 , 1 , m_dtos_x2z);
421+ if (m_openbc_half) {
422+ Box upper_half = m_spectral_domain_z;
423+ // Note that z-direction's index is 0 because we z is the unit-stride direction here.
424+ upper_half.growLo (0 ,-m_spectral_domain_z.length (0 )/2 );
425+ if (! m_cmd_x2z_half) {
426+ Box bottom_half = m_spectral_domain_z;
427+ bottom_half.growHi (0 ,-m_spectral_domain_z.length (0 )/2 );
428+ m_cmd_x2z_half = std::make_unique<MultiBlockCommMetaData>
429+ (m_cz, bottom_half, m_cx, IntVect (0 ), m_dtos_x2z);
430+ }
431+ NonLocalBC::ApplyDtosAndProjectionOnReciever packing
432+ {NonLocalBC::PackComponents{}, m_dtos_x2z};
433+ auto handler = ParallelCopy_nowait (m_cz, m_cx, *m_cmd_x2z_half, packing);
434+ m_cz.setVal (0 , upper_half, 0 , 1 );
435+ ParallelCopy_finish (m_cz, std::move (handler), *m_cmd_x2z_half, packing);
436+ } else {
437+ ParallelCopy (m_cz, m_cx, *m_cmd_x2z, 0 , 0 , 1 , m_dtos_x2z);
438+ }
419439 }
420440#endif
421441 m_fft_fwd_z.template compute_c2c <Direction::forward>();
@@ -439,7 +459,22 @@ void R2C<T,D,S>::backward_doit (MF& outmf, IntVect const& ngout)
439459 }
440460#if (AMREX_SPACEDIM == 3)
441461 else if ( m_cmd_z2x) {
442- ParallelCopy (m_cx, m_cz, *m_cmd_z2x, 0 , 0 , 1 , m_dtos_z2x);
462+ if (m_openbc_half) {
463+ Box upper_half = m_spectral_domain_x;
464+ upper_half.growLo (2 ,-m_spectral_domain_x.length (2 )/2 );
465+ if (! m_cmd_z2x_half) {
466+ Box bottom_half = m_spectral_domain_x;
467+ bottom_half.growHi (2 ,-m_spectral_domain_x.length (2 )/2 );
468+ m_cmd_z2x_half = std::make_unique<MultiBlockCommMetaData>
469+ (m_cx, bottom_half, m_cz, IntVect (0 ), m_dtos_z2x);
470+ }
471+ NonLocalBC::ApplyDtosAndProjectionOnReciever packing
472+ {NonLocalBC::PackComponents{}, m_dtos_z2x};
473+ auto handler = ParallelCopy_nowait (m_cx, m_cz, *m_cmd_z2x_half, packing);
474+ ParallelCopy_finish (m_cx, std::move (handler), *m_cmd_z2x_half, packing);
475+ } else {
476+ ParallelCopy (m_cx, m_cz, *m_cmd_z2x, 0 , 0 , 1 , m_dtos_z2x);
477+ }
443478 }
444479#endif
445480
0 commit comments