xref: /petsc/src/vec/pf/impls/string/cstring.c (revision a5b23f4acc7afc99d3844ebd5fb65a81c16e8b8c)
1292f8084SBarry Smith 
2c6db04a5SJed Brown #include <../src/vec/pf/pfimpl.h>            /*I "petscpf.h" I*/
3292f8084SBarry Smith 
4292f8084SBarry Smith /*
5*a5b23f4aSJose 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 {
11292f8084SBarry Smith   PetscErrorCode ierr;
12ace3abfcSBarry Smith   PetscBool      iascii;
13292f8084SBarry Smith 
14292f8084SBarry Smith   PetscFunctionBegin;
15251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
16292f8084SBarry Smith   if (iascii) {
17292f8084SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"String = %s\n",(char*)value);CHKERRQ(ierr);
18292f8084SBarry Smith   }
19292f8084SBarry Smith   PetscFunctionReturn(0);
20292f8084SBarry Smith }
21292f8084SBarry Smith 
22e0877f53SBarry Smith static PetscErrorCode PFDestroy_String(void *value)
23292f8084SBarry Smith {
24292f8084SBarry Smith   PetscErrorCode ierr;
25292f8084SBarry Smith 
26292f8084SBarry Smith   PetscFunctionBegin;
27503cfb0cSBarry Smith   ierr = PetscFree(value);CHKERRQ(ierr);
28292f8084SBarry Smith   PetscFunctionReturn(0);
29292f8084SBarry Smith }
30292f8084SBarry Smith 
31292f8084SBarry Smith /*
32292f8084SBarry Smith     PFStringCreateFunction - Creates a function from a string
33292f8084SBarry Smith 
34292f8084SBarry Smith    Collective over PF
35292f8084SBarry Smith 
36292f8084SBarry Smith   Input Parameters:
37292f8084SBarry Smith +    pf - the function object
38292f8084SBarry Smith -    string - the string that defines the function
39292f8084SBarry Smith 
40292f8084SBarry Smith   Output Parameter:
41292f8084SBarry Smith .    f - the function pointer.
42292f8084SBarry Smith 
43292f8084SBarry Smith .seealso: PFSetFromOptions()
44292f8084SBarry Smith 
45292f8084SBarry Smith */
467087cfbeSBarry Smith PetscErrorCode  PFStringCreateFunction(PF pf,char *string,void **f)
47292f8084SBarry Smith {
480598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
49292f8084SBarry Smith   PetscErrorCode ierr;
50292f8084SBarry Smith   char           task[1024],tmp[256],lib[PETSC_MAX_PATH_LEN],username[64];
51292f8084SBarry Smith   FILE           *fd;
52ace3abfcSBarry Smith   PetscBool      tmpshared,wdshared,keeptmpfiles = PETSC_FALSE;
53292f8084SBarry Smith   MPI_Comm       comm;
54292f8084SBarry Smith #endif
55292f8084SBarry Smith 
56292f8084SBarry Smith   PetscFunctionBegin;
570598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
58503cfb0cSBarry Smith   ierr = PetscFree(pf->data);CHKERRQ(ierr);
59292f8084SBarry Smith   ierr = PetscStrallocpy(string,(char**)&pf->data);CHKERRQ(ierr);
60292f8084SBarry Smith 
61292f8084SBarry Smith   /* create the new C function and compile it */
62ce94432eSBarry Smith   ierr = PetscSharedTmp(PetscObjectComm((PetscObject)pf),&tmpshared);CHKERRQ(ierr);
63ce94432eSBarry Smith   ierr = PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf),&wdshared);CHKERRQ(ierr);
64292f8084SBarry Smith   if (tmpshared) {  /* do it in /tmp since everyone has one */
65ce94432eSBarry Smith     ierr = PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
66ce94432eSBarry Smith     ierr = PetscObjectGetComm((PetscObject)pf,&comm);CHKERRQ(ierr);
67292f8084SBarry Smith   } else if (!wdshared) {  /* each one does in private /tmp */
68ce94432eSBarry Smith     ierr = PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
69292f8084SBarry Smith     comm = PETSC_COMM_SELF;
70292f8084SBarry Smith   } else { /* do it in current directory */
71292f8084SBarry Smith     ierr = PetscStrcpy(tmp,".");CHKERRQ(ierr);
72ce94432eSBarry Smith     ierr = PetscObjectGetComm((PetscObject)pf,&comm);CHKERRQ(ierr);
73292f8084SBarry Smith   }
74c5929fdfSBarry Smith   ierr = PetscOptionsGetBool(((PetscObject)pf)->options,((PetscObject)pf)->prefix,"-pf_string_keep_files",&keeptmpfiles,NULL);CHKERRQ(ierr);
75f6e5521dSKarl 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);
76f6e5521dSKarl 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);
77f6e5521dSKarl Rupp 
787cfd0b05SBarry Smith #if defined(PETSC_HAVE_POPEN)
790298fd71SBarry Smith   ierr = PetscPOpen(comm,NULL,task,"r",&fd);CHKERRQ(ierr);
80016831caSBarry Smith   ierr = PetscPClose(comm,fd);CHKERRQ(ierr);
817cfd0b05SBarry Smith #else
82e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
837cfd0b05SBarry Smith #endif
84292f8084SBarry Smith 
85ffc4695bSBarry Smith   ierr = MPI_Barrier(comm);CHKERRMPI(ierr);
86292f8084SBarry Smith 
87292f8084SBarry Smith   /* load the apply function from the dynamic library */
88292f8084SBarry Smith   ierr = PetscGetUserName(username,64);CHKERRQ(ierr);
89292f8084SBarry Smith   sprintf(lib,"%s/%s/libpetscdlib",tmp,username);
900298fd71SBarry Smith   ierr = PetscDLLibrarySym(comm,NULL,lib,"PFApply_String",f);CHKERRQ(ierr);
91ce94432eSBarry Smith   if (!f) SETERRQ1(PetscObjectComm((PetscObject)pf),PETSC_ERR_ARG_WRONGSTATE,"Cannot find function %s",lib);
92292f8084SBarry Smith #endif
93292f8084SBarry Smith   PetscFunctionReturn(0);
94292f8084SBarry Smith }
95292f8084SBarry Smith 
96e0877f53SBarry Smith static PetscErrorCode PFSetFromOptions_String(PetscOptionItems *PetscOptionsObject,PF pf)
97292f8084SBarry Smith {
98292f8084SBarry Smith   PetscErrorCode ierr;
99ace3abfcSBarry Smith   PetscBool      flag;
100292f8084SBarry Smith   char           value[PETSC_MAX_PATH_LEN];
1014c8fdceaSLisandro Dalcin   PetscErrorCode (*f)(void*,PetscInt,const PetscScalar*,PetscScalar*) = NULL;
102292f8084SBarry Smith 
103292f8084SBarry Smith   PetscFunctionBegin;
104e55864a3SBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"String function options");CHKERRQ(ierr);
105589a23caSBarry Smith   ierr = PetscOptionsString("-pf_string","Enter the function","PFStringCreateFunction","",value,sizeof(value),&flag);CHKERRQ(ierr);
106292f8084SBarry Smith   if (flag) {
107292f8084SBarry Smith     ierr           = PFStringCreateFunction(pf,value,(void**)&f);CHKERRQ(ierr);
108292f8084SBarry Smith     pf->ops->apply = f;
109292f8084SBarry Smith   }
110292f8084SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
111292f8084SBarry Smith   PetscFunctionReturn(0);
112292f8084SBarry Smith }
113292f8084SBarry Smith 
11426e7fa26SJed Brown typedef PetscErrorCode (*FCN)(void*,PetscInt,const PetscScalar*,PetscScalar*); /* force argument to next function to not be extern C*/
1156ac5842eSBarry Smith 
1168cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf,void *value)
117292f8084SBarry Smith {
118292f8084SBarry Smith   PetscErrorCode ierr;
1194c8fdceaSLisandro Dalcin   FCN            f = NULL;
120292f8084SBarry Smith 
121292f8084SBarry Smith   PetscFunctionBegin;
122292f8084SBarry Smith   if (value) {
123292f8084SBarry Smith     ierr = PFStringCreateFunction(pf,(char*)value,(void**)&f);CHKERRQ(ierr);
124292f8084SBarry Smith   }
1250298fd71SBarry Smith   ierr                    = PFSet(pf,f,NULL,PFView_String,PFDestroy_String,NULL);CHKERRQ(ierr);
126292f8084SBarry Smith   pf->ops->setfromoptions = PFSetFromOptions_String;
127292f8084SBarry Smith   PetscFunctionReturn(0);
128292f8084SBarry Smith }
129292f8084SBarry Smith 
130