6#ifndef PRECICE_NO_PETSC
17#include "petscdrawtypes.h"
20#include "petscsystypes.h"
22#include "petscviewertypes.h"
30#ifndef PRECICE_NO_PETSC
34using new_signature = PetscErrorCode(PetscOptions,
const char[],
const char[]);
35using old_signature = PetscErrorCode(
const char[],
const char[]);
44template <
typename curr_signature = decltype(PetscOptionsSetValue)>
45PetscErrorCode PetscOptionsSetValueWrapper(
const char name[],
const char value[],
49 return PetscOptionsSetValueImpl(
nullptr,
name, value);
59template <
typename curr_signature = decltype(PetscOptionsSetValue)>
60PetscErrorCode PetscOptionsSetValueWrapper(
const char name[],
const char value[],
64 return PetscOptionsSetValueImpl(
name, value);
72#ifndef PRECICE_NO_PETSC
81#ifndef PRECICE_NO_PETSC
82 PetscBool petscIsInitialized;
83 PetscInitialized(&petscIsInitialized);
84 if (not petscIsInitialized) {
85 PETSC_COMM_WORLD = comm;
87 PetscOptionsSetValue(
nullptr,
"-no_signal_handler",
nullptr);
90 char ** argv =
nullptr;
91 ierr = PetscInitialize(&argc, &argv,
"",
nullptr);
100#ifndef PRECICE_NO_PETSC
104 PetscBool petscIsInitialized;
105 PetscInitialized(&petscIsInitialized);
106 if (petscIsInitialized) {
107 PetscOptionsSetValueWrapper(
"-options_left",
"no");
114#ifndef PRECICE_NO_PETSC
118#include "petscdraw.h"
119#include "petscviewer.h"
126 PetscErrorCode ierr = 0;
127 if (format ==
ASCII) {
128 ierr = PetscViewerASCIIOpen(comm, filename.
c_str(), &
viewer);
130 }
else if (format ==
BINARY) {
131 ierr = PetscViewerBinaryOpen(comm, filename.
c_str(), FILE_MODE_WRITE, &
viewer);
139 PetscErrorCode ierr = 0;
140 ierr = PetscViewerCreate(comm, &
viewer);
142 ierr = PetscViewerSetType(
viewer, PETSCVIEWERASCII);
149 PetscViewerPopFormat(
viewer);
151 PetscViewerDestroy(&
viewer);
156 auto ierr = PetscViewerPushFormat(
viewer, format);
169 PetscObjectGetComm(
reinterpret_cast<PetscObject
>(obj), &comm);
176 PetscErrorCode ierr = 0;
177 ierr = PetscObjectSetName(
reinterpret_cast<PetscObject
>(obj),
name.
c_str());
185 PetscObjectGetName(
reinterpret_cast<PetscObject
>(obj), &cstr);
193 PetscErrorCode ierr = 0;
210 vector = other.vector;
211 other.vector =
nullptr;
224 PetscErrorCode ierr = 0;
238 PetscErrorCode ierr = 0;
239 PetscBool petscIsInitialized;
240 PetscInitialized(&petscIsInitialized);
241 if (petscIsInitialized &&
vector)
242 ierr = VecDestroy(&
vector);
259 PetscErrorCode ierr = 0;
260 ierr = VecDuplicate(other, &newvector);
261 [&] { CHKERRV(ierr); }();
274 PetscErrorCode ierr = 0;
276 ierr = MatCreateVecs(m,
nullptr, &newvector);
278 ierr = MatCreateVecs(m, &newvector,
nullptr);
280 [&] { CHKERRV(ierr); }();
287 swap(vector, other.vector);
290Vector::operator Vec &()
297 PetscErrorCode ierr = 0;
298 ierr = VecSetSizes(
vector, PETSC_DECIDE, rows);
300 ierr = VecSetFromOptions(
vector);
306 PetscErrorCode ierr = 0;
308 ierr = VecGetSize(
vector, &size);
315 PetscErrorCode ierr = 0;
317 ierr = VecGetLocalSize(
vector, &size);
324 PetscErrorCode ierr = 0;
325 ierr = VecSetValue(
vector, row, value, INSERT_VALUES);
331 PetscErrorCode ierr = 0;
333 PetscInt range_start, range_end, size;
334 VecGetSize(
vector, &size);
335 VecGetOwnershipRange(
vector, &range_start, &range_end);
336 double step_size = (stop - start) / size;
337 ierr = VecGetArray(
vector, &a);
339 for (PetscInt i = range_start; i < range_end; i++) {
340 a[i - range_start] = (i + start) * step_size;
342 VecRestoreArray(
vector, &a);
347 PetscErrorCode ierr = 0;
354 PetscRandomSetType(rctx, PETSCRAND48);
355 PetscRandomSetSeed(rctx, dist(rd));
356 PetscRandomSeed(rctx);
357 ierr = VecSetRandom(
vector, rctx);
359 PetscRandomDestroy(&rctx);
370 PetscErrorCode ierr = 0;
371 ierr = VecGetArray(
vector, &data);
374 ierr = VecRestoreArray(
vector, &data);
388 PetscErrorCode ierr = 0;
389 ierr = VecGetArray(
vector, &data);
391 auto dataEnd =
std::next(data, localSize);
393 ierr = VecRestoreArray(
vector, &data);
400 PetscErrorCode ierr = 0;
403 ierr = VecGetArray(
vector, &a);
405 ierr = VecGetSize(
vector, &size);
407 ierr = PetscSortReal(size, a);
409 ierr = VecRestoreArray(
vector, &a);
415 PetscErrorCode ierr = 0;
416 ierr = VecAssemblyBegin(
vector);
418 ierr = VecAssemblyEnd(
vector);
424 PetscInt range_start, range_end;
425 VecGetOwnershipRange(
vector, &range_start, &range_end);
432 VecView(
vector, viewer.viewer);
438 VecNorm(
vector, NORM_2, &val);
445 VecLoad(
vector, viewer.viewer);
451 ierr = VecView(
vector, PETSC_VIEWER_STDOUT_WORLD);
464 PetscErrorCode ierr = 0;
472 PetscErrorCode ierr = 0;
473 PetscBool petscIsInitialized;
474 PetscInitialized(&petscIsInitialized);
475 if (petscIsInitialized &&
matrix)
476 ierr = MatDestroy(&
matrix);
480Matrix::operator Mat &()
487 PetscErrorCode ierr = 0;
488 ierr = MatAssemblyBegin(
matrix, type);
490 ierr = MatAssemblyEnd(
matrix, type);
494void Matrix::init(PetscInt localRows, PetscInt localCols, PetscInt globalRows, PetscInt globalCols,
495 MatType type,
bool doSetup)
497 PetscErrorCode ierr = 0;
498 if (type !=
nullptr) {
499 ierr = MatSetType(
matrix, type);
502 ierr = MatSetSizes(
matrix, localRows, localCols, globalRows, globalCols);
504 ierr = MatSetFromOptions(
matrix);
513 PetscErrorCode ierr = 0;
515 ierr = MatDestroy(&
matrix);
525 MatGetInfo(
matrix, flag, &info);
531 PetscErrorCode ierr = 0;
532 ierr = MatSetValue(
matrix, row, col, value, INSERT_VALUES);
538 PetscErrorCode ierr = 0;
545 PetscRandomSetType(rctx, PETSCRAND48);
546 PetscRandomSetSeed(rctx, dist(rd));
547 PetscRandomSeed(rctx);
548 ierr = MatSetRandom(
matrix, rctx);
550 PetscRandomDestroy(&rctx);
555 PetscErrorCode ierr = 0;
556 const PetscScalar *vec;
557 PetscInt range_start, range_end;
558 VecGetOwnershipRange(v.
vector, &range_start, &range_end);
562 ierr = VecGetArrayRead(v.
vector, &vec);
564 ierr = MatSetValues(
matrix, range_end - range_start, irow.
data(), 1, &col, vec, INSERT_VALUES);
566 ierr = VecRestoreArrayRead(v.
vector, &vec);
568 ierr = MatAssemblyBegin(
matrix, MAT_FINAL_ASSEMBLY);
570 ierr = MatAssemblyEnd(
matrix, MAT_FINAL_ASSEMBLY);
577 MatGetSize(
matrix, &m, &n);
584 MatGetLocalSize(
matrix, &m, &n);
590 PetscInt range_start, range_end;
591 MatGetOwnershipRange(
matrix, &range_start, &range_end);
597 PetscInt range_start, range_end;
598 MatGetOwnershipRangeColumn(
matrix, &range_start, &range_end);
604 PetscErrorCode ierr = 0;
606 ierr = MatGetBlockSize(
matrix, &bs);
613 PetscErrorCode ierr = 0;
615 ierr = MatView(
matrix, viewer.viewer);
621 PetscErrorCode ierr = 0;
623 ierr = MatLoad(
matrix, viewer.viewer);
630 viewer.pushFormat(PETSC_VIEWER_ASCII_DENSE);
631 PetscErrorCode ierr = MatView(
matrix, viewer.viewer);
638 viewer.pushFormat(PETSC_VIEWER_ASCII_DENSE);
639 PetscErrorCode ierr = MatView(
matrix, viewer.viewer);
641 ierr = MatView(
matrix, viewer.viewer);
645 ierr = PetscViewerDrawGetDraw(viewer.viewer, 0, &draw);
647 ierr = PetscDrawSetPause(draw, -1);
655 PetscErrorCode ierr = 0;
663 PetscErrorCode ierr = 0;
664 PetscBool petscIsInitialized;
665 PetscInitialized(&petscIsInitialized);
666 if (petscIsInitialized &&
ksp)
667 ierr = KSPDestroy(&
ksp);
671KSPSolver::operator KSP &()
678 PetscErrorCode ierr = 0;
679 ierr = KSPReset(
ksp);
685 KSPConvergedReason convReason;
686 PetscErrorCode ierr = 0;
687 ierr = KSPGetConvergedReason(
ksp, &convReason);
691 if (convReason > 0) {
694 if (convReason == KSP_DIVERGED_ITS) {
709 KSPSolveTranspose(
ksp, b, x);
717 KSPConvergedReason convReason;
718 KSPGetConvergedReason(
ksp, &convReason);
720 PetscReal rtol, atol, dtol;
722 KSPGetTolerances(
ksp, &rtol, &atol, &dtol, &miter);
726 bool converged = (convReason >= 0);
727 bool stopped = (convReason == KSP_DIVERGED_ITS);
728 oss <<
"Solver " << (converged ?
"converged" : (stopped ?
"stopped" :
"diverged"));
732 switch (convReason) {
733 case (KSP_CONVERGED_RTOL):
734 case (KSP_CONVERGED_RTOL_NORMAL):
735 oss <<
" sufficient relative convergence";
737 case (KSP_CONVERGED_ATOL):
738 case (KSP_CONVERGED_ATOL_NORMAL):
739 oss <<
" sufficient absolute convergence";
741 case (KSP_DIVERGED_ITS):
742 oss <<
" reaching the maximum iterations";
744 case (KSP_DIVERGED_DTOL):
745 oss <<
" sufficient divergence";
747 case (KSP_DIVERGED_NANORINF):
748 oss <<
" the residual norm becoming nan or inf";
750 case (KSP_DIVERGED_BREAKDOWN):
751 oss <<
" a generic breakdown of the method";
754 oss <<
" the PETSc reason " << KSPConvergedReasons[convReason];
758 double bnorm = b.
l2norm();
759 double dlim = bnorm * dtol;
760 double rlim = bnorm * rtol;
762 oss <<
". Last residual norm: " <<
getResidualNorm() <<
", limits: relative " << rlim <<
" (rtol " << rtol <<
"), absolute " << atol <<
", divergence " << dlim <<
"(dtol " << dtol <<
')';
769 PetscErrorCode ierr = 0;
771 ierr = KSPGetIterationNumber(
ksp, &its);
778 PetscErrorCode ierr = 0;
780 ierr = KSPGetResidualNorm(
ksp, &val);
787 PetscErrorCode ierr = 0;
789 ierr = KSPGetTolerances(
ksp, &rtol,
nullptr,
nullptr,
nullptr);
798 PetscErrorCode ierr = 0;
799 PetscBool petscIsInitialized;
800 PetscInitialized(&petscIsInitialized);
802 if (IS and petscIsInitialized) {
803 ierr = ISLocalToGlobalMappingDestroy(IS);
810 PetscErrorCode ierr = 0;
811 PetscBool petscIsInitialized;
812 PetscInitialized(&petscIsInitialized);
814 if (ao and petscIsInitialized) {
815 ierr = AODestroy(ao);
#define PRECICE_TRACE(...)
int MPI_Comm_size(MPI_Comm comm, int *size)
#define PRECICE_ASSERT(...)
This class provides a lightweight logger.
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)