# Description of the NVECTOR operations¶

The standard vector operations defined by the generic N_Vector module are defined as follows. For each of these operations, we give the name, usage of the function, and a description of its mathematical operations below.

N_Vector_ID N_VGetVectorID(N_Vector w)

Returns the vector type identifier for the vector w. It is used to determine the vector implementation type (e.g. serial, parallel, …) from the abstract N_Vector interface. Returned values are given in the table, Vector Identifications associated with vector kernels supplied with SUNDIALS

Usage:

id = N_VGetVectorID(w);

N_Vector N_VClone(N_Vector w)

Creates a new N_Vector of the same type as an existing vector w and sets the ops field. It does not copy the vector, but rather allocates storage for the new vector.

Usage:

v = N_VClone(w);

N_Vector N_VCloneEmpty(N_Vector w)

Creates a new N_Vector of the same type as an existing vector w and sets the ops field. It does not allocate storage for the new vector’s data.

Usage:

v = N VCloneEmpty(w);

void N_VDestroy(N_Vector v)

Destroys the N_Vector v and frees memory allocated for its internal data.

Usage:

N_VDestroy(v);

void N_VSpace(N_Vector v, sunindextype* lrw, sunindextype* liw)

Returns storage requirements for the N_Vector v: lrw contains the number of realtype words and liw contains the number of integer words. This function is advisory only, for use in determining a user’s total space requirements; it could be a dummy function in a user-supplied NVECTOR module if that information is not of interest.

Usage:

N_VSpace(nvSpec, &lrw, &liw);

realtype* N_VGetArrayPointer(N_Vector v)

Returns a pointer to a realtype array from the N_Vector v. Note that this assumes that the internal data in the N_Vector is a contiguous array of realtype. This routine is only used in the solver-specific interfaces to the dense and banded (serial) linear solvers, and in the interfaces to the banded (serial) and band-block-diagonal (parallel) preconditioner modules provided with SUNDIALS.

Usage:

vdata = N_VGetArrayPointer(v);

void N_VSetArrayPointer(realtype* vdata, N_Vector v)

Replaces the data array pointer in an N_Vector with a given array of realtype. Note that this assumes that the internal data in the N_Vector is a contiguous array of realtype. This routine is only used in the interfaces to the dense (serial) linear solver, hence need not exist in a user-supplied NVECTOR module.

Usage:

N_VSetArrayPointer(vdata,v);

void* N_VGetCommunicator(N_Vector v)

Returns a pointer to the MPI_Comm object associated with the vector (if applicable). For MPI-unaware vector implementations, this should return NULL.

Usage:

commptr = N_VGetCommunicator(v);

sunindextype N_VGetLength(N_Vector v)

Returns the global length (number of ‘active’ entries) in the NVECTOR v. This value should be cumulative across all processes if the vector is used in a parallel environment. If v contains additional storage, e.g., for parallel communication, those entries should not be included.

Usage:

global_length = N_VGetLength(v);

void N_VLinearSum(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z)

Performs the operation z = ax + by, where a and b are realtype scalars and x and y are of type N_Vector:

$z_i = a x_i + b y_i, \quad i=0,\ldots,n-1.$

The output vector z can be the same as either of the input vectors (x or y).

Usage:

N_VLinearSum(a, x, b, y, z);

void N_VConst(realtype c, N_Vector z)

Sets all components of the N_Vector z to realtype c:

$z_i = c, \quad i=0,\ldots,n-1.$

Usage:

N_VConst(c, z);

void N_VProd(N_Vector x, N_Vector y, N_Vector z)

Sets the N_Vector z to be the component-wise product of the N_Vector inputs x and y:

$z_i = x_i y_i, \quad i=0,\ldots,n-1.$

Usage:

N_VProd(x, y, z);

void N_VDiv(N_Vector x, N_Vector y, N_Vector z)

Sets the N_Vector z to be the component-wise ratio of the N_Vector inputs x and y:

$z_i = \frac{x_i}{y_i}, \quad i=0,\ldots,n-1.$

The $$y_i$$ may not be tested for 0 values. It should only be called with a y that is guaranteed to have all nonzero components.

Usage:

N_VDiv(x, y, z);

void N_VScale(realtype c, N_Vector x, N_Vector z)

Scales the N_Vector x by the realtype scalar c and returns the result in z:

$z_i = c x_i, \quad i=0,\ldots,n-1.$

Usage:

N_VScale(c, x, z);

void N_VAbs(N_Vector x, N_Vector z)

