16 #if defined(MFEM_USE_SUNDIALS) && defined(MFEM_USE_MPI)
17 #include <nvector/nvector_parallel.h>
18 #include <nvector/nvector_parhyp.h>
38 for (
int i = 0; i < s; i++)
55 for (i = 0; i < np; i++)
63 for (i = 0; i < np; i++)
64 for (j = 0; j < dim[i]; j++)
74 for (
int i = 0; i <
size; i++)
93 const double *d =
data;
95 #ifdef MFEM_USE_OPENMP
96 #pragma omp parallel for reduction(+:prod)
98 for (
int i = 0; i < s; i++)
110 mfem_error(
"Vector::operator*(const Vector &) const");
119 for (
int i = 0; i <
size; i++)
129 for (
int i = 0; i <
size; i++)
139 double *p =
data, v = value;
140 for (i = 0; i < s; i++)
149 for (
int i = 0; i <
size; i++)
159 for (
int i = 0; i <
size; i++)
168 for (
int i = 0; i <
size; i++)
180 mfem_error(
"Vector::operator-=(const Vector &)");
183 for (
int i = 0; i <
size; i++)
195 mfem_error(
"Vector::operator+=(const Vector &)");
198 for (
int i = 0; i <
size; i++)
210 mfem_error(
"Vector::Add(const double, const Vector &)");
215 for (
int i = 0; i <
size; i++)
217 data[i] += a * Va(i);
228 mfem_error(
"Vector::Set(const double, const Vector &)");
231 for (
int i = 0; i <
size; i++)
241 double *vp = v.
data, *p =
data + offset;
244 if (offset+vs >
size)
246 mfem_error(
"Vector::SetVector(const Vector &, int)");
250 for (
int i = 0; i < vs; i++)
258 for (
int i = 0; i <
size; i++)
269 mfem_error(
"add(Vector &v1, Vector &v2, Vector &v)");
273 #ifdef MFEM_USE_OPENMP
274 #pragma omp parallel for
276 for (
int i = 0; i < v.
size; i++)
287 mfem_error (
"add(Vector &v1, double alpha, Vector &v2, Vector &v)");
294 else if (alpha == 1.0)
300 const double *v1p = v1.
data, *v2p = v2.
data;
303 #ifdef MFEM_USE_OPENMP
304 #pragma omp parallel for
306 for (
int i = 0; i < s; i++)
308 vp[i] = v1p[i] + alpha*v2p[i];
317 mfem_error (
"add(const double a, const Vector &x, const Vector &y,"
330 const double *xp = x.
data;
331 const double *yp = y.
data;
335 #ifdef MFEM_USE_OPENMP
336 #pragma omp parallel for
338 for (
int i = 0; i < s; i++)
340 zp[i] = a * (xp[i] + yp[i]);
350 mfem_error(
"add(const double a, const Vector &x,\n"
351 " const double b, const Vector &y, Vector &z)");
375 const double *xp = x.
data;
376 const double *yp = y.
data;
380 #ifdef MFEM_USE_OPENMP
381 #pragma omp parallel for
383 for (
int i = 0; i < s; i++)
385 zp[i] = a * xp[i] + b * yp[i];
395 mfem_error (
"subtract(const Vector &, const Vector &, Vector &)");
398 const double *xp = x.
data;
399 const double *yp = y.
data;
403 #ifdef MFEM_USE_OPENMP
404 #pragma omp parallel for
406 for (
int i = 0; i < s; i++)
408 zp[i] = xp[i] - yp[i];
416 mfem_error(
"subtract(const double a, const Vector &x,"
417 " const Vector &y, Vector &z)");
430 const double *xp = x.
data;
431 const double *yp = y.
data;
435 #ifdef MFEM_USE_OPENMP
436 #pragma omp parallel for
438 for (
int i = 0; i < s; i++)
440 zp[i] = a * (xp[i] - yp[i]);
449 for (
int i = 0; i <
size; i++)
455 else if (v[i] > hi[i])
464 int i, j, n = dofs.
Size();
468 for (i = 0; i < n; i++)
470 if ((j=dofs[i]) >= 0)
472 elemvect(i) =
data[j];
476 elemvect(i) = -
data[-1-j];
483 int i, j, n = dofs.
Size();
485 for (i = 0; i < n; i++)
487 if ((j=dofs[i]) >= 0)
489 elem_data[i] =
data[j];
493 elem_data[i] = -
data[-1-j];
500 const int n = dofs.
Size();
502 for (
int i = 0; i < n; i++)
504 const int j = dofs[i];
518 int i, j, n = dofs.
Size();
520 for (i = 0; i < n; i++)
522 if ((j=dofs[i]) >= 0)
524 data[j] = elemvect(i);
528 data[-1-j] = -elemvect(i);
535 int i, j, n = dofs.
Size();
537 for (i = 0; i < n; i++)
539 if ((j=dofs[i]) >= 0)
541 data[j] = elem_data[i];
545 data[-1-j] = -elem_data[i];
552 MFEM_ASSERT(dofs.
Size() == elemvect.
Size(),
"");
553 int i, j, n = dofs.
Size();
555 for (i = 0; i < n; i++)
557 if ((j=dofs[i]) >= 0)
559 data[j] += elemvect(i);
563 data[-1-j] -= elemvect(i);
570 int i, j, n = dofs.
Size();
572 for (i = 0; i < n; i++)
574 if ((j = dofs[i]) >= 0)
576 data[j] += elem_data[i];
580 data[-1-j] -= elem_data[i];
588 int i, j, n = dofs.
Size();
590 for (i = 0; i < n; i++)
591 if ((j=dofs[i]) >= 0)
593 data[j] += a * elemvect(i);
597 data[-1-j] -= a * elemvect(i);
611 if (!
size) {
return; }
621 if ( i % width == 0 )
636 std::ios::fmtflags old_fmt = out.flags();
637 out.setf(std::ios::scientific);
638 std::streamsize old_prec = out.precision(14);
642 for (i = 0; i <
size; i++)
644 out <<
data[i] <<
'\n';
647 out.precision(old_prec);
654 const double max = (double)(RAND_MAX) + 1.;
662 srand((
unsigned)seed);
664 for (
int i = 0; i <
size; i++)
666 data[i] = std::abs(rand()/max);
682 return std::abs(
data[0]);
688 for (
int i = 0; i <
size; i++)
692 const double absdata = std::abs(
data[i]);
693 if (scale <= absdata)
695 const double sqr_arg = scale / absdata;
696 sum = 1.0 + sum * (sqr_arg * sqr_arg);
700 const double sqr_arg = absdata / scale;
701 sum += (sqr_arg * sqr_arg);
704 return scale * std::sqrt(sum);
710 for (
int i = 0; i <
size; i++)
712 max = std::max(std::abs(
data[i]), max);
720 for (
int i = 0; i <
size; i++)
722 sum += std::abs(
data[i]);
729 MFEM_ASSERT(p > 0.0,
"Vector::Normlp");
738 if (p < std::numeric_limits<double>::infinity())
750 return std::abs(
data[0]);
756 for (
int i = 0; i <
size; i++)
760 const double absdata = std::abs(
data[i]);
761 if (scale <= absdata)
763 sum = 1.0 + sum * std::pow(scale / absdata, p);
767 sum += std::pow(absdata / scale, p);
770 return scale * std::pow(sum, 1.0/p);
778 double max =
data[0];
780 for (
int i = 1; i <
size; i++)
791 double min =
data[0];
793 for (
int i = 1; i <
size; i++)
806 for (
int i = 0; i <
size; i++)
814 #ifdef MFEM_USE_SUNDIALS
820 #define SUNFALSE FALSE
825 N_Vector_ID nvid = N_VGetVectorID(nv);
828 case SUNDIALS_NVEC_SERIAL:
832 case SUNDIALS_NVEC_PARALLEL:
835 case SUNDIALS_NVEC_PARHYP:
837 hypre_Vector *hpv_local = N_VGetVector_ParHyp(nv)->local_vector;
843 MFEM_ABORT(
"N_Vector type " << nvid <<
" is not supported");
849 MFEM_ASSERT(nv,
"N_Vector handle is NULL");
850 N_Vector_ID nvid = N_VGetVectorID(nv);
853 case SUNDIALS_NVEC_SERIAL:
854 MFEM_ASSERT(NV_OWN_DATA_S(nv) == SUNFALSE,
"invalid serial N_Vector");
855 NV_DATA_S(nv) =
data;
856 NV_LENGTH_S(nv) =
size;
859 case SUNDIALS_NVEC_PARALLEL:
860 MFEM_ASSERT(NV_OWN_DATA_P(nv) == SUNFALSE,
"invalid parallel N_Vector");
861 NV_DATA_P(nv) =
data;
862 NV_LOCLENGTH_P(nv) =
size;
864 case SUNDIALS_NVEC_PARHYP:
866 hypre_Vector *hpv_local = N_VGetVector_ParHyp(nv)->local_vector;
867 MFEM_ASSERT(hpv_local->owns_data ==
false,
"invalid hypre N_Vector");
868 hpv_local->data =
data;
869 hpv_local->size =
size;
874 MFEM_ABORT(
"N_Vector type " << nvid <<
" is not supported");
878 #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 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 mfem_error(const char *msg)
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)
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)