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; 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; 356e26ddf31SBarry Smith size_t len; 357e26ddf31SBarry Smith char *value; 358ace3abfcSBarry Smith PetscBool foundrange; 3596497c311SBarry Smith PetscInt i; 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; 3736497c311SBarry Smith for (; i < (PetscInt)len; i++) { 374e26ddf31SBarry Smith if (value[i] == '-') { 3756497c311SBarry Smith PetscCheck(i != (PetscInt)(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; 4036497c311SBarry Smith for (PetscInt 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); 436*1690c2aeSBarry 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); 437c272547aSJed Brown #else 438d25d7f95SJed Brown long lid; 439d25d7f95SJed Brown sscanf(str, "%ld", &lid); 440*1690c2aeSBarry 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); 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 7216497c311SBarry 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) 7226497c311SBarry Smith { 7236497c311SBarry Smith const char *prefix = PetscOptionsObject->prefix; 7246497c311SBarry Smith const PetscOptions options = PetscOptionsObject->options; 7256497c311SBarry Smith PetscBool wasset; 7266497c311SBarry Smith 7276497c311SBarry Smith PetscFunctionBegin; 7286497c311SBarry Smith PetscAssertPointer(opt, 2); 7296497c311SBarry Smith PetscAssertPointer(value, 6); 7306497c311SBarry Smith if (set) PetscAssertPointer(set, 7); 7316497c311SBarry Smith PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d less than allowed bound %d", currentvalue, lb); 7326497c311SBarry Smith PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d greater than allowed bound %d", currentvalue, ub); 7336497c311SBarry Smith if (!PetscOptionsObject->count) { 7346497c311SBarry Smith PetscOptionItem amsopt; 7356497c311SBarry Smith 7366497c311SBarry Smith PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt)); 7376497c311SBarry Smith PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data)); 7386497c311SBarry Smith *(PetscMPIInt *)amsopt->data = currentvalue; 7396497c311SBarry Smith 7406497c311SBarry Smith PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, ¤tvalue, &wasset)); 7416497c311SBarry Smith if (wasset) *(PetscMPIInt *)amsopt->data = currentvalue; 7426497c311SBarry Smith } 7436497c311SBarry Smith PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, value, &wasset)); 7446497c311SBarry Smith PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d less than allowed bound %d", *value, lb); 7456497c311SBarry Smith PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d greater than allowed bound %d", *value, ub); 7466497c311SBarry Smith if (set) *set = wasset; 7476497c311SBarry 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))); } 7486497c311SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 7496497c311SBarry Smith } 7506497c311SBarry Smith 751d71ae5a4SJacob 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) 752d71ae5a4SJacob Faibussowitsch { 75310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 75444ef3d73SBarry Smith PetscBool lset; 75553acd3b1SBarry Smith 75653acd3b1SBarry Smith PetscFunctionBegin; 7574f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7584f572ea9SToby Isaac PetscAssertPointer(value, 6); 7594f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 7601a1499c8SBarry Smith if (!PetscOptionsObject->count) { 76110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 76210c654e6SJacob Faibussowitsch 7639566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 76464facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 7659566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 766af6d86caSBarry Smith } 76710c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 76844ef3d73SBarry Smith if (set) *set = lset; 76910c654e6SJacob 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))); 7703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77153acd3b1SBarry Smith } 77253acd3b1SBarry Smith 77352ce0ab5SPierre 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) 774d71ae5a4SJacob Faibussowitsch { 77510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 77652ce0ab5SPierre Jolivet const PetscOptions options = PetscOptionsObject->options; 77752ce0ab5SPierre Jolivet PetscBool wasset; 77853acd3b1SBarry Smith 77953acd3b1SBarry Smith PetscFunctionBegin; 7804f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7814f572ea9SToby Isaac PetscAssertPointer(value, 6); 7824f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 78352ce0ab5SPierre Jolivet PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb); 78452ce0ab5SPierre Jolivet PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub); 785e55864a3SBarry Smith if (!PetscOptionsObject->count) { 78610c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 78710c654e6SJacob Faibussowitsch 7889566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt)); 7899566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data)); 7900fdccdaeSBarry Smith *(PetscReal *)amsopt->data = currentvalue; 79152ce0ab5SPierre Jolivet 79252ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(options, prefix, opt, ¤tvalue, &wasset)); 79352ce0ab5SPierre Jolivet if (wasset) *(PetscReal *)amsopt->data = currentvalue; 794538aa990SBarry Smith } 79552ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset)); 79652ce0ab5SPierre 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); 79752ce0ab5SPierre 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); 79852ce0ab5SPierre Jolivet if (set) *set = wasset; 79910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 80052ce0ab5SPierre 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))); 80153acd3b1SBarry Smith } 8023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80353acd3b1SBarry Smith } 80453acd3b1SBarry Smith 805d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set) 806d71ae5a4SJacob Faibussowitsch { 80753acd3b1SBarry Smith PetscFunctionBegin; 80853acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX) 8099566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set)); 81053acd3b1SBarry Smith #else 8119566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set)); 81253acd3b1SBarry Smith #endif 8133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81453acd3b1SBarry Smith } 81553acd3b1SBarry Smith 816d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsName_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 817d71ae5a4SJacob Faibussowitsch { 81810c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 81953acd3b1SBarry Smith 82053acd3b1SBarry Smith PetscFunctionBegin; 8214f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8224f572ea9SToby Isaac PetscAssertPointer(flg, 5); 823e55864a3SBarry Smith if (!PetscOptionsObject->count) { 82410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 82510c654e6SJacob Faibussowitsch 8269566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 8279566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 828a297a907SKarl Rupp 829ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 8301ae3d29cSBarry Smith } 83110c654e6SJacob Faibussowitsch PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg)); 83210c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 8333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83453acd3b1SBarry Smith } 83553acd3b1SBarry Smith 836d71ae5a4SJacob 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) 837d71ae5a4SJacob Faibussowitsch { 83810c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 83944ef3d73SBarry Smith PetscBool lset; 84053acd3b1SBarry Smith 84153acd3b1SBarry Smith PetscFunctionBegin; 8424f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8434f572ea9SToby Isaac PetscAssertPointer(value, 7); 8444f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8451a1499c8SBarry Smith if (!PetscOptionsObject->count) { 84610c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 84710c654e6SJacob Faibussowitsch 8489566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt)); 84964facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8509566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8513cc1e11dSBarry Smith amsopt->flist = list; 8523cc1e11dSBarry Smith } 85310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 85444ef3d73SBarry Smith if (set) *set = lset; 85510c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue)); 8563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85753acd3b1SBarry Smith } 85853acd3b1SBarry Smith 85910c654e6SJacob Faibussowitsch #ifdef __cplusplus 86010c654e6SJacob Faibussowitsch #include <type_traits> 86110c654e6SJacob Faibussowitsch #endif 86210c654e6SJacob Faibussowitsch 863d71ae5a4SJacob 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) 864d71ae5a4SJacob Faibussowitsch { 86510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 86644ef3d73SBarry Smith PetscBool lset; 86753acd3b1SBarry Smith 86853acd3b1SBarry Smith PetscFunctionBegin; 8694f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8704f572ea9SToby Isaac PetscAssertPointer(value, 8); 8714f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8721a1499c8SBarry Smith if (!PetscOptionsObject->count) { 87310c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 87410c654e6SJacob Faibussowitsch 8759566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt)); 87664facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8779566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8789566063dSJacob Faibussowitsch PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list)); 87910c654e6SJacob Faibussowitsch PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX); 88010c654e6SJacob Faibussowitsch #ifdef __cplusplus 88110c654e6SJacob Faibussowitsch static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, ""); 88210c654e6SJacob Faibussowitsch #endif 88310c654e6SJacob Faibussowitsch amsopt->nlist = (char)ntext; 8841ae3d29cSBarry Smith } 88510c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset)); 88644ef3d73SBarry Smith if (set) *set = lset; 88710c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 88810c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 88910c654e6SJacob Faibussowitsch 89010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext)); 89110c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i])); 89210c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man))); 89353acd3b1SBarry Smith } 8943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89553acd3b1SBarry Smith } 89653acd3b1SBarry Smith 897d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 898d71ae5a4SJacob Faibussowitsch { 89910c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 90053acd3b1SBarry Smith 90153acd3b1SBarry Smith PetscFunctionBegin; 9024f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9034f572ea9SToby Isaac PetscAssertPointer(flg, 5); 904e55864a3SBarry Smith if (!PetscOptionsObject->count) { 90510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 90610c654e6SJacob Faibussowitsch 9079566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9089566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 909a297a907SKarl Rupp 910ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9111ae3d29cSBarry Smith } 91268b16fdaSBarry Smith *flg = PETSC_FALSE; 91310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 91410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 91510c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 91610c654e6SJacob Faibussowitsch 91710c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " Pick at most one of -------------\n")); 91810c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 91953acd3b1SBarry Smith } 9203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92153acd3b1SBarry Smith } 92253acd3b1SBarry Smith 923d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 924d71ae5a4SJacob Faibussowitsch { 92510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 92653acd3b1SBarry Smith 92753acd3b1SBarry Smith PetscFunctionBegin; 9284f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9294f572ea9SToby Isaac PetscAssertPointer(flg, 5); 930e55864a3SBarry Smith if (!PetscOptionsObject->count) { 93110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 93210c654e6SJacob Faibussowitsch 9339566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9349566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 935a297a907SKarl Rupp 936ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9371ae3d29cSBarry Smith } 93817326d04SJed Brown *flg = PETSC_FALSE; 93910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 94010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 94253acd3b1SBarry Smith } 94353acd3b1SBarry Smith 944d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 945d71ae5a4SJacob Faibussowitsch { 94610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 94753acd3b1SBarry Smith 94853acd3b1SBarry Smith PetscFunctionBegin; 9494f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9504f572ea9SToby Isaac PetscAssertPointer(flg, 5); 951e55864a3SBarry Smith if (!PetscOptionsObject->count) { 95210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 95310c654e6SJacob Faibussowitsch 9549566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9559566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 956a297a907SKarl Rupp 957ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9581ae3d29cSBarry Smith } 95917326d04SJed Brown *flg = PETSC_FALSE; 96010c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 96110c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 96353acd3b1SBarry Smith } 96453acd3b1SBarry Smith 965d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBool_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set) 966d71ae5a4SJacob Faibussowitsch { 96710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 968ace3abfcSBarry Smith PetscBool iset; 96953acd3b1SBarry Smith 97053acd3b1SBarry Smith PetscFunctionBegin; 9714f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9724f572ea9SToby Isaac PetscAssertPointer(flg, 6); 9734f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 974e55864a3SBarry Smith if (!PetscOptionsObject->count) { 97510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 97610c654e6SJacob Faibussowitsch 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9789566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 979a297a907SKarl Rupp 98094ae4db5SBarry Smith *(PetscBool *)amsopt->data = currentvalue; 981af6d86caSBarry Smith } 98210c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset)); 98353acd3b1SBarry Smith if (set) *set = iset; 98410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 98510c654e6SJacob Faibussowitsch const char *curvalue = PetscBools[currentvalue]; 98610c654e6SJacob Faibussowitsch 98710c654e6SJacob 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))); 98853acd3b1SBarry Smith } 9893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99053acd3b1SBarry Smith } 99153acd3b1SBarry Smith 992d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set) 993d71ae5a4SJacob Faibussowitsch { 99410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 99553acd3b1SBarry Smith 99653acd3b1SBarry Smith PetscFunctionBegin; 9974f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9984f572ea9SToby Isaac PetscAssertPointer(n, 6); 99910c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10004f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10014f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1002e55864a3SBarry Smith if (!PetscOptionsObject->count) { 100310c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1004e26ddf31SBarry Smith PetscReal *vals; 100510c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1006e26ddf31SBarry Smith 10079566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt)); 100810c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 100910c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 101010c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 101110c654e6SJacob Faibussowitsch amsopt->data = vals; 1012e26ddf31SBarry Smith } 101310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 101410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 101510c654e6SJacob Faibussowitsch const PetscInt nv = *n; 101610c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 101710c654e6SJacob Faibussowitsch 101810c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0])); 101910c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i])); 102010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 102153acd3b1SBarry Smith } 10223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 102353acd3b1SBarry Smith } 102453acd3b1SBarry Smith 1025d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set) 1026d71ae5a4SJacob Faibussowitsch { 102710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 1028050cccc3SHong Zhang 1029050cccc3SHong Zhang PetscFunctionBegin; 10304f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10314f572ea9SToby Isaac PetscAssertPointer(n, 6); 103210c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10334f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10344f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1035050cccc3SHong Zhang if (!PetscOptionsObject->count) { 103610c654e6SJacob Faibussowitsch const PetscInt nv = *n; 103710c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1038050cccc3SHong Zhang PetscScalar *vals; 1039050cccc3SHong Zhang 10409566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt)); 104110c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 104210c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 104310c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 104410c654e6SJacob Faibussowitsch amsopt->data = vals; 1045050cccc3SHong Zhang } 104610c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 104710c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 104810c654e6SJacob Faibussowitsch const PetscInt nv = *n; 104910c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 105010c654e6SJacob Faibussowitsch 105110c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0]))); 105210c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i]))); 105310c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1054050cccc3SHong Zhang } 10553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1056050cccc3SHong Zhang } 105753acd3b1SBarry Smith 1058d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set) 1059d71ae5a4SJacob Faibussowitsch { 106010c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 106153acd3b1SBarry Smith 106253acd3b1SBarry Smith PetscFunctionBegin; 10634f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10644f572ea9SToby Isaac PetscAssertPointer(n, 6); 106510c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10664f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10674f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1068e55864a3SBarry Smith if (!PetscOptionsObject->count) { 106910c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1070e26ddf31SBarry Smith PetscInt *vals; 107110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1072e26ddf31SBarry Smith 10739566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt)); 107410c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 107510c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 107610c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 107710c654e6SJacob Faibussowitsch amsopt->data = vals; 1078e26ddf31SBarry Smith } 107910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 108010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 108110c654e6SJacob Faibussowitsch const PetscInt nv = *n; 108210c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 108310c654e6SJacob Faibussowitsch 108410c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0])); 108510c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i])); 108610c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 108753acd3b1SBarry Smith } 10883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 108953acd3b1SBarry Smith } 109053acd3b1SBarry Smith 1091d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set) 1092d71ae5a4SJacob Faibussowitsch { 109310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 109453acd3b1SBarry Smith 109553acd3b1SBarry Smith PetscFunctionBegin; 10964f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10974f572ea9SToby Isaac PetscAssertPointer(nmax, 6); 109810c654e6SJacob Faibussowitsch PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax); 10994f572ea9SToby Isaac if (*nmax) PetscAssertPointer(value, 5); 11004f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1101e55864a3SBarry Smith if (!PetscOptionsObject->count) { 110210c654e6SJacob Faibussowitsch const PetscInt nmaxv = *nmax; 110310c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1104a297a907SKarl Rupp 110510c654e6SJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt)); 110610c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data)); 110710c654e6SJacob Faibussowitsch amsopt->arraylength = nmaxv; 11081ae3d29cSBarry Smith } 110910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set)); 111010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 11113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 111253acd3b1SBarry Smith } 111353acd3b1SBarry Smith 1114d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set) 1115d71ae5a4SJacob Faibussowitsch { 111610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 1117e2446a98SMatthew Knepley 1118e2446a98SMatthew Knepley PetscFunctionBegin; 11194f572ea9SToby Isaac PetscAssertPointer(opt, 2); 11204f572ea9SToby Isaac PetscAssertPointer(n, 6); 112110c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 11224f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 11234f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1124e55864a3SBarry Smith if (!PetscOptionsObject->count) { 112510c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1126ace3abfcSBarry Smith PetscBool *vals; 112710c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 11281ae3d29cSBarry Smith 11299566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt)); 113010c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 113110c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 113210c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 113310c654e6SJacob Faibussowitsch amsopt->data = vals; 11341ae3d29cSBarry Smith } 113510c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 113610c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 113710c654e6SJacob Faibussowitsch const PetscInt nv = *n; 113810c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 113910c654e6SJacob Faibussowitsch 114010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%d", Prefix(prefix), opt + 1, value[0])); 114110c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i])); 114210c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1143e2446a98SMatthew Knepley } 11443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1145e2446a98SMatthew Knepley } 1146e2446a98SMatthew Knepley 114788aa4217SBarry Smith /*MC 1148648c30bcSBarry Smith PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user 11498cc676e6SMatthew G Knepley 115088aa4217SBarry Smith Synopsis: 115110450e9eSJacob Faibussowitsch #include <petscviewer.h> 11523a89f35bSSatish Balay PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 115388aa4217SBarry Smith 11547cdbe19fSJose E. Roman Logically Collective on the communicator passed in `PetscOptionsBegin()` 11557cdbe19fSJose E. Roman 11568cc676e6SMatthew G Knepley Input Parameters: 11578cc676e6SMatthew G Knepley + opt - option name 11588cc676e6SMatthew G Knepley . text - short string that describes the option 11598cc676e6SMatthew G Knepley - man - manual page with additional information on option 11608cc676e6SMatthew G Knepley 1161d8d19677SJose E. Roman Output Parameters: 11628cc676e6SMatthew G Knepley + viewer - the viewer 11639314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed 1164811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE` 11658cc676e6SMatthew G Knepley 11668cc676e6SMatthew G Knepley Level: beginner 11678cc676e6SMatthew G Knepley 116895452b02SPatrick Sanan Notes: 1169811af0c4SBarry Smith Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()` 11708cc676e6SMatthew G Knepley 1171648c30bcSBarry Smith See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options 11728cc676e6SMatthew G Knepley 1173648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`, 1174db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 1175aec76313SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 1176db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 1177c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 1178db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 1179db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 118088aa4217SBarry Smith M*/ 1181d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems *PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 1182d71ae5a4SJacob Faibussowitsch { 118310c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 118410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 11858cc676e6SMatthew G Knepley 11868cc676e6SMatthew G Knepley PetscFunctionBegin; 11874f572ea9SToby Isaac PetscAssertPointer(opt, 2); 11884f572ea9SToby Isaac PetscAssertPointer(viewer, 5); 11894f572ea9SToby Isaac if (format) PetscAssertPointer(format, 6); 11904f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 11911a1499c8SBarry Smith if (!PetscOptionsObject->count) { 119210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 119310c654e6SJacob Faibussowitsch 11949566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 119564facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 11969566063dSJacob Faibussowitsch PetscCall(PetscStrdup("", (char **)&amsopt->data)); 11978cc676e6SMatthew G Knepley } 1198648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set)); 119910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man))); 12003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12018cc676e6SMatthew G Knepley } 1202