Sets the components of the N_Vector z to be the absolute values of the components of the N_Vector x:

$z_i = |x_i|, \quad i=0,\ldots,n-1.$

Usage:

N_VAbs(x, z);

void N_VInv(N_Vector x, N_Vector z)

Sets the components of the N_Vector z to be the inverses of the components of the N_Vector x:

$z_i = 1.0/x_i, \quad i=0,\ldots,n-1.$

This routine may not check for division by 0. It should be called only with an x which is guaranteed to have all nonzero components.

Usage:

N_VInv(x, z);

void N_VAddConst(N_Vector x, realtype b, N_Vector z)

Adds the realtype scalar b to all components of x and returns the result in the N_Vector z:

$z_i = x_i+b, \quad i=0,\ldots,n-1.$

Usage:

N_VAddConst(x, b, z);

realtype N_VDotProd(N_Vector x, N_Vector z)

Returns the value of the dot-product of the N_Vectors x and y:

$d = \sum_{i=0}^{n-1} x_i y_i.$

Usage:

d = N_VDotProd(x, y);

realtype N_VMaxNorm(N_Vector x)

Returns the value of the $$l_{\infty}$$ norm of the N_Vector x:

$m = \max_{0\le i\le n-1} |x_i|.$

Usage:

m = N_VMaxNorm(x);

realtype N_VWrmsNorm(N_Vector x, N_Vector w)

Returns the weighted root-mean-square norm of the N_Vector x with (positive) realtype weight vector w:

$m = \sqrt{\left( \sum_{i=0}^{n-1} (x_i w_i)^2 \right) / n}$

Usage:

m = N_VWrmsNorm(x, w);

realtype N_VWrmsNormMask(N_Vector x, N_Vector w, N_Vector id)

Returns the weighted root mean square norm of the N_Vector x with realtype weight vector w built using only the elements of x corresponding to positive elements of the N_Vector id:

$m = \sqrt{\left( \sum_{i=0}^{n-1} (x_i w_i H(id_i))^2 \right) / n},$

where $$H(\alpha)=\begin{cases} 1 & \alpha>0\\ 0 & \alpha \leq 0\end{cases}$$.

Usage:

m = N_VWrmsNormMask(x, w, id);

realtype N_VMin(N_Vector x)

Returns the smallest element of the N_Vector x:

$m = \min_{0\le i\le n-1} x_i.$

Usage:

m = N_VMin(x);

realtype N_VWl2Norm(N_Vector x, N_Vector w)

Returns the weighted Euclidean $$l_2$$ norm of the N_Vector x with realtype weight vector w:

$m = \sqrt{\sum_{i=0}^{n-1}\left(x_i w_i\right)^2}.$

Usage:

m = N_VWL2Norm(x, w);

realtype N_VL1Norm(N_Vector x)

Returns the $$l_1$$ norm of the N_Vector x:

$m = \sum_{i=0}^{n-1} |x_i|.$

Usage:

m = N_VL1Norm(x);

void N_VCompare(realtype c, N_Vector x, N_Vector z)

Compares the components of the N_Vector x to the realtype scalar c and returns an N_Vector z such that for all $$0\le i\le n-1$$,

$\begin{split}z_i = \begin{cases} 1.0 &\quad\text{if}\; |x_i| \ge c,\\ 0.0 &\quad\text{otherwise}\end{cases}.\end{split}$

Usage:

N_VCompare(c, x, z);

booleantype N_VInvTest(N_Vector x, N_Vector z)

Sets the components of the N_Vector z to be the inverses of the components of the N_Vector x, with prior testing for zero values:

$z_i = 1.0/x_i, \quad i=0,\ldots,n-1.$

This routine returns a boolean assigned to SUNTRUE if all components of x are nonzero (successful inversion) and returns SUNFALSE otherwise.

Usage:

t = N_VInvTest(x, z);

booleantype N_VConstrMask(N_Vector c, N_Vector x, N_Vector m)

Performs the following constraint tests based on the values in $$c_i$$:

$\begin{split}x_i > 0 \;\text{if}\; c_i = 2, \\ x_i \ge 0 \;\text{if}\; c_i = 1, \\ x_i < 0 \;\text{if}\; c_i = -2, \\ x_i \le 0 \;\text{if}\; c_i = -1.\end{split}$

There is no constraint on $$x_i$$ if $$c_i = 0$$. This routine returns a boolean assigned to SUNFALSE if any element failed the constraint test and assigned to SUNTRUE if all passed. It also sets a mask vector m, with elements equal to 1.0 where the constraint test failed, and 0.0 where the test passed. This routine is used only for constraint checking.

