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" 40 # define LIBMESH_SAW_I 44 # undef I // Avoid complex.h contamination 51 #include <unordered_map> 56 #include <condition_variable> 62 template <
typename T>
class SparseMatrix;
109 const std::vector<numeric_index_type> & ghost,
143 virtual void close ()
override;
148 virtual void clear () noexcept
override;
150 virtual void zero ()
override;
152 virtual std::unique_ptr<NumericVector<T>>
zero_clone ()
const override;
154 virtual std::unique_ptr<NumericVector<T>>
clone ()
const override;
158 const bool fast=
false,
162 const bool fast=
false,
167 const std::vector<numeric_index_type> & ghost,
168 const bool fast =
false,
172 const bool fast =
false)
override;
180 virtual Real min ()
const override;
182 virtual Real max ()
const override;
184 virtual T
sum ()
const override;
211 virtual void get(
const std::vector<numeric_index_type> & index,
212 T * values)
const override;
247 const T
value)
override;
250 const T
value)
override;
252 virtual void add (
const T s)
override;
265 const std::vector<numeric_index_type> & dof_indices)
override;
288 virtual void insert (
const T * v,
289 const std::vector<numeric_index_type> & dof_indices)
override;
291 virtual void scale (
const T factor)
override;
297 virtual void abs()
override;
308 virtual void localize (std::vector<T> & v_local)
const override;
313 const std::vector<numeric_index_type> & send_list)
const override;
315 virtual void localize (std::vector<T> & v_local,
316 const std::vector<numeric_index_type> & indices)
const override;
320 const std::vector<numeric_index_type> & send_list)
override;
334 const std::vector<numeric_index_type> & rows,
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;
487 template <
typename T>
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)
509 template <
typename T>
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);
533 template <
typename T>
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);
558 template <
typename T>
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);
586 template <
typename T>
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)
604 this->_is_closed =
true;
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));
656 _global_to_local_map[indices[i]] = i;
658 LibmeshPetscCall(ISRestoreIndices(ghostis, &indices));
664 #else // PETSc < 3.21.0 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));
694 _global_to_local_map[indices[i]] = i-my_local_size;
696 LibmeshPetscCall(ISLocalToGlobalMappingRestoreIndices(mapping, &indices));
701 LibmeshPetscCall(VecGhostRestoreLocalForm(_vec,&localrep));
710 template <
typename T>
719 template <
typename T>
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");
779 this->_is_closed =
true;
788 template <
typename T>
794 this->
init(n,n,fast,ptype);
799 template <
typename T>
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));
863 this->_is_closed =
true;
871 template <
typename T>
876 parallel_object_only();
882 const PetscVector<T> & v = cast_ref<const PetscVector<T> &>(other);
895 this->_is_closed =
true;
898 this->_type = v.
_type;
901 LibmeshPetscCall(VecDuplicate (v.
_vec, &this->_vec));
909 template <
typename T>
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;
927 template <
typename T>
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.");
947 _global_to_local_map.clear();
952 template <
typename T>
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));
979 template <
typename T>
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;
991 template <
typename T>
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;
1004 template <
typename T>
1010 PetscInt petsc_size=0;
1015 LibmeshPetscCall(VecGetSize(_vec, &petsc_size));
1022 template <
typename T>
1028 PetscInt petsc_size=0;
1030 LibmeshPetscCall(VecGetLocalSize(_vec, &petsc_size));
1037 template <
typename T>
1045 if (_array_is_present)
1049 PetscInt petsc_first=0, petsc_last=0;
1050 LibmeshPetscCall(VecGetOwnershipRange (_vec, &petsc_first, &petsc_last));
1059 template <
typename T>
1067 if (_array_is_present)
1071 PetscInt petsc_first=0, petsc_last=0;
1072 LibmeshPetscCall(VecGetOwnershipRange (_vec, &petsc_first, &petsc_last));
1081 template <
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;
1139 template <
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]);
1157 template <
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]);
1178 template <
typename T>
1183 _values_manually_retrieved =
true;
1189 template <
typename T>
1194 _values_manually_retrieved =
true;
1196 return _read_only_values;
1199 template <
typename T>
1205 _values_manually_retrieved =
false;
1209 template <
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);
1228 template <
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);
1247 template <
typename T>
1251 parallel_object_only();
1257 std::swap(_vec, v.
_vec);
1261 #ifdef LIBMESH_HAVE_CXX11_THREAD 1269 std::swap(_values, v.
_values);
1274 template <
typename T>
1280 return std::numeric_limits<PetscInt>::max();
1285 #ifdef LIBMESH_HAVE_CXX11 1287 "PETSc and libMesh integer sizes must match!");
1300 #endif // #ifdef LIBMESH_HAVE_PETSC 1301 #endif // LIBMESH_PETSC_VECTOR_H std::string name(const ElemQuality q)
This function returns a string containing some name for q.
virtual Real l2_norm() const override
PetscVector(const Parallel::Communicator &comm_in, const ParallelType type=AUTOMATIC)
Dummy-Constructor.
bool closed()
Checks that the library has been closed.
virtual void localize(std::vector< T > &v_local) const override
Creates a copy of the global vector in the local vector v_local.
This class provides a nice interface to PETSc's Vec object.
void add_vector_conjugate_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A)
.
virtual void add_vector_transpose(const NumericVector< T > &v, const SparseMatrix< T > &A) override
Computes , i.e.
virtual void zero() override
Set all entries to zero.
bool _destroy_vec_on_exit
This boolean value should only be set to false for the constructor which takes a PETSc Vec object...
virtual numeric_index_type size() const override
virtual Real linfty_norm() const override
numeric_index_type _local_size
Size of the local values from _get_array()
virtual numeric_index_type first_local_index() const override
virtual bool initialized() const
void _get_array(bool read_only) const
Queries the array (and the local form if the vector is ghosted) from PETSc.
virtual numeric_index_type local_size() const override
virtual void add(const numeric_index_type i, const T value) override
Adds value to the vector entry specified by i.
Vec _vec
Actual PETSc vector datatype to hold vector entries.
numeric_index_type _last
Last local index.
Provides a uniform interface to vector storage schemes for different linear algebra libraries...
PetscScalar * _values
Pointer to the actual PETSc array of the values of the vector.
bool _values_read_only
Whether or not the data array is for read only access.
The libMesh namespace provides an interface to certain functionality in the library.
virtual void pointwise_divide(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
void _restore_array() const
Restores the array (and the local form if the vector is ghosted) to PETSc.
std::atomic< bool > _array_is_present
If true, the actual PETSc array of the values of the vector is currently accessible.
uint8_t processor_id_type
PetscInt * numeric_petsc_cast(const numeric_index_type *p)
virtual void swap(NumericVector< T > &v) override
Swaps the contents of this with v.
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.
const PetscScalar * _read_only_values
Pointer to the actual PETSc array of the values of the vector.
virtual void pointwise_mult(const NumericVector< T > &vec1, const NumericVector< T > &vec2) override
Computes (summation not implied) i.e.
virtual Real l1_norm() const override
Vec _local_form
PETSc vector datatype to hold the local form of a ghosted vector.
GlobalToLocalMap _global_to_local_map
Map that maps global to local ghost cells (will be empty if not in ghost cell mode).
virtual void abs() override
Sets for each entry in the vector.
void min(const T &r, T &o, Request &req) const
dof_id_type numeric_index_type
bool _is_initialized
Flag that tells if init() has been called.
const PetscScalar * get_array_read() const
Get read only access to the raw PETSc Vector data array.
virtual NumericVector< T > & operator+=(const NumericVector< T > &v) override
Adds v to *this, .
virtual void conjugate() override
Negates the imaginary component of each entry in the vector.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
virtual T operator()(const numeric_index_type i) const override
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.
numeric_index_type map_global_to_local_index(const numeric_index_type i) const
virtual std::size_t max_allowed_id() const override
ParallelType _type
Type of vector.
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.
virtual numeric_index_type last_local_index() const override
std::string enum_to_string(const T e)
virtual T sum() const override
std::mutex _petsc_get_restore_array_mutex
Mutex for _get_array and _restore_array.
void restore_array()
Restore the data array.
ParallelType type() const
virtual std::unique_ptr< NumericVector< T > > clone() const override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
T indefinite_dot(const NumericVector< T > &v) const
std::unordered_map< numeric_index_type, numeric_index_type > GlobalToLocalMap
Type for map that maps global to local ghost cells.
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.
virtual void clear() noexcept override
clear() is called from the destructor, so it should not throw.
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.
virtual Real max() const override
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...
bool initialized()
Checks that library initialization has been done.
numeric_index_type _first
First local index.
PetscVector< T > & operator=(const PetscVector< T > &v)
Copy assignment operator.
virtual void reciprocal() override
Computes the component-wise reciprocal, .
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 NumericVector< T > & operator*=(const NumericVector< T > &v) override
Computes the component-wise multiplication of this vector's entries by another's, ...
bool _values_manually_retrieved
Whether or not the data array has been manually retrieved using get_array() or get_array_read() ...
virtual void print_matlab(const std::string &name="") const override
Print the contents of the vector in Matlab's sparse matrix format.
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.
virtual void scale(const T factor) override
Scale each element of the vector by the given factor.
PetscScalar * get_array()
Get read/write access to the raw PETSc Vector data array.
virtual std::unique_ptr< NumericVector< T > > zero_clone() const override
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
const Elem & get(const ElemType type_in)
virtual Real min() const override
virtual void close() override
Calls the NumericVector's internal assembly routines, ensuring that the values are consistent across ...
virtual NumericVector< T > & operator/=(const NumericVector< T > &v) override
Computes the component-wise division of this vector's entries by another's, .
ParallelType
Defines an enum for parallel data structure types.
virtual NumericVector< T > & operator-=(const NumericVector< T > &v) override
Subtracts v from *this, .
virtual T dot(const NumericVector< T > &v) const override