1 /* -----------------------------------------------------------------
2 * Programmer(s): Radu Serban and Aaron Collier @ LLNL
3 * -----------------------------------------------------------------
4 * SUNDIALS Copyright Start
5 * Copyright (c) 2002-2019, Lawrence Livermore National Security
6 * and Southern Methodist University.
7 * All rights reserved.
8 *
9 * See the top-level LICENSE and NOTICE files for details.
10 *
11 * SPDX-License-Identifier: BSD-3-Clause
12 * SUNDIALS Copyright End
13 * -----------------------------------------------------------------
14 * This is the implementation file for a generic NVECTOR package.
15 * It contains the implementation of the N_Vector operations listed
16 * in nvector.h.
17 * -----------------------------------------------------------------*/
18
19 #include <stdlib.h>
20
21 #include <sundials/sundials_nvector.h>
22
23 /*
24 * -----------------------------------------------------------------
25 * Functions in the 'ops' structure
26 * -----------------------------------------------------------------
27 */
28
N_VGetVectorID(N_Vector w)29 N_Vector_ID N_VGetVectorID(N_Vector w)
30 {
31 N_Vector_ID id;
32 id = w->ops->nvgetvectorid(w);
33 return(id);
34 }
35
N_VClone(N_Vector w)36 N_Vector N_VClone(N_Vector w)
37 {
38 N_Vector v = NULL;
39 v = w->ops->nvclone(w);
40 return(v);
41 }
42
N_VCloneEmpty(N_Vector w)43 N_Vector N_VCloneEmpty(N_Vector w)
44 {
45 N_Vector v = NULL;
46 v = w->ops->nvcloneempty(w);
47 return(v);
48 }
49
N_VDestroy(N_Vector v)50 void N_VDestroy(N_Vector v)
51 {
52 if (v==NULL) return;
53 v->ops->nvdestroy(v);
54 return;
55 }
56
N_VSpace(N_Vector v,sunindextype * lrw,sunindextype * liw)57 void N_VSpace(N_Vector v, sunindextype *lrw, sunindextype *liw)
58 {
59 v->ops->nvspace(v, lrw, liw);
60 return;
61 }
62
N_VGetArrayPointer(N_Vector v)63 realtype *N_VGetArrayPointer(N_Vector v)
64 {
65 return((realtype *) v->ops->nvgetarraypointer(v));
66 }
67
N_VSetArrayPointer(realtype * v_data,N_Vector v)68 void N_VSetArrayPointer(realtype *v_data, N_Vector v)
69 {
70 v->ops->nvsetarraypointer(v_data, v);
71 return;
72 }
73
74 /* -----------------------------------------------------------------
75 * standard vector operations
76 * ----------------------------------------------------------------- */
77
N_VLinearSum(realtype a,N_Vector x,realtype b,N_Vector y,N_Vector z)78 void N_VLinearSum(realtype a, N_Vector x, realtype b, N_Vector y, N_Vector z)
79 {
80 z->ops->nvlinearsum(a, x, b, y, z);
81 return;
82 }
83
N_VConst(realtype c,N_Vector z)84 void N_VConst(realtype c, N_Vector z)
85 {
86 z->ops->nvconst(c, z);
87 return;
88 }
89
N_VProd(N_Vector x,N_Vector y,N_Vector z)90 void N_VProd(N_Vector x, N_Vector y, N_Vector z)
91 {
92 z->ops->nvprod(x, y, z);
93 return;
94 }
95
N_VDiv(N_Vector x,N_Vector y,N_Vector z)96 void N_VDiv(N_Vector x, N_Vector y, N_Vector z)
97 {
98 z->ops->nvdiv(x, y, z);
99 return;
100 }
101
N_VScale(realtype c,N_Vector x,N_Vector z)102 void N_VScale(realtype c, N_Vector x, N_Vector z)
103 {
104 z->ops->nvscale(c, x, z);
105 return;
106 }
107
N_VAbs(N_Vector x,N_Vector z)108 void N_VAbs(N_Vector x, N_Vector z)
109 {
110 z->ops->nvabs(x, z);
111 return;
112 }
113
N_VInv(N_Vector x,N_Vector z)114 void N_VInv(N_Vector x, N_Vector z)
115 {
116 z->ops->nvinv(x, z);
117 return;
118 }
119
N_VAddConst(N_Vector x,realtype b,N_Vector z)120 void N_VAddConst(N_Vector x, realtype b, N_Vector z)
121 {
122 z->ops->nvaddconst(x, b, z);
123 return;
124 }
125
N_VDotProd(N_Vector x,N_Vector y)126 realtype N_VDotProd(N_Vector x, N_Vector y)
127 {
128 return((realtype) y->ops->nvdotprod(x, y));
129 }
130
N_VMaxNorm(N_Vector x)131 realtype N_VMaxNorm(N_Vector x)
132 {
133 return((realtype) x->ops->nvmaxnorm(x));
134 }
135
N_VWrmsNorm(N_Vector x,N_Vector w)136 realtype N_VWrmsNorm(N_Vector x, N_Vector w)
137 {
138 return((realtype) x->ops->nvwrmsnorm(x, w));
139 }
140
N_VWrmsNormMask(N_Vector x,N_Vector w,N_Vector id)141 realtype N_VWrmsNormMask(N_Vector x, N_Vector w, N_Vector id)
142 {
143 return((realtype) x->ops->nvwrmsnormmask(x, w, id));
144 }
145
N_VMin(N_Vector x)146 realtype N_VMin(N_Vector x)
147 {
148 return((realtype) x->ops->nvmin(x));
149 }
150
N_VWL2Norm(N_Vector x,N_Vector w)151 realtype N_VWL2Norm(N_Vector x, N_Vector w)
152 {
153 return((realtype) x->ops->nvwl2norm(x, w));
154 }
155
N_VL1Norm(N_Vector x)156 realtype N_VL1Norm(N_Vector x)
157 {
158 return((realtype) x->ops->nvl1norm(x));
159 }
160
N_VCompare(realtype c,N_Vector x,N_Vector z)161 void N_VCompare(realtype c, N_Vector x, N_Vector z)
162 {
163 z->ops->nvcompare(c, x, z);
164 return;
165 }
166
N_VInvTest(N_Vector x,N_Vector z)167 booleantype N_VInvTest(N_Vector x, N_Vector z)
168 {
169 return((booleantype) z->ops->nvinvtest(x, z));
170 }
171
N_VConstrMask(N_Vector c,N_Vector x,N_Vector m)172 booleantype N_VConstrMask(N_Vector c, N_Vector x, N_Vector m)
173 {
174 return((booleantype) x->ops->nvconstrmask(c, x, m));
175 }
176
N_VMinQuotient(N_Vector num,N_Vector denom)177 realtype N_VMinQuotient(N_Vector num, N_Vector denom)
178 {
179 return((realtype) num->ops->nvminquotient(num, denom));
180 }
181
182 /* -----------------------------------------------------------------
183 * fused vector operations
184 * ----------------------------------------------------------------- */
185
N_VLinearCombination(int nvec,realtype * c,N_Vector * X,N_Vector z)186 int N_VLinearCombination(int nvec, realtype* c, N_Vector* X, N_Vector z)
187 {
188 int i;
189 realtype ONE=RCONST(1.0);
190
191 if (z->ops->nvlinearcombination != NULL) {
192
193 return(z->ops->nvlinearcombination(nvec, c, X, z));
194
195 } else {
196
197 z->ops->nvscale(c[0], X[0], z);
198 for (i=1; i<nvec; i++) {
199 z->ops->nvlinearsum(c[i], X[i], ONE, z, z);
200 }
201 return(0);
202
203 }
204 }
205
N_VScaleAddMulti(int nvec,realtype * a,N_Vector x,N_Vector * Y,N_Vector * Z)206 int N_VScaleAddMulti(int nvec, realtype* a, N_Vector x, N_Vector* Y, N_Vector* Z)
207 {
208 int i;
209 realtype ONE=RCONST(1.0);
210
211 if (x->ops->nvscaleaddmulti != NULL) {
212
213 return(x->ops->nvscaleaddmulti(nvec, a, x, Y, Z));
214
215 } else {
216
217 for (i=0; i<nvec; i++) {
218 x->ops->nvlinearsum(a[i], x, ONE, Y[i], Z[i]);
219 }
220 return(0);
221
222 }
223 }
224
N_VDotProdMulti(int nvec,N_Vector x,N_Vector * Y,realtype * dotprods)225 int N_VDotProdMulti(int nvec, N_Vector x, N_Vector* Y, realtype* dotprods)
226 {
227 int i;
228
229 if (x->ops->nvdotprodmulti != NULL) {
230
231 return(x->ops->nvdotprodmulti(nvec, x, Y, dotprods));
232
233 } else {
234
235 for (i=0; i<nvec; i++) {
236 dotprods[i] = x->ops->nvdotprod(x, Y[i]);
237 }
238 return(0);
239
240 }
241 }
242
243 /* -----------------------------------------------------------------
244 * vector array operations
245 * ----------------------------------------------------------------- */
246
N_VLinearSumVectorArray(int nvec,realtype a,N_Vector * X,realtype b,N_Vector * Y,N_Vector * Z)247 int N_VLinearSumVectorArray(int nvec, realtype a, N_Vector* X,
248 realtype b, N_Vector* Y, N_Vector* Z)
249 {
250 int i;
251
252 if (Z[0]->ops->nvlinearsumvectorarray != NULL) {
253
254 return(Z[0]->ops->nvlinearsumvectorarray(nvec, a, X, b, Y, Z));
255
256 } else {
257
258 for (i=0; i<nvec; i++) {
259 Z[0]->ops->nvlinearsum(a, X[i], b, Y[i], Z[i]);
260 }
261 return(0);
262
263 }
264 }
265
N_VScaleVectorArray(int nvec,realtype * c,N_Vector * X,N_Vector * Z)266 int N_VScaleVectorArray(int nvec, realtype* c, N_Vector* X, N_Vector* Z)
267 {
268 int i;
269
270 if (Z[0]->ops->nvscalevectorarray != NULL) {
271
272 return(Z[0]->ops->nvscalevectorarray(nvec, c, X, Z));
273
274 } else {
275
276 for (i=0; i<nvec; i++) {
277 Z[0]->ops->nvscale(c[i], X[i], Z[i]);
278 }
279 return(0);
280
281 }
282 }
283
N_VConstVectorArray(int nvec,realtype c,N_Vector * Z)284 int N_VConstVectorArray(int nvec, realtype c, N_Vector* Z)
285 {
286 int i, ier;
287
288 if (Z[0]->ops->nvconstvectorarray != NULL) {
289
290 ier = Z[0]->ops->nvconstvectorarray(nvec, c, Z);
291 return(ier);
292
293 } else {
294
295 for (i=0; i<nvec; i++) {
296 Z[0]->ops->nvconst(c, Z[i]);
297 }
298 return(0);
299
300 }
301 }
302
N_VWrmsNormVectorArray(int nvec,N_Vector * X,N_Vector * W,realtype * nrm)303 int N_VWrmsNormVectorArray(int nvec, N_Vector* X, N_Vector* W, realtype* nrm)
304 {
305 int i, ier;
306
307 if (X[0]->ops->nvwrmsnormvectorarray != NULL) {
308
309 ier = X[0]->ops->nvwrmsnormvectorarray(nvec, X, W, nrm);
310 return(ier);
311
312 } else {
313
314 for (i=0; i<nvec; i++) {
315 nrm[i] = X[0]->ops->nvwrmsnorm(X[i], W[i]);
316 }
317 return(0);
318
319 }
320 }
321
N_VWrmsNormMaskVectorArray(int nvec,N_Vector * X,N_Vector * W,N_Vector id,realtype * nrm)322 int N_VWrmsNormMaskVectorArray(int nvec, N_Vector* X, N_Vector* W, N_Vector id,
323 realtype* nrm)
324 {
325 int i, ier;
326
327 if (id->ops->nvwrmsnormmaskvectorarray != NULL) {
328
329 ier = id->ops->nvwrmsnormmaskvectorarray(nvec, X, W, id, nrm);
330 return(ier);
331
332 } else {
333
334 for (i=0; i<nvec; i++) {
335 nrm[i] = id->ops->nvwrmsnormmask(X[i], W[i], id);
336 }
337 return(0);
338
339 }
340 }
341
N_VScaleAddMultiVectorArray(int nvec,int nsum,realtype * a,N_Vector * X,N_Vector ** Y,N_Vector ** Z)342 int N_VScaleAddMultiVectorArray(int nvec, int nsum, realtype* a, N_Vector* X,
343 N_Vector** Y, N_Vector** Z)
344 {
345 int i, j, ier;
346 realtype ONE=RCONST(1.0);
347 N_Vector* YY=NULL;
348 N_Vector* ZZ=NULL;
349
350 if (X[0]->ops->nvscaleaddmultivectorarray != NULL) {
351
352 ier = X[0]->ops->nvscaleaddmultivectorarray(nvec, nsum, a, X, Y, Z);
353 return(ier);
354
355 } else if (X[0]->ops->nvscaleaddmulti != NULL ) {
356
357 /* allocate arrays of vectors */
358 YY = (N_Vector *) malloc(nsum * sizeof(N_Vector));
359 ZZ = (N_Vector *) malloc(nsum * sizeof(N_Vector));
360
361 for (i=0; i<nvec; i++) {
362
363 for (j=0; j<nsum; j++) {
364 YY[j] = Y[j][i];
365 ZZ[j] = Z[j][i];
366 }
367
368 ier = X[0]->ops->nvscaleaddmulti(nsum, a, X[i], YY, ZZ);
369 if (ier != 0) break;
370 }
371
372 /* free array of vectors */
373 free(YY);
374 free(ZZ);
375
376 return(ier);
377
378 } else {
379
380 for (i=0; i<nvec; i++) {
381 for (j=0; j<nsum; j++) {
382 X[0]->ops->nvlinearsum(a[j], X[i], ONE, Y[j][i], Z[j][i]);
383 }
384 }
385 return(0);
386 }
387 }
388
N_VLinearCombinationVectorArray(int nvec,int nsum,realtype * c,N_Vector ** X,N_Vector * Z)389 int N_VLinearCombinationVectorArray(int nvec, int nsum, realtype* c, N_Vector** X,
390 N_Vector* Z)
391 {
392 int i, j, ier;
393 realtype ONE=RCONST(1.0);
394 N_Vector* Y=NULL;
395
396 if (Z[0]->ops->nvlinearcombinationvectorarray != NULL) {
397
398 ier = Z[0]->ops->nvlinearcombinationvectorarray(nvec, nsum, c, X, Z);
399 return(ier);
400
401 } else if (Z[0]->ops->nvlinearcombination != NULL ) {
402
403 /* allocate array of vectors */
404 Y = (N_Vector *) malloc(nsum * sizeof(N_Vector));
405
406 for (i=0; i<nvec; i++) {
407
408 for (j=0; j<nsum; j++) {
409 Y[j] = X[j][i];
410 }
411
412 ier = Z[0]->ops->nvlinearcombination(nsum, c, Y, Z[i]);
413 if (ier != 0) break;
414 }
415
416 /* free array of vectors */
417 free(Y);
418
419 return(ier);
420
421 } else {
422
423 for (i=0; i<nvec; i++) {
424 Z[0]->ops->nvscale(c[0], X[0][i], Z[i]);
425 for (j=1; j<nsum; j++) {
426 Z[0]->ops->nvlinearsum(c[j], X[j][i], ONE, Z[i], Z[i]);
427 }
428 }
429 return(0);
430 }
431 }
432
433 /*
434 * -----------------------------------------------------------------
435 * Additional functions exported by the generic NVECTOR:
436 * N_VCloneEmptyVectorArray
437 * N_VCloneVectorArray
438 * N_VDestroyVectorArray
439 * -----------------------------------------------------------------
440 */
441
N_VCloneEmptyVectorArray(int count,N_Vector w)442 N_Vector *N_VCloneEmptyVectorArray(int count, N_Vector w)
443 {
444 N_Vector *vs = NULL;
445 int j;
446
447 if (count <= 0) return(NULL);
448
449 vs = (N_Vector *) malloc(count * sizeof(N_Vector));
450 if(vs == NULL) return(NULL);
451
452 for (j = 0; j < count; j++) {
453 vs[j] = N_VCloneEmpty(w);
454 if (vs[j] == NULL) {
455 N_VDestroyVectorArray(vs, j-1);
456 return(NULL);
457 }
458 }
459
460 return(vs);
461 }
462
N_VCloneVectorArray(int count,N_Vector w)463 N_Vector *N_VCloneVectorArray(int count, N_Vector w)
464 {
465 N_Vector *vs = NULL;
466 int j;
467
468 if (count <= 0) return(NULL);
469
470 vs = (N_Vector *) malloc(count * sizeof(N_Vector));
471 if(vs == NULL) return(NULL);
472
473 for (j = 0; j < count; j++) {
474 vs[j] = N_VClone(w);
475 if (vs[j] == NULL) {
476 N_VDestroyVectorArray(vs, j-1);
477 return(NULL);
478 }
479 }
480
481 return(vs);
482 }
483
N_VDestroyVectorArray(N_Vector * vs,int count)484 void N_VDestroyVectorArray(N_Vector *vs, int count)
485 {
486 int j;
487
488 if (vs==NULL) return;
489
490 for (j = 0; j < count; j++) N_VDestroy(vs[j]);
491
492 free(vs); vs = NULL;
493
494 return;
495 }
496