35 return it::Record(
"Petsc",
"PETSc solver settings.\n It provides interface to various PETSc solvers. The convergence criteria is:\n"
37 "norm( res_i ) < max( norm( res_0 ) * r_tol, a_tol )\n"
39 "where ```res_i``` is the residuum vector after i-th iteration of the solver and ```res_0``` is the estimate of the norm of the initial residual. "
40 "If the initial guess of the solution is provided (usually only for transient equations) the residual of this estimate is used, "
41 "otherwise the norm of preconditioned RHS is used. "
42 "The default norm is (($L_2$)) norm of preconditioned residual: (($ P^{-1}(Ax-b)$)), usage of other norm may be prescribed using the 'option' key. "
43 "See also PETSc documentation for KSPSetNormType.")
46 "If not, we use the value 1.0e-7."),
47 "Residual tolerance relative to the initial error.")
49 "If not, we use the value 1.0e-11."),
50 "Absolute residual tolerance.")
52 "If not, we use the value 1000."),
53 "Maximum number of outer iterations of the linear solver.")
55 "If the string is left empty (by default), the internal default options is used.")
66 init_guess_nonzero(false),
74 ierr = VecZeroEntries(
rhs_ ); CHKERRV( ierr );
84 :
LinSys(other), params_(other.params_), v_rhs_(NULL), solution_precision_(other.solution_precision_)
130 ASSERT_PERMANENT(
false).error(
"Can not set values. Matrix is not preallocated.\n");
148 ASSERT_PERMANENT(
false).error(
"Can not set values. Matrix is not preallocated.\n");
164 default:
DebugOut() <<
"LS SetValues with non allowed insert mode.\n";
177 ierr = VecSetValues(
rhs_,nrow,
rows,vals,(InsertMode)
status_); CHKERRV( ierr );
181 default:
ASSERT_PERMANENT(
false).error(
"LinSys's status disallow set values.\n");
193 for (i=0; i<nrow; i++) {
195 for(j=0; j<ncol; j++) {
198 VecSetValue(
on_vec_,row,1.0,ADD_VALUES);
200 VecSetValue(
off_vec_,row,1.0,ADD_VALUES);
210 PetscInt *on_nz, *off_nz;
211 PetscScalar *on_array, *off_array;
223 VecGetArray(
on_vec_, &on_array );
224 VecGetArray(
off_vec_, &off_array );
231 VecRestoreArray(
on_vec_,&on_array);
232 VecRestoreArray(
off_vec_,&off_array);
242 0, on_nz, 0, off_nz, &
matrix_); CHKERRV( ierr );
245 MatSetOption(
matrix_, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE);
250 MatSetOption(
matrix_, MAT_IGNORE_ZERO_ENTRIES, PETSC_TRUE);
267 ndofs = cell.get_dof_indices(dof_indices);
270 for (
auto side : cell.side_range())
274 for (
auto edge : side.edge_sides())
276 auto cell_other =
edge.cell();
277 ndofs_other = cell_other.get_dof_indices(dof_indices_other);
284 for (
auto neigh_side : cell.neighb_sides())
286 auto cell_other = neigh_side.cell();
287 ndofs_other = cell_other.get_dof_indices(dof_indices_other);
297 ndofs = cell.get_dof_indices(dof_indices);
298 MatSetValues(
matrix_, ndofs, dof_indices.data(), ndofs, dof_indices.data(), values.
data(), INSERT_VALUES);
300 for (
auto side : cell.side_range())
304 for (
auto edge : side.edge_sides())
306 auto cell_other =
edge.cell();
307 ndofs_other = cell_other.get_dof_indices(dof_indices_other);
308 MatSetValues(
matrix_, ndofs, dof_indices.data(), ndofs_other, dof_indices_other.
data(), values.
data(), INSERT_VALUES);
309 MatSetValues(
matrix_, ndofs_other, dof_indices_other.
data(), ndofs, dof_indices.data(), values.
data(), INSERT_VALUES);
314 for (
auto neigh_side : cell.neighb_sides())
316 auto cell_other = neigh_side.cell();
317 ndofs_other = cell_other.get_dof_indices(dof_indices_other);
318 MatSetValues(
matrix_, ndofs, dof_indices.data(), ndofs_other, dof_indices_other.
data(), values.
data(), INSERT_VALUES);
319 MatSetValues(
matrix_, ndofs_other, dof_indices_other.
data(), ndofs, dof_indices.data(), values.
data(), INSERT_VALUES);
322 MatAssemblyBegin(
matrix_, MAT_FINAL_ASSEMBLY);
323 MatAssemblyEnd(
matrix_, MAT_FINAL_ASSEMBLY);
330 MatAssemblyType assemblyType = MAT_FINAL_ASSEMBLY;
339 WarningOut() <<
"Finalizing linear system without setting values.\n";
342 ierr = MatAssemblyBegin(
matrix_, assembly_type); CHKERRV( ierr );
343 ierr = VecAssemblyBegin(
rhs_); CHKERRV( ierr );
344 ierr = MatAssemblyEnd(
matrix_, assembly_type); CHKERRV( ierr );
345 ierr = VecAssemblyEnd(
rhs_); CHKERRV( ierr );
347 if (assembly_type == MAT_FINAL_ASSEMBLY)
status_ =
DONE;
363 ASSERT_EQ(
status_,
DONE).error(
"System matrix and right-hand side are not assembled when applying constraints." );
366 PetscInt numConstraints =
static_cast<PetscInt
>(
constraints_.size() );
369 const PetscScalar diagScalar =
static_cast<PetscScalar
>( scalar );
375 ConstraintVec_::const_iterator cIter =
constraints_.begin( );
376 ConstraintVec_::const_iterator cEnd =
constraints_.end( );
378 for ( ; cIter != cEnd; ++cIter ) {
379 globalDofs.push_back(
static_cast<PetscInt
>( cIter -> first ) );
380 values.push_back(
static_cast<PetscScalar
>( cIter -> second ) * diagScalar );
388 ierr = MatZeroRows(
matrix_, numConstraints, globalDofPtr, diagScalar, PETSC_NULL, PETSC_NULL ); CHKERRV( ierr );
392 if ( numConstraints ) {
393 ierr = VecSetValues(
rhs_, numConstraints, globalDofPtr, valuePtr, INSERT_VALUES ); CHKERRV( ierr );
398 ierr = VecAssemblyBegin(
rhs_ ); CHKERRV( ierr );
399 ierr = VecAssemblyEnd(
rhs_ ); CHKERRV( ierr );
412 const char *petsc_dflt_opt;
427 petsc_dflt_opt=
"-ksp_type cg -ksp_diagonal_scale -ksp_diagonal_scale_fix -pc_type asm -pc_asm_type basic -pc_asm_overlap 4 -sub_pc_type icc -sub_pc_factor_levels 3 -sub_pc_factor_fill 6.0";
430 petsc_dflt_opt=
"-ksp_type bcgs -ksp_diagonal_scale -ksp_diagonal_scale_fix -pc_type asm -pc_asm_overlap 4 -sub_pc_type ilu -sub_pc_factor_levels 3 -sub_pc_factor_fill 6.0";
436 petsc_dflt_opt=
"-ksp_type cg -pc_type icc -pc_factor_levels 3 -ksp_diagonal_scale -ksp_diagonal_scale_fix -pc_factor_fill 6.0";
439 petsc_dflt_opt=
"-ksp_type bcgs -pc_type ilu -pc_factor_levels 5 -ksp_diagonal_scale -ksp_diagonal_scale_fix -pc_factor_fill 6.0";
443 LogOut().fmt(
"inserting petsc options: {}\n",
params_.c_str());
447 PetscOptionsInsertString(NULL,
params_.c_str());
449 MatSetOption(
matrix_, MAT_USE_INODES, PETSC_FALSE );
458 KSPSetFromOptions(
system);
465 KSPGetType(
system, &type);
466 if (strcmp(type, KSPPREONLY) != 0)
467 KSPSetInitialGuessNonzero(
system, PETSC_TRUE);
475 KSPGetIterationNumber(
system,&nits);
481 LogOut().fmt(
"convergence reason {}, number of iterations is {}\n",
reason, nits);
497 FilePath matFileName(text +
"_flow123d_matrix.m",FilePath::FileType::output_file);
498 FilePath rhsFileName(text +
"_flow123d_rhs.m",FilePath::FileType::output_file);
499 FilePath solFileName(text +
"_flow123d_sol.m",FilePath::FileType::output_file);
501 PetscViewer myViewer;
504 PetscViewerASCIIOpen(
comm_,((
string)matFileName).c_str(),&myViewer);
505 PetscViewerSetFormat(myViewer,PETSC_VIEWER_ASCII_MATLAB);
507 PetscViewerDestroy(&myViewer);
510 WarningOut() <<
"PetscViewer: the matrix of LinSys is not set.\n";
512 if (
rhs_ != NULL ) {
513 PetscViewerASCIIOpen(
comm_,((
string)rhsFileName).c_str(),&myViewer);
514 PetscViewerSetFormat(myViewer,PETSC_VIEWER_ASCII_MATLAB);
515 VecView(
rhs_, myViewer );
516 PetscViewerDestroy(&myViewer);
519 WarningOut() <<
"PetscViewer: the rhs of LinSys is not set.\n";
522 PetscViewerASCIIOpen(
comm_,((
string)solFileName).c_str(),&myViewer);
523 PetscViewerSetFormat(myViewer,PETSC_VIEWER_ASCII_MATLAB);
525 PetscViewerDestroy(&myViewer);
528 WarningOut() <<
"PetscViewer: the solution of LinSys is not set.\n";
549 std::string user_params = in_rec.
val<
string>(
"options");
550 if (user_params !=
"")
params_ = user_params;
564 double residual_norm;
565 VecNorm(
residual_, NORM_2, &residual_norm);
566 return residual_norm;