/**
* A class that implements the interface to use the BDDC preconditioner from
- * PETSc.
+ * PETSc (<a
+ * href="https://petsc.org/release/docs/manualpages/PC/PCBDDC.html">PCBDDC</a>),
+ * which is a two-level, substructuring, non-overlapping domain decomposition
+ * preconditioner. Details of the implementation can be found in "S Zampini,
+ * SISC (2016)". It mainly consists of two elements:
+ *
+ * <ul>
+ * <li> Local solvers: Solvers for each subdomain. These are performed concurrently by each processor
+ * <li> A coarse solver: Continuity between each subdomain is imposed in a small number of DoFs, referred to as <em>primal DoFs</em>. This solver solves such problem.
+ * </ul>
+ *
+ * The size of the primal space is determined through the @p AdditionalData parameters.
*
* @ingroup PETScWrappers
*/
* than what is exposed here.
*/
AdditionalData(const bool use_vertices = true,
- const bool use_edges_ = false,
- const bool use_faces_ = false,
- const bool symmetric_ = false,
- const unsigned int coords_cdim_ = 0,
- const types::global_dof_index coords_n_ = 0,
- const PetscReal * coords_data_ = nullptr);
+ const bool use_edges_ = false,
+ const bool use_faces_ = false,
+ const bool symmetric_ = false,
+ const unsigned int coords_cdim_ = 0,
+ const types::global_dof_index coords_n_ = 0,
+ const PetscReal * coords_data_ = nullptr);
/**
* This flag sets the use of degrees of freedom in the vertices of the
- * subdomain as primal variables.
+ * subdomains as primal variables for the creation of the coarse space.
*/
bool use_vertices;
/**
* This flag sets the use of degrees of freedom in the edges of the
- * subdomain as primal variables.
+ * subdomain as primal variables for the creation of the coarse space.
+ * Continuity is actually imposed at the edge average.
*/
bool use_edges;
/**
* This flag sets the use of degrees of freedom in the faces of the
- * subdomain as primal variables.
+ * subdomain as primal variables for the creation of the coarse space.
+ * Continuity is actually imposed at the face average.
*/
bool use_faces;
bool symmetric;
/**
- * Support for H1 problems
+ * Set the number of coordinates that each DoF has, i.e. 2 in 2D and 3 in
+ * 3D.
+ */
+ unsigned int coords_cdim;
+
+ /**
+ * Set the number of degrees of freedom that the problem has.
*/
- unsigned int coords_cdim;
types::global_dof_index coords_n;
- const PetscReal
- *coords_data; /* not referenced, consumed at initialize time */
+
+ /**
+ * Set the location of each DoF. This helps in improving the definition of
+ * the vertices for unstructured meshes.
+ */
+ const PetscReal *coords_data;
};
/**
std::to_string(col_owners) + ")"));
}
# endif
+ PetscErrorCode ierr;
// create the local to global mappings as arrays.
IndexSet::size_type n_l2g_row = local_active_rows.n_elements();
IS is_glob_row, is_glob_col;
// Create row index set
ISLocalToGlobalMapping l2gmap_row;
- ISCreateGeneral(communicator,
- n_l2g_row,
- idx_glob_row.data(),
- PETSC_COPY_VALUES,
- &is_glob_row);
- ISLocalToGlobalMappingCreateIS(is_glob_row, &l2gmap_row);
- ISDestroy(&is_glob_row);
- ISLocalToGlobalMappingViewFromOptions(l2gmap_row, NULL, "-view_map");
+ ierr = ISCreateGeneral(communicator,
+ n_l2g_row,
+ idx_glob_row.data(),
+ PETSC_COPY_VALUES,
+ &is_glob_row);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr = ISLocalToGlobalMappingCreateIS(is_glob_row, &l2gmap_row);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr = ISDestroy(&is_glob_row);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr =
+ ISLocalToGlobalMappingViewFromOptions(l2gmap_row, NULL, "-view_map");
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
// Create column index set
ISLocalToGlobalMapping l2gmap_col;
- ISCreateGeneral(communicator,
- n_l2g_col,
- idx_glob_col.data(),
- PETSC_COPY_VALUES,
- &is_glob_col);
- ISLocalToGlobalMappingCreateIS(is_glob_col, &l2gmap_col);
- ISDestroy(&is_glob_col);
- ISLocalToGlobalMappingViewFromOptions(l2gmap_col, NULL, "-view_map");
+ ierr = ISCreateGeneral(communicator,
+ n_l2g_col,
+ idx_glob_col.data(),
+ PETSC_COPY_VALUES,
+ &is_glob_col);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr = ISLocalToGlobalMappingCreateIS(is_glob_col, &l2gmap_col);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr = ISDestroy(&is_glob_col);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr =
+ ISLocalToGlobalMappingViewFromOptions(l2gmap_col, NULL, "-view_map");
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
// create the matrix with the IS constructor.
- PetscErrorCode ierr = MatCreateIS(communicator,
- 1,
- local_rows.n_elements(),
- local_columns.n_elements(),
- sparsity_pattern.n_rows(),
- sparsity_pattern.n_cols(),
- l2gmap_row,
- l2gmap_col,
- &matrix);
- AssertThrow(ierr == 0, ExcPETScError(ierr));
- ISLocalToGlobalMappingDestroy(&l2gmap_row);
- ISLocalToGlobalMappingDestroy(&l2gmap_col);
+ ierr = MatCreateIS(communicator,
+ 1,
+ local_rows.n_elements(),
+ local_columns.n_elements(),
+ sparsity_pattern.n_rows(),
+ sparsity_pattern.n_cols(),
+ l2gmap_row,
+ l2gmap_col,
+ &matrix);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr = ISLocalToGlobalMappingDestroy(&l2gmap_row);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr = ISLocalToGlobalMappingDestroy(&l2gmap_col);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
// next preset the exact given matrix
// entries with zeros. This doesn't avoid any
// In the MATIS case, we use the local matrix instead
Mat local_matrix;
- MatISGetLocalMat(matrix, &local_matrix);
- MatSetType(local_matrix,
- MATSEQAIJ); // SEQ as it is local! TODO: Allow for OpenMP
- // parallelization in local node.
+ ierr = MatISGetLocalMat(matrix, &local_matrix);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+ ierr = MatSetType(local_matrix,
+ MATSEQAIJ); // SEQ as it is local! TODO: Allow for
+ // OpenMP parallelization in local node.
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
if (local_rows.n_elements() > 0)
{
// MatSEQAIJSetPreallocationCSR
close_matrix(local_matrix);
set_keep_zero_rows(local_matrix);
}
- MatISRestoreLocalMat(matrix, &local_matrix);
+ ierr = MatISRestoreLocalMat(matrix, &local_matrix);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
}
# ifndef DOXYGEN