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)
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)
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)
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: #if defined(PETSC_USE_SOCKET_VIEWER)
478: } else if (issocket) {
479: Vec_Seq *x = (Vec_Seq *)xin->data;
480: PetscViewerSocketPutScalar(viewer,xin->map.n,1,x->array);
481: #endif
482: } else if (isbinary) {
483: VecView_Seq_Binary(xin,viewer);
484: #if defined(PETSC_HAVE_MATHEMATICA)
485: } else if (ismathematica) {
486: PetscViewerMathematicaPutVector(viewer,xin);
487: #endif
488: #if defined(PETSC_HAVE_PNETCDF)
489: } else if (isnetcdf) {
490: VecView_Seq_Netcdf(xin,viewer);
491: #endif
492: #if defined(PETSC_HAVE_MATLAB)
493: } else if (ismatlab) {
494: VecView_Seq_Matlab(xin,viewer);
495: #endif
496: } else {
497: SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported by this vector object",((PetscObject)viewer)->type_name);
498: }
499: return(0);
500: }
504: PetscErrorCode VecGetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],PetscScalar y[])
505: {
506: Vec_Seq *x = (Vec_Seq *)xin->data;
507: PetscScalar *xx = x->array;
508: PetscInt i;
511: for (i=0; i<ni; i++) {
512: #if defined(PETSC_USE_DEBUG)
513: if (ix[i] < 0) SETERRQ1(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D cannot be negative",ix[i]);
514: 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);
515: #endif
516: y[i] = xx[ix[i]];
517: }
518: return(0);
519: }
523: PetscErrorCode VecSetValues_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar y[],InsertMode m)
524: {
525: Vec_Seq *x = (Vec_Seq *)xin->data;
526: PetscScalar *xx = x->array;
527: PetscInt i;
530: if (m == INSERT_VALUES) {
531: for (i=0; i<ni; i++) {
532: if (ix[i] < 0) continue;
533: #if defined(PETSC_USE_DEBUG)
534: if (ix[i] >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->map.n);
535: #endif
536: xx[ix[i]] = y[i];
537: }
538: } else {
539: for (i=0; i<ni; i++) {
540: if (ix[i] < 0) continue;
541: #if defined(PETSC_USE_DEBUG)
542: if (ix[i] >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",ix[i],xin->map.n);
543: #endif
544: xx[ix[i]] += y[i];
545: }
546: }
547: return(0);
548: }
552: PetscErrorCode VecSetValuesBlocked_Seq(Vec xin,PetscInt ni,const PetscInt ix[],const PetscScalar yin[],InsertMode m)
553: {
554: Vec_Seq *x = (Vec_Seq *)xin->data;
555: PetscScalar *xx = x->array,*y = (PetscScalar*)yin;
556: PetscInt i,bs = xin->map.bs,start,j;
558: /*
559: For optimization could treat bs = 2, 3, 4, 5 as special cases with loop unrolling
560: */
562: if (m == INSERT_VALUES) {
563: for (i=0; i<ni; i++) {
564: start = bs*ix[i];
565: if (start < 0) continue;
566: #if defined(PETSC_USE_DEBUG)
567: if (start >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->map.n);
568: #endif
569: for (j=0; j<bs; j++) {
570: xx[start+j] = y[j];
571: }
572: y += bs;
573: }
574: } else {
575: for (i=0; i<ni; i++) {
576: start = bs*ix[i];
577: if (start < 0) continue;
578: #if defined(PETSC_USE_DEBUG)
579: if (start >= xin->map.n) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Out of range index value %D maximum %D",start,xin->map.n);
580: #endif
581: for (j=0; j<bs; j++) {
582: xx[start+j] += y[j];
583: }
584: y += bs;
585: }
586: }
587: return(0);
588: }
593: PetscErrorCode VecDestroy_Seq(Vec v)
594: {
595: Vec_Seq *vs = (Vec_Seq*)v->data;
600: /* if memory was published with AMS then destroy it */
601: PetscObjectDepublish(v);
603: #if defined(PETSC_USE_LOG)
604: PetscLogObjectState((PetscObject)v,"Length=%D",v->map.n);
605: #endif
606: PetscFree(vs->array_allocated);
607: PetscFree(vs);
609: return(0);
610: }
614: static PetscErrorCode VecPublish_Seq(PetscObject obj)
615: {
617: return(0);
618: }
620: EXTERN PetscErrorCode VecLoad_Binary(PetscViewer, VecType, Vec*);
622: static struct _VecOps DvOps = {VecDuplicate_Seq, /* 1 */
623: VecDuplicateVecs_Default,
624: VecDestroyVecs_Default,
625: VecDot_Seq,
626: VecMDot_Seq,
627: VecNorm_Seq,
628: VecTDot_Seq,
629: VecMTDot_Seq,
630: VecScale_Seq,
631: VecCopy_Seq, /* 10 */
632: VecSet_Seq,
633: VecSwap_Seq,
634: VecAXPY_Seq,
635: VecAXPBY_Seq,
636: VecMAXPY_Seq,
637: VecAYPX_Seq,
638: VecWAXPY_Seq,
639: VecPointwiseMult_Seq,
640: VecPointwiseDivide_Seq,
641: VecSetValues_Seq, /* 20 */
642: 0,0,
643: VecGetArray_Seq,
644: VecGetSize_Seq,
645: VecGetSize_Seq,
646: VecRestoreArray_Seq,
647: VecMax_Seq,
648: VecMin_Seq,
649: VecSetRandom_Seq,0, /* 30 */
650: VecSetValuesBlocked_Seq,
651: VecDestroy_Seq,
652: VecView_Seq,
653: VecPlaceArray_Seq,
654: VecReplaceArray_Seq,
655: VecDot_Seq,
656: VecTDot_Seq,
657: VecNorm_Seq,
658: VecMDot_Seq,
659: VecMTDot_Seq, /* 40 */
660: VecLoadIntoVector_Default,
661: VecReciprocal_Default,
662: 0, /* VecViewNative */
663: VecConjugate_Seq,
664: 0,
665: 0,
666: VecResetArray_Seq,
667: 0,
668: VecMaxPointwiseDivide_Seq,
669: VecLoad_Binary, /* 50 */
670: VecPointwiseMax_Seq,
671: VecPointwiseMaxAbs_Seq,
672: VecPointwiseMin_Seq,
673: VecGetValues_Seq
674: };
677: /*
678: This is called by VecCreate_Seq() (i.e. VecCreateSeq()) and VecCreateSeqWithArray()
679: */
682: static PetscErrorCode VecCreate_Seq_Private(Vec v,const PetscScalar array[])
683: {
684: Vec_Seq *s;
688: PetscMemcpy(v->ops,&DvOps,sizeof(DvOps));
689: PetscNew(Vec_Seq,&s);
690: v->precision = PETSC_SCALAR;
691: v->data = (void*)s;
692: v->bops->publish = VecPublish_Seq;
693: v->petscnative = PETSC_TRUE;
694: s->array = (PetscScalar *)array;
695: s->array_allocated = 0;
697: if (v->map.bs == -1) v->map.bs = 1;
698: PetscMapInitialize(v->comm,&v->map);
699: PetscObjectChangeTypeName((PetscObject)v,VECSEQ);
700: #if defined(PETSC_HAVE_MATLAB)
701: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEnginePut_C","VecMatlabEnginePut_Default",VecMatlabEnginePut_Default);
702: PetscObjectComposeFunctionDynamic((PetscObject)v,"PetscMatlabEngineGet_C","VecMatlabEngineGet_Default",VecMatlabEngineGet_Default);
703: #endif
704: PetscPublishAll(v);
705: return(0);
706: }
710: /*@C
711: VecCreateSeqWithArray - Creates a standard,sequential array-style vector,
712: where the user provides the array space to store the vector values.
714: Collective on MPI_Comm
716: Input Parameter:
717: + comm - the communicator, should be PETSC_COMM_SELF
718: . n - the vector length
719: - array - memory where the vector elements are to be stored.
721: Output Parameter:
722: . V - the vector
724: Notes:
725: Use VecDuplicate() or VecDuplicateVecs() to form additional vectors of the
726: same type as an existing vector.
728: If the user-provided array is PETSC_NULL, then VecPlaceArray() can be used
729: at a later stage to SET the array for storing the vector values.
731: PETSc does NOT free the array when the vector is destroyed via VecDestroy().
732: The user should not free the array until the vector is destroyed.
734: Level: intermediate
736: Concepts: vectors^creating with array
738: .seealso: VecCreateMPIWithArray(), VecCreate(), VecDuplicate(), VecDuplicateVecs(),
739: VecCreateGhost(), VecCreateSeq(), VecPlaceArray()
740: @*/
741: PetscErrorCode VecCreateSeqWithArray(MPI_Comm comm,PetscInt n,const PetscScalar array[],Vec *V)
742: {
744: PetscMPIInt size;
747: VecCreate(comm,V);
748: VecSetSizes(*V,n,n);
749: MPI_Comm_size(comm,&size);
750: if (size > 1) {
751: SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot create VECSEQ on more than one process");
752: }
753: VecCreate_Seq_Private(*V,array);
754: return(0);
755: }
757: /*MC
758: VECSEQ - VECSEQ = "seq" - The basic sequential vector
760: Options Database Keys:
761: . -vec_type seq - sets the vector type to VECSEQ during a call to VecSetFromOptions()
763: Level: beginner
765: .seealso: VecCreate(), VecSetType(), VecSetFromOptions(), VecCreateSeqWithArray(), VECMPI, VecType, VecCreateMPI(), VecCreateSeq()
766: M*/
771: PetscErrorCode VecCreate_Seq(Vec V)
772: {
773: Vec_Seq *s;
774: PetscScalar *array;
776: PetscInt n = PetscMax(V->map.n,V->map.N);
777: PetscMPIInt size;
780: MPI_Comm_size(V->comm,&size);
781: if (size > 1) {
782: SETERRQ(PETSC_ERR_ARG_WRONG,"Cannot create VECSEQ on more than one process");
783: }
784: PetscMalloc( n*sizeof(PetscScalar),&array);
785: PetscMemzero(array,n*sizeof(PetscScalar));
786: VecCreate_Seq_Private(V,array);
787: s = (Vec_Seq*)V->data;
788: s->array_allocated = array;
789: return(0);
790: }
796: PetscErrorCode VecDuplicate_Seq(Vec win,Vec *V)
797: {
801: VecCreateSeq(win->comm,win->map.n,V);
802: if (win->mapping) {
803: (*V)->mapping = win->mapping;
804: PetscObjectReference((PetscObject)win->mapping);
805: }
806: if (win->bmapping) {
807: (*V)->bmapping = win->bmapping;
808: PetscObjectReference((PetscObject)win->bmapping);
809: }
810: (*V)->map.bs = win->map.bs;
811: PetscOListDuplicate(win->olist,&(*V)->olist);
812: PetscFListDuplicate(win->qlist,&(*V)->qlist);
813: return(0);
814: }