xref: /petsc/src/vec/pf/impls/string/cstring.c (revision 5f80ce2ab25dff0f4601e710601cbbcecf323266)
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 
9e0877f53SBarry Smith static PetscErrorCode PFView_String(void *value,PetscViewer viewer)
10292f8084SBarry Smith {
11ace3abfcSBarry Smith   PetscBool      iascii;
12292f8084SBarry Smith 
13292f8084SBarry Smith   PetscFunctionBegin;
14*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
15292f8084SBarry Smith   if (iascii) {
16*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscViewerASCIIPrintf(viewer,"String = %s\n",(char*)value));
17292f8084SBarry Smith   }
18292f8084SBarry Smith   PetscFunctionReturn(0);
19292f8084SBarry Smith }
20292f8084SBarry Smith 
21e0877f53SBarry Smith static PetscErrorCode PFDestroy_String(void *value)
22292f8084SBarry Smith {
23292f8084SBarry Smith   PetscFunctionBegin;
24*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(value));
25292f8084SBarry Smith   PetscFunctionReturn(0);
26292f8084SBarry Smith }
27292f8084SBarry Smith 
28292f8084SBarry Smith /*
29292f8084SBarry Smith     PFStringCreateFunction - Creates a function from a string
30292f8084SBarry Smith 
31292f8084SBarry Smith    Collective over PF
32292f8084SBarry Smith 
33292f8084SBarry Smith   Input Parameters:
34292f8084SBarry Smith +    pf - the function object
35292f8084SBarry Smith -    string - the string that defines the function
36292f8084SBarry Smith 
37292f8084SBarry Smith   Output Parameter:
38292f8084SBarry Smith .    f - the function pointer.
39292f8084SBarry Smith 
40292f8084SBarry Smith .seealso: PFSetFromOptions()
41292f8084SBarry Smith 
42292f8084SBarry Smith */
437087cfbeSBarry Smith PetscErrorCode  PFStringCreateFunction(PF pf,char *string,void **f)
44292f8084SBarry Smith {
450598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
46292f8084SBarry Smith   char           task[1024],tmp[256],lib[PETSC_MAX_PATH_LEN],username[64];
47292f8084SBarry Smith   FILE           *fd;
48ace3abfcSBarry Smith   PetscBool      tmpshared,wdshared,keeptmpfiles = PETSC_FALSE;
49292f8084SBarry Smith   MPI_Comm       comm;
50292f8084SBarry Smith #endif
51292f8084SBarry Smith 
52292f8084SBarry Smith   PetscFunctionBegin;
530598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
54*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(pf->data));
55*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrallocpy(string,(char**)&pf->data));
56292f8084SBarry Smith 
57292f8084SBarry Smith   /* create the new C function and compile it */
58*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSharedTmp(PetscObjectComm((PetscObject)pf),&tmpshared));
59*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf),&wdshared));
60292f8084SBarry Smith   if (tmpshared) {  /* do it in /tmp since everyone has one */
61*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN));
62*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectGetComm((PetscObject)pf,&comm));
63292f8084SBarry Smith   } else if (!wdshared) {  /* each one does in private /tmp */
64*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN));
65292f8084SBarry Smith     comm = PETSC_COMM_SELF;
66292f8084SBarry Smith   } else { /* do it in current directory */
67*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcpy(tmp,"."));
68*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscObjectGetComm((PetscObject)pf,&comm));
69292f8084SBarry Smith   }
70*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsGetBool(((PetscObject)pf)->options,((PetscObject)pf)->prefix,"-pf_string_keep_files",&keeptmpfiles,NULL));
71f6e5521dSKarl Rupp   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);
72f6e5521dSKarl Rupp   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);
73f6e5521dSKarl Rupp 
747cfd0b05SBarry Smith #if defined(PETSC_HAVE_POPEN)
75*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPOpen(comm,NULL,task,"r",&fd));
76*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscPClose(comm,fd));
777cfd0b05SBarry Smith #else
78e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
797cfd0b05SBarry Smith #endif
80292f8084SBarry Smith 
81*5f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Barrier(comm));
82292f8084SBarry Smith 
83292f8084SBarry Smith   /* load the apply function from the dynamic library */
84*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscGetUserName(username,64));
85292f8084SBarry Smith   sprintf(lib,"%s/%s/libpetscdlib",tmp,username);
86*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscDLLibrarySym(comm,NULL,lib,"PFApply_String",f));
872c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!f,PetscObjectComm((PetscObject)pf),PETSC_ERR_ARG_WRONGSTATE,"Cannot find function %s",lib);
88292f8084SBarry Smith #endif
89292f8084SBarry Smith   PetscFunctionReturn(0);
90292f8084SBarry Smith }
91292f8084SBarry Smith 
92e0877f53SBarry Smith static PetscErrorCode PFSetFromOptions_String(PetscOptionItems *PetscOptionsObject,PF pf)
93292f8084SBarry Smith {
94ace3abfcSBarry Smith   PetscBool      flag;
95292f8084SBarry Smith   char           value[PETSC_MAX_PATH_LEN];
964c8fdceaSLisandro Dalcin   PetscErrorCode (*f)(void*,PetscInt,const PetscScalar*,PetscScalar*) = NULL;
97292f8084SBarry Smith 
98292f8084SBarry Smith   PetscFunctionBegin;
99*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsHead(PetscOptionsObject,"String function options"));
100*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsString("-pf_string","Enter the function","PFStringCreateFunction","",value,sizeof(value),&flag));
101292f8084SBarry Smith   if (flag) {
102*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PFStringCreateFunction(pf,value,(void**)&f));
103292f8084SBarry Smith     pf->ops->apply = f;
104292f8084SBarry Smith   }
105*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscOptionsTail());
106292f8084SBarry Smith   PetscFunctionReturn(0);
107292f8084SBarry Smith }
108292f8084SBarry Smith 
10926e7fa26SJed Brown typedef PetscErrorCode (*FCN)(void*,PetscInt,const PetscScalar*,PetscScalar*); /* force argument to next function to not be extern C*/
1106ac5842eSBarry Smith 
1118cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf,void *value)
112292f8084SBarry Smith {
1134c8fdceaSLisandro Dalcin   FCN            f = NULL;
114292f8084SBarry Smith 
115292f8084SBarry Smith   PetscFunctionBegin;
116292f8084SBarry Smith   if (value) {
117*5f80ce2aSJacob Faibussowitsch     CHKERRQ(PFStringCreateFunction(pf,(char*)value,(void**)&f));
118292f8084SBarry Smith   }
119*5f80ce2aSJacob Faibussowitsch   CHKERRQ(PFSet(pf,f,NULL,PFView_String,PFDestroy_String,NULL));
120292f8084SBarry Smith   pf->ops->setfromoptions = PFSetFromOptions_String;
121292f8084SBarry Smith   PetscFunctionReturn(0);
122292f8084SBarry Smith }
123