153acd3b1SBarry Smith /* 23fc1eb6aSBarry Smith Implements the higher-level options database querying methods. These are self-documenting and can attach at runtime to 33fc1eb6aSBarry Smith GUI code to display the options and get values from the users. 453acd3b1SBarry Smith 553acd3b1SBarry Smith */ 653acd3b1SBarry Smith 7af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 8665c2dedSJed Brown #include <petscviewer.h> 953acd3b1SBarry Smith 1010c654e6SJacob Faibussowitsch static const char *ManSection(const char *str) 1110c654e6SJacob Faibussowitsch { 1210c654e6SJacob Faibussowitsch return str ? str : "None"; 1310c654e6SJacob Faibussowitsch } 1410c654e6SJacob Faibussowitsch 1510c654e6SJacob Faibussowitsch static const char *Prefix(const char *str) 1610c654e6SJacob Faibussowitsch { 1710c654e6SJacob Faibussowitsch return str ? str : ""; 1810c654e6SJacob Faibussowitsch } 1910c654e6SJacob Faibussowitsch 2010c654e6SJacob Faibussowitsch static int ShouldPrintHelp(const PetscOptionItems *opts) 2110c654e6SJacob Faibussowitsch { 2210c654e6SJacob Faibussowitsch return opts->printhelp && opts->count == 1 && !opts->alreadyprinted; 2310c654e6SJacob Faibussowitsch } 242aa6d131SJed Brown 2553acd3b1SBarry Smith /* 2653acd3b1SBarry Smith Keep a linked list of options that have been posted and we are waiting for 273fc1eb6aSBarry Smith user selection. See the manual page for PetscOptionsBegin() 2853acd3b1SBarry Smith 2953acd3b1SBarry Smith Eventually we'll attach this beast to a MPI_Comm 3053acd3b1SBarry Smith */ 31e55864a3SBarry Smith 3253acd3b1SBarry Smith /* 3353acd3b1SBarry Smith Handles setting up the data structure in a call to PetscOptionsBegin() 3453acd3b1SBarry Smith */ 35d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBegin_Private(PetscOptionItems *PetscOptionsObject, MPI_Comm comm, const char prefix[], const char title[], const char mansec[]) 36d71ae5a4SJacob Faibussowitsch { 3753acd3b1SBarry Smith PetscFunctionBegin; 384f572ea9SToby Isaac if (prefix) PetscAssertPointer(prefix, 3); 394f572ea9SToby Isaac PetscAssertPointer(title, 4); 404f572ea9SToby Isaac if (mansec) PetscAssertPointer(mansec, 5); 410eb63584SBarry Smith if (!PetscOptionsObject->alreadyprinted) { 429566063dSJacob Faibussowitsch if (!PetscOptionsHelpPrintedSingleton) PetscCall(PetscOptionsHelpPrintedCreate(&PetscOptionsHelpPrintedSingleton)); 439566063dSJacob Faibussowitsch PetscCall(PetscOptionsHelpPrintedCheck(PetscOptionsHelpPrintedSingleton, prefix, title, &PetscOptionsObject->alreadyprinted)); 440eb63584SBarry Smith } 4502c9f0b5SLisandro Dalcin PetscOptionsObject->next = NULL; 46e55864a3SBarry Smith PetscOptionsObject->comm = comm; 47e55864a3SBarry Smith PetscOptionsObject->changedmethod = PETSC_FALSE; 48a297a907SKarl Rupp 499566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(prefix, &PetscOptionsObject->prefix)); 509566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(title, &PetscOptionsObject->title)); 5153acd3b1SBarry Smith 529566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasHelp(PetscOptionsObject->options, &PetscOptionsObject->printhelp)); 5310c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, "----------------------------------------\n%s:\n", title)); 543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5553acd3b1SBarry Smith } 5653acd3b1SBarry Smith 573194b578SJed Brown /* 583194b578SJed Brown Handles setting up the data structure in a call to PetscObjectOptionsBegin() 593194b578SJed Brown */ 60d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscObjectOptionsBegin_Private(PetscObject obj, PetscOptionItems *PetscOptionsObject) 61d71ae5a4SJacob Faibussowitsch { 623194b578SJed Brown char title[256]; 633194b578SJed Brown PetscBool flg; 643194b578SJed Brown 653194b578SJed Brown PetscFunctionBegin; 664f572ea9SToby Isaac PetscAssertPointer(PetscOptionsObject, 2); 67dbbe0bcdSBarry Smith PetscValidHeader(obj, 1); 68e55864a3SBarry Smith PetscOptionsObject->object = obj; 69e55864a3SBarry Smith PetscOptionsObject->alreadyprinted = obj->optionsprinted; 70a297a907SKarl Rupp 719566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(obj->description, obj->class_name, &flg)); 729566063dSJacob Faibussowitsch if (flg) PetscCall(PetscSNPrintf(title, sizeof(title), "%s options", obj->class_name)); 739566063dSJacob Faibussowitsch else PetscCall(PetscSNPrintf(title, sizeof(title), "%s (%s) options", obj->description, obj->class_name)); 749566063dSJacob Faibussowitsch PetscCall(PetscOptionsBegin_Private(PetscOptionsObject, obj->comm, obj->prefix, title, obj->mansec)); 753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 763194b578SJed Brown } 773194b578SJed Brown 7853acd3b1SBarry Smith /* 7953acd3b1SBarry Smith Handles adding another option to the list of options within this particular PetscOptionsBegin() PetscOptionsEnd() 8053acd3b1SBarry Smith */ 813ba16761SJacob Faibussowitsch static PetscErrorCode PetscOptionItemCreate_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscOptionType t, PetscOptionItem *amsopt) 82d71ae5a4SJacob Faibussowitsch { 833be6e4c3SJed Brown PetscBool valid; 8453acd3b1SBarry Smith 8553acd3b1SBarry Smith PetscFunctionBegin; 869566063dSJacob Faibussowitsch PetscCall(PetscOptionsValidKey(opt, &valid)); 875f80ce2aSJacob Faibussowitsch PetscCheck(valid, PETSC_COMM_WORLD, PETSC_ERR_ARG_INCOMP, "The option '%s' is not a valid key", opt); 883be6e4c3SJed Brown 899566063dSJacob Faibussowitsch PetscCall(PetscNew(amsopt)); 9002c9f0b5SLisandro Dalcin (*amsopt)->next = NULL; 9153acd3b1SBarry Smith (*amsopt)->set = PETSC_FALSE; 926356e834SBarry Smith (*amsopt)->type = t; 9302c9f0b5SLisandro Dalcin (*amsopt)->data = NULL; 9461b37b28SSatish Balay 959566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(text, &(*amsopt)->text)); 969566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(opt, &(*amsopt)->option)); 979566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(man, &(*amsopt)->man)); 9853acd3b1SBarry Smith 9910c654e6SJacob Faibussowitsch { 10010c654e6SJacob Faibussowitsch PetscOptionItem cur = PetscOptionsObject->next; 10110c654e6SJacob Faibussowitsch 10210c654e6SJacob Faibussowitsch while (cur->next) cur = cur->next; 10310c654e6SJacob Faibussowitsch cur->next = *amsopt; 10453acd3b1SBarry Smith } 1053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10653acd3b1SBarry Smith } 10753acd3b1SBarry Smith 108aee2cecaSBarry Smith /* 10910450e9eSJacob Faibussowitsch This is needed because certain strings may be freed by SAWs, hence we cannot use PetscStrallocpy() 11010450e9eSJacob Faibussowitsch */ 11110450e9eSJacob Faibussowitsch static PetscErrorCode PetscStrdup(const char s[], char *t[]) 11210450e9eSJacob Faibussowitsch { 11310450e9eSJacob Faibussowitsch char *tmp = NULL; 11410450e9eSJacob Faibussowitsch 11510450e9eSJacob Faibussowitsch PetscFunctionBegin; 11610450e9eSJacob Faibussowitsch if (s) { 11710450e9eSJacob Faibussowitsch size_t len; 11810450e9eSJacob Faibussowitsch 11910450e9eSJacob Faibussowitsch PetscCall(PetscStrlen(s, &len)); 12010450e9eSJacob Faibussowitsch tmp = (char *)malloc((len + 1) * sizeof(*tmp)); 12110450e9eSJacob Faibussowitsch PetscCheck(tmp, PETSC_COMM_SELF, PETSC_ERR_MEM, "No memory to duplicate string"); 12210450e9eSJacob Faibussowitsch PetscCall(PetscArraycpy(tmp, s, len + 1)); 12310450e9eSJacob Faibussowitsch } 12410450e9eSJacob Faibussowitsch *t = tmp; 12510450e9eSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12610450e9eSJacob Faibussowitsch } 12710450e9eSJacob Faibussowitsch 12810450e9eSJacob Faibussowitsch #if defined(PETSC_HAVE_SAWS) 12910450e9eSJacob Faibussowitsch #include <petscviewersaws.h> 13010450e9eSJacob Faibussowitsch 13110450e9eSJacob Faibussowitsch static int count = 0; 13210450e9eSJacob Faibussowitsch 13310450e9eSJacob Faibussowitsch PetscErrorCode PetscOptionsSAWsDestroy(void) 13410450e9eSJacob Faibussowitsch { 13510450e9eSJacob Faibussowitsch PetscFunctionBegin; 13610450e9eSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13710450e9eSJacob Faibussowitsch } 13810450e9eSJacob Faibussowitsch 13910450e9eSJacob Faibussowitsch static const char *OptionsHeader = "<head>\n" 14010450e9eSJacob Faibussowitsch "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n" 14110450e9eSJacob Faibussowitsch "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n" 14210450e9eSJacob Faibussowitsch "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n" 14310450e9eSJacob Faibussowitsch "<script>\n" 14410450e9eSJacob Faibussowitsch "jQuery(document).ready(function() {\n" 14510450e9eSJacob Faibussowitsch "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n" 14610450e9eSJacob Faibussowitsch "})\n" 14710450e9eSJacob Faibussowitsch "</script>\n" 14810450e9eSJacob Faibussowitsch "</head>\n"; 14910450e9eSJacob Faibussowitsch 15010450e9eSJacob Faibussowitsch /* Determines the size and style of the scroll region where PETSc options selectable from users are displayed */ 15110450e9eSJacob Faibussowitsch static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>"; 15210450e9eSJacob Faibussowitsch 15310450e9eSJacob Faibussowitsch /* 15410450e9eSJacob Faibussowitsch PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs 15510450e9eSJacob Faibussowitsch 15610450e9eSJacob Faibussowitsch Bugs: 15710450e9eSJacob Faibussowitsch + All processes must traverse through the exact same set of option queries due to the call to PetscScanString() 15810450e9eSJacob Faibussowitsch . Internal strings have arbitrary length and string copies are not checked that they fit into string space 15910450e9eSJacob Faibussowitsch - Only works for PetscInt == int, PetscReal == double etc 16010450e9eSJacob Faibussowitsch 16110450e9eSJacob Faibussowitsch */ 16266976f2fSJacob Faibussowitsch static PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems *PetscOptionsObject) 16310450e9eSJacob Faibussowitsch { 16410450e9eSJacob Faibussowitsch PetscOptionItem next = PetscOptionsObject->next; 16510450e9eSJacob Faibussowitsch static int mancount = 0; 16610450e9eSJacob Faibussowitsch char options[16]; 16710450e9eSJacob Faibussowitsch PetscBool changedmethod = PETSC_FALSE; 16810450e9eSJacob Faibussowitsch PetscBool stopasking = PETSC_FALSE; 16910450e9eSJacob Faibussowitsch char manname[16], textname[16]; 17010450e9eSJacob Faibussowitsch char dir[1024]; 17110450e9eSJacob Faibussowitsch 17210450e9eSJacob Faibussowitsch PetscFunctionBegin; 17310450e9eSJacob Faibussowitsch /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */ 17410450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(options, PETSC_STATIC_ARRAY_LENGTH(options), "Options_%d", count++)); 17510450e9eSJacob Faibussowitsch 17610450e9eSJacob Faibussowitsch PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */ 17710450e9eSJacob Faibussowitsch 17810450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title")); 17910450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING)); 18010450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix")); 18110450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING)); 18210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN)); 18310450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN)); 18410450e9eSJacob Faibussowitsch 18510450e9eSJacob Faibussowitsch while (next) { 18610450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(manname, PETSC_STATIC_ARRAY_LENGTH(manname), "_man_%d", mancount)); 18710450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname)); 18810450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING)); 18910450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(textname, PETSC_STATIC_ARRAY_LENGTH(textname), "_text_%d", mancount++)); 19010450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname)); 19110450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING)); 19210450e9eSJacob Faibussowitsch 19310450e9eSJacob Faibussowitsch switch (next->type) { 19410450e9eSJacob Faibussowitsch case OPTION_HEAD: 19510450e9eSJacob Faibussowitsch break; 19610450e9eSJacob Faibussowitsch case OPTION_INT_ARRAY: 19710450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 19810450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT)); 19910450e9eSJacob Faibussowitsch break; 20010450e9eSJacob Faibussowitsch case OPTION_REAL_ARRAY: 20110450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 20210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE)); 20310450e9eSJacob Faibussowitsch break; 20410450e9eSJacob Faibussowitsch case OPTION_INT: 20510450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 20610450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT)); 20710450e9eSJacob Faibussowitsch break; 20810450e9eSJacob Faibussowitsch case OPTION_REAL: 20910450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 21010450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE)); 21110450e9eSJacob Faibussowitsch break; 21210450e9eSJacob Faibussowitsch case OPTION_BOOL: 21310450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 21410450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN)); 21510450e9eSJacob Faibussowitsch break; 21610450e9eSJacob Faibussowitsch case OPTION_BOOL_ARRAY: 21710450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 21810450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN)); 21910450e9eSJacob Faibussowitsch break; 22010450e9eSJacob Faibussowitsch case OPTION_STRING: 22110450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 22210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING)); 22310450e9eSJacob Faibussowitsch break; 22410450e9eSJacob Faibussowitsch case OPTION_STRING_ARRAY: 22510450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 22610450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING)); 22710450e9eSJacob Faibussowitsch break; 22810450e9eSJacob Faibussowitsch case OPTION_FLIST: { 22910450e9eSJacob Faibussowitsch PetscInt ntext; 23010450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 23110450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING)); 23210450e9eSJacob Faibussowitsch PetscCall(PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext)); 23310450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata)); 23410450e9eSJacob Faibussowitsch } break; 23510450e9eSJacob Faibussowitsch case OPTION_ELIST: { 23610450e9eSJacob Faibussowitsch PetscInt ntext = next->nlist; 23710450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 23810450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING)); 23910450e9eSJacob Faibussowitsch PetscCall(PetscMalloc1((ntext + 1), (char ***)&next->edata)); 24010450e9eSJacob Faibussowitsch PetscCall(PetscMemcpy(next->edata, next->list, ntext * sizeof(char *))); 24110450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata)); 24210450e9eSJacob Faibussowitsch } break; 24310450e9eSJacob Faibussowitsch default: 24410450e9eSJacob Faibussowitsch break; 24510450e9eSJacob Faibussowitsch } 24610450e9eSJacob Faibussowitsch next = next->next; 24710450e9eSJacob Faibussowitsch } 24810450e9eSJacob Faibussowitsch 24910450e9eSJacob Faibussowitsch /* wait until accessor has unlocked the memory */ 25010450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Push_Header, ("index.html", OptionsHeader)); 25110450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom)); 25210450e9eSJacob Faibussowitsch PetscCall(PetscSAWsBlock()); 25310450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Pop_Header, ("index.html")); 25410450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Pop_Body, ("index.html", 2)); 25510450e9eSJacob Faibussowitsch 25610450e9eSJacob Faibussowitsch /* determine if any values have been set in GUI */ 25710450e9eSJacob Faibussowitsch next = PetscOptionsObject->next; 25810450e9eSJacob Faibussowitsch while (next) { 25910450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 26010450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Selected, (dir, (int *)&next->set)); 26110450e9eSJacob Faibussowitsch next = next->next; 26210450e9eSJacob Faibussowitsch } 26310450e9eSJacob Faibussowitsch 26410450e9eSJacob Faibussowitsch /* reset counter to -2; this updates the screen with the new options for the selected method */ 26510450e9eSJacob Faibussowitsch if (changedmethod) PetscOptionsObject->count = -2; 26610450e9eSJacob Faibussowitsch 26710450e9eSJacob Faibussowitsch if (stopasking) { 26810450e9eSJacob Faibussowitsch PetscOptionsPublish = PETSC_FALSE; 26910450e9eSJacob Faibussowitsch PetscOptionsObject->count = 0; //do not ask for same thing again 27010450e9eSJacob Faibussowitsch } 27110450e9eSJacob Faibussowitsch 27210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Delete, ("/PETSc/Options")); 27310450e9eSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27410450e9eSJacob Faibussowitsch } 27510450e9eSJacob Faibussowitsch #else 27610450e9eSJacob Faibussowitsch /* 2773fc1eb6aSBarry Smith PetscScanString - Gets user input via stdin from process and broadcasts to all processes 2783fc1eb6aSBarry Smith 279d083f849SBarry Smith Collective 2803fc1eb6aSBarry Smith 2813fc1eb6aSBarry Smith Input Parameters: 2823fc1eb6aSBarry Smith + commm - communicator for the broadcast, must be PETSC_COMM_WORLD 2833fc1eb6aSBarry Smith . n - length of the string, must be the same on all processes 2843fc1eb6aSBarry Smith - str - location to store input 285aee2cecaSBarry Smith 286aee2cecaSBarry Smith Bugs: 287aee2cecaSBarry Smith . Assumes process 0 of the given communicator has access to stdin 288aee2cecaSBarry Smith 289aee2cecaSBarry Smith */ 290d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[]) 291d71ae5a4SJacob Faibussowitsch { 2923fc1eb6aSBarry Smith PetscMPIInt rank, nm; 293aee2cecaSBarry Smith 294aee2cecaSBarry Smith PetscFunctionBegin; 2959566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 296dd400576SPatrick Sanan if (rank == 0) { 2975f80ce2aSJacob Faibussowitsch char c = (char)getchar(); 2985f80ce2aSJacob Faibussowitsch size_t i = 0; 2995f80ce2aSJacob Faibussowitsch 300aee2cecaSBarry Smith while (c != '\n' && i < n - 1) { 301aee2cecaSBarry Smith str[i++] = c; 302aee2cecaSBarry Smith c = (char)getchar(); 303aee2cecaSBarry Smith } 30410c654e6SJacob Faibussowitsch str[i] = '\0'; 305aee2cecaSBarry Smith } 3069566063dSJacob Faibussowitsch PetscCall(PetscMPIIntCast(n, &nm)); 3079566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(str, nm, MPI_CHAR, 0, comm)); 3083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 309aee2cecaSBarry Smith } 310aee2cecaSBarry Smith 3115b02f95dSBarry Smith /* 3123cc1e11dSBarry Smith PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime 313aee2cecaSBarry Smith 31495452b02SPatrick Sanan Notes: 31595452b02SPatrick Sanan this isn't really practical, it is just to demonstrate the principle 316aee2cecaSBarry Smith 3177781c08eSBarry Smith A carriage return indicates no change from the default; but this like -ksp_monitor <stdout> the default is actually not stdout the default 3187781c08eSBarry Smith is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug? 3197781c08eSBarry Smith 320aee2cecaSBarry Smith Bugs: 3217781c08eSBarry Smith + All processes must traverse through the exact same set of option queries due to the call to PetscScanString() 3223cc1e11dSBarry Smith . Internal strings have arbitrary length and string copies are not checked that they fit into string space 323aee2cecaSBarry Smith - Only works for PetscInt == int, PetscReal == double etc 324aee2cecaSBarry Smith 325aec76313SJacob Faibussowitsch Developer Notes: 32695452b02SPatrick Sanan Normally the GUI that presents the options the user and retrieves the values would be running in a different 3273cc1e11dSBarry Smith address space and communicating with the PETSc program 3283cc1e11dSBarry Smith 329aee2cecaSBarry Smith */ 33010450e9eSJacob Faibussowitsch static PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems *PetscOptionsObject) 331d71ae5a4SJacob Faibussowitsch { 3324416b707SBarry Smith PetscOptionItem next = PetscOptionsObject->next; 3336356e834SBarry Smith char str[512]; 3347781c08eSBarry Smith PetscBool bid; 335a4404d99SBarry Smith PetscReal ir, *valr; 336330cf3c9SBarry Smith PetscInt *vald; 337330cf3c9SBarry Smith size_t i; 3386356e834SBarry Smith 3392a409bb0SBarry Smith PetscFunctionBegin; 3409566063dSJacob Faibussowitsch PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title)); 3416356e834SBarry Smith while (next) { 3426356e834SBarry Smith switch (next->type) { 343d71ae5a4SJacob Faibussowitsch case OPTION_HEAD: 344d71ae5a4SJacob Faibussowitsch break; 345e26ddf31SBarry Smith case OPTION_INT_ARRAY: 3464bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1)); 347e26ddf31SBarry Smith vald = (PetscInt *)next->data; 348e26ddf31SBarry Smith for (i = 0; i < next->arraylength; i++) { 3499566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i])); 35048a46eb9SPierre Jolivet if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ",")); 351e26ddf31SBarry Smith } 3529566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man)); 3539566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 354e26ddf31SBarry Smith if (str[0]) { 355e26ddf31SBarry Smith PetscToken token; 356e26ddf31SBarry Smith PetscInt n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end; 357e26ddf31SBarry Smith size_t len; 358e26ddf31SBarry Smith char *value; 359ace3abfcSBarry Smith PetscBool foundrange; 360e26ddf31SBarry Smith 361e26ddf31SBarry Smith next->set = PETSC_TRUE; 362e26ddf31SBarry Smith value = str; 3639566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(value, ',', &token)); 3649566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 365e26ddf31SBarry Smith while (n < nmax) { 366e26ddf31SBarry Smith if (!value) break; 367e26ddf31SBarry Smith 368e26ddf31SBarry Smith /* look for form d-D where d and D are integers */ 369e26ddf31SBarry Smith foundrange = PETSC_FALSE; 3709566063dSJacob Faibussowitsch PetscCall(PetscStrlen(value, &len)); 371e26ddf31SBarry Smith if (value[0] == '-') i = 2; 372e26ddf31SBarry Smith else i = 1; 373330cf3c9SBarry Smith for (; i < len; i++) { 374e26ddf31SBarry Smith if (value[i] == '-') { 37508401ef6SPierre Jolivet PetscCheck(i != len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value); 376e26ddf31SBarry Smith value[i] = 0; 3779566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToInt(value, &start)); 3789566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToInt(value + i + 1, &end)); 37908401ef6SPierre Jolivet PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, value, value + i + 1); 380cc73adaaSBarry Smith PetscCheck(n + end - start - 1 < nmax, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, not enough space in left in array (%" PetscInt_FMT ") to contain entire range from %" PetscInt_FMT " to %" PetscInt_FMT, n, nmax - n, start, end); 381e26ddf31SBarry Smith for (; start < end; start++) { 3829371c9d4SSatish Balay *dvalue = start; 3839371c9d4SSatish Balay dvalue++; 3849371c9d4SSatish Balay n++; 385e26ddf31SBarry Smith } 386e26ddf31SBarry Smith foundrange = PETSC_TRUE; 387e26ddf31SBarry Smith break; 388e26ddf31SBarry Smith } 389e26ddf31SBarry Smith } 390e26ddf31SBarry Smith if (!foundrange) { 3919566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToInt(value, dvalue)); 392e26ddf31SBarry Smith dvalue++; 393e26ddf31SBarry Smith n++; 394e26ddf31SBarry Smith } 3959566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 396e26ddf31SBarry Smith } 3979566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 398e26ddf31SBarry Smith } 399e26ddf31SBarry Smith break; 400e26ddf31SBarry Smith case OPTION_REAL_ARRAY: 4014bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1)); 402e26ddf31SBarry Smith valr = (PetscReal *)next->data; 403e26ddf31SBarry Smith for (i = 0; i < next->arraylength; i++) { 4049566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i])); 40548a46eb9SPierre Jolivet if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ",")); 406e26ddf31SBarry Smith } 4079566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man)); 4089566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 409e26ddf31SBarry Smith if (str[0]) { 410e26ddf31SBarry Smith PetscToken token; 411e26ddf31SBarry Smith PetscInt n = 0, nmax = next->arraylength; 412e26ddf31SBarry Smith PetscReal *dvalue = (PetscReal *)next->data; 413e26ddf31SBarry Smith char *value; 414e26ddf31SBarry Smith 415e26ddf31SBarry Smith next->set = PETSC_TRUE; 416e26ddf31SBarry Smith value = str; 4179566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(value, ',', &token)); 4189566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 419e26ddf31SBarry Smith while (n < nmax) { 420e26ddf31SBarry Smith if (!value) break; 4219566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToReal(value, dvalue)); 422e26ddf31SBarry Smith dvalue++; 423e26ddf31SBarry Smith n++; 4249566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 425e26ddf31SBarry Smith } 4269566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 427e26ddf31SBarry Smith } 428e26ddf31SBarry Smith break; 4296356e834SBarry Smith case OPTION_INT: 4304bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%d>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(int *)next->data, next->text, next->man)); 4319566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4323fc1eb6aSBarry Smith if (str[0]) { 433d25d7f95SJed Brown #if defined(PETSC_SIZEOF_LONG_LONG) 434d25d7f95SJed Brown long long lid; 435d25d7f95SJed Brown sscanf(str, "%lld", &lid); 436cc73adaaSBarry Smith PetscCheck(lid <= PETSC_MAX_INT && lid >= PETSC_MIN_INT, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %lld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid); 437c272547aSJed Brown #else 438d25d7f95SJed Brown long lid; 439d25d7f95SJed Brown sscanf(str, "%ld", &lid); 440cc73adaaSBarry Smith PetscCheck(lid <= PETSC_MAX_INT && lid >= PETSC_MIN_INT, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %ld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid); 441c272547aSJed Brown #endif 442a297a907SKarl Rupp 443d25d7f95SJed Brown next->set = PETSC_TRUE; 444d25d7f95SJed Brown *((PetscInt *)next->data) = (PetscInt)lid; 445aee2cecaSBarry Smith } 446aee2cecaSBarry Smith break; 447aee2cecaSBarry Smith case OPTION_REAL: 4484bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%g>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(double *)next->data, next->text, next->man)); 4499566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4503fc1eb6aSBarry Smith if (str[0]) { 451ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 452a4404d99SBarry Smith sscanf(str, "%e", &ir); 453570b7f6dSBarry Smith #elif defined(PETSC_USE_REAL___FP16) 454570b7f6dSBarry Smith float irtemp; 455570b7f6dSBarry Smith sscanf(str, "%e", &irtemp); 456570b7f6dSBarry Smith ir = irtemp; 457ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE) 458aee2cecaSBarry Smith sscanf(str, "%le", &ir); 459ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128) 460d9822059SBarry Smith ir = strtoflt128(str, 0); 461d9822059SBarry Smith #else 462513dbe71SLisandro Dalcin SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type"); 463a4404d99SBarry Smith #endif 464aee2cecaSBarry Smith next->set = PETSC_TRUE; 465aee2cecaSBarry Smith *((PetscReal *)next->data) = ir; 466aee2cecaSBarry Smith } 467aee2cecaSBarry Smith break; 4687781c08eSBarry Smith case OPTION_BOOL: 4694bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, *(PetscBool *)next->data ? "true" : "false", next->text, next->man)); 4709566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4717781c08eSBarry Smith if (str[0]) { 4729566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToBool(str, &bid)); 4737781c08eSBarry Smith next->set = PETSC_TRUE; 4747781c08eSBarry Smith *((PetscBool *)next->data) = bid; 4757781c08eSBarry Smith } 4767781c08eSBarry Smith break; 477aee2cecaSBarry Smith case OPTION_STRING: 4784bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <%s>: %s (%s) ", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, (char *)next->data, next->text, next->man)); 4799566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4803fc1eb6aSBarry Smith if (str[0]) { 481aee2cecaSBarry Smith next->set = PETSC_TRUE; 48264facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 4839566063dSJacob Faibussowitsch PetscCall(PetscStrdup(str, (char **)&next->data)); 4846356e834SBarry Smith } 4856356e834SBarry Smith break; 486a264d7a6SBarry Smith case OPTION_FLIST: 4879566063dSJacob Faibussowitsch PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data)); 4889566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4893cc1e11dSBarry Smith if (str[0]) { 490e55864a3SBarry Smith PetscOptionsObject->changedmethod = PETSC_TRUE; 4913cc1e11dSBarry Smith next->set = PETSC_TRUE; 49264facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 4939566063dSJacob Faibussowitsch PetscCall(PetscStrdup(str, (char **)&next->data)); 4943cc1e11dSBarry Smith } 4953cc1e11dSBarry Smith break; 496d71ae5a4SJacob Faibussowitsch default: 497d71ae5a4SJacob Faibussowitsch break; 4986356e834SBarry Smith } 4996356e834SBarry Smith next = next->next; 5006356e834SBarry Smith } 5013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5026356e834SBarry Smith } 503b3506946SBarry Smith #endif 504b3506946SBarry Smith 505d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject) 506d71ae5a4SJacob Faibussowitsch { 50710c654e6SJacob Faibussowitsch PetscOptionItem next, last; 50853acd3b1SBarry Smith 50953acd3b1SBarry Smith PetscFunctionBegin; 51083355fc5SBarry Smith if (PetscOptionsObject->next) { 51183355fc5SBarry Smith if (!PetscOptionsObject->count) { 512a264d7a6SBarry Smith #if defined(PETSC_HAVE_SAWS) 5139566063dSJacob Faibussowitsch PetscCall(PetscOptionsSAWsInput(PetscOptionsObject)); 514b3506946SBarry Smith #else 5159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject)); 516b3506946SBarry Smith #endif 517aee2cecaSBarry Smith } 518aee2cecaSBarry Smith } 5196356e834SBarry Smith 5209566063dSJacob Faibussowitsch PetscCall(PetscFree(PetscOptionsObject->title)); 5216356e834SBarry Smith 522e26ddf31SBarry Smith /* reset counter to -2; this updates the screen with the new options for the selected method */ 523e55864a3SBarry Smith if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2; 5247a72a596SBarry Smith /* reset alreadyprinted flag */ 525e55864a3SBarry Smith PetscOptionsObject->alreadyprinted = PETSC_FALSE; 526e55864a3SBarry Smith if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE; 527e55864a3SBarry Smith PetscOptionsObject->object = NULL; 52853acd3b1SBarry Smith 52910c654e6SJacob Faibussowitsch while ((next = PetscOptionsObject->next)) { 53010c654e6SJacob Faibussowitsch const PetscOptionType type = next->type; 53110c654e6SJacob Faibussowitsch const size_t arraylength = next->arraylength; 53210c654e6SJacob Faibussowitsch void *data = next->data; 53310c654e6SJacob Faibussowitsch 53410c654e6SJacob Faibussowitsch if (next->set) { 53510c654e6SJacob Faibussowitsch char option[256], value[1024], tmp[32]; 53610c654e6SJacob Faibussowitsch 537e55864a3SBarry Smith if (PetscOptionsObject->prefix) { 538c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(option, "-", sizeof(option))); 539c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option))); 54010c654e6SJacob Faibussowitsch PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option))); 54110c654e6SJacob Faibussowitsch } else { 54210c654e6SJacob Faibussowitsch PetscCall(PetscStrncpy(option, next->option, sizeof(option))); 54310c654e6SJacob Faibussowitsch } 5446356e834SBarry Smith 54510c654e6SJacob Faibussowitsch switch (type) { 546d71ae5a4SJacob Faibussowitsch case OPTION_HEAD: 547d71ae5a4SJacob Faibussowitsch break; 5486356e834SBarry Smith case OPTION_INT_ARRAY: 54910c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscInt *)data)[0])); 55010c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 55110c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscInt *)data)[j])); 552c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 553c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5546356e834SBarry Smith } 5556356e834SBarry Smith break; 556d71ae5a4SJacob Faibussowitsch case OPTION_INT: 55710c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)*(PetscInt *)data)); 558d71ae5a4SJacob Faibussowitsch break; 559d71ae5a4SJacob Faibussowitsch case OPTION_REAL: 56010c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data)); 561d71ae5a4SJacob Faibussowitsch break; 5626356e834SBarry Smith case OPTION_REAL_ARRAY: 56310c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0])); 56410c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 56510c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j])); 566c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 567c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5686356e834SBarry Smith } 5696356e834SBarry Smith break; 570050cccc3SHong Zhang case OPTION_SCALAR_ARRAY: 57110c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0]))); 57210c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 57310c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j]))); 574c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 575c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 576050cccc3SHong Zhang } 577050cccc3SHong Zhang break; 578d71ae5a4SJacob Faibussowitsch case OPTION_BOOL: 57910c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data)); 580d71ae5a4SJacob Faibussowitsch break; 5817781c08eSBarry Smith case OPTION_BOOL_ARRAY: 58210c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0])); 58310c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 58410c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j])); 585c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 586c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5871ae3d29cSBarry Smith } 5881ae3d29cSBarry Smith break; 58910c654e6SJacob Faibussowitsch case OPTION_FLIST: // fall-through 59010c654e6SJacob Faibussowitsch case OPTION_ELIST: // fall-through 591d71ae5a4SJacob Faibussowitsch case OPTION_STRING: 59210c654e6SJacob Faibussowitsch PetscCall(PetscStrncpy(value, (char *)data, sizeof(value))); 593d71ae5a4SJacob Faibussowitsch break; 5941ae3d29cSBarry Smith case OPTION_STRING_ARRAY: 59510c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0])); 59610c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; j++) { 59710c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j])); 598c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 599c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 6001ae3d29cSBarry Smith } 6016356e834SBarry Smith break; 6026356e834SBarry Smith } 6039566063dSJacob Faibussowitsch PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value)); 6046356e834SBarry Smith } 60510c654e6SJacob Faibussowitsch if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list)); 60610c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->text)); 60710c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->option)); 60810c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->man)); 60910c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->edata)); 610c979a496SBarry Smith 61110c654e6SJacob Faibussowitsch if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) { 61210c654e6SJacob Faibussowitsch free(data); 613c979a496SBarry Smith } else { 61410c654e6SJacob Faibussowitsch // use next->data instead of data because PetscFree() sets it to NULL 61510c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->data)); 616c979a496SBarry Smith } 6177781c08eSBarry Smith 61810c654e6SJacob Faibussowitsch last = next; 61910c654e6SJacob Faibussowitsch PetscOptionsObject->next = next->next; 6209566063dSJacob Faibussowitsch PetscCall(PetscFree(last)); 6216356e834SBarry Smith } 6229566063dSJacob Faibussowitsch PetscCall(PetscFree(PetscOptionsObject->prefix)); 62302c9f0b5SLisandro Dalcin PetscOptionsObject->next = NULL; 6243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62553acd3b1SBarry Smith } 62653acd3b1SBarry Smith 62710c654e6SJacob Faibussowitsch static PetscErrorCode GetListLength(const char *const *list, PetscInt *len) 62810c654e6SJacob Faibussowitsch { 62910c654e6SJacob Faibussowitsch PetscInt retlen = 0; 63010c654e6SJacob Faibussowitsch 63110c654e6SJacob Faibussowitsch PetscFunctionBegin; 6324f572ea9SToby Isaac PetscAssertPointer(len, 2); 63310c654e6SJacob Faibussowitsch while (list[retlen]) { 6344f572ea9SToby Isaac PetscAssertPointer(list[retlen], 1); 63510c654e6SJacob Faibussowitsch PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries"); 63610c654e6SJacob Faibussowitsch } 63710c654e6SJacob Faibussowitsch PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix"); 63810c654e6SJacob Faibussowitsch /* drop item name and prefix*/ 63910c654e6SJacob Faibussowitsch *len = retlen - 2; 64010c654e6SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 64110c654e6SJacob Faibussowitsch } 64210c654e6SJacob Faibussowitsch 643d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set) 644d71ae5a4SJacob Faibussowitsch { 64553acd3b1SBarry Smith PetscInt ntext = 0; 646aa5bb8c0SSatish Balay PetscInt tval; 647ace3abfcSBarry Smith PetscBool tflg; 64853acd3b1SBarry Smith 64953acd3b1SBarry Smith PetscFunctionBegin; 6504f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6514f572ea9SToby Isaac PetscAssertPointer(list, 5); 6524f572ea9SToby Isaac PetscAssertPointer(value, 7); 6534f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 65410c654e6SJacob Faibussowitsch PetscCall(GetListLength(list, &ntext)); 6559566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[currentvalue], &tval, &tflg)); 656aa5bb8c0SSatish Balay /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */ 657aa5bb8c0SSatish Balay if (tflg) *value = (PetscEnum)tval; 658aa5bb8c0SSatish Balay if (set) *set = tflg; 6593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66053acd3b1SBarry Smith } 66153acd3b1SBarry Smith 662d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set) 663d71ae5a4SJacob Faibussowitsch { 66410c654e6SJacob Faibussowitsch PetscInt nlist = 0; 66510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 666d3e47460SLisandro Dalcin 667d3e47460SLisandro Dalcin PetscFunctionBegin; 6684f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6694f572ea9SToby Isaac PetscAssertPointer(list, 5); 6704f572ea9SToby Isaac PetscAssertPointer(value, 6); 6714f572ea9SToby Isaac PetscAssertPointer(n, 7); 67210c654e6SJacob Faibussowitsch PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n); 6734f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 67410c654e6SJacob Faibussowitsch PetscCall(GetListLength(list, &nlist)); 67510c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set)); 67610c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 67710c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 67810c654e6SJacob Faibussowitsch const PetscInt nv = *n; 67910c654e6SJacob Faibussowitsch 68010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]])); 68110c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]])); 68210c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text)); 68310c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i])); 68410c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man))); 685d3e47460SLisandro Dalcin } 6863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 687d3e47460SLisandro Dalcin } 688d3e47460SLisandro Dalcin 689d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsInt_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set, PetscInt lb, PetscInt ub) 690d71ae5a4SJacob Faibussowitsch { 69110c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 69210c654e6SJacob Faibussowitsch const PetscOptions options = PetscOptionsObject->options; 69312655325SBarry Smith PetscBool wasset; 69453acd3b1SBarry Smith 69553acd3b1SBarry Smith PetscFunctionBegin; 6964f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6974f572ea9SToby Isaac PetscAssertPointer(value, 6); 6984f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 69908401ef6SPierre Jolivet PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb); 70008401ef6SPierre Jolivet PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub); 701e55864a3SBarry Smith if (!PetscOptionsObject->count) { 70210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 70310c654e6SJacob Faibussowitsch 7049566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt)); 7059566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data)); 70612655325SBarry Smith *(PetscInt *)amsopt->data = currentvalue; 7073e211508SBarry Smith 70810c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetInt(options, prefix, opt, ¤tvalue, &wasset)); 709ad540459SPierre Jolivet if (wasset) *(PetscInt *)amsopt->data = currentvalue; 710af6d86caSBarry Smith } 71110c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset)); 712cc73adaaSBarry Smith PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, *value, lb); 713cc73adaaSBarry Smith PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, *value, ub); 71444ef3d73SBarry Smith if (set) *set = wasset; 71510c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 71610c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %" PetscInt_FMT " : formerly %" PetscInt_FMT ">: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? *value : currentvalue, currentvalue, text, ManSection(man))); 71753acd3b1SBarry Smith } 7183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71953acd3b1SBarry Smith } 72053acd3b1SBarry Smith 721d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsString_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set) 722d71ae5a4SJacob Faibussowitsch { 72310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 72444ef3d73SBarry Smith PetscBool lset; 72553acd3b1SBarry Smith 72653acd3b1SBarry Smith PetscFunctionBegin; 7274f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7284f572ea9SToby Isaac PetscAssertPointer(value, 6); 7294f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 7301a1499c8SBarry Smith if (!PetscOptionsObject->count) { 73110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 73210c654e6SJacob Faibussowitsch 7339566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 73464facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 7359566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 736af6d86caSBarry Smith } 73710c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 73844ef3d73SBarry Smith if (set) *set = lset; 73910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %s : formerly %s>: %s (%s)\n", Prefix(prefix), opt + 1, lset ? value : currentvalue, currentvalue, text, ManSection(man))); 7403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 74153acd3b1SBarry Smith } 74253acd3b1SBarry Smith 74352ce0ab5SPierre Jolivet PetscErrorCode PetscOptionsReal_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set, PetscReal lb, PetscReal ub) 744d71ae5a4SJacob Faibussowitsch { 74510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 74652ce0ab5SPierre Jolivet const PetscOptions options = PetscOptionsObject->options; 74752ce0ab5SPierre Jolivet PetscBool wasset; 74853acd3b1SBarry Smith 74953acd3b1SBarry Smith PetscFunctionBegin; 7504f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7514f572ea9SToby Isaac PetscAssertPointer(value, 6); 7524f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 75352ce0ab5SPierre Jolivet PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb); 75452ce0ab5SPierre Jolivet PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub); 755e55864a3SBarry Smith if (!PetscOptionsObject->count) { 75610c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 75710c654e6SJacob Faibussowitsch 7589566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt)); 7599566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data)); 7600fdccdaeSBarry Smith *(PetscReal *)amsopt->data = currentvalue; 76152ce0ab5SPierre Jolivet 76252ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(options, prefix, opt, ¤tvalue, &wasset)); 76352ce0ab5SPierre Jolivet if (wasset) *(PetscReal *)amsopt->data = currentvalue; 764538aa990SBarry Smith } 76552ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset)); 76652ce0ab5SPierre Jolivet PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %g less than allowed bound %g", (double)*value, (double)lb); 76752ce0ab5SPierre Jolivet PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %g greater than allowed bound %g", (double)*value, (double)ub); 76852ce0ab5SPierre Jolivet if (set) *set = wasset; 76910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 77052ce0ab5SPierre Jolivet PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %g : formerly %g>: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? (double)*value : (double)currentvalue, (double)currentvalue, text, ManSection(man))); 77153acd3b1SBarry Smith } 7723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77353acd3b1SBarry Smith } 77453acd3b1SBarry Smith 775d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set) 776d71ae5a4SJacob Faibussowitsch { 77753acd3b1SBarry Smith PetscFunctionBegin; 77853acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX) 7799566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set)); 78053acd3b1SBarry Smith #else 7819566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set)); 78253acd3b1SBarry Smith #endif 7833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 78453acd3b1SBarry Smith } 78553acd3b1SBarry Smith 786d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 787d71ae5a4SJacob Faibussowitsch { 78810c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 78953acd3b1SBarry Smith 79053acd3b1SBarry Smith PetscFunctionBegin; 7914f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7924f572ea9SToby Isaac PetscAssertPointer(flg, 5); 793e55864a3SBarry Smith if (!PetscOptionsObject->count) { 79410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 79510c654e6SJacob Faibussowitsch 7969566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 7979566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 798a297a907SKarl Rupp 799ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 8001ae3d29cSBarry Smith } 80110c654e6SJacob Faibussowitsch PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg)); 80210c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 8033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80453acd3b1SBarry Smith } 80553acd3b1SBarry Smith 806d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsFList_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char ltext[], const char man[], PetscFunctionList list, const char currentvalue[], char value[], size_t len, PetscBool *set) 807d71ae5a4SJacob Faibussowitsch { 80810c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 80944ef3d73SBarry Smith PetscBool lset; 81053acd3b1SBarry Smith 81153acd3b1SBarry Smith PetscFunctionBegin; 8124f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8134f572ea9SToby Isaac PetscAssertPointer(value, 7); 8144f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8151a1499c8SBarry Smith if (!PetscOptionsObject->count) { 81610c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 81710c654e6SJacob Faibussowitsch 8189566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt)); 81964facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8209566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8213cc1e11dSBarry Smith amsopt->flist = list; 8223cc1e11dSBarry Smith } 82310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 82444ef3d73SBarry Smith if (set) *set = lset; 82510c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue)); 8263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82753acd3b1SBarry Smith } 82853acd3b1SBarry Smith 82910c654e6SJacob Faibussowitsch #ifdef __cplusplus 83010c654e6SJacob Faibussowitsch #include <type_traits> 83110c654e6SJacob Faibussowitsch #endif 83210c654e6SJacob Faibussowitsch 833d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEList_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char ltext[], const char man[], const char *const *list, PetscInt ntext, const char currentvalue[], PetscInt *value, PetscBool *set) 834d71ae5a4SJacob Faibussowitsch { 83510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 83644ef3d73SBarry Smith PetscBool lset; 83753acd3b1SBarry Smith 83853acd3b1SBarry Smith PetscFunctionBegin; 8394f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8404f572ea9SToby Isaac PetscAssertPointer(value, 8); 8414f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8421a1499c8SBarry Smith if (!PetscOptionsObject->count) { 84310c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 84410c654e6SJacob Faibussowitsch 8459566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt)); 84664facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8479566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8489566063dSJacob Faibussowitsch PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list)); 84910c654e6SJacob Faibussowitsch PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX); 85010c654e6SJacob Faibussowitsch #ifdef __cplusplus 85110c654e6SJacob Faibussowitsch static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, ""); 85210c654e6SJacob Faibussowitsch #endif 85310c654e6SJacob Faibussowitsch amsopt->nlist = (char)ntext; 8541ae3d29cSBarry Smith } 85510c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset)); 85644ef3d73SBarry Smith if (set) *set = lset; 85710c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 85810c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 85910c654e6SJacob Faibussowitsch 86010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext)); 86110c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i])); 86210c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man))); 86353acd3b1SBarry Smith } 8643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86553acd3b1SBarry Smith } 86653acd3b1SBarry Smith 867d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 868d71ae5a4SJacob Faibussowitsch { 86910c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 87053acd3b1SBarry Smith 87153acd3b1SBarry Smith PetscFunctionBegin; 8724f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8734f572ea9SToby Isaac PetscAssertPointer(flg, 5); 874e55864a3SBarry Smith if (!PetscOptionsObject->count) { 87510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 87610c654e6SJacob Faibussowitsch 8779566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 8789566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 879a297a907SKarl Rupp 880ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 8811ae3d29cSBarry Smith } 88268b16fdaSBarry Smith *flg = PETSC_FALSE; 88310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 88410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 88510c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 88610c654e6SJacob Faibussowitsch 88710c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " Pick at most one of -------------\n")); 88810c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 88953acd3b1SBarry Smith } 8903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89153acd3b1SBarry Smith } 89253acd3b1SBarry Smith 893d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 894d71ae5a4SJacob Faibussowitsch { 89510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 89653acd3b1SBarry Smith 89753acd3b1SBarry Smith PetscFunctionBegin; 8984f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8994f572ea9SToby Isaac PetscAssertPointer(flg, 5); 900e55864a3SBarry Smith if (!PetscOptionsObject->count) { 90110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 90210c654e6SJacob Faibussowitsch 9039566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9049566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 905a297a907SKarl Rupp 906ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9071ae3d29cSBarry Smith } 90817326d04SJed Brown *flg = PETSC_FALSE; 90910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 91010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91253acd3b1SBarry Smith } 91353acd3b1SBarry Smith 914d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 915d71ae5a4SJacob Faibussowitsch { 91610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 91753acd3b1SBarry Smith 91853acd3b1SBarry Smith PetscFunctionBegin; 9194f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9204f572ea9SToby Isaac PetscAssertPointer(flg, 5); 921e55864a3SBarry Smith if (!PetscOptionsObject->count) { 92210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 92310c654e6SJacob Faibussowitsch 9249566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9259566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 926a297a907SKarl Rupp 927ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9281ae3d29cSBarry Smith } 92917326d04SJed Brown *flg = PETSC_FALSE; 93010c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 93110c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 93353acd3b1SBarry Smith } 93453acd3b1SBarry Smith 935d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set) 936d71ae5a4SJacob Faibussowitsch { 93710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 938ace3abfcSBarry Smith PetscBool iset; 93953acd3b1SBarry Smith 94053acd3b1SBarry Smith PetscFunctionBegin; 9414f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9424f572ea9SToby Isaac PetscAssertPointer(flg, 6); 9434f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 944e55864a3SBarry Smith if (!PetscOptionsObject->count) { 94510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 94610c654e6SJacob Faibussowitsch 9479566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9489566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 949a297a907SKarl Rupp 95094ae4db5SBarry Smith *(PetscBool *)amsopt->data = currentvalue; 951af6d86caSBarry Smith } 95210c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset)); 95353acd3b1SBarry Smith if (set) *set = iset; 95410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 95510c654e6SJacob Faibussowitsch const char *curvalue = PetscBools[currentvalue]; 95610c654e6SJacob Faibussowitsch 95710c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %s : formerly %s> %s (%s)\n", Prefix(prefix), opt + 1, iset ? PetscBools[*flg] : curvalue, curvalue, text, ManSection(man))); 95853acd3b1SBarry Smith } 9593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 96053acd3b1SBarry Smith } 96153acd3b1SBarry Smith 962d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set) 963d71ae5a4SJacob Faibussowitsch { 96410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 96553acd3b1SBarry Smith 96653acd3b1SBarry Smith PetscFunctionBegin; 9674f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9684f572ea9SToby Isaac PetscAssertPointer(n, 6); 96910c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 9704f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 9714f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 972e55864a3SBarry Smith if (!PetscOptionsObject->count) { 97310c654e6SJacob Faibussowitsch const PetscInt nv = *n; 974e26ddf31SBarry Smith PetscReal *vals; 97510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 976e26ddf31SBarry Smith 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt)); 97810c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 97910c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 98010c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 98110c654e6SJacob Faibussowitsch amsopt->data = vals; 982e26ddf31SBarry Smith } 98310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 98410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 98510c654e6SJacob Faibussowitsch const PetscInt nv = *n; 98610c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 98710c654e6SJacob Faibussowitsch 98810c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0])); 98910c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i])); 99010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 99153acd3b1SBarry Smith } 9923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99353acd3b1SBarry Smith } 99453acd3b1SBarry Smith 995d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set) 996d71ae5a4SJacob Faibussowitsch { 99710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 998050cccc3SHong Zhang 999050cccc3SHong Zhang PetscFunctionBegin; 10004f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10014f572ea9SToby Isaac PetscAssertPointer(n, 6); 100210c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10034f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10044f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1005050cccc3SHong Zhang if (!PetscOptionsObject->count) { 100610c654e6SJacob Faibussowitsch const PetscInt nv = *n; 100710c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1008050cccc3SHong Zhang PetscScalar *vals; 1009050cccc3SHong Zhang 10109566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt)); 101110c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 101210c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 101310c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 101410c654e6SJacob Faibussowitsch amsopt->data = vals; 1015050cccc3SHong Zhang } 101610c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 101710c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 101810c654e6SJacob Faibussowitsch const PetscInt nv = *n; 101910c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 102010c654e6SJacob Faibussowitsch 102110c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0]))); 102210c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i]))); 102310c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1024050cccc3SHong Zhang } 10253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1026050cccc3SHong Zhang } 102753acd3b1SBarry Smith 1028d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set) 1029d71ae5a4SJacob Faibussowitsch { 103010c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 103153acd3b1SBarry Smith 103253acd3b1SBarry Smith PetscFunctionBegin; 10334f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10344f572ea9SToby Isaac PetscAssertPointer(n, 6); 103510c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10364f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10374f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1038e55864a3SBarry Smith if (!PetscOptionsObject->count) { 103910c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1040e26ddf31SBarry Smith PetscInt *vals; 104110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1042e26ddf31SBarry Smith 10439566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt)); 104410c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 104510c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 104610c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 104710c654e6SJacob Faibussowitsch amsopt->data = vals; 1048e26ddf31SBarry Smith } 104910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 105010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 105110c654e6SJacob Faibussowitsch const PetscInt nv = *n; 105210c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 105310c654e6SJacob Faibussowitsch 105410c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0])); 105510c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i])); 105610c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 105753acd3b1SBarry Smith } 10583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 105953acd3b1SBarry Smith } 106053acd3b1SBarry Smith 1061d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set) 1062d71ae5a4SJacob Faibussowitsch { 106310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 106453acd3b1SBarry Smith 106553acd3b1SBarry Smith PetscFunctionBegin; 10664f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10674f572ea9SToby Isaac PetscAssertPointer(nmax, 6); 106810c654e6SJacob Faibussowitsch PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax); 10694f572ea9SToby Isaac if (*nmax) PetscAssertPointer(value, 5); 10704f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1071e55864a3SBarry Smith if (!PetscOptionsObject->count) { 107210c654e6SJacob Faibussowitsch const PetscInt nmaxv = *nmax; 107310c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1074a297a907SKarl Rupp 107510c654e6SJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt)); 107610c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data)); 107710c654e6SJacob Faibussowitsch amsopt->arraylength = nmaxv; 10781ae3d29cSBarry Smith } 107910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set)); 108010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 10813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 108253acd3b1SBarry Smith } 108353acd3b1SBarry Smith 1084d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set) 1085d71ae5a4SJacob Faibussowitsch { 108610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 1087e2446a98SMatthew Knepley 1088e2446a98SMatthew Knepley PetscFunctionBegin; 10894f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10904f572ea9SToby Isaac PetscAssertPointer(n, 6); 109110c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10924f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10934f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1094e55864a3SBarry Smith if (!PetscOptionsObject->count) { 109510c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1096ace3abfcSBarry Smith PetscBool *vals; 109710c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 10981ae3d29cSBarry Smith 10999566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt)); 110010c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 110110c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 110210c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 110310c654e6SJacob Faibussowitsch amsopt->data = vals; 11041ae3d29cSBarry Smith } 110510c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 110610c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 110710c654e6SJacob Faibussowitsch const PetscInt nv = *n; 110810c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 110910c654e6SJacob Faibussowitsch 111010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%d", Prefix(prefix), opt + 1, value[0])); 111110c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i])); 111210c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1113e2446a98SMatthew Knepley } 11143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1115e2446a98SMatthew Knepley } 1116e2446a98SMatthew Knepley 111788aa4217SBarry Smith /*MC 1118*648c30bcSBarry Smith PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user 11198cc676e6SMatthew G Knepley 112088aa4217SBarry Smith Synopsis: 112110450e9eSJacob Faibussowitsch #include <petscviewer.h> 11223a89f35bSSatish Balay PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 112388aa4217SBarry Smith 11247cdbe19fSJose E. Roman Logically Collective on the communicator passed in `PetscOptionsBegin()` 11257cdbe19fSJose E. Roman 11268cc676e6SMatthew G Knepley Input Parameters: 11278cc676e6SMatthew G Knepley + opt - option name 11288cc676e6SMatthew G Knepley . text - short string that describes the option 11298cc676e6SMatthew G Knepley - man - manual page with additional information on option 11308cc676e6SMatthew G Knepley 1131d8d19677SJose E. Roman Output Parameters: 11328cc676e6SMatthew G Knepley + viewer - the viewer 11339314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed 1134811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE` 11358cc676e6SMatthew G Knepley 11368cc676e6SMatthew G Knepley Level: beginner 11378cc676e6SMatthew G Knepley 113895452b02SPatrick Sanan Notes: 1139811af0c4SBarry Smith Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()` 11408cc676e6SMatthew G Knepley 1141*648c30bcSBarry Smith See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options 11428cc676e6SMatthew G Knepley 1143*648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`, 1144db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 1145aec76313SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 1146db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 1147c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 1148db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 1149db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 115088aa4217SBarry Smith M*/ 1151d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 1152d71ae5a4SJacob Faibussowitsch { 115310c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 115410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 11558cc676e6SMatthew G Knepley 11568cc676e6SMatthew G Knepley PetscFunctionBegin; 11574f572ea9SToby Isaac PetscAssertPointer(opt, 2); 11584f572ea9SToby Isaac PetscAssertPointer(viewer, 5); 11594f572ea9SToby Isaac if (format) PetscAssertPointer(format, 6); 11604f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 11611a1499c8SBarry Smith if (!PetscOptionsObject->count) { 116210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 116310c654e6SJacob Faibussowitsch 11649566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 116564facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 11669566063dSJacob Faibussowitsch PetscCall(PetscStrdup("", (char **)&amsopt->data)); 11678cc676e6SMatthew G Knepley } 1168*648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set)); 116910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man))); 11703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11718cc676e6SMatthew G Knepley } 1172