/*******************************************************************
* *
* File : nvector_serial.h *
* Programmers : Scott D. Cohen, Alan C. Hindmarsh, *
* : Radu Serban, and Allan G. Taylor, LLNL *
* Version of : 26 June 2002 *
*-----------------------------------------------------------------*
* Copyright (c) 2002, The Regents of the University of California *
* Produced at the Lawrence Livermore National Laboratory *
* All rights reserved *
* For details, see sundials/shared/LICENSE *
*-----------------------------------------------------------------*
* This is the header file for a serial implementation of the *
* NVECTOR package. *
* *
* Part I of this file contains declarations which are specific *
* to the particular machine environment in which this version *
* of the vector package is to be used. This includes the *
* typedef for the 'content' fields of the structures M_Env and *
* N_Vector (M_EnvSerialContent and N_VectorSerialContent, *
* respectively). *
* *
* Part II of this file defines accessor macros that allow the *
* user to use efficiently the type N_Vector without making *
* explicit references to its underlying representation. *
* *
* Part III of this file contains the prototype for the *
* initialization routine specific to this implementation *
* (M_EnvInit_Serial) as well as prototypes for the vector *
* kernels which operate on the serial N_Vector. These *
* prototypes are unique to this particular implementation of *
* the vector package. *
* *
* NOTES: *
* *
* The definitions of the generic M_Env and N_Vector structures *
* are in the header file nvector.h. *
* *
* The definitions of the types realtype and integertype are in *
* the header file sundialstypes.h and these may be changed *
* according to the user's needs. The sundialstypes.h file also *
* contains the definition for the type booleantype. *
* *
* N_Vector arguments to arithmetic kernels need not be *
* distinct. Thus, for example, the call *
* N_VLinearSum_Serial(a,x,b,y,y); y <- ax+by *
* is legal. *
* *
* This version of nvector is for the ordinary sequential *
* machine environment. In the documentation given below, N is *
* the length of all N_Vector parameters and x[i] denotes the *
* ith component of the N_Vector x, where 0 <= i <= N-1. *
* *
*******************************************************************/
#ifdef __cplusplus /* wrapper to enable C++ usage */
extern "C" {
#endif
#ifndef included_nvector_serial_h
#define included_nvector_serial_h
#include "nvector.h" /* Generic M_Env and N_Vector type definitions */
#include "sundialstypes.h"
/****************************************************************
* PART I: *
* Serial implementaion of M_Env and N_Vector *
****************************************************************/
/* The serial implementation of the machine environment has
ID tag 'serial' */
#define ID_TAG_S "serial"
/* The serial implementation of the machine environment 'content'
structure contains the length of vectors */
struct _M_EnvSerialContent {
integertype length;
};
typedef struct _M_EnvSerialContent *M_EnvSerialContent;
/* The serial implementation of the N_Vector 'content'
structure contains the length of the vector and a pointer
to an array of realtype components */
struct _N_VectorSerialContent {
integertype length;
realtype *data;
};
typedef struct _N_VectorSerialContent *N_VectorSerialContent;
/****************************************************************
* *
* PART II: Macros *
* NV_MAKE_S, NV_DISPOSE_S, NVS_MAKE_S, NVS_DISPOSE_S *
* ME_CONTENT_S, NV_CONTENT_S *
* NV_DATA_S, NV_LENGTH_S, NV_Ith_S *
*--------------------------------------------------------------*
* In the descriptions below, the following user declarations *
* are assumed: *
* *
* M_Env machenv; *
* N_Vector v, *vs; *
* realtype *v_data, **vs_data, r; *
* integertype v_len, s_len, i; *
* *
* (1) NV_MAKE_S, NV_DISPOSE_S *
* *
* These companion routines are used to create and *
* destroy an N_Vector with a component array v_data *
* allocated by the user. *
* *
* The call NV_MAKE_S(v, v_data, machenv) makes v an *
* N_Vector with component array v_data. The length of the *
* array is taken from machenv. *
* NV_MAKE_S stores the pointer v_data so that changes *
* made by the user to the elements of v_data are *
* simultaneously reflected in v. There is no copying of *
* elements. *
* *
* The call NV_DISPOSE_S(v) frees all memory associated *
* with v except for its component array. This memory was *
* allocated by the user and, therefore, should be *
* deallocated by the user. *
* *
* (2) NVS_MAKE_S, NVS_DISPOSE_S *
* *
* These companion routines are used to create and destroy *
* an array of N_Vectors with component vs_data allocated *
* by the user. *
* *
* The call NVS_MAKE_S(vs, vs_data, s_len, machenv) makes *
* vs an array of s_len N_Vectors, each with component *
* array vs_data[i] and array length taken from machenv. *
* NVS_MAKE_S stores the pointers vs_data[i] so that *
* changes made by the user to the elements of vs_data are *
* simultaneously reflected in vs. There is no copying of *
* elements. *
* *
* The call NVS_DISPOSE_S(vs) frees all memory associated *
* with vs except for its components' component array. *
* This memory was allocated by the user and, therefore, *
* should be deallocated by the user. *
* *
* (3) ME_CONTENT_S, NV_CONTENT_S *
* *
* These routines give access to the contents of the serial *
* machine environment and N_Vector, respectively. *
* *
* The assignment m_cont = ME_CONTENT_S(machenv) sets *
* m_cont to be a pointer to the serial machine *
* environment content structure. *
* *
* The assignment v_cont = NV_CONTENT_S(v) sets *
* v_cont to be a pointer to the serial N_Vector content *
* structure. *
* *
* (4) NV_DATA_S, NV_LENGTH_S *
* *
* These routines give individual access to the parts of *
* the content of a serial N_Vector. *
* *
* The assignment v_data=NV_DATA_S(v) sets v_data to be *
* a pointer to the first component of v. The assignment *
* NV_DATA_S(v)=v_data sets the component array of v to *
* be v_data by storing the pointer v_data. *
* *
* The assignment v_len=NV_LENGTH_S(v) sets v_len to be *
* the length of v. The call NV_LENGTH_S(v)=len_v sets *
* the length of v to be len_v. *
* *
* (5) NV_Ith_S *
* *
* In the following description, the components of an *
* N_Vector are numbered 0..N-1, where N is the length of *
* v. *
* *
* The assignment r=NV_Ith_S(v,i) sets r to be the value of *
* the ith component of v. The assignment NV_Ith_S(v,i)=r *
* sets the value of the ith component of v to be r. *
* *
* Notes.. *
* *
* Users who use the macros (1) and/or (2) must *
* #include<stdlib.h> since these macros expand to calls to *
* malloc and free. *
* *
* When looping over the components of an N_Vector v, it is *
* more efficient to first obtain the component array via *
* v_data=NV_DATA_S(v) and then access v_data[i] within the *
* loop than it is to use NV_Ith_S(v,i) within the loop. *
* *
* NV_MAKE_S and NV_DISPOSE_S are similar to N_VNew_Serial and *
* N_VFree_Serial, while NVS_MAKE_S and NVS_DISPOSE_S are *
* similar to N_VNew_S_Serial and N_VFree_S_Serial. The *
* difference is one of responsibility for component memory *
* allocation and deallocation. N_VNew_Serial allocates memory *
* for the N_Vector components and N_VFree_Serial frees the *
* component memory allocated by N_VNew_Serial. For NV_MAKE_S *
* and NV_DISPOSE_S, the component memory is allocated and *
* freed by the user of this package. Similar remarks hold for *
* NVS_MAKE_S, NVS_DISPOSE_S and N_VNew_S_Serial, *
* N_VFree_S_Serial. *
* *
****************************************************************/
#define NV_MAKE_S(v, v_data, machenv) \
v = (N_Vector) malloc(sizeof(*v)); \
v->content = (N_VectorSerialContent) malloc(sizeof(struct _N_VectorSerialContent)); \
v->content->data = v_data; \
v->content->length = machenv->content->v_len; \
v->menv = machenv
#define NV_DISPOSE_S(v) \
free((N_VectorSerialContent)(v->content)); \
free(v)
#define NVS_MAKE_S(vs, vs_data, s_len, machenv) \
vs = (N_Vector_S) malloc(s_len*sizeof(N_Vector *)); \
for ((int)is=0; is<s_len; is++) { \
NV_MAKE_S(vs[is], vs_data[is], machenv); \
}
#define NVS_DISPOSE_S(vs, s_len) \
for ((int)is=0; is<s_len; is++) NV_DISPOSE_S(vs[i]); \
free(vs);
#define ME_CONTENT_S(m) ( (M_EnvSerialContent)(m->content) )
#define NV_CONTENT_S(v) ( (N_VectorSerialContent)(v->content) )
#define NV_LENGTH_S(v) ( NV_CONTENT_S(v)->length )
#define NV_DATA_S(v) ( NV_CONTENT_S(v)->data )
#define NV_Ith_S(v,i) ( NV_DATA_S(v)[i] )
/****************************************************************
* PART III: *
* Functions exported by nvector_serial *
****************************************************************/
/*--------------------------------------------------------------*
* Routine : M_EnvInit_Serial *
*--------------------------------------------------------------*
* This function sets the content field of the machine *
* environment for the serial implementation to a structure of *
* type _MEnvSerialContent and attaches the vector operations *
* defined for this implementation. *
* *
* If successful, M_EnvInit_Serial returns a pointer of type *
* M_Env. This pointer should in turn be passed in any user *
* calls to N_VNew, or uses of the macros NV_MAKE_S and *
* NVS_MAKE_S. *
* *
*--------------------------------------------------------------*
* *
* vec_length is the length of the vector. *
* *
*--------------------------------------------------------------*/
M_Env M_EnvInit_Serial(integertype vec_length);
/*--------------------------------------------------------------*
* Function M_EnvFree_Serial *
*--------------------------------------------------------------*
* Function to free the block of machine-dependent environment *
* information created by M_EnvInit_Serial. *
* Its only argument is the pointer machenv returned by *
* M_EnvInit_Serial. *
* *
*--------------------------------------------------------------*/
void M_EnvFree_Serial(M_Env machenv);
/*--------------------------------------------------------------*
* Serial implementations of the vector operations *
* *
* For a complete description of each of the following routines *
* see the header file nvector.h *
*--------------------------------------------------------------*/
N_Vector N_VNew_Serial(integertype n, M_Env machEnv);
N_Vector_S N_VNew_S_Serial(integertype ns, integertype n, M_Env machEnv);
void N_VFree_Serial(N_Vector v);
void N_VFree_S_Serial(integertype ns, N_Vector_S vs);
N_Vector N_VMake_Serial(integertype n, realtype *v_data, M_Env machEnv);
void N_VDispose_Serial(N_Vector v);
realtype *N_VGetData_Serial(N_Vector v);
void N_VSetData_Serial(realtype *v_data, N_Vector v);
void N_VLinearSum_Serial(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z);
void N_VConst_Serial(realtype c, N_Vector z);
void N_VProd_Serial(N_Vector x, N_Vector y, N_Vector z);
void N_VDiv_Serial(N_Vector x, N_Vector y, N_Vector z);
void N_VScale_Serial(realtype c, N_Vector x, N_Vector z);
void N_VAbs_Serial(N_Vector x, N_Vector z);
void N_VInv_Serial(N_Vector x, N_Vector z);
void N_VAddConst_Serial(N_Vector x, realtype b, N_Vector z);
realtype N_VDotProd_Serial(N_Vector x, N_Vector y);
realtype N_VMaxNorm_Serial(N_Vector x);
realtype N_VWrmsNorm_Serial(N_Vector x, N_Vector w);
realtype N_VMin_Serial(N_Vector x);
realtype N_VWL2Norm_Serial(N_Vector x, N_Vector w);
realtype N_VL1Norm_Serial(N_Vector x);
void N_VOneMask_Serial(N_Vector x);
void N_VCompare_Serial(realtype c, N_Vector x, N_Vector z);
booleantype N_VInvTest_Serial(N_Vector x, N_Vector z);
booleantype N_VConstrProdPos_Serial(N_Vector c, N_Vector x);
booleantype N_VConstrMask_Serial(N_Vector c, N_Vector x, N_Vector m);
realtype N_VMinQuotient_Serial(N_Vector num, N_Vector denom);
void N_VPrint_Serial(N_Vector x);
#endif
#ifdef __cplusplus
}
#endif