20#include "libmesh/numeric_vector.h"
21#include "libmesh/distributed_vector.h"
22#include "libmesh/laspack_vector.h"
23#include "libmesh/eigen_sparse_vector.h"
24#include "libmesh/petsc_vector.h"
25#include "libmesh/trilinos_epetra_vector.h"
26#include "libmesh/shell_matrix.h"
27#include "libmesh/tensor_tools.h"
28#include "libmesh/enum_solver_package.h"
29#include "libmesh/int_range.h"
32#ifdef LIBMESH_HAVE_GZSTREAM
45#ifdef LIBMESH_HAVE_CXX11_REGEX
60std::unique_ptr<NumericVector<T>>
66 switch (solver_package)
69#ifdef LIBMESH_HAVE_LASPACK
71 return std::make_unique<LaspackVector<T>>(comm, parallel_type);
74#ifdef LIBMESH_HAVE_PETSC
76 return std::make_unique<PetscVector<T>>(comm, parallel_type);
79#ifdef LIBMESH_TRILINOS_HAVE_EPETRA
81 return std::make_unique<EpetraVector<T>>(comm, parallel_type);
84#ifdef LIBMESH_HAVE_EIGEN
86 return std::make_unique<EigenSparseVector<T>>(comm, parallel_type);
90 return std::make_unique<DistributedVector<T>>(comm, parallel_type);
109#ifndef LIBMESH_ENABLE_GHOSTED
124 libmesh_not_implemented();
129 const std::vector<numeric_index_type> & dof_indices)
134 this->set (dof_indices[i], v[i]);
141 const std::vector<numeric_index_type> & dof_indices)
143 libmesh_assert_equal_to (V.
size(), dof_indices.size());
147 this->set (dof_indices[i], V(i));
154 const Real threshold)
const
158 int first_different_i = std::numeric_limits<int>::max();
161 while (first_different_i==std::numeric_limits<int>::max()
162 && i<last_local_index())
164 if (std::abs((*
this)(i) - other_vector(i)) > threshold)
165 first_different_i = i;
171 this->comm().min(first_different_i);
173 if (first_different_i == std::numeric_limits<int>::max())
176 return first_different_i;
182 const Real threshold)
const
186 int first_different_i = std::numeric_limits<int>::max();
191 if (std::abs((*
this)(i) - other_vector(i)) > threshold *
192 std::max(std::abs((*
this)(i)), std::abs(other_vector(i))))
193 first_different_i = i;
197 while (first_different_i==std::numeric_limits<int>::max()
198 && i<last_local_index());
201 this->comm().min(first_different_i);
203 if (first_different_i == std::numeric_limits<int>::max())
206 return first_different_i;
212 const Real threshold)
const
216 int first_different_i = std::numeric_limits<int>::max();
219 const Real my_norm = this->linfty_norm();
221 const Real abs_threshold = std::max(my_norm, other_norm) * threshold;
225 if (std::abs((*
this)(i) - other_vector(i) ) > abs_threshold)
226 first_different_i = i;
230 while (first_different_i==std::numeric_limits<int>::max()
231 && i<last_local_index());
234 this->comm().min(first_different_i);
236 if (first_different_i == std::numeric_limits<int>::max())
239 return first_different_i;
247 parallel_object_only();
252 end_dof = this->last_local_index();
256 if (this->processor_id() == 0)
258 std::unique_ptr<std::ofstream> file;
261 file = std::make_unique<std::ofstream>(filename.c_str());
263 std::ostream & os = (filename ==
"") ?
libMesh::out : *file;
266 os <<
"%Vec Object: () " << this->n_processors() <<
" MPI processes\n"
267 <<
"% type: " << (this->n_processors() > 1 ?
"mpi" :
"seq") <<
"\n"
271 os << (*
this)(i) <<
'\n';
276 this->comm().receive(p, cbuf);
282 os <<
"];\n" << std::endl;
286 std::vector<T> cbuf(end_dof - first_dof);
289 cbuf[i] = (*
this)(first_dof+i);
290 this->comm().send(0,cbuf);
299 LOG_SCOPE(
"read_matlab()",
"NumericVector");
301#ifndef LIBMESH_HAVE_CXX11_REGEX
302 libmesh_not_implemented();
305 parallel_object_only();
311 std::vector<numeric_index_type> first_entries, end_entries;
320 std::unique_ptr<std::istream> file;
323 std::vector<T> entries;
328 if (this->processor_id() == 0)
332 const std::regex start_regex
333 (
"\\s*\\w+\\s*=\\s*\\[");
334 const std::regex end_regex
339#ifdef LIBMESH_HAVE_GZSTREAM
340 auto inf = std::make_unique<igzstream>();
342 inf->open(filename.c_str(), std::ios::in);
343 file = std::move(inf);
345 libmesh_error_msg(
"ERROR: need gzstream to handle .gz files!!!");
350 auto inf = std::make_unique<std::ifstream>();
355 inf->open(new_name.c_str(), std::ios::in);
356 file = std::move(inf);
359 const std::string whitespace =
" \t";
361 bool have_started =
false;
362 bool have_ended =
false;
364 for (std::string line; std::getline(*file, line);)
371 std::istringstream l(line);
378 (!have_started,
"Confused by premature entries in vector file " << filename);
380 entries.push_back(
value);
384 else if (std::regex_search(line, start_regex))
387 else if (std::regex_search(line, end_regex))
395 (!have_started,
"Confused by missing assignment-beginning in vector file " << filename);
398 (!have_ended,
"Confused by missing assignment-ending in vector file " << filename);
401 this->comm().broadcast(n);
406 first_entry = this->first_local_index(),
407 end_entry = this->last_local_index();
412 first_entry = this->processor_id() * n / this->n_processors(),
413 end_entry = (this->processor_id()+1) * n / this->n_processors();
416 this->comm().gather(0, first_entry, first_entries);
417 this->comm().gather(0, end_entry, end_entries);
424 (this->size() != n) ||
425 (this->local_size() != end_entry - first_entry);
427 this->comm().max(need_init);
430 this->
init(n, end_entry - first_entry);
435 if (this->processor_id() == 0)
436 for (
auto p :
make_range(this->n_processors()))
440 std::vector<numeric_index_type> indices(n_local);
441 std::iota(indices.begin(), indices.end(), first_entry_p);
442 this->insert(entries.data() + first_entries[p],
567 for (
const auto & index : indices)
568 norm += std::abs(v(index));
570 this->comm().sum(norm);
584 for (
const auto & index : indices)
585 norm += TensorTools::norm_sq(v(index));
587 this->comm().sum(norm);
589 return std::sqrt(norm);
601 for (
const auto & index : indices)
608 this->comm().max(norm);
626 v1(v1in), v2(v2in), norm_sq(0) {}
629 v1(other.v1), v2(other.v2), norm_sq(0) {}
633 norm_sq += TensorTools::norm_sq(v1(i) - v2(i));
636 void join(
const L2Differ & other) {
637 norm_sq += other.norm_sq;
641 L2Differ differ(*
this, v);
645 this->comm().sum(differ.norm_sq);
647 return std::sqrt(differ.norm_sq);
663 v1(v1in), v2(v2in), norm(0) {}
666 v1(other.v1), v2(other.v2), norm(0) {}
673 void join(
const L1Differ & other) {
678 L1Differ differ(*
this, v);
682 this->comm().sum(differ.norm);
691 const std::vector<numeric_index_type> & dof_indices)
696 this->add (dof_indices[i], v[i]);
703 const std::vector<numeric_index_type> & dof_indices)
707 const std::size_t n = dof_indices.size();
708 libmesh_assert_equal_to(v.
size(), n);
710 this->add (dof_indices[i], v(i));
736 return this->readable() && v.
readable() &&
737 this->size() == v.
size() &&
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
Real l1_norm_diff(const NumericVector< T > &other_vec) const
virtual numeric_index_type last_local_index() const =0
void set_type(ParallelType t)
Allow the user to change the ParallelType of the NumericVector under some circumstances.
Real l2_norm_diff(const NumericVector< T > &other_vec) const
virtual void read_matlab(const std::string &filename)
Read the contents of the vector from the Matlab-script format used by PETSc.
virtual void print_matlab(const std::string &filename="") const
Print the contents of the vector in Matlab's sparse matrix format.
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices)
Inserts the entries of v in *this at the locations specified by v.
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
Computes , where v is a pointer and each dof_indices[i] specifies where to add value v[i].
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
virtual numeric_index_type size() const =0
virtual Real linfty_norm() const =0
bool compatible(const NumericVector< T > &v) const
virtual Real subset_l1_norm(const std::set< numeric_index_type > &indices) const
virtual numeric_index_type local_size() const =0
virtual Real subset_l2_norm(const std::set< numeric_index_type > &indices) const
virtual int compare(const NumericVector< T > &other_vector, const Real threshold=TOLERANCE) const
virtual numeric_index_type first_local_index() const =0
virtual int local_relative_compare(const NumericVector< T > &other_vector, const Real threshold=TOLERANCE) const
virtual int global_relative_compare(const NumericVector< T > &other_vector, const Real threshold=TOLERANCE) const
virtual Real subset_linfty_norm(const std::set< numeric_index_type > &indices) const
Generic shell matrix, i.e.
virtual void vector_mult_add(NumericVector< T > &dest, const NumericVector< T > &arg) const =0
Multiplies the matrix with arg and adds the result to dest.
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
void init(triangulateio &t)
Initializes the fields of t to nullptr/0 as necessary.
bool ends_with(std::string_view superstring, std::string_view suffix)
Look for a substring at the very end of a string.
std::string unzip_file(std::string_view name)
Create an unzipped copy of a bz2 or xz file, returning the name of the now-unzipped file that can be ...
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.
void libmesh_ignore(const Args &...)
dof_id_type numeric_index_type
SolverPackage
Defines an enum for various linear solver packages.
bool initialized()
Checks that library initialization has been done.
auto l1_norm_diff(const NumericVector< T > &vec1, const NumericVector< T > &vec2)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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...