xref: /petsc/src/vec/pf/impls/matlab/cmatlab.c (revision 98d129c30f3ee9fdddc40fdbc5a989b7be64f888)
1 #include <../src/vec/pf/pfimpl.h> /*I "petscpf.h" I*/
2 #include <petscmatlab.h>          /*I  "petscmatlab.h"  I*/
3 
4 /*
5         This PF generates a MATLAB function on the fly
6 */
7 typedef struct {
8   PetscInt          dimin, dimout;
9   PetscMatlabEngine mengine;
10   char             *string;
11 } PF_Matlab;
12 
13 static PetscErrorCode PFView_Matlab(void *value, PetscViewer viewer)
14 {
15   PetscBool  iascii;
16   PF_Matlab *matlab = (PF_Matlab *)value;
17 
18   PetscFunctionBegin;
19   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
20   if (iascii) PetscCall(PetscViewerASCIIPrintf(viewer, "Matlab Matlab = %s\n", matlab->string));
21   PetscFunctionReturn(PETSC_SUCCESS);
22 }
23 
24 static PetscErrorCode PFDestroy_Matlab(void *value)
25 {
26   PF_Matlab *matlab = (PF_Matlab *)value;
27 
28   PetscFunctionBegin;
29   PetscCall(PetscFree(matlab->string));
30   PetscCall(PetscMatlabEngineDestroy(&matlab->mengine));
31   PetscCall(PetscFree(matlab));
32   PetscFunctionReturn(PETSC_SUCCESS);
33 }
34 
35 static PetscErrorCode PFApply_Matlab(void *value, PetscInt n, const PetscScalar *in, PetscScalar *out)
36 {
37   PF_Matlab *matlab = (PF_Matlab *)value;
38 
39   PetscFunctionBegin;
40   PetscCheck(value, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Need to set string for MATLAB function, via -pf_matlab string");
41   PetscCall(PetscMatlabEnginePutArray(matlab->mengine, matlab->dimin, n, in, "x"));
42   PetscCall(PetscMatlabEngineEvaluate(matlab->mengine, matlab->string));
43   PetscCall(PetscMatlabEngineGetArray(matlab->mengine, matlab->dimout, n, out, "f"));
44   PetscFunctionReturn(PETSC_SUCCESS);
45 }
46 
47 static PetscErrorCode PFSetFromOptions_Matlab(PF pf, PetscOptionItems *PetscOptionsObject)
48 {
49   PetscBool  flag;
50   char       value[256];
51   PF_Matlab *matlab = (PF_Matlab *)pf->data;
52 
53   PetscFunctionBegin;
54   PetscOptionsHeadBegin(PetscOptionsObject, "Matlab function options");
55   PetscCall(PetscOptionsString("-pf_matlab", "Matlab function", "None", "", value, sizeof(value), &flag));
56   if (flag) PetscCall(PetscStrallocpy((char *)value, &matlab->string));
57   PetscOptionsHeadEnd();
58   PetscFunctionReturn(PETSC_SUCCESS);
59 }
60 
61 PETSC_INTERN PetscErrorCode PFCreate_Matlab(PF pf, void *value)
62 {
63   PF_Matlab *matlab;
64 
65   PetscFunctionBegin;
66   PetscCall(PetscNew(&matlab));
67   matlab->dimin  = pf->dimin;
68   matlab->dimout = pf->dimout;
69 
70   PetscCall(PetscMatlabEngineCreate(PetscObjectComm((PetscObject)pf), NULL, &matlab->mengine));
71 
72   if (value) PetscCall(PetscStrallocpy((char *)value, &matlab->string));
73   PetscCall(PFSet(pf, PFApply_Matlab, NULL, PFView_Matlab, PFDestroy_Matlab, matlab));
74 
75   pf->ops->setfromoptions = PFSetFromOptions_Matlab;
76   PetscFunctionReturn(PETSC_SUCCESS);
77 }
78