21#ifndef LIBMESH_PETSC_VECTOR_H
22#define LIBMESH_PETSC_VECTOR_H
25#include "libmesh/libmesh_config.h"
27#ifdef LIBMESH_HAVE_PETSC
30#include "libmesh/numeric_vector.h"
31#include "libmesh/petsc_macro.h"
32#include "libmesh/int_range.h"
33#include "libmesh/libmesh_common.h"
34#include "libmesh/petsc_solver_exception.h"
35#include "libmesh/parallel_only.h"
36#include "libmesh/enum_to_string.h"
51#include <unordered_map>
56#include <condition_variable>
62template <
typename T>
class SparseMatrix;
109 const std::vector<numeric_index_type> & ghost,
148 virtual void clear () noexcept override;
158 const
bool fast=false,
162 const
bool fast=false,
168 const
bool fast = false,
172 const
bool fast = false) override;
184 virtual T
sum () const override;
212 T * values) const override;
247 const T
value) override;
250 const T
value) override;
252 virtual
void add (const T s) override;
288 virtual
void insert (const T * v,
291 virtual
void scale (const T factor) override;
297 virtual
void abs() override;
308 virtual
void localize (
std::vector<T> & v_local) const override;
331 virtual
void print_matlab(const
std::
string & name = "") const override;
335 bool supplying_global_rows = true) const override;
353 virtual std::unique_ptr<NumericVector<T>>
354 get_subvector(
const std::vector<numeric_index_type> & rows)
override;
357 const std::vector<numeric_index_type> & rows)
override;
371#ifdef LIBMESH_HAVE_CXX11_THREAD
479 template <NormType N>
Real norm ()
const;
492 _array_is_present(false),
496 _local_form(nullptr),
497 _read_only_values(nullptr),
499 _global_to_local_map(),
500 _destroy_vec_on_exit(true),
501 _values_manually_retrieved(false),
502 _values_read_only(false)
516 _array_is_present(false),
520 _local_form(nullptr),
521 _read_only_values(nullptr),
523 _global_to_local_map(),
524 _destroy_vec_on_exit(true),
525 _values_manually_retrieved(false),
526 _values_read_only(false)
528 this->
init(n, n,
false, ptype);
541 _array_is_present(false),
545 _local_form(nullptr),
546 _read_only_values(nullptr),
548 _global_to_local_map(),
549 _destroy_vec_on_exit(true),
550 _values_manually_retrieved(false),
551 _values_read_only(false)
553 this->
init(n, n_local,
false, ptype);
563 const std::vector<numeric_index_type> & ghost,
567 _array_is_present(false),
571 _local_form(nullptr),
572 _read_only_values(nullptr),
574 _global_to_local_map(),
575 _destroy_vec_on_exit(true),
576 _values_manually_retrieved(false),
577 _values_read_only(false)
579 this->
init(n, n_local, ghost,
false, ptype);
592 _array_is_present(false),
596 _local_form(nullptr),
597 _read_only_values(nullptr),
599 _global_to_local_map(),
600 _destroy_vec_on_exit(false),
601 _values_manually_retrieved(false),
602 _values_read_only(false)
609 PetscInt petsc_local_size=0;
610 LibmeshPetscCall(VecGetLocalSize(
_vec, &petsc_local_size));
614 LibmeshPetscCall(VecGetType(
_vec, &ptype));
618 PetscInt petsc_global_size = 0;
619 LibmeshPetscCall(VecGetSize(
_vec, &petsc_global_size));
624 bool is_serial = (petsc_local_size == petsc_global_size);
625 comm_in.
min(is_serial);
629 comm_in.
sum(sum_of_local_sizes);
630 libmesh_assert_equal_to(sum_of_local_sizes,
631 cast_int<dof_id_type>(petsc_global_size));
634#if PETSC_RELEASE_GREATER_EQUALS(3, 21, 0)
636 if (std::strcmp(ptype, VECMPI) == 0)
639 LibmeshPetscCall(VecGhostGetGhostIS(
_vec, &ghostis));
642 LibmeshPetscCall(VecGhostGetLocalForm(
_vec, &localrep));
647 if (ghostis && localrep)
650 LibmeshPetscCall(ISGetSize(ghostis, &ghost_size));
652 const PetscInt * indices;
653 LibmeshPetscCall(ISGetIndices(ghostis, &indices));
658 LibmeshPetscCall(ISRestoreIndices(ghostis, &indices));
668 ISLocalToGlobalMapping mapping =
nullptr;
669 Vec localrep =
nullptr;
673 if (std::strcmp(ptype, VECMPI) == 0)
675 LibmeshPetscCall(VecGetLocalToGlobalMapping(
_vec, &mapping));
676 LibmeshPetscCall(VecGhostGetLocalForm(
_vec,&localrep));
682 if (mapping && localrep)
687 LibmeshPetscCall(ISLocalToGlobalMappingGetSize(mapping, &n));
690 const PetscInt * indices;
691 LibmeshPetscCall(ISLocalToGlobalMappingGetIndices(mapping,&indices));
696 LibmeshPetscCall(ISLocalToGlobalMappingRestoreIndices(mapping, &indices));
701 LibmeshPetscCall(VecGhostRestoreLocalForm(
_vec,&localrep));
726 parallel_object_only();
728 PetscInt petsc_n=
static_cast<PetscInt
>(n);
746 (this->n_processors()==1 && n==n_local) ||
750 if (this->_type ==
SERIAL || (this->n_processors() == 1))
752 LibmeshPetscCallA(PETSC_COMM_SELF, VecCreate(PETSC_COMM_SELF, &_vec));
753 LibmeshPetscCallA(PETSC_COMM_SELF, VecSetSizes(_vec, petsc_n, petsc_n));
754 LibmeshPetscCallA(PETSC_COMM_SELF, VecSetFromOptions (_vec));
759#ifdef LIBMESH_HAVE_MPI
760 PetscInt petsc_n_local=cast_int<PetscInt>(n_local);
761 libmesh_assert_less_equal (n_local, n);
763 LibmeshPetscCall(VecCreate(this->comm().get(), &_vec));
764 LibmeshPetscCall(VecSetSizes(_vec, petsc_n_local, petsc_n));
766 libmesh_assert_equal_to (n_local, n);
767 LibmeshPetscCallA(PETSC_COMM_SELF, VecCreate(PETSC_COMM_SELF, &_vec));
768 LibmeshPetscCallA(PETSC_COMM_SELF, VecSetSizes(_vec, petsc_n, petsc_n));
770 LibmeshPetscCall(VecSetFromOptions(_vec));
774 libmesh_error_msg(
"Unsupported type " <<
776 " for parallel init with no ghost indices supplied");
778 this->_is_initialized =
true;
779 this->_is_closed =
true;
794 this->init(n,n,fast,ptype);
803 const std::vector<numeric_index_type> & ghost,
807 parallel_object_only();
809 if (this->comm().size() == 1)
812 this->init(n, n_local, fast, ptype);
816 PetscInt petsc_n=
static_cast<PetscInt
>(n);
817 PetscInt petsc_n_local=
static_cast<PetscInt
>(n_local);
818 PetscInt petsc_n_ghost=
static_cast<PetscInt
>(ghost.size());
833 PetscInt * petsc_ghost = ghost.empty() ? LIBMESH_PETSC_NULLPTR :
834 const_cast<PetscInt *
>(
reinterpret_cast<const PetscInt *
>(ghost.data()));
846 _global_to_local_map[ghost[i]] = i;
850 LibmeshPetscCall(VecCreateGhost (this->comm().get(), petsc_n_local, petsc_n,
851 petsc_n_ghost, petsc_ghost,
858 LibmeshPetscCall(PetscObjectAppendOptionsPrefix((PetscObject)_vec,
"ghost_"));
860 LibmeshPetscCall(VecSetFromOptions (_vec));
862 this->_is_initialized =
true;
863 this->_is_closed =
true;
876 parallel_object_only();
882 const PetscVector<T> & v = cast_ref<const PetscVector<T> &>(other);
895 this->_is_closed =
true;
896 this->_is_initialized =
true;
898 this->_type = v.
_type;
901 LibmeshPetscCall(VecDuplicate (v.
_vec, &this->_vec));
913 parallel_object_only();
915 this->_restore_array();
917 VecAssemblyBeginEnd(this->comm(), _vec);
919 if (this->is_effectively_ghosted())
920 VecGhostUpdateBeginEnd(this->comm(), _vec, INSERT_VALUES, SCATTER_FORWARD);
922 this->_is_closed =
true;
931 exceptionless_parallel_object_only();
934 this->_restore_array();
936 if ((this->
initialized()) && (this->_destroy_vec_on_exit))
940 PetscErrorCode ierr = VecDestroy(&_vec);
942 libmesh_warning(
"Warning: VecDestroy returned a non-zero error code which we ignored.");
945 this->_is_closed = this->_is_initialized =
false;
947 _global_to_local_map.clear();
956 parallel_object_only();
960 this->_restore_array();
964 if (!this->is_effectively_ghosted())
965 LibmeshPetscCall(VecSet (_vec, z));
971 LibmeshPetscCall(VecGhostGetLocalForm (_vec,&loc_vec));
972 LibmeshPetscCall(VecSet (loc_vec, z));
973 LibmeshPetscCall(VecGhostRestoreLocalForm (_vec, &loc_vec));
983 std::unique_ptr<NumericVector<T>> cloned_vector =
984 std::make_unique<PetscVector<T>>(this->comm(), this->type());
985 cloned_vector->init(*
this);
986 return cloned_vector;
995 std::unique_ptr<NumericVector<T>> cloned_vector =
996 std::make_unique<PetscVector<T>>(this->comm(), this->type());
997 cloned_vector->init(*
this,
true);
998 *cloned_vector = *
this;
999 return cloned_vector;
1004template <
typename T>
1010 PetscInt petsc_size=0;
1015 LibmeshPetscCall(VecGetSize(_vec, &petsc_size));
1022template <
typename T>
1028 PetscInt petsc_size=0;
1030 LibmeshPetscCall(VecGetLocalSize(_vec, &petsc_size));
1037template <
typename T>
1045 if (_array_is_present)
1049 PetscInt petsc_first=0, petsc_last=0;
1050 LibmeshPetscCall(VecGetOwnershipRange (_vec, &petsc_first, &petsc_last));
1059template <
typename T>
1067 if (_array_is_present)
1071 PetscInt petsc_first=0, petsc_last=0;
1072 LibmeshPetscCall(VecGetOwnershipRange (_vec, &petsc_first, &petsc_last));
1081template <
typename T>
1090 if (_array_is_present)
1097 PetscInt petsc_first=0, petsc_last=0;
1098 LibmeshPetscCall(VecGetOwnershipRange (_vec, &petsc_first, &petsc_last));
1104 if ((i>=first) && (i<last))
1109 GlobalToLocalMap::const_iterator it = _global_to_local_map.find(i);
1111 const GlobalToLocalMap::const_iterator end = _global_to_local_map.end();
1114 std::ostringstream error_message;
1115 error_message <<
"No index " << i <<
" in ghosted vector.\n"
1116 <<
"Vector contains [" << first <<
',' << last <<
")\n";
1117 GlobalToLocalMap::const_iterator
b = _global_to_local_map.begin();
1120 error_message <<
"And empty ghost array.\n";
1124 error_message <<
"And ghost array {" <<
b->first;
1125 for (++
b;
b != end; ++
b)
1126 error_message <<
',' <<
b->first;
1127 error_message <<
"}\n";
1130 libmesh_error_msg(error_message.str());
1134 return it->second+last-first;
1139template <
typename T>
1143 this->_get_array(
true);
1148 if (this->is_effectively_ghosted())
1149 libmesh_assert_less (local_index, _local_size);
1152 return static_cast<T
>(_read_only_values[local_index]);
1157template <
typename T>
1162 this->_get_array(
true);
1164 const std::size_t num = index.size();
1166 for (std::size_t i=0; i<num; i++)
1170 if (this->is_effectively_ghosted())
1171 libmesh_assert_less (local_index, _local_size);
1173 values[i] =
static_cast<T
>(_read_only_values[local_index]);
1178template <
typename T>
1183 _values_manually_retrieved =
true;
1189template <
typename T>
1194 _values_manually_retrieved =
true;
1196 return _read_only_values;
1199template <
typename T>
1205 _values_manually_retrieved =
false;
1209template <
typename T>
1213 parallel_object_only();
1215 this->_restore_array();
1218 PetscReal returnval=0.;
1220 LibmeshPetscCall(VecMin (_vec, &index, &returnval));
1223 return static_cast<Real>(returnval);
1228template <
typename T>
1232 parallel_object_only();
1234 this->_restore_array();
1237 PetscReal returnval=0.;
1239 LibmeshPetscCall(VecMax (_vec, &index, &returnval));
1242 return static_cast<Real>(returnval);
1247template <
typename T>
1251 parallel_object_only();
1257 std::swap(_vec, v.
_vec);
1261#ifdef LIBMESH_HAVE_CXX11_THREAD
1269 std::swap(_values, v.
_values);
1274template <
typename T>
1280 return std::numeric_limits<PetscInt>::max();
1285#ifdef LIBMESH_HAVE_CXX11
1287 "PETSc and libMesh integer sizes must match!");
void min(const T &r, T &o, Request &req) const
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
ParallelType type() const
virtual void swap(NumericVector< T > &v)
Swaps the contents of this with v.
ParallelType _type
Type of vector.
virtual bool initialized() const
bool _is_initialized
true once init() has been called.
bool _is_closed
Flag which tracks whether the vector's values are consistent on all processors after insertion or add...
This class provides a nice interface to PETSc's Vec object.
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices) override
Inserts the entries of v in *this at the locations specified by v.
Vec _local_form
PETSc vector datatype to hold the local form of a ghosted vector.
PetscVector(PetscVector &&)=delete
This class manages a C-style struct (Vec) manually, so we don't want to allow any automatic copy/move...
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
virtual std::unique_ptr< NumericVector< T > > get_subvector(const std::vector< numeric_index_type > &rows) override
Creates a view into this vector using the indices in rows.
PetscVector(Vec v, const Parallel::Communicator &comm_in)
Constructor.
virtual Real min() const override
PetscVector(const PetscVector &)=delete
virtual Real linfty_norm() const override
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices) override
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
virtual void set(const numeric_index_type i, const T value) override
Sets v(i) = value.
virtual numeric_index_type size() const override
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
PetscVector(const Parallel::Communicator &comm_in, const ParallelType type=AUTOMATIC)
Dummy-Constructor.
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
std::mutex _petsc_get_restore_array_mutex
Mutex for _get_array and _restore_array.
numeric_index_type _first
First local index.
virtual void restore_subvector(std::unique_ptr< NumericVector< T > > subvector, const std::vector< numeric_index_type > &rows) override
Restores a view into this vector using the indices in rows.
bool _values_read_only
Whether or not the data array is for read only access.
PetscVector(const Parallel::Communicator &comm_in, const numeric_index_type n, const ParallelType type=AUTOMATIC)
Constructor.
virtual numeric_index_type first_local_index() const override
bool _values_manually_retrieved
Whether or not the data array has been manually retrieved using get_array() or get_array_read()
virtual std::size_t max_allowed_id() const override
void _get_array(bool read_only) const
Queries the array (and the local form if the vector is ghosted) from PETSc.
virtual void localize_to_one(std::vector< T > &v_local, const processor_id_type proc_id=0) const override
Creates a local copy of the global vector in v_local only on processor proc_id.
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
virtual Real max() const override
PetscScalar * _values
Pointer to the actual PETSc array of the values of the vector.
void _restore_array() const
Restores the array (and the local form if the vector is ghosted) to PETSc.
numeric_index_type _local_size
Size of the local values from _get_array()
virtual void print_matlab(const std::string &name="") const override
Print the contents of the vector in Matlab's sparse matrix format.
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
numeric_index_type _last
Last local index.
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
virtual void pointwise_divide(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
numeric_index_type map_global_to_local_index(const numeric_index_type i) const
virtual Real l2_norm() const override
void restore_array()
Restore the data array.
virtual void create_subvector(NumericVector< T > &subvector, const std::vector< numeric_index_type > &rows, bool supplying_global_rows=true) const override
Fills in subvector from this vector using the indices in rows.
const PetscScalar * _read_only_values
Pointer to the actual PETSc array of the values of the vector.
virtual numeric_index_type last_local_index() const override
PetscVector(const Parallel::Communicator &comm_in, const numeric_index_type N, const numeric_index_type n_local, const std::vector< numeric_index_type > &ghost, const ParallelType type=AUTOMATIC)
Constructor.
virtual T operator()(const numeric_index_type i) const override
virtual std::unique_ptr< NumericVector< T > > clone() const override
virtual numeric_index_type local_size() const override
virtual void get(const std::vector< numeric_index_type > &index, T *values) const override
Access multiple components at once.
const PetscScalar * get_array_read() const
Get read only access to the raw PETSc Vector data array.
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
std::atomic< bool > _array_is_present
If true, the actual PETSc array of the values of the vector is currently accessible.
PetscVector(const Parallel::Communicator &comm_in, const numeric_index_type n, const numeric_index_type n_local, const ParallelType type=AUTOMATIC)
Constructor.
std::unordered_map< numeric_index_type, numeric_index_type > GlobalToLocalMap
Type for map that maps global to local ghost cells.
GlobalToLocalMap _global_to_local_map
Map that maps global to local ghost cells (will be empty if not in ghost cell mode).
virtual Real l1_norm() const override
T indefinite_dot(const NumericVector< T > &v) const
PetscVector< T > & operator=(const PetscVector< T > &v)
Copy assignment operator.
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i.
virtual void zero() override
Set all entries to zero.
virtual void reciprocal() override
Computes the component-wise reciprocal, .
virtual void clear() noexcept override
clear() is called from the destructor, so it should not throw.
virtual T dot(const NumericVector< T > &v) const override
Vec _vec
Actual PETSc vector datatype to hold vector entries.
void add_vector_conjugate_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A)
.
virtual T sum() const override
virtual void abs() override
Sets for each entry in the vector.
bool _destroy_vec_on_exit
This boolean value should only be set to false for the constructor which takes a PETSc Vec object.
PetscScalar * get_array()
Get read/write access to the raw PETSc Vector data array.
virtual void init(const numeric_index_type N, const numeric_index_type n_local, const bool fast=false, const ParallelType type=AUTOMATIC) override
Change the dimension of the vector to n.
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
ParallelType
Defines an enum for parallel data structure types.
bool closed()
Checks that the library has been closed.
dof_id_type numeric_index_type
PetscInt * numeric_petsc_cast(const numeric_index_type *p)
bool initialized()
Checks that library initialization has been done.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
uint8_t processor_id_type
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...