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