MFEM  v3.4
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
vector.cpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 // Implementation of data type vector
13 
14 #include "vector.hpp"
15 
16 #if defined(MFEM_USE_SUNDIALS) && defined(MFEM_USE_MPI)
17 #include <nvector/nvector_parallel.h>
18 #include <nvector/nvector_parhyp.h>
19 #endif
20 
21 #include <iostream>
22 #include <iomanip>
23 #include <cmath>
24 #include <cstdlib>
25 #include <ctime>
26 #include <limits>
27 
28 namespace mfem
29 {
30 
32 {
33  int s = v.Size();
34 
35  if (s > 0)
36  {
37  MFEM_ASSERT(v.data, "invalid source vector");
38  allocsize = size = s;
39  data = new double[s];
40  std::memcpy(data, v.data, sizeof(double)*s);
41  }
42  else
43  {
44  allocsize = size = 0;
45  data = NULL;
46  }
47 }
48 
49 void Vector::Load(std::istream **in, int np, int *dim)
50 {
51  int i, j, s;
52 
53  s = 0;
54  for (i = 0; i < np; i++)
55  {
56  s += dim[i];
57  }
58 
59  SetSize(s);
60 
61  int p = 0;
62  for (i = 0; i < np; i++)
63  for (j = 0; j < dim[i]; j++)
64  {
65  *in[i] >> data[p++];
66  }
67 }
68 
69 void Vector::Load(std::istream &in, int Size)
70 {
71  SetSize(Size);
72 
73  for (int i = 0; i < size; i++)
74  {
75  in >> data[i];
76  }
77 }
78 
79 double &Vector::Elem(int i)
80 {
81  return operator()(i);
82 }
83 
84 const double &Vector::Elem(int i) const
85 {
86  return operator()(i);
87 }
88 
89 double Vector::operator*(const double *v) const
90 {
91  int s = size;
92  const double *d = data;
93  double prod = 0.0;
94 #ifdef MFEM_USE_OPENMP
95  #pragma omp parallel for reduction(+:prod)
96 #endif
97  for (int i = 0; i < s; i++)
98  {
99  prod += d[i] * v[i];
100  }
101  return prod;
102 }
103 
104 double Vector::operator*(const Vector &v) const
105 {
106 #ifdef MFEM_DEBUG
107  if (v.size != size)
108  {
109  mfem_error("Vector::operator*(const Vector &) const");
110  }
111 #endif
112 
113  return operator*(v.data);
114 }
115 
116 Vector &Vector::operator=(const double *v)
117 {
118  if (data != v)
119  {
120  MFEM_ASSERT(data + size <= v || v + size <= data, "Vectors overlap!");
121  std::memcpy(data, v, sizeof(double)*size);
122  }
123  return *this;
124 }
125 
127 {
128  SetSize(v.Size());
129  return operator=(v.data);
130 }
131 
132 Vector &Vector::operator=(double value)
133 {
134  int i, s = size;
135  double *p = data, v = value;
136  for (i = 0; i < s; i++)
137  {
138  *(p++) = v;
139  }
140  return *this;
141 }
142 
144 {
145  for (int i = 0; i < size; i++)
146  {
147  data[i] *= c;
148  }
149  return *this;
150 }
151 
153 {
154  double m = 1.0/c;
155  for (int i = 0; i < size; i++)
156  {
157  data[i] *= m;
158  }
159  return *this;
160 }
161 
163 {
164  for (int i = 0; i < size; i++)
165  {
166  data[i] -= c;
167  }
168  return *this;
169 }
170 
172 {
173 #ifdef MFEM_DEBUG
174  if (size != v.size)
175  {
176  mfem_error("Vector::operator-=(const Vector &)");
177  }
178 #endif
179  for (int i = 0; i < size; i++)
180  {
181  data[i] -= v(i);
182  }
183  return *this;
184 }
185 
187 {
188 #ifdef MFEM_DEBUG
189  if (size != v.size)
190  {
191  mfem_error("Vector::operator+=(const Vector &)");
192  }
193 #endif
194  for (int i = 0; i < size; i++)
195  {
196  data[i] += v(i);
197  }
198  return *this;
199 }
200 
201 Vector &Vector::Add(const double a, const Vector &Va)
202 {
203 #ifdef MFEM_DEBUG
204  if (size != Va.size)
205  {
206  mfem_error("Vector::Add(const double, const Vector &)");
207  }
208 #endif
209  if (a != 0.0)
210  {
211  for (int i = 0; i < size; i++)
212  {
213  data[i] += a * Va(i);
214  }
215  }
216  return *this;
217 }
218 
219 Vector &Vector::Set(const double a, const Vector &Va)
220 {
221 #ifdef MFEM_DEBUG
222  if (size != Va.size)
223  {
224  mfem_error("Vector::Set(const double, const Vector &)");
225  }
226 #endif
227  for (int i = 0; i < size; i++)
228  {
229  data[i] = a * Va(i);
230  }
231  return *this;
232 }
233 
234 void Vector::SetVector(const Vector &v, int offset)
235 {
236  int vs = v.Size();
237  double *vp = v.data, *p = data + offset;
238 
239 #ifdef MFEM_DEBUG
240  if (offset+vs > size)
241  {
242  mfem_error("Vector::SetVector(const Vector &, int)");
243  }
244 #endif
245 
246  for (int i = 0; i < vs; i++)
247  {
248  p[i] = vp[i];
249  }
250 }
251 
253 {
254  for (int i = 0; i < size; i++)
255  {
256  data[i] = -data[i];
257  }
258 }
259 
260 void add(const Vector &v1, const Vector &v2, Vector &v)
261 {
262 #ifdef MFEM_DEBUG
263  if (v.size != v1.size || v.size != v2.size)
264  {
265  mfem_error("add(Vector &v1, Vector &v2, Vector &v)");
266  }
267 #endif
268 
269 #ifdef MFEM_USE_OPENMP
270  #pragma omp parallel for
271 #endif
272  for (int i = 0; i < v.size; i++)
273  {
274  v.data[i] = v1.data[i] + v2.data[i];
275  }
276 }
277 
278 void add(const Vector &v1, double alpha, const Vector &v2, Vector &v)
279 {
280 #ifdef MFEM_DEBUG
281  if (v.size != v1.size || v.size != v2.size)
282  {
283  mfem_error ("add(Vector &v1, double alpha, Vector &v2, Vector &v)");
284  }
285 #endif
286  if (alpha == 0.0)
287  {
288  v = v1;
289  }
290  else if (alpha == 1.0)
291  {
292  add(v1, v2, v);
293  }
294  else
295  {
296  const double *v1p = v1.data, *v2p = v2.data;
297  double *vp = v.data;
298  int s = v.size;
299 #ifdef MFEM_USE_OPENMP
300  #pragma omp parallel for
301 #endif
302  for (int i = 0; i < s; i++)
303  {
304  vp[i] = v1p[i] + alpha*v2p[i];
305  }
306  }
307 }
308 
309 void add(const double a, const Vector &x, const Vector &y, Vector &z)
310 {
311 #ifdef MFEM_DEBUG
312  if (x.size != y.size || x.size != z.size)
313  mfem_error ("add(const double a, const Vector &x, const Vector &y,"
314  " Vector &z)");
315 #endif
316  if (a == 0.0)
317  {
318  z = 0.0;
319  }
320  else if (a == 1.0)
321  {
322  add(x, y, z);
323  }
324  else
325  {
326  const double *xp = x.data;
327  const double *yp = y.data;
328  double *zp = z.data;
329  int s = x.size;
330 
331 #ifdef MFEM_USE_OPENMP
332  #pragma omp parallel for
333 #endif
334  for (int i = 0; i < s; i++)
335  {
336  zp[i] = a * (xp[i] + yp[i]);
337  }
338  }
339 }
340 
341 void add(const double a, const Vector &x,
342  const double b, const Vector &y, Vector &z)
343 {
344 #ifdef MFEM_DEBUG
345  if (x.size != y.size || x.size != z.size)
346  mfem_error("add(const double a, const Vector &x,\n"
347  " const double b, const Vector &y, Vector &z)");
348 #endif
349  if (a == 0.0)
350  {
351  z.Set(b, y);
352  }
353  else if (b == 0.0)
354  {
355  z.Set(a, x);
356  }
357  else if (a == 1.0)
358  {
359  add(x, b, y, z);
360  }
361  else if (b == 1.0)
362  {
363  add(y, a, x, z);
364  }
365  else if (a == b)
366  {
367  add(a, x, y, z);
368  }
369  else
370  {
371  const double *xp = x.data;
372  const double *yp = y.data;
373  double *zp = z.data;
374  int s = x.size;
375 
376 #ifdef MFEM_USE_OPENMP
377  #pragma omp parallel for
378 #endif
379  for (int i = 0; i < s; i++)
380  {
381  zp[i] = a * xp[i] + b * yp[i];
382  }
383  }
384 }
385 
386 void subtract(const Vector &x, const Vector &y, Vector &z)
387 {
388 #ifdef MFEM_DEBUG
389  if (x.size != y.size || x.size != z.size)
390  {
391  mfem_error ("subtract(const Vector &, const Vector &, Vector &)");
392  }
393 #endif
394  const double *xp = x.data;
395  const double *yp = y.data;
396  double *zp = z.data;
397  int s = x.size;
398 
399 #ifdef MFEM_USE_OPENMP
400  #pragma omp parallel for
401 #endif
402  for (int i = 0; i < s; i++)
403  {
404  zp[i] = xp[i] - yp[i];
405  }
406 }
407 
408 void subtract(const double a, const Vector &x, const Vector &y, Vector &z)
409 {
410 #ifdef MFEM_DEBUG
411  if (x.size != y.size || x.size != z.size)
412  mfem_error("subtract(const double a, const Vector &x,"
413  " const Vector &y, Vector &z)");
414 #endif
415 
416  if (a == 0.)
417  {
418  z = 0.;
419  }
420  else if (a == 1.)
421  {
422  subtract(x, y, z);
423  }
424  else
425  {
426  const double *xp = x.data;
427  const double *yp = y.data;
428  double *zp = z.data;
429  int s = x.size;
430 
431 #ifdef MFEM_USE_OPENMP
432  #pragma omp parallel for
433 #endif
434  for (int i = 0; i < s; i++)
435  {
436  zp[i] = a * (xp[i] - yp[i]);
437  }
438  }
439 }
440 
441 void Vector::median(const Vector &lo, const Vector &hi)
442 {
443  double *v = data;
444 
445  for (int i = 0; i < size; i++)
446  {
447  if (v[i] < lo[i])
448  {
449  v[i] = lo[i];
450  }
451  else if (v[i] > hi[i])
452  {
453  v[i] = hi[i];
454  }
455  }
456 }
457 
458 void Vector::GetSubVector(const Array<int> &dofs, Vector &elemvect) const
459 {
460  int i, j, n = dofs.Size();
461 
462  elemvect.SetSize (n);
463 
464  for (i = 0; i < n; i++)
465  {
466  if ((j=dofs[i]) >= 0)
467  {
468  elemvect(i) = data[j];
469  }
470  else
471  {
472  elemvect(i) = -data[-1-j];
473  }
474  }
475 }
476 
477 void Vector::GetSubVector(const Array<int> &dofs, double *elem_data) const
478 {
479  int i, j, n = dofs.Size();
480 
481  for (i = 0; i < n; i++)
482  {
483  if ((j=dofs[i]) >= 0)
484  {
485  elem_data[i] = data[j];
486  }
487  else
488  {
489  elem_data[i] = -data[-1-j];
490  }
491  }
492 }
493 
494 void Vector::SetSubVector(const Array<int> &dofs, const double value)
495 {
496  const int n = dofs.Size();
497 
498  for (int i = 0; i < n; i++)
499  {
500  const int j = dofs[i];
501  if (j >= 0)
502  {
503  data[j] = value;
504  }
505  else
506  {
507  data[-1-j] = -value;
508  }
509  }
510 }
511 
512 void Vector::SetSubVector(const Array<int> &dofs, const Vector &elemvect)
513 {
514  int i, j, n = dofs.Size();
515 
516  for (i = 0; i < n; i++)
517  {
518  if ((j=dofs[i]) >= 0)
519  {
520  data[j] = elemvect(i);
521  }
522  else
523  {
524  data[-1-j] = -elemvect(i);
525  }
526  }
527 }
528 
529 void Vector::SetSubVector(const Array<int> &dofs, double *elem_data)
530 {
531  int i, j, n = dofs.Size();
532 
533  for (i = 0; i < n; i++)
534  {
535  if ((j=dofs[i]) >= 0)
536  {
537  data[j] = elem_data[i];
538  }
539  else
540  {
541  data[-1-j] = -elem_data[i];
542  }
543  }
544 }
545 
546 void Vector::AddElementVector(const Array<int> &dofs, const Vector &elemvect)
547 {
548  MFEM_ASSERT(dofs.Size() == elemvect.Size(), "");
549  int i, j, n = dofs.Size();
550 
551  for (i = 0; i < n; i++)
552  {
553  if ((j=dofs[i]) >= 0)
554  {
555  data[j] += elemvect(i);
556  }
557  else
558  {
559  data[-1-j] -= elemvect(i);
560  }
561  }
562 }
563 
564 void Vector::AddElementVector(const Array<int> &dofs, double *elem_data)
565 {
566  int i, j, n = dofs.Size();
567 
568  for (i = 0; i < n; i++)
569  {
570  if ((j = dofs[i]) >= 0)
571  {
572  data[j] += elem_data[i];
573  }
574  else
575  {
576  data[-1-j] -= elem_data[i];
577  }
578  }
579 }
580 
581 void Vector::AddElementVector(const Array<int> &dofs, const double a,
582  const Vector &elemvect)
583 {
584  int i, j, n = dofs.Size();
585 
586  for (i = 0; i < n; i++)
587  if ((j=dofs[i]) >= 0)
588  {
589  data[j] += a * elemvect(i);
590  }
591  else
592  {
593  data[-1-j] -= a * elemvect(i);
594  }
595 }
596 
597 void Vector::SetSubVectorComplement(const Array<int> &dofs, const double val)
598 {
599  Vector dofs_vals;
600  GetSubVector(dofs, dofs_vals);
601  operator=(val);
602  SetSubVector(dofs, dofs_vals);
603 }
604 
605 void Vector::Print(std::ostream &out, int width) const
606 {
607  if (!size) { return; }
608 
609  for (int i = 0; 1; )
610  {
611  out << data[i];
612  i++;
613  if (i == size)
614  {
615  break;
616  }
617  if ( i % width == 0 )
618  {
619  out << '\n';
620  }
621  else
622  {
623  out << ' ';
624  }
625  }
626  out << '\n';
627 }
628 
629 void Vector::Print_HYPRE(std::ostream &out) const
630 {
631  int i;
632  std::ios::fmtflags old_fmt = out.flags();
633  out.setf(std::ios::scientific);
634  std::streamsize old_prec = out.precision(14);
635 
636  out << size << '\n'; // number of rows
637 
638  for (i = 0; i < size; i++)
639  {
640  out << data[i] << '\n';
641  }
642 
643  out.precision(old_prec);
644  out.flags(old_fmt);
645 }
646 
647 void Vector::Randomize(int seed)
648 {
649  // static unsigned int seed = time(0);
650  const double max = (double)(RAND_MAX) + 1.;
651 
652  if (seed == 0)
653  {
654  seed = (int)time(0);
655  }
656 
657  // srand(seed++);
658  srand((unsigned)seed);
659 
660  for (int i = 0; i < size; i++)
661  {
662  data[i] = std::abs(rand()/max);
663  }
664 }
665 
666 double Vector::Norml2() const
667 {
668  // Scale entries of Vector on the fly, using algorithms from
669  // std::hypot() and LAPACK's drm2. This scaling ensures that the
670  // argument of each call to std::pow is <= 1 to avoid overflow.
671  if (0 == size)
672  {
673  return 0.0;
674  } // end if 0 == size
675 
676  if (1 == size)
677  {
678  return std::abs(data[0]);
679  } // end if 1 == size
680 
681  double scale = 0.0;
682  double sum = 0.0;
683 
684  for (int i = 0; i < size; i++)
685  {
686  if (data[i] != 0.0)
687  {
688  const double absdata = std::abs(data[i]);
689  if (scale <= absdata)
690  {
691  const double sqr_arg = scale / absdata;
692  sum = 1.0 + sum * (sqr_arg * sqr_arg);
693  scale = absdata;
694  continue;
695  } // end if scale <= absdata
696  const double sqr_arg = absdata / scale;
697  sum += (sqr_arg * sqr_arg); // else scale > absdata
698  } // end if data[i] != 0
699  }
700  return scale * std::sqrt(sum);
701 }
702 
703 double Vector::Normlinf() const
704 {
705  double max = 0.0;
706  for (int i = 0; i < size; i++)
707  {
708  max = std::max(std::abs(data[i]), max);
709  }
710  return max;
711 }
712 
713 double Vector::Norml1() const
714 {
715  double sum = 0.0;
716  for (int i = 0; i < size; i++)
717  {
718  sum += std::abs(data[i]);
719  }
720  return sum;
721 }
722 
723 double Vector::Normlp(double p) const
724 {
725  MFEM_ASSERT(p > 0.0, "Vector::Normlp");
726  if (p == 1.0)
727  {
728  return Norml1();
729  }
730  if (p == 2.0)
731  {
732  return Norml2();
733  }
734  if (p < infinity())
735  {
736  // Scale entries of Vector on the fly, using algorithms from
737  // std::hypot() and LAPACK's drm2. This scaling ensures that the
738  // argument of each call to std::pow is <= 1 to avoid overflow.
739  if (0 == size)
740  {
741  return 0.0;
742  } // end if 0 == size
743 
744  if (1 == size)
745  {
746  return std::abs(data[0]);
747  } // end if 1 == size
748 
749  double scale = 0.0;
750  double sum = 0.0;
751 
752  for (int i = 0; i < size; i++)
753  {
754  if (data[i] != 0.0)
755  {
756  const double absdata = std::abs(data[i]);
757  if (scale <= absdata)
758  {
759  sum = 1.0 + sum * std::pow(scale / absdata, p);
760  scale = absdata;
761  continue;
762  } // end if scale <= absdata
763  sum += std::pow(absdata / scale, p); // else scale > absdata
764  } // end if data[i] != 0
765  }
766  return scale * std::pow(sum, 1.0/p);
767  } // end if p < infinity()
768 
769  return Normlinf(); // else p >= infinity()
770 }
771 
772 double Vector::Max() const
773 {
774  double max = data[0];
775 
776  for (int i = 1; i < size; i++)
777  if (data[i] > max)
778  {
779  max = data[i];
780  }
781 
782  return max;
783 }
784 
785 double Vector::Min() const
786 {
787  double min = data[0];
788 
789  for (int i = 1; i < size; i++)
790  if (data[i] < min)
791  {
792  min = data[i];
793  }
794 
795  return min;
796 }
797 
798 double Vector::Sum() const
799 {
800  double sum = 0.0;
801 
802  for (int i = 0; i < size; i++)
803  {
804  sum += data[i];
805  }
806 
807  return sum;
808 }
809 
810 #ifdef MFEM_USE_SUNDIALS
811 
812 #ifndef SUNTRUE
813 #define SUNTRUE TRUE
814 #endif
815 #ifndef SUNFALSE
816 #define SUNFALSE FALSE
817 #endif
818 
819 Vector::Vector(N_Vector nv)
820 {
821  N_Vector_ID nvid = N_VGetVectorID(nv);
822  switch (nvid)
823  {
824  case SUNDIALS_NVEC_SERIAL:
825  SetDataAndSize(NV_DATA_S(nv), NV_LENGTH_S(nv));
826  break;
827 #ifdef MFEM_USE_MPI
828  case SUNDIALS_NVEC_PARALLEL:
829  SetDataAndSize(NV_DATA_P(nv), NV_LOCLENGTH_P(nv));
830  break;
831  case SUNDIALS_NVEC_PARHYP:
832  {
833  hypre_Vector *hpv_local = N_VGetVector_ParHyp(nv)->local_vector;
834  SetDataAndSize(hpv_local->data, hpv_local->size);
835  break;
836  }
837 #endif
838  default:
839  MFEM_ABORT("N_Vector type " << nvid << " is not supported");
840  }
841 }
842 
843 void Vector::ToNVector(N_Vector &nv)
844 {
845  MFEM_ASSERT(nv, "N_Vector handle is NULL");
846  N_Vector_ID nvid = N_VGetVectorID(nv);
847  switch (nvid)
848  {
849  case SUNDIALS_NVEC_SERIAL:
850  MFEM_ASSERT(NV_OWN_DATA_S(nv) == SUNFALSE, "invalid serial N_Vector");
851  NV_DATA_S(nv) = data;
852  NV_LENGTH_S(nv) = size;
853  break;
854 #ifdef MFEM_USE_MPI
855  case SUNDIALS_NVEC_PARALLEL:
856  MFEM_ASSERT(NV_OWN_DATA_P(nv) == SUNFALSE, "invalid parallel N_Vector");
857  NV_DATA_P(nv) = data;
858  NV_LOCLENGTH_P(nv) = size;
859  break;
860  case SUNDIALS_NVEC_PARHYP:
861  {
862  hypre_Vector *hpv_local = N_VGetVector_ParHyp(nv)->local_vector;
863  MFEM_ASSERT(hpv_local->owns_data == false, "invalid hypre N_Vector");
864  hpv_local->data = data;
865  hpv_local->size = size;
866  break;
867  }
868 #endif
869  default:
870  MFEM_ABORT("N_Vector type " << nvid << " is not supported");
871  }
872 }
873 
874 #endif // MFEM_USE_SUNDIALS
875 
876 }
int Size() const
Logical size of the array.
Definition: array.hpp:133
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
Definition: vector.cpp:494
void SetVector(const Vector &v, int offset)
Definition: vector.cpp:234
Vector()
Default constructor for Vector. Sets size = 0 and data = NULL.
Definition: vector.hpp:58
double & Elem(int i)
Access Vector entries. Index i = 0 .. size-1.
Definition: vector.cpp:79
void SetSize(int s)
Resize the vector to size s.
Definition: vector.hpp:328
double Norml2() const
Returns the l2 norm of the vector.
Definition: vector.cpp:666
double & operator()(int i)
Access Vector entries using () for 0-based indexing.
Definition: vector.hpp:357
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Definition: vector.cpp:458
int Size() const
Returns the size of the vector.
Definition: vector.hpp:120
double Normlinf() const
Returns the l_infinity norm of the vector.
Definition: vector.cpp:703
void Randomize(int seed=0)
Set random values in the vector.
Definition: vector.cpp:647
void add(const Vector &v1, const Vector &v2, Vector &v)
Definition: vector.cpp:260
double operator*(const double *) const
Dot product with a double * array.
Definition: vector.cpp:89
Vector & operator=(const double *v)
Copy Size() entries from v.
Definition: vector.cpp:116
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
Definition: vector.cpp:49
double Normlp(double p) const
Returns the l_p norm of the vector.
Definition: vector.cpp:723
int dim
Definition: ex3.cpp:47
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
Definition: error.cpp:146
void median(const Vector &lo, const Vector &hi)
v = median(v,lo,hi) entrywise. Implementation assumes lo &lt;= hi.
Definition: vector.cpp:441
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add (element) subvector to the vector.
Definition: vector.cpp:546
Vector & operator/=(double c)
Definition: vector.cpp:152
void SetSubVectorComplement(const Array< int > &dofs, const double val)
Set all vector entries NOT in the &#39;dofs&#39; array to the given &#39;val&#39;.
Definition: vector.cpp:597
Vector & operator*=(double c)
Definition: vector.cpp:143
double Min() const
Returns the minimal element of the vector.
Definition: vector.cpp:785
double Norml1() const
Returns the l_1 norm of the vector.
Definition: vector.cpp:713
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
Definition: vector.cpp:605
void subtract(const Vector &x, const Vector &y, Vector &z)
Definition: vector.cpp:386
void Print_HYPRE(std::ostream &out) const
Prints vector to stream out in HYPRE_Vector format.
Definition: vector.cpp:629
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:101
Vector & Set(const double a, const Vector &x)
(*this) = a * x
Definition: vector.cpp:219
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
Definition: vector.cpp:201
double Max() const
Returns the maximal element of the vector.
Definition: vector.cpp:772
Vector & operator-=(double c)
Definition: vector.cpp:162
double infinity()
Define a shortcut for std::numeric_limits&lt;double&gt;::infinity()
Definition: vector.hpp:42
const double alpha
Definition: ex15.cpp:337
Vector data type.
Definition: vector.hpp:48
int allocsize
Definition: vector.hpp:52
Vector & operator+=(const Vector &v)
Definition: vector.cpp:186
double * data
Definition: vector.hpp:53
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:64
double Sum() const
Return the sum of the vector entries.
Definition: vector.cpp:798
virtual N_Vector ToNVector()
Return a new wrapper SUNDIALS N_Vector of type SUNDIALS_NVEC_SERIAL.
Definition: vector.hpp:283
void Neg()
(*this) = -(*this)
Definition: vector.cpp:252