Usage:

t = N_VConstrMask(c, x, m);

realtype N_VMinQuotient(N_Vector num, N_Vector denom)

This routine returns the minimum of the quotients obtained by termwise dividing the elements of n by the elements in d:

$\min_{i=0,\ldots,n-1} \frac{\text{num}_i}{\text{denom}_i}.$

A zero element in denom will be skipped. If no such quotients are found, then the large value BIG_REAL (defined in the header file sundials_types.h) is returned.

Usage:

minq = N_VMinQuotient(num, denom);


## Description of the NVECTOR fused operations¶

The following fused vector operations are optional. These operations are intended to increase data reuse, reduce parallel communication on distributed memory systems, and lower the number of kernel launches on systems with accelerators. If a particular NVECTOR implementation defines one of the fused vector operations as NULL, the NVECTOR interface will call one of the above standard vector operations as necessary. As above, for each operation, we give the name, usage of the function, and a description of its mathematical operations below.

int N_VLinearCombination(int nv, realtype* c, N_Vector* X, N_Vector z)

This routine computes the linear combination of nv vectors with $$n$$ elements:

$z_i = \sum_{j=0}^{nv-1} c_j x_{j,i}, \quad i=0,\ldots,n-1,$

where $$c$$ is an array of $$nv$$ scalars, $$x_j$$ is a vector in the vector array X, and z is the output vector. If the output vector z is one of the vectors in X, then it must be the first vector in the vector array. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VLinearCombination(nv, c, X, z);

int N_VScaleAddMulti(int nv, realtype* c, N_Vector x, N_Vector* Y, N_Vector* Z)

This routine scales and adds one vector to nv vectors with $$n$$ elements:

$z_{j,i} = c_j x_i + y_{j,i}, \quad j=0,\ldots,nv-1 \quad i=0,\ldots,n-1,$

where c is an array of scalars, x is a vector, $$y_j$$ is a vector in the vector array Y, and $$z_j$$ is an output vector in the vector array Z. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VScaleAddMulti(nv, c, x, Y, Z);

int N_VDotProdMulti(int nv, N_Vector x, N_Vector* Y, realtype* d)

This routine computes the dot product of a vector with nv vectors having $$n$$ elements:

$d_j = \sum_{i=0}^{n-1} x_i y_{j,i}, \quad j=0,\ldots,nv-1,$

where d is an array of scalars containing the computed dot products, x is a vector, and $$y_j$$ is a vector the vector array Y. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VDotProdMulti(nv, x, Y, d);


## Description of the NVECTOR vector array operations¶

The following vector array operations are also optional. As with the fused vector operations, these are intended to increase data reuse, reduce parallel communication on distributed memory systems, and lower the number of kernel launches on systems with accelerators. If a particular NVECTOR implementation defines one of the fused or vector array operations as NULL, the NVECTOR interface will call one of the above standard vector operations as necessary. As above, for each operation, we give the name, usage of the function, and a description of its mathematical operations below.

int N_VLinearSumVectorArray(int nv, realtype a, N_Vector X, realtype b, N_Vector* Y, N_Vector* Z)

This routine computes the linear sum of two vector arrays of nv vectors with $$n$$ elements:

$z_{j,i} = a x_{j,i} + b y_{j,i}, \quad i=0,\ldots,n-1 \quad j=0,\ldots,nv-1,$

where a and b are scalars, $$x_j$$ and $$y_j$$ are vectors in the vector arrays X and Y respectively, and $$z_j$$ is a vector in the output vector array Z. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VLinearSumVectorArray(nv, a, X, b, Y, Z);

int N_VScaleVectorArray(int nv, realtype* c, N_Vector* X, N_Vector* Z)

This routine scales each element in a vector of $$n$$ elements in a vector array of nv vectors by a potentially different constant:

$z_{j,i} = c_j x_{j,i}, \quad i=0,\ldots,n-1 \quad j=0,\ldots,nv-1,$

where c is an array of scalars, $$x_j$$ is a vector in the vector array X, and $$z_j$$ is a vector in the output vector array Z. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VScaleVectorArray(nv, c, X, Z);

int N_VConstVectorArray(int nv, realtype c, N_Vector* Z)

This routine sets each element in a vector of $$n$$ elements in a vector array of nv vectors to the same value:

$z_{j,i} = c, \quad i=0,\ldots,n-1 \quad j=0,\ldots,nv-1,$

