16 #if defined(MFEM_USE_SUNDIALS) && defined(MFEM_USE_MPI)
17 #include <nvector/nvector_parallel.h>
18 #include <nvector/nvector_parhyp.h>
37 MFEM_ASSERT(v.
data,
"invalid source vector");
40 std::memcpy(
data, v.
data,
sizeof(
double)*s);
54 for (i = 0; i < np; i++)
62 for (i = 0; i < np; i++)
63 for (j = 0; j < dim[i]; j++)
73 for (
int i = 0; i <
size; i++)
92 const double *d =
data;
94 #ifdef MFEM_USE_OPENMP
95 #pragma omp parallel for reduction(+:prod)
97 for (
int i = 0; i < s; i++)
109 mfem_error(
"Vector::operator*(const Vector &) const");
121 std::memcpy(
data, v,
sizeof(
double)*
size);
135 double *p =
data, v = value;
136 for (i = 0; i < s; i++)
145 for (
int i = 0; i <
size; i++)
155 for (
int i = 0; i <
size; i++)
164 for (
int i = 0; i <
size; i++)
176 mfem_error(
"Vector::operator-=(const Vector &)");
179 for (
int i = 0; i <
size; i++)
191 mfem_error(
"Vector::operator+=(const Vector &)");
194 for (
int i = 0; i <
size; i++)
206 mfem_error(
"Vector::Add(const double, const Vector &)");
211 for (
int i = 0; i <
size; i++)
213 data[i] += a * Va(i);
224 mfem_error(
"Vector::Set(const double, const Vector &)");
227 for (
int i = 0; i <
size; i++)
237 double *vp = v.
data, *p =
data + offset;
240 if (offset+vs >
size)
242 mfem_error(
"Vector::SetVector(const Vector &, int)");
246 for (
int i = 0; i < vs; i++)
254 for (
int i = 0; i <
size; i++)
265 mfem_error(
"add(Vector &v1, Vector &v2, Vector &v)");
269 #ifdef MFEM_USE_OPENMP
270 #pragma omp parallel for
272 for (
int i = 0; i < v.
size; i++)
283 mfem_error (
"add(Vector &v1, double alpha, Vector &v2, Vector &v)");
290 else if (alpha == 1.0)
296 const double *v1p = v1.
data, *v2p = v2.
data;
299 #ifdef MFEM_USE_OPENMP
300 #pragma omp parallel for
302 for (
int i = 0; i < s; i++)
304 vp[i] = v1p[i] + alpha*v2p[i];
313 mfem_error (
"add(const double a, const Vector &x, const Vector &y,"
326 const double *xp = x.
data;
327 const double *yp = y.
data;
331 #ifdef MFEM_USE_OPENMP
332 #pragma omp parallel for
334 for (
int i = 0; i < s; i++)
336 zp[i] = a * (xp[i] + yp[i]);
346 mfem_error(
"add(const double a, const Vector &x,\n"
347 " const double b, const Vector &y, Vector &z)");
371 const double *xp = x.
data;
372 const double *yp = y.
data;
376 #ifdef MFEM_USE_OPENMP
377 #pragma omp parallel for
379 for (
int i = 0; i < s; i++)
381 zp[i] = a * xp[i] + b * yp[i];
391 mfem_error (
"subtract(const Vector &, const Vector &, Vector &)");
394 const double *xp = x.
data;
395 const double *yp = y.
data;
399 #ifdef MFEM_USE_OPENMP
400 #pragma omp parallel for
402 for (
int i = 0; i < s; i++)
404 zp[i] = xp[i] - yp[i];
412 mfem_error(
"subtract(const double a, const Vector &x,"
413 " const Vector &y, Vector &z)");
426 const double *xp = x.
data;
427 const double *yp = y.
data;
431 #ifdef MFEM_USE_OPENMP
432 #pragma omp parallel for
434 for (
int i = 0; i < s; i++)
436 zp[i] = a * (xp[i] - yp[i]);
445 for (
int i = 0; i <
size; i++)
451 else if (v[i] > hi[i])
460 int i, j, n = dofs.
Size();
464 for (i = 0; i < n; i++)
466 if ((j=dofs[i]) >= 0)
468 elemvect(i) =
data[j];
472 elemvect(i) = -
data[-1-j];
479 int i, j, n = dofs.
Size();
481 for (i = 0; i < n; i++)
483 if ((j=dofs[i]) >= 0)
485 elem_data[i] =
data[j];
489 elem_data[i] = -
data[-1-j];
496 const int n = dofs.
Size();
498 for (
int i = 0; i < n; i++)
500 const int j = dofs[i];
514 int i, j, n = dofs.
Size();
516 for (i = 0; i < n; i++)
518 if ((j=dofs[i]) >= 0)
520 data[j] = elemvect(i);
524 data[-1-j] = -elemvect(i);
531 int i, j, n = dofs.
Size();
533 for (i = 0; i < n; i++)
535 if ((j=dofs[i]) >= 0)
537 data[j] = elem_data[i];
541 data[-1-j] = -elem_data[i];
548 MFEM_ASSERT(dofs.
Size() == elemvect.
Size(),
"");
549 int i, j, n = dofs.
Size();
551 for (i = 0; i < n; i++)
553 if ((j=dofs[i]) >= 0)
555 data[j] += elemvect(i);
559 data[-1-j] -= elemvect(i);
566 int i, j, n = dofs.
Size();
568 for (i = 0; i < n; i++)
570 if ((j = dofs[i]) >= 0)
572 data[j] += elem_data[i];
576 data[-1-j] -= elem_data[i];
584 int i, j, n = dofs.
Size();
586 for (i = 0; i < n; i++)
587 if ((j=dofs[i]) >= 0)
589 data[j] += a * elemvect(i);
593 data[-1-j] -= a * elemvect(i);
607 if (!
size) {
return; }
617 if ( i % width == 0 )
632 std::ios::fmtflags old_fmt = out.flags();
633 out.setf(std::ios::scientific);
634 std::streamsize old_prec = out.precision(14);
638 for (i = 0; i <
size; i++)
640 out <<
data[i] <<
'\n';
643 out.precision(old_prec);
650 const double max = (double)(RAND_MAX) + 1.;
658 srand((
unsigned)seed);
660 for (
int i = 0; i <
size; i++)
662 data[i] = std::abs(rand()/max);
678 return std::abs(
data[0]);
684 for (
int i = 0; i <
size; i++)
688 const double absdata = std::abs(
data[i]);
689 if (scale <= absdata)
691 const double sqr_arg = scale / absdata;
692 sum = 1.0 + sum * (sqr_arg * sqr_arg);
696 const double sqr_arg = absdata / scale;
697 sum += (sqr_arg * sqr_arg);
700 return scale * std::sqrt(sum);
706 for (
int i = 0; i <
size; i++)
708 max = std::max(std::abs(
data[i]), max);
716 for (
int i = 0; i <
size; i++)
718 sum += std::abs(
data[i]);
725 MFEM_ASSERT(p > 0.0,
"Vector::Normlp");
746 return std::abs(
data[0]);
752 for (
int i = 0; i <
size; i++)
756 const double absdata = std::abs(
data[i]);
757 if (scale <= absdata)
759 sum = 1.0 + sum * std::pow(scale / absdata, p);
763 sum += std::pow(absdata / scale, p);
766 return scale * std::pow(sum, 1.0/p);
774 double max =
data[0];
776 for (
int i = 1; i <
size; i++)
787 double min =
data[0];
789 for (
int i = 1; i <
size; i++)
802 for (
int i = 0; i <
size; i++)
810 #ifdef MFEM_USE_SUNDIALS
816 #define SUNFALSE FALSE
821 N_Vector_ID nvid = N_VGetVectorID(nv);
824 case SUNDIALS_NVEC_SERIAL:
828 case SUNDIALS_NVEC_PARALLEL:
831 case SUNDIALS_NVEC_PARHYP:
833 hypre_Vector *hpv_local = N_VGetVector_ParHyp(nv)->local_vector;
839 MFEM_ABORT(
"N_Vector type " << nvid <<
" is not supported");
845 MFEM_ASSERT(nv,
"N_Vector handle is NULL");
846 N_Vector_ID nvid = N_VGetVectorID(nv);
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;
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;
860 case SUNDIALS_NVEC_PARHYP:
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;
870 MFEM_ABORT(
"N_Vector type " << nvid <<
" is not supported");
874 #endif // MFEM_USE_SUNDIALS
int Size() const
Logical size of the array.
void SetSubVector(const Array< int > &dofs, const double value)
Set the entries listed in dofs to the given value.
void SetVector(const Vector &v, int offset)
Vector()
Default constructor for Vector. Sets size = 0 and data = NULL.
double & Elem(int i)
Access Vector entries. Index i = 0 .. size-1.
void SetSize(int s)
Resize the vector to size s.
double Norml2() const
Returns the l2 norm of the vector.
double & operator()(int i)
Access Vector entries using () for 0-based indexing.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
int Size() const
Returns the size of the vector.
double Normlinf() const
Returns the l_infinity norm of the vector.
void Randomize(int seed=0)
Set random values in the vector.
void add(const Vector &v1, const Vector &v2, Vector &v)
double operator*(const double *) const
Dot product with a double * array.
Vector & operator=(const double *v)
Copy Size() entries from v.
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
double Normlp(double p) const
Returns the l_p norm of the vector.
void mfem_error(const char *msg)
Function called when an error is encountered. Used by the macros MFEM_ABORT, MFEM_ASSERT, MFEM_VERIFY.
void median(const Vector &lo, const Vector &hi)
v = median(v,lo,hi) entrywise. Implementation assumes lo <= hi.
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add (element) subvector to the vector.
Vector & operator/=(double c)
void SetSubVectorComplement(const Array< int > &dofs, const double val)
Set all vector entries NOT in the 'dofs' array to the given 'val'.
Vector & operator*=(double c)
double Min() const
Returns the minimal element of the vector.
double Norml1() const
Returns the l_1 norm of the vector.
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
void subtract(const Vector &x, const Vector &y, Vector &z)
void Print_HYPRE(std::ostream &out) const
Prints vector to stream out in HYPRE_Vector format.
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Vector & Set(const double a, const Vector &x)
(*this) = a * x
Vector & Add(const double a, const Vector &Va)
(*this) += a * Va
double Max() const
Returns the maximal element of the vector.
Vector & operator-=(double c)
double infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
Vector & operator+=(const Vector &v)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
double Sum() const
Return the sum of the vector entries.
virtual N_Vector ToNVector()
Return a new wrapper SUNDIALS N_Vector of type SUNDIALS_NVEC_SERIAL.
void Neg()
(*this) = -(*this)