libmesh解析
本工作只是尝试解析原libmesh的代码,供学习使用
 全部  命名空间 文件 函数 变量 类型定义 枚举 枚举值 友元 
numeric_vector.C
浏览该文件的文档.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2023 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 // Local Includes
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"
30 
31 
32 // C++ includes
33 #include <cstdlib> // *must* precede <cmath> for proper std:abs() on PGI, Sun Studio CC
34 #include <cmath> // for std::abs
35 #include <limits>
36 #include <memory>
37 
38 
39 namespace libMesh
40 {
41 
42 
43 
44 //------------------------------------------------------------------
45 // NumericVector methods
46 
47 // Full specialization for Real datatypes
48 template <typename T>
49 std::unique_ptr<NumericVector<T>>
50 NumericVector<T>::build(const Parallel::Communicator & comm, const SolverPackage solver_package)
51 {
52  // Build the appropriate vector
53  switch (solver_package)
54  {
55 
56 #ifdef LIBMESH_HAVE_LASPACK
57  case LASPACK_SOLVERS:
58  return std::make_unique<LaspackVector<T>>(comm, AUTOMATIC);
59 #endif
60 
61 #ifdef LIBMESH_HAVE_PETSC
62  case PETSC_SOLVERS:
63  return std::make_unique<PetscVector<T>>(comm, AUTOMATIC);
64 #endif
65 
66 #ifdef LIBMESH_TRILINOS_HAVE_EPETRA
67  case TRILINOS_SOLVERS:
68  return std::make_unique<EpetraVector<T>>(comm, AUTOMATIC);
69 #endif
70 
71 #ifdef LIBMESH_HAVE_EIGEN
72  case EIGEN_SOLVERS:
73  return std::make_unique<EigenSparseVector<T>>(comm, AUTOMATIC);
74 #endif
75 
76  default:
77  return std::make_unique<DistributedVector<T>>(comm, AUTOMATIC);
78  }
79 }
80 
81 
82 
83 template <typename T>
84 void NumericVector<T>::insert (const T * v,
85  const std::vector<numeric_index_type> & dof_indices)
86 {
87  libmesh_assert (v);
88 
89  for (auto i : index_range(dof_indices))
90  this->set (dof_indices[i], v[i]);
91 }
92 
93 
94 
95 template <typename T>
97  const std::vector<numeric_index_type> & dof_indices)
98 {
99  libmesh_assert_equal_to (V.size(), dof_indices.size());
100  libmesh_assert (V.readable());
101 
102  for (auto i : index_range(dof_indices))
103  this->set (dof_indices[i], V(i));
104 }
105 
106 
107 
108 template <typename T>
109 int NumericVector<T>::compare (const NumericVector<T> & other_vector,
110  const Real threshold) const
111 {
112  libmesh_assert(this->compatible(other_vector));
113 
114  int first_different_i = std::numeric_limits<int>::max();
115  numeric_index_type i = first_local_index();
116 
117  while (first_different_i==std::numeric_limits<int>::max()
118  && i<last_local_index())
119  {
120  if (std::abs((*this)(i) - other_vector(i)) > threshold)
121  first_different_i = i;
122  else
123  i++;
124  }
125 
126  // Find the correct first differing index in parallel
127  this->comm().min(first_different_i);
128 
129  if (first_different_i == std::numeric_limits<int>::max())
130  return -1;
131 
132  return first_different_i;
133 }
134 
135 
136 template <typename T>
138  const Real threshold) const
139 {
140  libmesh_assert(this->compatible(other_vector));
141 
142  int first_different_i = std::numeric_limits<int>::max();
143  numeric_index_type i = first_local_index();
144 
145  do
146  {
147  if (std::abs((*this)(i) - other_vector(i)) > threshold *
148  std::max(std::abs((*this)(i)), std::abs(other_vector(i))))
149  first_different_i = i;
150  else
151  i++;
152  }
153  while (first_different_i==std::numeric_limits<int>::max()
154  && i<last_local_index());
155 
156  // Find the correct first differing index in parallel
157  this->comm().min(first_different_i);
158 
159  if (first_different_i == std::numeric_limits<int>::max())
160  return -1;
161 
162  return first_different_i;
163 }
164 
165 
166 template <typename T>
168  const Real threshold) const
169 {
170  libmesh_assert(this->compatible(other_vector));
171 
172  int first_different_i = std::numeric_limits<int>::max();
173  numeric_index_type i = first_local_index();
174 
175  const Real my_norm = this->linfty_norm();
176  const Real other_norm = other_vector.linfty_norm();
177  const Real abs_threshold = std::max(my_norm, other_norm) * threshold;
178 
179  do
180  {
181  if (std::abs((*this)(i) - other_vector(i) ) > abs_threshold)
182  first_different_i = i;
183  else
184  i++;
185  }
186  while (first_different_i==std::numeric_limits<int>::max()
187  && i<last_local_index());
188 
189  // Find the correct first differing index in parallel
190  this->comm().min(first_different_i);
191 
192  if (first_different_i == std::numeric_limits<int>::max())
193  return -1;
194 
195  return first_different_i;
196 }
197 
198 /*
199 // Full specialization for float datatypes (DistributedVector wants this)
200 
201 template <>
202 int NumericVector<float>::compare (const NumericVector<float> & other_vector,
203 const Real threshold) const
204 {
205 libmesh_assert (this->initialized());
206 libmesh_assert (other_vector.initialized());
207 libmesh_assert_equal_to (this->first_local_index(), other_vector.first_local_index());
208 libmesh_assert_equal_to (this->last_local_index(), other_vector.last_local_index());
209 
210 int rvalue = -1;
211 numeric_index_type i = first_local_index();
212 
213 do
214 {
215 if (std::abs((*this)(i) - other_vector(i) ) > threshold)
216 rvalue = i;
217 else
218 i++;
219 }
220 while (rvalue==-1 && i<last_local_index());
221 
222 return rvalue;
223 }
224 
225 // Full specialization for double datatypes
226 template <>
227 int NumericVector<double>::compare (const NumericVector<double> & other_vector,
228 const Real threshold) const
229 {
230 libmesh_assert (this->initialized());
231 libmesh_assert (other_vector.initialized());
232 libmesh_assert_equal_to (this->first_local_index(), other_vector.first_local_index());
233 libmesh_assert_equal_to (this->last_local_index(), other_vector.last_local_index());
234 
235 int rvalue = -1;
236 numeric_index_type i = first_local_index();
237 
238 do
239 {
240 if (std::abs((*this)(i) - other_vector(i) ) > threshold)
241 rvalue = i;
242 else
243 i++;
244 }
245 while (rvalue==-1 && i<last_local_index());
246 
247 return rvalue;
248 }
249 
250 #ifdef LIBMESH_DEFAULT_TRIPLE_PRECISION
251 // Full specialization for long double datatypes
252 template <>
253 int NumericVector<long double>::compare (const NumericVector<long double> & other_vector,
254 const Real threshold) const
255 {
256 libmesh_assert (this->initialized());
257 libmesh_assert (other_vector.initialized());
258 libmesh_assert_equal_to (this->first_local_index(), other_vector.first_local_index());
259 libmesh_assert_equal_to (this->last_local_index(), other_vector.last_local_index());
260 
261 int rvalue = -1;
262 numeric_index_type i = first_local_index();
263 
264 do
265 {
266 if (std::abs((*this)(i) - other_vector(i) ) > threshold)
267 rvalue = i;
268 else
269 i++;
270 }
271 while (rvalue==-1 && i<last_local_index());
272 
273 return rvalue;
274 }
275 #endif
276 
277 
278 // Full specialization for Complex datatypes
279 template <>
280 int NumericVector<Complex>::compare (const NumericVector<Complex> & other_vector,
281 const Real threshold) const
282 {
283 libmesh_assert (this->initialized());
284 libmesh_assert (other_vector.initialized());
285 libmesh_assert_equal_to (this->first_local_index(), other_vector.first_local_index());
286 libmesh_assert_equal_to (this->last_local_index(), other_vector.last_local_index());
287 
288 int rvalue = -1;
289 numeric_index_type i = first_local_index();
290 
291 do
292 {
293 if ((std::abs((*this)(i).real() - other_vector(i).real()) > threshold) || (std::abs((*this)(i).imag() - other_vector(i).imag()) > threshold))
294 rvalue = i;
295 else
296 i++;
297 }
298 while (rvalue==-1 && i<this->last_local_index());
299 
300 return rvalue;
301 }
302 */
303 
304 
305 template <class T>
306 Real NumericVector<T>::subset_l1_norm (const std::set<numeric_index_type> & indices) const
307 {
308  libmesh_assert (this->readable());
309 
310  const NumericVector<T> & v = *this;
311 
312  Real norm = 0;
313 
314  for (const auto & index : indices)
315  norm += std::abs(v(index));
316 
317  this->comm().sum(norm);
318 
319  return norm;
320 }
321 
322 template <class T>
323 Real NumericVector<T>::subset_l2_norm (const std::set<numeric_index_type> & indices) const
324 {
325  libmesh_assert (this->readable());
326 
327  const NumericVector<T> & v = *this;
328 
329  Real norm = 0;
330 
331  for (const auto & index : indices)
332  norm += TensorTools::norm_sq(v(index));
333 
334  this->comm().sum(norm);
335 
336  return std::sqrt(norm);
337 }
338 
339 template <class T>
340 Real NumericVector<T>::subset_linfty_norm (const std::set<numeric_index_type> & indices) const
341 {
342  libmesh_assert (this->readable());
343 
344  const NumericVector<T> & v = *this;
345 
346  Real norm = 0;
347 
348  for (const auto & index : indices)
349  {
350  Real value = std::abs(v(index));
351  if (value > norm)
352  norm = value;
353  }
354 
355  this->comm().max(norm);
356 
357  return norm;
358 }
359 
360 
361 
362 template <class T>
364 {
365  libmesh_assert(this->compatible(v));
366 
367  Real norm = 0;
368  for (const auto i : make_range(this->first_local_index(), this->last_local_index()))
369  norm += TensorTools::norm_sq((*this)(i) - v(i));
370 
371  this->comm().sum(norm);
372 
373  return std::sqrt(norm);
374 }
375 
376 
377 
378 template <typename T>
380  const std::vector<numeric_index_type> & dof_indices)
381 {
382  libmesh_assert(v);
383 
384  for (auto i : index_range(dof_indices))
385  this->add (dof_indices[i], v[i]);
386 }
387 
388 
389 
390 template <typename T>
392  const std::vector<numeric_index_type> & dof_indices)
393 {
394  libmesh_assert(v.readable());
395 
396  const std::size_t n = dof_indices.size();
397  libmesh_assert_equal_to(v.size(), n);
398  for (numeric_index_type i=0; i != n; i++)
399  this->add (dof_indices[i], v(i));
400 }
401 
402 
403 
404 template <typename T>
406  const ShellMatrix<T> & a)
407 {
408  libmesh_assert(this->compatible(v));
409 
410  a.vector_mult_add(*this,v);
411 }
412 
413 
414 
415 template <typename T>
417 {
418  return this->initialized() && this->closed();
419 }
420 
421 
422 template <typename T>
424 {
425  return this->readable() && v.readable() &&
426  this->size() == v.size() &&
427  this->local_size() == v.local_size() &&
428  this->first_local_index() == v.first_local_index() &&
429  this->last_local_index() == v.last_local_index();
430 }
431 
432 
433 
434 //------------------------------------------------------------------
435 // Explicit instantiations
436 template class LIBMESH_EXPORT NumericVector<Number>;
437 
438 } // namespace libMesh
virtual void insert(const T *v, const std::vector< numeric_index_type > &dof_indices)
将 v 的条目插入到 *this 中,位置由 dof_indices 指定。请注意,此方法的库实现是线程安全的。
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:268
virtual int compare(const NumericVector< T > &other_vector, const Real threshold=TOLERANCE) const
比较 this 与 other_vector 的等效性,(在给定的 threshold 内) 如果等效则返回 -1 ,或者返回第一个索引,其中 abs(a[i]-b[i]) 超过阈值。 ...
EIGEN_SOLVERS
Definition: libmesh.C:249
virtual Real subset_linfty_norm(const std::set< numeric_index_type > &indices) const
获取指定条目的向量的最大绝对值,即指定条目的 -范数。
TRILINOS_SOLVERS
Definition: libmesh.C:247
virtual numeric_index_type size() const =0
获取向量的大小。
virtual void add_vector(const T *v, const std::vector< numeric_index_type > &dof_indices)
计算 ,其中 v 是一个指针, 每个 dof_indices[i] 指定了要添加的值 v[i] 的位置。 这应该在子类中进行重写以提高效率。请注意,此方法的库实现是线程安全的。 ...
提供了不同线性代数库的向量存储方案的统一接口。
Definition: dof_map.h:67
bool readable() const
检查该向量是否能够用于全局操作。
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的平方根。
Definition: type_vector.h:88
virtual void vector_mult_add(NumericVector< T > &dest, const NumericVector< T > &arg) const =0
将矩阵与 arg 相乘并将结果添加到 dest 中。
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的绝对值。
Definition: type_vector.h:112
T norm_sq(std::complex< T > a)
Definition: tensor_tools.h:74
dof_id_type numeric_index_type
Definition: id_types.h:99
LASPACK_SOLVERS
Definition: libmesh.C:251
virtual Real subset_l1_norm(const std::set< numeric_index_type > &indices) const
获取指定条目的向量的 -范数,即指定条目的绝对值之和。
virtual int local_relative_compare(const NumericVector< T > &other_vector, const Real threshold=TOLERANCE) const
比较该向量与另一个向量的局部相对差异。
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
构建一个 NumericVector 对象。
virtual numeric_index_type first_local_index() const =0
获取实际存储在该处理器上的第一个向量元素的索引。
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual numeric_index_type local_size() const =0
获取向量的本地大小,即 index_stop - index_start。
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:261
ADRealEigenVector< T, D, asd > norm(const ADRealEigenVector< T, D, asd > &)
计算自动微分实数向量的范数。
Definition: type_vector.h:64
通用的Shell矩阵,即一个仅定义其对向量的作用的矩阵。此类包含必须在派生类中重写的纯虚拟成员。
virtual numeric_index_type last_local_index() const =0
获取实际存储在该处理器上的最后一个向量元素的索引+1。
bool compatible(const NumericVector< T > &v) const
检查该向量和向量 v 是否能够一起用于全局操作。
virtual Real linfty_norm() const =0
获取向量的 -范数,即向量的最大绝对值。
virtual Real subset_l2_norm(const std::set< numeric_index_type > &indices) const
获取指定条目的向量的 -范数,即指定条目平方和的平方根。
Real l2_norm_diff(const NumericVector< T > &other_vec) const
获取 -范数的向量差值 , 其中 是 this。