Actual source code: cstring.c


  2: #include <../src/vec/pf/pfimpl.h>

  4: /*
  5:         This PF generates a function on the fly and loads it into the running
  6:    program.
  7: */

  9: static PetscErrorCode PFView_String(void *value, PetscViewer viewer)
 10: {
 11:   PetscBool iascii;

 13:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii);
 14:   if (iascii) PetscViewerASCIIPrintf(viewer, "String = %s\n", (char *)value);
 15:   return 0;
 16: }

 18: static PetscErrorCode PFDestroy_String(void *value)
 19: {
 20:   PetscFree(value);
 21:   return 0;
 22: }

 24: /*
 25:     PFStringCreateFunction - Creates a function from a string

 27:    Collective over PF

 29:   Input Parameters:
 30: +    pf - the function object
 31: -    string - the string that defines the function

 33:   Output Parameter:
 34: .    f - the function pointer.

 36: .seealso: `PFSetFromOptions()`

 38: */
 39: PetscErrorCode PFStringCreateFunction(PF pf, char *string, void **f)
 40: {
 41: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
 42:   char      task[1024], tmp[256], lib[PETSC_MAX_PATH_LEN], username[64];
 43:   FILE     *fd;
 44:   PetscBool tmpshared, wdshared, keeptmpfiles = PETSC_FALSE;
 45:   MPI_Comm  comm;
 46: #endif

 48: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
 49:   PetscFree(pf->data);
 50:   PetscStrallocpy(string, (char **)&pf->data);

 52:   /* create the new C function and compile it */
 53:   PetscSharedTmp(PetscObjectComm((PetscObject)pf), &tmpshared);
 54:   PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf), &wdshared);
 55:   if (tmpshared) { /* do it in /tmp since everyone has one */
 56:     PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_MAX_PATH_LEN);
 57:     PetscObjectGetComm((PetscObject)pf, &comm);
 58:   } else if (!wdshared) { /* each one does in private /tmp */
 59:     PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_MAX_PATH_LEN);
 60:     comm = PETSC_COMM_SELF;
 61:   } else { /* do it in current directory */
 62:     PetscStrcpy(tmp, ".");
 63:     PetscObjectGetComm((PetscObject)pf, &comm);
 64:   }
 65:   PetscOptionsGetBool(((PetscObject)pf)->options, ((PetscObject)pf)->prefix, "-pf_string_keep_files", &keeptmpfiles, NULL);
 66:   if (keeptmpfiles)
 67:     sprintf(task, "cd %s ; mkdir ${USERNAME} ; cd ${USERNAME} ; \\cp -f ${PETSC_DIR}/src/pf/impls/string/makefile ./makefile ; ke  MIN=%d NOUT=%d petscdlib STRINGFUNCTION=\"%s\" ; sync\n", tmp, (int)pf->dimin, (int)pf->dimout, string);
 68:   else
 69:     sprintf(task, "cd %s ; mkdir ${USERNAME} ; cd ${USERNAME} ; \\cp -f ${PETSC_DIR}/src/pf/impls/string/makefile ./makefile ; make  MIN=%d NOUT=%d -f makefile petscdlib STRINGFUNCTION=\"%s\" ; \\rm -f makefile petscdlib.c libpetscdlib.a ;  sync\n", tmp,
 70:             (int)pf->dimin, (int)pf->dimout, string);

 72:   #if defined(PETSC_HAVE_POPEN)
 73:   PetscPOpen(comm, NULL, task, "r", &fd);
 74:   PetscPClose(comm, fd);
 75:   #else
 76:   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine");
 77:   #endif

 79:   MPI_Barrier(comm);

 81:   /* load the apply function from the dynamic library */
 82:   PetscGetUserName(username, 64);
 83:   sprintf(lib, "%s/%s/libpetscdlib", tmp, username);
 84:   PetscDLLibrarySym(comm, NULL, lib, "PFApply_String", f);
 86: #endif
 87:   return 0;
 88: }

 90: static PetscErrorCode PFSetFromOptions_String(PF pf, PetscOptionItems *PetscOptionsObject)
 91: {
 92:   PetscBool flag;
 93:   char      value[PETSC_MAX_PATH_LEN];
 94:   PetscErrorCode (*f)(void *, PetscInt, const PetscScalar *, PetscScalar *) = NULL;

 96:   PetscOptionsHeadBegin(PetscOptionsObject, "String function options");
 97:   PetscOptionsString("-pf_string", "Enter the function", "PFStringCreateFunction", "", value, sizeof(value), &flag);
 98:   if (flag) {
 99:     PFStringCreateFunction(pf, value, (void **)&f);
100:     pf->ops->apply = f;
101:   }
102:   PetscOptionsHeadEnd();
103:   return 0;
104: }

106: typedef PetscErrorCode (*FCN)(void *, PetscInt, const PetscScalar *, PetscScalar *); /* force argument to next function to not be extern C*/

108: PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf, void *value)
109: {
110:   FCN f = NULL;

112:   if (value) PFStringCreateFunction(pf, (char *)value, (void **)&f);
113:   PFSet(pf, f, NULL, PFView_String, PFDestroy_String, NULL);
114:   pf->ops->setfromoptions = PFSetFromOptions_String;
115:   return 0;
116: }