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