1292f8084SBarry Smith 2c6db04a5SJed Brown #include <../src/vec/pf/pfimpl.h> /*I "petscpf.h" I*/ 3292f8084SBarry Smith 4292f8084SBarry Smith /* 5a5b23f4aSJose E. Roman This PF generates a function on the fly and loads it into the running 6292f8084SBarry Smith program. 7292f8084SBarry Smith */ 8292f8084SBarry Smith 9d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFView_String(void *value, PetscViewer viewer) 10d71ae5a4SJacob Faibussowitsch { 11ace3abfcSBarry Smith PetscBool iascii; 12292f8084SBarry Smith 13292f8084SBarry Smith PetscFunctionBegin; 149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1548a46eb9SPierre Jolivet if (iascii) PetscCall(PetscViewerASCIIPrintf(viewer, "String = %s\n", (char *)value)); 163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17292f8084SBarry Smith } 18292f8084SBarry Smith 19d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFDestroy_String(void *value) 20d71ae5a4SJacob Faibussowitsch { 21292f8084SBarry Smith PetscFunctionBegin; 229566063dSJacob Faibussowitsch PetscCall(PetscFree(value)); 233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24292f8084SBarry Smith } 25292f8084SBarry Smith 26f236b2adSBarry Smith static PetscErrorCode PFSetFromOptions_String(PF pf, PetscOptionItems *PetscOptionsObject) 27f236b2adSBarry Smith { 28f236b2adSBarry Smith PetscBool flag; 29f236b2adSBarry Smith char value[PETSC_MAX_PATH_LEN]; 30292f8084SBarry Smith 31f236b2adSBarry Smith PetscFunctionBegin; 32f236b2adSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "String function options"); 33f236b2adSBarry Smith PetscCall(PetscOptionsString("-pf_string", "Enter the function", "PFStringCreateFunction", "", value, sizeof(value), &flag)); 34f236b2adSBarry Smith if (flag) PetscCall(PFStringSetFunction(pf, value)); 35f236b2adSBarry Smith PetscOptionsHeadEnd(); 36f236b2adSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 37f236b2adSBarry Smith } 38f236b2adSBarry Smith 3938b5cf2dSJacob Faibussowitsch /*@C 40f236b2adSBarry Smith PFStringSetFunction - Creates a function from a string 41f236b2adSBarry Smith 42f236b2adSBarry Smith Collective 43292f8084SBarry Smith 44292f8084SBarry Smith Input Parameters: 45292f8084SBarry Smith + pf - the function object 46292f8084SBarry Smith - string - the string that defines the function 47292f8084SBarry Smith 48e33f79d8SJacob Faibussowitsch Level: intermediate 49e33f79d8SJacob Faibussowitsch 50f236b2adSBarry Smith Developer Notes: 51e33f79d8SJacob Faibussowitsch Currently this can be used only ONCE in a running code. It needs to be fixed to generate a 52e33f79d8SJacob Faibussowitsch new library name for each new function added. 53f236b2adSBarry Smith 54f236b2adSBarry Smith Requires `PETSC_HAVE_POPEN` `PETSC_USE_SHARED_LIBRARIES` `PETSC_HAVE_DYNAMIC_LIBRARIES` to use 55292f8084SBarry Smith 56db781477SPatrick Sanan .seealso: `PFSetFromOptions()` 5738b5cf2dSJacob Faibussowitsch @*/ 58f236b2adSBarry Smith PetscErrorCode PFStringSetFunction(PF pf, const char *string) 59d71ae5a4SJacob Faibussowitsch { 60f236b2adSBarry Smith char task[1024], tmp[PETSC_MAX_PATH_LEN], lib[PETSC_MAX_PATH_LEN]; 61ace3abfcSBarry Smith PetscBool tmpshared, wdshared, keeptmpfiles = PETSC_FALSE; 62292f8084SBarry Smith MPI_Comm comm; 63f236b2adSBarry Smith FILE *fd; 64f236b2adSBarry Smith char *data; 65f236b2adSBarry Smith PetscErrorCode (*f)(void *, PetscInt, const PetscScalar *, PetscScalar *); 66292f8084SBarry Smith 67292f8084SBarry Smith PetscFunctionBegin; 68f236b2adSBarry Smith PetscCall(PetscObjectChangeTypeName((PetscObject)pf, PFSTRING)); 69292f8084SBarry Smith /* create the new C function and compile it */ 709566063dSJacob Faibussowitsch PetscCall(PetscSharedTmp(PetscObjectComm((PetscObject)pf), &tmpshared)); 719566063dSJacob Faibussowitsch PetscCall(PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf), &wdshared)); 72292f8084SBarry Smith if (tmpshared) { /* do it in /tmp since everyone has one */ 73a364092eSJacob Faibussowitsch PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_STATIC_ARRAY_LENGTH(tmp))); 749566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)pf, &comm)); 75292f8084SBarry Smith } else if (!wdshared) { /* each one does in private /tmp */ 76a364092eSJacob Faibussowitsch PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_STATIC_ARRAY_LENGTH(tmp))); 77292f8084SBarry Smith comm = PETSC_COMM_SELF; 78292f8084SBarry Smith } else { /* do it in current directory */ 79c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(tmp, ".", sizeof(tmp))); 809566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)pf, &comm)); 81292f8084SBarry Smith } 829566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)pf)->options, ((PetscObject)pf)->prefix, "-pf_string_keep_files", &keeptmpfiles, NULL)); 83f236b2adSBarry Smith PetscCall(PetscSNPrintf(task, PETSC_STATIC_ARRAY_LENGTH(task), "cd %s ; if [ ! -d ${USERNAME} ]; then mkdir ${USERNAME}; fi ; cd ${USERNAME} ; rm -f makefile petscdlib.* ; cp -f ${PETSC_DIR}/src/vec/pf/impls/string/makefile ./makefile ; ${PETSC_MAKE} NIN=%" PetscInt_FMT " NOUT=%" PetscInt_FMT " -f makefile libpetscdlib STRINGFUNCTION=\"%s\" %s ; sync\n", tmp, pf->dimin, pf->dimout, string, keeptmpfiles ? "; rm -f makefile petscdlib.c" : "")); 84f6e5521dSKarl Rupp 859566063dSJacob Faibussowitsch PetscCall(PetscPOpen(comm, NULL, task, "r", &fd)); 869566063dSJacob Faibussowitsch PetscCall(PetscPClose(comm, fd)); 879566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(comm)); 88292f8084SBarry Smith 89292f8084SBarry Smith /* load the apply function from the dynamic library */ 90f236b2adSBarry Smith PetscCall(PetscSNPrintf(lib, PETSC_STATIC_ARRAY_LENGTH(lib), "%s/${USERNAME}/libpetscdlib", tmp)); 91f236b2adSBarry Smith PetscCall(PetscDLLibrarySym(comm, NULL, lib, "PFApply_String", (void **)&f)); 9228b400f6SJacob Faibussowitsch PetscCheck(f, PetscObjectComm((PetscObject)pf), PETSC_ERR_ARG_WRONGSTATE, "Cannot find function %s", lib); 93f236b2adSBarry Smith 94f236b2adSBarry Smith PetscCall(PetscFree(pf->data)); 95f236b2adSBarry Smith PetscCall(PetscStrallocpy(string, (char **)&data)); 96f236b2adSBarry Smith PetscCall(PFSet(pf, f, NULL, PFView_String, PFDestroy_String, data)); 97f236b2adSBarry Smith pf->ops->setfromoptions = PFSetFromOptions_String; 983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99292f8084SBarry Smith } 100292f8084SBarry Smith 101*da8c939bSJacob Faibussowitsch PETSC_INTERN PetscErrorCode PFCreate_String(PF pf, void *value) 102d71ae5a4SJacob Faibussowitsch { 103292f8084SBarry Smith PetscFunctionBegin; 104f236b2adSBarry Smith PetscCall(PFStringSetFunction(pf, (const char *)value)); 1053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 106292f8084SBarry Smith } 107