where c is a scalar and $$z_j$$ is a vector in the vector array Z. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VConstVectorArray(nv, c, Z);

int N_VWrmsNormVectorArray(int nv, N_Vector* X, N_Vector* W, realtype* m)

This routine computes the weighted root mean square norm of each vector in a vector array:

$m_j = \left( \frac1n \sum_{i=0}^{n-1} \left(x_{j,i} w_{j,i}\right)^2\right)^{1/2}, \quad j=0,\ldots,nv-1,$

where $$x_j$$ is a vector in the vector array X, $$w_j$$ is a weight vector in the vector array W, and m is the output array of scalars containing the computed norms. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VWrmsNormVectorArray(nv, X, W, m);

int N_VWrmsNormMaskVectorArray(int nv, N_Vector* X, N_Vector* W, N_Vector id, realtype* m)

This routine computes the masked weighted root mean square norm of each vector in a vector array:

$m_j = \left( \frac1n \sum_{i=0}^{n-1} \left(x_{j,i} w_{j,i} H(id_i)\right)^2 \right)^{1/2}, \quad j=0,\ldots,nv-1,$

where $$H(id_i)=1$$ for $$id_i > 0$$ and is zero otherwise, $$x_j$$ is a vector in the vector array X, $$w_j$$ is a weight vector in the vector array W, id is the mask vector, and m is the output array of scalars containing the computed norms. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VWrmsNormMaskVectorArray(nv, X, W, id, m);

int N_VScaleAddMultiVectorArray(int nv, int nsum, realtype* c, N_Vector* X, N_Vector** YY, N_Vector** ZZ)

This routine scales and adds a vector array of nv vectors to nsum other vector arrays:

$z_{k,j,i} = c_k x_{j,i} + y_{k,j,i}, \quad i=0,\ldots,n-1 \quad j=0,\ldots,nv-1, \quad k=0,\ldots,nsum-1$

where c is an array of scalars, $$x_j$$ is a vector in the vector array X, $$y_{k,j}$$ is a vector in the array of vector arrays YY, and $$z_{k,j}$$ is an output vector in the array of vector arrays ZZ. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VScaleAddMultiVectorArray(nv, nsum, c, x, YY, ZZ);

int N_VLinearCombinationVectorArray(int nv, int nsum, realtype* c, N_Vector** XX, N_Vector* Z)

This routine computes the linear combination of nsum vector arrays containing nv vectors:

$z_{j,i} = \sum_{k=0}^{nsum-1} c_k x_{k,j,i}, \quad i=0,\ldots,n-1 \quad j=0,\ldots,nv-1,$

where c is an array of scalars, $$x_{k,j}$$ is a vector in array of vector arrays XX, and $$z_{j,i}$$ is an output vector in the vector array Z. If the output vector array is one of the vector arrays in XX, it must be the first vector array in XX. The operation returns 0 for success and a non-zero value otherwise.

Usage:

ier = N_VLinearCombinationVectorArray(nv, nsum, c, XX, Z);


## Description of the NVECTOR local reduction operations¶

The following local reduction operations are also optional. As with the fused and vector array operations, these are intended to reduce parallel communication on distributed memory systems. If a particular NVECTOR implementation defines one of the local reduction operations as NULL, the NVECTOR interface will call one of the above standard vector operations as necessary. As above, for each operation, we give the name, usage of the function, and a description of its mathematical operations below.

realtype N_VDotProdLocal(N_Vector x, N_Vector y)

This routine computes the MPI task-local portion of the ordinary dot product of x and y:

$d=\sum_{i=0}^{n_{local}-1} x_i y_i,$

where $$n_{local}$$ corresponds to the number of components in the vector on this MPI task (or $$n_{local}=n$$ for MPI-unaware applications).

Usage:

d = N_VDotProdLocal(x, y);

realtype N_VMaxNormLocal(N_Vector x)

This routine computes the MPI task-local portion of the maximum norm of the NVECTOR x:

$m = \max_{0\le i< n_{local}} | x_i |,$

where $$n_{local}$$ corresponds to the number of components in the vector on this MPI task (or $$n_{local}=n$$ for MPI-unaware applications).

Usage:

m = N_VMaxNormLocal(x);

realtype N_VMinLocal(N_Vector x)

This routine computes the smallest element of the MPI task-local portion of the NVECTOR x:

$m = \min_{0\le i< n_{local}} x_i,$

