6#ifndef PRECICE_NO_PETSC
17#include "petscdrawtypes.h"
20#include "petscsystypes.h"
22#include "petscviewertypes.h"
23#include "precice/impl/versions.hpp"
33#ifndef PRECICE_NO_PETSC
42#ifndef PRECICE_NO_PETSC
43 PetscBool petscIsInitialized;
44 PetscInitialized(&petscIsInitialized);
45 if (not petscIsInitialized) {
46 PETSC_COMM_WORLD = comm;
48 PetscOptionsSetValue(
nullptr,
"-no_signal_handler",
nullptr);
51 char **argv =
nullptr;
52 ierr = PetscInitialize(&argc, &argv,
"",
nullptr);
61#ifndef PRECICE_NO_PETSC
65 PetscBool petscIsInitialized;
66 PetscInitialized(&petscIsInitialized);
67 if (petscIsInitialized) {
68 PetscOptionsSetValue(
nullptr,
"-options_left",
"no");
75#ifndef PRECICE_NO_PETSC
80#include "petscviewer.h"
87 PetscErrorCode ierr = 0;
88 if (format ==
ASCII) {
89 ierr = PetscViewerASCIIOpen(comm, filename.c_str(), &
viewer);
91 }
else if (format ==
BINARY) {
92 ierr = PetscViewerBinaryOpen(comm, filename.c_str(), FILE_MODE_WRITE, &
viewer);
100 PetscErrorCode ierr = 0;
101 ierr = PetscViewerCreate(comm, &
viewer);
103 ierr = PetscViewerSetType(
viewer, PETSCVIEWERASCII);
110 PetscViewerPopFormat(
viewer);
112 PetscViewerDestroy(&
viewer);
117 auto ierr = PetscViewerPushFormat(
viewer, format);
130 PetscObjectGetComm(
reinterpret_cast<PetscObject
>(obj), &comm);
137 PetscErrorCode ierr = 0;
138 ierr = PetscObjectSetName(
reinterpret_cast<PetscObject
>(obj), name.c_str());
146 PetscObjectGetName(
reinterpret_cast<PetscObject
>(obj), &cstr);
154 PetscErrorCode ierr = 0;
172 other.vector =
nullptr;
185 PetscErrorCode ierr = 0;
199 PetscErrorCode ierr = 0;
200 PetscBool petscIsInitialized;
201 PetscInitialized(&petscIsInitialized);
202 if (petscIsInitialized &&
vector)
203 ierr = VecDestroy(&
vector);
220 PetscErrorCode ierr = 0;
221 ierr = VecDuplicate(other, &newvector);
222 [&] { CHKERRV(ierr); }();
223 return Vector{newvector, name};
235 PetscErrorCode ierr = 0;
237 ierr = MatCreateVecs(m,
nullptr, &newvector);
239 ierr = MatCreateVecs(m, &newvector,
nullptr);
241 [&] { CHKERRV(ierr); }();
242 return Vector{newvector, name};
251Vector::operator Vec &()
258 PetscErrorCode ierr = 0;
259 ierr = VecSetSizes(
vector, PETSC_DECIDE, rows);
261 ierr = VecSetFromOptions(
vector);
267 PetscErrorCode ierr = 0;
269 ierr = VecGetSize(
vector, &size);
276 PetscErrorCode ierr = 0;
278 ierr = VecGetLocalSize(
vector, &size);
285 PetscErrorCode ierr = 0;
286 ierr = VecSetValue(
vector, row, value, INSERT_VALUES);
292 PetscErrorCode ierr = 0;
294 PetscInt range_start, range_end, size;
295 VecGetSize(
vector, &size);
296 VecGetOwnershipRange(
vector, &range_start, &range_end);
297 double step_size = (stop - start) / size;
298 ierr = VecGetArray(
vector, &a);
300 for (PetscInt i = range_start; i < range_end; i++) {
301 a[i - range_start] = (i + start) * step_size;
303 VecRestoreArray(
vector, &a);
308 PetscErrorCode ierr = 0;
311 std::random_device rd;
312 std::uniform_real_distribution<double> dist(0, 1);
315 PetscRandomSetType(rctx, PETSCRAND48);
316 PetscRandomSetSeed(rctx, dist(rd));
317 PetscRandomSeed(rctx);
318 ierr = VecSetRandom(
vector, rctx);
320 PetscRandomDestroy(&rctx);
331 PetscErrorCode ierr = 0;
332 ierr = VecGetArray(
vector, &data);
334 std::copy(source.
begin(), source.
end(), data);
335 ierr = VecRestoreArray(
vector, &data);
349 PetscErrorCode ierr = 0;
350 ierr = VecGetArray(
vector, &data);
352 auto dataEnd = std::next(data, localSize);
353 std::copy(data, dataEnd, destination.
begin());
354 ierr = VecRestoreArray(
vector, &data);
361 PetscErrorCode ierr = 0;
364 ierr = VecGetArray(
vector, &a);
366 ierr = VecGetSize(
vector, &size);
368 ierr = PetscSortReal(size, a);
370 ierr = VecRestoreArray(
vector, &a);
376 PetscErrorCode ierr = 0;
377 ierr = VecAssemblyBegin(
vector);
379 ierr = VecAssemblyEnd(
vector);
385 PetscInt range_start, range_end;
386 VecGetOwnershipRange(
vector, &range_start, &range_end);
387 return std::make_pair(range_start, range_end);
399 VecNorm(
vector, NORM_2, &val);
412 ierr = VecView(
vector, PETSC_VIEWER_STDOUT_WORLD);
425 PetscErrorCode ierr = 0;
433 PetscErrorCode ierr = 0;
434 PetscBool petscIsInitialized;
435 PetscInitialized(&petscIsInitialized);
436 if (petscIsInitialized &&
matrix)
437 ierr = MatDestroy(&
matrix);
441Matrix::operator Mat &()
448 PetscErrorCode ierr = 0;
449 ierr = MatAssemblyBegin(
matrix, type);
451 ierr = MatAssemblyEnd(
matrix, type);
455void Matrix::init(PetscInt localRows, PetscInt localCols, PetscInt globalRows, PetscInt globalCols,
456 MatType type,
bool doSetup)
458 PetscErrorCode ierr = 0;
459 if (type !=
nullptr) {
460 ierr = MatSetType(
matrix, type);
463 ierr = MatSetSizes(
matrix, localRows, localCols, globalRows, globalCols);
465 ierr = MatSetFromOptions(
matrix);
474 PetscErrorCode ierr = 0;
476 ierr = MatDestroy(&
matrix);
486 MatGetInfo(
matrix, flag, &info);
492 PetscErrorCode ierr = 0;
493 ierr = MatSetValue(
matrix, row, col, value, INSERT_VALUES);
499 PetscErrorCode ierr = 0;
502 std::random_device rd;
503 std::uniform_real_distribution<double> dist(0, 1);
506 PetscRandomSetType(rctx, PETSCRAND48);
507 PetscRandomSetSeed(rctx, dist(rd));
508 PetscRandomSeed(rctx);
509 ierr = MatSetRandom(
matrix, rctx);
511 PetscRandomDestroy(&rctx);
516 PetscErrorCode ierr = 0;
517 const PetscScalar *vec;
518 PetscInt range_start, range_end;
519 VecGetOwnershipRange(v.
vector, &range_start, &range_end);
520 std::vector<PetscInt> irow(range_end - range_start);
521 std::iota(irow.begin(), irow.end(), range_start);
523 ierr = VecGetArrayRead(v.
vector, &vec);
525 ierr = MatSetValues(
matrix, range_end - range_start, irow.data(), 1, &col, vec, INSERT_VALUES);
527 ierr = VecRestoreArrayRead(v.
vector, &vec);
529 ierr = MatAssemblyBegin(
matrix, MAT_FINAL_ASSEMBLY);
531 ierr = MatAssemblyEnd(
matrix, MAT_FINAL_ASSEMBLY);
538 MatGetSize(
matrix, &m, &n);
539 return std::make_pair(m, n);
545 MatGetLocalSize(
matrix, &m, &n);
546 return std::make_pair(m, n);
551 PetscInt range_start, range_end;
552 MatGetOwnershipRange(
matrix, &range_start, &range_end);
553 return std::make_pair(range_start, range_end);
558 PetscInt range_start, range_end;
559 MatGetOwnershipRangeColumn(
matrix, &range_start, &range_end);
560 return std::make_pair(range_start, range_end);
565 PetscErrorCode ierr = 0;
567 ierr = MatGetBlockSize(
matrix, &bs);
574 PetscErrorCode ierr = 0;
582 PetscErrorCode ierr = 0;
606 ierr = PetscViewerDrawGetDraw(viewer.
viewer, 0, &draw);
608 ierr = PetscDrawSetPause(draw, -1);
616 PetscErrorCode ierr = 0;
624 PetscErrorCode ierr = 0;
625 PetscBool petscIsInitialized;
626 PetscInitialized(&petscIsInitialized);
627 if (petscIsInitialized &&
ksp)
628 ierr = KSPDestroy(&
ksp);
632KSPSolver::operator KSP &()
639 PetscErrorCode ierr = 0;
640 ierr = KSPReset(
ksp);
646 KSPConvergedReason convReason;
647 PetscErrorCode ierr = 0;
648 ierr = KSPGetConvergedReason(
ksp, &convReason);
652 if (convReason > 0) {
655 if (convReason == KSP_DIVERGED_ITS) {
670 KSPSolveTranspose(
ksp, b, x);
678 KSPConvergedReason convReason;
679 KSPGetConvergedReason(
ksp, &convReason);
681 PetscReal rtol, atol, dtol;
683 KSPGetTolerances(
ksp, &rtol, &atol, &dtol, &miter);
685 std::ostringstream oss;
687 bool converged = (convReason >= 0);
688 bool stopped = (convReason == KSP_DIVERGED_ITS);
689 oss <<
"Solver " << (converged ?
"converged" : (stopped ?
"stopped" :
"diverged"));
693 switch (convReason) {
694 case (KSP_CONVERGED_RTOL):
695#if (PETSC_MAJOR == 3) && (PETSC_MINOR < 24)
696 case (KSP_CONVERGED_RTOL_NORMAL):
698 case (KSP_CONVERGED_RTOL_NORMAL_EQUATIONS):
700 oss <<
" sufficient relative convergence";
702 case (KSP_CONVERGED_ATOL):
703#if (PETSC_MAJOR == 3) && (PETSC_MINOR < 24)
704 case (KSP_CONVERGED_ATOL_NORMAL):
706 case (KSP_CONVERGED_ATOL_NORMAL_EQUATIONS):
708 oss <<
" sufficient absolute convergence";
710 case (KSP_DIVERGED_ITS):
711 oss <<
" reaching the maximum iterations";
713 case (KSP_DIVERGED_DTOL):
714 oss <<
" sufficient divergence";
716 case (KSP_DIVERGED_NANORINF):
717 oss <<
" the residual norm becoming nan or inf";
719 case (KSP_DIVERGED_BREAKDOWN):
720 oss <<
" a generic breakdown of the method";
723 oss <<
" the PETSc reason " << KSPConvergedReasons[convReason];
727 double bnorm = b.
l2norm();
728 double dlim = bnorm * dtol;
729 double rlim = bnorm * rtol;
731 oss <<
". Last residual norm: " <<
getResidualNorm() <<
", limits: relative " << rlim <<
" (rtol " << rtol <<
"), absolute " << atol <<
", divergence " << dlim <<
"(dtol " << dtol <<
')';
738 PetscErrorCode ierr = 0;
740 ierr = KSPGetIterationNumber(
ksp, &its);
747 PetscErrorCode ierr = 0;
749 ierr = KSPGetResidualNorm(
ksp, &val);
756 PetscErrorCode ierr = 0;
758 ierr = KSPGetTolerances(
ksp, &rtol,
nullptr,
nullptr,
nullptr);
767 PetscErrorCode ierr = 0;
768 PetscBool petscIsInitialized;
769 PetscInitialized(&petscIsInitialized);
771 if (IS and petscIsInitialized) {
772 ierr = ISLocalToGlobalMappingDestroy(IS);
779 PetscErrorCode ierr = 0;
780 PetscBool petscIsInitialized;
781 PetscInitialized(&petscIsInitialized);
783 if (ao and petscIsInitialized) {
784 ierr = AODestroy(ao);
#define PRECICE_TRACE(...)
int MPI_Comm_size(MPI_Comm comm, int *size)
#define PRECICE_ASSERT(...)
A C++ 11 implementation of the non-owning C++20 std::span type.
constexpr iterator begin() const noexcept
constexpr iterator end() const noexcept
constexpr size_type size() const noexcept
static CommStatePtr current()
Returns an owning pointer to the current CommState.
static bool weInitialized
Whether we have initialized Petsc or if it was initialized by an application calling us.
static void finalize()
Finalizes Petsc environment.
static void initialize(utils::Parallel::Communicator comm)
Initializes the Petsc environment.
static logging::Logger _log
SolverResult getSolverResult()
Returns the current convergence reason as a SolverRestult.
PetscReal getRealtiveTolerance()
Returns the relavtive tolerance of the KSP.
std::string summaryFor(Vector &b)
Returns a summary the KSP solving for b.
SolverResult solveTranspose(Vector &b, Vector &x)
Solves the transposed linear system, returns false it not converged.
void reset()
Destroys and recreates the ksp on the same communicator.
KSPSolver(const KSPSolver &)=delete
Delete copy and assignment constructor.
PetscReal getResidualNorm()
Returns the last residual norm of the KSP.
PetscInt getIterationNumber()
Returns the iteration number of solver, either during or after the solve call.
SolverResult solve(Vector &b, Vector &x)
Solves the linear system, returns false it not converged.
SolverResult
The state of the KSP after returning from solve()
@ Diverged
The solver diverged.
@ Stopped
The solver reached the maximum iterations.
@ Converged
The solver converged.
void setColumn(Vector &v, PetscInt col)
void read(const std::string &filename)
Reads the matrix from file, stored in PETSc binary format.
void write(const std::string &filename, VIEWERFORMAT format=ASCII) const
Writes the matrix to file.
void assemble(MatAssemblyType type=MAT_FINAL_ASSEMBLY)
void view() const
Prints the matrix.
std::pair< PetscInt, PetscInt > getSize() const
Returns (rows, cols) global size.
void setValue(PetscInt row, PetscInt col, PetscScalar value)
void viewDraw() const
Graphically draws the matrix structure.
void init(PetscInt localRows, PetscInt localCols, PetscInt globalRows, PetscInt globalCols, MatType type=nullptr, bool doSetup=true)
Initializes matrix of given size and type.
std::pair< PetscInt, PetscInt > ownerRange() const
Returns a pair that mark the beginning and end of the matrix' ownership range.
PetscInt blockSize() const
Returns the block size of the matrix.
void reset()
Destroys and recreates the matrix on the same communicator.
Matrix(const Matrix &)=delete
Delete copy and assignment constructor.
std::pair< PetscInt, PetscInt > getLocalSize() const
Returns (rows, cols) local size.
MatInfo getInfo(MatInfoType flag) const
Get the MatInfo struct for the matrix.
std::pair< PetscInt, PetscInt > ownerRangeColumn() const
Returns a pair that mark the beginning and end of the matrix' column ownership range.
Vector & copyTo(precice::span< double > destination)
double l2norm() const
returns the l2-norm of the vector
PetscInt getLocalSize() const
void arange(double start, double stop)
void read(const std::string &filename, VIEWERFORMAT format=ASCII)
Reads the vector from file.
void setValue(PetscInt row, PetscScalar value)
void sort()
Sorts the LOCAL partition of the vector.
static Vector allocate(const std::string &name="")
Allocates a new vector on the given MPI communicator.
Vector & copyFrom(precice::span< const double > source)
void view() const
Prints the vector.
std::pair< PetscInt, PetscInt > ownerRange() const
Returns a pair that mark the beginning and end of the vectors ownership range. Use first and second t...
void write(const std::string &filename, VIEWERFORMAT format=ASCII) const
Writes the vector to file.
static logging::Logger _log
void swap(Vector &other) noexcept
Swaps the ownership of two vectors.
Vector & operator=(const Vector &other)
Vector(const std::string &name="")
Creates a new vector on the given MPI communicator.
void init(PetscInt rows)
Sets the size and calls VecSetFromOptions.
void setName(T obj, const std::string &name)
std::string getName(T obj)
MPI_Comm getCommunicator(T obj)
void destroy(ISLocalToGlobalMapping *IS)
Destroys an ISLocalToGlobalMapping, if IS is not null and PetscIsInitialized.
void swap(Vector &lhs, Vector &rhs) noexcept
contains precice-related utilities.
Viewer(const std::string &filename, VIEWERFORMAT format, MPI_Comm comm)
void pushFormat(PetscViewerFormat format)
Viewer(PetscViewerType type, MPI_Comm comm)