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 20ce78bad3SBarry Smith 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 */ 35ce78bad3SBarry Smith 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 */ 60ce78bad3SBarry Smith 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 */ 81ce78bad3SBarry Smith 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 static const char *OptionsHeader = "<head>\n" 13410450e9eSJacob Faibussowitsch "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/jquery-1.9.1.js\"></script>\n" 13510450e9eSJacob Faibussowitsch "<script type=\"text/javascript\" src=\"https://www.mcs.anl.gov/research/projects/saws/js/SAWs.js\"></script>\n" 13610450e9eSJacob Faibussowitsch "<script type=\"text/javascript\" src=\"js/PETSc.js\"></script>\n" 13710450e9eSJacob Faibussowitsch "<script>\n" 13810450e9eSJacob Faibussowitsch "jQuery(document).ready(function() {\n" 13910450e9eSJacob Faibussowitsch "PETSc.getAndDisplayDirectory(null,\"#variablesInfo\")\n" 14010450e9eSJacob Faibussowitsch "})\n" 14110450e9eSJacob Faibussowitsch "</script>\n" 14210450e9eSJacob Faibussowitsch "</head>\n"; 14310450e9eSJacob Faibussowitsch 14410450e9eSJacob Faibussowitsch /* Determines the size and style of the scroll region where PETSc options selectable from users are displayed */ 14510450e9eSJacob Faibussowitsch static const char *OptionsBodyBottom = "<div id=\"variablesInfo\" style=\"background-color:lightblue;height:auto;max-height:500px;overflow:scroll;\"></div>\n<br>\n</body>"; 14610450e9eSJacob Faibussowitsch 14710450e9eSJacob Faibussowitsch /* 14810450e9eSJacob Faibussowitsch PetscOptionsSAWsInput - Presents all the PETSc Options processed by the program so the user may change them at runtime using the SAWs 14910450e9eSJacob Faibussowitsch 15010450e9eSJacob Faibussowitsch Bugs: 15110450e9eSJacob Faibussowitsch + All processes must traverse through the exact same set of option queries due to the call to PetscScanString() 15210450e9eSJacob Faibussowitsch . Internal strings have arbitrary length and string copies are not checked that they fit into string space 15310450e9eSJacob Faibussowitsch - Only works for PetscInt == int, PetscReal == double etc 15410450e9eSJacob Faibussowitsch 15510450e9eSJacob Faibussowitsch */ 156ce78bad3SBarry Smith static PetscErrorCode PetscOptionsSAWsInput(PetscOptionItems PetscOptionsObject) 15710450e9eSJacob Faibussowitsch { 15810450e9eSJacob Faibussowitsch PetscOptionItem next = PetscOptionsObject->next; 15910450e9eSJacob Faibussowitsch static int mancount = 0; 16010450e9eSJacob Faibussowitsch char options[16]; 16110450e9eSJacob Faibussowitsch PetscBool changedmethod = PETSC_FALSE; 16210450e9eSJacob Faibussowitsch PetscBool stopasking = PETSC_FALSE; 16310450e9eSJacob Faibussowitsch char manname[16], textname[16]; 16410450e9eSJacob Faibussowitsch char dir[1024]; 16510450e9eSJacob Faibussowitsch 16610450e9eSJacob Faibussowitsch PetscFunctionBegin; 16710450e9eSJacob Faibussowitsch /* the next line is a bug, this will only work if all processors are here, the comm passed in is ignored!!! */ 16810450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(options, PETSC_STATIC_ARRAY_LENGTH(options), "Options_%d", count++)); 16910450e9eSJacob Faibussowitsch 17010450e9eSJacob Faibussowitsch PetscOptionsObject->pprefix = PetscOptionsObject->prefix; /* SAWs will change this, so cannot pass prefix directly */ 17110450e9eSJacob Faibussowitsch 17210450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "_title")); 17310450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->title, 1, SAWs_READ, SAWs_STRING)); 17410450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", "prefix")); 17510450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &PetscOptionsObject->pprefix, 1, SAWs_READ, SAWs_STRING)); 17610450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, ("/PETSc/Options/ChangedMethod", &changedmethod, 1, SAWs_WRITE, SAWs_BOOLEAN)); 17710450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, ("/PETSc/Options/StopAsking", &stopasking, 1, SAWs_WRITE, SAWs_BOOLEAN)); 17810450e9eSJacob Faibussowitsch 17910450e9eSJacob Faibussowitsch while (next) { 18010450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(manname, PETSC_STATIC_ARRAY_LENGTH(manname), "_man_%d", mancount)); 18110450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", manname)); 18210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->man, 1, SAWs_READ, SAWs_STRING)); 18310450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(textname, PETSC_STATIC_ARRAY_LENGTH(textname), "_text_%d", mancount++)); 18410450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", textname)); 18510450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->text, 1, SAWs_READ, SAWs_STRING)); 18610450e9eSJacob Faibussowitsch 18710450e9eSJacob Faibussowitsch switch (next->type) { 18810450e9eSJacob Faibussowitsch case OPTION_HEAD: 18910450e9eSJacob Faibussowitsch break; 19010450e9eSJacob Faibussowitsch case OPTION_INT_ARRAY: 19110450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 19210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_INT)); 19310450e9eSJacob Faibussowitsch break; 19410450e9eSJacob Faibussowitsch case OPTION_REAL_ARRAY: 19510450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 19610450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_DOUBLE)); 19710450e9eSJacob Faibussowitsch break; 19810450e9eSJacob Faibussowitsch case OPTION_INT: 19910450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 20010450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_INT)); 20110450e9eSJacob Faibussowitsch break; 20210450e9eSJacob Faibussowitsch case OPTION_REAL: 20310450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 20410450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_DOUBLE)); 20510450e9eSJacob Faibussowitsch break; 20610450e9eSJacob Faibussowitsch case OPTION_BOOL: 20710450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 20810450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, 1, SAWs_WRITE, SAWs_BOOLEAN)); 20910450e9eSJacob Faibussowitsch break; 21010450e9eSJacob Faibussowitsch case OPTION_BOOL_ARRAY: 21110450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 21210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_BOOLEAN)); 21310450e9eSJacob Faibussowitsch break; 21410450e9eSJacob Faibussowitsch case OPTION_STRING: 21510450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 21610450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING)); 21710450e9eSJacob Faibussowitsch break; 21810450e9eSJacob Faibussowitsch case OPTION_STRING_ARRAY: 21910450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 22010450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, next->data, next->arraylength, SAWs_WRITE, SAWs_STRING)); 22110450e9eSJacob Faibussowitsch break; 22210450e9eSJacob Faibussowitsch case OPTION_FLIST: { 22310450e9eSJacob Faibussowitsch PetscInt ntext; 22410450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 22510450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING)); 22610450e9eSJacob Faibussowitsch PetscCall(PetscFunctionListGet(next->flist, (const char ***)&next->edata, &ntext)); 22710450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata)); 22810450e9eSJacob Faibussowitsch } break; 22910450e9eSJacob Faibussowitsch case OPTION_ELIST: { 23010450e9eSJacob Faibussowitsch PetscInt ntext = next->nlist; 23110450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 23210450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Register, (dir, &next->data, 1, SAWs_WRITE, SAWs_STRING)); 23357508eceSPierre Jolivet PetscCall(PetscMalloc1(ntext + 1, (char ***)&next->edata)); 23410450e9eSJacob Faibussowitsch PetscCall(PetscMemcpy(next->edata, next->list, ntext * sizeof(char *))); 23510450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Set_Legal_Variable_Values, (dir, ntext, next->edata)); 23610450e9eSJacob Faibussowitsch } break; 23710450e9eSJacob Faibussowitsch default: 23810450e9eSJacob Faibussowitsch break; 23910450e9eSJacob Faibussowitsch } 24010450e9eSJacob Faibussowitsch next = next->next; 24110450e9eSJacob Faibussowitsch } 24210450e9eSJacob Faibussowitsch 24310450e9eSJacob Faibussowitsch /* wait until accessor has unlocked the memory */ 24410450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Push_Header, ("index.html", OptionsHeader)); 24510450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Push_Body, ("index.html", 2, OptionsBodyBottom)); 24610450e9eSJacob Faibussowitsch PetscCall(PetscSAWsBlock()); 24710450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Pop_Header, ("index.html")); 24810450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Pop_Body, ("index.html", 2)); 24910450e9eSJacob Faibussowitsch 25010450e9eSJacob Faibussowitsch /* determine if any values have been set in GUI */ 25110450e9eSJacob Faibussowitsch next = PetscOptionsObject->next; 25210450e9eSJacob Faibussowitsch while (next) { 25310450e9eSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Options/%s", next->option)); 25410450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Selected, (dir, (int *)&next->set)); 25510450e9eSJacob Faibussowitsch next = next->next; 25610450e9eSJacob Faibussowitsch } 25710450e9eSJacob Faibussowitsch 25810450e9eSJacob Faibussowitsch /* reset counter to -2; this updates the screen with the new options for the selected method */ 25910450e9eSJacob Faibussowitsch if (changedmethod) PetscOptionsObject->count = -2; 26010450e9eSJacob Faibussowitsch 26110450e9eSJacob Faibussowitsch if (stopasking) { 26210450e9eSJacob Faibussowitsch PetscOptionsPublish = PETSC_FALSE; 26310450e9eSJacob Faibussowitsch PetscOptionsObject->count = 0; //do not ask for same thing again 26410450e9eSJacob Faibussowitsch } 26510450e9eSJacob Faibussowitsch 26610450e9eSJacob Faibussowitsch PetscCallSAWs(SAWs_Delete, ("/PETSc/Options")); 26710450e9eSJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26810450e9eSJacob Faibussowitsch } 26910450e9eSJacob Faibussowitsch #else 27010450e9eSJacob Faibussowitsch /* 2713fc1eb6aSBarry Smith PetscScanString - Gets user input via stdin from process and broadcasts to all processes 2723fc1eb6aSBarry Smith 273d083f849SBarry Smith Collective 2743fc1eb6aSBarry Smith 2753fc1eb6aSBarry Smith Input Parameters: 2763fc1eb6aSBarry Smith + commm - communicator for the broadcast, must be PETSC_COMM_WORLD 2773fc1eb6aSBarry Smith . n - length of the string, must be the same on all processes 2783fc1eb6aSBarry Smith - str - location to store input 279aee2cecaSBarry Smith 280aee2cecaSBarry Smith Bugs: 281aee2cecaSBarry Smith . Assumes process 0 of the given communicator has access to stdin 282aee2cecaSBarry Smith 283aee2cecaSBarry Smith */ 284d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscScanString(MPI_Comm comm, size_t n, char str[]) 285d71ae5a4SJacob Faibussowitsch { 2863fc1eb6aSBarry Smith PetscMPIInt rank, nm; 287aee2cecaSBarry Smith 288aee2cecaSBarry Smith PetscFunctionBegin; 2899566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 290dd400576SPatrick Sanan if (rank == 0) { 2915f80ce2aSJacob Faibussowitsch char c = (char)getchar(); 2925f80ce2aSJacob Faibussowitsch size_t i = 0; 2935f80ce2aSJacob Faibussowitsch 294aee2cecaSBarry Smith while (c != '\n' && i < n - 1) { 295aee2cecaSBarry Smith str[i++] = c; 296aee2cecaSBarry Smith c = (char)getchar(); 297aee2cecaSBarry Smith } 29810c654e6SJacob Faibussowitsch str[i] = '\0'; 299aee2cecaSBarry Smith } 3009566063dSJacob Faibussowitsch PetscCall(PetscMPIIntCast(n, &nm)); 3019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Bcast(str, nm, MPI_CHAR, 0, comm)); 3023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 303aee2cecaSBarry Smith } 304aee2cecaSBarry Smith 3055b02f95dSBarry Smith /* 3063cc1e11dSBarry Smith PetscOptionsGetFromTextInput - Presents all the PETSc Options processed by the program so the user may change them at runtime 307aee2cecaSBarry Smith 30895452b02SPatrick Sanan Notes: 30995452b02SPatrick Sanan this isn't really practical, it is just to demonstrate the principle 310aee2cecaSBarry Smith 3117781c08eSBarry Smith A carriage return indicates no change from the default; but this like -ksp_monitor <stdout> the default is actually not stdout the default 3127781c08eSBarry Smith is to do nothing so to get it to use stdout you need to type stdout. This is kind of bug? 3137781c08eSBarry Smith 314aee2cecaSBarry Smith Bugs: 3157781c08eSBarry Smith + All processes must traverse through the exact same set of option queries due to the call to PetscScanString() 3163cc1e11dSBarry Smith . Internal strings have arbitrary length and string copies are not checked that they fit into string space 317aee2cecaSBarry Smith - Only works for PetscInt == int, PetscReal == double etc 318aee2cecaSBarry Smith 319aec76313SJacob Faibussowitsch Developer Notes: 32095452b02SPatrick Sanan Normally the GUI that presents the options the user and retrieves the values would be running in a different 3213cc1e11dSBarry Smith address space and communicating with the PETSc program 3223cc1e11dSBarry Smith 323aee2cecaSBarry Smith */ 324ce78bad3SBarry Smith static PetscErrorCode PetscOptionsGetFromTextInput(PetscOptionItems PetscOptionsObject) 325d71ae5a4SJacob Faibussowitsch { 3264416b707SBarry Smith PetscOptionItem next = PetscOptionsObject->next; 3276356e834SBarry Smith char str[512]; 3287781c08eSBarry Smith PetscBool bid; 329a4404d99SBarry Smith PetscReal ir, *valr; 330330cf3c9SBarry Smith PetscInt *vald; 3316356e834SBarry Smith 3322a409bb0SBarry Smith PetscFunctionBegin; 3339566063dSJacob Faibussowitsch PetscCall((*PetscPrintf)(PETSC_COMM_WORLD, "%s --------------------\n", PetscOptionsObject->title)); 3346356e834SBarry Smith while (next) { 3356356e834SBarry Smith switch (next->type) { 336d71ae5a4SJacob Faibussowitsch case OPTION_HEAD: 337d71ae5a4SJacob Faibussowitsch break; 338e26ddf31SBarry Smith case OPTION_INT_ARRAY: 3394bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1)); 340e26ddf31SBarry Smith vald = (PetscInt *)next->data; 3416497c311SBarry Smith for (PetscInt i = 0; i < next->arraylength; i++) { 3429566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%" PetscInt_FMT, vald[i])); 34348a46eb9SPierre Jolivet if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ",")); 344e26ddf31SBarry Smith } 3459566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man)); 3469566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 347e26ddf31SBarry Smith if (str[0]) { 348e26ddf31SBarry Smith PetscToken token; 349e26ddf31SBarry Smith PetscInt n = 0, nmax = next->arraylength, *dvalue = (PetscInt *)next->data, start, end; 350ce78bad3SBarry Smith size_t len; 351ce78bad3SBarry Smith const char *value; 352ace3abfcSBarry Smith PetscBool foundrange; 353e26ddf31SBarry Smith 354e26ddf31SBarry Smith next->set = PETSC_TRUE; 355e26ddf31SBarry Smith value = str; 3569566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(value, ',', &token)); 3579566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 358e26ddf31SBarry Smith while (n < nmax) { 359ce78bad3SBarry Smith char *ivalue; 360ce78bad3SBarry Smith PetscInt i; 361ce78bad3SBarry Smith 362e26ddf31SBarry Smith if (!value) break; 363ce78bad3SBarry Smith PetscCall(PetscStrallocpy(value, &ivalue)); 364e26ddf31SBarry Smith 365e26ddf31SBarry Smith /* look for form d-D where d and D are integers */ 366e26ddf31SBarry Smith foundrange = PETSC_FALSE; 367ce78bad3SBarry Smith PetscCall(PetscStrlen(ivalue, &len)); 368ce78bad3SBarry Smith if (ivalue[0] == '-') i = 2; 369e26ddf31SBarry Smith else i = 1; 370ce78bad3SBarry Smith for (; i < (PetscInt)len; i++) { 371ce78bad3SBarry Smith if (ivalue[i] == '-') { 372ce78bad3SBarry Smith PetscCheck(i != (PetscInt)(len - 1), PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry %s", n, ivalue); 373ce78bad3SBarry Smith ivalue[i] = 0; 374ce78bad3SBarry Smith PetscCall(PetscOptionsStringToInt(ivalue, &start)); 375ce78bad3SBarry Smith PetscCall(PetscOptionsStringToInt(ivalue + i + 1, &end)); 376ce78bad3SBarry Smith PetscCheck(end > start, PETSC_COMM_SELF, PETSC_ERR_USER, "Error in %" PetscInt_FMT "-th array entry, %s-%s cannot have decreasing list", n, ivalue, ivalue + i + 1); 377cc73adaaSBarry 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); 378e26ddf31SBarry Smith for (; start < end; start++) { 3799371c9d4SSatish Balay *dvalue = start; 3809371c9d4SSatish Balay dvalue++; 3819371c9d4SSatish Balay n++; 382e26ddf31SBarry Smith } 383e26ddf31SBarry Smith foundrange = PETSC_TRUE; 384e26ddf31SBarry Smith break; 385e26ddf31SBarry Smith } 386e26ddf31SBarry Smith } 387e26ddf31SBarry Smith if (!foundrange) { 388ce78bad3SBarry Smith PetscCall(PetscOptionsStringToInt(ivalue, dvalue)); 389e26ddf31SBarry Smith dvalue++; 390e26ddf31SBarry Smith n++; 391e26ddf31SBarry Smith } 392ce78bad3SBarry Smith PetscCall(PetscFree(ivalue)); 3939566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 394e26ddf31SBarry Smith } 3959566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 396e26ddf31SBarry Smith } 397e26ddf31SBarry Smith break; 398e26ddf31SBarry Smith case OPTION_REAL_ARRAY: 3994bb2516aSBarry Smith PetscCall(PetscPrintf(PETSC_COMM_WORLD, "-%s%s: <", PetscOptionsObject->prefix ? PetscOptionsObject->prefix : "", next->option + 1)); 400e26ddf31SBarry Smith valr = (PetscReal *)next->data; 4016497c311SBarry Smith for (PetscInt i = 0; i < next->arraylength; i++) { 4029566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, "%g", (double)valr[i])); 40348a46eb9SPierre Jolivet if (i < next->arraylength - 1) PetscCall(PetscPrintf(PETSC_COMM_WORLD, ",")); 404e26ddf31SBarry Smith } 4059566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PETSC_COMM_WORLD, ">: %s (%s) ", next->text, next->man)); 4069566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 407e26ddf31SBarry Smith if (str[0]) { 408e26ddf31SBarry Smith PetscToken token; 409e26ddf31SBarry Smith PetscInt n = 0, nmax = next->arraylength; 410e26ddf31SBarry Smith PetscReal *dvalue = (PetscReal *)next->data; 411ce78bad3SBarry Smith const char *value; 412e26ddf31SBarry Smith 413e26ddf31SBarry Smith next->set = PETSC_TRUE; 414e26ddf31SBarry Smith value = str; 4159566063dSJacob Faibussowitsch PetscCall(PetscTokenCreate(value, ',', &token)); 4169566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 417e26ddf31SBarry Smith while (n < nmax) { 418e26ddf31SBarry Smith if (!value) break; 4199566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToReal(value, dvalue)); 420e26ddf31SBarry Smith dvalue++; 421e26ddf31SBarry Smith n++; 4229566063dSJacob Faibussowitsch PetscCall(PetscTokenFind(token, &value)); 423e26ddf31SBarry Smith } 4249566063dSJacob Faibussowitsch PetscCall(PetscTokenDestroy(&token)); 425e26ddf31SBarry Smith } 426e26ddf31SBarry Smith break; 4276356e834SBarry Smith case OPTION_INT: 4284bb2516aSBarry 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)); 4299566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4303fc1eb6aSBarry Smith if (str[0]) { 431d25d7f95SJed Brown #if defined(PETSC_SIZEOF_LONG_LONG) 432d25d7f95SJed Brown long long lid; 433d25d7f95SJed Brown sscanf(str, "%lld", &lid); 4341690c2aeSBarry 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); 435c272547aSJed Brown #else 436d25d7f95SJed Brown long lid; 437d25d7f95SJed Brown sscanf(str, "%ld", &lid); 4381690c2aeSBarry 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); 439c272547aSJed Brown #endif 440a297a907SKarl Rupp 441d25d7f95SJed Brown next->set = PETSC_TRUE; 442d25d7f95SJed Brown *((PetscInt *)next->data) = (PetscInt)lid; 443aee2cecaSBarry Smith } 444aee2cecaSBarry Smith break; 445aee2cecaSBarry Smith case OPTION_REAL: 4464bb2516aSBarry 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)); 4479566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4483fc1eb6aSBarry Smith if (str[0]) { 449ce63c4c1SBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 450a4404d99SBarry Smith sscanf(str, "%e", &ir); 451570b7f6dSBarry Smith #elif defined(PETSC_USE_REAL___FP16) 452570b7f6dSBarry Smith float irtemp; 453570b7f6dSBarry Smith sscanf(str, "%e", &irtemp); 454570b7f6dSBarry Smith ir = irtemp; 455ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL_DOUBLE) 456aee2cecaSBarry Smith sscanf(str, "%le", &ir); 457ce63c4c1SBarry Smith #elif defined(PETSC_USE_REAL___FLOAT128) 458d9822059SBarry Smith ir = strtoflt128(str, 0); 459d9822059SBarry Smith #else 460513dbe71SLisandro Dalcin SETERRQ(PETSC_COMM_SELF, PETSC_ERR_LIB, "Unknown scalar type"); 461a4404d99SBarry Smith #endif 462aee2cecaSBarry Smith next->set = PETSC_TRUE; 463aee2cecaSBarry Smith *((PetscReal *)next->data) = ir; 464aee2cecaSBarry Smith } 465aee2cecaSBarry Smith break; 4667781c08eSBarry Smith case OPTION_BOOL: 4674bb2516aSBarry 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)); 4689566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4697781c08eSBarry Smith if (str[0]) { 4709566063dSJacob Faibussowitsch PetscCall(PetscOptionsStringToBool(str, &bid)); 4717781c08eSBarry Smith next->set = PETSC_TRUE; 4727781c08eSBarry Smith *((PetscBool *)next->data) = bid; 4737781c08eSBarry Smith } 4747781c08eSBarry Smith break; 475aee2cecaSBarry Smith case OPTION_STRING: 4764bb2516aSBarry 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)); 4779566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4783fc1eb6aSBarry Smith if (str[0]) { 479aee2cecaSBarry Smith next->set = PETSC_TRUE; 48064facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 4819566063dSJacob Faibussowitsch PetscCall(PetscStrdup(str, (char **)&next->data)); 4826356e834SBarry Smith } 4836356e834SBarry Smith break; 484a264d7a6SBarry Smith case OPTION_FLIST: 4859566063dSJacob Faibussowitsch PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, stdout, PetscOptionsObject->prefix, next->option, next->text, next->man, next->flist, (char *)next->data, (char *)next->data)); 4869566063dSJacob Faibussowitsch PetscCall(PetscScanString(PETSC_COMM_WORLD, 512, str)); 4873cc1e11dSBarry Smith if (str[0]) { 488e55864a3SBarry Smith PetscOptionsObject->changedmethod = PETSC_TRUE; 4893cc1e11dSBarry Smith next->set = PETSC_TRUE; 49064facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 4919566063dSJacob Faibussowitsch PetscCall(PetscStrdup(str, (char **)&next->data)); 4923cc1e11dSBarry Smith } 4933cc1e11dSBarry Smith break; 494d71ae5a4SJacob Faibussowitsch default: 495d71ae5a4SJacob Faibussowitsch break; 4966356e834SBarry Smith } 4976356e834SBarry Smith next = next->next; 4986356e834SBarry Smith } 4993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5006356e834SBarry Smith } 501b3506946SBarry Smith #endif 502b3506946SBarry Smith 503ce78bad3SBarry Smith PetscErrorCode PetscOptionsEnd_Private(PetscOptionItems PetscOptionsObject) 504d71ae5a4SJacob Faibussowitsch { 50510c654e6SJacob Faibussowitsch PetscOptionItem next, last; 50653acd3b1SBarry Smith 50753acd3b1SBarry Smith PetscFunctionBegin; 50883355fc5SBarry Smith if (PetscOptionsObject->next) { 50983355fc5SBarry Smith if (!PetscOptionsObject->count) { 510a264d7a6SBarry Smith #if defined(PETSC_HAVE_SAWS) 5119566063dSJacob Faibussowitsch PetscCall(PetscOptionsSAWsInput(PetscOptionsObject)); 512b3506946SBarry Smith #else 5139566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetFromTextInput(PetscOptionsObject)); 514b3506946SBarry Smith #endif 515aee2cecaSBarry Smith } 516aee2cecaSBarry Smith } 5176356e834SBarry Smith 5189566063dSJacob Faibussowitsch PetscCall(PetscFree(PetscOptionsObject->title)); 5196356e834SBarry Smith 520e26ddf31SBarry Smith /* reset counter to -2; this updates the screen with the new options for the selected method */ 521e55864a3SBarry Smith if (PetscOptionsObject->changedmethod) PetscOptionsObject->count = -2; 5227a72a596SBarry Smith /* reset alreadyprinted flag */ 523e55864a3SBarry Smith PetscOptionsObject->alreadyprinted = PETSC_FALSE; 524e55864a3SBarry Smith if (PetscOptionsObject->object) PetscOptionsObject->object->optionsprinted = PETSC_TRUE; 525e55864a3SBarry Smith PetscOptionsObject->object = NULL; 52653acd3b1SBarry Smith 52710c654e6SJacob Faibussowitsch while ((next = PetscOptionsObject->next)) { 52810c654e6SJacob Faibussowitsch const PetscOptionType type = next->type; 52910c654e6SJacob Faibussowitsch const size_t arraylength = next->arraylength; 53010c654e6SJacob Faibussowitsch void *data = next->data; 53110c654e6SJacob Faibussowitsch 53210c654e6SJacob Faibussowitsch if (next->set) { 53310c654e6SJacob Faibussowitsch char option[256], value[1024], tmp[32]; 53410c654e6SJacob Faibussowitsch 535e55864a3SBarry Smith if (PetscOptionsObject->prefix) { 536c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(option, "-", sizeof(option))); 537c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(option, PetscOptionsObject->prefix, sizeof(option))); 53810c654e6SJacob Faibussowitsch PetscCall(PetscStrlcat(option, next->option + 1, sizeof(option))); 53910c654e6SJacob Faibussowitsch } else { 54010c654e6SJacob Faibussowitsch PetscCall(PetscStrncpy(option, next->option, sizeof(option))); 54110c654e6SJacob Faibussowitsch } 5426356e834SBarry Smith 54310c654e6SJacob Faibussowitsch switch (type) { 544d71ae5a4SJacob Faibussowitsch case OPTION_HEAD: 545d71ae5a4SJacob Faibussowitsch break; 5466356e834SBarry Smith case OPTION_INT_ARRAY: 547835f2295SStefano Zampini PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%" PetscInt_FMT, ((PetscInt *)data)[0])); 54810c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 549835f2295SStefano Zampini PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%" PetscInt_FMT, ((PetscInt *)data)[j])); 550c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 551c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5526356e834SBarry Smith } 5536356e834SBarry Smith break; 554d71ae5a4SJacob Faibussowitsch case OPTION_INT: 555835f2295SStefano Zampini PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%" PetscInt_FMT, *(PetscInt *)data)); 556d71ae5a4SJacob Faibussowitsch break; 557d71ae5a4SJacob Faibussowitsch case OPTION_REAL: 55810c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)*(PetscReal *)data)); 559d71ae5a4SJacob Faibussowitsch break; 5606356e834SBarry Smith case OPTION_REAL_ARRAY: 56110c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g", (double)((PetscReal *)data)[0])); 56210c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 56310c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g", (double)((PetscReal *)data)[j])); 564c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 565c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5666356e834SBarry Smith } 5676356e834SBarry Smith break; 568050cccc3SHong Zhang case OPTION_SCALAR_ARRAY: 56910c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[0]), (double)PetscImaginaryPart(((PetscScalar *)data)[0]))); 57010c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 57110c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%g+%gi", (double)PetscRealPart(((PetscScalar *)data)[j]), (double)PetscImaginaryPart(((PetscScalar *)data)[j]))); 572c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 573c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 574050cccc3SHong Zhang } 575050cccc3SHong Zhang break; 576d71ae5a4SJacob Faibussowitsch case OPTION_BOOL: 57710c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", *(int *)data)); 578d71ae5a4SJacob Faibussowitsch break; 5797781c08eSBarry Smith case OPTION_BOOL_ARRAY: 58010c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%d", (int)((PetscBool *)data)[0])); 58110c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; ++j) { 58210c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%d", (int)((PetscBool *)data)[j])); 583c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 584c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5851ae3d29cSBarry Smith } 5861ae3d29cSBarry Smith break; 58710c654e6SJacob Faibussowitsch case OPTION_FLIST: // fall-through 58810c654e6SJacob Faibussowitsch case OPTION_ELIST: // fall-through 589d71ae5a4SJacob Faibussowitsch case OPTION_STRING: 59010c654e6SJacob Faibussowitsch PetscCall(PetscStrncpy(value, (char *)data, sizeof(value))); 591d71ae5a4SJacob Faibussowitsch break; 5921ae3d29cSBarry Smith case OPTION_STRING_ARRAY: 59310c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(value, PETSC_STATIC_ARRAY_LENGTH(value), "%s", ((char **)data)[0])); 59410c654e6SJacob Faibussowitsch for (size_t j = 1; j < arraylength; j++) { 59510c654e6SJacob Faibussowitsch PetscCall(PetscSNPrintf(tmp, PETSC_STATIC_ARRAY_LENGTH(tmp), "%s", ((char **)data)[j])); 596c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, ",", sizeof(value))); 597c6a7a370SJeremy L Thompson PetscCall(PetscStrlcat(value, tmp, sizeof(value))); 5981ae3d29cSBarry Smith } 5996356e834SBarry Smith break; 6006356e834SBarry Smith } 6019566063dSJacob Faibussowitsch PetscCall(PetscOptionsSetValue(PetscOptionsObject->options, option, value)); 6026356e834SBarry Smith } 60310c654e6SJacob Faibussowitsch if (type == OPTION_ELIST) PetscCall(PetscStrNArrayDestroy(next->nlist, (char ***)&next->list)); 60410c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->text)); 60510c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->option)); 60610c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->man)); 60710c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->edata)); 608c979a496SBarry Smith 60910c654e6SJacob Faibussowitsch if (type == OPTION_STRING || type == OPTION_FLIST || type == OPTION_ELIST) { 61010c654e6SJacob Faibussowitsch free(data); 611c979a496SBarry Smith } else { 61210c654e6SJacob Faibussowitsch // use next->data instead of data because PetscFree() sets it to NULL 61310c654e6SJacob Faibussowitsch PetscCall(PetscFree(next->data)); 614c979a496SBarry Smith } 6157781c08eSBarry Smith 61610c654e6SJacob Faibussowitsch last = next; 61710c654e6SJacob Faibussowitsch PetscOptionsObject->next = next->next; 6189566063dSJacob Faibussowitsch PetscCall(PetscFree(last)); 6196356e834SBarry Smith } 6209566063dSJacob Faibussowitsch PetscCall(PetscFree(PetscOptionsObject->prefix)); 62102c9f0b5SLisandro Dalcin PetscOptionsObject->next = NULL; 6223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 62353acd3b1SBarry Smith } 62453acd3b1SBarry Smith 62510c654e6SJacob Faibussowitsch static PetscErrorCode GetListLength(const char *const *list, PetscInt *len) 62610c654e6SJacob Faibussowitsch { 62710c654e6SJacob Faibussowitsch PetscInt retlen = 0; 62810c654e6SJacob Faibussowitsch 62910c654e6SJacob Faibussowitsch PetscFunctionBegin; 6304f572ea9SToby Isaac PetscAssertPointer(len, 2); 63110c654e6SJacob Faibussowitsch while (list[retlen]) { 6324f572ea9SToby Isaac PetscAssertPointer(list[retlen], 1); 63310c654e6SJacob Faibussowitsch PetscCheck(++retlen < 50, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "List argument appears to be wrong or have more than 50 entries"); 63410c654e6SJacob Faibussowitsch } 63510c654e6SJacob Faibussowitsch PetscCheck(retlen > 2, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "List argument must have at least 2 entries: typename and type prefix"); 63610c654e6SJacob Faibussowitsch /* drop item name and prefix*/ 63710c654e6SJacob Faibussowitsch *len = retlen - 2; 63810c654e6SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 63910c654e6SJacob Faibussowitsch } 64010c654e6SJacob Faibussowitsch 641ce78bad3SBarry Smith PetscErrorCode PetscOptionsEnum_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum currentvalue, PetscEnum *value, PetscBool *set) 642d71ae5a4SJacob Faibussowitsch { 64353acd3b1SBarry Smith PetscInt ntext = 0; 644aa5bb8c0SSatish Balay PetscInt tval; 645ace3abfcSBarry Smith PetscBool tflg; 64653acd3b1SBarry Smith 64753acd3b1SBarry Smith PetscFunctionBegin; 6484f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6494f572ea9SToby Isaac PetscAssertPointer(list, 5); 6504f572ea9SToby Isaac PetscAssertPointer(value, 7); 6514f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 65210c654e6SJacob Faibussowitsch PetscCall(GetListLength(list, &ntext)); 6531163e504SMatthew G. Knepley PetscCall(PetscOptionsEList_Private(PetscOptionsObject, opt, text, man, list, ntext, list[(int)currentvalue], &tval, &tflg)); 654aa5bb8c0SSatish Balay /* with PETSC_USE_64BIT_INDICES sizeof(PetscInt) != sizeof(PetscEnum) */ 655aa5bb8c0SSatish Balay if (tflg) *value = (PetscEnum)tval; 656aa5bb8c0SSatish Balay if (set) *set = tflg; 6573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 65853acd3b1SBarry Smith } 65953acd3b1SBarry Smith 660ce78bad3SBarry Smith PetscErrorCode PetscOptionsEnumArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char *const *list, PetscEnum value[], PetscInt *n, PetscBool *set) 661d71ae5a4SJacob Faibussowitsch { 66210c654e6SJacob Faibussowitsch PetscInt nlist = 0; 66310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 664d3e47460SLisandro Dalcin 665d3e47460SLisandro Dalcin PetscFunctionBegin; 6664f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6674f572ea9SToby Isaac PetscAssertPointer(list, 5); 6684f572ea9SToby Isaac PetscAssertPointer(value, 6); 6694f572ea9SToby Isaac PetscAssertPointer(n, 7); 67010c654e6SJacob Faibussowitsch PetscCheck(*n > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") must be > 0", *n); 6714f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 67210c654e6SJacob Faibussowitsch PetscCall(GetListLength(list, &nlist)); 67310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetEnumArray(PetscOptionsObject->options, prefix, opt, list, value, n, set)); 67410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 67510c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 67610c654e6SJacob Faibussowitsch const PetscInt nv = *n; 67710c654e6SJacob Faibussowitsch 67810c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s", Prefix(prefix), opt + 1, list[value[0]])); 67910c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%s", list[value[i]])); 68010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (choose from)", text)); 68110c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nlist; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i])); 68210c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man))); 683d3e47460SLisandro Dalcin } 6843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 685d3e47460SLisandro Dalcin } 686d3e47460SLisandro Dalcin 687ce78bad3SBarry Smith PetscErrorCode PetscOptionsInt_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt currentvalue, PetscInt *value, PetscBool *set, PetscInt lb, PetscInt ub) 688d71ae5a4SJacob Faibussowitsch { 68910c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 69010c654e6SJacob Faibussowitsch const PetscOptions options = PetscOptionsObject->options; 69112655325SBarry Smith PetscBool wasset; 69253acd3b1SBarry Smith 69353acd3b1SBarry Smith PetscFunctionBegin; 6944f572ea9SToby Isaac PetscAssertPointer(opt, 2); 6954f572ea9SToby Isaac PetscAssertPointer(value, 6); 6964f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 69708401ef6SPierre Jolivet PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " less than allowed bound %" PetscInt_FMT, currentvalue, lb); 69808401ef6SPierre Jolivet PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %" PetscInt_FMT " greater than allowed bound %" PetscInt_FMT, currentvalue, ub); 699e55864a3SBarry Smith if (!PetscOptionsObject->count) { 70010c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 70110c654e6SJacob Faibussowitsch 7029566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt)); 7039566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data)); 70412655325SBarry Smith *(PetscInt *)amsopt->data = currentvalue; 7053e211508SBarry Smith 70610c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetInt(options, prefix, opt, ¤tvalue, &wasset)); 707ad540459SPierre Jolivet if (wasset) *(PetscInt *)amsopt->data = currentvalue; 708af6d86caSBarry Smith } 70910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetInt(options, prefix, opt, value, &wasset)); 710cc73adaaSBarry 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); 711cc73adaaSBarry 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); 71244ef3d73SBarry Smith if (set) *set = wasset; 71310c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 71410c654e6SJacob 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))); 71553acd3b1SBarry Smith } 7163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71753acd3b1SBarry Smith } 71853acd3b1SBarry Smith 719ce78bad3SBarry 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) 7206497c311SBarry Smith { 7216497c311SBarry Smith const char *prefix = PetscOptionsObject->prefix; 7226497c311SBarry Smith const PetscOptions options = PetscOptionsObject->options; 7236497c311SBarry Smith PetscBool wasset; 7246497c311SBarry Smith 7256497c311SBarry Smith PetscFunctionBegin; 7266497c311SBarry Smith PetscAssertPointer(opt, 2); 7276497c311SBarry Smith PetscAssertPointer(value, 6); 7286497c311SBarry Smith if (set) PetscAssertPointer(set, 7); 7296497c311SBarry Smith PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d less than allowed bound %d", currentvalue, lb); 7306497c311SBarry Smith PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %d greater than allowed bound %d", currentvalue, ub); 7316497c311SBarry Smith if (!PetscOptionsObject->count) { 7326497c311SBarry Smith PetscOptionItem amsopt; 7336497c311SBarry Smith 7346497c311SBarry Smith PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT, &amsopt)); 7356497c311SBarry Smith PetscCall(PetscMalloc(sizeof(PetscInt), &amsopt->data)); 7366497c311SBarry Smith *(PetscMPIInt *)amsopt->data = currentvalue; 7376497c311SBarry Smith 7386497c311SBarry Smith PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, ¤tvalue, &wasset)); 7396497c311SBarry Smith if (wasset) *(PetscMPIInt *)amsopt->data = currentvalue; 7406497c311SBarry Smith } 7416497c311SBarry Smith PetscCall(PetscOptionsGetMPIInt(options, prefix, opt, value, &wasset)); 7426497c311SBarry Smith PetscCheck(!wasset || *value >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d less than allowed bound %d", *value, lb); 7436497c311SBarry Smith PetscCheck(!wasset || *value <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Newly set value %d greater than allowed bound %d", *value, ub); 7446497c311SBarry Smith if (set) *set = wasset; 7453a7d0413SPierre Jolivet 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))); 7466497c311SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 7476497c311SBarry Smith } 7486497c311SBarry Smith 749ce78bad3SBarry Smith PetscErrorCode PetscOptionsString_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], const char currentvalue[], char value[], size_t len, PetscBool *set) 750d71ae5a4SJacob Faibussowitsch { 75110c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 75244ef3d73SBarry Smith PetscBool lset; 75353acd3b1SBarry Smith 75453acd3b1SBarry Smith PetscFunctionBegin; 7554f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7564f572ea9SToby Isaac PetscAssertPointer(value, 6); 7574f572ea9SToby Isaac if (set) PetscAssertPointer(set, 8); 7581a1499c8SBarry Smith if (!PetscOptionsObject->count) { 75910c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 76010c654e6SJacob Faibussowitsch 7619566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 76264facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 7639566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 764af6d86caSBarry Smith } 76510c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 76644ef3d73SBarry Smith if (set) *set = lset; 76710c654e6SJacob 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))); 7683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76953acd3b1SBarry Smith } 77053acd3b1SBarry Smith 771ce78bad3SBarry Smith PetscErrorCode PetscOptionsReal_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal currentvalue, PetscReal *value, PetscBool *set, PetscReal lb, PetscReal ub) 772d71ae5a4SJacob Faibussowitsch { 77310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 77452ce0ab5SPierre Jolivet const PetscOptions options = PetscOptionsObject->options; 77552ce0ab5SPierre Jolivet PetscBool wasset; 77653acd3b1SBarry Smith 77753acd3b1SBarry Smith PetscFunctionBegin; 7784f572ea9SToby Isaac PetscAssertPointer(opt, 2); 7794f572ea9SToby Isaac PetscAssertPointer(value, 6); 7804f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 78152ce0ab5SPierre Jolivet PetscCheck(currentvalue >= lb, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g less than allowed bound %g", (double)currentvalue, (double)lb); 78252ce0ab5SPierre Jolivet PetscCheck(currentvalue <= ub, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Current value %g greater than allowed bound %g", (double)currentvalue, (double)ub); 783e55864a3SBarry Smith if (!PetscOptionsObject->count) { 78410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 78510c654e6SJacob Faibussowitsch 7869566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL, &amsopt)); 7879566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscReal), &amsopt->data)); 7880fdccdaeSBarry Smith *(PetscReal *)amsopt->data = currentvalue; 78952ce0ab5SPierre Jolivet 79052ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(options, prefix, opt, ¤tvalue, &wasset)); 79152ce0ab5SPierre Jolivet if (wasset) *(PetscReal *)amsopt->data = currentvalue; 792538aa990SBarry Smith } 79352ce0ab5SPierre Jolivet PetscCall(PetscOptionsGetReal(PetscOptionsObject->options, prefix, opt, value, &wasset)); 79452ce0ab5SPierre 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); 79552ce0ab5SPierre 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); 79652ce0ab5SPierre Jolivet if (set) *set = wasset; 79710c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 79852ce0ab5SPierre 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))); 79953acd3b1SBarry Smith } 8003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 80153acd3b1SBarry Smith } 80253acd3b1SBarry Smith 803ce78bad3SBarry Smith PetscErrorCode PetscOptionsScalar_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar currentvalue, PetscScalar *value, PetscBool *set) 804d71ae5a4SJacob Faibussowitsch { 80553acd3b1SBarry Smith PetscFunctionBegin; 80653acd3b1SBarry Smith #if !defined(PETSC_USE_COMPLEX) 8079566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal(opt, text, man, currentvalue, value, set)); 80853acd3b1SBarry Smith #else 8099566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetScalar(PetscOptionsObject->options, PetscOptionsObject->prefix, opt, value, set)); 81053acd3b1SBarry Smith #endif 8113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 81253acd3b1SBarry Smith } 81353acd3b1SBarry Smith 814ce78bad3SBarry Smith PetscErrorCode PetscOptionsName_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 815d71ae5a4SJacob Faibussowitsch { 81610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 81753acd3b1SBarry Smith 81853acd3b1SBarry Smith PetscFunctionBegin; 8194f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8204f572ea9SToby Isaac PetscAssertPointer(flg, 5); 821e55864a3SBarry Smith if (!PetscOptionsObject->count) { 82210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 82310c654e6SJacob Faibussowitsch 8249566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 8259566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 826a297a907SKarl Rupp 827ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 8281ae3d29cSBarry Smith } 82910c654e6SJacob Faibussowitsch PetscCall(PetscOptionsHasName(PetscOptionsObject->options, prefix, opt, flg)); 83010c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 8313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 83253acd3b1SBarry Smith } 83353acd3b1SBarry Smith 834ce78bad3SBarry Smith 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) 835d71ae5a4SJacob Faibussowitsch { 83610c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 83744ef3d73SBarry Smith PetscBool lset; 83853acd3b1SBarry Smith 83953acd3b1SBarry Smith PetscFunctionBegin; 8404f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8414f572ea9SToby Isaac PetscAssertPointer(value, 7); 8424f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8431a1499c8SBarry Smith if (!PetscOptionsObject->count) { 84410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 84510c654e6SJacob Faibussowitsch 8469566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_FLIST, &amsopt)); 84764facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8489566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8493cc1e11dSBarry Smith amsopt->flist = list; 8503cc1e11dSBarry Smith } 85110c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetString(PetscOptionsObject->options, prefix, opt, value, len, &lset)); 85244ef3d73SBarry Smith if (set) *set = lset; 85310c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall(PetscFunctionListPrintTypes(PetscOptionsObject->comm, stdout, Prefix(prefix), opt, ltext, man, list, currentvalue, lset ? value : currentvalue)); 8543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 85553acd3b1SBarry Smith } 85653acd3b1SBarry Smith 85710c654e6SJacob Faibussowitsch #ifdef __cplusplus 85810c654e6SJacob Faibussowitsch #include <type_traits> 85910c654e6SJacob Faibussowitsch #endif 86010c654e6SJacob Faibussowitsch 861ce78bad3SBarry Smith 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) 862d71ae5a4SJacob Faibussowitsch { 86310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 86444ef3d73SBarry Smith PetscBool lset; 86553acd3b1SBarry Smith 86653acd3b1SBarry Smith PetscFunctionBegin; 8674f572ea9SToby Isaac PetscAssertPointer(opt, 2); 8684f572ea9SToby Isaac PetscAssertPointer(value, 8); 8694f572ea9SToby Isaac if (set) PetscAssertPointer(set, 9); 8701a1499c8SBarry Smith if (!PetscOptionsObject->count) { 87110c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 87210c654e6SJacob Faibussowitsch 8739566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, ltext, man, OPTION_ELIST, &amsopt)); 87464facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 8759566063dSJacob Faibussowitsch PetscCall(PetscStrdup(currentvalue ? currentvalue : "", (char **)&amsopt->data)); 8769566063dSJacob Faibussowitsch PetscCall(PetscStrNArrayallocpy(ntext, list, (char ***)&amsopt->list)); 87710c654e6SJacob Faibussowitsch PetscCheck(ntext <= CHAR_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of list entries %" PetscInt_FMT " > %d", ntext, CHAR_MAX); 87810c654e6SJacob Faibussowitsch #ifdef __cplusplus 87910c654e6SJacob Faibussowitsch static_assert(std::is_same<typename std::decay<decltype(amsopt->nlist)>::type, char>::value, ""); 88010c654e6SJacob Faibussowitsch #endif 88110c654e6SJacob Faibussowitsch amsopt->nlist = (char)ntext; 8821ae3d29cSBarry Smith } 88310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetEList(PetscOptionsObject->options, prefix, opt, list, ntext, value, &lset)); 88444ef3d73SBarry Smith if (set) *set = lset; 88510c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 88610c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 88710c654e6SJacob Faibussowitsch 88810c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <now %s : formerly %s> %s (choose one of)", Prefix(prefix), opt + 1, lset ? list[*value] : currentvalue, currentvalue, ltext)); 88910c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < ntext; ++i) PetscCall((*PetscHelpPrintf)(comm, " %s", list[i])); 89010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", ManSection(man))); 89153acd3b1SBarry Smith } 8923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 89353acd3b1SBarry Smith } 89453acd3b1SBarry Smith 895ce78bad3SBarry Smith PetscErrorCode PetscOptionsBoolGroupBegin_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 896d71ae5a4SJacob Faibussowitsch { 89710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 89853acd3b1SBarry Smith 89953acd3b1SBarry Smith PetscFunctionBegin; 9004f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9014f572ea9SToby Isaac PetscAssertPointer(flg, 5); 902e55864a3SBarry Smith if (!PetscOptionsObject->count) { 90310c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 90410c654e6SJacob Faibussowitsch 9059566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9069566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 907a297a907SKarl Rupp 908ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9091ae3d29cSBarry Smith } 91068b16fdaSBarry Smith *flg = PETSC_FALSE; 91110c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 91210c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 91310c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 91410c654e6SJacob Faibussowitsch 91510c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " Pick at most one of -------------\n")); 91610c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 91753acd3b1SBarry Smith } 9183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91953acd3b1SBarry Smith } 92053acd3b1SBarry Smith 921ce78bad3SBarry Smith PetscErrorCode PetscOptionsBoolGroup_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 922d71ae5a4SJacob Faibussowitsch { 92310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 92453acd3b1SBarry Smith 92553acd3b1SBarry Smith PetscFunctionBegin; 9264f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9274f572ea9SToby Isaac PetscAssertPointer(flg, 5); 928e55864a3SBarry Smith if (!PetscOptionsObject->count) { 92910c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 93010c654e6SJacob Faibussowitsch 9319566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9329566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 933a297a907SKarl Rupp 934ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9351ae3d29cSBarry Smith } 93617326d04SJed Brown *flg = PETSC_FALSE; 93710c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 93810c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 94053acd3b1SBarry Smith } 94153acd3b1SBarry Smith 942ce78bad3SBarry Smith PetscErrorCode PetscOptionsBoolGroupEnd_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool *flg) 943d71ae5a4SJacob Faibussowitsch { 94410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 94553acd3b1SBarry Smith 94653acd3b1SBarry Smith PetscFunctionBegin; 9474f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9484f572ea9SToby Isaac PetscAssertPointer(flg, 5); 949e55864a3SBarry Smith if (!PetscOptionsObject->count) { 95010c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 95110c654e6SJacob Faibussowitsch 9529566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9539566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 954a297a907SKarl Rupp 955ace3abfcSBarry Smith *(PetscBool *)amsopt->data = PETSC_FALSE; 9561ae3d29cSBarry Smith } 95717326d04SJed Brown *flg = PETSC_FALSE; 95810c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, NULL)); 95910c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 9603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 96153acd3b1SBarry Smith } 96253acd3b1SBarry Smith 963ce78bad3SBarry Smith PetscErrorCode PetscOptionsBool_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool currentvalue, PetscBool *flg, PetscBool *set) 964d71ae5a4SJacob Faibussowitsch { 96510c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 966ace3abfcSBarry Smith PetscBool iset; 96753acd3b1SBarry Smith 96853acd3b1SBarry Smith PetscFunctionBegin; 9694f572ea9SToby Isaac PetscAssertPointer(opt, 2); 9704f572ea9SToby Isaac PetscAssertPointer(flg, 6); 9714f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 972e55864a3SBarry Smith if (!PetscOptionsObject->count) { 97310c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 97410c654e6SJacob Faibussowitsch 9759566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL, &amsopt)); 9769566063dSJacob Faibussowitsch PetscCall(PetscMalloc(sizeof(PetscBool), &amsopt->data)); 977a297a907SKarl Rupp 97894ae4db5SBarry Smith *(PetscBool *)amsopt->data = currentvalue; 979af6d86caSBarry Smith } 98010c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBool(PetscOptionsObject->options, prefix, opt, flg, &iset)); 98153acd3b1SBarry Smith if (set) *set = iset; 98210c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 98310c654e6SJacob Faibussowitsch const char *curvalue = PetscBools[currentvalue]; 98410c654e6SJacob Faibussowitsch 98510c654e6SJacob 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))); 98653acd3b1SBarry Smith } 9873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 98853acd3b1SBarry Smith } 98953acd3b1SBarry Smith 990*4d81f786SBarry Smith PetscErrorCode PetscOptionsBool3_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool3 currentvalue, PetscBool3 *flg, PetscBool *set) 991*4d81f786SBarry Smith { 992*4d81f786SBarry Smith const char *prefix = PetscOptionsObject->prefix; 993*4d81f786SBarry Smith PetscBool iset; 994*4d81f786SBarry Smith 995*4d81f786SBarry Smith PetscFunctionBegin; 996*4d81f786SBarry Smith PetscAssertPointer(opt, 2); 997*4d81f786SBarry Smith PetscAssertPointer(flg, 6); 998*4d81f786SBarry Smith if (set) PetscAssertPointer(set, 7); 999*4d81f786SBarry Smith PetscCall(PetscOptionsGetBool3(PetscOptionsObject->options, prefix, opt, flg, &iset)); 1000*4d81f786SBarry Smith if (set) *set = iset; 1001*4d81f786SBarry Smith if (ShouldPrintHelp(PetscOptionsObject)) { 1002*4d81f786SBarry Smith const char *curvalue = PetscBool3s[currentvalue]; 1003*4d81f786SBarry Smith 1004*4d81f786SBarry Smith 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))); 1005*4d81f786SBarry Smith } 1006*4d81f786SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 1007*4d81f786SBarry Smith } 1008*4d81f786SBarry Smith 1009ce78bad3SBarry Smith PetscErrorCode PetscOptionsRealArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscReal value[], PetscInt *n, PetscBool *set) 1010d71ae5a4SJacob Faibussowitsch { 101110c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 101253acd3b1SBarry Smith 101353acd3b1SBarry Smith PetscFunctionBegin; 10144f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10154f572ea9SToby Isaac PetscAssertPointer(n, 6); 101610c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10174f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10184f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1019e55864a3SBarry Smith if (!PetscOptionsObject->count) { 102010c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1021e26ddf31SBarry Smith PetscReal *vals; 102210c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1023e26ddf31SBarry Smith 10249566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_REAL_ARRAY, &amsopt)); 102510c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 102610c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 102710c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 102810c654e6SJacob Faibussowitsch amsopt->data = vals; 1029e26ddf31SBarry Smith } 103010c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetRealArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 103110c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 103210c654e6SJacob Faibussowitsch const PetscInt nv = *n; 103310c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 103410c654e6SJacob Faibussowitsch 103510c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g", Prefix(prefix), opt + 1, (double)value[0])); 103610c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g", (double)value[i])); 103710c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 103853acd3b1SBarry Smith } 10393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 104053acd3b1SBarry Smith } 104153acd3b1SBarry Smith 1042ce78bad3SBarry Smith PetscErrorCode PetscOptionsScalarArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscScalar value[], PetscInt *n, PetscBool *set) 1043d71ae5a4SJacob Faibussowitsch { 104410c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 1045050cccc3SHong Zhang 1046050cccc3SHong Zhang PetscFunctionBegin; 10474f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10484f572ea9SToby Isaac PetscAssertPointer(n, 6); 104910c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10504f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10514f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1052050cccc3SHong Zhang if (!PetscOptionsObject->count) { 105310c654e6SJacob Faibussowitsch const PetscInt nv = *n; 105410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1055050cccc3SHong Zhang PetscScalar *vals; 1056050cccc3SHong Zhang 10579566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_SCALAR_ARRAY, &amsopt)); 105810c654e6SJacob Faibussowitsch PetscCall(PetscMalloc(nv * sizeof(*vals), &vals)); 105910c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 106010c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 106110c654e6SJacob Faibussowitsch amsopt->data = vals; 1062050cccc3SHong Zhang } 106310c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetScalarArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 106410c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 106510c654e6SJacob Faibussowitsch const PetscInt nv = *n; 106610c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 106710c654e6SJacob Faibussowitsch 106810c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%g+%gi", Prefix(prefix), opt + 1, (double)PetscRealPart(value[0]), (double)PetscImaginaryPart(value[0]))); 106910c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%g+%gi", (double)PetscRealPart(value[i]), (double)PetscImaginaryPart(value[i]))); 107010c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1071050cccc3SHong Zhang } 10723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1073050cccc3SHong Zhang } 107453acd3b1SBarry Smith 1075ce78bad3SBarry Smith PetscErrorCode PetscOptionsIntArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscInt value[], PetscInt *n, PetscBool *set) 1076d71ae5a4SJacob Faibussowitsch { 107710c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 107853acd3b1SBarry Smith 107953acd3b1SBarry Smith PetscFunctionBegin; 10804f572ea9SToby Isaac PetscAssertPointer(opt, 2); 10814f572ea9SToby Isaac PetscAssertPointer(n, 6); 108210c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 10834f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 10844f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1085e55864a3SBarry Smith if (!PetscOptionsObject->count) { 108610c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1087e26ddf31SBarry Smith PetscInt *vals; 108810c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1089e26ddf31SBarry Smith 10909566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_INT_ARRAY, &amsopt)); 109110c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 109210c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 109310c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 109410c654e6SJacob Faibussowitsch amsopt->data = vals; 1095e26ddf31SBarry Smith } 109610c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetIntArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 109710c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 109810c654e6SJacob Faibussowitsch const PetscInt nv = *n; 109910c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 110010c654e6SJacob Faibussowitsch 110110c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%" PetscInt_FMT, Prefix(prefix), opt + 1, value[0])); 110210c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%" PetscInt_FMT, value[i])); 110310c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 110453acd3b1SBarry Smith } 11053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 110653acd3b1SBarry Smith } 110753acd3b1SBarry Smith 1108ce78bad3SBarry Smith PetscErrorCode PetscOptionsStringArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], char *value[], PetscInt *nmax, PetscBool *set) 1109d71ae5a4SJacob Faibussowitsch { 111010c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 111153acd3b1SBarry Smith 111253acd3b1SBarry Smith PetscFunctionBegin; 11134f572ea9SToby Isaac PetscAssertPointer(opt, 2); 11144f572ea9SToby Isaac PetscAssertPointer(nmax, 6); 111510c654e6SJacob Faibussowitsch PetscCheck(*nmax >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *nmax); 11164f572ea9SToby Isaac if (*nmax) PetscAssertPointer(value, 5); 11174f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1118e55864a3SBarry Smith if (!PetscOptionsObject->count) { 111910c654e6SJacob Faibussowitsch const PetscInt nmaxv = *nmax; 112010c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 1121a297a907SKarl Rupp 112210c654e6SJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING_ARRAY, &amsopt)); 112310c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nmaxv, (char **)&amsopt->data)); 112410c654e6SJacob Faibussowitsch amsopt->arraylength = nmaxv; 11251ae3d29cSBarry Smith } 112610c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(PetscOptionsObject->options, prefix, opt, value, nmax, set)); 112710c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(PetscOptionsObject->comm, " -%s%s: <string1,string2,...>: %s (%s)\n", Prefix(prefix), opt + 1, text, ManSection(man))); 11283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 112953acd3b1SBarry Smith } 113053acd3b1SBarry Smith 1131ce78bad3SBarry Smith PetscErrorCode PetscOptionsBoolArray_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscBool value[], PetscInt *n, PetscBool *set) 1132d71ae5a4SJacob Faibussowitsch { 113310c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 1134e2446a98SMatthew Knepley 1135e2446a98SMatthew Knepley PetscFunctionBegin; 11364f572ea9SToby Isaac PetscAssertPointer(opt, 2); 11374f572ea9SToby Isaac PetscAssertPointer(n, 6); 113810c654e6SJacob Faibussowitsch PetscCheck(*n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "n (%" PetscInt_FMT ") cannot be negative", *n); 11394f572ea9SToby Isaac if (*n) PetscAssertPointer(value, 5); 11404f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 1141e55864a3SBarry Smith if (!PetscOptionsObject->count) { 114210c654e6SJacob Faibussowitsch const PetscInt nv = *n; 1143ace3abfcSBarry Smith PetscBool *vals; 114410c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 11451ae3d29cSBarry Smith 11469566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_BOOL_ARRAY, &amsopt)); 114710c654e6SJacob Faibussowitsch PetscCall(PetscMalloc1(nv, &vals)); 114810c654e6SJacob Faibussowitsch for (PetscInt i = 0; i < nv; ++i) vals[i] = value[i]; 114910c654e6SJacob Faibussowitsch amsopt->arraylength = nv; 115010c654e6SJacob Faibussowitsch amsopt->data = vals; 11511ae3d29cSBarry Smith } 115210c654e6SJacob Faibussowitsch PetscCall(PetscOptionsGetBoolArray(PetscOptionsObject->options, prefix, opt, value, n, set)); 115310c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) { 115410c654e6SJacob Faibussowitsch const PetscInt nv = *n; 115510c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 115610c654e6SJacob Faibussowitsch 115710c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%d", Prefix(prefix), opt + 1, value[0])); 115810c654e6SJacob Faibussowitsch for (PetscInt i = 1; i < nv; ++i) PetscCall((*PetscHelpPrintf)(comm, ",%d", value[i])); 115910c654e6SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, ">: %s (%s)\n", text, ManSection(man))); 1160e2446a98SMatthew Knepley } 11613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1162e2446a98SMatthew Knepley } 1163e2446a98SMatthew Knepley 116488aa4217SBarry Smith /*MC 1165648c30bcSBarry Smith PetscOptionsViewer - Creates a viewer appropriate for the type indicated by the user 11668cc676e6SMatthew G Knepley 116788aa4217SBarry Smith Synopsis: 116810450e9eSJacob Faibussowitsch #include <petscviewer.h> 11693a89f35bSSatish Balay PetscErrorCode PetscOptionsViewer(const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 117088aa4217SBarry Smith 11717cdbe19fSJose E. Roman Logically Collective on the communicator passed in `PetscOptionsBegin()` 11727cdbe19fSJose E. Roman 11738cc676e6SMatthew G Knepley Input Parameters: 11748cc676e6SMatthew G Knepley + opt - option name 11758cc676e6SMatthew G Knepley . text - short string that describes the option 11768cc676e6SMatthew G Knepley - man - manual page with additional information on option 11778cc676e6SMatthew G Knepley 1178d8d19677SJose E. Roman Output Parameters: 11798cc676e6SMatthew G Knepley + viewer - the viewer 11809314d9b7SBarry Smith . format - the PetscViewerFormat requested by the user, pass `NULL` if not needed 1181811af0c4SBarry Smith - set - `PETSC_TRUE` if found, else `PETSC_FALSE` 11828cc676e6SMatthew G Knepley 11838cc676e6SMatthew G Knepley Level: beginner 11848cc676e6SMatthew G Knepley 118595452b02SPatrick Sanan Notes: 1186811af0c4SBarry Smith Must be between a `PetscOptionsBegin()` and a `PetscOptionsEnd()` 11878cc676e6SMatthew G Knepley 1188648c30bcSBarry Smith See `PetscOptionsCreateViewer()` for the format of the supplied viewer and its options 11898cc676e6SMatthew G Knepley 1190648c30bcSBarry Smith .seealso: `PetscOptionsCreateViewer()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, `PetscOptionsGetInt()`, 1191db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 1192aec76313SJacob Faibussowitsch `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, 1193db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 1194c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 1195db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 1196db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 119788aa4217SBarry Smith M*/ 1198ce78bad3SBarry Smith PetscErrorCode PetscOptionsViewer_Private(PetscOptionItems PetscOptionsObject, const char opt[], const char text[], const char man[], PetscViewer *viewer, PetscViewerFormat *format, PetscBool *set) 1199d71ae5a4SJacob Faibussowitsch { 120010c654e6SJacob Faibussowitsch const MPI_Comm comm = PetscOptionsObject->comm; 120110c654e6SJacob Faibussowitsch const char *prefix = PetscOptionsObject->prefix; 12028cc676e6SMatthew G Knepley 12038cc676e6SMatthew G Knepley PetscFunctionBegin; 12044f572ea9SToby Isaac PetscAssertPointer(opt, 2); 12054f572ea9SToby Isaac PetscAssertPointer(viewer, 5); 12064f572ea9SToby Isaac if (format) PetscAssertPointer(format, 6); 12074f572ea9SToby Isaac if (set) PetscAssertPointer(set, 7); 12081a1499c8SBarry Smith if (!PetscOptionsObject->count) { 120910c654e6SJacob Faibussowitsch PetscOptionItem amsopt; 121010c654e6SJacob Faibussowitsch 12119566063dSJacob Faibussowitsch PetscCall(PetscOptionItemCreate_Private(PetscOptionsObject, opt, text, man, OPTION_STRING, &amsopt)); 121264facd6cSBarry Smith /* must use system malloc since SAWs may free this */ 12139566063dSJacob Faibussowitsch PetscCall(PetscStrdup("", (char **)&amsopt->data)); 12148cc676e6SMatthew G Knepley } 1215648c30bcSBarry Smith PetscCall(PetscOptionsCreateViewer(comm, PetscOptionsObject->options, prefix, opt, viewer, format, set)); 121610c654e6SJacob Faibussowitsch if (ShouldPrintHelp(PetscOptionsObject)) PetscCall((*PetscHelpPrintf)(comm, " -%s%s: <%s>: %s (%s)\n", Prefix(prefix), opt + 1, "", text, ManSection(man))); 12173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12188cc676e6SMatthew G Knepley } 1219