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