Actual source code: bvec2.c
1: #define PETSCVEC_DLL
2: /*
3: Implements the sequential vectors.
4: */
6: #include private/vecimpl.h
7: #include src/vec/vec/impls/dvecimpl.h
8: #include src/inline/dot.h
9: #include petscblaslapack.h
10: #if defined(PETSC_HAVE_PNETCDF)
12: #include "pnetcdf.h"
14: #endif
18: PetscErrorCode VecNorm_Seq(Vec xin,NormType type,PetscReal* z)
19: {
20: PetscScalar *xx;
22: PetscInt n = xin->map.n;
23: PetscBLASInt bn = (PetscBLASInt)n,one = 1;
26: if (type == NORM_2 || type == NORM_FROBENIUS) {
27: VecGetArray(xin,&xx);
28: /*
29: This is because the Fortran BLAS 1 Norm is very slow!
30: */
31: #if defined(PETSC_HAVE_SLOW_BLAS_NORM2)
32: #if defined(PETSC_USE_FORTRAN_KERNEL_NORM)
33: fortrannormsqr_(xx,&n,z);
34: *z = sqrt(*z);
35: #elif defined(PETSC_USE_UNROLLED_NORM)
36: {
37: PetscReal work = 0.0;
38: switch (n & 0x3) {
39: case 3: work += PetscRealPart(xx[0]*PetscConj(xx[0])); xx++;
40: case 2: work += PetscRealPart(xx[0]*PetscConj(xx[0])); xx++;
41: case 1: work += PetscRealPart(xx[0]*PetscConj(xx[0])); xx++; n -= 4;
42: }
43: while (n>0) {
44: work += PetscRealPart(xx[0]*PetscConj(xx[0])+xx[1]*PetscConj(xx[1])+
45: xx[2]*PetscConj(xx[2])+xx[3]*PetscConj(xx[3]));
46: xx += 4; n -= 4;
47: }
48: *z = sqrt(work);}
49: #else
50: {
51: PetscInt i;
52: PetscScalar sum=0.0;
53: for (i=0; i<n; i++) {
54: sum += (xx[i])*(PetscConj(xx[i]));
55: }
56: *z = sqrt(PetscRealPart(sum));
57: }
58: #endif
59: #else
60: *z = BLASnrm2_(&bn,xx,&one);
61: #endif
62: VecRestoreArray(xin,&xx);
63: if (n > 0) {
64: PetscLogFlops(2*n-1);
65: }
66: } else if (type == NORM_INFINITY) {
67: PetscInt i;
68: PetscReal max = 0.0,tmp;
70: VecGetArray(xin,&xx);
71: for (i=0; i<n; i++) {
72: if ((tmp = PetscAbsScalar(*xx)) > max) max = tmp;
73: /* check special case of tmp == NaN */
74: if (tmp != tmp) {max = tmp; break;}
75: xx++;
76: }
77: VecRestoreArray(xin,&xx);
78: *z = max;
79: } else if (type == NORM_1) {
80: VecGetArray(xin,&xx);
81: *z = BLASasum_(&bn,xx,&one);
82: VecRestoreArray(xin,&xx);
83: if (n > 0) {
84: PetscLogFlops(n-1);
85: }
86: } else if (type == NORM_1_AND_2) {
87: VecNorm_Seq(xin,NORM_1,z);
88: VecNorm_Seq(xin,NORM_2,z+1);
89: }
90: return(0);
91: }
95: PetscErrorCode VecView_Seq_File(Vec xin,PetscViewer viewer)
96: {
97: Vec_Seq *x = (Vec_Seq *)xin->data;
98: PetscErrorCode ierr;
99: PetscInt i,n = xin->map.n;
100: const char *name;
101: PetscViewerFormat format;
104: PetscViewerGetFormat(viewer,&format);
105: if (format == PETSC_VIEWER_ASCII_MATLAB) {
106: PetscObjectGetName((PetscObject)xin,&name);
107: PetscViewerASCIIPrintf(viewer,"%s = [\n",name);
108: for (i=0; i<n; i++) {
109: #if defined(PETSC_USE_COMPLEX)
110: if (PetscImaginaryPart(x->array[i]) > 0.0) {
111: PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei\n",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
112: } else if (PetscImaginaryPart(x->array[i]) < 0.0) {
113: PetscViewerASCIIPrintf(viewer,"%18.16e - %18.16ei\n",PetscRealPart(x->array[i]),-PetscImaginaryPart(x->array[i]));
114: } else {
115: PetscViewerASCIIPrintf(viewer,"%18.16e\n",PetscRealPart(x->array[i]));
116: }
117: #else
118: PetscViewerASCIIPrintf(viewer,"%18.16e\n",x->array[i]);
119: #endif
120: }
121: PetscViewerASCIIPrintf(viewer,"];\n");
122: } else if (format == PETSC_VIEWER_ASCII_SYMMODU) {
123: for (i=0; i<n; i++) {
124: #if defined(PETSC_USE_COMPLEX)
125: PetscViewerASCIIPrintf(viewer,"%18.16e %18.16e\n",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
126: #else
127: PetscViewerASCIIPrintf(viewer,"%18.16e\n",x->array[i]);
128: #endif
129: }
130: } else if (format == PETSC_VIEWER_ASCII_VTK || format == PETSC_VIEWER_ASCII_VTK_CELL) {
131: /*
132: state 0: No header has been output
133: state 1: Only POINT_DATA has been output
134: state 2: Only CELL_DATA has been output
135: state 3: Output both, POINT_DATA last
136: state 4: Output both, CELL_DATA last
137: */
138: static PetscInt stateId = -1;
139: int outputState = 0;
140: PetscTruth hasState;
141: int doOutput = 0;
142: PetscInt bs, b;
144: if (stateId < 0) {
145: PetscObjectComposedDataRegister(&stateId);
146: }
147: PetscObjectComposedDataGetInt((PetscObject) viewer, stateId, outputState, hasState);
148: if (!hasState) {
149: outputState = 0;
150: }
151: PetscObjectGetName((PetscObject) xin, &name);
152: VecGetBlockSize(xin, &bs);
153: if ((bs < 1) || (bs > 3)) {
154: SETERRQ1(PETSC_ERR_ARG_WRONGSTATE, "VTK can only handle 3D objects, but vector dimension is %d", bs);
155: }
156: if (format == PETSC_VIEWER_ASCII_VTK) {
157: if (outputState == 0) {
158: outputState = 1;
159: doOutput = 1;
160: } else if (outputState == 1) {
161: doOutput = 0;
162: } else if (outputState == 2) {
163: outputState = 3;
164: doOutput = 1;
165: } else if (outputState == 3) {
166: doOutput = 0;
167: } else if (outputState == 4) {
168: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Tried to output POINT_DATA again after intervening CELL_DATA");
169: }
170: if (doOutput) {
171: PetscViewerASCIIPrintf(viewer, "POINT_DATA %d\n", n);
172: }
173: } else {
174: if (outputState == 0) {
175: outputState = 2;
176: doOutput = 1;
177: } else if (outputState == 1) {
178: outputState = 4;
179: doOutput = 1;
180: } else if (outputState == 2) {
181: doOutput = 0;
182: } else if (outputState == 3) {
183: SETERRQ(PETSC_ERR_ARG_WRONGSTATE, "Tried to output CELL_DATA again after intervening POINT_DATA");
184: } else if (outputState == 4) {
185: doOutput = 0;
186: }
187: if (doOutput) {
188: PetscViewerASCIIPrintf(viewer, "CELL_DATA %d\n", n);
189: }
190: }
191: PetscObjectComposedDataSetInt((PetscObject) viewer, stateId, outputState);
192: if (name) {
193: PetscViewerASCIIPrintf(viewer, "SCALARS %s double %d\n", name, bs);
194: } else {
195: PetscViewerASCIIPrintf(viewer, "SCALARS scalars double %d\n", bs);
196: }
197: PetscViewerASCIIPrintf(viewer, "LOOKUP_TABLE default\n");
198: for (i=0; i<n/bs; i++) {
199: for (b=0; b<bs; b++) {
200: if (b > 0) {
201: PetscViewerASCIIPrintf(viewer," ");
202: }
203: #if !defined(PETSC_USE_COMPLEX)
204: PetscViewerASCIIPrintf(viewer,"%G",x->array[i*bs+b]);
205: #endif
206: }
207: PetscViewerASCIIPrintf(viewer,"\n");
208: }
209: } else if (format == PETSC_VIEWER_ASCII_VTK_COORDS) {
210: PetscInt bs, b;
212: VecGetBlockSize(xin, &bs);
213: if ((bs < 1) || (bs > 3)) {
214: SETERRQ1(PETSC_ERR_ARG_WRONGSTATE, "VTK can only handle 3D objects, but vector dimension is %d", bs);
215: }
216: for (i=0; i<n/bs; i++) {
217: for (b=0; b<bs; b++) {
218: if (b > 0) {
219: PetscViewerASCIIPrintf(viewer," ");
220: }
221: #if !defined(PETSC_USE_COMPLEX)
222: PetscViewerASCIIPrintf(viewer,"%G",x->array[i*bs+b]);
223: #endif
224: }
225: for (b=bs; b<3; b++) {
226: PetscViewerASCIIPrintf(viewer," 0.0");
227: }
228: PetscViewerASCIIPrintf(viewer,"\n");
229: }
230: } else if (format == PETSC_VIEWER_ASCII_PCICE) {
231: PetscInt bs, b;
233: VecGetBlockSize(xin, &bs);
234: if ((bs < 1) || (bs > 3)) {
235: SETERRQ1(PETSC_ERR_ARG_WRONGSTATE, "PCICE can only handle up to 3D objects, but vector dimension is %d", bs);
236: }
237: PetscViewerASCIIPrintf(viewer,"%D\n", xin->map.N/bs);
238: for (i=0; i<n/bs; i++) {
239: PetscViewerASCIIPrintf(viewer,"%7D ", i+1);
240: for (b=0; b<bs; b++) {
241: if (b > 0) {
242: PetscViewerASCIIPrintf(viewer," ");
243: }
244: #if !defined(PETSC_USE_COMPLEX)
245: PetscViewerASCIIPrintf(viewer,"% 12.5E",x->array[i*bs+b]);
246: #endif
247: }
248: PetscViewerASCIIPrintf(viewer,"\n");
249: }
250: } else if (format == PETSC_VIEWER_ASCII_PYLITH) {
251: PetscInt bs, b;
253: VecGetBlockSize(xin, &bs);
254: if (bs != 3) {
255: SETERRQ1(PETSC_ERR_ARG_WRONGSTATE, "PyLith can only handle 3D objects, but vector dimension is %d", bs);
256: }
257: PetscViewerASCIIPrintf(viewer,"#\n");
258: PetscViewerASCIIPrintf(viewer,"# Node X-coord Y-coord Z-coord\n");
259: PetscViewerASCIIPrintf(viewer,"#\n");
260: for (i=0; i<n/bs; i++) {
261: PetscViewerASCIIPrintf(viewer,"%7D ", i+1);
262: for (b=0; b<bs; b++) {
263: if (b > 0) {
264: PetscViewerASCIIPrintf(viewer," ");
265: }
266: #if !defined(PETSC_USE_COMPLEX)
267: PetscViewerASCIIPrintf(viewer,"% 16.8E",x->array[i*bs+b]);
268: #endif
269: }
270: PetscViewerASCIIPrintf(viewer,"\n");
271: }
272: } else {
273: for (i=0; i<n; i++) {
274: if (format == PETSC_VIEWER_ASCII_INDEX) {
275: PetscViewerASCIIPrintf(viewer,"%D: ",i);
276: }
277: #if defined(PETSC_USE_COMPLEX)
278: if (PetscImaginaryPart(x->array[i]) > 0.0) {
279: PetscViewerASCIIPrintf(viewer,"%G + %G i\n",PetscRealPart(x->array[i]),PetscImaginaryPart(x->array[i]));
280: } else if (PetscImaginaryPart(x->array[i]) < 0.0) {
281: PetscViewerASCIIPrintf(viewer,"%G - %G i\n",PetscRealPart(x->array[i]),-PetscImaginaryPart(x->array[i]));
282: } else {
283: PetscViewerASCIIPrintf(viewer,"%G\n",PetscRealPart(x->array[i]));
284: }
285: #else
286: PetscViewerASCIIPrintf(viewer,"%G\n",x->array[i]);
287: #endif
288: }
289: }
290: PetscViewerFlush(viewer);
291: return(0);
292: }
296: static PetscErrorCode VecView_Seq_Draw_LG(Vec xin,PetscViewer v)
297: {
298: Vec_Seq *x = (Vec_Seq *)xin->data;
300: PetscInt i,n = xin->map.n;
301: PetscDraw win;
302: PetscReal *xx;
303: PetscDrawLG lg;
306: PetscViewerDrawGetDrawLG(v,0,&lg);
307: PetscDrawLGGetDraw(lg,&win);
308: PetscDrawCheckResizedWindow(win);
309: PetscDrawLGReset(lg);
310: PetscMalloc((n+1)*sizeof(PetscReal),&xx);
311: for (i=0; i<n; i++) {
312: xx[i] = (PetscReal) i;
313: }
314: #if !defined(PETSC_USE_COMPLEX)
315: PetscDrawLGAddPoints(lg,n,&xx,&x->array);
316: #else
317: {
318: PetscReal *yy;
319: PetscMalloc((n+1)*sizeof(PetscReal),&yy);
320: for (i=0; i<n; i++) {
321: yy[i] = PetscRealPart(x->array[i]);
322: }
323: PetscDrawLGAddPoints(lg,n,&xx,&yy);
324: PetscFree(yy);
325: }
326: #endif
327: PetscFree(xx);
328: PetscDrawLGDraw(lg);
329: PetscDrawSynchronizedFlush(win);
330: return(0);
331: }
335: static PetscErrorCode VecView_Seq_Draw(Vec xin,PetscViewer v)
336: {
337: PetscErrorCode ierr;
338: PetscDraw draw;
339: PetscTruth isnull;
340: PetscViewerFormat format;
343: PetscViewerDrawGetDraw(v,0,&draw);
344: PetscDrawIsNull(draw,&isnull); if (isnull) return(0);
345:
346: PetscViewerGetFormat(v,&format);
347: /*
348: Currently it only supports drawing to a line graph */
349: if (format != PETSC_VIEWER_DRAW_LG) {
350: PetscViewerPushFormat(v,PETSC_VIEWER_DRAW_LG);
351: }
352: VecView_Seq_Draw_LG(xin,v);
353: if (format != PETSC_VIEWER_DRAW_LG) {
354: PetscViewerPopFormat(v);
355: }
357: return(0);
358: }
362: static PetscErrorCode VecView_Seq_Binary(Vec xin,PetscViewer viewer)
363: {
364: Vec_Seq *x = (Vec_Seq *)xin->data;
366: int fdes;
367: PetscInt n = xin->map.n,cookie=VEC_FILE_COOKIE;
368: FILE *file;
371: PetscViewerBinaryGetDescriptor(viewer,&fdes);
372: /* Write vector header */
373: PetscBinaryWrite(fdes,&cookie,1,PETSC_INT,PETSC_FALSE);
374: PetscBinaryWrite(fdes,&n,1,PETSC_INT,PETSC_FALSE);
376: /* Write vector contents */
377: PetscBinaryWrite(fdes,x->array,n,PETSC_SCALAR,PETSC_FALSE);
379: PetscViewerBinaryGetInfoPointer(viewer,&file);
380: if (file && xin->map.bs > 1) {
381: if (xin->prefix) {
382: PetscFPrintf(PETSC_COMM_SELF,file,"-%s_vecload_block_size %D\n",xin->prefix,xin->map.bs);
383: } else {
384: PetscFPrintf(PETSC_COMM_SELF,file,"-vecload_block_size %D\n",xin->map.bs);
385: }
386: }
387: return(0);
388: }
390: #if defined(PETSC_HAVE_PNETCDF)
393: PetscErrorCode VecView_Seq_Netcdf(Vec xin,PetscViewer v)
394: {
396: int n = xin->map.n,ncid,xdim,xdim_num=1,xin_id,xstart=0;
397: PetscScalar *xarray;
400: #if !defined(PETSC_USE_COMPLEX)
401: VecGetArray(xin,&xarray);
402: PetscViewerNetcdfGetID(v,&ncid);
403: if (ncid < 0) SETERRQ(PETSC_ERR_ORDER,"First call PetscViewerNetcdfOpen to create NetCDF dataset");
404: /* define dimensions */
405: ncmpi_def_dim(ncid,"PETSc_Vector_Global_Size",n,&xdim);
406: /* define variables */
407: ncmpi_def_var(ncid,"PETSc_Vector_Seq",NC_DOUBLE,xdim_num,&xdim,&xin_id);
408: /* leave define mode */
409: ncmpi_enddef(ncid);
410: /* store the vector */
411: VecGetOwnershipRange(xin,&xstart,PETSC_NULL);
412: ncmpi_put_vara_double_all(ncid,xin_id,(const MPI_Offset*)&xstart,(const MPI_Offset*)&n,xarray);
413: #else
414: PetscPrintf(PETSC_COMM_WORLD,"NetCDF viewer not supported for complex numbers\n");
415: #endif
416: return(0);
417: }
418: #endif
420: #if defined(PETSC_HAVE_MATLAB_ENGINE)
421: #include "mat.h" /* Matlab include file */
425: PetscErrorCode VecView_Seq_Matlab(Vec vec,PetscViewer viewer)
426: {
428: PetscInt n;
429: PetscScalar *array;
430:
432: VecGetLocalSize(vec,&n);
433: PetscObjectName((PetscObject)vec);
434: VecGetArray(vec,&array);
435: PetscViewerMatlabPutArray(viewer,n,1,array,vec->name);
436: VecRestoreArray(vec,&array);
437: return(0);
438: }
440: #endif
444: PetscErrorCode VecView_Seq(Vec xin,PetscViewer viewer)
445: {
447: PetscTruth isdraw,iascii,issocket,isbinary;
448: #if defined(PETSC_HAVE_MATHEMATICA)
449: PetscTruth ismathematica;
450: #endif
451: #if defined(PETSC_HAVE_PNETCDF)
452: PetscTruth isnetcdf;
453: #endif
454: #if defined(PETSC_HAVE_MATLAB_ENGINE)
455: PetscTruth ismatlab;
456: #endif
459: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_DRAW,&isdraw);
460: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
461: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
462: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_BINARY,&isbinary);
463: #if defined(PETSC_HAVE_MATHEMATICA)
464: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_MATHEMATICA,&ismathematica);
465: #endif
466: #if defined(PETSC_HAVE_PNETCDF)
467: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_NETCDF,&isnetcdf);
468: #endif
469: #if defined(PETSC_HAVE_MATLAB_ENGINE)
470: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_MATLAB,&ismatlab);
471: #endif
473: if (isdraw){
474: VecView_Seq_Draw(xin,viewer);
475: } else if (iascii){
476: VecView_Seq_File(xin,viewer);
477: } else if (isbinary) {
478: VecView_Seq_Binary(xin,viewer);
479: #if defined(PETSC_HAVE_MATHEMATICA)
480: } else if (ismathematica) {
481: PetscViewerMathematicaPutVector(viewer,xin);
482: #endif
483: #if defined(PETSC_HAVE_PNETCDF)
484: } else if (isnetcdf) {
485: VecView_Seq_Netcdf(xin,viewer);
486: #endif
487: #if defined(PETSC_HAVE_MATLAB_ENGINE)
488: } else if (ismatlab) {
489: VecView_Seq_Matlab(xin,viewer);
490: #endif
491: } else {
492: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this vector object",((PetscObject)viewer)->type_name);
493: }
494: return(0);
495: }
499: PetscErrorCode VecGetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],PetscScalar y[])
500: {
501: Vec_Seq *x = (Vec_Seq *)xin->data;
502: PetscScalar *xx = x->array;
503: PetscInt i;
506: for (i=0; i<ni; i++) {
507: if (xin->stash.ignorenegidx == PETSC_TRUE && ix[i] < 0) continue;
508: #if defined(PETSC_USE_DEBUG)
509: if (ix[i] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D cannot be negative",ix[i]);
510: if (ix[i] >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D to large maximum allowed %D",ix[i],xin->map.n);
511: #endif
512: y[i] = xx[ix[i]];
513: }
514: return(0);
515: }
519: PetscErrorCode VecSetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode m)
520: {
521: Vec_Seq *x = (Vec_Seq *)xin->data;
522: PetscScalar *xx = x->array;
523: PetscInt i;
526: if (m == INSERT_VALUES) {
527: for (i=0; i<ni; i++) {
528: if (xin->stash.ignorenegidx == PETSC_TRUE && ix[i] < 0) continue;
529: #if defined(PETSC_USE_DEBUG)
530: if (ix[i] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D cannot be negative",ix[i]);
531: if (ix[i] >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->map.n);
532: #endif
533: xx[ix[i]] = y[i];
534: }
535: } else {
536: for (i=0; i<ni; i++) {
537: if (xin->stash.ignorenegidx == PETSC_TRUE && ix[i] < 0) continue;
538: #if defined(PETSC_USE_DEBUG)
539: if (ix[i] >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->map.n);
540: #endif
541: xx[ix[i]] += y[i];
542: }
543: }
544: return(0);
545: }
549: PetscErrorCode VecSetValuesBlocked_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar yin[],InsertMode m)
550: {
551: Vec_Seq *x = (Vec_Seq *)xin->data;
552: PetscScalar *xx = x->array,*y = (PetscScalar*)yin;
553: PetscInt i,bs = xin->map.bs,start,j;
555: /*
556: For optimization could treat bs = 2, 3, 4, 5 as special cases with loop unrolling
557: */
559: if (m == INSERT_VALUES) {
560: for (i=0; i<ni; i++) {
561: start = bs*ix[i];
562: if (start < 0) continue;
563: #if defined(PETSC_USE_DEBUG)
564: if (start >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->map.n);
565: #endif
566: for (j=0; j<bs; j++) {
567: xx[start+j] = y[j];
568: }
569: y += bs;
570: }
571: } else {
572: for (i=0; i<ni; i++) {
573: start = bs*ix[i];
574: if (start < 0) continue;
575: #if defined(PETSC_USE_DEBUG)
576: if (start >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->map.n);
577: #endif
578: for (j=0; j<bs; j++) {
579: xx[start+j] += y[j];
580: }
581: y += bs;
582: }
583: }
584: return(0);
585: }
590: PetscErrorCode VecDestroy_Seq(Vec v)
591: {
592: Vec_Seq *vs = (Vec_Seq*)v->data;
597: /* if memory was published with AMS then destroy it */
598: PetscObjectDepublish(v);
600: #if defined(PETSC_USE_LOG)
601: PetscLogObjectState((PetscObject)v,"Length=%D",v->map.n);
602: #endif
603: PetscFree(vs->array_allocated);
604: PetscFree(vs);
606: return(0);
607: }
611: static PetscErrorCode VecPublish_Seq(PetscObject obj)
612: {
614: return(0);
615: }
617: EXTERN PetscErrorCode VecLoad_Binary(PetscViewer, VecType, Vec*);
619: static struct _VecOps DvOps = {VecDuplicate_Seq, /* 1 */
620: VecDuplicateVecs_Default,
621: VecDestroyVecs_Default,
622: VecDot_Seq,
623: VecMDot_Seq,
624: VecNorm_Seq,
625: VecTDot_Seq,
626: VecMTDot_Seq,
627: VecScale_Seq,
628: VecCopy_Seq, /* 10 */
629: VecSet_Seq,
630: VecSwap_Seq,
631: VecAXPY_Seq,
632: VecAXPBY_Seq,
633: VecMAXPY_Seq,
634: VecAYPX_Seq,
635: VecWAXPY_Seq,
636: VecPointwiseMult_Seq,
637: VecPointwiseDivide_Seq,
638: VecSetValues_Seq, /* 20 */
639: 0,0,
640: VecGetArray_Seq,
641: VecGetSize_Seq,
642: VecGetSize_Seq,
643: VecRestoreArray_Seq,
644: VecMax_Seq,
645: VecMin_Seq,
646: VecSetRandom_Seq,
647: VecSetOption_Seq, /* 30 */
648: VecSetValuesBlocked_Seq,
649: VecDestroy_Seq,
650: VecView_Seq,
651: VecPlaceArray_Seq,
652: VecReplaceArray_Seq,
653: VecDot_Seq,
654: VecTDot_Seq,
655: VecNorm_Seq,
656: VecMDot_Seq,
657: VecMTDot_Seq, /* 40 */
658: VecLoadIntoVector_Default,
659: VecReciprocal_Default,
660: 0, /* VecViewNative */
661: VecConjugate_Seq,
662: 0,
663: 0,
664: VecResetArray_Seq,
665: 0,
666: VecMaxPointwiseDivide_Seq,
667: VecLoad_Binary, /* 50 */
668: VecPointwiseMax_Seq,
669: VecPointwiseMaxAbs_Seq,
670: VecPointwiseMin_Seq,
671: VecGetValues_Seq
672: };
675: /*
676: This is called by VecCreate_Seq() (i.e. VecCreateSeq()) and VecCreateSeqWithArray()
677: */
680: static PetscErrorCode VecCreate_Seq_Private(Vec v,const PetscScalar array[])
681: {
682: Vec_Seq *s;
686: PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));
687: PetscNew(Vec_Seq,&s);
688: v->precision = PETSC_SCALAR;
689: v->data = (void*)s;
690: v->bops->publish = VecPublish_Seq;
691: v->petscnative = PETSC_TRUE;
692: s->array = (PetscScalar *)array;
693: s->array_allocated = 0;
695: if (v->map.bs == -1) v->map.bs = 1;
696: PetscMapSetUp(&v->map);
697: PetscObjectChangeTypeName((PetscObject)v,VECSEQ);
698: #if defined(PETSC_HAVE_MATLAB_ENGINE)
699: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEnginePut_C","VecMatlabEnginePut_Default",VecMatlabEnginePut_Default);
700: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEngineGet_C","VecMatlabEngineGet_Default",VecMatlabEngineGet_Default);
701: #endif
702: PetscPublishAll(v);
703: return(0);
704: }
708: /*@C
709: VecCreateSeqWithArray - Creates a standard,sequential array-style vector,
710: where the user provides the array space to store the vector values.
712: Collective on MPI_Comm
714: Input Parameter:
715: + comm - the communicator, should be PETSC_COMM_SELF
716: . n - the vector length
717: - array - memory where the vector elements are to be stored.
719: Output Parameter:
720: . V - the vector
722: Notes:
723: Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the
724: same type as an existing vector.
726: If the user-provided array is PETSC_NULL, then VecPlaceArray() can be used
727: at a later stage to SET the array for storing the vector values.
729: PETSc does NOT free the array when the vector is destroyed via VecDestroy().
730: The user should not free the array until the vector is destroyed.
732: Level: intermediate
734: Concepts: vectors^creating with array
736: .seealso: VecCreateMPIWithArray(), VecCreate(), VecDuplicate(), VecDuplicateVecs(),
737: VecCreateGhost(), VecCreateSeq(), VecPlaceArray()
738: @*/
739: PetscErrorCode VecCreateSeqWithArray(MPI_Comm comm,PetscInt n,const PetscScalar array[],Vec *V)
740: {
742: PetscMPIInt size;
745: VecCreate(comm,V);
746: VecSetSizes(*V,n,n);
747: MPI_Comm_size(comm,&size);
748: if (size > 1) {
749: SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot create VECSEQ on more than one process");
750: }
751: VecCreate_Seq_Private(*V,array);
752: return(0);
753: }
755: /*MC
756: VECSEQ - VECSEQ = "seq" - The basic sequential vector
758: Options Database Keys:
759: . -vec_type seq - sets the vector type to VECSEQ during a call to VecSetFromOptions()
761: Level: beginner
763: .seealso: VecCreate(), VecSetType(), VecSetFromOptions(), VecCreateSeqWithArray(), VECMPI, VecType, VecCreateMPI(), VecCreateSeq()
764: M*/
769: PetscErrorCode VecCreate_Seq(Vec V)
770: {
771: Vec_Seq *s;
772: PetscScalar *array;
774: PetscInt n = PetscMax(V->map.n,V->map.N);
775: PetscMPIInt size;
778: MPI_Comm_size(V->comm,&size);
779: if (size > 1) {
780: SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot create VECSEQ on more than one process");
781: }
782: PetscMalloc( n*sizeof(PetscScalar),&array);
783: PetscLogObjectMemory(V, n*sizeof(PetscScalar));
784: PetscMemzero(array,n*sizeof(PetscScalar));
785: VecCreate_Seq_Private(V,array);
786: s = (Vec_Seq*)V->data;
787: s->array_allocated = array;
788: return(0);
789: }
795: PetscErrorCode VecDuplicate_Seq(Vec win,Vec *V)
796: {
800: VecCreateSeq(win->comm,win->map.n,V);
801: if (win->mapping) {
802: PetscObjectReference((PetscObject)win->mapping);
803: (*V)->mapping = win->mapping;
804: }
805: if (win->bmapping) {
806: PetscObjectReference((PetscObject)win->bmapping);
807: (*V)->bmapping = win->bmapping;
808: }
809: (*V)->map.bs = win->map.bs;
810: PetscOListDuplicate(win->olist,&(*V)->olist);
811: PetscFListDuplicate(win->qlist,&(*V)->qlist);
813: (*V)->stash.ignorenegidx = win->stash.ignorenegidx;
815: return(0);
816: }
820: PetscErrorCode VecSetOption_Seq(Vec v,VecOption op)
821: {
823: if (op == VEC_IGNORE_NEGATIVE_INDICES) {
824: v->stash.ignorenegidx = PETSC_TRUE;
825: } else if (op == VEC_TREAT_NEGATIVE_INDICES) {
826: v->stash.ignorenegidx = PETSC_FALSE;
827: }
828: return(0);
829: }