1 /* Define Feature test macros to make sure atoll is available (SVr4, POSIX.1-2001, 4.3BSD, C99), not in (C89 and POSIX.1-1996) */ 2 #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for atoll() */ 3 4 /* 5 These routines simplify the use of command line, file options, etc., and are used to manipulate the options database. 6 This provides the low-level interface, the high level interface is in aoptions.c 7 8 Some routines use regular malloc and free because it cannot know what malloc is requested with the 9 options database until it has already processed the input. 10 */ 11 12 #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 13 #include <petscviewer.h> 14 #include <ctype.h> 15 #if defined(PETSC_HAVE_MALLOC_H) 16 #include <malloc.h> 17 #endif 18 #if defined(PETSC_HAVE_STRINGS_H) 19 # include <strings.h> /* strcasecmp */ 20 #endif 21 22 #if defined(PETSC_HAVE_STRCASECMP) 23 #define PetscOptNameCmp(a,b) strcasecmp(a,b) 24 #elif defined(PETSC_HAVE_STRICMP) 25 #define PetscOptNameCmp(a,b) stricmp(a,b) 26 #else 27 #define PetscOptNameCmp(a,b) Error_strcasecmp_not_found 28 #endif 29 30 #include <petsc/private/hashtable.h> 31 32 /* This assumes ASCII encoding and ignores locale settings */ 33 /* Using tolower() is about 2X slower in microbenchmarks */ 34 PETSC_STATIC_INLINE int PetscToLower(int c) 35 { 36 return ((c >= 'A') & (c <= 'Z')) ? c + 'a' - 'A' : c; 37 } 38 39 /* Bob Jenkins's one at a time hash function (case-insensitive) */ 40 PETSC_STATIC_INLINE unsigned int PetscOptHash(const char key[]) 41 { 42 unsigned int hash = 0; 43 while (*key) { 44 hash += PetscToLower(*key++); 45 hash += hash << 10; 46 hash ^= hash >> 6; 47 } 48 hash += hash << 3; 49 hash ^= hash >> 11; 50 hash += hash << 15; 51 return hash; 52 } 53 54 PETSC_STATIC_INLINE int PetscOptEqual(const char a[],const char b[]) 55 { 56 return !PetscOptNameCmp(a,b); 57 } 58 59 KHASH_INIT(HO, kh_cstr_t, int, 1, PetscOptHash, PetscOptEqual) 60 61 /* 62 This table holds all the options set by the user. For simplicity, we use a static size database 63 */ 64 #define MAXOPTNAME PETSC_MAX_OPTION_NAME 65 #define MAXOPTIONS 512 66 #define MAXALIASES 25 67 #define MAXPREFIXES 25 68 #define MAXOPTIONSMONITORS 5 69 70 struct _n_PetscOptions { 71 PetscOptions previous; 72 int N; /* number of options */ 73 char *names[MAXOPTIONS]; /* option names */ 74 char *values[MAXOPTIONS]; /* option values */ 75 PetscBool used[MAXOPTIONS]; /* flag option use */ 76 PetscBool precedentProcessed; 77 78 /* Hash table */ 79 khash_t(HO) *ht; 80 81 /* Prefixes */ 82 int prefixind; 83 int prefixstack[MAXPREFIXES]; 84 char prefix[MAXOPTNAME]; 85 86 /* Aliases */ 87 int Naliases; /* number or aliases */ 88 char *aliases1[MAXALIASES]; /* aliased */ 89 char *aliases2[MAXALIASES]; /* aliasee */ 90 91 /* Help */ 92 PetscBool help; /* flag whether "-help" is in the database */ 93 PetscBool help_intro; /* flag whether "-help intro" is in the database */ 94 95 /* Monitors */ 96 PetscBool monitorFromOptions, monitorCancel; 97 PetscErrorCode (*monitor[MAXOPTIONSMONITORS])(const char[],const char[],void*); /* returns control to user after */ 98 PetscErrorCode (*monitordestroy[MAXOPTIONSMONITORS])(void**); /* */ 99 void *monitorcontext[MAXOPTIONSMONITORS]; /* to pass arbitrary user data into monitor */ 100 PetscInt numbermonitors; /* to, for instance, detect options being set */ 101 }; 102 103 static PetscOptions defaultoptions = NULL; /* the options database routines query this object for options */ 104 105 /* list of options which preceed others, i.e., are processed in PetscOptionsProcessPrecedentFlags() */ 106 static const char *precedentOptions[] = {"-options_monitor","-options_monitor_cancel","-help","-skip_petscrc"}; 107 enum PetscPrecedentOption {PO_OPTIONS_MONITOR,PO_OPTIONS_MONITOR_CANCEL,PO_HELP,PO_SKIP_PETSCRC,PO_NUM}; 108 109 static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions,const char[],const char[],int*); 110 111 /* 112 Options events monitor 113 */ 114 static PetscErrorCode PetscOptionsMonitor(PetscOptions options,const char name[],const char value[]) 115 { 116 PetscInt i; 117 PetscErrorCode ierr; 118 119 if (!PetscErrorHandlingInitialized) return 0; 120 PetscFunctionBegin; 121 if (!value) value = ""; 122 if (options->monitorFromOptions) { 123 ierr = PetscOptionsMonitorDefault(name,value,NULL);CHKERRQ(ierr); 124 } 125 for (i=0; i<options->numbermonitors; i++) { 126 ierr = (*options->monitor[i])(name,value,options->monitorcontext[i]);CHKERRQ(ierr); 127 } 128 PetscFunctionReturn(0); 129 } 130 131 /*@ 132 PetscOptionsCreate - Creates an empty options database. 133 134 Logically collective 135 136 Output Parameter: 137 . options - Options database object 138 139 Level: advanced 140 141 Developer Note: We may want eventually to pass a MPI_Comm to determine the ownership of the object 142 143 .seealso: PetscOptionsDestroy(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue() 144 @*/ 145 PetscErrorCode PetscOptionsCreate(PetscOptions *options) 146 { 147 if (!options) return PETSC_ERR_ARG_NULL; 148 *options = (PetscOptions)calloc(1,sizeof(**options)); 149 if (!*options) return PETSC_ERR_MEM; 150 return 0; 151 } 152 153 /*@ 154 PetscOptionsDestroy - Destroys an option database. 155 156 Logically collective on whatever communicator was associated with the call to PetscOptionsCreate() 157 158 Input Parameter: 159 . options - the PetscOptions object 160 161 Level: advanced 162 163 .seealso: PetscOptionsInsert(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsInsert(), PetscOptionsSetValue() 164 @*/ 165 PetscErrorCode PetscOptionsDestroy(PetscOptions *options) 166 { 167 PetscErrorCode ierr; 168 169 PetscFunctionBegin; 170 if (!*options) return 0; 171 if ((*options)->previous) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"You are destroying an option that has been used with PetscOptionsPush() but does not have a corresponding PetscOptionsPop()"); 172 ierr = PetscOptionsClear(*options);if (ierr) return ierr; 173 /* XXX what about monitors ? */ 174 free(*options); 175 *options = NULL; 176 PetscFunctionReturn(0); 177 } 178 179 /* 180 PetscOptionsCreateDefault - Creates the default global options database 181 */ 182 PetscErrorCode PetscOptionsCreateDefault(void) 183 { 184 PetscErrorCode ierr; 185 186 if (!defaultoptions) { 187 ierr = PetscOptionsCreate(&defaultoptions);if (ierr) return ierr; 188 } 189 return 0; 190 } 191 192 /*@ 193 PetscOptionsPush - Push a new PetscOptions object as the default provider of options 194 Allows using different parts of a code to use different options databases 195 196 Logically Collective 197 198 Input Parameter: 199 . opt - the options obtained with PetscOptionsCreate() 200 201 Notes: 202 Use PetscOptionsPop() to return to the previous default options database 203 204 The collectivity of this routine is complex; only the MPI processes that call this routine will 205 have the affect of these options. If some processes that create objects call this routine and others do 206 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 207 on different ranks. 208 209 Level: advanced 210 211 .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft() 212 213 @*/ 214 PetscErrorCode PetscOptionsPush(PetscOptions opt) 215 { 216 PetscErrorCode ierr; 217 218 PetscFunctionBegin; 219 ierr = PetscOptionsCreateDefault();CHKERRQ(ierr); 220 opt->previous = defaultoptions; 221 defaultoptions = opt; 222 PetscFunctionReturn(0); 223 } 224 225 /*@ 226 PetscOptionsPop - Pop the most recent PetscOptionsPush() to return to the previous default options 227 228 Logically collective on whatever communicator was associated with the call to PetscOptionsCreate() 229 230 Notes: 231 Use PetscOptionsPop() to return to the previous default options database 232 Allows using different parts of a code to use different options databases 233 234 Level: advanced 235 236 .seealso: PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsInsert(), PetscOptionsSetValue(), PetscOptionsLeft() 237 238 @*/ 239 PetscErrorCode PetscOptionsPop(void) 240 { 241 PetscOptions current = defaultoptions; 242 243 PetscFunctionBegin; 244 if (!defaultoptions) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing default options"); 245 if (!defaultoptions->previous) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PetscOptionsPop() called too many times"); 246 defaultoptions = defaultoptions->previous; 247 current->previous = NULL; 248 PetscFunctionReturn(0); 249 } 250 251 /* 252 PetscOptionsDestroyDefault - Destroys the default global options database 253 */ 254 PetscErrorCode PetscOptionsDestroyDefault(void) 255 { 256 PetscErrorCode ierr; 257 PetscOptions tmp; 258 259 if (!defaultoptions) return 0; 260 /* Destroy any options that the user forgot to pop */ 261 while (defaultoptions->previous) { 262 tmp = defaultoptions; 263 ierr = PetscOptionsPop();CHKERRQ(ierr); 264 ierr = PetscOptionsDestroy(&tmp);CHKERRQ(ierr); 265 } 266 ierr = PetscOptionsDestroy(&defaultoptions);if (ierr) return ierr; 267 return 0; 268 } 269 270 /*@C 271 PetscOptionsValidKey - PETSc Options database keys must begin with one or two dashes (-) followed by a letter. 272 273 Not collective 274 275 Input Parameter: 276 . key - string to check if valid 277 278 Output Parameter: 279 . valid - PETSC_TRUE if a valid key 280 281 Level: intermediate 282 @*/ 283 PetscErrorCode PetscOptionsValidKey(const char key[],PetscBool *valid) 284 { 285 char *ptr; 286 287 PetscFunctionBegin; 288 if (key) PetscValidCharPointer(key,1); 289 PetscValidPointer(valid,2); 290 *valid = PETSC_FALSE; 291 if (!key) PetscFunctionReturn(0); 292 if (key[0] != '-') PetscFunctionReturn(0); 293 if (key[1] == '-') key++; 294 if (!isalpha((int)key[1])) PetscFunctionReturn(0); 295 (void) strtod(key,&ptr); 296 if (ptr != key && !(*ptr == '_' || isalnum((int)*ptr))) PetscFunctionReturn(0); 297 *valid = PETSC_TRUE; 298 PetscFunctionReturn(0); 299 } 300 301 /*@C 302 PetscOptionsInsertString - Inserts options into the database from a string 303 304 Logically Collective 305 306 Input Parameter: 307 + options - options object 308 - in_str - string that contains options separated by blanks 309 310 Level: intermediate 311 312 The collectivity of this routine is complex; only the MPI processes that call this routine will 313 have the affect of these options. If some processes that create objects call this routine and others do 314 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 315 on different ranks. 316 317 Contributed by Boyana Norris 318 319 .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(), 320 PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(), 321 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 322 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 323 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 324 PetscOptionsFList(), PetscOptionsEList(), PetscOptionsInsertFile() 325 @*/ 326 PetscErrorCode PetscOptionsInsertString(PetscOptions options,const char in_str[]) 327 { 328 MPI_Comm comm = PETSC_COMM_SELF; 329 PetscErrorCode ierr; 330 char *first,*second; 331 PetscToken token; 332 333 PetscFunctionBegin; 334 ierr = PetscTokenCreate(in_str,' ',&token);CHKERRQ(ierr); 335 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 336 while (first) { 337 PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key; 338 ierr = PetscStrcasecmp(first,"-options_file",&isfile);CHKERRQ(ierr); 339 ierr = PetscStrcasecmp(first,"-options_file_yaml",&isfileyaml);CHKERRQ(ierr); 340 ierr = PetscStrcasecmp(first,"-options_string_yaml",&isstringyaml);CHKERRQ(ierr); 341 ierr = PetscStrcasecmp(first,"-prefix_push",&ispush);CHKERRQ(ierr); 342 ierr = PetscStrcasecmp(first,"-prefix_pop",&ispop);CHKERRQ(ierr); 343 ierr = PetscOptionsValidKey(first,&key);CHKERRQ(ierr); 344 if (!key) { 345 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 346 } else if (isfile) { 347 ierr = PetscTokenFind(token,&second);CHKERRQ(ierr); 348 ierr = PetscOptionsInsertFile(comm,options,second,PETSC_TRUE);CHKERRQ(ierr); 349 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 350 } else if (isfileyaml) { 351 ierr = PetscTokenFind(token,&second);CHKERRQ(ierr); 352 ierr = PetscOptionsInsertFileYAML(comm,options,second,PETSC_TRUE);CHKERRQ(ierr); 353 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 354 } else if (isstringyaml) { 355 ierr = PetscTokenFind(token,&second);CHKERRQ(ierr); 356 ierr = PetscOptionsInsertStringYAML(options,second);CHKERRQ(ierr); 357 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 358 } else if (ispush) { 359 ierr = PetscTokenFind(token,&second);CHKERRQ(ierr); 360 ierr = PetscOptionsPrefixPush(options,second);CHKERRQ(ierr); 361 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 362 } else if (ispop) { 363 ierr = PetscOptionsPrefixPop(options);CHKERRQ(ierr); 364 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 365 } else { 366 ierr = PetscTokenFind(token,&second);CHKERRQ(ierr); 367 ierr = PetscOptionsValidKey(second,&key);CHKERRQ(ierr); 368 if (!key) { 369 ierr = PetscOptionsSetValue(options,first,second);CHKERRQ(ierr); 370 ierr = PetscTokenFind(token,&first);CHKERRQ(ierr); 371 } else { 372 ierr = PetscOptionsSetValue(options,first,NULL);CHKERRQ(ierr); 373 first = second; 374 } 375 } 376 } 377 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 378 PetscFunctionReturn(0); 379 } 380 381 /* 382 Returns a line (ended by a \n, \r or null character of any length. Result should be freed with free() 383 */ 384 static char *Petscgetline(FILE * f) 385 { 386 size_t size = 0; 387 size_t len = 0; 388 size_t last = 0; 389 char *buf = NULL; 390 391 if (feof(f)) return NULL; 392 do { 393 size += 1024; /* BUFSIZ is defined as "the optimal read size for this platform" */ 394 buf = (char*)realloc((void*)buf,size); /* realloc(NULL,n) is the same as malloc(n) */ 395 /* Actually do the read. Note that fgets puts a terminal '\0' on the 396 end of the string, so we make sure we overwrite this */ 397 if (!fgets(buf+len,1024,f)) buf[len]=0; 398 PetscStrlen(buf,&len); 399 last = len - 1; 400 } while (!feof(f) && buf[last] != '\n' && buf[last] != '\r'); 401 if (len) return buf; 402 free(buf); 403 return NULL; 404 } 405 406 static PetscErrorCode PetscOptionsFilename(MPI_Comm comm,const char file[],char filename[PETSC_MAX_PATH_LEN],PetscBool *yaml) 407 { 408 char fname[PETSC_MAX_PATH_LEN+8],path[PETSC_MAX_PATH_LEN+8],*tail; 409 PetscErrorCode ierr; 410 411 PetscFunctionBegin; 412 *yaml = PETSC_FALSE; 413 ierr = PetscStrreplace(comm,file,fname,sizeof(fname));CHKERRQ(ierr); 414 ierr = PetscFixFilename(fname,path);CHKERRQ(ierr); 415 ierr = PetscStrendswith(path,":yaml",yaml);CHKERRQ(ierr); 416 if (*yaml) { 417 ierr = PetscStrrchr(path,':',&tail);CHKERRQ(ierr); 418 tail[-1] = 0; /* remove ":yaml" suffix from path */ 419 } 420 ierr = PetscStrncpy(filename,path,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 421 /* check for standard YAML and JSON filename extensions */ 422 if (!*yaml) {ierr = PetscStrendswith(filename,".yaml",yaml);CHKERRQ(ierr);} 423 if (!*yaml) {ierr = PetscStrendswith(filename,".yml", yaml);CHKERRQ(ierr);} 424 if (!*yaml) {ierr = PetscStrendswith(filename,".json",yaml);CHKERRQ(ierr);} 425 if (!*yaml) { /* check file contents */ 426 PetscMPIInt rank; 427 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 428 if (!rank) { 429 FILE *fh = fopen(filename,"r"); 430 if (fh) { 431 char buf[6] = ""; 432 if (fread(buf,1,6,fh) > 0) { 433 ierr = PetscStrncmp(buf,"%YAML ",6,yaml);CHKERRQ(ierr); /* check for '%YAML' tag */ 434 if (!*yaml) {ierr = PetscStrncmp(buf,"---",3,yaml);CHKERRQ(ierr);} /* check for document start */ 435 } 436 (void)fclose(fh); 437 } 438 } 439 ierr = MPI_Bcast(yaml,1,MPIU_BOOL,0,comm);CHKERRMPI(ierr); 440 } 441 PetscFunctionReturn(0); 442 } 443 444 static PetscErrorCode PetscOptionsInsertFilePetsc(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require) 445 { 446 char *string,*vstring = NULL,*astring = NULL,*packed = NULL; 447 char *tokens[4]; 448 PetscErrorCode ierr; 449 size_t i,len,bytes; 450 FILE *fd; 451 PetscToken token=NULL; 452 int err; 453 char *cmatch; 454 const char cmt='#'; 455 PetscInt line=1; 456 PetscMPIInt rank,cnt=0,acnt=0,counts[2]; 457 PetscBool isdir,alias=PETSC_FALSE,valid; 458 459 PetscFunctionBegin; 460 ierr = PetscMemzero(tokens,sizeof(tokens));CHKERRQ(ierr); 461 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 462 if (!rank) { 463 char fpath[PETSC_MAX_PATH_LEN]; 464 char fname[PETSC_MAX_PATH_LEN]; 465 466 ierr = PetscStrreplace(PETSC_COMM_SELF,file,fpath,sizeof(fpath));CHKERRQ(ierr); 467 ierr = PetscFixFilename(fpath,fname);CHKERRQ(ierr); 468 469 fd = fopen(fname,"r"); 470 ierr = PetscTestDirectory(fname,'r',&isdir);CHKERRQ(ierr); 471 if (isdir && require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Specified options file %s is a directory",fname); 472 if (fd && !isdir) { 473 PetscSegBuffer vseg,aseg; 474 ierr = PetscSegBufferCreate(1,4000,&vseg);CHKERRQ(ierr); 475 ierr = PetscSegBufferCreate(1,2000,&aseg);CHKERRQ(ierr); 476 477 /* the following line will not work when opening initial files (like .petscrc) since info is not yet set */ 478 ierr = PetscInfo1(NULL,"Opened options file %s\n",file);CHKERRQ(ierr); 479 480 while ((string = Petscgetline(fd))) { 481 /* eliminate comments from each line */ 482 ierr = PetscStrchr(string,cmt,&cmatch);CHKERRQ(ierr); 483 if (cmatch) *cmatch = 0; 484 ierr = PetscStrlen(string,&len);CHKERRQ(ierr); 485 /* replace tabs, ^M, \n with " " */ 486 for (i=0; i<len; i++) { 487 if (string[i] == '\t' || string[i] == '\r' || string[i] == '\n') { 488 string[i] = ' '; 489 } 490 } 491 ierr = PetscTokenCreate(string,' ',&token);CHKERRQ(ierr); 492 ierr = PetscTokenFind(token,&tokens[0]);CHKERRQ(ierr); 493 if (!tokens[0]) { 494 goto destroy; 495 } else if (!tokens[0][0]) { /* if token 0 is empty (string begins with spaces), redo */ 496 ierr = PetscTokenFind(token,&tokens[0]);CHKERRQ(ierr); 497 } 498 for (i=1; i<4; i++) { 499 ierr = PetscTokenFind(token,&tokens[i]);CHKERRQ(ierr); 500 } 501 if (!tokens[0]) { 502 goto destroy; 503 } else if (tokens[0][0] == '-') { 504 ierr = PetscOptionsValidKey(tokens[0],&valid);CHKERRQ(ierr); 505 if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: invalid option %s",fname,line,tokens[0]); 506 ierr = PetscStrlen(tokens[0],&len);CHKERRQ(ierr); 507 ierr = PetscSegBufferGet(vseg,len+1,&vstring);CHKERRQ(ierr); 508 ierr = PetscArraycpy(vstring,tokens[0],len);CHKERRQ(ierr); 509 vstring[len] = ' '; 510 if (tokens[1]) { 511 ierr = PetscOptionsValidKey(tokens[1],&valid);CHKERRQ(ierr); 512 if (valid) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: cannot specify two options per line (%s %s)",fname,line,tokens[0],tokens[1]); 513 ierr = PetscStrlen(tokens[1],&len);CHKERRQ(ierr); 514 ierr = PetscSegBufferGet(vseg,len+3,&vstring);CHKERRQ(ierr); 515 vstring[0] = '"'; 516 ierr = PetscArraycpy(vstring+1,tokens[1],len);CHKERRQ(ierr); 517 vstring[len+1] = '"'; 518 vstring[len+2] = ' '; 519 } 520 } else { 521 ierr = PetscStrcasecmp(tokens[0],"alias",&alias);CHKERRQ(ierr); 522 if (alias) { 523 ierr = PetscOptionsValidKey(tokens[1],&valid);CHKERRQ(ierr); 524 if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: invalid aliased option %s",fname,line,tokens[1]); 525 if (!tokens[2]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: alias missing for %s",fname,line,tokens[1]); 526 ierr = PetscOptionsValidKey(tokens[2],&valid);CHKERRQ(ierr); 527 if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: invalid aliasee option %s",fname,line,tokens[2]); 528 ierr = PetscStrlen(tokens[1],&len);CHKERRQ(ierr); 529 ierr = PetscSegBufferGet(aseg,len+1,&astring);CHKERRQ(ierr); 530 ierr = PetscArraycpy(astring,tokens[1],len);CHKERRQ(ierr); 531 astring[len] = ' '; 532 533 ierr = PetscStrlen(tokens[2],&len);CHKERRQ(ierr); 534 ierr = PetscSegBufferGet(aseg,len+1,&astring);CHKERRQ(ierr); 535 ierr = PetscArraycpy(astring,tokens[2],len);CHKERRQ(ierr); 536 astring[len] = ' '; 537 } else SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown first token in options file %s line %D: %s",fname,line,tokens[0]); 538 } 539 { 540 const char *extraToken = alias ? tokens[3] : tokens[2]; 541 if (extraToken) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Error in options file %s line %D: extra token %s",fname,line,extraToken); 542 } 543 destroy: 544 free(string); 545 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 546 alias = PETSC_FALSE; 547 line++; 548 } 549 err = fclose(fd); 550 if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file %s",fname); 551 ierr = PetscSegBufferGetSize(aseg,&bytes);CHKERRQ(ierr); /* size without null termination */ 552 ierr = PetscMPIIntCast(bytes,&acnt);CHKERRQ(ierr); 553 ierr = PetscSegBufferGet(aseg,1,&astring);CHKERRQ(ierr); 554 astring[0] = 0; 555 ierr = PetscSegBufferGetSize(vseg,&bytes);CHKERRQ(ierr); /* size without null termination */ 556 ierr = PetscMPIIntCast(bytes,&cnt);CHKERRQ(ierr); 557 ierr = PetscSegBufferGet(vseg,1,&vstring);CHKERRQ(ierr); 558 vstring[0] = 0; 559 ierr = PetscMalloc1(2+acnt+cnt,&packed);CHKERRQ(ierr); 560 ierr = PetscSegBufferExtractTo(aseg,packed);CHKERRQ(ierr); 561 ierr = PetscSegBufferExtractTo(vseg,packed+acnt+1);CHKERRQ(ierr); 562 ierr = PetscSegBufferDestroy(&aseg);CHKERRQ(ierr); 563 ierr = PetscSegBufferDestroy(&vseg);CHKERRQ(ierr); 564 } else if (require) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_USER,"Unable to open options file %s",fname); 565 } 566 567 counts[0] = acnt; 568 counts[1] = cnt; 569 err = MPI_Bcast(counts,2,MPI_INT,0,comm); 570 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in first MPI collective call, could be caused by using an incorrect mpiexec or a network problem, it can be caused by having VPN running: see https://petsc.org/release/faq/"); 571 acnt = counts[0]; 572 cnt = counts[1]; 573 if (rank) { 574 ierr = PetscMalloc1(2+acnt+cnt,&packed);CHKERRQ(ierr); 575 } 576 if (acnt || cnt) { 577 ierr = MPI_Bcast(packed,2+acnt+cnt,MPI_CHAR,0,comm);CHKERRMPI(ierr); 578 astring = packed; 579 vstring = packed + acnt + 1; 580 } 581 582 if (acnt) { 583 ierr = PetscTokenCreate(astring,' ',&token);CHKERRQ(ierr); 584 ierr = PetscTokenFind(token,&tokens[0]);CHKERRQ(ierr); 585 while (tokens[0]) { 586 ierr = PetscTokenFind(token,&tokens[1]);CHKERRQ(ierr); 587 ierr = PetscOptionsSetAlias(options,tokens[0],tokens[1]);CHKERRQ(ierr); 588 ierr = PetscTokenFind(token,&tokens[0]);CHKERRQ(ierr); 589 } 590 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 591 } 592 593 if (cnt) { 594 ierr = PetscOptionsInsertString(options,vstring);CHKERRQ(ierr); 595 } 596 ierr = PetscFree(packed);CHKERRQ(ierr); 597 PetscFunctionReturn(0); 598 } 599 600 /*@C 601 PetscOptionsInsertFile - Inserts options into the database from a file. 602 603 Collective 604 605 Input Parameter: 606 + comm - the processes that will share the options (usually PETSC_COMM_WORLD) 607 . options - options database, use NULL for default global database 608 . file - name of file, 609 ".yml" and ".yaml" filename extensions are inserted as YAML options, 610 append ":yaml" to filename to force YAML options. 611 - require - if PETSC_TRUE will generate an error if the file does not exist 612 613 Notes: 614 Use # for lines that are comments and which should be ignored. 615 Usually, instead of using this command, one should list the file name in the call to PetscInitialize(), this insures that certain options 616 such as -log_view or -malloc_debug are processed properly. This routine only sets options into the options database that will be processed by later 617 calls to XXXSetFromOptions() it should not be used for options listed under PetscInitialize(). 618 The collectivity of this routine is complex; only the MPI processes in comm will 619 have the affect of these options. If some processes that create objects call this routine and others do 620 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 621 on different ranks. 622 623 Level: developer 624 625 .seealso: PetscOptionsSetValue(), PetscOptionsView(), PetscOptionsHasName(), PetscOptionsGetInt(), 626 PetscOptionsGetReal(), PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(), 627 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 628 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 629 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 630 PetscOptionsFList(), PetscOptionsEList() 631 632 @*/ 633 PetscErrorCode PetscOptionsInsertFile(MPI_Comm comm,PetscOptions options,const char file[],PetscBool require) 634 { 635 char filename[PETSC_MAX_PATH_LEN]; 636 PetscBool yaml; 637 PetscErrorCode ierr; 638 639 PetscFunctionBegin; 640 ierr = PetscOptionsFilename(comm,file,filename,&yaml);CHKERRQ(ierr); 641 if (yaml) { 642 ierr = PetscOptionsInsertFileYAML(comm,options,filename,require);CHKERRQ(ierr); 643 } else { 644 ierr = PetscOptionsInsertFilePetsc(comm,options,filename,require);CHKERRQ(ierr); 645 } 646 PetscFunctionReturn(0); 647 } 648 649 /*@C 650 PetscOptionsInsertArgs - Inserts options into the database from a array of strings 651 652 Logically Collective 653 654 Input Parameter: 655 + options - options object 656 . argc - the array lenght 657 - args - the string array 658 659 Level: intermediate 660 661 .seealso: PetscOptions, PetscOptionsInsertString(), PetscOptionsInsertFile() 662 @*/ 663 PetscErrorCode PetscOptionsInsertArgs(PetscOptions options,int argc,char *args[]) 664 { 665 MPI_Comm comm = PETSC_COMM_WORLD; 666 PetscErrorCode ierr; 667 int left = PetscMax(argc,0); 668 char *const *eargs = args; 669 670 PetscFunctionBegin; 671 while (left) { 672 PetscBool isfile,isfileyaml,isstringyaml,ispush,ispop,key; 673 ierr = PetscStrcasecmp(eargs[0],"-options_file",&isfile);CHKERRQ(ierr); 674 ierr = PetscStrcasecmp(eargs[0],"-options_file_yaml",&isfileyaml);CHKERRQ(ierr); 675 ierr = PetscStrcasecmp(eargs[0],"-options_string_yaml",&isstringyaml);CHKERRQ(ierr); 676 ierr = PetscStrcasecmp(eargs[0],"-prefix_push",&ispush);CHKERRQ(ierr); 677 ierr = PetscStrcasecmp(eargs[0],"-prefix_pop",&ispop);CHKERRQ(ierr); 678 ierr = PetscOptionsValidKey(eargs[0],&key);CHKERRQ(ierr); 679 if (!key) { 680 eargs++; left--; 681 } else if (isfile) { 682 if (left <= 1 || eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file filename option"); 683 ierr = PetscOptionsInsertFile(comm,options,eargs[1],PETSC_TRUE);CHKERRQ(ierr); 684 eargs += 2; left -= 2; 685 } else if (isfileyaml) { 686 if (left <= 1 || eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing filename for -options_file_yaml filename option"); 687 ierr = PetscOptionsInsertFileYAML(comm,options,eargs[1],PETSC_TRUE);CHKERRQ(ierr); 688 eargs += 2; left -= 2; 689 } else if (isstringyaml) { 690 if (left <= 1 || eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing string for -options_string_yaml string option"); 691 ierr = PetscOptionsInsertStringYAML(options,eargs[1]);CHKERRQ(ierr); 692 eargs += 2; left -= 2; 693 } else if (ispush) { 694 if (left <= 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option"); 695 if (eargs[1][0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Missing prefix for -prefix_push option (prefixes cannot start with '-')"); 696 ierr = PetscOptionsPrefixPush(options,eargs[1]);CHKERRQ(ierr); 697 eargs += 2; left -= 2; 698 } else if (ispop) { 699 ierr = PetscOptionsPrefixPop(options);CHKERRQ(ierr); 700 eargs++; left--; 701 } else { 702 PetscBool nextiskey = PETSC_FALSE; 703 if (left >= 2) {ierr = PetscOptionsValidKey(eargs[1],&nextiskey);CHKERRQ(ierr);} 704 if (left < 2 || nextiskey) { 705 ierr = PetscOptionsSetValue(options,eargs[0],NULL);CHKERRQ(ierr); 706 eargs++; left--; 707 } else { 708 ierr = PetscOptionsSetValue(options,eargs[0],eargs[1]);CHKERRQ(ierr); 709 eargs += 2; left -= 2; 710 } 711 } 712 } 713 PetscFunctionReturn(0); 714 } 715 716 PETSC_STATIC_INLINE PetscErrorCode PetscOptionsStringToBoolIfSet_Private(enum PetscPrecedentOption opt,const char *val[],PetscBool set[],PetscBool *flg) 717 { 718 PetscErrorCode ierr; 719 720 PetscFunctionBegin; 721 if (set[opt]) { 722 ierr = PetscOptionsStringToBool(val[opt],flg);CHKERRQ(ierr); 723 } else *flg = PETSC_FALSE; 724 PetscFunctionReturn(0); 725 } 726 727 /* Process options with absolute precedence */ 728 static PetscErrorCode PetscOptionsProcessPrecedentFlags(PetscOptions options,int argc,char *args[],PetscBool *skip_petscrc,PetscBool *skip_petscrc_set) 729 { 730 const char* const *opt = precedentOptions; 731 const size_t n = PO_NUM; 732 size_t o; 733 int a; 734 const char **val; 735 PetscBool *set; 736 PetscErrorCode ierr; 737 738 PetscFunctionBegin; 739 ierr = PetscCalloc2(n,&val,n,&set);CHKERRQ(ierr); 740 741 /* Look for options possibly set using PetscOptionsSetValue beforehand */ 742 for (o=0; o<n; o++) { 743 ierr = PetscOptionsFindPair(options,NULL,opt[o],&val[o],&set[o]);CHKERRQ(ierr); 744 } 745 746 /* Loop through all args to collect last occuring value of each option */ 747 for (a=1; a<argc; a++) { 748 PetscBool valid, eq; 749 750 ierr = PetscOptionsValidKey(args[a],&valid);CHKERRQ(ierr); 751 if (!valid) continue; 752 for (o=0; o<n; o++) { 753 ierr = PetscStrcasecmp(args[a],opt[o],&eq);CHKERRQ(ierr); 754 if (eq) { 755 set[o] = PETSC_TRUE; 756 if (a == argc-1 || !args[a+1] || !args[a+1][0] || args[a+1][0] == '-') val[o] = NULL; 757 else val[o] = args[a+1]; 758 break; 759 } 760 } 761 } 762 763 /* Process flags */ 764 ierr = PetscStrcasecmp(val[PO_HELP], "intro", &options->help_intro);CHKERRQ(ierr); 765 if (options->help_intro) options->help = PETSC_TRUE; 766 else {ierr = PetscOptionsStringToBoolIfSet_Private(PO_HELP, val,set,&options->help);CHKERRQ(ierr);} 767 ierr = PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR_CANCEL,val,set,&options->monitorCancel);CHKERRQ(ierr); 768 ierr = PetscOptionsStringToBoolIfSet_Private(PO_OPTIONS_MONITOR, val,set,&options->monitorFromOptions);CHKERRQ(ierr); 769 ierr = PetscOptionsStringToBoolIfSet_Private(PO_SKIP_PETSCRC, val,set,skip_petscrc);CHKERRQ(ierr); 770 *skip_petscrc_set = set[PO_SKIP_PETSCRC]; 771 772 /* Store precedent options in database and mark them as used */ 773 for (o=0; o<n; o++) { 774 if (set[o]) { 775 ierr = PetscOptionsSetValue_Private(options,opt[o],val[o],&a);CHKERRQ(ierr); 776 options->used[a] = PETSC_TRUE; 777 } 778 } 779 780 ierr = PetscFree2(val,set);CHKERRQ(ierr); 781 options->precedentProcessed = PETSC_TRUE; 782 PetscFunctionReturn(0); 783 } 784 785 PETSC_STATIC_INLINE PetscErrorCode PetscOptionsSkipPrecedent(PetscOptions options,const char name[],PetscBool *flg) 786 { 787 int i; 788 PetscErrorCode ierr; 789 790 *flg = PETSC_FALSE; 791 if (options->precedentProcessed) { 792 for (i=0; i<PO_NUM; i++) { 793 if (!PetscOptNameCmp(precedentOptions[i],name)) { 794 /* check if precedent option has been set already */ 795 ierr = PetscOptionsFindPair(options,NULL,name,NULL,flg);if (ierr) return ierr; 796 if (*flg) break; 797 } 798 } 799 } 800 return 0; 801 } 802 803 /*@C 804 PetscOptionsInsert - Inserts into the options database from the command line, 805 the environmental variable and a file. 806 807 Collective on PETSC_COMM_WORLD 808 809 Input Parameters: 810 + options - options database or NULL for the default global database 811 . argc - count of number of command line arguments 812 . args - the command line arguments 813 - file - [optional] PETSc database file, append ":yaml" to filename to specify YAML options format. 814 Use NULL or empty string to not check for code specific file. 815 Also checks ~/.petscrc, .petscrc and petscrc. 816 Use -skip_petscrc in the code specific file (or command line) to skip ~/.petscrc, .petscrc and petscrc files. 817 818 Note: 819 Since PetscOptionsInsert() is automatically called by PetscInitialize(), 820 the user does not typically need to call this routine. PetscOptionsInsert() 821 can be called several times, adding additional entries into the database. 822 823 Options Database Keys: 824 + -options_file <filename> - read options from a file 825 - -options_file_yaml <filename> - read options from a YAML file 826 827 See PetscInitialize() for options related to option database monitoring. 828 829 Level: advanced 830 831 .seealso: PetscOptionsDestroy(), PetscOptionsView(), PetscOptionsInsertString(), PetscOptionsInsertFile(), 832 PetscInitialize() 833 @*/ 834 PetscErrorCode PetscOptionsInsert(PetscOptions options,int *argc,char ***args,const char file[]) 835 { 836 MPI_Comm comm = PETSC_COMM_WORLD; 837 PetscErrorCode ierr; 838 PetscMPIInt rank; 839 PetscBool hasArgs = (argc && *argc) ? PETSC_TRUE : PETSC_FALSE; 840 PetscBool skipPetscrc = PETSC_FALSE, skipPetscrcSet = PETSC_FALSE; 841 842 PetscFunctionBegin; 843 if (hasArgs && !(args && *args)) SETERRQ(comm,PETSC_ERR_ARG_NULL,"*argc > 1 but *args not given"); 844 ierr = MPI_Comm_rank(comm,&rank);CHKERRMPI(ierr); 845 846 if (!options) { 847 ierr = PetscOptionsCreateDefault();CHKERRQ(ierr); 848 options = defaultoptions; 849 } 850 if (hasArgs) { 851 /* process options with absolute precedence */ 852 ierr = PetscOptionsProcessPrecedentFlags(options,*argc,*args,&skipPetscrc,&skipPetscrcSet);CHKERRQ(ierr); 853 } 854 if (file && file[0]) { 855 ierr = PetscOptionsInsertFile(comm,options,file,PETSC_TRUE);CHKERRQ(ierr); 856 /* if -skip_petscrc has not been set from command line, check whether it has been set in the file */ 857 if (!skipPetscrcSet) {ierr = PetscOptionsGetBool(options,NULL,"-skip_petscrc",&skipPetscrc,NULL);CHKERRQ(ierr);} 858 } 859 if (!skipPetscrc) { 860 char filename[PETSC_MAX_PATH_LEN]; 861 ierr = PetscGetHomeDirectory(filename,sizeof(filename));CHKERRQ(ierr); 862 ierr = MPI_Bcast(filename,(int)sizeof(filename),MPI_CHAR,0,comm);CHKERRMPI(ierr); 863 if (filename[0]) {ierr = PetscStrcat(filename,"/.petscrc");CHKERRQ(ierr);} 864 ierr = PetscOptionsInsertFile(comm,options,filename,PETSC_FALSE);CHKERRQ(ierr); 865 ierr = PetscOptionsInsertFile(comm,options,".petscrc",PETSC_FALSE);CHKERRQ(ierr); 866 ierr = PetscOptionsInsertFile(comm,options,"petscrc",PETSC_FALSE);CHKERRQ(ierr); 867 } 868 869 /* insert environment options */ 870 { 871 char *eoptions = NULL; 872 size_t len = 0; 873 if (!rank) { 874 eoptions = (char*)getenv("PETSC_OPTIONS"); 875 ierr = PetscStrlen(eoptions,&len);CHKERRQ(ierr); 876 } 877 ierr = MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm);CHKERRMPI(ierr); 878 if (len) { 879 if (rank) {ierr = PetscMalloc1(len+1,&eoptions);CHKERRQ(ierr);} 880 ierr = MPI_Bcast(eoptions,len,MPI_CHAR,0,comm);CHKERRMPI(ierr); 881 if (rank) eoptions[len] = 0; 882 ierr = PetscOptionsInsertString(options,eoptions);CHKERRQ(ierr); 883 if (rank) {ierr = PetscFree(eoptions);CHKERRQ(ierr);} 884 } 885 } 886 887 /* insert YAML environment options */ 888 { 889 char *eoptions = NULL; 890 size_t len = 0; 891 if (!rank) { 892 eoptions = (char*)getenv("PETSC_OPTIONS_YAML"); 893 ierr = PetscStrlen(eoptions,&len);CHKERRQ(ierr); 894 } 895 ierr = MPI_Bcast(&len,1,MPIU_SIZE_T,0,comm);CHKERRMPI(ierr); 896 if (len) { 897 if (rank) {ierr = PetscMalloc1(len+1,&eoptions);CHKERRQ(ierr);} 898 ierr = MPI_Bcast(eoptions,len,MPI_CHAR,0,comm);CHKERRMPI(ierr); 899 if (rank) eoptions[len] = 0; 900 ierr = PetscOptionsInsertStringYAML(options,eoptions);CHKERRQ(ierr); 901 if (rank) {ierr = PetscFree(eoptions);CHKERRQ(ierr);} 902 } 903 } 904 905 /* insert command line options here because they take precedence over arguments in petscrc/environment */ 906 if (hasArgs) {ierr = PetscOptionsInsertArgs(options,*argc-1,*args+1);CHKERRQ(ierr);} 907 PetscFunctionReturn(0); 908 } 909 910 /*@C 911 PetscOptionsView - Prints the options that have been loaded. This is 912 useful for debugging purposes. 913 914 Logically Collective on PetscViewer 915 916 Input Parameter: 917 + options - options database, use NULL for default global database 918 - viewer - must be an PETSCVIEWERASCII viewer 919 920 Options Database Key: 921 . -options_view - Activates PetscOptionsView() within PetscFinalize() 922 923 Notes: 924 Only the rank zero process of MPI_Comm used to create view prints the option values. Other processes 925 may have different values but they are not printed. 926 927 Level: advanced 928 929 .seealso: PetscOptionsAllUsed() 930 @*/ 931 PetscErrorCode PetscOptionsView(PetscOptions options,PetscViewer viewer) 932 { 933 PetscErrorCode ierr; 934 PetscInt i; 935 PetscBool isascii; 936 937 PetscFunctionBegin; 938 if (viewer) PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 939 options = options ? options : defaultoptions; 940 if (!viewer) viewer = PETSC_VIEWER_STDOUT_WORLD; 941 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr); 942 if (!isascii) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Only supports ASCII viewer"); 943 944 if (!options->N) { 945 ierr = PetscViewerASCIIPrintf(viewer,"#No PETSc Option Table entries\n");CHKERRQ(ierr); 946 PetscFunctionReturn(0); 947 } 948 949 ierr = PetscViewerASCIIPrintf(viewer,"#PETSc Option Table entries:\n");CHKERRQ(ierr); 950 for (i=0; i<options->N; i++) { 951 if (options->values[i]) { 952 ierr = PetscViewerASCIIPrintf(viewer,"-%s %s\n",options->names[i],options->values[i]);CHKERRQ(ierr); 953 } else { 954 ierr = PetscViewerASCIIPrintf(viewer,"-%s\n",options->names[i]);CHKERRQ(ierr); 955 } 956 } 957 ierr = PetscViewerASCIIPrintf(viewer,"#End of PETSc Option Table entries\n");CHKERRQ(ierr); 958 PetscFunctionReturn(0); 959 } 960 961 /* 962 Called by error handlers to print options used in run 963 */ 964 PETSC_EXTERN PetscErrorCode PetscOptionsViewError(void) 965 { 966 PetscInt i; 967 PetscOptions options = defaultoptions; 968 969 PetscFunctionBegin; 970 if (options->N) { 971 (*PetscErrorPrintf)("PETSc Option Table entries:\n"); 972 } else { 973 (*PetscErrorPrintf)("No PETSc Option Table entries\n"); 974 } 975 for (i=0; i<options->N; i++) { 976 if (options->values[i]) { 977 (*PetscErrorPrintf)("-%s %s\n",options->names[i],options->values[i]); 978 } else { 979 (*PetscErrorPrintf)("-%s\n",options->names[i]); 980 } 981 } 982 PetscFunctionReturn(0); 983 } 984 985 /*@C 986 PetscOptionsPrefixPush - Designate a prefix to be used by all options insertions to follow. 987 988 Logically Collective 989 990 Input Parameter: 991 + options - options database, or NULL for the default global database 992 - prefix - The string to append to the existing prefix 993 994 Options Database Keys: 995 + -prefix_push <some_prefix_> - push the given prefix 996 - -prefix_pop - pop the last prefix 997 998 Notes: 999 It is common to use this in conjunction with -options_file as in 1000 1001 $ -prefix_push system1_ -options_file system1rc -prefix_pop -prefix_push system2_ -options_file system2rc -prefix_pop 1002 1003 where the files no longer require all options to be prefixed with -system2_. 1004 1005 The collectivity of this routine is complex; only the MPI processes that call this routine will 1006 have the affect of these options. If some processes that create objects call this routine and others do 1007 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 1008 on different ranks. 1009 1010 Level: advanced 1011 1012 .seealso: PetscOptionsPrefixPop(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue() 1013 @*/ 1014 PetscErrorCode PetscOptionsPrefixPush(PetscOptions options,const char prefix[]) 1015 { 1016 PetscErrorCode ierr; 1017 size_t n; 1018 PetscInt start; 1019 char key[MAXOPTNAME+1]; 1020 PetscBool valid; 1021 1022 PetscFunctionBegin; 1023 PetscValidCharPointer(prefix,2); 1024 options = options ? options : defaultoptions; 1025 if (options->prefixind >= MAXPREFIXES) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum depth of prefix stack %d exceeded, recompile \n src/sys/objects/options.c with larger value for MAXPREFIXES",MAXPREFIXES); 1026 key[0] = '-'; /* keys must start with '-' */ 1027 ierr = PetscStrncpy(key+1,prefix,sizeof(key)-1);CHKERRQ(ierr); 1028 ierr = PetscOptionsValidKey(key,&valid);CHKERRQ(ierr); 1029 if (!valid && options->prefixind > 0 && isdigit((int)prefix[0])) valid = PETSC_TRUE; /* If the prefix stack is not empty, make numbers a valid prefix */ 1030 if (!valid) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Given prefix \"%s\" not valid (the first character must be a letter%s, do not include leading '-')",prefix,options->prefixind?" or digit":""); 1031 start = options->prefixind ? options->prefixstack[options->prefixind-1] : 0; 1032 ierr = PetscStrlen(prefix,&n);CHKERRQ(ierr); 1033 if (n+1 > sizeof(options->prefix)-start) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Maximum prefix length %d exceeded",sizeof(options->prefix)); 1034 ierr = PetscArraycpy(options->prefix+start,prefix,n+1);CHKERRQ(ierr); 1035 options->prefixstack[options->prefixind++] = start+n; 1036 PetscFunctionReturn(0); 1037 } 1038 1039 /*@C 1040 PetscOptionsPrefixPop - Remove the latest options prefix, see PetscOptionsPrefixPush() for details 1041 1042 Logically Collective on the MPI_Comm that called PetscOptionsPrefixPush() 1043 1044 Input Parameters: 1045 . options - options database, or NULL for the default global database 1046 1047 Level: advanced 1048 1049 .seealso: PetscOptionsPrefixPush(), PetscOptionsPush(), PetscOptionsPop(), PetscOptionsCreate(), PetscOptionsSetValue() 1050 @*/ 1051 PetscErrorCode PetscOptionsPrefixPop(PetscOptions options) 1052 { 1053 PetscInt offset; 1054 1055 PetscFunctionBegin; 1056 options = options ? options : defaultoptions; 1057 if (options->prefixind < 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"More prefixes popped than pushed"); 1058 options->prefixind--; 1059 offset = options->prefixind ? options->prefixstack[options->prefixind-1] : 0; 1060 options->prefix[offset] = 0; 1061 PetscFunctionReturn(0); 1062 } 1063 1064 /*@C 1065 PetscOptionsClear - Removes all options form the database leaving it empty. 1066 1067 Logically Collective 1068 1069 Input Parameters: 1070 . options - options database, use NULL for the default global database 1071 1072 The collectivity of this routine is complex; only the MPI processes that call this routine will 1073 have the affect of these options. If some processes that create objects call this routine and others do 1074 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 1075 on different ranks. 1076 1077 Level: developer 1078 1079 .seealso: PetscOptionsInsert() 1080 @*/ 1081 PetscErrorCode PetscOptionsClear(PetscOptions options) 1082 { 1083 PetscInt i; 1084 1085 options = options ? options : defaultoptions; 1086 if (!options) return 0; 1087 1088 for (i=0; i<options->N; i++) { 1089 if (options->names[i]) free(options->names[i]); 1090 if (options->values[i]) free(options->values[i]); 1091 } 1092 options->N = 0; 1093 1094 for (i=0; i<options->Naliases; i++) { 1095 free(options->aliases1[i]); 1096 free(options->aliases2[i]); 1097 } 1098 options->Naliases = 0; 1099 1100 /* destroy hash table */ 1101 kh_destroy(HO,options->ht); 1102 options->ht = NULL; 1103 1104 options->prefixind = 0; 1105 options->prefix[0] = 0; 1106 options->help = PETSC_FALSE; 1107 return 0; 1108 } 1109 1110 /*@C 1111 PetscOptionsSetAlias - Makes a key and alias for another key 1112 1113 Logically Collective 1114 1115 Input Parameters: 1116 + options - options database, or NULL for default global database 1117 . newname - the alias 1118 - oldname - the name that alias will refer to 1119 1120 Level: advanced 1121 1122 The collectivity of this routine is complex; only the MPI processes that call this routine will 1123 have the affect of these options. If some processes that create objects call this routine and others do 1124 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 1125 on different ranks. 1126 1127 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(), 1128 PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(), 1129 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 1130 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 1131 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 1132 PetscOptionsFList(), PetscOptionsEList() 1133 @*/ 1134 PetscErrorCode PetscOptionsSetAlias(PetscOptions options,const char newname[],const char oldname[]) 1135 { 1136 PetscInt n; 1137 size_t len; 1138 PetscBool valid; 1139 PetscErrorCode ierr; 1140 1141 PetscFunctionBegin; 1142 PetscValidCharPointer(newname,2); 1143 PetscValidCharPointer(oldname,3); 1144 options = options ? options : defaultoptions; 1145 ierr = PetscOptionsValidKey(newname,&valid);CHKERRQ(ierr); 1146 if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliased option %s",newname); 1147 ierr = PetscOptionsValidKey(oldname,&valid);CHKERRQ(ierr); 1148 if (!valid) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid aliasee option %s",oldname); 1149 1150 n = options->Naliases; 1151 if (n >= MAXALIASES) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MEM,"You have defined to many PETSc options aliases, limit %d recompile \n src/sys/objects/options.c with larger value for MAXALIASES",MAXALIASES); 1152 1153 newname++; oldname++; 1154 ierr = PetscStrlen(newname,&len);CHKERRQ(ierr); 1155 options->aliases1[n] = (char*)malloc((len+1)*sizeof(char)); 1156 ierr = PetscStrcpy(options->aliases1[n],newname);CHKERRQ(ierr); 1157 ierr = PetscStrlen(oldname,&len);CHKERRQ(ierr); 1158 options->aliases2[n] = (char*)malloc((len+1)*sizeof(char)); 1159 ierr = PetscStrcpy(options->aliases2[n],oldname);CHKERRQ(ierr); 1160 options->Naliases++; 1161 PetscFunctionReturn(0); 1162 } 1163 1164 /*@C 1165 PetscOptionsSetValue - Sets an option name-value pair in the options 1166 database, overriding whatever is already present. 1167 1168 Logically Collective 1169 1170 Input Parameters: 1171 + options - options database, use NULL for the default global database 1172 . name - name of option, this SHOULD have the - prepended 1173 - value - the option value (not used for all options, so can be NULL) 1174 1175 Level: intermediate 1176 1177 Note: 1178 This function can be called BEFORE PetscInitialize() 1179 1180 The collectivity of this routine is complex; only the MPI processes that call this routine will 1181 have the affect of these options. If some processes that create objects call this routine and others do 1182 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 1183 on different ranks. 1184 1185 Developers Note: Uses malloc() directly because PETSc may not be initialized yet. 1186 1187 .seealso: PetscOptionsInsert(), PetscOptionsClearValue() 1188 @*/ 1189 PetscErrorCode PetscOptionsSetValue(PetscOptions options,const char name[],const char value[]) 1190 { 1191 return PetscOptionsSetValue_Private(options,name,value,NULL); 1192 } 1193 1194 static PetscErrorCode PetscOptionsSetValue_Private(PetscOptions options,const char name[],const char value[],int *pos) 1195 { 1196 size_t len; 1197 int N,n,i; 1198 char **names; 1199 char fullname[MAXOPTNAME] = ""; 1200 PetscBool flg; 1201 PetscErrorCode ierr; 1202 1203 if (!options) { 1204 ierr = PetscOptionsCreateDefault();if (ierr) return ierr; 1205 options = defaultoptions; 1206 } 1207 1208 if (name[0] != '-') return PETSC_ERR_ARG_OUTOFRANGE; 1209 1210 ierr = PetscOptionsSkipPrecedent(options,name,&flg);if (ierr) return ierr; 1211 if (flg) return 0; 1212 1213 name++; /* skip starting dash */ 1214 1215 if (options->prefixind > 0) { 1216 strncpy(fullname,options->prefix,sizeof(fullname)); 1217 fullname[sizeof(fullname)-1] = 0; 1218 strncat(fullname,name,sizeof(fullname)-strlen(fullname)-1); 1219 fullname[sizeof(fullname)-1] = 0; 1220 name = fullname; 1221 } 1222 1223 /* check against aliases */ 1224 N = options->Naliases; 1225 for (i=0; i<N; i++) { 1226 int result = PetscOptNameCmp(options->aliases1[i],name); 1227 if (!result) { name = options->aliases2[i]; break; } 1228 } 1229 1230 /* slow search */ 1231 N = n = options->N; 1232 names = options->names; 1233 for (i=0; i<N; i++) { 1234 int result = PetscOptNameCmp(names[i],name); 1235 if (!result) { 1236 n = i; goto setvalue; 1237 } else if (result > 0) { 1238 n = i; break; 1239 } 1240 } 1241 if (N >= MAXOPTIONS) return PETSC_ERR_MEM; 1242 /* shift remaining values up 1 */ 1243 for (i=N; i>n; i--) { 1244 options->names[i] = options->names[i-1]; 1245 options->values[i] = options->values[i-1]; 1246 options->used[i] = options->used[i-1]; 1247 } 1248 options->names[n] = NULL; 1249 options->values[n] = NULL; 1250 options->used[n] = PETSC_FALSE; 1251 options->N++; 1252 1253 /* destroy hash table */ 1254 kh_destroy(HO,options->ht); 1255 options->ht = NULL; 1256 1257 /* set new name */ 1258 len = strlen(name); 1259 options->names[n] = (char*)malloc((len+1)*sizeof(char)); 1260 if (!options->names[n]) return PETSC_ERR_MEM; 1261 strcpy(options->names[n],name); 1262 1263 setvalue: 1264 /* set new value */ 1265 if (options->values[n]) free(options->values[n]); 1266 len = value ? strlen(value) : 0; 1267 if (len) { 1268 options->values[n] = (char*)malloc((len+1)*sizeof(char)); 1269 if (!options->values[n]) return PETSC_ERR_MEM; 1270 strcpy(options->values[n],value); 1271 } else { 1272 options->values[n] = NULL; 1273 } 1274 1275 /* handle -help so that it can be set from anywhere */ 1276 if (!PetscOptNameCmp(name,"help")) { 1277 options->help = PETSC_TRUE; 1278 options->help_intro = (value && !PetscOptNameCmp(value,"intro")) ? PETSC_TRUE : PETSC_FALSE; 1279 options->used[n] = PETSC_TRUE; 1280 } 1281 1282 if (PetscErrorHandlingInitialized) { 1283 ierr = PetscOptionsMonitor(options,name,value);CHKERRQ(ierr); 1284 } 1285 if (pos) *pos = n; 1286 return 0; 1287 } 1288 1289 /*@C 1290 PetscOptionsClearValue - Clears an option name-value pair in the options 1291 database, overriding whatever is already present. 1292 1293 Logically Collective 1294 1295 Input Parameter: 1296 + options - options database, use NULL for the default global database 1297 - name - name of option, this SHOULD have the - prepended 1298 1299 Level: intermediate 1300 1301 The collectivity of this routine is complex; only the MPI processes that call this routine will 1302 have the affect of these options. If some processes that create objects call this routine and others do 1303 not the code may fail in complicated ways because the same parallel solvers may incorrectly use different options 1304 on different ranks. 1305 1306 .seealso: PetscOptionsInsert() 1307 @*/ 1308 PetscErrorCode PetscOptionsClearValue(PetscOptions options,const char name[]) 1309 { 1310 int N,n,i; 1311 char **names; 1312 PetscErrorCode ierr; 1313 1314 PetscFunctionBegin; 1315 options = options ? options : defaultoptions; 1316 if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name); 1317 if (!PetscOptNameCmp(name,"-help")) options->help = options->help_intro = PETSC_FALSE; 1318 1319 name++; /* skip starting dash */ 1320 1321 /* slow search */ 1322 N = n = options->N; 1323 names = options->names; 1324 for (i=0; i<N; i++) { 1325 int result = PetscOptNameCmp(names[i],name); 1326 if (!result) { 1327 n = i; break; 1328 } else if (result > 0) { 1329 n = N; break; 1330 } 1331 } 1332 if (n == N) PetscFunctionReturn(0); /* it was not present */ 1333 1334 /* remove name and value */ 1335 if (options->names[n]) free(options->names[n]); 1336 if (options->values[n]) free(options->values[n]); 1337 /* shift remaining values down 1 */ 1338 for (i=n; i<N-1; i++) { 1339 options->names[i] = options->names[i+1]; 1340 options->values[i] = options->values[i+1]; 1341 options->used[i] = options->used[i+1]; 1342 } 1343 options->N--; 1344 1345 /* destroy hash table */ 1346 kh_destroy(HO,options->ht); 1347 options->ht = NULL; 1348 1349 ierr = PetscOptionsMonitor(options,name,NULL);CHKERRQ(ierr); 1350 PetscFunctionReturn(0); 1351 } 1352 1353 /*@C 1354 PetscOptionsFindPair - Gets an option name-value pair from the options database. 1355 1356 Not Collective 1357 1358 Input Parameters: 1359 + options - options database, use NULL for the default global database 1360 . pre - the string to prepend to the name or NULL, this SHOULD NOT have the "-" prepended 1361 - name - name of option, this SHOULD have the "-" prepended 1362 1363 Output Parameters: 1364 + value - the option value (optional, not used for all options) 1365 - set - whether the option is set (optional) 1366 1367 Notes: 1368 Each process may find different values or no value depending on how options were inserted into the database 1369 1370 Level: developer 1371 1372 .seealso: PetscOptionsSetValue(), PetscOptionsClearValue() 1373 @*/ 1374 PetscErrorCode PetscOptionsFindPair(PetscOptions options,const char pre[],const char name[],const char *value[],PetscBool *set) 1375 { 1376 char buf[MAXOPTNAME]; 1377 PetscBool usehashtable = PETSC_TRUE; 1378 PetscBool matchnumbers = PETSC_TRUE; 1379 PetscErrorCode ierr; 1380 1381 PetscFunctionBegin; 1382 options = options ? options : defaultoptions; 1383 if (pre && PetscUnlikely(pre[0] == '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre); 1384 if (PetscUnlikely(name[0] != '-')) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name); 1385 1386 name++; /* skip starting dash */ 1387 1388 /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */ 1389 if (pre && pre[0]) { 1390 char *ptr = buf; 1391 if (name[0] == '-') { *ptr++ = '-'; name++; } 1392 ierr = PetscStrncpy(ptr,pre,buf+sizeof(buf)-ptr);CHKERRQ(ierr); 1393 ierr = PetscStrlcat(buf,name,sizeof(buf));CHKERRQ(ierr); 1394 name = buf; 1395 } 1396 1397 if (PetscDefined(USE_DEBUG)) { 1398 PetscBool valid; 1399 char key[MAXOPTNAME+1] = "-"; 1400 ierr = PetscStrncpy(key+1,name,sizeof(key)-1);CHKERRQ(ierr); 1401 ierr = PetscOptionsValidKey(key,&valid);CHKERRQ(ierr); 1402 if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name); 1403 } 1404 1405 if (!options->ht && usehashtable) { 1406 int i,ret; 1407 khiter_t it; 1408 khash_t(HO) *ht; 1409 ht = kh_init(HO); 1410 if (PetscUnlikely(!ht)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed"); 1411 ret = kh_resize(HO,ht,options->N*2); /* twice the required size to reduce risk of collisions */ 1412 if (PetscUnlikely(ret)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed"); 1413 for (i=0; i<options->N; i++) { 1414 it = kh_put(HO,ht,options->names[i],&ret); 1415 if (PetscUnlikely(ret != 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MEM,"Hash table allocation failed"); 1416 kh_val(ht,it) = i; 1417 } 1418 options->ht = ht; 1419 } 1420 1421 if (usehashtable) 1422 { /* fast search */ 1423 khash_t(HO) *ht = options->ht; 1424 khiter_t it = kh_get(HO,ht,name); 1425 if (it != kh_end(ht)) { 1426 int i = kh_val(ht,it); 1427 options->used[i] = PETSC_TRUE; 1428 if (value) *value = options->values[i]; 1429 if (set) *set = PETSC_TRUE; 1430 PetscFunctionReturn(0); 1431 } 1432 } else 1433 { /* slow search */ 1434 int i, N = options->N; 1435 for (i=0; i<N; i++) { 1436 int result = PetscOptNameCmp(options->names[i],name); 1437 if (!result) { 1438 options->used[i] = PETSC_TRUE; 1439 if (value) *value = options->values[i]; 1440 if (set) *set = PETSC_TRUE; 1441 PetscFunctionReturn(0); 1442 } else if (result > 0) { 1443 break; 1444 } 1445 } 1446 } 1447 1448 /* 1449 The following block slows down all lookups in the most frequent path (most lookups are unsuccessful). 1450 Maybe this special lookup mode should be enabled on request with a push/pop API. 1451 The feature of matching _%d_ used sparingly in the codebase. 1452 */ 1453 if (matchnumbers) { 1454 int i,j,cnt = 0,locs[16],loce[16]; 1455 /* determine the location and number of all _%d_ in the key */ 1456 for (i=0; name[i]; i++) { 1457 if (name[i] == '_') { 1458 for (j=i+1; name[j]; j++) { 1459 if (name[j] >= '0' && name[j] <= '9') continue; 1460 if (name[j] == '_' && j > i+1) { /* found a number */ 1461 locs[cnt] = i+1; 1462 loce[cnt++] = j+1; 1463 } 1464 i = j-1; 1465 break; 1466 } 1467 } 1468 } 1469 for (i=0; i<cnt; i++) { 1470 PetscBool found; 1471 char opt[MAXOPTNAME+1] = "-", tmp[MAXOPTNAME]; 1472 ierr = PetscStrncpy(tmp,name,PetscMin((size_t)(locs[i]+1),sizeof(tmp)));CHKERRQ(ierr); 1473 ierr = PetscStrlcat(opt,tmp,sizeof(opt));CHKERRQ(ierr); 1474 ierr = PetscStrlcat(opt,name+loce[i],sizeof(opt));CHKERRQ(ierr); 1475 ierr = PetscOptionsFindPair(options,NULL,opt,value,&found);CHKERRQ(ierr); 1476 if (found) {if (set) *set = PETSC_TRUE; PetscFunctionReturn(0);} 1477 } 1478 } 1479 1480 if (set) *set = PETSC_FALSE; 1481 PetscFunctionReturn(0); 1482 } 1483 1484 /* Check whether any option begins with pre+name */ 1485 PETSC_EXTERN PetscErrorCode PetscOptionsFindPairPrefix_Private(PetscOptions options,const char pre[], const char name[],const char *value[],PetscBool *set) 1486 { 1487 char buf[MAXOPTNAME]; 1488 int numCnt = 0, locs[16],loce[16]; 1489 PetscErrorCode ierr; 1490 1491 PetscFunctionBegin; 1492 options = options ? options : defaultoptions; 1493 if (pre && pre[0] == '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Prefix cannot begin with '-': Instead %s",pre); 1494 if (name[0] != '-') SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Name must begin with '-': Instead %s",name); 1495 1496 name++; /* skip starting dash */ 1497 1498 /* append prefix to name, if prefix="foo_" and option='--bar", prefixed option is --foo_bar */ 1499 if (pre && pre[0]) { 1500 char *ptr = buf; 1501 if (name[0] == '-') { *ptr++ = '-'; name++; } 1502 ierr = PetscStrncpy(ptr,pre,sizeof(buf)+(size_t)(ptr-buf));CHKERRQ(ierr); 1503 ierr = PetscStrlcat(buf,name,sizeof(buf));CHKERRQ(ierr); 1504 name = buf; 1505 } 1506 1507 if (PetscDefined(USE_DEBUG)) { 1508 PetscBool valid; 1509 char key[MAXOPTNAME+1] = "-"; 1510 ierr = PetscStrncpy(key+1,name,sizeof(key)-1);CHKERRQ(ierr); 1511 ierr = PetscOptionsValidKey(key,&valid);CHKERRQ(ierr); 1512 if (!valid) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid option '%s' obtained from pre='%s' and name='%s'",key,pre?pre:"",name); 1513 } 1514 1515 /* determine the location and number of all _%d_ in the key */ 1516 { 1517 int i,j; 1518 for (i=0; name[i]; i++) { 1519 if (name[i] == '_') { 1520 for (j=i+1; name[j]; j++) { 1521 if (name[j] >= '0' && name[j] <= '9') continue; 1522 if (name[j] == '_' && j > i+1) { /* found a number */ 1523 locs[numCnt] = i+1; 1524 loce[numCnt++] = j+1; 1525 } 1526 i = j-1; 1527 break; 1528 } 1529 } 1530 } 1531 } 1532 1533 { /* slow search */ 1534 int c, i; 1535 size_t len; 1536 PetscBool match; 1537 1538 for (c = -1; c < numCnt; ++c) { 1539 char opt[MAXOPTNAME+1] = "", tmp[MAXOPTNAME]; 1540 1541 if (c < 0) { 1542 ierr = PetscStrcpy(opt,name);CHKERRQ(ierr); 1543 } else { 1544 ierr = PetscStrncpy(tmp,name,PetscMin((size_t)(locs[c]+1),sizeof(tmp)));CHKERRQ(ierr); 1545 ierr = PetscStrlcat(opt,tmp,sizeof(opt));CHKERRQ(ierr); 1546 ierr = PetscStrlcat(opt,name+loce[c],sizeof(opt));CHKERRQ(ierr); 1547 } 1548 ierr = PetscStrlen(opt,&len);CHKERRQ(ierr); 1549 for (i=0; i<options->N; i++) { 1550 ierr = PetscStrncmp(options->names[i],opt,len,&match);CHKERRQ(ierr); 1551 if (match) { 1552 options->used[i] = PETSC_TRUE; 1553 if (value) *value = options->values[i]; 1554 if (set) *set = PETSC_TRUE; 1555 PetscFunctionReturn(0); 1556 } 1557 } 1558 } 1559 } 1560 1561 if (set) *set = PETSC_FALSE; 1562 PetscFunctionReturn(0); 1563 } 1564 1565 /*@C 1566 PetscOptionsReject - Generates an error if a certain option is given. 1567 1568 Not Collective 1569 1570 Input Parameters: 1571 + options - options database, use NULL for default global database 1572 . pre - the option prefix (may be NULL) 1573 . name - the option name one is seeking 1574 - mess - error message (may be NULL) 1575 1576 Level: advanced 1577 1578 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(),OptionsHasName(), 1579 PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), 1580 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 1581 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 1582 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 1583 PetscOptionsFList(), PetscOptionsEList() 1584 @*/ 1585 PetscErrorCode PetscOptionsReject(PetscOptions options,const char pre[],const char name[],const char mess[]) 1586 { 1587 PetscErrorCode ierr; 1588 PetscBool flag = PETSC_FALSE; 1589 1590 PetscFunctionBegin; 1591 ierr = PetscOptionsHasName(options,pre,name,&flag);CHKERRQ(ierr); 1592 if (flag) { 1593 if (mess && mess[0]) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s with %s",pre?pre:"",name+1,mess); 1594 else SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Program has disabled option: -%s%s",pre?pre:"",name+1); 1595 } 1596 PetscFunctionReturn(0); 1597 } 1598 1599 /*@C 1600 PetscOptionsHasHelp - Determines whether the "-help" option is in the database. 1601 1602 Not Collective 1603 1604 Input Parameters: 1605 . options - options database, use NULL for default global database 1606 1607 Output Parameters: 1608 . set - PETSC_TRUE if found else PETSC_FALSE. 1609 1610 Level: advanced 1611 1612 .seealso: PetscOptionsHasName() 1613 @*/ 1614 PetscErrorCode PetscOptionsHasHelp(PetscOptions options,PetscBool *set) 1615 { 1616 PetscFunctionBegin; 1617 PetscValidPointer(set,2); 1618 options = options ? options : defaultoptions; 1619 *set = options->help; 1620 PetscFunctionReturn(0); 1621 } 1622 1623 PetscErrorCode PetscOptionsHasHelpIntro_Internal(PetscOptions options,PetscBool *set) 1624 { 1625 PetscFunctionBegin; 1626 PetscValidPointer(set,2); 1627 options = options ? options : defaultoptions; 1628 *set = options->help_intro; 1629 PetscFunctionReturn(0); 1630 } 1631 1632 /*@C 1633 PetscOptionsHasName - Determines whether a certain option is given in the database. This returns true whether the option is a number, string or Boolean, even 1634 if its value is set to false. 1635 1636 Not Collective 1637 1638 Input Parameters: 1639 + options - options database, use NULL for default global database 1640 . pre - string to prepend to the name or NULL 1641 - name - the option one is seeking 1642 1643 Output Parameters: 1644 . set - PETSC_TRUE if found else PETSC_FALSE. 1645 1646 Level: beginner 1647 1648 Notes: 1649 In many cases you probably want to use PetscOptionsGetBool() instead of calling this, to allowing toggling values. 1650 1651 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(), 1652 PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), 1653 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 1654 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 1655 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 1656 PetscOptionsFList(), PetscOptionsEList() 1657 @*/ 1658 PetscErrorCode PetscOptionsHasName(PetscOptions options,const char pre[],const char name[],PetscBool *set) 1659 { 1660 const char *value; 1661 PetscErrorCode ierr; 1662 PetscBool flag; 1663 1664 PetscFunctionBegin; 1665 ierr = PetscOptionsFindPair(options,pre,name,&value,&flag);CHKERRQ(ierr); 1666 if (set) *set = flag; 1667 PetscFunctionReturn(0); 1668 } 1669 1670 /*@C 1671 PetscOptionsGetAll - Lists all the options the program was run with in a single string. 1672 1673 Not Collective 1674 1675 Input Parameter: 1676 . options - the options database, use NULL for the default global database 1677 1678 Output Parameter: 1679 . copts - pointer where string pointer is stored 1680 1681 Notes: 1682 The array and each entry in the array should be freed with PetscFree() 1683 Each process may have different values depending on how the options were inserted into the database 1684 1685 Level: advanced 1686 1687 .seealso: PetscOptionsAllUsed(), PetscOptionsView(), PetscOptionsPush(), PetscOptionsPop() 1688 @*/ 1689 PetscErrorCode PetscOptionsGetAll(PetscOptions options,char *copts[]) 1690 { 1691 PetscErrorCode ierr; 1692 PetscInt i; 1693 size_t len = 1,lent = 0; 1694 char *coptions = NULL; 1695 1696 PetscFunctionBegin; 1697 PetscValidPointer(copts,2); 1698 options = options ? options : defaultoptions; 1699 /* count the length of the required string */ 1700 for (i=0; i<options->N; i++) { 1701 ierr = PetscStrlen(options->names[i],&lent);CHKERRQ(ierr); 1702 len += 2 + lent; 1703 if (options->values[i]) { 1704 ierr = PetscStrlen(options->values[i],&lent);CHKERRQ(ierr); 1705 len += 1 + lent; 1706 } 1707 } 1708 ierr = PetscMalloc1(len,&coptions);CHKERRQ(ierr); 1709 coptions[0] = 0; 1710 for (i=0; i<options->N; i++) { 1711 ierr = PetscStrcat(coptions,"-");CHKERRQ(ierr); 1712 ierr = PetscStrcat(coptions,options->names[i]);CHKERRQ(ierr); 1713 ierr = PetscStrcat(coptions," ");CHKERRQ(ierr); 1714 if (options->values[i]) { 1715 ierr = PetscStrcat(coptions,options->values[i]);CHKERRQ(ierr); 1716 ierr = PetscStrcat(coptions," ");CHKERRQ(ierr); 1717 } 1718 } 1719 *copts = coptions; 1720 PetscFunctionReturn(0); 1721 } 1722 1723 /*@C 1724 PetscOptionsUsed - Indicates if PETSc has used a particular option set in the database 1725 1726 Not Collective 1727 1728 Input Parameter: 1729 + options - options database, use NULL for default global database 1730 - name - string name of option 1731 1732 Output Parameter: 1733 . used - PETSC_TRUE if the option was used, otherwise false, including if option was not found in options database 1734 1735 Level: advanced 1736 1737 Notes: 1738 The value returned may be different on each process and depends on which options have been processed 1739 on the given process 1740 1741 .seealso: PetscOptionsView(), PetscOptionsLeft(), PetscOptionsAllUsed() 1742 @*/ 1743 PetscErrorCode PetscOptionsUsed(PetscOptions options,const char *name,PetscBool *used) 1744 { 1745 PetscInt i; 1746 PetscErrorCode ierr; 1747 1748 PetscFunctionBegin; 1749 PetscValidCharPointer(name,2); 1750 PetscValidPointer(used,3); 1751 options = options ? options : defaultoptions; 1752 *used = PETSC_FALSE; 1753 for (i=0; i<options->N; i++) { 1754 ierr = PetscStrcasecmp(options->names[i],name,used);CHKERRQ(ierr); 1755 if (*used) { 1756 *used = options->used[i]; 1757 break; 1758 } 1759 } 1760 PetscFunctionReturn(0); 1761 } 1762 1763 /*@ 1764 PetscOptionsAllUsed - Returns a count of the number of options in the 1765 database that have never been selected. 1766 1767 Not Collective 1768 1769 Input Parameter: 1770 . options - options database, use NULL for default global database 1771 1772 Output Parameter: 1773 . N - count of options not used 1774 1775 Level: advanced 1776 1777 Notes: 1778 The value returned may be different on each process and depends on which options have been processed 1779 on the given process 1780 1781 .seealso: PetscOptionsView() 1782 @*/ 1783 PetscErrorCode PetscOptionsAllUsed(PetscOptions options,PetscInt *N) 1784 { 1785 PetscInt i,n = 0; 1786 1787 PetscFunctionBegin; 1788 PetscValidIntPointer(N,2); 1789 options = options ? options : defaultoptions; 1790 for (i=0; i<options->N; i++) { 1791 if (!options->used[i]) n++; 1792 } 1793 *N = n; 1794 PetscFunctionReturn(0); 1795 } 1796 1797 /*@ 1798 PetscOptionsLeft - Prints to screen any options that were set and never used. 1799 1800 Not Collective 1801 1802 Input Parameter: 1803 . options - options database; use NULL for default global database 1804 1805 Options Database Key: 1806 . -options_left - activates PetscOptionsAllUsed() within PetscFinalize() 1807 1808 Notes: 1809 This is rarely used directly, it is called by PetscFinalize() in debug more or if -options_left 1810 is passed otherwise to help users determine possible mistakes in their usage of options. This 1811 only prints values on process zero of PETSC_COMM_WORLD. Other processes depending the objects 1812 used may have different options that are left unused. 1813 1814 Level: advanced 1815 1816 .seealso: PetscOptionsAllUsed() 1817 @*/ 1818 PetscErrorCode PetscOptionsLeft(PetscOptions options) 1819 { 1820 PetscErrorCode ierr; 1821 PetscInt i; 1822 PetscInt cnt = 0; 1823 PetscOptions toptions; 1824 1825 PetscFunctionBegin; 1826 toptions = options ? options : defaultoptions; 1827 for (i=0; i<toptions->N; i++) { 1828 if (!toptions->used[i]) { 1829 if (toptions->values[i]) { 1830 ierr = PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s value: %s\n",toptions->names[i],toptions->values[i]);CHKERRQ(ierr); 1831 } else { 1832 ierr = PetscPrintf(PETSC_COMM_WORLD,"Option left: name:-%s (no value)\n",toptions->names[i]);CHKERRQ(ierr); 1833 } 1834 } 1835 } 1836 if (!options) { 1837 toptions = defaultoptions; 1838 while (toptions->previous) { 1839 cnt++; 1840 toptions = toptions->previous; 1841 } 1842 if (cnt) { 1843 ierr = PetscPrintf(PETSC_COMM_WORLD,"Option left: You may have forgotten some calls to PetscOptionsPop(),\n PetscOptionsPop() has been called %D less times than PetscOptionsPush()\n",cnt);CHKERRQ(ierr); 1844 } 1845 } 1846 PetscFunctionReturn(0); 1847 } 1848 1849 /*@C 1850 PetscOptionsLeftGet - Returns all options that were set and never used. 1851 1852 Not Collective 1853 1854 Input Parameter: 1855 . options - options database, use NULL for default global database 1856 1857 Output Parameter: 1858 + N - count of options not used 1859 . names - names of options not used 1860 - values - values of options not used 1861 1862 Level: advanced 1863 1864 Notes: 1865 Users should call PetscOptionsLeftRestore() to free the memory allocated in this routine 1866 Notes: The value returned may be different on each process and depends on which options have been processed 1867 on the given process 1868 1869 .seealso: PetscOptionsAllUsed(), PetscOptionsLeft() 1870 @*/ 1871 PetscErrorCode PetscOptionsLeftGet(PetscOptions options,PetscInt *N,char **names[],char **values[]) 1872 { 1873 PetscErrorCode ierr; 1874 PetscInt i,n; 1875 1876 PetscFunctionBegin; 1877 if (N) PetscValidIntPointer(N,2); 1878 if (names) PetscValidPointer(names,3); 1879 if (values) PetscValidPointer(values,4); 1880 options = options ? options : defaultoptions; 1881 1882 /* The number of unused PETSc options */ 1883 n = 0; 1884 for (i=0; i<options->N; i++) { 1885 if (!options->used[i]) n++; 1886 } 1887 if (N) { *N = n; } 1888 if (names) { ierr = PetscMalloc1(n,names);CHKERRQ(ierr); } 1889 if (values) { ierr = PetscMalloc1(n,values);CHKERRQ(ierr); } 1890 1891 n = 0; 1892 if (names || values) { 1893 for (i=0; i<options->N; i++) { 1894 if (!options->used[i]) { 1895 if (names) (*names)[n] = options->names[i]; 1896 if (values) (*values)[n] = options->values[i]; 1897 n++; 1898 } 1899 } 1900 } 1901 PetscFunctionReturn(0); 1902 } 1903 1904 /*@C 1905 PetscOptionsLeftRestore - Free memory for the unused PETSc options obtained using PetscOptionsLeftGet. 1906 1907 Not Collective 1908 1909 Input Parameter: 1910 + options - options database, use NULL for default global database 1911 . names - names of options not used 1912 - values - values of options not used 1913 1914 Level: advanced 1915 1916 .seealso: PetscOptionsAllUsed(), PetscOptionsLeft(), PetscOptionsLeftGet() 1917 @*/ 1918 PetscErrorCode PetscOptionsLeftRestore(PetscOptions options,PetscInt *N,char **names[],char **values[]) 1919 { 1920 PetscErrorCode ierr; 1921 1922 PetscFunctionBegin; 1923 if (N) PetscValidIntPointer(N,2); 1924 if (names) PetscValidPointer(names,3); 1925 if (values) PetscValidPointer(values,4); 1926 if (N) { *N = 0; } 1927 if (names) { ierr = PetscFree(*names);CHKERRQ(ierr); } 1928 if (values) { ierr = PetscFree(*values);CHKERRQ(ierr); } 1929 PetscFunctionReturn(0); 1930 } 1931 1932 /*@C 1933 PetscOptionsMonitorDefault - Print all options set value events using the supplied PetscViewer. 1934 1935 Logically Collective on ctx 1936 1937 Input Parameters: 1938 + name - option name string 1939 . value - option value string 1940 - ctx - an ASCII viewer or NULL 1941 1942 Level: intermediate 1943 1944 Notes: 1945 If ctx=NULL, PetscPrintf() is used. 1946 The first MPI rank in the PetscViewer viewer actually prints the values, other 1947 processes may have different values set 1948 1949 .seealso: PetscOptionsMonitorSet() 1950 @*/ 1951 PetscErrorCode PetscOptionsMonitorDefault(const char name[],const char value[],void *ctx) 1952 { 1953 PetscErrorCode ierr; 1954 1955 PetscFunctionBegin; 1956 if (ctx) { 1957 PetscViewer viewer = (PetscViewer)ctx; 1958 if (!value) { 1959 ierr = PetscViewerASCIIPrintf(viewer,"Removing option: %s\n",name,value);CHKERRQ(ierr); 1960 } else if (!value[0]) { 1961 ierr = PetscViewerASCIIPrintf(viewer,"Setting option: %s (no value)\n",name);CHKERRQ(ierr); 1962 } else { 1963 ierr = PetscViewerASCIIPrintf(viewer,"Setting option: %s = %s\n",name,value);CHKERRQ(ierr); 1964 } 1965 } else { 1966 MPI_Comm comm = PETSC_COMM_WORLD; 1967 if (!value) { 1968 ierr = PetscPrintf(comm,"Removing option: %s\n",name,value);CHKERRQ(ierr); 1969 } else if (!value[0]) { 1970 ierr = PetscPrintf(comm,"Setting option: %s (no value)\n",name);CHKERRQ(ierr); 1971 } else { 1972 ierr = PetscPrintf(comm,"Setting option: %s = %s\n",name,value);CHKERRQ(ierr); 1973 } 1974 } 1975 PetscFunctionReturn(0); 1976 } 1977 1978 /*@C 1979 PetscOptionsMonitorSet - Sets an ADDITIONAL function to be called at every method that 1980 modified the PETSc options database. 1981 1982 Not Collective 1983 1984 Input Parameters: 1985 + monitor - pointer to function (if this is NULL, it turns off monitoring 1986 . mctx - [optional] context for private data for the 1987 monitor routine (use NULL if no context is desired) 1988 - monitordestroy - [optional] routine that frees monitor context 1989 (may be NULL) 1990 1991 Calling Sequence of monitor: 1992 $ monitor (const char name[], const char value[], void *mctx) 1993 1994 + name - option name string 1995 . value - option value string 1996 - mctx - optional monitoring context, as set by PetscOptionsMonitorSet() 1997 1998 Options Database Keys: 1999 See PetscInitialize() for options related to option database monitoring. 2000 2001 Notes: 2002 The default is to do nothing. To print the name and value of options 2003 being inserted into the database, use PetscOptionsMonitorDefault() as the monitoring routine, 2004 with a null monitoring context. 2005 2006 Several different monitoring routines may be set by calling 2007 PetscOptionsMonitorSet() multiple times; all will be called in the 2008 order in which they were set. 2009 2010 Level: intermediate 2011 2012 .seealso: PetscOptionsMonitorDefault(), PetscInitialize() 2013 @*/ 2014 PetscErrorCode PetscOptionsMonitorSet(PetscErrorCode (*monitor)(const char name[], const char value[], void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 2015 { 2016 PetscOptions options = defaultoptions; 2017 2018 PetscFunctionBegin; 2019 if (options->monitorCancel) PetscFunctionReturn(0); 2020 if (options->numbermonitors >= MAXOPTIONSMONITORS) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many PetscOptions monitors set"); 2021 options->monitor[options->numbermonitors] = monitor; 2022 options->monitordestroy[options->numbermonitors] = monitordestroy; 2023 options->monitorcontext[options->numbermonitors++] = (void*)mctx; 2024 PetscFunctionReturn(0); 2025 } 2026 2027 /* 2028 PetscOptionsStringToBool - Converts string to PetscBool, handles cases like "yes", "no", "true", "false", "0", "1", "off", "on". 2029 Empty string is considered as true. 2030 */ 2031 PetscErrorCode PetscOptionsStringToBool(const char value[],PetscBool *a) 2032 { 2033 PetscBool istrue,isfalse; 2034 size_t len; 2035 PetscErrorCode ierr; 2036 2037 PetscFunctionBegin; 2038 /* PetscStrlen() returns 0 for NULL or "" */ 2039 ierr = PetscStrlen(value,&len);CHKERRQ(ierr); 2040 if (!len) {*a = PETSC_TRUE; PetscFunctionReturn(0);} 2041 ierr = PetscStrcasecmp(value,"TRUE",&istrue);CHKERRQ(ierr); 2042 if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);} 2043 ierr = PetscStrcasecmp(value,"YES",&istrue);CHKERRQ(ierr); 2044 if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);} 2045 ierr = PetscStrcasecmp(value,"1",&istrue);CHKERRQ(ierr); 2046 if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);} 2047 ierr = PetscStrcasecmp(value,"on",&istrue);CHKERRQ(ierr); 2048 if (istrue) {*a = PETSC_TRUE; PetscFunctionReturn(0);} 2049 ierr = PetscStrcasecmp(value,"FALSE",&isfalse);CHKERRQ(ierr); 2050 if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);} 2051 ierr = PetscStrcasecmp(value,"NO",&isfalse);CHKERRQ(ierr); 2052 if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);} 2053 ierr = PetscStrcasecmp(value,"0",&isfalse);CHKERRQ(ierr); 2054 if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);} 2055 ierr = PetscStrcasecmp(value,"off",&isfalse);CHKERRQ(ierr); 2056 if (isfalse) {*a = PETSC_FALSE; PetscFunctionReturn(0);} 2057 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Unknown logical value: %s",value); 2058 } 2059 2060 /* 2061 PetscOptionsStringToInt - Converts a string to an integer value. Handles special cases such as "default" and "decide" 2062 */ 2063 PetscErrorCode PetscOptionsStringToInt(const char name[],PetscInt *a) 2064 { 2065 PetscErrorCode ierr; 2066 size_t len; 2067 PetscBool decide,tdefault,mouse; 2068 2069 PetscFunctionBegin; 2070 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 2071 if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value"); 2072 2073 ierr = PetscStrcasecmp(name,"PETSC_DEFAULT",&tdefault);CHKERRQ(ierr); 2074 if (!tdefault) { 2075 ierr = PetscStrcasecmp(name,"DEFAULT",&tdefault);CHKERRQ(ierr); 2076 } 2077 ierr = PetscStrcasecmp(name,"PETSC_DECIDE",&decide);CHKERRQ(ierr); 2078 if (!decide) { 2079 ierr = PetscStrcasecmp(name,"DECIDE",&decide);CHKERRQ(ierr); 2080 } 2081 ierr = PetscStrcasecmp(name,"mouse",&mouse);CHKERRQ(ierr); 2082 2083 if (tdefault) *a = PETSC_DEFAULT; 2084 else if (decide) *a = PETSC_DECIDE; 2085 else if (mouse) *a = -1; 2086 else { 2087 char *endptr; 2088 long strtolval; 2089 2090 strtolval = strtol(name,&endptr,10); 2091 if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no integer value (do not include . in it)",name); 2092 2093 #if defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE_ATOLL) 2094 (void) strtolval; 2095 *a = atoll(name); 2096 #elif defined(PETSC_USE_64BIT_INDICES) && defined(PETSC_HAVE___INT64) 2097 (void) strtolval; 2098 *a = _atoi64(name); 2099 #else 2100 *a = (PetscInt)strtolval; 2101 #endif 2102 } 2103 PetscFunctionReturn(0); 2104 } 2105 2106 #if defined(PETSC_USE_REAL___FLOAT128) 2107 #include <quadmath.h> 2108 #endif 2109 2110 static PetscErrorCode PetscStrtod(const char name[],PetscReal *a,char **endptr) 2111 { 2112 PetscFunctionBegin; 2113 #if defined(PETSC_USE_REAL___FLOAT128) 2114 *a = strtoflt128(name,endptr); 2115 #else 2116 *a = (PetscReal)strtod(name,endptr); 2117 #endif 2118 PetscFunctionReturn(0); 2119 } 2120 2121 static PetscErrorCode PetscStrtoz(const char name[],PetscScalar *a,char **endptr,PetscBool *isImaginary) 2122 { 2123 PetscBool hasi = PETSC_FALSE; 2124 char *ptr; 2125 PetscReal strtoval; 2126 PetscErrorCode ierr; 2127 2128 PetscFunctionBegin; 2129 ierr = PetscStrtod(name,&strtoval,&ptr);CHKERRQ(ierr); 2130 if (ptr == name) { 2131 strtoval = 1.; 2132 hasi = PETSC_TRUE; 2133 if (name[0] == 'i') { 2134 ptr++; 2135 } else if (name[0] == '+' && name[1] == 'i') { 2136 ptr += 2; 2137 } else if (name[0] == '-' && name[1] == 'i') { 2138 strtoval = -1.; 2139 ptr += 2; 2140 } 2141 } else if (*ptr == 'i') { 2142 hasi = PETSC_TRUE; 2143 ptr++; 2144 } 2145 *endptr = ptr; 2146 *isImaginary = hasi; 2147 if (hasi) { 2148 #if !defined(PETSC_USE_COMPLEX) 2149 SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s contains imaginary but complex not supported ",name); 2150 #else 2151 *a = PetscCMPLX(0.,strtoval); 2152 #endif 2153 } else { 2154 *a = strtoval; 2155 } 2156 PetscFunctionReturn(0); 2157 } 2158 2159 /* 2160 Converts a string to PetscReal value. Handles special cases like "default" and "decide" 2161 */ 2162 PetscErrorCode PetscOptionsStringToReal(const char name[],PetscReal *a) 2163 { 2164 size_t len; 2165 PetscBool match; 2166 char *endptr; 2167 PetscErrorCode ierr; 2168 2169 PetscFunctionBegin; 2170 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 2171 if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"String of length zero has no numerical value"); 2172 2173 ierr = PetscStrcasecmp(name,"PETSC_DEFAULT",&match);CHKERRQ(ierr); 2174 if (!match) { 2175 ierr = PetscStrcasecmp(name,"DEFAULT",&match);CHKERRQ(ierr); 2176 } 2177 if (match) {*a = PETSC_DEFAULT; PetscFunctionReturn(0);} 2178 2179 ierr = PetscStrcasecmp(name,"PETSC_DECIDE",&match);CHKERRQ(ierr); 2180 if (!match) { 2181 ierr = PetscStrcasecmp(name,"DECIDE",&match);CHKERRQ(ierr); 2182 } 2183 if (match) {*a = PETSC_DECIDE; PetscFunctionReturn(0);} 2184 2185 ierr = PetscStrtod(name,a,&endptr);CHKERRQ(ierr); 2186 if ((size_t) (endptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value",name); 2187 PetscFunctionReturn(0); 2188 } 2189 2190 PetscErrorCode PetscOptionsStringToScalar(const char name[],PetscScalar *a) 2191 { 2192 PetscBool imag1; 2193 size_t len; 2194 PetscScalar val = 0.; 2195 char *ptr = NULL; 2196 PetscErrorCode ierr; 2197 2198 PetscFunctionBegin; 2199 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 2200 if (!len) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"character string of length zero has no numerical value"); 2201 ierr = PetscStrtoz(name,&val,&ptr,&imag1);CHKERRQ(ierr); 2202 #if defined(PETSC_USE_COMPLEX) 2203 if ((size_t) (ptr - name) < len) { 2204 PetscBool imag2; 2205 PetscScalar val2; 2206 2207 ierr = PetscStrtoz(ptr,&val2,&ptr,&imag2);CHKERRQ(ierr); 2208 if (imag1 || !imag2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s: must specify imaginary component second",name); 2209 val = PetscCMPLX(PetscRealPart(val),PetscImaginaryPart(val2)); 2210 } 2211 #endif 2212 if ((size_t) (ptr - name) != len) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Input string %s has no numeric value ",name); 2213 *a = val; 2214 PetscFunctionReturn(0); 2215 } 2216 2217 /*@C 2218 PetscOptionsGetBool - Gets the Logical (true or false) value for a particular 2219 option in the database. 2220 2221 Not Collective 2222 2223 Input Parameters: 2224 + options - options database, use NULL for default global database 2225 . pre - the string to prepend to the name or NULL 2226 - name - the option one is seeking 2227 2228 Output Parameter: 2229 + ivalue - the logical value to return 2230 - set - PETSC_TRUE if found, else PETSC_FALSE 2231 2232 Level: beginner 2233 2234 Notes: 2235 TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE 2236 FALSE, false, NO, no, and 0 all translate to PETSC_FALSE 2237 2238 If the option is given, but no value is provided, then ivalue and set are both given the value PETSC_TRUE. That is -requested_bool 2239 is equivalent to -requested_bool true 2240 2241 If the user does not supply the option at all ivalue is NOT changed. Thus 2242 you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true. 2243 2244 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 2245 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsGetInt(), PetscOptionsBool(), 2246 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2247 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2248 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2249 PetscOptionsFList(), PetscOptionsEList() 2250 @*/ 2251 PetscErrorCode PetscOptionsGetBool(PetscOptions options,const char pre[],const char name[],PetscBool *ivalue,PetscBool *set) 2252 { 2253 const char *value; 2254 PetscBool flag; 2255 PetscErrorCode ierr; 2256 2257 PetscFunctionBegin; 2258 PetscValidCharPointer(name,3); 2259 if (ivalue) PetscValidBoolPointer(ivalue,4); 2260 ierr = PetscOptionsFindPair(options,pre,name,&value,&flag);CHKERRQ(ierr); 2261 if (flag) { 2262 if (set) *set = PETSC_TRUE; 2263 ierr = PetscOptionsStringToBool(value, &flag);CHKERRQ(ierr); 2264 if (ivalue) *ivalue = flag; 2265 } else { 2266 if (set) *set = PETSC_FALSE; 2267 } 2268 PetscFunctionReturn(0); 2269 } 2270 2271 /*@C 2272 PetscOptionsGetEList - Puts a list of option values that a single one may be selected from 2273 2274 Not Collective 2275 2276 Input Parameters: 2277 + options - options database, use NULL for default global database 2278 . pre - the string to prepend to the name or NULL 2279 . opt - option name 2280 . list - the possible choices (one of these must be selected, anything else is invalid) 2281 - ntext - number of choices 2282 2283 Output Parameter: 2284 + value - the index of the value to return (defaults to zero if the option name is given but no choice is listed) 2285 - set - PETSC_TRUE if found, else PETSC_FALSE 2286 2287 Level: intermediate 2288 2289 Notes: 2290 If the user does not supply the option value is NOT changed. Thus 2291 you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true. 2292 2293 See PetscOptionsFList() for when the choices are given in a PetscFunctionList() 2294 2295 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(), 2296 PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), 2297 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2298 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2299 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2300 PetscOptionsFList(), PetscOptionsEList() 2301 @*/ 2302 PetscErrorCode PetscOptionsGetEList(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscInt ntext,PetscInt *value,PetscBool *set) 2303 { 2304 PetscErrorCode ierr; 2305 size_t alen,len = 0, tlen = 0; 2306 char *svalue; 2307 PetscBool aset,flg = PETSC_FALSE; 2308 PetscInt i; 2309 2310 PetscFunctionBegin; 2311 PetscValidCharPointer(opt,3); 2312 for (i=0; i<ntext; i++) { 2313 ierr = PetscStrlen(list[i],&alen);CHKERRQ(ierr); 2314 if (alen > len) len = alen; 2315 tlen += len + 1; 2316 } 2317 len += 5; /* a little extra space for user mistypes */ 2318 ierr = PetscMalloc1(len,&svalue);CHKERRQ(ierr); 2319 ierr = PetscOptionsGetString(options,pre,opt,svalue,len,&aset);CHKERRQ(ierr); 2320 if (aset) { 2321 ierr = PetscEListFind(ntext,list,svalue,value,&flg);CHKERRQ(ierr); 2322 if (!flg) { 2323 char *avail,*pavl; 2324 2325 ierr = PetscMalloc1(tlen,&avail);CHKERRQ(ierr); 2326 pavl = avail; 2327 for (i=0; i<ntext; i++) { 2328 ierr = PetscStrlen(list[i],&alen);CHKERRQ(ierr); 2329 ierr = PetscStrcpy(pavl,list[i]);CHKERRQ(ierr); 2330 pavl += alen; 2331 ierr = PetscStrcpy(pavl," ");CHKERRQ(ierr); 2332 pavl += 1; 2333 } 2334 ierr = PetscStrtolower(avail);CHKERRQ(ierr); 2335 SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown option %s for -%s%s. Available options: %s",svalue,pre ? pre : "",opt+1,avail); 2336 } 2337 if (set) *set = PETSC_TRUE; 2338 } else if (set) *set = PETSC_FALSE; 2339 ierr = PetscFree(svalue);CHKERRQ(ierr); 2340 PetscFunctionReturn(0); 2341 } 2342 2343 /*@C 2344 PetscOptionsGetEnum - Gets the enum value for a particular option in the database. 2345 2346 Not Collective 2347 2348 Input Parameters: 2349 + options - options database, use NULL for default global database 2350 . pre - option prefix or NULL 2351 . opt - option name 2352 . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null 2353 - defaultv - the default (current) value 2354 2355 Output Parameter: 2356 + value - the value to return 2357 - set - PETSC_TRUE if found, else PETSC_FALSE 2358 2359 Level: beginner 2360 2361 Notes: 2362 If the user does not supply the option value is NOT changed. Thus 2363 you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true. 2364 2365 List is usually something like PCASMTypes or some other predefined list of enum names 2366 2367 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(), 2368 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 2369 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 2370 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2371 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2372 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2373 PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum() 2374 @*/ 2375 PetscErrorCode PetscOptionsGetEnum(PetscOptions options,const char pre[],const char opt[],const char * const *list,PetscEnum *value,PetscBool *set) 2376 { 2377 PetscErrorCode ierr; 2378 PetscInt ntext = 0,tval; 2379 PetscBool fset; 2380 2381 PetscFunctionBegin; 2382 PetscValidCharPointer(opt,3); 2383 while (list[ntext++]) { 2384 if (ntext > 50) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument appears to be wrong or have more than 50 entries"); 2385 } 2386 if (ntext < 3) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"List argument must have at least two entries: typename and type prefix"); 2387 ntext -= 3; 2388 ierr = PetscOptionsGetEList(options,pre,opt,list,ntext,&tval,&fset);CHKERRQ(ierr); 2389 /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */ 2390 if (fset) *value = (PetscEnum)tval; 2391 if (set) *set = fset; 2392 PetscFunctionReturn(0); 2393 } 2394 2395 /*@C 2396 PetscOptionsGetInt - Gets the integer value for a particular option in the database. 2397 2398 Not Collective 2399 2400 Input Parameters: 2401 + options - options database, use NULL for default global database 2402 . pre - the string to prepend to the name or NULL 2403 - name - the option one is seeking 2404 2405 Output Parameter: 2406 + ivalue - the integer value to return 2407 - set - PETSC_TRUE if found, else PETSC_FALSE 2408 2409 Level: beginner 2410 2411 Notes: 2412 If the user does not supply the option ivalue is NOT changed. Thus 2413 you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true. 2414 2415 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 2416 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 2417 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 2418 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2419 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2420 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2421 PetscOptionsFList(), PetscOptionsEList() 2422 @*/ 2423 PetscErrorCode PetscOptionsGetInt(PetscOptions options,const char pre[],const char name[],PetscInt *ivalue,PetscBool *set) 2424 { 2425 const char *value; 2426 PetscErrorCode ierr; 2427 PetscBool flag; 2428 2429 PetscFunctionBegin; 2430 PetscValidCharPointer(name,3); 2431 PetscValidIntPointer(ivalue,4); 2432 ierr = PetscOptionsFindPair(options,pre,name,&value,&flag);CHKERRQ(ierr); 2433 if (flag) { 2434 if (!value) { 2435 if (set) *set = PETSC_FALSE; 2436 } else { 2437 if (set) *set = PETSC_TRUE; 2438 ierr = PetscOptionsStringToInt(value,ivalue);CHKERRQ(ierr); 2439 } 2440 } else { 2441 if (set) *set = PETSC_FALSE; 2442 } 2443 PetscFunctionReturn(0); 2444 } 2445 2446 /*@C 2447 PetscOptionsGetReal - Gets the double precision value for a particular 2448 option in the database. 2449 2450 Not Collective 2451 2452 Input Parameters: 2453 + options - options database, use NULL for default global database 2454 . pre - string to prepend to each name or NULL 2455 - name - the option one is seeking 2456 2457 Output Parameter: 2458 + dvalue - the double value to return 2459 - set - PETSC_TRUE if found, PETSC_FALSE if not found 2460 2461 Notes: 2462 If the user does not supply the option dvalue is NOT changed. Thus 2463 you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true. 2464 2465 Level: beginner 2466 2467 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 2468 PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(),PetscOptionsBool(), 2469 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2470 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2471 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2472 PetscOptionsFList(), PetscOptionsEList() 2473 @*/ 2474 PetscErrorCode PetscOptionsGetReal(PetscOptions options,const char pre[],const char name[],PetscReal *dvalue,PetscBool *set) 2475 { 2476 const char *value; 2477 PetscBool flag; 2478 PetscErrorCode ierr; 2479 2480 PetscFunctionBegin; 2481 PetscValidCharPointer(name,3); 2482 PetscValidRealPointer(dvalue,4); 2483 ierr = PetscOptionsFindPair(options,pre,name,&value,&flag);CHKERRQ(ierr); 2484 if (flag) { 2485 if (!value) { 2486 if (set) *set = PETSC_FALSE; 2487 } else { 2488 if (set) *set = PETSC_TRUE; 2489 ierr = PetscOptionsStringToReal(value,dvalue);CHKERRQ(ierr); 2490 } 2491 } else { 2492 if (set) *set = PETSC_FALSE; 2493 } 2494 PetscFunctionReturn(0); 2495 } 2496 2497 /*@C 2498 PetscOptionsGetScalar - Gets the scalar value for a particular 2499 option in the database. 2500 2501 Not Collective 2502 2503 Input Parameters: 2504 + options - options database, use NULL for default global database 2505 . pre - string to prepend to each name or NULL 2506 - name - the option one is seeking 2507 2508 Output Parameter: 2509 + dvalue - the double value to return 2510 - set - PETSC_TRUE if found, else PETSC_FALSE 2511 2512 Level: beginner 2513 2514 Usage: 2515 A complex number 2+3i must be specified with NO spaces 2516 2517 Notes: 2518 If the user does not supply the option dvalue is NOT changed. Thus 2519 you should ALWAYS initialize the ivalue if you access it without first checking if the set flag is true. 2520 2521 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 2522 PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), 2523 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2524 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2525 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2526 PetscOptionsFList(), PetscOptionsEList() 2527 @*/ 2528 PetscErrorCode PetscOptionsGetScalar(PetscOptions options,const char pre[],const char name[],PetscScalar *dvalue,PetscBool *set) 2529 { 2530 const char *value; 2531 PetscBool flag; 2532 PetscErrorCode ierr; 2533 2534 PetscFunctionBegin; 2535 PetscValidCharPointer(name,3); 2536 PetscValidScalarPointer(dvalue,4); 2537 ierr = PetscOptionsFindPair(options,pre,name,&value,&flag);CHKERRQ(ierr); 2538 if (flag) { 2539 if (!value) { 2540 if (set) *set = PETSC_FALSE; 2541 } else { 2542 #if !defined(PETSC_USE_COMPLEX) 2543 ierr = PetscOptionsStringToReal(value,dvalue);CHKERRQ(ierr); 2544 #else 2545 ierr = PetscOptionsStringToScalar(value,dvalue);CHKERRQ(ierr); 2546 #endif 2547 if (set) *set = PETSC_TRUE; 2548 } 2549 } else { /* flag */ 2550 if (set) *set = PETSC_FALSE; 2551 } 2552 PetscFunctionReturn(0); 2553 } 2554 2555 /*@C 2556 PetscOptionsGetString - Gets the string value for a particular option in 2557 the database. 2558 2559 Not Collective 2560 2561 Input Parameters: 2562 + options - options database, use NULL for default global database 2563 . pre - string to prepend to name or NULL 2564 . name - the option one is seeking 2565 - len - maximum length of the string including null termination 2566 2567 Output Parameters: 2568 + string - location to copy string 2569 - set - PETSC_TRUE if found, else PETSC_FALSE 2570 2571 Level: beginner 2572 2573 Fortran Note: 2574 The Fortran interface is slightly different from the C/C++ 2575 interface (len is not used). Sample usage in Fortran follows 2576 .vb 2577 character *20 string 2578 PetscErrorCode ierr 2579 PetscBool set 2580 call PetscOptionsGetString(PETSC_NULL_OPTIONS,PETSC_NULL_CHARACTER,'-s',string,set,ierr) 2581 .ve 2582 2583 Notes: 2584 if the option is given but no string is provided then an empty string is returned and set is given the value of PETSC_TRUE 2585 2586 If the user does not use the option then the string is not changed. Thus 2587 you should ALWAYS initialize the string if you access it without first checking if the set flag is true. 2588 2589 Note: 2590 Even if the user provided no string (for example -optionname -someotheroption) the flag is set to PETSC_TRUE (and the string is fulled with nulls). 2591 2592 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(), 2593 PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), 2594 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2595 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2596 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2597 PetscOptionsFList(), PetscOptionsEList() 2598 @*/ 2599 PetscErrorCode PetscOptionsGetString(PetscOptions options,const char pre[],const char name[],char string[],size_t len,PetscBool *set) 2600 { 2601 const char *value; 2602 PetscBool flag; 2603 PetscErrorCode ierr; 2604 2605 PetscFunctionBegin; 2606 PetscValidCharPointer(name,3); 2607 PetscValidCharPointer(string,4); 2608 ierr = PetscOptionsFindPair(options,pre,name,&value,&flag);CHKERRQ(ierr); 2609 if (!flag) { 2610 if (set) *set = PETSC_FALSE; 2611 } else { 2612 if (set) *set = PETSC_TRUE; 2613 if (value) { 2614 ierr = PetscStrncpy(string,value,len);CHKERRQ(ierr); 2615 } else { 2616 ierr = PetscArrayzero(string,len);CHKERRQ(ierr); 2617 } 2618 } 2619 PetscFunctionReturn(0); 2620 } 2621 2622 char *PetscOptionsGetStringMatlab(PetscOptions options,const char pre[],const char name[]) 2623 { 2624 const char *value; 2625 PetscBool flag; 2626 PetscErrorCode ierr; 2627 2628 PetscFunctionBegin; 2629 ierr = PetscOptionsFindPair(options,pre,name,&value,&flag);if (ierr) PetscFunctionReturn(NULL); 2630 if (flag) PetscFunctionReturn((char*)value); 2631 else PetscFunctionReturn(NULL); 2632 } 2633 2634 /*@C 2635 PetscOptionsGetBoolArray - Gets an array of Logical (true or false) values for a particular 2636 option in the database. The values must be separated with commas with 2637 no intervening spaces. 2638 2639 Not Collective 2640 2641 Input Parameters: 2642 + options - options database, use NULL for default global database 2643 . pre - string to prepend to each name or NULL 2644 . name - the option one is seeking 2645 - nmax - maximum number of values to retrieve 2646 2647 Output Parameter: 2648 + dvalue - the integer values to return 2649 . nmax - actual number of values retreived 2650 - set - PETSC_TRUE if found, else PETSC_FALSE 2651 2652 Level: beginner 2653 2654 Notes: 2655 TRUE, true, YES, yes, nostring, and 1 all translate to PETSC_TRUE 2656 FALSE, false, NO, no, and 0 all translate to PETSC_FALSE 2657 2658 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 2659 PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(), 2660 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2661 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2662 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2663 PetscOptionsFList(), PetscOptionsEList() 2664 @*/ 2665 PetscErrorCode PetscOptionsGetBoolArray(PetscOptions options,const char pre[],const char name[],PetscBool dvalue[],PetscInt *nmax,PetscBool *set) 2666 { 2667 const char *svalue; 2668 char *value; 2669 PetscErrorCode ierr; 2670 PetscInt n = 0; 2671 PetscBool flag; 2672 PetscToken token; 2673 2674 PetscFunctionBegin; 2675 PetscValidCharPointer(name,3); 2676 PetscValidBoolPointer(dvalue,4); 2677 PetscValidIntPointer(nmax,5); 2678 2679 ierr = PetscOptionsFindPair(options,pre,name,&svalue,&flag);CHKERRQ(ierr); 2680 if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);} 2681 if (set) *set = PETSC_TRUE; 2682 ierr = PetscTokenCreate(svalue,',',&token);CHKERRQ(ierr); 2683 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2684 while (value && n < *nmax) { 2685 ierr = PetscOptionsStringToBool(value,dvalue);CHKERRQ(ierr); 2686 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2687 dvalue++; 2688 n++; 2689 } 2690 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 2691 *nmax = n; 2692 PetscFunctionReturn(0); 2693 } 2694 2695 /*@C 2696 PetscOptionsGetEnumArray - Gets an array of enum values for a particular option in the database. 2697 2698 Not Collective 2699 2700 Input Parameters: 2701 + options - options database, use NULL for default global database 2702 . pre - option prefix or NULL 2703 . name - option name 2704 . list - array containing the list of choices, followed by the enum name, followed by the enum prefix, followed by a null 2705 - nmax - maximum number of values to retrieve 2706 2707 Output Parameters: 2708 + ivalue - the enum values to return 2709 . nmax - actual number of values retreived 2710 - set - PETSC_TRUE if found, else PETSC_FALSE 2711 2712 Level: beginner 2713 2714 Notes: 2715 The array must be passed as a comma separated list. 2716 2717 There must be no intervening spaces between the values. 2718 2719 list is usually something like PCASMTypes or some other predefined list of enum names. 2720 2721 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), PetscOptionsGetInt(), 2722 PetscOptionsGetEnum(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 2723 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), PetscOptionsName(), 2724 PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), PetscOptionsStringArray(),PetscOptionsRealArray(), 2725 PetscOptionsScalar(), PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2726 PetscOptionsFList(), PetscOptionsEList(), PetscOptionsGetEList(), PetscOptionsEnum() 2727 @*/ 2728 PetscErrorCode PetscOptionsGetEnumArray(PetscOptions options,const char pre[],const char name[],const char *const *list,PetscEnum ivalue[],PetscInt *nmax,PetscBool *set) 2729 { 2730 const char *svalue; 2731 char *value; 2732 PetscInt n = 0; 2733 PetscEnum evalue; 2734 PetscBool flag; 2735 PetscToken token; 2736 PetscErrorCode ierr; 2737 2738 PetscFunctionBegin; 2739 PetscValidCharPointer(name,3); 2740 PetscValidPointer(list,4); 2741 PetscValidPointer(ivalue,5); 2742 PetscValidIntPointer(nmax,6); 2743 2744 ierr = PetscOptionsFindPair(options,pre,name,&svalue,&flag);CHKERRQ(ierr); 2745 if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);} 2746 if (set) *set = PETSC_TRUE; 2747 ierr = PetscTokenCreate(svalue,',',&token);CHKERRQ(ierr); 2748 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2749 while (value && n < *nmax) { 2750 ierr = PetscEnumFind(list,value,&evalue,&flag);CHKERRQ(ierr); 2751 if (!flag) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Unknown enum value '%s' for -%s%s",svalue,pre ? pre : "",name+1); 2752 ivalue[n++] = evalue; 2753 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2754 } 2755 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 2756 *nmax = n; 2757 PetscFunctionReturn(0); 2758 } 2759 2760 /*@C 2761 PetscOptionsGetIntArray - Gets an array of integer values for a particular 2762 option in the database. 2763 2764 Not Collective 2765 2766 Input Parameters: 2767 + options - options database, use NULL for default global database 2768 . pre - string to prepend to each name or NULL 2769 . name - the option one is seeking 2770 - nmax - maximum number of values to retrieve 2771 2772 Output Parameter: 2773 + ivalue - the integer values to return 2774 . nmax - actual number of values retreived 2775 - set - PETSC_TRUE if found, else PETSC_FALSE 2776 2777 Level: beginner 2778 2779 Notes: 2780 The array can be passed as 2781 a comma separated list: 0,1,2,3,4,5,6,7 2782 a range (start-end+1): 0-8 2783 a range with given increment (start-end+1:inc): 0-7:2 2784 a combination of values and ranges separated by commas: 0,1-8,8-15:2 2785 2786 There must be no intervening spaces between the values. 2787 2788 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 2789 PetscOptionsGetString(), PetscOptionsGetRealArray(), PetscOptionsBool(), 2790 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2791 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2792 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2793 PetscOptionsFList(), PetscOptionsEList() 2794 @*/ 2795 PetscErrorCode PetscOptionsGetIntArray(PetscOptions options,const char pre[],const char name[],PetscInt ivalue[],PetscInt *nmax,PetscBool *set) 2796 { 2797 const char *svalue; 2798 char *value; 2799 PetscErrorCode ierr; 2800 PetscInt n = 0,i,j,start,end,inc,nvalues; 2801 size_t len; 2802 PetscBool flag,foundrange; 2803 PetscToken token; 2804 2805 PetscFunctionBegin; 2806 PetscValidCharPointer(name,3); 2807 PetscValidIntPointer(ivalue,4); 2808 PetscValidIntPointer(nmax,5); 2809 2810 ierr = PetscOptionsFindPair(options,pre,name,&svalue,&flag);CHKERRQ(ierr); 2811 if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);} 2812 if (set) *set = PETSC_TRUE; 2813 ierr = PetscTokenCreate(svalue,',',&token);CHKERRQ(ierr); 2814 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2815 while (value && n < *nmax) { 2816 /* look for form d-D where d and D are integers */ 2817 foundrange = PETSC_FALSE; 2818 ierr = PetscStrlen(value,&len);CHKERRQ(ierr); 2819 if (value[0] == '-') i=2; 2820 else i=1; 2821 for (;i<(int)len; i++) { 2822 if (value[i] == '-') { 2823 if (i == (int)len-1) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry %s\n",n,value); 2824 value[i] = 0; 2825 2826 ierr = PetscOptionsStringToInt(value,&start);CHKERRQ(ierr); 2827 inc = 1; 2828 j = i+1; 2829 for (;j<(int)len; j++) { 2830 if (value[j] == ':') { 2831 value[j] = 0; 2832 2833 ierr = PetscOptionsStringToInt(value+j+1,&inc);CHKERRQ(ierr); 2834 if (inc <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry,%s cannot have negative increment",n,value+j+1); 2835 break; 2836 } 2837 } 2838 ierr = PetscOptionsStringToInt(value+i+1,&end);CHKERRQ(ierr); 2839 if (end <= start) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, %s-%s cannot have decreasing list",n,value,value+i+1); 2840 nvalues = (end-start)/inc + (end-start)%inc; 2841 if (n + nvalues > *nmax) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_USER,"Error in %D-th array entry, not enough space left in array (%D) to contain entire range from %D to %D",n,*nmax-n,start,end); 2842 for (;start<end; start+=inc) { 2843 *ivalue = start; ivalue++;n++; 2844 } 2845 foundrange = PETSC_TRUE; 2846 break; 2847 } 2848 } 2849 if (!foundrange) { 2850 ierr = PetscOptionsStringToInt(value,ivalue);CHKERRQ(ierr); 2851 ivalue++; 2852 n++; 2853 } 2854 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2855 } 2856 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 2857 *nmax = n; 2858 PetscFunctionReturn(0); 2859 } 2860 2861 /*@C 2862 PetscOptionsGetRealArray - Gets an array of double precision values for a 2863 particular option in the database. The values must be separated with 2864 commas with no intervening spaces. 2865 2866 Not Collective 2867 2868 Input Parameters: 2869 + options - options database, use NULL for default global database 2870 . pre - string to prepend to each name or NULL 2871 . name - the option one is seeking 2872 - nmax - maximum number of values to retrieve 2873 2874 Output Parameters: 2875 + dvalue - the double values to return 2876 . nmax - actual number of values retreived 2877 - set - PETSC_TRUE if found, else PETSC_FALSE 2878 2879 Level: beginner 2880 2881 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 2882 PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(), 2883 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2884 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2885 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2886 PetscOptionsFList(), PetscOptionsEList() 2887 @*/ 2888 PetscErrorCode PetscOptionsGetRealArray(PetscOptions options,const char pre[],const char name[],PetscReal dvalue[],PetscInt *nmax,PetscBool *set) 2889 { 2890 const char *svalue; 2891 char *value; 2892 PetscErrorCode ierr; 2893 PetscInt n = 0; 2894 PetscBool flag; 2895 PetscToken token; 2896 2897 PetscFunctionBegin; 2898 PetscValidCharPointer(name,3); 2899 PetscValidRealPointer(dvalue,4); 2900 PetscValidIntPointer(nmax,5); 2901 2902 ierr = PetscOptionsFindPair(options,pre,name,&svalue,&flag);CHKERRQ(ierr); 2903 if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);} 2904 if (set) *set = PETSC_TRUE; 2905 ierr = PetscTokenCreate(svalue,',',&token);CHKERRQ(ierr); 2906 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2907 while (value && n < *nmax) { 2908 ierr = PetscOptionsStringToReal(value,dvalue++);CHKERRQ(ierr); 2909 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2910 n++; 2911 } 2912 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 2913 *nmax = n; 2914 PetscFunctionReturn(0); 2915 } 2916 2917 /*@C 2918 PetscOptionsGetScalarArray - Gets an array of scalars for a 2919 particular option in the database. The values must be separated with 2920 commas with no intervening spaces. 2921 2922 Not Collective 2923 2924 Input Parameters: 2925 + options - options database, use NULL for default global database 2926 . pre - string to prepend to each name or NULL 2927 . name - the option one is seeking 2928 - nmax - maximum number of values to retrieve 2929 2930 Output Parameters: 2931 + dvalue - the scalar values to return 2932 . nmax - actual number of values retreived 2933 - set - PETSC_TRUE if found, else PETSC_FALSE 2934 2935 Level: beginner 2936 2937 .seealso: PetscOptionsGetInt(), PetscOptionsHasName(), 2938 PetscOptionsGetString(), PetscOptionsGetIntArray(), PetscOptionsBool(), 2939 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 2940 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 2941 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 2942 PetscOptionsFList(), PetscOptionsEList() 2943 @*/ 2944 PetscErrorCode PetscOptionsGetScalarArray(PetscOptions options,const char pre[],const char name[],PetscScalar dvalue[],PetscInt *nmax,PetscBool *set) 2945 { 2946 const char *svalue; 2947 char *value; 2948 PetscErrorCode ierr; 2949 PetscInt n = 0; 2950 PetscBool flag; 2951 PetscToken token; 2952 2953 PetscFunctionBegin; 2954 PetscValidCharPointer(name,3); 2955 PetscValidScalarPointer(dvalue,4); 2956 PetscValidIntPointer(nmax,5); 2957 2958 ierr = PetscOptionsFindPair(options,pre,name,&svalue,&flag);CHKERRQ(ierr); 2959 if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);} 2960 if (set) *set = PETSC_TRUE; 2961 ierr = PetscTokenCreate(svalue,',',&token);CHKERRQ(ierr); 2962 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2963 while (value && n < *nmax) { 2964 ierr = PetscOptionsStringToScalar(value,dvalue++);CHKERRQ(ierr); 2965 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 2966 n++; 2967 } 2968 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 2969 *nmax = n; 2970 PetscFunctionReturn(0); 2971 } 2972 2973 /*@C 2974 PetscOptionsGetStringArray - Gets an array of string values for a particular 2975 option in the database. The values must be separated with commas with 2976 no intervening spaces. 2977 2978 Not Collective 2979 2980 Input Parameters: 2981 + options - options database, use NULL for default global database 2982 . pre - string to prepend to name or NULL 2983 . name - the option one is seeking 2984 - nmax - maximum number of strings 2985 2986 Output Parameters: 2987 + strings - location to copy strings 2988 . nmax - the number of strings found 2989 - set - PETSC_TRUE if found, else PETSC_FALSE 2990 2991 Level: beginner 2992 2993 Notes: 2994 The nmax parameter is used for both input and output. 2995 2996 The user should pass in an array of pointers to char, to hold all the 2997 strings returned by this function. 2998 2999 The user is responsible for deallocating the strings that are 3000 returned. The Fortran interface for this routine is not supported. 3001 3002 .seealso: PetscOptionsGetInt(), PetscOptionsGetReal(), 3003 PetscOptionsHasName(), PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool(), 3004 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 3005 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 3006 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 3007 PetscOptionsFList(), PetscOptionsEList() 3008 @*/ 3009 PetscErrorCode PetscOptionsGetStringArray(PetscOptions options,const char pre[],const char name[],char *strings[],PetscInt *nmax,PetscBool *set) 3010 { 3011 const char *svalue; 3012 char *value; 3013 PetscErrorCode ierr; 3014 PetscInt n = 0; 3015 PetscBool flag; 3016 PetscToken token; 3017 3018 PetscFunctionBegin; 3019 PetscValidCharPointer(name,3); 3020 PetscValidPointer(strings,4); 3021 PetscValidIntPointer(nmax,5); 3022 3023 ierr = PetscOptionsFindPair(options,pre,name,&svalue,&flag);CHKERRQ(ierr); 3024 if (!flag || !svalue) { if (set) *set = PETSC_FALSE; *nmax = 0; PetscFunctionReturn(0);} 3025 if (set) *set = PETSC_TRUE; 3026 ierr = PetscTokenCreate(svalue,',',&token);CHKERRQ(ierr); 3027 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 3028 while (value && n < *nmax) { 3029 ierr = PetscStrallocpy(value,&strings[n]);CHKERRQ(ierr); 3030 ierr = PetscTokenFind(token,&value);CHKERRQ(ierr); 3031 n++; 3032 } 3033 ierr = PetscTokenDestroy(&token);CHKERRQ(ierr); 3034 *nmax = n; 3035 PetscFunctionReturn(0); 3036 } 3037 3038 /*@C 3039 PetscOptionsDeprecated - mark an option as deprecated, optionally replacing it with a new one 3040 3041 Prints a deprecation warning, unless an option is supplied to suppress. 3042 3043 Logically Collective 3044 3045 Input Parameters: 3046 + pre - string to prepend to name or NULL 3047 . oldname - the old, deprecated option 3048 . newname - the new option, or NULL if option is purely removed 3049 . version - a string describing the version of first deprecation, e.g. "3.9" 3050 - info - additional information string, or NULL. 3051 3052 Options Database Keys: 3053 . -options_suppress_deprecated_warnings - do not print deprecation warnings 3054 3055 Notes: 3056 Must be called between PetscOptionsBegin() (or PetscObjectOptionsBegin()) and PetscOptionsEnd(). 3057 Only the proces of rank zero that owns the PetscOptionsItems are argument (managed by PetscOptionsBegin() or 3058 PetscObjectOptionsBegin() prints the information 3059 If newname is provided, the old option is replaced. Otherwise, it remains 3060 in the options database. 3061 If an option is not replaced, the info argument should be used to advise the user 3062 on how to proceed. 3063 There is a limit on the length of the warning printed, so very long strings 3064 provided as info may be truncated. 3065 3066 Level: developer 3067 3068 .seealso: PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsScalar(), PetscOptionsBool(), PetscOptionsString(), PetscOptionsSetValue() 3069 3070 @*/ 3071 PetscErrorCode PetscOptionsDeprecated_Private(PetscOptionItems *PetscOptionsObject,const char oldname[],const char newname[],const char version[],const char info[]) 3072 { 3073 PetscErrorCode ierr; 3074 PetscBool found,quiet; 3075 const char *value; 3076 const char * const quietopt="-options_suppress_deprecated_warnings"; 3077 char msg[4096]; 3078 char *prefix = NULL; 3079 PetscOptions options = NULL; 3080 MPI_Comm comm = PETSC_COMM_SELF; 3081 3082 PetscFunctionBegin; 3083 PetscValidCharPointer(oldname,2); 3084 PetscValidCharPointer(version,4); 3085 if (PetscOptionsObject) { 3086 prefix = PetscOptionsObject->prefix; 3087 options = PetscOptionsObject->options; 3088 comm = PetscOptionsObject->comm; 3089 } 3090 ierr = PetscOptionsFindPair(options,prefix,oldname,&value,&found);CHKERRQ(ierr); 3091 if (found) { 3092 if (newname) { 3093 if (prefix) { 3094 ierr = PetscOptionsPrefixPush(options,prefix);CHKERRQ(ierr); 3095 } 3096 ierr = PetscOptionsSetValue(options,newname,value);CHKERRQ(ierr); 3097 if (prefix) { 3098 ierr = PetscOptionsPrefixPop(options);CHKERRQ(ierr); 3099 } 3100 ierr = PetscOptionsClearValue(options,oldname);CHKERRQ(ierr); 3101 } 3102 quiet = PETSC_FALSE; 3103 ierr = PetscOptionsGetBool(options,NULL,quietopt,&quiet,NULL);CHKERRQ(ierr); 3104 if (!quiet) { 3105 ierr = PetscStrcpy(msg,"** PETSc DEPRECATION WARNING ** : the option ");CHKERRQ(ierr); 3106 ierr = PetscStrcat(msg,oldname);CHKERRQ(ierr); 3107 ierr = PetscStrcat(msg," is deprecated as of version ");CHKERRQ(ierr); 3108 ierr = PetscStrcat(msg,version);CHKERRQ(ierr); 3109 ierr = PetscStrcat(msg," and will be removed in a future release.");CHKERRQ(ierr); 3110 if (newname) { 3111 ierr = PetscStrcat(msg," Please use the option ");CHKERRQ(ierr); 3112 ierr = PetscStrcat(msg,newname);CHKERRQ(ierr); 3113 ierr = PetscStrcat(msg," instead.");CHKERRQ(ierr); 3114 } 3115 if (info) { 3116 ierr = PetscStrcat(msg," ");CHKERRQ(ierr); 3117 ierr = PetscStrcat(msg,info);CHKERRQ(ierr); 3118 } 3119 ierr = PetscStrcat(msg," (Silence this warning with ");CHKERRQ(ierr); 3120 ierr = PetscStrcat(msg,quietopt);CHKERRQ(ierr); 3121 ierr = PetscStrcat(msg,")\n");CHKERRQ(ierr); 3122 ierr = PetscPrintf(comm,msg);CHKERRQ(ierr); 3123 } 3124 } 3125 PetscFunctionReturn(0); 3126 } 3127