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)); 239*57508eceSPierre Jolivet 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; 3376356e834SBarry Smith 3382a409bb0SBarry Smith PetscFunctionBegin; 3399566063dSJacob Faibussowitsch PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title)); 3406356e834SBarry Smith while (next) { 3416356e834SBarry Smith switch (next->type) { 342d71ae5a4SJacob Faibussowitsch case OPTION_HEAD: 343d71ae5a4SJacob Faibussowitsch break; 344e26ddf31SBarry Smith case OPTION_INT_ARRAY: 3454bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1)); 346e26ddf31SBarry Smith vald = (PetscInt *)next->data; 3476497c311SBarry Smith for (PetscInt i = 0; i < next->arraylength; i++) { 3489566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i])); 34948a46eb9SPierre Jolivet if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ",")); 350e26ddf31SBarry Smith } 3519566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man)); 3529566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 353e26ddf31SBarry Smith if (str[0]) { 354e26ddf31SBarry Smith PetscToken token; 355e26ddf31SBarry Smith PetscInt n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end; 356dd460d27SBarry Smith size_t i, len; 357e26ddf31SBarry Smith char *value; 358ace3abfcSBarry Smith PetscBool foundrange; 359e26ddf31SBarry Smith 360e26ddf31SBarry Smith next->set = PETSC_TRUE; 361e26ddf31SBarry Smith value = str; 3629566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(value, ',', &token)); 3639566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 364e26ddf31SBarry Smith while (n < nmax) { 365e26ddf31SBarry Smith if (!value) break; 366e26ddf31SBarry Smith 367e26ddf31SBarry Smith /* look for form d-D where d and D are integers */ 368e26ddf31SBarry Smith foundrange = PETSC_FALSE; 3699566063dSJacob Faibussowitsch PetscCall(PetscStrlen(value, &len)); 370e26ddf31SBarry Smith if (value[0] == '-') i = 2; 371e26ddf31SBarry Smith else i = 1; 372dd460d27SBarry Smith for (; i < len; i++) { 373e26ddf31SBarry Smith if (value[i] == '-') { 374dd460d27SBarry Smith PetscCheck(i != len - 1, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, value); 375e26ddf31SBarry Smith value[i] = 0; 3769566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToInt(value, &start)); 3779566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToInt(value + i + 1, &end)); 37808401ef6SPierre 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); 379cc73adaaSBarry 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); 380e26ddf31SBarry Smith for (; start < end; start++) { 3819371c9d4SSatish Balay *dvalue = start; 3829371c9d4SSatish Balay dvalue++; 3839371c9d4SSatish Balay n++; 384e26ddf31SBarry Smith } 385e26ddf31SBarry Smith foundrange = PETSC_TRUE; 386e26ddf31SBarry Smith break; 387e26ddf31SBarry Smith } 388e26ddf31SBarry Smith } 389e26ddf31SBarry Smith if (!foundrange) { 3909566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToInt(value, dvalue)); 391e26ddf31SBarry Smith dvalue++; 392e26ddf31SBarry Smith n++; 393e26ddf31SBarry Smith } 3949566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 395e26ddf31SBarry Smith } 3969566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 397e26ddf31SBarry Smith } 398e26ddf31SBarry Smith break; 399e26ddf31SBarry Smith case OPTION_REAL_ARRAY: 4004bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1)); 401e26ddf31SBarry Smith valr = (PetscReal *)next->data; 4026497c311SBarry Smith for (PetscInt i = 0; i < next->arraylength; i++) { 4039566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i])); 40448a46eb9SPierre Jolivet if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ",")); 405e26ddf31SBarry Smith } 4069566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man)); 4079566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 408e26ddf31SBarry Smith if (str[0]) { 409e26ddf31SBarry Smith PetscToken token; 410e26ddf31SBarry Smith PetscInt n = 0, nmax = next->arraylength; 411e26ddf31SBarry Smith PetscReal *dvalue = (PetscReal *)next->data; 412e26ddf31SBarry Smith char *value; 413e26ddf31SBarry Smith 414e26ddf31SBarry Smith next->set = PETSC_TRUE; 415e26ddf31SBarry Smith value = str; 4169566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(value, ',', &token)); 4179566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 418e26ddf31SBarry Smith while (n < nmax) { 419e26ddf31SBarry Smith if (!value) break; 4209566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToReal(value, dvalue)); 421e26ddf31SBarry Smith dvalue++; 422e26ddf31SBarry Smith n++; 4239566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 424e26ddf31SBarry Smith } 4259566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 426e26ddf31SBarry Smith } 427e26ddf31SBarry Smith break; 4286356e834SBarry Smith case OPTION_INT: 4294bb2516aSBarry 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)); 4309566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4313fc1eb6aSBarry Smith if (str[0]) { 432d25d7f95SJed Brown #if defined(PETSC_SIZEOF_LONG_LONG) 433d25d7f95SJed Brown long long lid; 434d25d7f95SJed Brown sscanf(str, "%lld", &lid); 4351690c2aeSBarry Smith PetscCheck(lid <= PETSC_INT_MAX && lid >= PETSC_INT_MIN, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %lld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid); 436c272547aSJed Brown #else 437d25d7f95SJed Brown long lid; 438d25d7f95SJed Brown sscanf(str, "%ld", &lid); 4391690c2aeSBarry Smith PetscCheck(lid <= PETSC_INT_MAX && lid >= PETSC_INT_MIN, PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE, "Argument: -%s%s %ld", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1, lid); 440c272547aSJed Brown #endif 441a297a907SKarl Rupp 442d25d7f95SJed Brown next->set = PETSC_TRUE; 443d25d7f95SJed Brown *((PetscInt *)next->data) = (PetscInt)lid; 444aee2cecaSBarry Smith } 445aee2cecaSBarry Smith break; 446aee2cecaSBarry Smith case OPTION_REAL: 4474bb2516aSBarry 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)); 4489566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4493fc1eb6aSBarry Smith if (str[0]) { 450ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 451a4404d99SBarry Smith sscanf(str, "%e", &ir); 452570b7f6dSBarry Smith #elif defined(PETSC_USE_REAL___FP16) 453570b7f6dSBarry Smith float irtemp; 454570b7f6dSBarry Smith sscanf(str, "%e", &irtemp); 455570b7f6dSBarry Smith ir = irtemp; 456ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE) 457aee2cecaSBarry Smith sscanf(str, "%le", &ir); 458ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128) 459d9822059SBarry Smith ir = strtoflt128(str, 0); 460d9822059SBarry Smith #else 461513dbe71SLisandro Dalcin SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type"); 462a4404d99SBarry Smith #endif 463aee2cecaSBarry Smith next->set = PETSC_TRUE; 464aee2cecaSBarry Smith *((PetscReal *)next->data) = ir; 465aee2cecaSBarry Smith } 466aee2cecaSBarry Smith break; 4677781c08eSBarry Smith case OPTION_BOOL: 4684bb2516aSBarry 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)); 4699566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4707781c08eSBarry Smith if (str[0]) { 4719566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToBool(str, &bid)); 4727781c08eSBarry Smith next->set = PETSC_TRUE; 4737781c08eSBarry Smith *((PetscBool *)next->data) = bid; 4747781c08eSBarry Smith } 4757781c08eSBarry Smith break; 476aee2cecaSBarry Smith case OPTION_STRING: 4774bb2516aSBarry 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)); 4789566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4793fc1eb6aSBarry Smith if (str[0]) { 480aee2cecaSBarry Smith next->set = PETSC_TRUE; 48164facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 4829566063dSJacob Faibussowitsch PetscCall(PetscStrdup(str, (char **)&next->data)); 4836356e834SBarry Smith } 4846356e834SBarry Smith break; 485a264d7a6SBarry Smith case OPTION_FLIST: 4869566063dSJacob Faibussowitsch PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data)); 4879566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4883cc1e11dSBarry Smith if (str[0]) { 489e55864a3SBarry Smith PetscOptionsObject->changedmethod = PETSC_TRUE; 4903cc1e11dSBarry Smith next->set = PETSC_TRUE; 49164facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 4929566063dSJacob Faibussowitsch PetscCall(PetscStrdup(str, (char **)&next->data)); 4933cc1e11dSBarry Smith } 4943cc1e11dSBarry Smith break; 495d71ae5a4SJacob Faibussowitsch default: 496d71ae5a4SJacob Faibussowitsch break; 4976356e834SBarry Smith } 4986356e834SBarry Smith next = next->next; 4996356e834SBarry Smith } 5003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5016356e834SBarry Smith } 502b3506946SBarry Smith #endif 503b3506946SBarry Smith 504d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems *PetscOptionsObject) 505d71ae5a4SJacob Faibussowitsch { 50610c654e6SJacob Faibussowitsch PetscOptionItem next, last; 50753acd3b1SBarry Smith 50853acd3b1SBarry Smith PetscFunctionBegin; 50983355fc5SBarry Smith if (PetscOptionsObject->next) { 51083355fc5SBarry Smith if (!PetscOptionsObject->count) { 511a264d7a6SBarry Smith #if defined(PETSC_HAVE_SAWS) 5129566063dSJacob Faibussowitsch PetscCall(PetscOptionsSAWsInput(PetscOptionsObject)); 513b3506946SBarry Smith #else 5149566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject)); 515b3506946SBarry Smith #endif 516aee2cecaSBarry Smith } 517aee2cecaSBarry Smith } 5186356e834SBarry Smith 5199566063dSJacob Faibussowitsch PetscCall(PetscFree(PetscOptionsObject->title)); 5206356e834SBarry Smith 521e26ddf31SBarry Smith /* reset counter to -2; this updates the screen with the new options for the selected method */ 522e55864a3SBarry Smith if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2; 5237a72a596SBarry Smith /* reset alreadyprinted flag */ 524e55864a3SBarry Smith PetscOptionsObject->alreadyprinted = PETSC_FALSE; 525e55864a3SBarry Smith if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE; 526e55864a3SBarry Smith PetscOptionsObject->object = NULL; 52753acd3b1SBarry Smith 52810c654e6SJacob Faibussowitsch while ((next = PetscOptionsObject->next)) { 52910c654e6SJacob Faibussowitsch const PetscOptionType type = next->type; 53010c654e6SJacob Faibussowitsch const size_t arraylength = next->arraylength; 53110c654e6SJacob Faibussowitsch void *data = next->data; 53210c654e6SJacob Faibussowitsch 53310c654e6SJacob Faibussowitsch if (next->set) { 53410c654e6SJacob Faibussowitsch char option[256], value[1024], tmp[32]; 53510c654e6SJacob Faibussowitsch 536e55864a3SBarry Smith if (PetscOptionsObject->prefix) { 537c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(option, "-", sizeof(option))); 538c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option))); 53910c654e6SJacob Faibussowitsch PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option))); 54010c654e6SJacob Faibussowitsch } else { 54110c654e6SJacob Faibussowitsch PetscCall(PetscStrncpy(option, next->option, sizeof(option))); 54210c654e6SJacob Faibussowitsch } 5436356e834SBarry Smith 54410c654e6SJacob Faibussowitsch switch (type) { 545d71ae5a4SJacob Faibussowitsch case OPTION_HEAD: 546d71ae5a4SJacob Faibussowitsch break; 5476356e834SBarry Smith case OPTION_INT_ARRAY: 54810c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscInt *)data)[0])); 54910c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 55010c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscInt *)data)[j])); 551c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 552c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5536356e834SBarry Smith } 5546356e834SBarry Smith break; 555d71ae5a4SJacob Faibussowitsch case OPTION_INT: 55610c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)*(PetscInt *)data)); 557d71ae5a4SJacob Faibussowitsch break; 558d71ae5a4SJacob Faibussowitsch case OPTION_REAL: 55910c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data)); 560d71ae5a4SJacob Faibussowitsch break; 5616356e834SBarry Smith case OPTION_REAL_ARRAY: 56210c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0])); 56310c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 56410c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j])); 565c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 566c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5676356e834SBarry Smith } 5686356e834SBarry Smith break; 569050cccc3SHong Zhang case OPTION_SCALAR_ARRAY: 57010c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0]))); 57110c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 57210c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j]))); 573c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 574c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 575050cccc3SHong Zhang } 576050cccc3SHong Zhang break; 577d71ae5a4SJacob Faibussowitsch case OPTION_BOOL: 57810c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data)); 579d71ae5a4SJacob Faibussowitsch break; 5807781c08eSBarry Smith case OPTION_BOOL_ARRAY: 58110c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0])); 58210c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 58310c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j])); 584c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 585c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5861ae3d29cSBarry Smith } 5871ae3d29cSBarry Smith break; 58810c654e6SJacob Faibussowitsch case OPTION_FLIST: // fall-through 58910c654e6SJacob Faibussowitsch case OPTION_ELIST: // fall-through 590d71ae5a4SJacob Faibussowitsch case OPTION_STRING: 59110c654e6SJacob Faibussowitsch PetscCall(PetscStrncpy(value, (char *)data, sizeof(value))); 592d71ae5a4SJacob Faibussowitsch break; 5931ae3d29cSBarry Smith case OPTION_STRING_ARRAY: 59410c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0])); 59510c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; j++) { 59610c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j])); 597c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 598c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5991ae3d29cSBarry Smith } 6006356e834SBarry Smith break; 6016356e834SBarry Smith } 6029566063dSJacob Faibussowitsch PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value)); 6036356e834SBarry Smith } 60410c654e6SJacob Faibussowitsch if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list)); 60510c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->text)); 60610c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->option)); 60710c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->man)); 60810c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->edata)); 609c979a496SBarry Smith 61010c654e6SJacob Faibussowitsch if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) { 61110c654e6SJacob Faibussowitsch free(data); 612c979a496SBarry Smith } else { 61310c654e6SJacob Faibussowitsch // use next->data instead of data because PetscFree() sets it to NULL 61410c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->data)); 615c979a496SBarry Smith } 6167781c08eSBarry Smith 61710c654e6SJacob Faibussowitsch last = next; 61810c654e6SJacob Faibussowitsch PetscOptionsObject->next = next->next; 6199566063dSJacob Faibussowitsch PetscCall(PetscFree(last)); 6206356e834SBarry Smith } 6219566063dSJacob Faibussowitsch PetscCall(PetscFree(PetscOptionsObject->prefix)); 62202c9f0b5SLisandro Dalcin PetscOptionsObject->next = NULL; 6233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62453acd3b1SBarry Smith } 62553acd3b1SBarry Smith 62610c654e6SJacob Faibussowitsch static PetscErrorCode GetListLength(const char *const *list, PetscInt *len) 62710c654e6SJacob Faibussowitsch { 62810c654e6SJacob Faibussowitsch PetscInt retlen = 0; 62910c654e6SJacob Faibussowitsch 63010c654e6SJacob Faibussowitsch PetscFunctionBegin; 6314f572ea9SToby Isaac PetscAssertPointer(len, 2); 63210c654e6SJacob Faibussowitsch while (list[retlen]) { 6334f572ea9SToby Isaac PetscAssertPointer(list[retlen], 1); 63410c654e6SJacob Faibussowitsch PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries"); 63510c654e6SJacob Faibussowitsch } 63610c654e6SJacob Faibussowitsch PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix"); 63710c654e6SJacob Faibussowitsch /* drop item name and prefix*/ 63810c654e6SJacob Faibussowitsch *len = retlen - 2; 63910c654e6SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 64010c654e6SJacob Faibussowitsch } 64110c654e6SJacob Faibussowitsch 642d71ae5a4SJacob 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) 643d71ae5a4SJacob Faibussowitsch { 64453acd3b1SBarry Smith PetscInt ntext = 0; 645aa5bb8c0SSatish Balay PetscInt tval; 646ace3abfcSBarry Smith PetscBool tflg; 64753acd3b1SBarry Smith 64853acd3b1SBarry Smith PetscFunctionBegin; 6494f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6504f572ea9SToby Isaac PetscAssertPointer(list, 5); 6514f572ea9SToby Isaac PetscAssertPointer(value, 7); 6524f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 65310c654e6SJacob Faibussowitsch PetscCall(GetListLength(list, &ntext)); 6549566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[currentvalue], &tval, &tflg)); 655aa5bb8c0SSatish Balay /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */ 656aa5bb8c0SSatish Balay if (tflg) *value = (PetscEnum)tval; 657aa5bb8c0SSatish Balay if (set) *set = tflg; 6583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 65953acd3b1SBarry Smith } 66053acd3b1SBarry Smith 661d71ae5a4SJacob 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) 662d71ae5a4SJacob Faibussowitsch { 66310c654e6SJacob Faibussowitsch PetscInt nlist = 0; 66410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 665d3e47460SLisandro Dalcin 666d3e47460SLisandro Dalcin PetscFunctionBegin; 6674f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6684f572ea9SToby Isaac PetscAssertPointer(list, 5); 6694f572ea9SToby Isaac PetscAssertPointer(value, 6); 6704f572ea9SToby Isaac PetscAssertPointer(n, 7); 67110c654e6SJacob Faibussowitsch PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n); 6724f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 67310c654e6SJacob Faibussowitsch PetscCall(GetListLength(list, &nlist)); 67410c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set)); 67510c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 67610c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 67710c654e6SJacob Faibussowitsch const PetscInt nv = *n; 67810c654e6SJacob Faibussowitsch 67910c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]])); 68010c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]])); 68110c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text)); 68210c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i])); 68310c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man))); 684d3e47460SLisandro Dalcin } 6853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 686d3e47460SLisandro Dalcin } 687d3e47460SLisandro Dalcin 688d71ae5a4SJacob 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) 689d71ae5a4SJacob Faibussowitsch { 69010c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 69110c654e6SJacob Faibussowitsch const PetscOptions options = PetscOptionsObject->options; 69212655325SBarry Smith PetscBool wasset; 69353acd3b1SBarry Smith 69453acd3b1SBarry Smith PetscFunctionBegin; 6954f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6964f572ea9SToby Isaac PetscAssertPointer(value, 6); 6974f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 69808401ef6SPierre Jolivet PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb); 69908401ef6SPierre Jolivet PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub); 700e55864a3SBarry Smith if (!PetscOptionsObject->count) { 70110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 70210c654e6SJacob Faibussowitsch 7039566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt)); 7049566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data)); 70512655325SBarry Smith *(PetscInt *)amsopt->data = currentvalue; 7063e211508SBarry Smith 70710c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetInt(options, prefix, opt, ¤tvalue, &wasset)); 708ad540459SPierre Jolivet if (wasset) *(PetscInt *)amsopt->data = currentvalue; 709af6d86caSBarry Smith } 71010c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset)); 711cc73adaaSBarry 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); 712cc73adaaSBarry 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); 71344ef3d73SBarry Smith if (set) *set = wasset; 71410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 71510c654e6SJacob 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))); 71653acd3b1SBarry Smith } 7173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71853acd3b1SBarry Smith } 71953acd3b1SBarry Smith 7206497c311SBarry Smith PetscErrorCode PetscOptionsMPIInt_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscMPIInt currentvalue, PetscMPIInt *value, PetscBool *set, PetscMPIInt lb, PetscMPIInt ub) 7216497c311SBarry Smith { 7226497c311SBarry Smith const char *prefix = PetscOptionsObject->prefix; 7236497c311SBarry Smith const PetscOptions options = PetscOptionsObject->options; 7246497c311SBarry Smith PetscBool wasset; 7256497c311SBarry Smith 7266497c311SBarry Smith PetscFunctionBegin; 7276497c311SBarry Smith PetscAssertPointer(opt, 2); 7286497c311SBarry Smith PetscAssertPointer(value, 6); 7296497c311SBarry Smith if (set) PetscAssertPointer(set, 7); 7306497c311SBarry Smith PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d less than allowed bound %d", currentvalue, lb); 7316497c311SBarry Smith PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d greater than allowed bound %d", currentvalue, ub); 7326497c311SBarry Smith if (!PetscOptionsObject->count) { 7336497c311SBarry Smith PetscOptionItem amsopt; 7346497c311SBarry Smith 7356497c311SBarry Smith PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt)); 7366497c311SBarry Smith PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data)); 7376497c311SBarry Smith *(PetscMPIInt *)amsopt->data = currentvalue; 7386497c311SBarry Smith 7396497c311SBarry Smith PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, ¤tvalue, &wasset)); 7406497c311SBarry Smith if (wasset) *(PetscMPIInt *)amsopt->data = currentvalue; 7416497c311SBarry Smith } 7426497c311SBarry Smith PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, value, &wasset)); 7436497c311SBarry Smith PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d less than allowed bound %d", *value, lb); 7446497c311SBarry Smith PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d greater than allowed bound %d", *value, ub); 7456497c311SBarry Smith if (set) *set = wasset; 7466497c311SBarry Smith if (ShouldPrintHelp(PetscOptionsObject)) { PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <now %d : formerly %d>: %s (%s)\n", Prefix(prefix), opt + 1, wasset ? *value : currentvalue, currentvalue, text, ManSection(man))); } 7476497c311SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 7486497c311SBarry Smith } 7496497c311SBarry Smith 750d71ae5a4SJacob 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) 751d71ae5a4SJacob Faibussowitsch { 75210c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 75344ef3d73SBarry Smith PetscBool lset; 75453acd3b1SBarry Smith 75553acd3b1SBarry Smith PetscFunctionBegin; 7564f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7574f572ea9SToby Isaac PetscAssertPointer(value, 6); 7584f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 7591a1499c8SBarry Smith if (!PetscOptionsObject->count) { 76010c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 76110c654e6SJacob Faibussowitsch 7629566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 76364facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 7649566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 765af6d86caSBarry Smith } 76610c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 76744ef3d73SBarry Smith if (set) *set = lset; 76810c654e6SJacob 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))); 7693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77053acd3b1SBarry Smith } 77153acd3b1SBarry Smith 77252ce0ab5SPierre 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) 773d71ae5a4SJacob Faibussowitsch { 77410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 77552ce0ab5SPierre Jolivet const PetscOptions options = PetscOptionsObject->options; 77652ce0ab5SPierre Jolivet PetscBool wasset; 77753acd3b1SBarry Smith 77853acd3b1SBarry Smith PetscFunctionBegin; 7794f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7804f572ea9SToby Isaac PetscAssertPointer(value, 6); 7814f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 78252ce0ab5SPierre Jolivet PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb); 78352ce0ab5SPierre Jolivet PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub); 784e55864a3SBarry Smith if (!PetscOptionsObject->count) { 78510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 78610c654e6SJacob Faibussowitsch 7879566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt)); 7889566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data)); 7890fdccdaeSBarry Smith *(PetscReal *)amsopt->data = currentvalue; 79052ce0ab5SPierre Jolivet 79152ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(options, prefix, opt, ¤tvalue, &wasset)); 79252ce0ab5SPierre Jolivet if (wasset) *(PetscReal *)amsopt->data = currentvalue; 793538aa990SBarry Smith } 79452ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset)); 79552ce0ab5SPierre 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); 79652ce0ab5SPierre 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); 79752ce0ab5SPierre Jolivet if (set) *set = wasset; 79810c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 79952ce0ab5SPierre 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))); 80053acd3b1SBarry Smith } 8013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80253acd3b1SBarry Smith } 80353acd3b1SBarry Smith 804d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set) 805d71ae5a4SJacob Faibussowitsch { 80653acd3b1SBarry Smith PetscFunctionBegin; 80753acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX) 8089566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set)); 80953acd3b1SBarry Smith #else 8109566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set)); 81153acd3b1SBarry Smith #endif 8123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81353acd3b1SBarry Smith } 81453acd3b1SBarry Smith 815d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 816d71ae5a4SJacob Faibussowitsch { 81710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 81853acd3b1SBarry Smith 81953acd3b1SBarry Smith PetscFunctionBegin; 8204f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8214f572ea9SToby Isaac PetscAssertPointer(flg, 5); 822e55864a3SBarry Smith if (!PetscOptionsObject->count) { 82310c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 82410c654e6SJacob Faibussowitsch 8259566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 8269566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 827a297a907SKarl Rupp 828ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 8291ae3d29cSBarry Smith } 83010c654e6SJacob Faibussowitsch PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg)); 83110c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 8323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83353acd3b1SBarry Smith } 83453acd3b1SBarry Smith 835d71ae5a4SJacob 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) 836d71ae5a4SJacob Faibussowitsch { 83710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 83844ef3d73SBarry Smith PetscBool lset; 83953acd3b1SBarry Smith 84053acd3b1SBarry Smith PetscFunctionBegin; 8414f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8424f572ea9SToby Isaac PetscAssertPointer(value, 7); 8434f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8441a1499c8SBarry Smith if (!PetscOptionsObject->count) { 84510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 84610c654e6SJacob Faibussowitsch 8479566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt)); 84864facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8499566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8503cc1e11dSBarry Smith amsopt->flist = list; 8513cc1e11dSBarry Smith } 85210c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 85344ef3d73SBarry Smith if (set) *set = lset; 85410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue)); 8553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85653acd3b1SBarry Smith } 85753acd3b1SBarry Smith 85810c654e6SJacob Faibussowitsch #ifdef __cplusplus 85910c654e6SJacob Faibussowitsch #include <type_traits> 86010c654e6SJacob Faibussowitsch #endif 86110c654e6SJacob Faibussowitsch 862d71ae5a4SJacob 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) 863d71ae5a4SJacob Faibussowitsch { 86410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 86544ef3d73SBarry Smith PetscBool lset; 86653acd3b1SBarry Smith 86753acd3b1SBarry Smith PetscFunctionBegin; 8684f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8694f572ea9SToby Isaac PetscAssertPointer(value, 8); 8704f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8711a1499c8SBarry Smith if (!PetscOptionsObject->count) { 87210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 87310c654e6SJacob Faibussowitsch 8749566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt)); 87564facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8769566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8779566063dSJacob Faibussowitsch PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list)); 87810c654e6SJacob Faibussowitsch PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX); 87910c654e6SJacob Faibussowitsch #ifdef __cplusplus 88010c654e6SJacob Faibussowitsch static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, ""); 88110c654e6SJacob Faibussowitsch #endif 88210c654e6SJacob Faibussowitsch amsopt->nlist = (char)ntext; 8831ae3d29cSBarry Smith } 88410c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset)); 88544ef3d73SBarry Smith if (set) *set = lset; 88610c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 88710c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 88810c654e6SJacob Faibussowitsch 88910c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext)); 89010c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i])); 89110c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man))); 89253acd3b1SBarry Smith } 8933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89453acd3b1SBarry Smith } 89553acd3b1SBarry Smith 896d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 897d71ae5a4SJacob Faibussowitsch { 89810c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 89953acd3b1SBarry Smith 90053acd3b1SBarry Smith PetscFunctionBegin; 9014f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9024f572ea9SToby Isaac PetscAssertPointer(flg, 5); 903e55864a3SBarry Smith if (!PetscOptionsObject->count) { 90410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 90510c654e6SJacob Faibussowitsch 9069566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9079566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 908a297a907SKarl Rupp 909ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9101ae3d29cSBarry Smith } 91168b16fdaSBarry Smith *flg = PETSC_FALSE; 91210c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 91310c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 91410c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 91510c654e6SJacob Faibussowitsch 91610c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " Pick at most one of -------------\n")); 91710c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 91853acd3b1SBarry Smith } 9193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92053acd3b1SBarry Smith } 92153acd3b1SBarry Smith 922d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 923d71ae5a4SJacob Faibussowitsch { 92410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 92553acd3b1SBarry Smith 92653acd3b1SBarry Smith PetscFunctionBegin; 9274f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9284f572ea9SToby Isaac PetscAssertPointer(flg, 5); 929e55864a3SBarry Smith if (!PetscOptionsObject->count) { 93010c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 93110c654e6SJacob Faibussowitsch 9329566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9339566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 934a297a907SKarl Rupp 935ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9361ae3d29cSBarry Smith } 93717326d04SJed Brown *flg = PETSC_FALSE; 93810c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 93910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 94153acd3b1SBarry Smith } 94253acd3b1SBarry Smith 943d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 944d71ae5a4SJacob Faibussowitsch { 94510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 94653acd3b1SBarry Smith 94753acd3b1SBarry Smith PetscFunctionBegin; 9484f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9494f572ea9SToby Isaac PetscAssertPointer(flg, 5); 950e55864a3SBarry Smith if (!PetscOptionsObject->count) { 95110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 95210c654e6SJacob Faibussowitsch 9539566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9549566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 955a297a907SKarl Rupp 956ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9571ae3d29cSBarry Smith } 95817326d04SJed Brown *flg = PETSC_FALSE; 95910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 96010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 96253acd3b1SBarry Smith } 96353acd3b1SBarry Smith 964d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set) 965d71ae5a4SJacob Faibussowitsch { 96610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 967ace3abfcSBarry Smith PetscBool iset; 96853acd3b1SBarry Smith 96953acd3b1SBarry Smith PetscFunctionBegin; 9704f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9714f572ea9SToby Isaac PetscAssertPointer(flg, 6); 9724f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 973e55864a3SBarry Smith if (!PetscOptionsObject->count) { 97410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 97510c654e6SJacob Faibussowitsch 9769566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9779566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 978a297a907SKarl Rupp 97994ae4db5SBarry Smith *(PetscBool *)amsopt->data = currentvalue; 980af6d86caSBarry Smith } 98110c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset)); 98253acd3b1SBarry Smith if (set) *set = iset; 98310c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 98410c654e6SJacob Faibussowitsch const char *curvalue = PetscBools[currentvalue]; 98510c654e6SJacob Faibussowitsch 98610c654e6SJacob 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))); 98753acd3b1SBarry Smith } 9883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98953acd3b1SBarry Smith } 99053acd3b1SBarry Smith 991d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set) 992d71ae5a4SJacob Faibussowitsch { 99310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 99453acd3b1SBarry Smith 99553acd3b1SBarry Smith PetscFunctionBegin; 9964f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9974f572ea9SToby Isaac PetscAssertPointer(n, 6); 99810c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 9994f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10004f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1001e55864a3SBarry Smith if (!PetscOptionsObject->count) { 100210c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1003e26ddf31SBarry Smith PetscReal *vals; 100410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1005e26ddf31SBarry Smith 10069566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt)); 100710c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 100810c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 100910c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 101010c654e6SJacob Faibussowitsch amsopt->data = vals; 1011e26ddf31SBarry Smith } 101210c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 101310c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 101410c654e6SJacob Faibussowitsch const PetscInt nv = *n; 101510c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 101610c654e6SJacob Faibussowitsch 101710c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0])); 101810c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i])); 101910c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 102053acd3b1SBarry Smith } 10213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 102253acd3b1SBarry Smith } 102353acd3b1SBarry Smith 1024d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set) 1025d71ae5a4SJacob Faibussowitsch { 102610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 1027050cccc3SHong Zhang 1028050cccc3SHong Zhang PetscFunctionBegin; 10294f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10304f572ea9SToby Isaac PetscAssertPointer(n, 6); 103110c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10324f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10334f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1034050cccc3SHong Zhang if (!PetscOptionsObject->count) { 103510c654e6SJacob Faibussowitsch const PetscInt nv = *n; 103610c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1037050cccc3SHong Zhang PetscScalar *vals; 1038050cccc3SHong Zhang 10399566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt)); 104010c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 104110c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 104210c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 104310c654e6SJacob Faibussowitsch amsopt->data = vals; 1044050cccc3SHong Zhang } 104510c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 104610c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 104710c654e6SJacob Faibussowitsch const PetscInt nv = *n; 104810c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 104910c654e6SJacob Faibussowitsch 105010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0]))); 105110c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i]))); 105210c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1053050cccc3SHong Zhang } 10543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1055050cccc3SHong Zhang } 105653acd3b1SBarry Smith 1057d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set) 1058d71ae5a4SJacob Faibussowitsch { 105910c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 106053acd3b1SBarry Smith 106153acd3b1SBarry Smith PetscFunctionBegin; 10624f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10634f572ea9SToby Isaac PetscAssertPointer(n, 6); 106410c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10654f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10664f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1067e55864a3SBarry Smith if (!PetscOptionsObject->count) { 106810c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1069e26ddf31SBarry Smith PetscInt *vals; 107010c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1071e26ddf31SBarry Smith 10729566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt)); 107310c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 107410c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 107510c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 107610c654e6SJacob Faibussowitsch amsopt->data = vals; 1077e26ddf31SBarry Smith } 107810c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 107910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 108010c654e6SJacob Faibussowitsch const PetscInt nv = *n; 108110c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 108210c654e6SJacob Faibussowitsch 108310c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0])); 108410c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i])); 108510c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 108653acd3b1SBarry Smith } 10873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 108853acd3b1SBarry Smith } 108953acd3b1SBarry Smith 1090d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set) 1091d71ae5a4SJacob Faibussowitsch { 109210c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 109353acd3b1SBarry Smith 109453acd3b1SBarry Smith PetscFunctionBegin; 10954f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10964f572ea9SToby Isaac PetscAssertPointer(nmax, 6); 109710c654e6SJacob Faibussowitsch PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax); 10984f572ea9SToby Isaac if (*nmax) PetscAssertPointer(value, 5); 10994f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1100e55864a3SBarry Smith if (!PetscOptionsObject->count) { 110110c654e6SJacob Faibussowitsch const PetscInt nmaxv = *nmax; 110210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1103a297a907SKarl Rupp 110410c654e6SJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt)); 110510c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data)); 110610c654e6SJacob Faibussowitsch amsopt->arraylength = nmaxv; 11071ae3d29cSBarry Smith } 110810c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set)); 110910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 11103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 111153acd3b1SBarry Smith } 111253acd3b1SBarry Smith 1113d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set) 1114d71ae5a4SJacob Faibussowitsch { 111510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 1116e2446a98SMatthew Knepley 1117e2446a98SMatthew Knepley PetscFunctionBegin; 11184f572ea9SToby Isaac PetscAssertPointer(opt, 2); 11194f572ea9SToby Isaac PetscAssertPointer(n, 6); 112010c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 11214f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 11224f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1123e55864a3SBarry Smith if (!PetscOptionsObject->count) { 112410c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1125ace3abfcSBarry Smith PetscBool *vals; 112610c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 11271ae3d29cSBarry Smith 11289566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt)); 112910c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 113010c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 113110c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 113210c654e6SJacob Faibussowitsch amsopt->data = vals; 11331ae3d29cSBarry Smith } 113410c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 113510c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 113610c654e6SJacob Faibussowitsch const PetscInt nv = *n; 113710c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 113810c654e6SJacob Faibussowitsch 113910c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%d", Prefix(prefix), opt + 1, value[0])); 114010c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i])); 114110c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1142e2446a98SMatthew Knepley } 11433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1144e2446a98SMatthew Knepley } 1145e2446a98SMatthew Knepley 114688aa4217SBarry Smith /*MC 1147648c30bcSBarry Smith PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user 11488cc676e6SMatthew G Knepley 114988aa4217SBarry Smith Synopsis: 115010450e9eSJacob Faibussowitsch #include <petscviewer.h> 11513a89f35bSSatish Balay PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 115288aa4217SBarry Smith 11537cdbe19fSJose E. Roman Logically Collective on the communicator passed in `PetscOptionsBegin()` 11547cdbe19fSJose E. Roman 11558cc676e6SMatthew G Knepley Input Parameters: 11568cc676e6SMatthew G Knepley + opt - option name 11578cc676e6SMatthew G Knepley . text - short string that describes the option 11588cc676e6SMatthew G Knepley - man - manual page with additional information on option 11598cc676e6SMatthew G Knepley 1160d8d19677SJose E. Roman Output Parameters: 11618cc676e6SMatthew G Knepley + viewer - the viewer 11629314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed 1163811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE` 11648cc676e6SMatthew G Knepley 11658cc676e6SMatthew G Knepley Level: beginner 11668cc676e6SMatthew G Knepley 116795452b02SPatrick Sanan Notes: 1168811af0c4SBarry Smith Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()` 11698cc676e6SMatthew G Knepley 1170648c30bcSBarry Smith See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options 11718cc676e6SMatthew G Knepley 1172648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`, 1173db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 1174aec76313SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 1175db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 1176c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 1177db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 1178db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 117988aa4217SBarry Smith M*/ 1180d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 1181d71ae5a4SJacob Faibussowitsch { 118210c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 118310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 11848cc676e6SMatthew G Knepley 11858cc676e6SMatthew G Knepley PetscFunctionBegin; 11864f572ea9SToby Isaac PetscAssertPointer(opt, 2); 11874f572ea9SToby Isaac PetscAssertPointer(viewer, 5); 11884f572ea9SToby Isaac if (format) PetscAssertPointer(format, 6); 11894f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 11901a1499c8SBarry Smith if (!PetscOptionsObject->count) { 119110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 119210c654e6SJacob Faibussowitsch 11939566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 119464facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 11959566063dSJacob Faibussowitsch PetscCall(PetscStrdup("", (char **)&amsopt->data)); 11968cc676e6SMatthew G Knepley } 1197648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set)); 119810c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man))); 11993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12008cc676e6SMatthew G Knepley } 1201