Skip to content

Commit a091d64

Browse files
add off-diagonal terms to to the matrix.
1 parent 2e8bb8e commit a091d64

File tree

1 file changed

+55
-25
lines changed

1 file changed

+55
-25
lines changed

Source/NonlinearSolvers/MatrixPC.H

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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>
213212
void 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

222220
template <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

234228
template <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

Comments
 (0)