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) {
15: PetscViewerASCIIPrintf(viewer,"String = %s\n",(char*)value);
16: }
17: return 0;
18: }
20: static PetscErrorCode PFDestroy_String(void *value)
21: {
22: PetscFree(value);
23: return 0;
24: }
26: /*
27: PFStringCreateFunction - Creates a function from a string
29: Collective over PF
31: Input Parameters:
32: + pf - the function object
33: - string - the string that defines the function
35: Output Parameter:
36: . f - the function pointer.
38: .seealso: PFSetFromOptions()
40: */
41: PetscErrorCode PFStringCreateFunction(PF pf,char *string,void **f)
42: {
43: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
44: char task[1024],tmp[256],lib[PETSC_MAX_PATH_LEN],username[64];
45: FILE *fd;
46: PetscBool tmpshared,wdshared,keeptmpfiles = PETSC_FALSE;
47: MPI_Comm comm;
48: #endif
50: #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
51: PetscFree(pf->data);
52: PetscStrallocpy(string,(char**)&pf->data);
54: /* create the new C function and compile it */
55: PetscSharedTmp(PetscObjectComm((PetscObject)pf),&tmpshared);
56: PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf),&wdshared);
57: if (tmpshared) { /* do it in /tmp since everyone has one */
58: PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN);
59: PetscObjectGetComm((PetscObject)pf,&comm);
60: } else if (!wdshared) { /* each one does in private /tmp */
61: PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN);
62: comm = PETSC_COMM_SELF;
63: } else { /* do it in current directory */
64: PetscStrcpy(tmp,".");
65: PetscObjectGetComm((PetscObject)pf,&comm);
66: }
67: PetscOptionsGetBool(((PetscObject)pf)->options,((PetscObject)pf)->prefix,"-pf_string_keep_files",&keeptmpfiles,NULL);
68: if (keeptmpfiles) 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);
69: else 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,(int)pf->dimin,(int)pf->dimout,string);
71: #if defined(PETSC_HAVE_POPEN)
72: PetscPOpen(comm,NULL,task,"r",&fd);
73: PetscPClose(comm,fd);
74: #else
75: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
76: #endif
78: MPI_Barrier(comm);
80: /* load the apply function from the dynamic library */
81: PetscGetUserName(username,64);
82: sprintf(lib,"%s/%s/libpetscdlib",tmp,username);
83: PetscDLLibrarySym(comm,NULL,lib,"PFApply_String",f);
85: #endif
86: return 0;
87: }
89: static PetscErrorCode PFSetFromOptions_String(PetscOptionItems *PetscOptionsObject,PF pf)
90: {
91: PetscBool flag;
92: char value[PETSC_MAX_PATH_LEN];
93: PetscErrorCode (*f)(void*,PetscInt,const PetscScalar*,PetscScalar*) = NULL;
95: PetscOptionsHead(PetscOptionsObject,"String function options");
96: PetscOptionsString("-pf_string","Enter the function","PFStringCreateFunction","",value,sizeof(value),&flag);
97: if (flag) {
98: PFStringCreateFunction(pf,value,(void**)&f);
99: pf->ops->apply = f;
100: }
101: PetscOptionsTail();
102: return 0;
103: }
105: typedef PetscErrorCode (*FCN)(void*,PetscInt,const PetscScalar*,PetscScalar*); /* force argument to next function to not be extern C*/
107: PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf,void *value)
108: {
109: FCN f = NULL;
111: if (value) {
112: PFStringCreateFunction(pf,(char*)value,(void**)&f);
113: }
114: PFSet(pf,f,NULL,PFView_String,PFDestroy_String,NULL);
115: pf->ops->setfromoptions = PFSetFromOptions_String;
116: return 0;
117: }