where $$n_{local}$$ corresponds to the number of components in the vector on this MPI task (or $$n_{local}=n$$ for MPI-unaware applications).

Usage:

m = N_VMinLocal(x);

realtype N_VL1NormLocal(N_Vector x)

This routine computes the MPI task-local portion of the $$l_1$$ norm of the N_Vector x:

$n = \sum_{i=0}^{n_{local}-1} | x_i |,$

where $$n_{local}$$ corresponds to the number of components in the vector on this MPI task (or $$n_{local}=n$$ for MPI-unaware applications).

Usage:

n = N_VL1NormLocal(x);

realtype N_VWSqrSumLocal(N_Vector x, N_Vector w)

This routine computes the MPI task-local portion of the weighted squared sum of the NVECTOR x with weight vector w:

$s = \sum_{i=0}^{n_{local}-1} (x_i w_i)^2,$

where $$n_{local}$$ corresponds to the number of components in the vector on this MPI task (or $$n_{local}=n$$ for MPI-unaware applications).

Usage:

s = N_VWSqrSumLocal(x, w);

realtype N_VWSqrSumMaskLocal(N_Vector x, N_Vector w, N_Vector id)

This routine computes the MPI task-local portion of the weighted squared sum of the NVECTOR x with weight vector w built using only the elements of x corresponding to positive elements of the NVECTOR id:

$m = \sum_{i=0}^{n_{local}-1} (x_i w_i H(id_i))^2,$

where

$\begin{split}H(\alpha) = \begin{cases} 1 & \alpha > 0 \\ 0 & \alpha \leq 0 \end{cases}\end{split}$

and $$n_{local}$$ corresponds to the number of components in the vector on this MPI task (or $$n_{local}=n$$ for MPI-unaware applications).

Usage:

s = N_VWSqrSumMaskLocal(x, w, id);

booleantype N_VInvTestLocal(N_Vector x)

This routine sets the MPI task-local components of the NVECTOR z to be the inverses of the components of the NVECTOR x, with prior testing for zero values:

$z_i = 1.0 / x_i , \: i=0,\ldots,n_{local}-1$

where $$n_{local}$$ corresponds to the number of components in the vector on this MPI task (or $$n_{local}=n$$ for MPI-unaware applications). This routine returns a boolean assigned to SUNTRUE if all task-local components of x are nonzero (successful inversion) and returns SUNFALSE otherwise.

Usage:

t = N_VInvTestLocal(x);

booleantype N_VConstrMaskLocal(N_Vector c, N_Vector x, N_Vector m)

This routine performs the following constraint tests: $$x_i > 0$$ if $$c_i=2$$, $$x_i \ge 0$$ if $$c_i=1$$, $$x_i \le 0$$ if $$c_i=-1$$, $$x_i < 0$$ if $$c_i=-2$$, and $$x_i =$$ anything if $$c_i=0$$, for all MPI task-local components of the vectors. This routine returns a boolean assigned to SUNFALSE if any task-local element failed the constraint test and assigned to SUNTRUE if all passed. It also sets a mask vector m, with elements equal to 1.0 where the constraint test failed, and 0.0 where the test passed. This routine is used only for constraint checking.

Usage:

t = N_VConstrMaskLocal(c, x, m);

realtype N_VMinQuotientLocal(N_Vector num, N_Vector denom)

This routine returns the minimum of the quotients obtained by term-wise dividing $$num_i$$ by $$denom_i$$, for all MPI task-local components of the vectors. A zero element in denom will be skipped. If no such quotients are found, then the large value BIG_REAL (defined in the header file sundials_types.h) is returned.

Usage:

minq = N_VMinQuotientLocal(num, denom);


## Description of the NVECTOR exchange operations¶

The following vector exchange operations are also optional and are intended only for use when interfacing with the XBraid library for parallel-in-time integration. In that setting these operations are required but are otherwise unused by SUNDIALS packages and may be set to NULL. For each operation, we give the function signature, a description of the expected behavior, and an example of the function usage.

int N_VBufSize(N_Vector x, sunindextype *size)

This routine returns the buffer size need to exchange in the data in the vector x between computational nodes.

Usage:

flag = N_VBufSize(x, &buf_size)

int N_VBufPack(N_Vector x, void *buf)

This routine fills the exchange buffer buf with the vector data in x.

Usage:

flag = N_VBufPack(x, &buf)

int N_VBufUnpack(N_Vector x, void *buf)

This routine unpacks the data in the exchange buffer buf into the vector x.

Usage:

flag = N_VBufUnpack(x, buf)