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