1 /* -----------------------------------------------------------------
2 * Programmer(s): Radu Serban, Aaron Collier, and
3 * David J. Gardner @ LLNL
4 * Daniel R. Reynolds @ SMU
5 * -----------------------------------------------------------------
6 * SUNDIALS Copyright Start
7 * Copyright (c) 2002-2020, Lawrence Livermore National Security
8 * and Southern Methodist University.
9 * All rights reserved.
10 *
11 * See the top-level LICENSE and NOTICE files for details.
12 *
13 * SPDX-License-Identifier: BSD-3-Clause
14 * SUNDIALS Copyright End
15 * -----------------------------------------------------------------
16 * This is the implementation file for a generic NVECTOR package.
17 * It contains the implementation of the N_Vector operations listed
18 * in nvector.h.
19 * -----------------------------------------------------------------*/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include <sundials/sundials_nvector.h>
25
26 /* -----------------------------------------------------------------
27 * Create an empty NVector object
28 * -----------------------------------------------------------------*/
29
N_VNewEmpty()30 N_Vector N_VNewEmpty()
31 {
32 N_Vector v;
33 N_Vector_Ops ops;
34
35 /* create vector object */
36 v = NULL;
37 v = (N_Vector) malloc(sizeof *v);
38 if (v == NULL) return(NULL);
39
40 /* create vector ops structure */
41 ops = NULL;
42 ops = (N_Vector_Ops) malloc(sizeof *ops);
43 if (ops == NULL) { free(v); return(NULL); }
44
45 /* initialize operations to NULL */
46
47 /* constructors, destructors, and utility operations */
48 ops->nvgetvectorid = NULL;
49 ops->nvclone = NULL;
50 ops->nvcloneempty = NULL;
51 ops->nvdestroy = NULL;
52 ops->nvspace = NULL;
53 ops->nvgetarraypointer = NULL;
54 ops->nvsetarraypointer = NULL;
55 ops->nvgetcommunicator = NULL;
56 ops->nvgetlength = NULL;
57
58 /* standard vector operations */
59 ops->nvlinearsum = NULL;
60 ops->nvconst = NULL;
61 ops->nvprod = NULL;
62 ops->nvdiv = NULL;
63 ops->nvscale = NULL;
64 ops->nvabs = NULL;
65 ops->nvinv = NULL;
66 ops->nvaddconst = NULL;
67 ops->nvdotprod = NULL;
68 ops->nvmaxnorm = NULL;
69 ops->nvwrmsnormmask = NULL;
70 ops->nvwrmsnorm = NULL;
71 ops->nvmin = NULL;
72 ops->nvwl2norm = NULL;
73 ops->nvl1norm = NULL;
74 ops->nvcompare = NULL;
75 ops->nvinvtest = NULL;
76 ops->nvconstrmask = NULL;
77 ops->nvminquotient = NULL;
78
79 /* fused vector operations (optional) */
80 ops->nvlinearcombination = NULL;
81 ops->nvscaleaddmulti = NULL;
82 ops->nvdotprodmulti = NULL;
83
84 /* vector array operations (optional) */
85 ops->nvlinearsumvectorarray = NULL;
86 ops->nvscalevectorarray = NULL;
87 ops->nvconstvectorarray = NULL;
88 ops->nvwrmsnormvectorarray = NULL;
89 ops->nvwrmsnormmaskvectorarray = NULL;
90 ops->nvscaleaddmultivectorarray = NULL;
91 ops->nvlinearcombinationvectorarray = NULL;
92
93 /* local reduction operations (optional) */
94 ops->nvdotprodlocal = NULL;
95 ops->nvmaxnormlocal = NULL;
96 ops->nvminlocal = NULL;
97 ops->nvl1normlocal = NULL;
98 ops->nvinvtestlocal = NULL;
99 ops->nvconstrmasklocal = NULL;
100 ops->nvminquotientlocal = NULL;
101 ops->nvwsqrsumlocal = NULL;
102 ops->nvwsqrsummasklocal = NULL;
103
104 /* debugging functions (called when SUNDIALS_DEBUG_PRINTVEC is defined) */
105 ops->nvprint = NULL;
106 ops->nvprintfile = NULL;
107
108 /* attach ops and initialize content to NULL */
109 v->ops = ops;
110 v->content = NULL;
111
112 return(v);
113 }
114
115
116 /* -----------------------------------------------------------------
117 * Free a generic N_Vector (assumes content is already empty)
118 * -----------------------------------------------------------------*/
119
N_VFreeEmpty(N_Vector v)120 void N_VFreeEmpty(N_Vector v)
121 {
122 if (v == NULL) return;
123
124 /* free non-NULL ops structure */
125 if (v->ops) free(v->ops);
126 v->ops = NULL;
127
128 /* free overall N_Vector object and return */
129 free(v);
130 return;
131 }
132
133
134 /* -----------------------------------------------------------------
135 * Copy a vector 'ops' structure
136 * -----------------------------------------------------------------*/
137
N_VCopyOps(N_Vector w,N_Vector v)138 int N_VCopyOps(N_Vector w, N_Vector v)
139 {
140 /* Check that ops structures exist */
141 if (w == NULL || v == NULL) return(-1);
142 if (w->ops == NULL || v->ops == NULL) return(-1);
143
144 /* Copy ops from w to v */
145
146 /* constructors, destructors, and utility operations */
147 v->ops->nvgetvectorid = w->ops->nvgetvectorid;
148 v->ops->nvclone = w->ops->nvclone;
149 v->ops->nvcloneempty = w->ops->nvcloneempty;
150 v->ops->nvdestroy = w->ops->nvdestroy;
151 v->ops->nvspace = w->ops->nvspace;
152 v->ops->nvgetarraypointer = w->ops->nvgetarraypointer;
153 v->ops->nvsetarraypointer = w->ops->nvsetarraypointer;
154 v->ops->nvgetcommunicator = w->ops->nvgetcommunicator;
155 v->ops->nvgetlength = w->ops->nvgetlength;
156
157 /* standard vector operations */
158 v->ops->nvlinearsum = w->ops->nvlinearsum;
159 v->ops->nvconst = w->ops->nvconst;
160 v->ops->nvprod = w->ops->nvprod;
161 v->ops->nvdiv = w->ops->nvdiv;
162 v->ops->nvscale = w->ops->nvscale;
163 v->ops->nvabs = w->ops->nvabs;
164 v->ops->nvinv = w->ops->nvinv;
165 v->ops->nvaddconst = w->ops->nvaddconst;
166 v->ops->nvdotprod = w->ops->nvdotprod;
167 v->ops->nvmaxnorm = w->ops->nvmaxnorm;
168 v->ops->nvwrmsnormmask = w->ops->nvwrmsnormmask;
169 v->ops->nvwrmsnorm = w->ops->nvwrmsnorm;
170 v->ops->nvmin = w->ops->nvmin;
171 v->ops->nvwl2norm = w->ops->nvwl2norm;
172 v->ops->nvl1norm = w->ops->nvl1norm;
173 v->ops->nvcompare = w->ops->nvcompare;
174 v->ops->nvinvtest = w->ops->nvinvtest;
175 v->ops->nvconstrmask = w->ops->nvconstrmask;
176 v->ops->nvminquotient = w->ops->nvminquotient;
177
178 /* fused vector operations */
179 v->ops->nvlinearcombination = w->ops->nvlinearcombination;
180 v->ops->nvscaleaddmulti = w->ops->nvscaleaddmulti;
181 v->ops->nvdotprodmulti = w->ops->nvdotprodmulti;
182
183 /* vector array operations */
184 v->ops->nvlinearsumvectorarray = w->ops->nvlinearsumvectorarray;
185 v->ops->nvscalevectorarray = w->ops->nvscalevectorarray;
186 v->ops->nvconstvectorarray = w->ops->nvconstvectorarray;
187 v->ops->nvwrmsnormvectorarray = w->ops->nvwrmsnormvectorarray;
188 v->ops->nvwrmsnormmaskvectorarray = w->ops->nvwrmsnormmaskvectorarray;
189 v->ops->nvscaleaddmultivectorarray = w->ops->nvscaleaddmultivectorarray;
190 v->ops->nvlinearcombinationvectorarray = w->ops->nvlinearcombinationvectorarray;
191
192 /* local reduction operations */
193 v->ops->nvdotprodlocal = w->ops->nvdotprodlocal;
194 v->ops->nvmaxnormlocal = w->ops->nvmaxnormlocal;
195 v->ops->nvminlocal = w->ops->nvminlocal;
196 v->ops->nvl1normlocal = w->ops->nvl1normlocal;
197 v->ops->nvinvtestlocal = w->ops->nvinvtestlocal;
198 v->ops->nvconstrmasklocal = w->ops->nvconstrmasklocal;
199 v->ops->nvminquotientlocal = w->ops->nvminquotientlocal;
200 v->ops->nvwsqrsumlocal = w->ops->nvwsqrsumlocal;
201 v->ops->nvwsqrsummasklocal = w->ops->nvwsqrsummasklocal;
202
203 /* debugging functions (called when SUNDIALS_DEBUG_PRINTVEC is defined) */
204 v->ops->nvprint = w->ops->nvprint;
205 v->ops->nvprintfile = w->ops->nvprintfile;
206
207 return(0);
208 }
209
210 /* -----------------------------------------------------------------
211 * Functions in the 'ops' structure
212 * -----------------------------------------------------------------*/
213
N_VGetVectorID(N_Vector w)214 N_Vector_ID N_VGetVectorID(N_Vector w)
215 {
216 return(w->ops->nvgetvectorid(w));
217 }
218
N_VClone(N_Vector w)219 N_Vector N_VClone(N_Vector w)
220 {
221 return(w->ops->nvclone(w));
222 }
223
N_VCloneEmpty(N_Vector w)224 N_Vector N_VCloneEmpty(N_Vector w)
225 {
226 return(w->ops->nvcloneempty(w));
227 }
228
N_VDestroy(N_Vector v)229 void N_VDestroy(N_Vector v)
230 {
231 if (v == NULL) return;
232
233 /* if the destroy operation exists use it */
234 if (v->ops)
235 if (v->ops->nvdestroy) { v->ops->nvdestroy(v); return; }
236
237 /* if we reach this point, either ops == NULL or nvdestroy == NULL,
238 try to cleanup by freeing the content, ops, and vector */
239 if (v->content) { free(v->content); v->content = NULL; }
240 if (v->ops) { free(v->ops); v->ops = NULL; }
241 free(v); v = NULL;
242
243 return;
244 }
245
N_VSpace(N_Vector v,sunindextype * lrw,sunindextype * liw)246 void N_VSpace(N_Vector v, sunindextype *lrw, sunindextype *liw)
247 {
248 v->ops->nvspace(v, lrw, liw);
249 return;
250 }
251
N_VGetArrayPointer(N_Vector v)252 realtype *N_VGetArrayPointer(N_Vector v)
253 {
254 return((realtype *) v->ops->nvgetarraypointer(v));
255 }
256
N_VSetArrayPointer(realtype * v_data,N_Vector v)257 void N_VSetArrayPointer(realtype *v_data, N_Vector v)
258 {
259 v->ops->nvsetarraypointer(v_data, v);
260 return;
261 }
262
N_VGetCommunicator(N_Vector v)263 void *N_VGetCommunicator(N_Vector v)
264 {
265 if (v->ops->nvgetcommunicator)
266 return(v->ops->nvgetcommunicator(v));
267 else
268 return(NULL);
269 }
270
N_VGetLength(N_Vector v)271 sunindextype N_VGetLength(N_Vector v)
272 {
273 return((sunindextype) v->ops->nvgetlength(v));
274 }
275
276 /* -----------------------------------------------------------------
277 * standard vector operations
278 * -----------------------------------------------------------------*/
279
N_VLinearSum(realtype a,N_Vector x,realtype b,N_Vector y,N_Vector z)280 void N_VLinearSum(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z)
281 {
282 z->ops->nvlinearsum(a, x, b, y, z);
283 return;
284 }
285
N_VConst(realtype c,N_Vector z)286 void N_VConst(realtype c, N_Vector z)
287 {
288 z->ops->nvconst(c, z);
289 return;
290 }
291
N_VProd(N_Vector x,N_Vector y,N_Vector z)292 void N_VProd(N_Vector x, N_Vector y, N_Vector z)
293 {
294 z->ops->nvprod(x, y, z);
295 return;
296 }
297
N_VDiv(N_Vector x,N_Vector y,N_Vector z)298 void N_VDiv(N_Vector x, N_Vector y, N_Vector z)
299 {
300 z->ops->nvdiv(x, y, z);
301 return;
302 }
303
N_VScale(realtype c,N_Vector x,N_Vector z)304 void N_VScale(realtype c, N_Vector x, N_Vector z)
305 {
306 z->ops->nvscale(c, x, z);
307 return;
308 }
309
N_VAbs(N_Vector x,N_Vector z)310 void N_VAbs(N_Vector x, N_Vector z)
311 {
312 z->ops->nvabs(x, z);
313 return;
314 }
315
N_VInv(N_Vector x,N_Vector z)316 void N_VInv(N_Vector x, N_Vector z)
317 {
318 z->ops->nvinv(x, z);
319 return;
320 }
321
N_VAddConst(N_Vector x,realtype b,N_Vector z)322 void N_VAddConst(N_Vector x, realtype b, N_Vector z)
323 {
324 z->ops->nvaddconst(x, b, z);
325 return;
326 }
327
N_VDotProd(N_Vector x,N_Vector y)328 realtype N_VDotProd(N_Vector x, N_Vector y)
329 {
330 return((realtype) y->ops->nvdotprod(x, y));
331 }
332
N_VMaxNorm(N_Vector x)333 realtype N_VMaxNorm(N_Vector x)
334 {
335 return((realtype) x->ops->nvmaxnorm(x));
336 }
337
N_VWrmsNorm(N_Vector x,N_Vector w)338 realtype N_VWrmsNorm(N_Vector x, N_Vector w)
339 {
340 return((realtype) x->ops->nvwrmsnorm(x, w));
341 }
342
N_VWrmsNormMask(N_Vector x,N_Vector w,N_Vector id)343 realtype N_VWrmsNormMask(N_Vector x, N_Vector w, N_Vector id)
344 {
345 return((realtype) x->ops->nvwrmsnormmask(x, w, id));
346 }
347
N_VMin(N_Vector x)348 realtype N_VMin(N_Vector x)
349 {
350 return((realtype) x->ops->nvmin(x));
351 }
352
N_VWL2Norm(N_Vector x,N_Vector w)353 realtype N_VWL2Norm(N_Vector x, N_Vector w)
354 {
355 return((realtype) x->ops->nvwl2norm(x, w));
356 }
357
N_VL1Norm(N_Vector x)358 realtype N_VL1Norm(N_Vector x)
359 {
360 return((realtype) x->ops->nvl1norm(x));
361 }
362
N_VCompare(realtype c,N_Vector x,N_Vector z)363 void N_VCompare(realtype c, N_Vector x, N_Vector z)
364 {
365 z->ops->nvcompare(c, x, z);
366 return;
367 }
368
N_VInvTest(N_Vector x,N_Vector z)369 booleantype N_VInvTest(N_Vector x, N_Vector z)
370 {
371 return((booleantype) z->ops->nvinvtest(x, z));
372 }
373
N_VConstrMask(N_Vector c,N_Vector x,N_Vector m)374 booleantype N_VConstrMask(N_Vector c, N_Vector x, N_Vector m)
375 {
376 return((booleantype) x->ops->nvconstrmask(c, x, m));
377 }
378
N_VMinQuotient(N_Vector num,N_Vector denom)379 realtype N_VMinQuotient(N_Vector num, N_Vector denom)
380 {
381 return((realtype) num->ops->nvminquotient(num, denom));
382 }
383
384 /* -----------------------------------------------------------------
385 * OPTIONAL fused vector operations
386 * -----------------------------------------------------------------*/
387
N_VLinearCombination(int nvec,realtype * c,N_Vector * X,N_Vector z)388 int N_VLinearCombination(int nvec, realtype* c, N_Vector* X, N_Vector z)
389 {
390 int i;
391 realtype ONE=RCONST(1.0);
392
393 if (z->ops->nvlinearcombination != NULL) {
394
395 return(z->ops->nvlinearcombination(nvec, c, X, z));
396
397 } else {
398
399 z->ops->nvscale(c[0], X[0], z);
400 for (i=1; i<nvec; i++) {
401 z->ops->nvlinearsum(c[i], X[i], ONE, z, z);
402 }
403 return(0);
404
405 }
406 }
407
N_VScaleAddMulti(int nvec,realtype * a,N_Vector x,N_Vector * Y,N_Vector * Z)408 int N_VScaleAddMulti(int nvec, realtype* a, N_Vector x, N_Vector* Y, N_Vector* Z)
409 {
410 int i;
411 realtype ONE=RCONST(1.0);
412
413 if (x->ops->nvscaleaddmulti != NULL) {
414
415 return(x->ops->nvscaleaddmulti(nvec, a, x, Y, Z));
416
417 } else {
418
419 for (i=0; i<nvec; i++) {
420 x->ops->nvlinearsum(a[i], x, ONE, Y[i], Z[i]);
421 }
422 return(0);
423
424 }
425 }
426
N_VDotProdMulti(int nvec,N_Vector x,N_Vector * Y,realtype * dotprods)427 int N_VDotProdMulti(int nvec, N_Vector x, N_Vector* Y, realtype* dotprods)
428 {
429 int i;
430
431 if (x->ops->nvdotprodmulti != NULL) {
432
433 return(x->ops->nvdotprodmulti(nvec, x, Y, dotprods));
434
435 } else {
436
437 for (i=0; i<nvec; i++) {
438 dotprods[i] = x->ops->nvdotprod(x, Y[i]);
439 }
440 return(0);
441
442 }
443 }
444
445 /* -----------------------------------------------------------------
446 * OPTIONAL vector array operations
447 * -----------------------------------------------------------------*/
448
N_VLinearSumVectorArray(int nvec,realtype a,N_Vector * X,realtype b,N_Vector * Y,N_Vector * Z)449 int N_VLinearSumVectorArray(int nvec, realtype a, N_Vector* X,
450 realtype b, N_Vector* Y, N_Vector* Z)
451 {
452 int i;
453
454 if (Z[0]->ops->nvlinearsumvectorarray != NULL) {
455
456 return(Z[0]->ops->nvlinearsumvectorarray(nvec, a, X, b, Y, Z));
457
458 } else {
459
460 for (i=0; i<nvec; i++) {
461 Z[0]->ops->nvlinearsum(a, X[i], b, Y[i], Z[i]);
462 }
463 return(0);
464
465 }
466 }
467
N_VScaleVectorArray(int nvec,realtype * c,N_Vector * X,N_Vector * Z)468 int N_VScaleVectorArray(int nvec, realtype* c, N_Vector* X, N_Vector* Z)
469 {
470 int i;
471
472 if (Z[0]->ops->nvscalevectorarray != NULL) {
473
474 return(Z[0]->ops->nvscalevectorarray(nvec, c, X, Z));
475
476 } else {
477
478 for (i=0; i<nvec; i++) {
479 Z[0]->ops->nvscale(c[i], X[i], Z[i]);
480 }
481 return(0);
482
483 }
484 }
485
N_VConstVectorArray(int nvec,realtype c,N_Vector * Z)486 int N_VConstVectorArray(int nvec, realtype c, N_Vector* Z)
487 {
488 int i, ier;
489
490 if (Z[0]->ops->nvconstvectorarray != NULL) {
491
492 ier = Z[0]->ops->nvconstvectorarray(nvec, c, Z);
493 return(ier);
494
495 } else {
496
497 for (i=0; i<nvec; i++) {
498 Z[0]->ops->nvconst(c, Z[i]);
499 }
500 return(0);
501
502 }
503 }
504
N_VWrmsNormVectorArray(int nvec,N_Vector * X,N_Vector * W,realtype * nrm)505 int N_VWrmsNormVectorArray(int nvec, N_Vector* X, N_Vector* W, realtype* nrm)
506 {
507 int i, ier;
508
509 if (X[0]->ops->nvwrmsnormvectorarray != NULL) {
510
511 ier = X[0]->ops->nvwrmsnormvectorarray(nvec, X, W, nrm);
512 return(ier);
513
514 } else {
515
516 for (i=0; i<nvec; i++) {
517 nrm[i] = X[0]->ops->nvwrmsnorm(X[i], W[i]);
518 }
519 return(0);
520
521 }
522 }
523
N_VWrmsNormMaskVectorArray(int nvec,N_Vector * X,N_Vector * W,N_Vector id,realtype * nrm)524 int N_VWrmsNormMaskVectorArray(int nvec, N_Vector* X, N_Vector* W, N_Vector id,
525 realtype* nrm)
526 {
527 int i, ier;
528
529 if (id->ops->nvwrmsnormmaskvectorarray != NULL) {
530
531 ier = id->ops->nvwrmsnormmaskvectorarray(nvec, X, W, id, nrm);
532 return(ier);
533
534 } else {
535
536 for (i=0; i<nvec; i++) {
537 nrm[i] = id->ops->nvwrmsnormmask(X[i], W[i], id);
538 }
539 return(0);
540
541 }
542 }
543
N_VScaleAddMultiVectorArray(int nvec,int nsum,realtype * a,N_Vector * X,N_Vector ** Y,N_Vector ** Z)544 int N_VScaleAddMultiVectorArray(int nvec, int nsum, realtype* a, N_Vector* X,
545 N_Vector** Y, N_Vector** Z)
546 {
547 int i, j;
548 int ier=0;
549 realtype ONE=RCONST(1.0);
550 N_Vector* YY=NULL;
551 N_Vector* ZZ=NULL;
552
553 if (X[0]->ops->nvscaleaddmultivectorarray != NULL) {
554
555 ier = X[0]->ops->nvscaleaddmultivectorarray(nvec, nsum, a, X, Y, Z);
556 return(ier);
557
558 } else if (X[0]->ops->nvscaleaddmulti != NULL ) {
559
560 /* allocate arrays of vectors */
561 YY = (N_Vector*) malloc(nsum * sizeof(N_Vector));
562 ZZ = (N_Vector*) malloc(nsum * sizeof(N_Vector));
563
564 for (i=0; i<nvec; i++) {
565
566 for (j=0; j<nsum; j++) {
567 YY[j] = Y[j][i];
568 ZZ[j] = Z[j][i];
569 }
570
571 ier = X[0]->ops->nvscaleaddmulti(nsum, a, X[i], YY, ZZ);
572 if (ier != 0) break;
573 }
574
575 /* free array of vectors */
576 free(YY);
577 free(ZZ);
578
579 return(ier);
580
581 } else {
582
583 for (i=0; i<nvec; i++) {
584 for (j=0; j<nsum; j++) {
585 X[0]->ops->nvlinearsum(a[j], X[i], ONE, Y[j][i], Z[j][i]);
586 }
587 }
588 return(0);
589 }
590 }
591
N_VLinearCombinationVectorArray(int nvec,int nsum,realtype * c,N_Vector ** X,N_Vector * Z)592 int N_VLinearCombinationVectorArray(int nvec, int nsum, realtype* c,
593 N_Vector** X, N_Vector* Z)
594 {
595 int i, j;
596 int ier=0;
597 realtype ONE=RCONST(1.0);
598 N_Vector* Y=NULL;
599
600 if (Z[0]->ops->nvlinearcombinationvectorarray != NULL) {
601
602 ier = Z[0]->ops->nvlinearcombinationvectorarray(nvec, nsum, c, X, Z);
603 return(ier);
604
605 } else if (Z[0]->ops->nvlinearcombination != NULL ) {
606
607 /* allocate array of vectors */
608 Y = (N_Vector* ) malloc(nsum * sizeof(N_Vector));
609
610 for (i=0; i<nvec; i++) {
611
612 for (j=0; j<nsum; j++) {
613 Y[j] = X[j][i];
614 }
615
616 ier = Z[0]->ops->nvlinearcombination(nsum, c, Y, Z[i]);
617 if (ier != 0) break;
618 }
619
620 /* free array of vectors */
621 free(Y);
622
623 return(ier);
624
625 } else {
626
627 for (i=0; i<nvec; i++) {
628 Z[0]->ops->nvscale(c[0], X[0][i], Z[i]);
629 for (j=1; j<nsum; j++) {
630 Z[0]->ops->nvlinearsum(c[j], X[j][i], ONE, Z[i], Z[i]);
631 }
632 }
633 return(0);
634 }
635 }
636
637 /* -----------------------------------------------------------------
638 * OPTIONAL local reduction kernels (no parallel communication)
639 * -----------------------------------------------------------------*/
640
N_VDotProdLocal(N_Vector x,N_Vector y)641 realtype N_VDotProdLocal(N_Vector x, N_Vector y)
642 {
643 return((realtype) y->ops->nvdotprodlocal(x, y));
644 }
645
N_VMaxNormLocal(N_Vector x)646 realtype N_VMaxNormLocal(N_Vector x)
647 {
648 return((realtype) x->ops->nvmaxnormlocal(x));
649 }
650
N_VMinLocal(N_Vector x)651 realtype N_VMinLocal(N_Vector x)
652 {
653 return((realtype) x->ops->nvminlocal(x));
654 }
655
N_VL1NormLocal(N_Vector x)656 realtype N_VL1NormLocal(N_Vector x)
657 {
658 return((realtype) x->ops->nvl1normlocal(x));
659 }
660
N_VWSqrSumLocal(N_Vector x,N_Vector w)661 realtype N_VWSqrSumLocal(N_Vector x, N_Vector w)
662 {
663 return((realtype) x->ops->nvwsqrsumlocal(x,w));
664 }
665
N_VWSqrSumMaskLocal(N_Vector x,N_Vector w,N_Vector id)666 realtype N_VWSqrSumMaskLocal(N_Vector x, N_Vector w, N_Vector id)
667 {
668 return((realtype) x->ops->nvwsqrsummasklocal(x,w,id));
669 }
670
N_VInvTestLocal(N_Vector x,N_Vector z)671 booleantype N_VInvTestLocal(N_Vector x, N_Vector z)
672 {
673 return((booleantype) z->ops->nvinvtestlocal(x,z));
674 }
675
N_VConstrMaskLocal(N_Vector c,N_Vector x,N_Vector m)676 booleantype N_VConstrMaskLocal(N_Vector c, N_Vector x, N_Vector m)
677 {
678 return((booleantype) x->ops->nvconstrmasklocal(c,x,m));
679 }
680
N_VMinQuotientLocal(N_Vector num,N_Vector denom)681 realtype N_VMinQuotientLocal(N_Vector num, N_Vector denom)
682 {
683 return((realtype) num->ops->nvminquotientlocal(num,denom));
684 }
685
686 /* -----------------------------------------------------------------
687 * Additional functions exported by the generic NVECTOR:
688 * N_VNewVectorArray
689 * N_VCloneEmptyVectorArray
690 * N_VCloneVectorArray
691 * N_VDestroyVectorArray
692 * -----------------------------------------------------------------*/
N_VNewVectorArray(int count)693 N_Vector* N_VNewVectorArray(int count)
694 {
695 N_Vector* vs = NULL;
696
697 if (count <= 0) return(NULL);
698
699 vs = (N_Vector* ) malloc(count * sizeof(N_Vector));
700 if(vs == NULL) return(NULL);
701
702 return(vs);
703 }
704
N_VCloneEmptyVectorArray(int count,N_Vector w)705 N_Vector* N_VCloneEmptyVectorArray(int count, N_Vector w)
706 {
707 N_Vector* vs = NULL;
708 int j;
709
710 if (count <= 0) return(NULL);
711
712 vs = (N_Vector* ) malloc(count * sizeof(N_Vector));
713 if(vs == NULL) return(NULL);
714
715 for (j = 0; j < count; j++) {
716 vs[j] = N_VCloneEmpty(w);
717 if (vs[j] == NULL) {
718 N_VDestroyVectorArray(vs, j-1);
719 return(NULL);
720 }
721 }
722
723 return(vs);
724 }
725
N_VCloneVectorArray(int count,N_Vector w)726 N_Vector* N_VCloneVectorArray(int count, N_Vector w)
727 {
728 N_Vector* vs = NULL;
729 int j;
730
731 if (count <= 0) return(NULL);
732
733 vs = (N_Vector* ) malloc(count * sizeof(N_Vector));
734 if(vs == NULL) return(NULL);
735
736 for (j = 0; j < count; j++) {
737 vs[j] = N_VClone(w);
738 if (vs[j] == NULL) {
739 N_VDestroyVectorArray(vs, j-1);
740 return(NULL);
741 }
742 }
743
744 return(vs);
745 }
746
N_VDestroyVectorArray(N_Vector * vs,int count)747 void N_VDestroyVectorArray(N_Vector* vs, int count)
748 {
749 int j;
750
751 if (vs==NULL) return;
752
753 for (j = 0; j < count; j++) N_VDestroy(vs[j]);
754
755 free(vs); vs = NULL;
756
757 return;
758 }
759
760 /* These function are really only for users of the Fortran interface */
N_VGetVecAtIndexVectorArray(N_Vector * vs,int index)761 N_Vector N_VGetVecAtIndexVectorArray(N_Vector* vs, int index)
762 {
763 if (vs==NULL) return NULL;
764 else if (index < 0) return NULL;
765 else return vs[index];
766 }
767
N_VSetVecAtIndexVectorArray(N_Vector * vs,int index,N_Vector w)768 void N_VSetVecAtIndexVectorArray(N_Vector* vs, int index, N_Vector w)
769 {
770 if (vs==NULL) return;
771 else if (index < 0) return;
772 else vs[index] = w;
773 }
774
775
776 /* -----------------------------------------------------------------
777 * Debugging functions
778 * ----------------------------------------------------------------- */
779
N_VPrint(N_Vector v)780 void N_VPrint(N_Vector v)
781 {
782 if (v == NULL) {
783 printf("NULL Vector\n");
784 return;
785 }
786 if (v->ops->nvprint == NULL) {
787 printf("NULL Print Op\n");
788 return;
789 }
790 v->ops->nvprint(v);
791 return;
792 }
793
794
N_VPrintFile(N_Vector v,FILE * outfile)795 void N_VPrintFile(N_Vector v, FILE* outfile)
796 {
797 if (v == NULL) {
798 fprintf(outfile, "NULL Vector\n");
799 return;
800 }
801 if (v->ops->nvprintfile == NULL) {
802 fprintf(outfile, "NULL PrintFile Op\n");
803 return;
804 }
805 v->ops->nvprintfile(v, outfile);
806 return;
807 }
808