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