Actual source code: bag.c
2: #include <../src/sys/bag/bagimpl.h> /*I "petscbag.h" I*/
4: /*
5: Ugly variable to indicate if we are inside a PetscBagLoad() and should not call PetscOptions....
6: */
7: static PetscBool PetscBagInLoad = PETSC_FALSE;
11: /*
12: Adds item to the linked list in a bag
13: */
14: static PetscErrorCode PetscBagRegister_Private(PetscBag bag,PetscBagItem item,const char*name,const char*help)
15: {
19: item->freelist = PETSC_FALSE;
20: PetscStrncpy(item->name,name,PETSC_BAG_NAME_LENGTH-1);
21: PetscStrncpy(item->help,help,PETSC_BAG_HELP_LENGTH-1);
22: if (!bag->bagitems) bag->bagitems = item;
23: else {
24: PetscBagItem nitem = bag->bagitems;
25: while (nitem->next) {
26: nitem = nitem->next;
27: }
28: nitem->next = item;
29: }
30: bag->count++;
31: return(0);
32: }
36: /*@C
37: PetscBagRegisterEnum - add an enum value to the bag
39: Logically Collective on PetscBag
41: Input Parameter:
42: + bag - the bag of values
43: . addr - location of enum in struct
44: . mdefault - the initial value
45: . list - array of strings containing names of enum values followed by enum name followed by enum prefix
46: - help - longer string with more information about the value
48: Level: beginner
50: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
51: PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
52: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()
54: @*/
55: PetscErrorCode PetscBagRegisterEnum(PetscBag bag,void *addr,const char **list,PetscEnum mdefault, const char *name, const char* help)
56: {
58: PetscBagItem item;
59: char nname[PETSC_BAG_NAME_LENGTH+1];
60: PetscBool printhelp;
61: PetscInt i = 0;
64: if (!PetscBagInLoad) {
65: nname[0] = '-';
66: nname[1] = 0;
67: PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
68: PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
69: if (printhelp) {
70: while (list[i++]);
71: (*PetscHelpPrintf)(bag->bagcomm," -%s%s <%s>: (%s) %s (choose one of) ",bag->bagprefix?bag->bagprefix:"",name,list[mdefault],list[i-3],help);
72: for (i=0; list[i+2]; i++){
73: (*PetscHelpPrintf)(bag->bagcomm," %s",list[i]);
74: }
75: (*PetscHelpPrintf)(bag->bagcomm,"\n");
76: }
77: PetscOptionsGetEnum(bag->bagprefix,nname,list,&mdefault,PETSC_NULL);
78: }
80: PetscNew(struct _n_PetscBagItem,&item);
81: item->dtype = PETSC_ENUM;
82: item->offset = ((char*)addr) - ((char*)bag);
83: if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
84: item->next = 0;
85: item->msize = 1;
86: item->list = list;
87: *(PetscEnum*)addr = mdefault;
88: PetscBagRegister_Private(bag,item,name,help);
89: return(0);
90: }
94: /*@C
95: PetscBagRegisterInt - add an integer value to the bag
97: Logically Collective on PetscBag
99: Input Parameter:
100: + bag - the bag of values
101: . addr - location of integer in struct
102: . mdefault - the initial value
103: . name - name of the integer
104: - help - longer string with more information about the value
106: Level: beginner
108: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
109: PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
110: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
112: @*/
113: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault, const char* name, const char* help)
114: {
116: PetscBagItem item;
117: char nname[PETSC_BAG_NAME_LENGTH+1];
118: PetscBool printhelp;
121: if (!PetscBagInLoad) {
122: nname[0] = '-';
123: nname[1] = 0;
124: PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
125: PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
126: if (printhelp) {
127: (*PetscHelpPrintf)(bag->bagcomm," -%s%s <%d>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
128: }
129: PetscOptionsGetInt(bag->bagprefix,nname,&mdefault,PETSC_NULL);
130: }
132: PetscNew(struct _n_PetscBagItem,&item);
133: item->dtype = PETSC_INT;
134: item->offset = ((char*)addr) - ((char*)bag);
135: if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
136: item->next = 0;
137: item->msize = 1;
138: *(PetscInt*)addr = mdefault;
139: PetscBagRegister_Private(bag,item,name,help);
140: return(0);
141: }
145: /*@C
146: PetscBagRegisterString - add a string value to the bag
148: Logically Collective on PetscBag
150: Input Parameter:
151: + bag - the bag of values
152: . addr - location of start of string in struct
153: . msize - length of the string space in the struct
154: . mdefault - the initial value
155: . name - name of the string
156: - help - longer string with more information about the value
158: Level: beginner
160: Note: The struct should have the field char mystring[msize]; not char *mystring
162: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
163: PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
164: PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
166: @*/
167: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault, const char* name, const char* help)
168: {
170: PetscBagItem item;
171: char nname[PETSC_BAG_NAME_LENGTH+1];
172: PetscBool printhelp;
175: if (!PetscBagInLoad) {
176: nname[0] = '-';
177: nname[1] = 0;
178: PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
179: PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
180: if (printhelp) {
181: (*PetscHelpPrintf)(bag->bagcomm," -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
182: }
183: }
185: PetscNew(struct _n_PetscBagItem,&item);
186: item->dtype = PETSC_CHAR;
187: item->offset = ((char*)addr) - ((char*)bag);
188: if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
189: item->next = 0;
190: item->msize = msize;
191: if (mdefault != (char*)addr) {
192: PetscStrncpy((char*)addr,mdefault,msize-1);
193: }
194: if (!PetscBagInLoad) {
195: PetscOptionsGetString(bag->bagprefix,nname,(char*)addr,msize,PETSC_NULL);
196: }
197: PetscBagRegister_Private(bag,item,name,help);
198: return(0);
199: }
203: /*@C
204: PetscBagRegisterReal - add a real value to the bag
206: Logically Collective on PetscBag
208: Input Parameter:
209: + bag - the bag of values
210: . addr - location of double in struct
211: . mdefault - the initial value
212: . name - name of the variable
213: - help - longer string with more information about the value
215: Level: beginner
217: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
218: PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
219: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
221: @*/
222: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char* name, const char* help)
223: {
225: PetscBagItem item;
226: char nname[PETSC_BAG_NAME_LENGTH+1];
227: PetscBool printhelp;
230: if (!PetscBagInLoad) {
231: nname[0] = '-';
232: nname[1] = 0;
233: PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
234: PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
235: if (printhelp) {
236: (*PetscHelpPrintf)(bag->bagcomm," -%s%s <%G>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
237: }
238: PetscOptionsGetReal(bag->bagprefix,nname,&mdefault,PETSC_NULL);
239: }
241: PetscNew(struct _n_PetscBagItem,&item);
242: item->dtype = PETSC_REAL;
243: item->offset = ((char*)addr) - ((char*)bag);
244: if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
245: item->next = 0;
246: item->msize = 1;
247: *(PetscReal*)addr = mdefault;
248: PetscBagRegister_Private(bag,item,name,help);
249: return(0);
250: }
254: /*@C
255: PetscBagRegisterScalar - add a real or complex number value to the bag
257: Logically Collective on PetscBag
259: Input Parameter:
260: + bag - the bag of values
261: . addr - location of scalar in struct
262: . mdefault - the initial value
263: . name - name of the variable
264: - help - longer string with more information about the value
267: Level: beginner
269: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
270: PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
271: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
273: @*/
274: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault, const char* name, const char* help)
275: {
277: PetscBagItem item;
278: char nname[PETSC_BAG_NAME_LENGTH+1];
279: PetscBool printhelp;
282: if (!PetscBagInLoad) {
283: nname[0] = '-';
284: nname[1] = 0;
285: PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
286: PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
287: if (printhelp) {
288: (*PetscHelpPrintf)(bag->bagcomm," -%s%s <%G + %Gi>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscRealPart(mdefault),PetscImaginaryPart(mdefault),help);
289: }
290: PetscOptionsGetScalar(bag->bagprefix,nname,&mdefault,PETSC_NULL);
291: }
293: PetscNew(struct _n_PetscBagItem,&item);
294: item->dtype = PETSC_SCALAR;
295: item->offset = ((char*)addr) - ((char*)bag);
296: if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
297: item->next = 0;
298: item->msize = 1;
299: *(PetscScalar*)addr = mdefault;
300: PetscBagRegister_Private(bag,item,name,help);
301: return(0);
302: }
306: /*@C
307: PetscBagRegisterBool - add a logical value to the bag
309: Logically Collective on PetscBag
311: Input Parameter:
312: + bag - the bag of values
313: . addr - location of logical in struct
314: . mdefault - the initial value
315: . name - name of the variable
316: - help - longer string with more information about the value
319: Level: beginner
321: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
322: PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
323: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
325: @*/
326: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool mdefault, const char* name, const char* help)
327: {
329: PetscBagItem item;
330: char nname[PETSC_BAG_NAME_LENGTH+1];
331: PetscBool printhelp;
334: /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
335: if (mdefault != PETSC_FALSE && mdefault != PETSC_TRUE) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Boolean %s %s must be boolean; integer value %d",name,help,(int)mdefault);
336: if (!PetscBagInLoad) {
337: nname[0] = '-';
338: nname[1] = 0;
339: PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
340: PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
341: if (printhelp) {
342: (*PetscHelpPrintf)(bag->bagcomm," -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscBools[mdefault],help);
343: }
344: PetscOptionsGetBool(bag->bagprefix,nname,&mdefault,PETSC_NULL);
345: }
347: PetscNew(struct _n_PetscBagItem,&item);
348: item->dtype = PETSC_BOOL;
349: item->offset = ((char*)addr) - ((char*)bag);
350: if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
351: item->next = 0;
352: item->msize = 1;
353: *(PetscBool*)addr = mdefault;
354: PetscBagRegister_Private(bag,item,name,help);
355: return(0);
356: }
360: /*@C
361: PetscBagDestroy - Destroys a bag values
363: Collective on PetscBag
365: Input Parameter:
366: . bag - the bag of values
368: Level: beginner
370: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
371: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
372: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
374: @*/
375: PetscErrorCode PetscBagDestroy(PetscBag *bag)
376: {
378: PetscBagItem nitem = (*bag)->bagitems,item;
381: while (nitem) {
382: item = nitem->next;
383: if (nitem->freelist) {
384: void *v = (void*)nitem->list;
385: PetscFree(v);
386: }
387: PetscFree(nitem);
388: nitem = item;
389: }
390: if ((*bag)->bagprefix) { PetscFree((*bag)->bagprefix); }
391: PetscFree(*bag);
392: return(0);
393: }
397: /*@C
398: PetscBagSetFromOptions - Allows setting options from a bag
400: Collective on PetscBag
402: Input Parameter:
403: . bag - the bag of values
405: Level: beginner
407: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
408: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
409: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()
411: @*/
412: PetscErrorCode PetscBagSetFromOptions(PetscBag bag)
413: {
415: PetscBagItem nitem = bag->bagitems;
416: char name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
417:
419: PetscStrcpy(helpname,bag->bagname);
420: PetscStrcat(helpname," ");
421: PetscStrcat(helpname,bag->baghelp);
422: PetscOptionsBegin(bag->bagcomm,PETSC_NULL,helpname,0);
423: while (nitem) {
424: name[0] = '-';
425: name[1] = 0;
426: PetscStrcat(name,nitem->name);
427: if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
428: char *value = (char*)(((char*)bag) + nitem->offset);
429: PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,PETSC_NULL);
430: } else if (nitem->dtype == PETSC_REAL) {
431: PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
432: PetscOptionsReal(name,nitem->help,"",*value,value,PETSC_NULL);
433: } else if (nitem->dtype == PETSC_SCALAR) {
434: PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
435: PetscOptionsScalar(name,nitem->help,"",*value,value,PETSC_NULL);
436: } else if (nitem->dtype == PETSC_INT) {
437: PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
438: PetscOptionsInt(name,nitem->help,"",*value,value,PETSC_NULL);
439: } else if (nitem->dtype == PETSC_ENUM) {
440: PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
441: PetscInt i = 0;
442: while (nitem->list[i++]);
443: PetscOptionsEnum(name,nitem->help,nitem->list[i-3],nitem->list,*value,value,PETSC_NULL);
444: } else if (nitem->dtype == PETSC_BOOL) {
445: PetscBool *value = (PetscBool*)(((char*)bag) + nitem->offset);
446: PetscOptionsBool(name,nitem->help,"",*value,value,PETSC_NULL);
447: }
448: nitem = nitem->next;
449: }
451: /* process any options handlers added with PetscObjectAddOptionsHandler() */
452: PetscObjectProcessOptionsHandlers((PetscObject)bag);
453: PetscOptionsEnd();
454: return(0);
455: }
459: /*@C
460: PetscBagView - Views a bag of values as either ASCII text or a binary file
462: Collective on PetscBag
464: Input Parameter:
465: + bag - the bag of values
466: - viewer - location to view the values
468: Level: beginner
470: Warning: Currently PETSc bags saved in a binary file can only be read back
471: in on a machine of the same architecture. Let us know when this is a problem
472: and we'll fix it.
474: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
475: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
476: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()
478: @*/
479: PetscErrorCode PetscBagView(PetscBag bag,PetscViewer view)
480: {
481: PetscBool isascii,isbinary;
483: PetscBagItem nitem = bag->bagitems;
484:
486: PetscTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);
487: PetscTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
488: if (isascii) {
489: PetscViewerASCIIPrintf(view,"PetscBag Object: %s %s\n",bag->bagname,bag->baghelp);
490: while (nitem) {
491: if (nitem->dtype == PETSC_CHAR) {
492: char* value = (char*)(((char*)bag) + nitem->offset);
493: char tmp = value[nitem->msize-1]; /* special handling for fortran chars wihout null terminator */
494: value[nitem->msize-1] =0;
495: PetscViewerASCIIPrintf(view," %s = %s; %s\n",nitem->name,value,nitem->help);
496: value[nitem->msize-1] =tmp;
497: } else if (nitem->dtype == PETSC_REAL) {
498: PetscReal value = *(PetscReal*)(((char*)bag) + nitem->offset);
499: PetscViewerASCIIPrintf(view," %s = %G; %s\n",nitem->name,value,nitem->help);
500: } else if (nitem->dtype == PETSC_SCALAR) {
501: PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
502: #if defined(PETSC_USE_COMPLEX)
503: PetscViewerASCIIPrintf(view," %s = %G + %Gi; %s\n",nitem->name,PetscRealPart(value),PetscImaginaryPart(value),nitem->help);
504: #else
505: PetscViewerASCIIPrintf(view," %s = %G; %s\n",nitem->name,value,nitem->help);
506: #endif
507: } else if (nitem->dtype == PETSC_INT) {
508: PetscInt value = *(PetscInt*)(((char*)bag) + nitem->offset);
509: PetscViewerASCIIPrintf(view," %s = %D; %s\n",nitem->name,value,nitem->help);
510: } else if (nitem->dtype == PETSC_BOOL) {
511: PetscBool value = *(PetscBool*)(((char*)bag) + nitem->offset);
512: /* some Fortran compilers use -1 as boolean */
513: if (((int) value) == -1) value = PETSC_TRUE;
514: /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
515: if (value != PETSC_FALSE && value != PETSC_TRUE) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Boolean value for %s %s is corrupt; integer value %d",nitem->name,nitem->help,value);
516: PetscViewerASCIIPrintf(view," %s = %s; %s\n",nitem->name,PetscBools[value],nitem->help);
517: } else if (nitem->dtype == PETSC_ENUM) {
518: PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
519: PetscInt i = 0;
520: while (nitem->list[i++]);
521: PetscViewerASCIIPrintf(view," %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);
522: }
523: nitem = nitem->next;
524: }
525: } else if (isbinary) {
526: PetscInt classid = PETSC_BAG_FILE_CLASSID, bagsize = (PetscInt) bag->bagsize, dtype;
527: PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);
528: PetscViewerBinaryWrite(view,&bagsize,1,PETSC_INT,PETSC_TRUE);
529: PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);
530: PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
531: PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
532: while (nitem) {
533: PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);
534: dtype = (PetscInt)nitem->dtype;
535: PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);
536: PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
537: PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
538: PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);
539: /* some Fortran compilers use -1 as boolean */
540: if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;
542: PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);
543: if (dtype == PETSC_ENUM) {
544: PetscViewerBinaryWriteStringArray(view,(char **)nitem->list);
545: }
546: nitem = nitem->next;
547: }
548: } else {
549: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");
550: }
551: return(0);
552: }
556: /*@C
557: PetscBagLoad - Loads a bag of values from a binary file
559: Collective on PetscViewer
561: Input Parameter:
562: . viewer - file to load values from
564: Output Parameter:
565: . bag - the bag of values
567: Level: beginner
569: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
570: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
571: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
573: @*/
574: PetscErrorCode PetscBagLoad(PetscViewer view,PetscBag *bag)
575: {
577: PetscBool isbinary,skipoptions;
578: PetscInt classid,bagsizecount[2],i,offsetdtype[2],msize;
579: char name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
580: PetscBagItem nitem;
581: MPI_Comm comm;
584: PetscTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
585: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");
587: PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
588: if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
589: PetscViewerBinaryRead(view,bagsizecount,2,PETSC_INT);
590: PetscMalloc(bagsizecount[0],bag);
591: PetscMemzero(*bag,bagsizecount[0]);
592: (*bag)->bagsize = bagsizecount[0];
593: PetscObjectGetComm((PetscObject)view,&comm);
594: (*bag)->bagcomm = comm;
595: (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
597: PetscViewerBinaryRead(view,(*bag)->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
598: PetscViewerBinaryRead(view,(*bag)->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
600: PetscViewerBinaryGetSkipOptions(view,&skipoptions);
601: if (skipoptions) PetscBagInLoad = PETSC_TRUE;
603: for (i=0; i<bagsizecount[1]; i++) {
604: PetscViewerBinaryRead(view,offsetdtype,2,PETSC_INT);
605: PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
606: PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
607: PetscViewerBinaryRead(view,&msize,1,PETSC_INT);
609: if (offsetdtype[1] == (PetscInt) PETSC_CHAR) {
610: PetscViewerBinaryRead(view,((char*)(*bag))+offsetdtype[0],msize,PETSC_CHAR);
611: PetscBagRegisterString(*bag,((char*)(*bag))+offsetdtype[0],msize,((char*)(*bag))+offsetdtype[0],name,help);
612: } else if (offsetdtype[1] == (PetscInt) PETSC_REAL) {
613: PetscReal mdefault;
614: PetscViewerBinaryRead(view,&mdefault,1,PETSC_REAL);
615: PetscBagRegisterReal(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
616: } else if (offsetdtype[1] == (PetscInt) PETSC_SCALAR) {
617: PetscScalar mdefault;
618: PetscViewerBinaryRead(view,&mdefault,1,PETSC_SCALAR);
619: PetscBagRegisterScalar(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
620: } else if (offsetdtype[1] == (PetscInt) PETSC_INT) {
621: PetscInt mdefault;
622: PetscViewerBinaryRead(view,&mdefault,1,PETSC_INT);
623: PetscBagRegisterInt(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
624: } else if (offsetdtype[1] == (PetscInt) PETSC_BOOL) {
625: PetscBool mdefault;
626: PetscViewerBinaryRead(view,&mdefault,1,PETSC_BOOL);
627: PetscBagRegisterBool(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
628: } else if (offsetdtype[1] == (PetscInt) PETSC_ENUM) {
629: PetscEnum mdefault;
630: PetscViewerBinaryRead(view,&mdefault,1,PETSC_ENUM);
631: PetscViewerBinaryReadStringArray(view,&list);
632: PetscBagRegisterEnum(*bag,((char*)(*bag))+offsetdtype[0],(const char**)list,mdefault,name,help);
633: /* we malloced list in PetscViewerBinaryReadStringArray() so must free ourselves */
634: nitem = (*bag)->bagitems;
635: while (nitem->next) nitem = nitem->next;
636: nitem->freelist = PETSC_TRUE;
637: }
638: }
639: PetscBagInLoad = PETSC_FALSE;
640: return(0);
641: }
645: /*@
646: PetscBagCreate - Create a bag of values
648: Collective on MPI_Comm
650: Level: Intermediate
652: Input Parameters:
653: + comm - communicator to share bag
654: - bagsize - size of the C structure holding the values
656: Output Parameter:
657: . bag - the bag of values
659: Notes:
660: The size of the A struct must be small enough to fit in a PetscInt; by default
661: PetscInt is 4 bytes. The warning about casting to a shorter length can be ignored
662: below unless your A struct is too large
664: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
665: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
666: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
667: @*/
668: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
669: {
673: PetscMalloc(bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar),bag);
674: PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));
675: (*bag)->bagsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
676: (*bag)->bagcomm = comm;
677: (*bag)->bagprefix = PETSC_NULL;
678: (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
679: return(0);
680: }
681:
684: /*@C
685: PetscBagSetName - Sets the name of a bag of values
687: Not Collective
689: Level: Intermediate
691: Input Parameters:
692: + bag - the bag of values
693: . name - the name assigned to the bag
694: - help - help message for bag
696: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
697: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
698: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
699: @*/
701: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
702: {
705: PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
706: PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
707: return(0);
708: }
713: /*@C
714: PetscBagGetName - Gets the name of a bag of values
716: Not Collective
718: Level: Intermediate
720: Input Parameter:
721: . bag - the bag of values
723: Output Parameter:
724: . name - the name assigned to the bag
726: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
727: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
728: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
729: @*/
730: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
731: {
733: *name = bag->bagname;
734: return(0);
735: }
739: /*@C
740: PetscBagGetData - Gives back the user - access to memory that
741: should be used for storing user-data-structure
743: Not Collective
745: Level: Intermediate
747: Input Parameter:
748: . bag - the bag of values
750: Output Parameter:
751: . data - pointer to memory that will have user-data-structure
753: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
754: PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
755: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
756: @*/
757: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
758: {
760: *data = bag->structlocation;
761: return(0);
762: }
766: /*@C
767: PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
768: PetscBag items in the options database.
770: Logically collective on Bag.
772: Level: Intermediate
774: Input Parameters:
775: + bag - the bag of values
776: - prefix - the prefix to prepend all Bag item names with.
778: NOTES: Must be called prior to registering any of the bag items.
780: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
781: PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
782: @*/
784: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
785: {
788: if (!pre) {
789: PetscFree(bag->bagprefix);
790: } else {
791: if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
792: PetscFree(bag->bagprefix);
793: PetscStrallocpy(pre,&(bag->bagprefix));
794: }
795: return(0);
796: }