@@ -186,8 +186,7 @@ class MatrixPC : public Preconditioner<T,Ops>
186186 int m_ndofs_g = 0 ;
187187 bool m_pc_diag_only = false ;
188188 int m_pc_mat_nnz = 1 ;
189- int m_pc_mass_matrix_width = 0 ;
190- bool m_pc_mass_matrix_include_ij = false ;
189+ bool m_include_mass_matrices = false ;
191190
192191 std::string m_name = " noname" ;
193192
@@ -213,10 +212,9 @@ template <class T, class Ops>
213212void MatrixPC<T,Ops>::printParameters() const
214213{
215214 using namespace amrex ;
216- Print () << m_name << " verbose: " << (m_verbose?" true" :" false" ) << " \n " ;
217- Print () << m_name << " pc_diagonal_only: " << (m_pc_diag_only?" true" :" false" ) << " \n " ;
218- Print () << m_name << " pc_mass_matrix_width: " << m_pc_mass_matrix_width << " \n " ;
219- Print () << m_name << " pc_mass_matrix_include_ij: " << (m_pc_mass_matrix_include_ij?" true" :" false" ) << " \n " ;
215+ Print () << m_name << " verbose: " << (m_verbose?" true" :" false" ) << " \n " ;
216+ Print () << m_name << " pc_diagonal_only: " << (m_pc_diag_only?" true" :" false" ) << " \n " ;
217+ Print () << m_name << " include_mass_matrices: " << (m_include_mass_matrices?" true" :" false" ) << " \n " ;
220218}
221219
222220template <class T , class Ops >
@@ -225,10 +223,6 @@ void MatrixPC<T,Ops>::readParameters()
225223 const amrex::ParmParse pp (m_name);
226224 pp.query (" verbose" , m_verbose);
227225 pp.query (" pc_diagonal_only" , m_pc_diag_only);
228- pp.query (" pc_mass_matrix_width" , m_pc_mass_matrix_width);
229- if (m_pc_mass_matrix_width>0 ) {
230- pp.query (" pc_mass_matrix_include_ij" , m_pc_mass_matrix_include_ij);
231- }
232226}
233227
234228template <class T , class Ops >
@@ -279,14 +273,8 @@ void MatrixPC<T,Ops>::Define ( const T& a_U,
279273
280274
281275 m_bcoefs = m_ops->GetMassMatricesCoeff ();
282- if (m_bcoefs == nullptr ) {
283- if (m_pc_mass_matrix_width >= 0 ) {
284- std::stringstream warning_message;
285- warning_message << " pc_mass_matrix_width is nonnegative but unable to get mass matrices from operator.\n " ;
286- warning_message << " setting m_pc_mass_matrix_width = -1 (no mass matrix in PC).\n " ;
287- ablastr::warn_manager::WMRecordWarning (" MatrixPC" , warning_message.str ());
288- }
289- m_pc_mass_matrix_width = -1 ;
276+ if (m_bcoefs != nullptr ) {
277+ m_include_mass_matrices = true ;
290278 }
291279
292280 m_is_defined = true ;
@@ -634,19 +622,23 @@ int MatrixPC<T,Ops>::Assemble (const T& a_U)
634622 }
635623
636624 // Add the mass matrix piece
637- if (m_pc_mass_matrix_width >= 0 ) {
625+ if (m_include_mass_matrices ) {
638626
639- auto mm_width = m_pc_mass_matrix_width;
640- auto mm_incl_ij = m_pc_mass_matrix_include_ij;
641627 auto sigma_ii_arr = (*m_bcoefs)[lev][dir]->const_array (mfi);
628+ const amrex::IntVect MM_ncomps = m_ops->GetMassMatricesPCNcomp (dir);
629+ const int MM_ncomps_tot = (*m_bcoefs)[lev][dir]->nComp ();
630+ const int diag_MM_comp = (MM_ncomps_tot - 1 )/2 ;
631+ amrex::IntVect MM_width;
632+ for (int space_dir=0 ; space_dir<AMREX_SPACEDIM; space_dir++) {
633+ MM_width[space_dir] = (MM_ncomps[space_dir] - 1 )/2 ;
634+ }
642635
643636 ParallelFor (bx, [=] AMREX_GPU_DEVICE (int i, int j, int k)
644637 {
645638 int ridx_l = dof_arr (i,j,k,0 );
646639 if (ridx_l < 0 ) { return ; }
647640
648641 int icol = num_nz_ptr[ridx_l];
649-
650642 {
651643 int cidx_g_lhs = dof_arr (i,j,k,1 );
652644 amrex::Real val = sigma_ii_arr (i,j,k,0 );
@@ -656,9 +648,47 @@ int MatrixPC<T,Ops>::Assemble (const T& a_U)
656648 nnz_max, icol );
657649 if (!flag) { Gpu::Atomic::Max (nnz_actual_ptr, icol); }
658650 }
659-
660- amrex::ignore_unused (mm_width); // will be used when adding off-diagonal elements
661- amrex::ignore_unused (mm_incl_ij); // will be used when adding off-diagonal elements
651+ #if defined(WARPX_DIM_1D_Z)
652+ for (int width = 1 ; width <= MM_width[0 ]; width++) {
653+ {
654+ int cidx_g_rhs = dof_arr (i - width,j,k,1 );
655+ amrex::Real val = sigma_ii_arr (i,j,k,diag_MM_comp - width);
656+ auto flag = MatrixPCUtils::insertOrAdd ( cidx_g_rhs, val,
657+ &c_indices_g_ptr[ridx_l*nnz_max],
658+ &a_ij_ptr[ridx_l*nnz_max],
659+ nnz_max, icol );
660+ if (!flag) { Gpu::Atomic::Max (nnz_actual_ptr, icol); }
661+ }
662+ {
663+ int cidx_g_rhs = dof_arr (i + width,j,k,1 );
664+ amrex::Real val = sigma_ii_arr (i,j,k,diag_MM_comp + width);
665+ auto flag = MatrixPCUtils::insertOrAdd ( cidx_g_rhs, val,
666+ &c_indices_g_ptr[ridx_l*nnz_max],
667+ &a_ij_ptr[ridx_l*nnz_max],
668+ nnz_max, icol );
669+ if (!flag) { Gpu::Atomic::Max (nnz_actual_ptr, icol); }
670+ }
671+ }
672+ #endif
673+ #if defined(WARPX_DIM_XZ)
674+ int mm_comp = 0 ;
675+ for (int comp1 = 0 ; comp1 < MM_ncomps[1 ]; comp1++) {
676+ const int jj0 = comp1 - MM_width[1 ]; // e.g., -2 -1, 0, 1, 2
677+ for (int comp0 = 0 ; comp0 < MM_ncomps[0 ]; comp0++) {
678+ const int ii0 = comp0 - MM_width[0 ]; // e.g., -2 -1, 0, 1, 2
679+ if (!(ii0==0 && jj0==0 )) {
680+ int cidx_g_rhs = dof_arr (i + ii0,j + jj0,k,1 );
681+ amrex::Real val = sigma_ii_arr (i,j,k,mm_comp);
682+ auto flag = MatrixPCUtils::insertOrAdd ( cidx_g_rhs, val,
683+ &c_indices_g_ptr[ridx_l*nnz_max],
684+ &a_ij_ptr[ridx_l*nnz_max],
685+ nnz_max, icol );
686+ if (!flag) { Gpu::Atomic::Max (nnz_actual_ptr, icol); }
687+ }
688+ mm_comp++;
689+ }
690+ }
691+ #endif
662692
663693 num_nz_ptr[ridx_l] = icol;
664694 });
0 commit comments